1 /* 2 * kmp_settings.cpp -- Initialize environment variables 3 */ 4 5 //===----------------------------------------------------------------------===// 6 // 7 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 8 // See https://llvm.org/LICENSE.txt for license information. 9 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "kmp.h" 14 #include "kmp_affinity.h" 15 #include "kmp_atomic.h" 16 #if KMP_USE_HIER_SCHED 17 #include "kmp_dispatch_hier.h" 18 #endif 19 #include "kmp_environment.h" 20 #include "kmp_i18n.h" 21 #include "kmp_io.h" 22 #include "kmp_itt.h" 23 #include "kmp_lock.h" 24 #include "kmp_settings.h" 25 #include "kmp_str.h" 26 #include "kmp_wrapper_getpid.h" 27 #include <ctype.h> // toupper() 28 29 static int __kmp_env_toPrint(char const *name, int flag); 30 31 bool __kmp_env_format = 0; // 0 - old format; 1 - new format 32 33 // ----------------------------------------------------------------------------- 34 // Helper string functions. Subject to move to kmp_str. 35 36 #ifdef USE_LOAD_BALANCE 37 static double __kmp_convert_to_double(char const *s) { 38 double result; 39 40 if (KMP_SSCANF(s, "%lf", &result) < 1) { 41 result = 0.0; 42 } 43 44 return result; 45 } 46 #endif 47 48 #ifdef KMP_DEBUG 49 static unsigned int __kmp_readstr_with_sentinel(char *dest, char const *src, 50 size_t len, char sentinel) { 51 unsigned int i; 52 for (i = 0; i < len; i++) { 53 if ((*src == '\0') || (*src == sentinel)) { 54 break; 55 } 56 *(dest++) = *(src++); 57 } 58 *dest = '\0'; 59 return i; 60 } 61 #endif 62 63 static int __kmp_match_with_sentinel(char const *a, char const *b, size_t len, 64 char sentinel) { 65 size_t l = 0; 66 67 if (a == NULL) 68 a = ""; 69 if (b == NULL) 70 b = ""; 71 while (*a && *b && *b != sentinel) { 72 char ca = *a, cb = *b; 73 74 if (ca >= 'a' && ca <= 'z') 75 ca -= 'a' - 'A'; 76 if (cb >= 'a' && cb <= 'z') 77 cb -= 'a' - 'A'; 78 if (ca != cb) 79 return FALSE; 80 ++l; 81 ++a; 82 ++b; 83 } 84 return l >= len; 85 } 86 87 // Expected usage: 88 // token is the token to check for. 89 // buf is the string being parsed. 90 // *end returns the char after the end of the token. 91 // it is not modified unless a match occurs. 92 // 93 // Example 1: 94 // 95 // if (__kmp_match_str("token", buf, *end) { 96 // <do something> 97 // buf = end; 98 // } 99 // 100 // Example 2: 101 // 102 // if (__kmp_match_str("token", buf, *end) { 103 // char *save = **end; 104 // **end = sentinel; 105 // <use any of the __kmp*_with_sentinel() functions> 106 // **end = save; 107 // buf = end; 108 // } 109 110 static int __kmp_match_str(char const *token, char const *buf, 111 const char **end) { 112 113 KMP_ASSERT(token != NULL); 114 KMP_ASSERT(buf != NULL); 115 KMP_ASSERT(end != NULL); 116 117 while (*token && *buf) { 118 char ct = *token, cb = *buf; 119 120 if (ct >= 'a' && ct <= 'z') 121 ct -= 'a' - 'A'; 122 if (cb >= 'a' && cb <= 'z') 123 cb -= 'a' - 'A'; 124 if (ct != cb) 125 return FALSE; 126 ++token; 127 ++buf; 128 } 129 if (*token) { 130 return FALSE; 131 } 132 *end = buf; 133 return TRUE; 134 } 135 136 #if KMP_OS_DARWIN 137 static size_t __kmp_round4k(size_t size) { 138 size_t _4k = 4 * 1024; 139 if (size & (_4k - 1)) { 140 size &= ~(_4k - 1); 141 if (size <= KMP_SIZE_T_MAX - _4k) { 142 size += _4k; // Round up if there is no overflow. 143 } 144 } 145 return size; 146 } // __kmp_round4k 147 #endif 148 149 /* Here, multipliers are like __kmp_convert_to_seconds, but floating-point 150 values are allowed, and the return value is in milliseconds. The default 151 multiplier is milliseconds. Returns INT_MAX only if the value specified 152 matches "infinit*". Returns -1 if specified string is invalid. */ 153 int __kmp_convert_to_milliseconds(char const *data) { 154 int ret, nvalues, factor; 155 char mult, extra; 156 double value; 157 158 if (data == NULL) 159 return (-1); 160 if (__kmp_str_match("infinit", -1, data)) 161 return (INT_MAX); 162 value = (double)0.0; 163 mult = '\0'; 164 nvalues = KMP_SSCANF(data, "%lf%c%c", &value, &mult, &extra); 165 if (nvalues < 1) 166 return (-1); 167 if (nvalues == 1) 168 mult = '\0'; 169 if (nvalues == 3) 170 return (-1); 171 172 if (value < 0) 173 return (-1); 174 175 switch (mult) { 176 case '\0': 177 /* default is milliseconds */ 178 factor = 1; 179 break; 180 case 's': 181 case 'S': 182 factor = 1000; 183 break; 184 case 'm': 185 case 'M': 186 factor = 1000 * 60; 187 break; 188 case 'h': 189 case 'H': 190 factor = 1000 * 60 * 60; 191 break; 192 case 'd': 193 case 'D': 194 factor = 1000 * 24 * 60 * 60; 195 break; 196 default: 197 return (-1); 198 } 199 200 if (value >= ((INT_MAX - 1) / factor)) 201 ret = INT_MAX - 1; /* Don't allow infinite value here */ 202 else 203 ret = (int)(value * (double)factor); /* truncate to int */ 204 205 return ret; 206 } 207 208 static int __kmp_strcasecmp_with_sentinel(char const *a, char const *b, 209 char sentinel) { 210 if (a == NULL) 211 a = ""; 212 if (b == NULL) 213 b = ""; 214 while (*a && *b && *b != sentinel) { 215 char ca = *a, cb = *b; 216 217 if (ca >= 'a' && ca <= 'z') 218 ca -= 'a' - 'A'; 219 if (cb >= 'a' && cb <= 'z') 220 cb -= 'a' - 'A'; 221 if (ca != cb) 222 return (int)(unsigned char)*a - (int)(unsigned char)*b; 223 ++a; 224 ++b; 225 } 226 return *a 227 ? (*b && *b != sentinel) 228 ? (int)(unsigned char)*a - (int)(unsigned char)*b 229 : 1 230 : (*b && *b != sentinel) ? -1 : 0; 231 } 232 233 // ============================================================================= 234 // Table structures and helper functions. 235 236 typedef struct __kmp_setting kmp_setting_t; 237 typedef struct __kmp_stg_ss_data kmp_stg_ss_data_t; 238 typedef struct __kmp_stg_wp_data kmp_stg_wp_data_t; 239 typedef struct __kmp_stg_fr_data kmp_stg_fr_data_t; 240 241 typedef void (*kmp_stg_parse_func_t)(char const *name, char const *value, 242 void *data); 243 typedef void (*kmp_stg_print_func_t)(kmp_str_buf_t *buffer, char const *name, 244 void *data); 245 246 struct __kmp_setting { 247 char const *name; // Name of setting (environment variable). 248 kmp_stg_parse_func_t parse; // Parser function. 249 kmp_stg_print_func_t print; // Print function. 250 void *data; // Data passed to parser and printer. 251 int set; // Variable set during this "session" 252 // (__kmp_env_initialize() or kmp_set_defaults() call). 253 int defined; // Variable set in any "session". 254 }; // struct __kmp_setting 255 256 struct __kmp_stg_ss_data { 257 size_t factor; // Default factor: 1 for KMP_STACKSIZE, 1024 for others. 258 kmp_setting_t **rivals; // Array of pointers to rivals (including itself). 259 }; // struct __kmp_stg_ss_data 260 261 struct __kmp_stg_wp_data { 262 int omp; // 0 -- KMP_LIBRARY, 1 -- OMP_WAIT_POLICY. 263 kmp_setting_t **rivals; // Array of pointers to rivals (including itself). 264 }; // struct __kmp_stg_wp_data 265 266 struct __kmp_stg_fr_data { 267 int force; // 0 -- KMP_DETERMINISTIC_REDUCTION, 1 -- KMP_FORCE_REDUCTION. 268 kmp_setting_t **rivals; // Array of pointers to rivals (including itself). 269 }; // struct __kmp_stg_fr_data 270 271 static int __kmp_stg_check_rivals( // 0 -- Ok, 1 -- errors found. 272 char const *name, // Name of variable. 273 char const *value, // Value of the variable. 274 kmp_setting_t **rivals // List of rival settings (must include current one). 275 ); 276 277 // ----------------------------------------------------------------------------- 278 // Helper parse functions. 279 280 static void __kmp_stg_parse_bool(char const *name, char const *value, 281 int *out) { 282 if (__kmp_str_match_true(value)) { 283 *out = TRUE; 284 } else if (__kmp_str_match_false(value)) { 285 *out = FALSE; 286 } else { 287 __kmp_msg(kmp_ms_warning, KMP_MSG(BadBoolValue, name, value), 288 KMP_HNT(ValidBoolValues), __kmp_msg_null); 289 } 290 } // __kmp_stg_parse_bool 291 292 // placed here in order to use __kmp_round4k static function 293 void __kmp_check_stksize(size_t *val) { 294 // if system stack size is too big then limit the size for worker threads 295 if (*val > KMP_DEFAULT_STKSIZE * 16) // just a heuristics... 296 *val = KMP_DEFAULT_STKSIZE * 16; 297 if (*val < KMP_MIN_STKSIZE) 298 *val = KMP_MIN_STKSIZE; 299 if (*val > KMP_MAX_STKSIZE) 300 *val = KMP_MAX_STKSIZE; // dead code currently, but may work in future 301 #if KMP_OS_DARWIN 302 *val = __kmp_round4k(*val); 303 #endif // KMP_OS_DARWIN 304 } 305 306 static void __kmp_stg_parse_size(char const *name, char const *value, 307 size_t size_min, size_t size_max, 308 int *is_specified, size_t *out, 309 size_t factor) { 310 char const *msg = NULL; 311 #if KMP_OS_DARWIN 312 size_min = __kmp_round4k(size_min); 313 size_max = __kmp_round4k(size_max); 314 #endif // KMP_OS_DARWIN 315 if (value) { 316 if (is_specified != NULL) { 317 *is_specified = 1; 318 } 319 __kmp_str_to_size(value, out, factor, &msg); 320 if (msg == NULL) { 321 if (*out > size_max) { 322 *out = size_max; 323 msg = KMP_I18N_STR(ValueTooLarge); 324 } else if (*out < size_min) { 325 *out = size_min; 326 msg = KMP_I18N_STR(ValueTooSmall); 327 } else { 328 #if KMP_OS_DARWIN 329 size_t round4k = __kmp_round4k(*out); 330 if (*out != round4k) { 331 *out = round4k; 332 msg = KMP_I18N_STR(NotMultiple4K); 333 } 334 #endif 335 } 336 } else { 337 // If integer overflow occurred, * out == KMP_SIZE_T_MAX. Cut it to 338 // size_max silently. 339 if (*out < size_min) { 340 *out = size_max; 341 } else if (*out > size_max) { 342 *out = size_max; 343 } 344 } 345 if (msg != NULL) { 346 // Message is not empty. Print warning. 347 kmp_str_buf_t buf; 348 __kmp_str_buf_init(&buf); 349 __kmp_str_buf_print_size(&buf, *out); 350 KMP_WARNING(ParseSizeIntWarn, name, value, msg); 351 KMP_INFORM(Using_str_Value, name, buf.str); 352 __kmp_str_buf_free(&buf); 353 } 354 } 355 } // __kmp_stg_parse_size 356 357 static void __kmp_stg_parse_str(char const *name, char const *value, 358 char **out) { 359 __kmp_str_free(out); 360 *out = __kmp_str_format("%s", value); 361 } // __kmp_stg_parse_str 362 363 static void __kmp_stg_parse_int( 364 char const 365 *name, // I: Name of environment variable (used in warning messages). 366 char const *value, // I: Value of environment variable to parse. 367 int min, // I: Miminal allowed value. 368 int max, // I: Maximum allowed value. 369 int *out // O: Output (parsed) value. 370 ) { 371 char const *msg = NULL; 372 kmp_uint64 uint = *out; 373 __kmp_str_to_uint(value, &uint, &msg); 374 if (msg == NULL) { 375 if (uint < (unsigned int)min) { 376 msg = KMP_I18N_STR(ValueTooSmall); 377 uint = min; 378 } else if (uint > (unsigned int)max) { 379 msg = KMP_I18N_STR(ValueTooLarge); 380 uint = max; 381 } 382 } else { 383 // If overflow occurred msg contains error message and uint is very big. Cut 384 // tmp it to INT_MAX. 385 if (uint < (unsigned int)min) { 386 uint = min; 387 } else if (uint > (unsigned int)max) { 388 uint = max; 389 } 390 } 391 if (msg != NULL) { 392 // Message is not empty. Print warning. 393 kmp_str_buf_t buf; 394 KMP_WARNING(ParseSizeIntWarn, name, value, msg); 395 __kmp_str_buf_init(&buf); 396 __kmp_str_buf_print(&buf, "%" KMP_UINT64_SPEC "", uint); 397 KMP_INFORM(Using_uint64_Value, name, buf.str); 398 __kmp_str_buf_free(&buf); 399 } 400 *out = uint; 401 } // __kmp_stg_parse_int 402 403 #if KMP_DEBUG_ADAPTIVE_LOCKS 404 static void __kmp_stg_parse_file(char const *name, char const *value, 405 const char *suffix, char **out) { 406 char buffer[256]; 407 char *t; 408 int hasSuffix; 409 __kmp_str_free(out); 410 t = (char *)strrchr(value, '.'); 411 hasSuffix = t && __kmp_str_eqf(t, suffix); 412 t = __kmp_str_format("%s%s", value, hasSuffix ? "" : suffix); 413 __kmp_expand_file_name(buffer, sizeof(buffer), t); 414 __kmp_str_free(&t); 415 *out = __kmp_str_format("%s", buffer); 416 } // __kmp_stg_parse_file 417 #endif 418 419 #ifdef KMP_DEBUG 420 static char *par_range_to_print = NULL; 421 422 static void __kmp_stg_parse_par_range(char const *name, char const *value, 423 int *out_range, char *out_routine, 424 char *out_file, int *out_lb, 425 int *out_ub) { 426 size_t len = KMP_STRLEN(value) + 1; 427 par_range_to_print = (char *)KMP_INTERNAL_MALLOC(len + 1); 428 KMP_STRNCPY_S(par_range_to_print, len + 1, value, len + 1); 429 __kmp_par_range = +1; 430 __kmp_par_range_lb = 0; 431 __kmp_par_range_ub = INT_MAX; 432 for (;;) { 433 unsigned int len; 434 if (*value == '\0') { 435 break; 436 } 437 if (!__kmp_strcasecmp_with_sentinel("routine", value, '=')) { 438 value = strchr(value, '=') + 1; 439 len = __kmp_readstr_with_sentinel(out_routine, value, 440 KMP_PAR_RANGE_ROUTINE_LEN - 1, ','); 441 if (len == 0) { 442 goto par_range_error; 443 } 444 value = strchr(value, ','); 445 if (value != NULL) { 446 value++; 447 } 448 continue; 449 } 450 if (!__kmp_strcasecmp_with_sentinel("filename", value, '=')) { 451 value = strchr(value, '=') + 1; 452 len = __kmp_readstr_with_sentinel(out_file, value, 453 KMP_PAR_RANGE_FILENAME_LEN - 1, ','); 454 if (len == 0) { 455 goto par_range_error; 456 } 457 value = strchr(value, ','); 458 if (value != NULL) { 459 value++; 460 } 461 continue; 462 } 463 if ((!__kmp_strcasecmp_with_sentinel("range", value, '=')) || 464 (!__kmp_strcasecmp_with_sentinel("incl_range", value, '='))) { 465 value = strchr(value, '=') + 1; 466 if (KMP_SSCANF(value, "%d:%d", out_lb, out_ub) != 2) { 467 goto par_range_error; 468 } 469 *out_range = +1; 470 value = strchr(value, ','); 471 if (value != NULL) { 472 value++; 473 } 474 continue; 475 } 476 if (!__kmp_strcasecmp_with_sentinel("excl_range", value, '=')) { 477 value = strchr(value, '=') + 1; 478 if (KMP_SSCANF(value, "%d:%d", out_lb, out_ub) != 2) { 479 goto par_range_error; 480 } 481 *out_range = -1; 482 value = strchr(value, ','); 483 if (value != NULL) { 484 value++; 485 } 486 continue; 487 } 488 par_range_error: 489 KMP_WARNING(ParRangeSyntax, name); 490 __kmp_par_range = 0; 491 break; 492 } 493 } // __kmp_stg_parse_par_range 494 #endif 495 496 int __kmp_initial_threads_capacity(int req_nproc) { 497 int nth = 32; 498 499 /* MIN( MAX( 32, 4 * $OMP_NUM_THREADS, 4 * omp_get_num_procs() ), 500 * __kmp_max_nth) */ 501 if (nth < (4 * req_nproc)) 502 nth = (4 * req_nproc); 503 if (nth < (4 * __kmp_xproc)) 504 nth = (4 * __kmp_xproc); 505 506 if (nth > __kmp_max_nth) 507 nth = __kmp_max_nth; 508 509 return nth; 510 } 511 512 int __kmp_default_tp_capacity(int req_nproc, int max_nth, 513 int all_threads_specified) { 514 int nth = 128; 515 516 if (all_threads_specified) 517 return max_nth; 518 /* MIN( MAX (128, 4 * $OMP_NUM_THREADS, 4 * omp_get_num_procs() ), 519 * __kmp_max_nth ) */ 520 if (nth < (4 * req_nproc)) 521 nth = (4 * req_nproc); 522 if (nth < (4 * __kmp_xproc)) 523 nth = (4 * __kmp_xproc); 524 525 if (nth > __kmp_max_nth) 526 nth = __kmp_max_nth; 527 528 return nth; 529 } 530 531 // ----------------------------------------------------------------------------- 532 // Helper print functions. 533 534 static void __kmp_stg_print_bool(kmp_str_buf_t *buffer, char const *name, 535 int value) { 536 if (__kmp_env_format) { 537 KMP_STR_BUF_PRINT_BOOL; 538 } else { 539 __kmp_str_buf_print(buffer, " %s=%s\n", name, value ? "true" : "false"); 540 } 541 } // __kmp_stg_print_bool 542 543 static void __kmp_stg_print_int(kmp_str_buf_t *buffer, char const *name, 544 int value) { 545 if (__kmp_env_format) { 546 KMP_STR_BUF_PRINT_INT; 547 } else { 548 __kmp_str_buf_print(buffer, " %s=%d\n", name, value); 549 } 550 } // __kmp_stg_print_int 551 552 #if USE_ITT_BUILD && USE_ITT_NOTIFY 553 static void __kmp_stg_print_uint64(kmp_str_buf_t *buffer, char const *name, 554 kmp_uint64 value) { 555 if (__kmp_env_format) { 556 KMP_STR_BUF_PRINT_UINT64; 557 } else { 558 __kmp_str_buf_print(buffer, " %s=%" KMP_UINT64_SPEC "\n", name, value); 559 } 560 } // __kmp_stg_print_uint64 561 #endif 562 563 static void __kmp_stg_print_str(kmp_str_buf_t *buffer, char const *name, 564 char const *value) { 565 if (__kmp_env_format) { 566 KMP_STR_BUF_PRINT_STR; 567 } else { 568 __kmp_str_buf_print(buffer, " %s=%s\n", name, value); 569 } 570 } // __kmp_stg_print_str 571 572 static void __kmp_stg_print_size(kmp_str_buf_t *buffer, char const *name, 573 size_t value) { 574 if (__kmp_env_format) { 575 KMP_STR_BUF_PRINT_NAME_EX(name); 576 __kmp_str_buf_print_size(buffer, value); 577 __kmp_str_buf_print(buffer, "'\n"); 578 } else { 579 __kmp_str_buf_print(buffer, " %s=", name); 580 __kmp_str_buf_print_size(buffer, value); 581 __kmp_str_buf_print(buffer, "\n"); 582 return; 583 } 584 } // __kmp_stg_print_size 585 586 // ============================================================================= 587 // Parse and print functions. 588 589 // ----------------------------------------------------------------------------- 590 // KMP_DEVICE_THREAD_LIMIT, KMP_ALL_THREADS 591 592 static void __kmp_stg_parse_device_thread_limit(char const *name, 593 char const *value, void *data) { 594 kmp_setting_t **rivals = (kmp_setting_t **)data; 595 int rc; 596 if (strcmp(name, "KMP_ALL_THREADS") == 0) { 597 KMP_INFORM(EnvVarDeprecated, name, "KMP_DEVICE_THREAD_LIMIT"); 598 } 599 rc = __kmp_stg_check_rivals(name, value, rivals); 600 if (rc) { 601 return; 602 } 603 if (!__kmp_strcasecmp_with_sentinel("all", value, 0)) { 604 __kmp_max_nth = __kmp_xproc; 605 __kmp_allThreadsSpecified = 1; 606 } else { 607 __kmp_stg_parse_int(name, value, 1, __kmp_sys_max_nth, &__kmp_max_nth); 608 __kmp_allThreadsSpecified = 0; 609 } 610 K_DIAG(1, ("__kmp_max_nth == %d\n", __kmp_max_nth)); 611 612 } // __kmp_stg_parse_device_thread_limit 613 614 static void __kmp_stg_print_device_thread_limit(kmp_str_buf_t *buffer, 615 char const *name, void *data) { 616 __kmp_stg_print_int(buffer, name, __kmp_max_nth); 617 } // __kmp_stg_print_device_thread_limit 618 619 // ----------------------------------------------------------------------------- 620 // OMP_THREAD_LIMIT 621 static void __kmp_stg_parse_thread_limit(char const *name, char const *value, 622 void *data) { 623 __kmp_stg_parse_int(name, value, 1, __kmp_sys_max_nth, &__kmp_cg_max_nth); 624 K_DIAG(1, ("__kmp_cg_max_nth == %d\n", __kmp_cg_max_nth)); 625 626 } // __kmp_stg_parse_thread_limit 627 628 static void __kmp_stg_print_thread_limit(kmp_str_buf_t *buffer, 629 char const *name, void *data) { 630 __kmp_stg_print_int(buffer, name, __kmp_cg_max_nth); 631 } // __kmp_stg_print_thread_limit 632 633 // ----------------------------------------------------------------------------- 634 // KMP_TEAMS_THREAD_LIMIT 635 static void __kmp_stg_parse_teams_thread_limit(char const *name, 636 char const *value, void *data) { 637 __kmp_stg_parse_int(name, value, 1, __kmp_sys_max_nth, &__kmp_teams_max_nth); 638 } // __kmp_stg_teams_thread_limit 639 640 static void __kmp_stg_print_teams_thread_limit(kmp_str_buf_t *buffer, 641 char const *name, void *data) { 642 __kmp_stg_print_int(buffer, name, __kmp_teams_max_nth); 643 } // __kmp_stg_print_teams_thread_limit 644 645 // ----------------------------------------------------------------------------- 646 // KMP_USE_YIELD 647 static void __kmp_stg_parse_use_yield(char const *name, char const *value, 648 void *data) { 649 __kmp_stg_parse_int(name, value, 0, 2, &__kmp_use_yield); 650 __kmp_use_yield_exp_set = 1; 651 } // __kmp_stg_parse_use_yield 652 653 static void __kmp_stg_print_use_yield(kmp_str_buf_t *buffer, char const *name, 654 void *data) { 655 __kmp_stg_print_int(buffer, name, __kmp_use_yield); 656 } // __kmp_stg_print_use_yield 657 658 // ----------------------------------------------------------------------------- 659 // KMP_BLOCKTIME 660 661 static void __kmp_stg_parse_blocktime(char const *name, char const *value, 662 void *data) { 663 __kmp_dflt_blocktime = __kmp_convert_to_milliseconds(value); 664 if (__kmp_dflt_blocktime < 0) { 665 __kmp_dflt_blocktime = KMP_DEFAULT_BLOCKTIME; 666 __kmp_msg(kmp_ms_warning, KMP_MSG(InvalidValue, name, value), 667 __kmp_msg_null); 668 KMP_INFORM(Using_int_Value, name, __kmp_dflt_blocktime); 669 __kmp_env_blocktime = FALSE; // Revert to default as if var not set. 670 } else { 671 if (__kmp_dflt_blocktime < KMP_MIN_BLOCKTIME) { 672 __kmp_dflt_blocktime = KMP_MIN_BLOCKTIME; 673 __kmp_msg(kmp_ms_warning, KMP_MSG(SmallValue, name, value), 674 __kmp_msg_null); 675 KMP_INFORM(MinValueUsing, name, __kmp_dflt_blocktime); 676 } else if (__kmp_dflt_blocktime > KMP_MAX_BLOCKTIME) { 677 __kmp_dflt_blocktime = KMP_MAX_BLOCKTIME; 678 __kmp_msg(kmp_ms_warning, KMP_MSG(LargeValue, name, value), 679 __kmp_msg_null); 680 KMP_INFORM(MaxValueUsing, name, __kmp_dflt_blocktime); 681 } 682 __kmp_env_blocktime = TRUE; // KMP_BLOCKTIME was specified. 683 } 684 #if KMP_USE_MONITOR 685 // calculate number of monitor thread wakeup intervals corresponding to 686 // blocktime. 687 __kmp_monitor_wakeups = 688 KMP_WAKEUPS_FROM_BLOCKTIME(__kmp_dflt_blocktime, __kmp_monitor_wakeups); 689 __kmp_bt_intervals = 690 KMP_INTERVALS_FROM_BLOCKTIME(__kmp_dflt_blocktime, __kmp_monitor_wakeups); 691 #endif 692 K_DIAG(1, ("__kmp_env_blocktime == %d\n", __kmp_env_blocktime)); 693 if (__kmp_env_blocktime) { 694 K_DIAG(1, ("__kmp_dflt_blocktime == %d\n", __kmp_dflt_blocktime)); 695 } 696 } // __kmp_stg_parse_blocktime 697 698 static void __kmp_stg_print_blocktime(kmp_str_buf_t *buffer, char const *name, 699 void *data) { 700 __kmp_stg_print_int(buffer, name, __kmp_dflt_blocktime); 701 } // __kmp_stg_print_blocktime 702 703 // ----------------------------------------------------------------------------- 704 // KMP_DUPLICATE_LIB_OK 705 706 static void __kmp_stg_parse_duplicate_lib_ok(char const *name, 707 char const *value, void *data) { 708 /* actually this variable is not supported, put here for compatibility with 709 earlier builds and for static/dynamic combination */ 710 __kmp_stg_parse_bool(name, value, &__kmp_duplicate_library_ok); 711 } // __kmp_stg_parse_duplicate_lib_ok 712 713 static void __kmp_stg_print_duplicate_lib_ok(kmp_str_buf_t *buffer, 714 char const *name, void *data) { 715 __kmp_stg_print_bool(buffer, name, __kmp_duplicate_library_ok); 716 } // __kmp_stg_print_duplicate_lib_ok 717 718 // ----------------------------------------------------------------------------- 719 // KMP_INHERIT_FP_CONTROL 720 721 #if KMP_ARCH_X86 || KMP_ARCH_X86_64 722 723 static void __kmp_stg_parse_inherit_fp_control(char const *name, 724 char const *value, void *data) { 725 __kmp_stg_parse_bool(name, value, &__kmp_inherit_fp_control); 726 } // __kmp_stg_parse_inherit_fp_control 727 728 static void __kmp_stg_print_inherit_fp_control(kmp_str_buf_t *buffer, 729 char const *name, void *data) { 730 #if KMP_DEBUG 731 __kmp_stg_print_bool(buffer, name, __kmp_inherit_fp_control); 732 #endif /* KMP_DEBUG */ 733 } // __kmp_stg_print_inherit_fp_control 734 735 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */ 736 737 // Used for OMP_WAIT_POLICY 738 static char const *blocktime_str = NULL; 739 740 // ----------------------------------------------------------------------------- 741 // KMP_LIBRARY, OMP_WAIT_POLICY 742 743 static void __kmp_stg_parse_wait_policy(char const *name, char const *value, 744 void *data) { 745 746 kmp_stg_wp_data_t *wait = (kmp_stg_wp_data_t *)data; 747 int rc; 748 749 rc = __kmp_stg_check_rivals(name, value, wait->rivals); 750 if (rc) { 751 return; 752 } 753 754 if (wait->omp) { 755 if (__kmp_str_match("ACTIVE", 1, value)) { 756 __kmp_library = library_turnaround; 757 if (blocktime_str == NULL) { 758 // KMP_BLOCKTIME not specified, so set default to "infinite". 759 __kmp_dflt_blocktime = KMP_MAX_BLOCKTIME; 760 } 761 } else if (__kmp_str_match("PASSIVE", 1, value)) { 762 __kmp_library = library_throughput; 763 if (blocktime_str == NULL) { 764 // KMP_BLOCKTIME not specified, so set default to 0. 765 __kmp_dflt_blocktime = 0; 766 } 767 } else { 768 KMP_WARNING(StgInvalidValue, name, value); 769 } 770 } else { 771 if (__kmp_str_match("serial", 1, value)) { /* S */ 772 __kmp_library = library_serial; 773 } else if (__kmp_str_match("throughput", 2, value)) { /* TH */ 774 __kmp_library = library_throughput; 775 if (blocktime_str == NULL) { 776 // KMP_BLOCKTIME not specified, so set default to 0. 777 __kmp_dflt_blocktime = 0; 778 } 779 } else if (__kmp_str_match("turnaround", 2, value)) { /* TU */ 780 __kmp_library = library_turnaround; 781 } else if (__kmp_str_match("dedicated", 1, value)) { /* D */ 782 __kmp_library = library_turnaround; 783 } else if (__kmp_str_match("multiuser", 1, value)) { /* M */ 784 __kmp_library = library_throughput; 785 if (blocktime_str == NULL) { 786 // KMP_BLOCKTIME not specified, so set default to 0. 787 __kmp_dflt_blocktime = 0; 788 } 789 } else { 790 KMP_WARNING(StgInvalidValue, name, value); 791 } 792 } 793 } // __kmp_stg_parse_wait_policy 794 795 static void __kmp_stg_print_wait_policy(kmp_str_buf_t *buffer, char const *name, 796 void *data) { 797 798 kmp_stg_wp_data_t *wait = (kmp_stg_wp_data_t *)data; 799 char const *value = NULL; 800 801 if (wait->omp) { 802 switch (__kmp_library) { 803 case library_turnaround: { 804 value = "ACTIVE"; 805 } break; 806 case library_throughput: { 807 value = "PASSIVE"; 808 } break; 809 } 810 } else { 811 switch (__kmp_library) { 812 case library_serial: { 813 value = "serial"; 814 } break; 815 case library_turnaround: { 816 value = "turnaround"; 817 } break; 818 case library_throughput: { 819 value = "throughput"; 820 } break; 821 } 822 } 823 if (value != NULL) { 824 __kmp_stg_print_str(buffer, name, value); 825 } 826 827 } // __kmp_stg_print_wait_policy 828 829 #if KMP_USE_MONITOR 830 // ----------------------------------------------------------------------------- 831 // KMP_MONITOR_STACKSIZE 832 833 static void __kmp_stg_parse_monitor_stacksize(char const *name, 834 char const *value, void *data) { 835 __kmp_stg_parse_size(name, value, __kmp_sys_min_stksize, KMP_MAX_STKSIZE, 836 NULL, &__kmp_monitor_stksize, 1); 837 } // __kmp_stg_parse_monitor_stacksize 838 839 static void __kmp_stg_print_monitor_stacksize(kmp_str_buf_t *buffer, 840 char const *name, void *data) { 841 if (__kmp_env_format) { 842 if (__kmp_monitor_stksize > 0) 843 KMP_STR_BUF_PRINT_NAME_EX(name); 844 else 845 KMP_STR_BUF_PRINT_NAME; 846 } else { 847 __kmp_str_buf_print(buffer, " %s", name); 848 } 849 if (__kmp_monitor_stksize > 0) { 850 __kmp_str_buf_print_size(buffer, __kmp_monitor_stksize); 851 } else { 852 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined)); 853 } 854 if (__kmp_env_format && __kmp_monitor_stksize) { 855 __kmp_str_buf_print(buffer, "'\n"); 856 } 857 } // __kmp_stg_print_monitor_stacksize 858 #endif // KMP_USE_MONITOR 859 860 // ----------------------------------------------------------------------------- 861 // KMP_SETTINGS 862 863 static void __kmp_stg_parse_settings(char const *name, char const *value, 864 void *data) { 865 __kmp_stg_parse_bool(name, value, &__kmp_settings); 866 } // __kmp_stg_parse_settings 867 868 static void __kmp_stg_print_settings(kmp_str_buf_t *buffer, char const *name, 869 void *data) { 870 __kmp_stg_print_bool(buffer, name, __kmp_settings); 871 } // __kmp_stg_print_settings 872 873 // ----------------------------------------------------------------------------- 874 // KMP_STACKPAD 875 876 static void __kmp_stg_parse_stackpad(char const *name, char const *value, 877 void *data) { 878 __kmp_stg_parse_int(name, // Env var name 879 value, // Env var value 880 KMP_MIN_STKPADDING, // Min value 881 KMP_MAX_STKPADDING, // Max value 882 &__kmp_stkpadding // Var to initialize 883 ); 884 } // __kmp_stg_parse_stackpad 885 886 static void __kmp_stg_print_stackpad(kmp_str_buf_t *buffer, char const *name, 887 void *data) { 888 __kmp_stg_print_int(buffer, name, __kmp_stkpadding); 889 } // __kmp_stg_print_stackpad 890 891 // ----------------------------------------------------------------------------- 892 // KMP_STACKOFFSET 893 894 static void __kmp_stg_parse_stackoffset(char const *name, char const *value, 895 void *data) { 896 __kmp_stg_parse_size(name, // Env var name 897 value, // Env var value 898 KMP_MIN_STKOFFSET, // Min value 899 KMP_MAX_STKOFFSET, // Max value 900 NULL, // 901 &__kmp_stkoffset, // Var to initialize 902 1); 903 } // __kmp_stg_parse_stackoffset 904 905 static void __kmp_stg_print_stackoffset(kmp_str_buf_t *buffer, char const *name, 906 void *data) { 907 __kmp_stg_print_size(buffer, name, __kmp_stkoffset); 908 } // __kmp_stg_print_stackoffset 909 910 // ----------------------------------------------------------------------------- 911 // KMP_STACKSIZE, OMP_STACKSIZE, GOMP_STACKSIZE 912 913 static void __kmp_stg_parse_stacksize(char const *name, char const *value, 914 void *data) { 915 916 kmp_stg_ss_data_t *stacksize = (kmp_stg_ss_data_t *)data; 917 int rc; 918 919 rc = __kmp_stg_check_rivals(name, value, stacksize->rivals); 920 if (rc) { 921 return; 922 } 923 __kmp_stg_parse_size(name, // Env var name 924 value, // Env var value 925 __kmp_sys_min_stksize, // Min value 926 KMP_MAX_STKSIZE, // Max value 927 &__kmp_env_stksize, // 928 &__kmp_stksize, // Var to initialize 929 stacksize->factor); 930 931 } // __kmp_stg_parse_stacksize 932 933 // This function is called for printing both KMP_STACKSIZE (factor is 1) and 934 // OMP_STACKSIZE (factor is 1024). Currently it is not possible to print 935 // OMP_STACKSIZE value in bytes. We can consider adding this possibility by a 936 // customer request in future. 937 static void __kmp_stg_print_stacksize(kmp_str_buf_t *buffer, char const *name, 938 void *data) { 939 kmp_stg_ss_data_t *stacksize = (kmp_stg_ss_data_t *)data; 940 if (__kmp_env_format) { 941 KMP_STR_BUF_PRINT_NAME_EX(name); 942 __kmp_str_buf_print_size(buffer, (__kmp_stksize % 1024) 943 ? __kmp_stksize / stacksize->factor 944 : __kmp_stksize); 945 __kmp_str_buf_print(buffer, "'\n"); 946 } else { 947 __kmp_str_buf_print(buffer, " %s=", name); 948 __kmp_str_buf_print_size(buffer, (__kmp_stksize % 1024) 949 ? __kmp_stksize / stacksize->factor 950 : __kmp_stksize); 951 __kmp_str_buf_print(buffer, "\n"); 952 } 953 } // __kmp_stg_print_stacksize 954 955 // ----------------------------------------------------------------------------- 956 // KMP_VERSION 957 958 static void __kmp_stg_parse_version(char const *name, char const *value, 959 void *data) { 960 __kmp_stg_parse_bool(name, value, &__kmp_version); 961 } // __kmp_stg_parse_version 962 963 static void __kmp_stg_print_version(kmp_str_buf_t *buffer, char const *name, 964 void *data) { 965 __kmp_stg_print_bool(buffer, name, __kmp_version); 966 } // __kmp_stg_print_version 967 968 // ----------------------------------------------------------------------------- 969 // KMP_WARNINGS 970 971 static void __kmp_stg_parse_warnings(char const *name, char const *value, 972 void *data) { 973 __kmp_stg_parse_bool(name, value, &__kmp_generate_warnings); 974 if (__kmp_generate_warnings != kmp_warnings_off) { 975 // AC: only 0/1 values documented, so reset to explicit to distinguish from 976 // default setting 977 __kmp_generate_warnings = kmp_warnings_explicit; 978 } 979 } // __kmp_stg_parse_warnings 980 981 static void __kmp_stg_print_warnings(kmp_str_buf_t *buffer, char const *name, 982 void *data) { 983 // AC: TODO: change to print_int? (needs documentation change) 984 __kmp_stg_print_bool(buffer, name, __kmp_generate_warnings); 985 } // __kmp_stg_print_warnings 986 987 // ----------------------------------------------------------------------------- 988 // OMP_NESTED, OMP_NUM_THREADS 989 990 static void __kmp_stg_parse_nested(char const *name, char const *value, 991 void *data) { 992 int nested; 993 KMP_INFORM(EnvVarDeprecated, name, "OMP_MAX_ACTIVE_LEVELS"); 994 __kmp_stg_parse_bool(name, value, &nested); 995 if (nested) { 996 if (!__kmp_dflt_max_active_levels_set) 997 __kmp_dflt_max_active_levels = KMP_MAX_ACTIVE_LEVELS_LIMIT; 998 } else { // nesting explicitly turned off 999 __kmp_dflt_max_active_levels = 1; 1000 __kmp_dflt_max_active_levels_set = true; 1001 } 1002 } // __kmp_stg_parse_nested 1003 1004 static void __kmp_stg_print_nested(kmp_str_buf_t *buffer, char const *name, 1005 void *data) { 1006 if (__kmp_env_format) { 1007 KMP_STR_BUF_PRINT_NAME; 1008 } else { 1009 __kmp_str_buf_print(buffer, " %s", name); 1010 } 1011 __kmp_str_buf_print(buffer, ": deprecated; max-active-levels-var=%d\n", 1012 __kmp_dflt_max_active_levels); 1013 } // __kmp_stg_print_nested 1014 1015 static void __kmp_parse_nested_num_threads(const char *var, const char *env, 1016 kmp_nested_nthreads_t *nth_array) { 1017 const char *next = env; 1018 const char *scan = next; 1019 1020 int total = 0; // Count elements that were set. It'll be used as an array size 1021 int prev_comma = FALSE; // For correct processing sequential commas 1022 1023 // Count the number of values in the env. var string 1024 for (;;) { 1025 SKIP_WS(next); 1026 1027 if (*next == '\0') { 1028 break; 1029 } 1030 // Next character is not an integer or not a comma => end of list 1031 if (((*next < '0') || (*next > '9')) && (*next != ',')) { 1032 KMP_WARNING(NthSyntaxError, var, env); 1033 return; 1034 } 1035 // The next character is ',' 1036 if (*next == ',') { 1037 // ',' is the fisrt character 1038 if (total == 0 || prev_comma) { 1039 total++; 1040 } 1041 prev_comma = TRUE; 1042 next++; // skip ',' 1043 SKIP_WS(next); 1044 } 1045 // Next character is a digit 1046 if (*next >= '0' && *next <= '9') { 1047 prev_comma = FALSE; 1048 SKIP_DIGITS(next); 1049 total++; 1050 const char *tmp = next; 1051 SKIP_WS(tmp); 1052 if ((*next == ' ' || *next == '\t') && (*tmp >= '0' && *tmp <= '9')) { 1053 KMP_WARNING(NthSpacesNotAllowed, var, env); 1054 return; 1055 } 1056 } 1057 } 1058 if (!__kmp_dflt_max_active_levels_set && total > 1) 1059 __kmp_dflt_max_active_levels = KMP_MAX_ACTIVE_LEVELS_LIMIT; 1060 KMP_DEBUG_ASSERT(total > 0); 1061 if (total <= 0) { 1062 KMP_WARNING(NthSyntaxError, var, env); 1063 return; 1064 } 1065 1066 // Check if the nested nthreads array exists 1067 if (!nth_array->nth) { 1068 // Allocate an array of double size 1069 nth_array->nth = (int *)KMP_INTERNAL_MALLOC(sizeof(int) * total * 2); 1070 if (nth_array->nth == NULL) { 1071 KMP_FATAL(MemoryAllocFailed); 1072 } 1073 nth_array->size = total * 2; 1074 } else { 1075 if (nth_array->size < total) { 1076 // Increase the array size 1077 do { 1078 nth_array->size *= 2; 1079 } while (nth_array->size < total); 1080 1081 nth_array->nth = (int *)KMP_INTERNAL_REALLOC( 1082 nth_array->nth, sizeof(int) * nth_array->size); 1083 if (nth_array->nth == NULL) { 1084 KMP_FATAL(MemoryAllocFailed); 1085 } 1086 } 1087 } 1088 nth_array->used = total; 1089 int i = 0; 1090 1091 prev_comma = FALSE; 1092 total = 0; 1093 // Save values in the array 1094 for (;;) { 1095 SKIP_WS(scan); 1096 if (*scan == '\0') { 1097 break; 1098 } 1099 // The next character is ',' 1100 if (*scan == ',') { 1101 // ',' in the beginning of the list 1102 if (total == 0) { 1103 // The value is supposed to be equal to __kmp_avail_proc but it is 1104 // unknown at the moment. 1105 // So let's put a placeholder (#threads = 0) to correct it later. 1106 nth_array->nth[i++] = 0; 1107 total++; 1108 } else if (prev_comma) { 1109 // Num threads is inherited from the previous level 1110 nth_array->nth[i] = nth_array->nth[i - 1]; 1111 i++; 1112 total++; 1113 } 1114 prev_comma = TRUE; 1115 scan++; // skip ',' 1116 SKIP_WS(scan); 1117 } 1118 // Next character is a digit 1119 if (*scan >= '0' && *scan <= '9') { 1120 int num; 1121 const char *buf = scan; 1122 char const *msg = NULL; 1123 prev_comma = FALSE; 1124 SKIP_DIGITS(scan); 1125 total++; 1126 1127 num = __kmp_str_to_int(buf, *scan); 1128 if (num < KMP_MIN_NTH) { 1129 msg = KMP_I18N_STR(ValueTooSmall); 1130 num = KMP_MIN_NTH; 1131 } else if (num > __kmp_sys_max_nth) { 1132 msg = KMP_I18N_STR(ValueTooLarge); 1133 num = __kmp_sys_max_nth; 1134 } 1135 if (msg != NULL) { 1136 // Message is not empty. Print warning. 1137 KMP_WARNING(ParseSizeIntWarn, var, env, msg); 1138 KMP_INFORM(Using_int_Value, var, num); 1139 } 1140 nth_array->nth[i++] = num; 1141 } 1142 } 1143 } 1144 1145 static void __kmp_stg_parse_num_threads(char const *name, char const *value, 1146 void *data) { 1147 // TODO: Remove this option. OMP_NUM_THREADS is a list of positive integers! 1148 if (!__kmp_strcasecmp_with_sentinel("all", value, 0)) { 1149 // The array of 1 element 1150 __kmp_nested_nth.nth = (int *)KMP_INTERNAL_MALLOC(sizeof(int)); 1151 __kmp_nested_nth.size = __kmp_nested_nth.used = 1; 1152 __kmp_nested_nth.nth[0] = __kmp_dflt_team_nth = __kmp_dflt_team_nth_ub = 1153 __kmp_xproc; 1154 } else { 1155 __kmp_parse_nested_num_threads(name, value, &__kmp_nested_nth); 1156 if (__kmp_nested_nth.nth) { 1157 __kmp_dflt_team_nth = __kmp_nested_nth.nth[0]; 1158 if (__kmp_dflt_team_nth_ub < __kmp_dflt_team_nth) { 1159 __kmp_dflt_team_nth_ub = __kmp_dflt_team_nth; 1160 } 1161 } 1162 } 1163 K_DIAG(1, ("__kmp_dflt_team_nth == %d\n", __kmp_dflt_team_nth)); 1164 } // __kmp_stg_parse_num_threads 1165 1166 static void __kmp_stg_print_num_threads(kmp_str_buf_t *buffer, char const *name, 1167 void *data) { 1168 if (__kmp_env_format) { 1169 KMP_STR_BUF_PRINT_NAME; 1170 } else { 1171 __kmp_str_buf_print(buffer, " %s", name); 1172 } 1173 if (__kmp_nested_nth.used) { 1174 kmp_str_buf_t buf; 1175 __kmp_str_buf_init(&buf); 1176 for (int i = 0; i < __kmp_nested_nth.used; i++) { 1177 __kmp_str_buf_print(&buf, "%d", __kmp_nested_nth.nth[i]); 1178 if (i < __kmp_nested_nth.used - 1) { 1179 __kmp_str_buf_print(&buf, ","); 1180 } 1181 } 1182 __kmp_str_buf_print(buffer, "='%s'\n", buf.str); 1183 __kmp_str_buf_free(&buf); 1184 } else { 1185 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined)); 1186 } 1187 } // __kmp_stg_print_num_threads 1188 1189 // ----------------------------------------------------------------------------- 1190 // OpenMP 3.0: KMP_TASKING, OMP_MAX_ACTIVE_LEVELS, 1191 1192 static void __kmp_stg_parse_tasking(char const *name, char const *value, 1193 void *data) { 1194 __kmp_stg_parse_int(name, value, 0, (int)tskm_max, 1195 (int *)&__kmp_tasking_mode); 1196 } // __kmp_stg_parse_tasking 1197 1198 static void __kmp_stg_print_tasking(kmp_str_buf_t *buffer, char const *name, 1199 void *data) { 1200 __kmp_stg_print_int(buffer, name, __kmp_tasking_mode); 1201 } // __kmp_stg_print_tasking 1202 1203 static void __kmp_stg_parse_task_stealing(char const *name, char const *value, 1204 void *data) { 1205 __kmp_stg_parse_int(name, value, 0, 1, 1206 (int *)&__kmp_task_stealing_constraint); 1207 } // __kmp_stg_parse_task_stealing 1208 1209 static void __kmp_stg_print_task_stealing(kmp_str_buf_t *buffer, 1210 char const *name, void *data) { 1211 __kmp_stg_print_int(buffer, name, __kmp_task_stealing_constraint); 1212 } // __kmp_stg_print_task_stealing 1213 1214 static void __kmp_stg_parse_max_active_levels(char const *name, 1215 char const *value, void *data) { 1216 kmp_uint64 tmp_dflt = 0; 1217 char const *msg = NULL; 1218 if (!__kmp_dflt_max_active_levels_set) { 1219 // Don't overwrite __kmp_dflt_max_active_levels if we get an invalid setting 1220 __kmp_str_to_uint(value, &tmp_dflt, &msg); 1221 if (msg != NULL) { // invalid setting; print warning and ignore 1222 KMP_WARNING(ParseSizeIntWarn, name, value, msg); 1223 } else if (tmp_dflt > KMP_MAX_ACTIVE_LEVELS_LIMIT) { 1224 // invalid setting; print warning and ignore 1225 msg = KMP_I18N_STR(ValueTooLarge); 1226 KMP_WARNING(ParseSizeIntWarn, name, value, msg); 1227 } else { // valid setting 1228 __kmp_dflt_max_active_levels = tmp_dflt; 1229 __kmp_dflt_max_active_levels_set = true; 1230 } 1231 } 1232 } // __kmp_stg_parse_max_active_levels 1233 1234 static void __kmp_stg_print_max_active_levels(kmp_str_buf_t *buffer, 1235 char const *name, void *data) { 1236 __kmp_stg_print_int(buffer, name, __kmp_dflt_max_active_levels); 1237 } // __kmp_stg_print_max_active_levels 1238 1239 #if OMP_40_ENABLED 1240 // ----------------------------------------------------------------------------- 1241 // OpenMP 4.0: OMP_DEFAULT_DEVICE 1242 static void __kmp_stg_parse_default_device(char const *name, char const *value, 1243 void *data) { 1244 __kmp_stg_parse_int(name, value, 0, KMP_MAX_DEFAULT_DEVICE_LIMIT, 1245 &__kmp_default_device); 1246 } // __kmp_stg_parse_default_device 1247 1248 static void __kmp_stg_print_default_device(kmp_str_buf_t *buffer, 1249 char const *name, void *data) { 1250 __kmp_stg_print_int(buffer, name, __kmp_default_device); 1251 } // __kmp_stg_print_default_device 1252 #endif 1253 1254 #if OMP_50_ENABLED 1255 // ----------------------------------------------------------------------------- 1256 // OpenMP 5.0: OMP_TARGET_OFFLOAD 1257 static void __kmp_stg_parse_target_offload(char const *name, char const *value, 1258 void *data) { 1259 const char *next = value; 1260 const char *scan = next; 1261 1262 __kmp_target_offload = tgt_default; 1263 SKIP_WS(next); 1264 if (*next == '\0') 1265 return; 1266 scan = next; 1267 if (!__kmp_strcasecmp_with_sentinel("mandatory", scan, 0)) { 1268 __kmp_target_offload = tgt_mandatory; 1269 } else if (!__kmp_strcasecmp_with_sentinel("disabled", scan, 0)) { 1270 __kmp_target_offload = tgt_disabled; 1271 } else if (!__kmp_strcasecmp_with_sentinel("default", scan, 0)) { 1272 __kmp_target_offload = tgt_default; 1273 } else { 1274 KMP_WARNING(SyntaxErrorUsing, name, "DEFAULT"); 1275 } 1276 1277 } // __kmp_stg_parse_target_offload 1278 1279 static void __kmp_stg_print_target_offload(kmp_str_buf_t *buffer, 1280 char const *name, void *data) { 1281 const char *value = NULL; 1282 if (__kmp_target_offload == tgt_default) 1283 value = "DEFAULT"; 1284 else if (__kmp_target_offload == tgt_mandatory) 1285 value = "MANDATORY"; 1286 else if (__kmp_target_offload == tgt_disabled) 1287 value = "DISABLED"; 1288 KMP_DEBUG_ASSERT(value); 1289 if (__kmp_env_format) { 1290 KMP_STR_BUF_PRINT_NAME; 1291 } else { 1292 __kmp_str_buf_print(buffer, " %s", name); 1293 } 1294 __kmp_str_buf_print(buffer, "=%s\n", value); 1295 } // __kmp_stg_print_target_offload 1296 #endif 1297 1298 #if OMP_45_ENABLED 1299 // ----------------------------------------------------------------------------- 1300 // OpenMP 4.5: OMP_MAX_TASK_PRIORITY 1301 static void __kmp_stg_parse_max_task_priority(char const *name, 1302 char const *value, void *data) { 1303 __kmp_stg_parse_int(name, value, 0, KMP_MAX_TASK_PRIORITY_LIMIT, 1304 &__kmp_max_task_priority); 1305 } // __kmp_stg_parse_max_task_priority 1306 1307 static void __kmp_stg_print_max_task_priority(kmp_str_buf_t *buffer, 1308 char const *name, void *data) { 1309 __kmp_stg_print_int(buffer, name, __kmp_max_task_priority); 1310 } // __kmp_stg_print_max_task_priority 1311 1312 // KMP_TASKLOOP_MIN_TASKS 1313 // taskloop threashold to switch from recursive to linear tasks creation 1314 static void __kmp_stg_parse_taskloop_min_tasks(char const *name, 1315 char const *value, void *data) { 1316 int tmp; 1317 __kmp_stg_parse_int(name, value, 0, INT_MAX, &tmp); 1318 __kmp_taskloop_min_tasks = tmp; 1319 } // __kmp_stg_parse_taskloop_min_tasks 1320 1321 static void __kmp_stg_print_taskloop_min_tasks(kmp_str_buf_t *buffer, 1322 char const *name, void *data) { 1323 __kmp_stg_print_int(buffer, name, __kmp_taskloop_min_tasks); 1324 } // __kmp_stg_print_taskloop_min_tasks 1325 #endif // OMP_45_ENABLED 1326 1327 // ----------------------------------------------------------------------------- 1328 // KMP_DISP_NUM_BUFFERS 1329 static void __kmp_stg_parse_disp_buffers(char const *name, char const *value, 1330 void *data) { 1331 if (TCR_4(__kmp_init_serial)) { 1332 KMP_WARNING(EnvSerialWarn, name); 1333 return; 1334 } // read value before serial initialization only 1335 __kmp_stg_parse_int(name, value, 1, KMP_MAX_NTH, &__kmp_dispatch_num_buffers); 1336 } // __kmp_stg_parse_disp_buffers 1337 1338 static void __kmp_stg_print_disp_buffers(kmp_str_buf_t *buffer, 1339 char const *name, void *data) { 1340 __kmp_stg_print_int(buffer, name, __kmp_dispatch_num_buffers); 1341 } // __kmp_stg_print_disp_buffers 1342 1343 #if KMP_NESTED_HOT_TEAMS 1344 // ----------------------------------------------------------------------------- 1345 // KMP_HOT_TEAMS_MAX_LEVEL, KMP_HOT_TEAMS_MODE 1346 1347 static void __kmp_stg_parse_hot_teams_level(char const *name, char const *value, 1348 void *data) { 1349 if (TCR_4(__kmp_init_parallel)) { 1350 KMP_WARNING(EnvParallelWarn, name); 1351 return; 1352 } // read value before first parallel only 1353 __kmp_stg_parse_int(name, value, 0, KMP_MAX_ACTIVE_LEVELS_LIMIT, 1354 &__kmp_hot_teams_max_level); 1355 } // __kmp_stg_parse_hot_teams_level 1356 1357 static void __kmp_stg_print_hot_teams_level(kmp_str_buf_t *buffer, 1358 char const *name, void *data) { 1359 __kmp_stg_print_int(buffer, name, __kmp_hot_teams_max_level); 1360 } // __kmp_stg_print_hot_teams_level 1361 1362 static void __kmp_stg_parse_hot_teams_mode(char const *name, char const *value, 1363 void *data) { 1364 if (TCR_4(__kmp_init_parallel)) { 1365 KMP_WARNING(EnvParallelWarn, name); 1366 return; 1367 } // read value before first parallel only 1368 __kmp_stg_parse_int(name, value, 0, KMP_MAX_ACTIVE_LEVELS_LIMIT, 1369 &__kmp_hot_teams_mode); 1370 } // __kmp_stg_parse_hot_teams_mode 1371 1372 static void __kmp_stg_print_hot_teams_mode(kmp_str_buf_t *buffer, 1373 char const *name, void *data) { 1374 __kmp_stg_print_int(buffer, name, __kmp_hot_teams_mode); 1375 } // __kmp_stg_print_hot_teams_mode 1376 1377 #endif // KMP_NESTED_HOT_TEAMS 1378 1379 // ----------------------------------------------------------------------------- 1380 // KMP_HANDLE_SIGNALS 1381 1382 #if KMP_HANDLE_SIGNALS 1383 1384 static void __kmp_stg_parse_handle_signals(char const *name, char const *value, 1385 void *data) { 1386 __kmp_stg_parse_bool(name, value, &__kmp_handle_signals); 1387 } // __kmp_stg_parse_handle_signals 1388 1389 static void __kmp_stg_print_handle_signals(kmp_str_buf_t *buffer, 1390 char const *name, void *data) { 1391 __kmp_stg_print_bool(buffer, name, __kmp_handle_signals); 1392 } // __kmp_stg_print_handle_signals 1393 1394 #endif // KMP_HANDLE_SIGNALS 1395 1396 // ----------------------------------------------------------------------------- 1397 // KMP_X_DEBUG, KMP_DEBUG, KMP_DEBUG_BUF_*, KMP_DIAG 1398 1399 #ifdef KMP_DEBUG 1400 1401 #define KMP_STG_X_DEBUG(x) \ 1402 static void __kmp_stg_parse_##x##_debug(char const *name, char const *value, \ 1403 void *data) { \ 1404 __kmp_stg_parse_int(name, value, 0, INT_MAX, &kmp_##x##_debug); \ 1405 } /* __kmp_stg_parse_x_debug */ \ 1406 static void __kmp_stg_print_##x##_debug(kmp_str_buf_t *buffer, \ 1407 char const *name, void *data) { \ 1408 __kmp_stg_print_int(buffer, name, kmp_##x##_debug); \ 1409 } /* __kmp_stg_print_x_debug */ 1410 1411 KMP_STG_X_DEBUG(a) 1412 KMP_STG_X_DEBUG(b) 1413 KMP_STG_X_DEBUG(c) 1414 KMP_STG_X_DEBUG(d) 1415 KMP_STG_X_DEBUG(e) 1416 KMP_STG_X_DEBUG(f) 1417 1418 #undef KMP_STG_X_DEBUG 1419 1420 static void __kmp_stg_parse_debug(char const *name, char const *value, 1421 void *data) { 1422 int debug = 0; 1423 __kmp_stg_parse_int(name, value, 0, INT_MAX, &debug); 1424 if (kmp_a_debug < debug) { 1425 kmp_a_debug = debug; 1426 } 1427 if (kmp_b_debug < debug) { 1428 kmp_b_debug = debug; 1429 } 1430 if (kmp_c_debug < debug) { 1431 kmp_c_debug = debug; 1432 } 1433 if (kmp_d_debug < debug) { 1434 kmp_d_debug = debug; 1435 } 1436 if (kmp_e_debug < debug) { 1437 kmp_e_debug = debug; 1438 } 1439 if (kmp_f_debug < debug) { 1440 kmp_f_debug = debug; 1441 } 1442 } // __kmp_stg_parse_debug 1443 1444 static void __kmp_stg_parse_debug_buf(char const *name, char const *value, 1445 void *data) { 1446 __kmp_stg_parse_bool(name, value, &__kmp_debug_buf); 1447 // !!! TODO: Move buffer initialization of of this file! It may works 1448 // incorrectly if KMP_DEBUG_BUF is parsed before KMP_DEBUG_BUF_LINES or 1449 // KMP_DEBUG_BUF_CHARS. 1450 if (__kmp_debug_buf) { 1451 int i; 1452 int elements = __kmp_debug_buf_lines * __kmp_debug_buf_chars; 1453 1454 /* allocate and initialize all entries in debug buffer to empty */ 1455 __kmp_debug_buffer = (char *)__kmp_page_allocate(elements * sizeof(char)); 1456 for (i = 0; i < elements; i += __kmp_debug_buf_chars) 1457 __kmp_debug_buffer[i] = '\0'; 1458 1459 __kmp_debug_count = 0; 1460 } 1461 K_DIAG(1, ("__kmp_debug_buf = %d\n", __kmp_debug_buf)); 1462 } // __kmp_stg_parse_debug_buf 1463 1464 static void __kmp_stg_print_debug_buf(kmp_str_buf_t *buffer, char const *name, 1465 void *data) { 1466 __kmp_stg_print_bool(buffer, name, __kmp_debug_buf); 1467 } // __kmp_stg_print_debug_buf 1468 1469 static void __kmp_stg_parse_debug_buf_atomic(char const *name, 1470 char const *value, void *data) { 1471 __kmp_stg_parse_bool(name, value, &__kmp_debug_buf_atomic); 1472 } // __kmp_stg_parse_debug_buf_atomic 1473 1474 static void __kmp_stg_print_debug_buf_atomic(kmp_str_buf_t *buffer, 1475 char const *name, void *data) { 1476 __kmp_stg_print_bool(buffer, name, __kmp_debug_buf_atomic); 1477 } // __kmp_stg_print_debug_buf_atomic 1478 1479 static void __kmp_stg_parse_debug_buf_chars(char const *name, char const *value, 1480 void *data) { 1481 __kmp_stg_parse_int(name, value, KMP_DEBUG_BUF_CHARS_MIN, INT_MAX, 1482 &__kmp_debug_buf_chars); 1483 } // __kmp_stg_debug_parse_buf_chars 1484 1485 static void __kmp_stg_print_debug_buf_chars(kmp_str_buf_t *buffer, 1486 char const *name, void *data) { 1487 __kmp_stg_print_int(buffer, name, __kmp_debug_buf_chars); 1488 } // __kmp_stg_print_debug_buf_chars 1489 1490 static void __kmp_stg_parse_debug_buf_lines(char const *name, char const *value, 1491 void *data) { 1492 __kmp_stg_parse_int(name, value, KMP_DEBUG_BUF_LINES_MIN, INT_MAX, 1493 &__kmp_debug_buf_lines); 1494 } // __kmp_stg_parse_debug_buf_lines 1495 1496 static void __kmp_stg_print_debug_buf_lines(kmp_str_buf_t *buffer, 1497 char const *name, void *data) { 1498 __kmp_stg_print_int(buffer, name, __kmp_debug_buf_lines); 1499 } // __kmp_stg_print_debug_buf_lines 1500 1501 static void __kmp_stg_parse_diag(char const *name, char const *value, 1502 void *data) { 1503 __kmp_stg_parse_int(name, value, 0, INT_MAX, &kmp_diag); 1504 } // __kmp_stg_parse_diag 1505 1506 static void __kmp_stg_print_diag(kmp_str_buf_t *buffer, char const *name, 1507 void *data) { 1508 __kmp_stg_print_int(buffer, name, kmp_diag); 1509 } // __kmp_stg_print_diag 1510 1511 #endif // KMP_DEBUG 1512 1513 // ----------------------------------------------------------------------------- 1514 // KMP_ALIGN_ALLOC 1515 1516 static void __kmp_stg_parse_align_alloc(char const *name, char const *value, 1517 void *data) { 1518 __kmp_stg_parse_size(name, value, CACHE_LINE, INT_MAX, NULL, 1519 &__kmp_align_alloc, 1); 1520 } // __kmp_stg_parse_align_alloc 1521 1522 static void __kmp_stg_print_align_alloc(kmp_str_buf_t *buffer, char const *name, 1523 void *data) { 1524 __kmp_stg_print_size(buffer, name, __kmp_align_alloc); 1525 } // __kmp_stg_print_align_alloc 1526 1527 // ----------------------------------------------------------------------------- 1528 // KMP_PLAIN_BARRIER, KMP_FORKJOIN_BARRIER, KMP_REDUCTION_BARRIER 1529 1530 // TODO: Remove __kmp_barrier_branch_bit_env_name varibale, remove loops from 1531 // parse and print functions, pass required info through data argument. 1532 1533 static void __kmp_stg_parse_barrier_branch_bit(char const *name, 1534 char const *value, void *data) { 1535 const char *var; 1536 1537 /* ---------- Barrier branch bit control ------------ */ 1538 for (int i = bs_plain_barrier; i < bs_last_barrier; i++) { 1539 var = __kmp_barrier_branch_bit_env_name[i]; 1540 if ((strcmp(var, name) == 0) && (value != 0)) { 1541 char *comma; 1542 1543 comma = CCAST(char *, strchr(value, ',')); 1544 __kmp_barrier_gather_branch_bits[i] = 1545 (kmp_uint32)__kmp_str_to_int(value, ','); 1546 /* is there a specified release parameter? */ 1547 if (comma == NULL) { 1548 __kmp_barrier_release_branch_bits[i] = __kmp_barrier_release_bb_dflt; 1549 } else { 1550 __kmp_barrier_release_branch_bits[i] = 1551 (kmp_uint32)__kmp_str_to_int(comma + 1, 0); 1552 1553 if (__kmp_barrier_release_branch_bits[i] > KMP_MAX_BRANCH_BITS) { 1554 __kmp_msg(kmp_ms_warning, 1555 KMP_MSG(BarrReleaseValueInvalid, name, comma + 1), 1556 __kmp_msg_null); 1557 __kmp_barrier_release_branch_bits[i] = __kmp_barrier_release_bb_dflt; 1558 } 1559 } 1560 if (__kmp_barrier_gather_branch_bits[i] > KMP_MAX_BRANCH_BITS) { 1561 KMP_WARNING(BarrGatherValueInvalid, name, value); 1562 KMP_INFORM(Using_uint_Value, name, __kmp_barrier_gather_bb_dflt); 1563 __kmp_barrier_gather_branch_bits[i] = __kmp_barrier_gather_bb_dflt; 1564 } 1565 } 1566 K_DIAG(1, ("%s == %d,%d\n", __kmp_barrier_branch_bit_env_name[i], 1567 __kmp_barrier_gather_branch_bits[i], 1568 __kmp_barrier_release_branch_bits[i])) 1569 } 1570 } // __kmp_stg_parse_barrier_branch_bit 1571 1572 static void __kmp_stg_print_barrier_branch_bit(kmp_str_buf_t *buffer, 1573 char const *name, void *data) { 1574 const char *var; 1575 for (int i = bs_plain_barrier; i < bs_last_barrier; i++) { 1576 var = __kmp_barrier_branch_bit_env_name[i]; 1577 if (strcmp(var, name) == 0) { 1578 if (__kmp_env_format) { 1579 KMP_STR_BUF_PRINT_NAME_EX(__kmp_barrier_branch_bit_env_name[i]); 1580 } else { 1581 __kmp_str_buf_print(buffer, " %s='", 1582 __kmp_barrier_branch_bit_env_name[i]); 1583 } 1584 __kmp_str_buf_print(buffer, "%d,%d'\n", 1585 __kmp_barrier_gather_branch_bits[i], 1586 __kmp_barrier_release_branch_bits[i]); 1587 } 1588 } 1589 } // __kmp_stg_print_barrier_branch_bit 1590 1591 // ---------------------------------------------------------------------------- 1592 // KMP_PLAIN_BARRIER_PATTERN, KMP_FORKJOIN_BARRIER_PATTERN, 1593 // KMP_REDUCTION_BARRIER_PATTERN 1594 1595 // TODO: Remove __kmp_barrier_pattern_name variable, remove loops from parse and 1596 // print functions, pass required data to functions through data argument. 1597 1598 static void __kmp_stg_parse_barrier_pattern(char const *name, char const *value, 1599 void *data) { 1600 const char *var; 1601 /* ---------- Barrier method control ------------ */ 1602 1603 for (int i = bs_plain_barrier; i < bs_last_barrier; i++) { 1604 var = __kmp_barrier_pattern_env_name[i]; 1605 1606 if ((strcmp(var, name) == 0) && (value != 0)) { 1607 int j; 1608 char *comma = CCAST(char *, strchr(value, ',')); 1609 1610 /* handle first parameter: gather pattern */ 1611 for (j = bp_linear_bar; j < bp_last_bar; j++) { 1612 if (__kmp_match_with_sentinel(__kmp_barrier_pattern_name[j], value, 1, 1613 ',')) { 1614 __kmp_barrier_gather_pattern[i] = (kmp_bar_pat_e)j; 1615 break; 1616 } 1617 } 1618 if (j == bp_last_bar) { 1619 KMP_WARNING(BarrGatherValueInvalid, name, value); 1620 KMP_INFORM(Using_str_Value, name, 1621 __kmp_barrier_pattern_name[bp_linear_bar]); 1622 } 1623 1624 /* handle second parameter: release pattern */ 1625 if (comma != NULL) { 1626 for (j = bp_linear_bar; j < bp_last_bar; j++) { 1627 if (__kmp_str_match(__kmp_barrier_pattern_name[j], 1, comma + 1)) { 1628 __kmp_barrier_release_pattern[i] = (kmp_bar_pat_e)j; 1629 break; 1630 } 1631 } 1632 if (j == bp_last_bar) { 1633 __kmp_msg(kmp_ms_warning, 1634 KMP_MSG(BarrReleaseValueInvalid, name, comma + 1), 1635 __kmp_msg_null); 1636 KMP_INFORM(Using_str_Value, name, 1637 __kmp_barrier_pattern_name[bp_linear_bar]); 1638 } 1639 } 1640 } 1641 } 1642 } // __kmp_stg_parse_barrier_pattern 1643 1644 static void __kmp_stg_print_barrier_pattern(kmp_str_buf_t *buffer, 1645 char const *name, void *data) { 1646 const char *var; 1647 for (int i = bs_plain_barrier; i < bs_last_barrier; i++) { 1648 var = __kmp_barrier_pattern_env_name[i]; 1649 if (strcmp(var, name) == 0) { 1650 int j = __kmp_barrier_gather_pattern[i]; 1651 int k = __kmp_barrier_release_pattern[i]; 1652 if (__kmp_env_format) { 1653 KMP_STR_BUF_PRINT_NAME_EX(__kmp_barrier_pattern_env_name[i]); 1654 } else { 1655 __kmp_str_buf_print(buffer, " %s='", 1656 __kmp_barrier_pattern_env_name[i]); 1657 } 1658 __kmp_str_buf_print(buffer, "%s,%s'\n", __kmp_barrier_pattern_name[j], 1659 __kmp_barrier_pattern_name[k]); 1660 } 1661 } 1662 } // __kmp_stg_print_barrier_pattern 1663 1664 // ----------------------------------------------------------------------------- 1665 // KMP_ABORT_DELAY 1666 1667 static void __kmp_stg_parse_abort_delay(char const *name, char const *value, 1668 void *data) { 1669 // Units of KMP_DELAY_ABORT are seconds, units of __kmp_abort_delay is 1670 // milliseconds. 1671 int delay = __kmp_abort_delay / 1000; 1672 __kmp_stg_parse_int(name, value, 0, INT_MAX / 1000, &delay); 1673 __kmp_abort_delay = delay * 1000; 1674 } // __kmp_stg_parse_abort_delay 1675 1676 static void __kmp_stg_print_abort_delay(kmp_str_buf_t *buffer, char const *name, 1677 void *data) { 1678 __kmp_stg_print_int(buffer, name, __kmp_abort_delay); 1679 } // __kmp_stg_print_abort_delay 1680 1681 // ----------------------------------------------------------------------------- 1682 // KMP_CPUINFO_FILE 1683 1684 static void __kmp_stg_parse_cpuinfo_file(char const *name, char const *value, 1685 void *data) { 1686 #if KMP_AFFINITY_SUPPORTED 1687 __kmp_stg_parse_str(name, value, &__kmp_cpuinfo_file); 1688 K_DIAG(1, ("__kmp_cpuinfo_file == %s\n", __kmp_cpuinfo_file)); 1689 #endif 1690 } //__kmp_stg_parse_cpuinfo_file 1691 1692 static void __kmp_stg_print_cpuinfo_file(kmp_str_buf_t *buffer, 1693 char const *name, void *data) { 1694 #if KMP_AFFINITY_SUPPORTED 1695 if (__kmp_env_format) { 1696 KMP_STR_BUF_PRINT_NAME; 1697 } else { 1698 __kmp_str_buf_print(buffer, " %s", name); 1699 } 1700 if (__kmp_cpuinfo_file) { 1701 __kmp_str_buf_print(buffer, "='%s'\n", __kmp_cpuinfo_file); 1702 } else { 1703 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined)); 1704 } 1705 #endif 1706 } //__kmp_stg_print_cpuinfo_file 1707 1708 // ----------------------------------------------------------------------------- 1709 // KMP_FORCE_REDUCTION, KMP_DETERMINISTIC_REDUCTION 1710 1711 static void __kmp_stg_parse_force_reduction(char const *name, char const *value, 1712 void *data) { 1713 kmp_stg_fr_data_t *reduction = (kmp_stg_fr_data_t *)data; 1714 int rc; 1715 1716 rc = __kmp_stg_check_rivals(name, value, reduction->rivals); 1717 if (rc) { 1718 return; 1719 } 1720 if (reduction->force) { 1721 if (value != 0) { 1722 if (__kmp_str_match("critical", 0, value)) 1723 __kmp_force_reduction_method = critical_reduce_block; 1724 else if (__kmp_str_match("atomic", 0, value)) 1725 __kmp_force_reduction_method = atomic_reduce_block; 1726 else if (__kmp_str_match("tree", 0, value)) 1727 __kmp_force_reduction_method = tree_reduce_block; 1728 else { 1729 KMP_FATAL(UnknownForceReduction, name, value); 1730 } 1731 } 1732 } else { 1733 __kmp_stg_parse_bool(name, value, &__kmp_determ_red); 1734 if (__kmp_determ_red) { 1735 __kmp_force_reduction_method = tree_reduce_block; 1736 } else { 1737 __kmp_force_reduction_method = reduction_method_not_defined; 1738 } 1739 } 1740 K_DIAG(1, ("__kmp_force_reduction_method == %d\n", 1741 __kmp_force_reduction_method)); 1742 } // __kmp_stg_parse_force_reduction 1743 1744 static void __kmp_stg_print_force_reduction(kmp_str_buf_t *buffer, 1745 char const *name, void *data) { 1746 1747 kmp_stg_fr_data_t *reduction = (kmp_stg_fr_data_t *)data; 1748 if (reduction->force) { 1749 if (__kmp_force_reduction_method == critical_reduce_block) { 1750 __kmp_stg_print_str(buffer, name, "critical"); 1751 } else if (__kmp_force_reduction_method == atomic_reduce_block) { 1752 __kmp_stg_print_str(buffer, name, "atomic"); 1753 } else if (__kmp_force_reduction_method == tree_reduce_block) { 1754 __kmp_stg_print_str(buffer, name, "tree"); 1755 } else { 1756 if (__kmp_env_format) { 1757 KMP_STR_BUF_PRINT_NAME; 1758 } else { 1759 __kmp_str_buf_print(buffer, " %s", name); 1760 } 1761 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined)); 1762 } 1763 } else { 1764 __kmp_stg_print_bool(buffer, name, __kmp_determ_red); 1765 } 1766 1767 } // __kmp_stg_print_force_reduction 1768 1769 // ----------------------------------------------------------------------------- 1770 // KMP_STORAGE_MAP 1771 1772 static void __kmp_stg_parse_storage_map(char const *name, char const *value, 1773 void *data) { 1774 if (__kmp_str_match("verbose", 1, value)) { 1775 __kmp_storage_map = TRUE; 1776 __kmp_storage_map_verbose = TRUE; 1777 __kmp_storage_map_verbose_specified = TRUE; 1778 1779 } else { 1780 __kmp_storage_map_verbose = FALSE; 1781 __kmp_stg_parse_bool(name, value, &__kmp_storage_map); // !!! 1782 } 1783 } // __kmp_stg_parse_storage_map 1784 1785 static void __kmp_stg_print_storage_map(kmp_str_buf_t *buffer, char const *name, 1786 void *data) { 1787 if (__kmp_storage_map_verbose || __kmp_storage_map_verbose_specified) { 1788 __kmp_stg_print_str(buffer, name, "verbose"); 1789 } else { 1790 __kmp_stg_print_bool(buffer, name, __kmp_storage_map); 1791 } 1792 } // __kmp_stg_print_storage_map 1793 1794 // ----------------------------------------------------------------------------- 1795 // KMP_ALL_THREADPRIVATE 1796 1797 static void __kmp_stg_parse_all_threadprivate(char const *name, 1798 char const *value, void *data) { 1799 __kmp_stg_parse_int(name, value, 1800 __kmp_allThreadsSpecified ? __kmp_max_nth : 1, 1801 __kmp_max_nth, &__kmp_tp_capacity); 1802 } // __kmp_stg_parse_all_threadprivate 1803 1804 static void __kmp_stg_print_all_threadprivate(kmp_str_buf_t *buffer, 1805 char const *name, void *data) { 1806 __kmp_stg_print_int(buffer, name, __kmp_tp_capacity); 1807 } 1808 1809 // ----------------------------------------------------------------------------- 1810 // KMP_FOREIGN_THREADS_THREADPRIVATE 1811 1812 static void __kmp_stg_parse_foreign_threads_threadprivate(char const *name, 1813 char const *value, 1814 void *data) { 1815 __kmp_stg_parse_bool(name, value, &__kmp_foreign_tp); 1816 } // __kmp_stg_parse_foreign_threads_threadprivate 1817 1818 static void __kmp_stg_print_foreign_threads_threadprivate(kmp_str_buf_t *buffer, 1819 char const *name, 1820 void *data) { 1821 __kmp_stg_print_bool(buffer, name, __kmp_foreign_tp); 1822 } // __kmp_stg_print_foreign_threads_threadprivate 1823 1824 // ----------------------------------------------------------------------------- 1825 // KMP_AFFINITY, GOMP_CPU_AFFINITY, KMP_TOPOLOGY_METHOD 1826 1827 #if KMP_AFFINITY_SUPPORTED 1828 // Parse the proc id list. Return TRUE if successful, FALSE otherwise. 1829 static int __kmp_parse_affinity_proc_id_list(const char *var, const char *env, 1830 const char **nextEnv, 1831 char **proclist) { 1832 const char *scan = env; 1833 const char *next = scan; 1834 int empty = TRUE; 1835 1836 *proclist = NULL; 1837 1838 for (;;) { 1839 int start, end, stride; 1840 1841 SKIP_WS(scan); 1842 next = scan; 1843 if (*next == '\0') { 1844 break; 1845 } 1846 1847 if (*next == '{') { 1848 int num; 1849 next++; // skip '{' 1850 SKIP_WS(next); 1851 scan = next; 1852 1853 // Read the first integer in the set. 1854 if ((*next < '0') || (*next > '9')) { 1855 KMP_WARNING(AffSyntaxError, var); 1856 return FALSE; 1857 } 1858 SKIP_DIGITS(next); 1859 num = __kmp_str_to_int(scan, *next); 1860 KMP_ASSERT(num >= 0); 1861 1862 for (;;) { 1863 // Check for end of set. 1864 SKIP_WS(next); 1865 if (*next == '}') { 1866 next++; // skip '}' 1867 break; 1868 } 1869 1870 // Skip optional comma. 1871 if (*next == ',') { 1872 next++; 1873 } 1874 SKIP_WS(next); 1875 1876 // Read the next integer in the set. 1877 scan = next; 1878 if ((*next < '0') || (*next > '9')) { 1879 KMP_WARNING(AffSyntaxError, var); 1880 return FALSE; 1881 } 1882 1883 SKIP_DIGITS(next); 1884 num = __kmp_str_to_int(scan, *next); 1885 KMP_ASSERT(num >= 0); 1886 } 1887 empty = FALSE; 1888 1889 SKIP_WS(next); 1890 if (*next == ',') { 1891 next++; 1892 } 1893 scan = next; 1894 continue; 1895 } 1896 1897 // Next character is not an integer => end of list 1898 if ((*next < '0') || (*next > '9')) { 1899 if (empty) { 1900 KMP_WARNING(AffSyntaxError, var); 1901 return FALSE; 1902 } 1903 break; 1904 } 1905 1906 // Read the first integer. 1907 SKIP_DIGITS(next); 1908 start = __kmp_str_to_int(scan, *next); 1909 KMP_ASSERT(start >= 0); 1910 SKIP_WS(next); 1911 1912 // If this isn't a range, then go on. 1913 if (*next != '-') { 1914 empty = FALSE; 1915 1916 // Skip optional comma. 1917 if (*next == ',') { 1918 next++; 1919 } 1920 scan = next; 1921 continue; 1922 } 1923 1924 // This is a range. Skip over the '-' and read in the 2nd int. 1925 next++; // skip '-' 1926 SKIP_WS(next); 1927 scan = next; 1928 if ((*next < '0') || (*next > '9')) { 1929 KMP_WARNING(AffSyntaxError, var); 1930 return FALSE; 1931 } 1932 SKIP_DIGITS(next); 1933 end = __kmp_str_to_int(scan, *next); 1934 KMP_ASSERT(end >= 0); 1935 1936 // Check for a stride parameter 1937 stride = 1; 1938 SKIP_WS(next); 1939 if (*next == ':') { 1940 // A stride is specified. Skip over the ':" and read the 3rd int. 1941 int sign = +1; 1942 next++; // skip ':' 1943 SKIP_WS(next); 1944 scan = next; 1945 if (*next == '-') { 1946 sign = -1; 1947 next++; 1948 SKIP_WS(next); 1949 scan = next; 1950 } 1951 if ((*next < '0') || (*next > '9')) { 1952 KMP_WARNING(AffSyntaxError, var); 1953 return FALSE; 1954 } 1955 SKIP_DIGITS(next); 1956 stride = __kmp_str_to_int(scan, *next); 1957 KMP_ASSERT(stride >= 0); 1958 stride *= sign; 1959 } 1960 1961 // Do some range checks. 1962 if (stride == 0) { 1963 KMP_WARNING(AffZeroStride, var); 1964 return FALSE; 1965 } 1966 if (stride > 0) { 1967 if (start > end) { 1968 KMP_WARNING(AffStartGreaterEnd, var, start, end); 1969 return FALSE; 1970 } 1971 } else { 1972 if (start < end) { 1973 KMP_WARNING(AffStrideLessZero, var, start, end); 1974 return FALSE; 1975 } 1976 } 1977 if ((end - start) / stride > 65536) { 1978 KMP_WARNING(AffRangeTooBig, var, end, start, stride); 1979 return FALSE; 1980 } 1981 1982 empty = FALSE; 1983 1984 // Skip optional comma. 1985 SKIP_WS(next); 1986 if (*next == ',') { 1987 next++; 1988 } 1989 scan = next; 1990 } 1991 1992 *nextEnv = next; 1993 1994 { 1995 int len = next - env; 1996 char *retlist = (char *)__kmp_allocate((len + 1) * sizeof(char)); 1997 KMP_MEMCPY_S(retlist, (len + 1) * sizeof(char), env, len * sizeof(char)); 1998 retlist[len] = '\0'; 1999 *proclist = retlist; 2000 } 2001 return TRUE; 2002 } 2003 2004 // If KMP_AFFINITY is specified without a type, then 2005 // __kmp_affinity_notype should point to its setting. 2006 static kmp_setting_t *__kmp_affinity_notype = NULL; 2007 2008 static void __kmp_parse_affinity_env(char const *name, char const *value, 2009 enum affinity_type *out_type, 2010 char **out_proclist, int *out_verbose, 2011 int *out_warn, int *out_respect, 2012 enum affinity_gran *out_gran, 2013 int *out_gran_levels, int *out_dups, 2014 int *out_compact, int *out_offset) { 2015 char *buffer = NULL; // Copy of env var value. 2016 char *buf = NULL; // Buffer for strtok_r() function. 2017 char *next = NULL; // end of token / start of next. 2018 const char *start; // start of current token (for err msgs) 2019 int count = 0; // Counter of parsed integer numbers. 2020 int number[2]; // Parsed numbers. 2021 2022 // Guards. 2023 int type = 0; 2024 int proclist = 0; 2025 int verbose = 0; 2026 int warnings = 0; 2027 int respect = 0; 2028 int gran = 0; 2029 int dups = 0; 2030 2031 KMP_ASSERT(value != NULL); 2032 2033 if (TCR_4(__kmp_init_middle)) { 2034 KMP_WARNING(EnvMiddleWarn, name); 2035 __kmp_env_toPrint(name, 0); 2036 return; 2037 } 2038 __kmp_env_toPrint(name, 1); 2039 2040 buffer = 2041 __kmp_str_format("%s", value); // Copy env var to keep original intact. 2042 buf = buffer; 2043 SKIP_WS(buf); 2044 2045 // Helper macros. 2046 2047 // If we see a parse error, emit a warning and scan to the next ",". 2048 // 2049 // FIXME - there's got to be a better way to print an error 2050 // message, hopefully without overwritting peices of buf. 2051 #define EMIT_WARN(skip, errlist) \ 2052 { \ 2053 char ch; \ 2054 if (skip) { \ 2055 SKIP_TO(next, ','); \ 2056 } \ 2057 ch = *next; \ 2058 *next = '\0'; \ 2059 KMP_WARNING errlist; \ 2060 *next = ch; \ 2061 if (skip) { \ 2062 if (ch == ',') \ 2063 next++; \ 2064 } \ 2065 buf = next; \ 2066 } 2067 2068 #define _set_param(_guard, _var, _val) \ 2069 { \ 2070 if (_guard == 0) { \ 2071 _var = _val; \ 2072 } else { \ 2073 EMIT_WARN(FALSE, (AffParamDefined, name, start)); \ 2074 } \ 2075 ++_guard; \ 2076 } 2077 2078 #define set_type(val) _set_param(type, *out_type, val) 2079 #define set_verbose(val) _set_param(verbose, *out_verbose, val) 2080 #define set_warnings(val) _set_param(warnings, *out_warn, val) 2081 #define set_respect(val) _set_param(respect, *out_respect, val) 2082 #define set_dups(val) _set_param(dups, *out_dups, val) 2083 #define set_proclist(val) _set_param(proclist, *out_proclist, val) 2084 2085 #define set_gran(val, levels) \ 2086 { \ 2087 if (gran == 0) { \ 2088 *out_gran = val; \ 2089 *out_gran_levels = levels; \ 2090 } else { \ 2091 EMIT_WARN(FALSE, (AffParamDefined, name, start)); \ 2092 } \ 2093 ++gran; \ 2094 } 2095 2096 #if OMP_40_ENABLED 2097 KMP_DEBUG_ASSERT((__kmp_nested_proc_bind.bind_types != NULL) && 2098 (__kmp_nested_proc_bind.used > 0)); 2099 #endif 2100 2101 while (*buf != '\0') { 2102 start = next = buf; 2103 2104 if (__kmp_match_str("none", buf, CCAST(const char **, &next))) { 2105 set_type(affinity_none); 2106 #if OMP_40_ENABLED 2107 __kmp_nested_proc_bind.bind_types[0] = proc_bind_false; 2108 #endif 2109 buf = next; 2110 } else if (__kmp_match_str("scatter", buf, CCAST(const char **, &next))) { 2111 set_type(affinity_scatter); 2112 #if OMP_40_ENABLED 2113 __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel; 2114 #endif 2115 buf = next; 2116 } else if (__kmp_match_str("compact", buf, CCAST(const char **, &next))) { 2117 set_type(affinity_compact); 2118 #if OMP_40_ENABLED 2119 __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel; 2120 #endif 2121 buf = next; 2122 } else if (__kmp_match_str("logical", buf, CCAST(const char **, &next))) { 2123 set_type(affinity_logical); 2124 #if OMP_40_ENABLED 2125 __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel; 2126 #endif 2127 buf = next; 2128 } else if (__kmp_match_str("physical", buf, CCAST(const char **, &next))) { 2129 set_type(affinity_physical); 2130 #if OMP_40_ENABLED 2131 __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel; 2132 #endif 2133 buf = next; 2134 } else if (__kmp_match_str("explicit", buf, CCAST(const char **, &next))) { 2135 set_type(affinity_explicit); 2136 #if OMP_40_ENABLED 2137 __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel; 2138 #endif 2139 buf = next; 2140 } else if (__kmp_match_str("balanced", buf, CCAST(const char **, &next))) { 2141 set_type(affinity_balanced); 2142 #if OMP_40_ENABLED 2143 __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel; 2144 #endif 2145 buf = next; 2146 } else if (__kmp_match_str("disabled", buf, CCAST(const char **, &next))) { 2147 set_type(affinity_disabled); 2148 #if OMP_40_ENABLED 2149 __kmp_nested_proc_bind.bind_types[0] = proc_bind_false; 2150 #endif 2151 buf = next; 2152 } else if (__kmp_match_str("verbose", buf, CCAST(const char **, &next))) { 2153 set_verbose(TRUE); 2154 buf = next; 2155 } else if (__kmp_match_str("noverbose", buf, CCAST(const char **, &next))) { 2156 set_verbose(FALSE); 2157 buf = next; 2158 } else if (__kmp_match_str("warnings", buf, CCAST(const char **, &next))) { 2159 set_warnings(TRUE); 2160 buf = next; 2161 } else if (__kmp_match_str("nowarnings", buf, 2162 CCAST(const char **, &next))) { 2163 set_warnings(FALSE); 2164 buf = next; 2165 } else if (__kmp_match_str("respect", buf, CCAST(const char **, &next))) { 2166 set_respect(TRUE); 2167 buf = next; 2168 } else if (__kmp_match_str("norespect", buf, CCAST(const char **, &next))) { 2169 set_respect(FALSE); 2170 buf = next; 2171 } else if (__kmp_match_str("duplicates", buf, 2172 CCAST(const char **, &next)) || 2173 __kmp_match_str("dups", buf, CCAST(const char **, &next))) { 2174 set_dups(TRUE); 2175 buf = next; 2176 } else if (__kmp_match_str("noduplicates", buf, 2177 CCAST(const char **, &next)) || 2178 __kmp_match_str("nodups", buf, CCAST(const char **, &next))) { 2179 set_dups(FALSE); 2180 buf = next; 2181 } else if (__kmp_match_str("granularity", buf, 2182 CCAST(const char **, &next)) || 2183 __kmp_match_str("gran", buf, CCAST(const char **, &next))) { 2184 SKIP_WS(next); 2185 if (*next != '=') { 2186 EMIT_WARN(TRUE, (AffInvalidParam, name, start)); 2187 continue; 2188 } 2189 next++; // skip '=' 2190 SKIP_WS(next); 2191 2192 buf = next; 2193 if (__kmp_match_str("fine", buf, CCAST(const char **, &next))) { 2194 set_gran(affinity_gran_fine, -1); 2195 buf = next; 2196 } else if (__kmp_match_str("thread", buf, CCAST(const char **, &next))) { 2197 set_gran(affinity_gran_thread, -1); 2198 buf = next; 2199 } else if (__kmp_match_str("core", buf, CCAST(const char **, &next))) { 2200 set_gran(affinity_gran_core, -1); 2201 buf = next; 2202 #if KMP_USE_HWLOC 2203 } else if (__kmp_match_str("tile", buf, CCAST(const char **, &next))) { 2204 set_gran(affinity_gran_tile, -1); 2205 buf = next; 2206 #endif 2207 } else if (__kmp_match_str("package", buf, CCAST(const char **, &next))) { 2208 set_gran(affinity_gran_package, -1); 2209 buf = next; 2210 } else if (__kmp_match_str("node", buf, CCAST(const char **, &next))) { 2211 set_gran(affinity_gran_node, -1); 2212 buf = next; 2213 #if KMP_GROUP_AFFINITY 2214 } else if (__kmp_match_str("group", buf, CCAST(const char **, &next))) { 2215 set_gran(affinity_gran_group, -1); 2216 buf = next; 2217 #endif /* KMP_GROUP AFFINITY */ 2218 } else if ((*buf >= '0') && (*buf <= '9')) { 2219 int n; 2220 next = buf; 2221 SKIP_DIGITS(next); 2222 n = __kmp_str_to_int(buf, *next); 2223 KMP_ASSERT(n >= 0); 2224 buf = next; 2225 set_gran(affinity_gran_default, n); 2226 } else { 2227 EMIT_WARN(TRUE, (AffInvalidParam, name, start)); 2228 continue; 2229 } 2230 } else if (__kmp_match_str("proclist", buf, CCAST(const char **, &next))) { 2231 char *temp_proclist; 2232 2233 SKIP_WS(next); 2234 if (*next != '=') { 2235 EMIT_WARN(TRUE, (AffInvalidParam, name, start)); 2236 continue; 2237 } 2238 next++; // skip '=' 2239 SKIP_WS(next); 2240 if (*next != '[') { 2241 EMIT_WARN(TRUE, (AffInvalidParam, name, start)); 2242 continue; 2243 } 2244 next++; // skip '[' 2245 buf = next; 2246 if (!__kmp_parse_affinity_proc_id_list( 2247 name, buf, CCAST(const char **, &next), &temp_proclist)) { 2248 // warning already emitted. 2249 SKIP_TO(next, ']'); 2250 if (*next == ']') 2251 next++; 2252 SKIP_TO(next, ','); 2253 if (*next == ',') 2254 next++; 2255 buf = next; 2256 continue; 2257 } 2258 if (*next != ']') { 2259 EMIT_WARN(TRUE, (AffInvalidParam, name, start)); 2260 continue; 2261 } 2262 next++; // skip ']' 2263 set_proclist(temp_proclist); 2264 } else if ((*buf >= '0') && (*buf <= '9')) { 2265 // Parse integer numbers -- permute and offset. 2266 int n; 2267 next = buf; 2268 SKIP_DIGITS(next); 2269 n = __kmp_str_to_int(buf, *next); 2270 KMP_ASSERT(n >= 0); 2271 buf = next; 2272 if (count < 2) { 2273 number[count] = n; 2274 } else { 2275 KMP_WARNING(AffManyParams, name, start); 2276 } 2277 ++count; 2278 } else { 2279 EMIT_WARN(TRUE, (AffInvalidParam, name, start)); 2280 continue; 2281 } 2282 2283 SKIP_WS(next); 2284 if (*next == ',') { 2285 next++; 2286 SKIP_WS(next); 2287 } else if (*next != '\0') { 2288 const char *temp = next; 2289 EMIT_WARN(TRUE, (ParseExtraCharsWarn, name, temp)); 2290 continue; 2291 } 2292 buf = next; 2293 } // while 2294 2295 #undef EMIT_WARN 2296 #undef _set_param 2297 #undef set_type 2298 #undef set_verbose 2299 #undef set_warnings 2300 #undef set_respect 2301 #undef set_granularity 2302 2303 __kmp_str_free(&buffer); 2304 2305 if (proclist) { 2306 if (!type) { 2307 KMP_WARNING(AffProcListNoType, name); 2308 *out_type = affinity_explicit; 2309 #if OMP_40_ENABLED 2310 __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel; 2311 #endif 2312 } else if (*out_type != affinity_explicit) { 2313 KMP_WARNING(AffProcListNotExplicit, name); 2314 KMP_ASSERT(*out_proclist != NULL); 2315 KMP_INTERNAL_FREE(*out_proclist); 2316 *out_proclist = NULL; 2317 } 2318 } 2319 switch (*out_type) { 2320 case affinity_logical: 2321 case affinity_physical: { 2322 if (count > 0) { 2323 *out_offset = number[0]; 2324 } 2325 if (count > 1) { 2326 KMP_WARNING(AffManyParamsForLogic, name, number[1]); 2327 } 2328 } break; 2329 case affinity_balanced: { 2330 if (count > 0) { 2331 *out_compact = number[0]; 2332 } 2333 if (count > 1) { 2334 *out_offset = number[1]; 2335 } 2336 2337 if (__kmp_affinity_gran == affinity_gran_default) { 2338 #if KMP_MIC_SUPPORTED 2339 if (__kmp_mic_type != non_mic) { 2340 if (__kmp_affinity_verbose || __kmp_affinity_warnings) { 2341 KMP_WARNING(AffGranUsing, "KMP_AFFINITY", "fine"); 2342 } 2343 __kmp_affinity_gran = affinity_gran_fine; 2344 } else 2345 #endif 2346 { 2347 if (__kmp_affinity_verbose || __kmp_affinity_warnings) { 2348 KMP_WARNING(AffGranUsing, "KMP_AFFINITY", "core"); 2349 } 2350 __kmp_affinity_gran = affinity_gran_core; 2351 } 2352 } 2353 } break; 2354 case affinity_scatter: 2355 case affinity_compact: { 2356 if (count > 0) { 2357 *out_compact = number[0]; 2358 } 2359 if (count > 1) { 2360 *out_offset = number[1]; 2361 } 2362 } break; 2363 case affinity_explicit: { 2364 if (*out_proclist == NULL) { 2365 KMP_WARNING(AffNoProcList, name); 2366 __kmp_affinity_type = affinity_none; 2367 } 2368 if (count > 0) { 2369 KMP_WARNING(AffNoParam, name, "explicit"); 2370 } 2371 } break; 2372 case affinity_none: { 2373 if (count > 0) { 2374 KMP_WARNING(AffNoParam, name, "none"); 2375 } 2376 } break; 2377 case affinity_disabled: { 2378 if (count > 0) { 2379 KMP_WARNING(AffNoParam, name, "disabled"); 2380 } 2381 } break; 2382 case affinity_default: { 2383 if (count > 0) { 2384 KMP_WARNING(AffNoParam, name, "default"); 2385 } 2386 } break; 2387 default: { KMP_ASSERT(0); } 2388 } 2389 } // __kmp_parse_affinity_env 2390 2391 static void __kmp_stg_parse_affinity(char const *name, char const *value, 2392 void *data) { 2393 kmp_setting_t **rivals = (kmp_setting_t **)data; 2394 int rc; 2395 2396 rc = __kmp_stg_check_rivals(name, value, rivals); 2397 if (rc) { 2398 return; 2399 } 2400 2401 __kmp_parse_affinity_env(name, value, &__kmp_affinity_type, 2402 &__kmp_affinity_proclist, &__kmp_affinity_verbose, 2403 &__kmp_affinity_warnings, 2404 &__kmp_affinity_respect_mask, &__kmp_affinity_gran, 2405 &__kmp_affinity_gran_levels, &__kmp_affinity_dups, 2406 &__kmp_affinity_compact, &__kmp_affinity_offset); 2407 2408 } // __kmp_stg_parse_affinity 2409 2410 static void __kmp_stg_print_affinity(kmp_str_buf_t *buffer, char const *name, 2411 void *data) { 2412 if (__kmp_env_format) { 2413 KMP_STR_BUF_PRINT_NAME_EX(name); 2414 } else { 2415 __kmp_str_buf_print(buffer, " %s='", name); 2416 } 2417 if (__kmp_affinity_verbose) { 2418 __kmp_str_buf_print(buffer, "%s,", "verbose"); 2419 } else { 2420 __kmp_str_buf_print(buffer, "%s,", "noverbose"); 2421 } 2422 if (__kmp_affinity_warnings) { 2423 __kmp_str_buf_print(buffer, "%s,", "warnings"); 2424 } else { 2425 __kmp_str_buf_print(buffer, "%s,", "nowarnings"); 2426 } 2427 if (KMP_AFFINITY_CAPABLE()) { 2428 if (__kmp_affinity_respect_mask) { 2429 __kmp_str_buf_print(buffer, "%s,", "respect"); 2430 } else { 2431 __kmp_str_buf_print(buffer, "%s,", "norespect"); 2432 } 2433 switch (__kmp_affinity_gran) { 2434 case affinity_gran_default: 2435 __kmp_str_buf_print(buffer, "%s", "granularity=default,"); 2436 break; 2437 case affinity_gran_fine: 2438 __kmp_str_buf_print(buffer, "%s", "granularity=fine,"); 2439 break; 2440 case affinity_gran_thread: 2441 __kmp_str_buf_print(buffer, "%s", "granularity=thread,"); 2442 break; 2443 case affinity_gran_core: 2444 __kmp_str_buf_print(buffer, "%s", "granularity=core,"); 2445 break; 2446 case affinity_gran_package: 2447 __kmp_str_buf_print(buffer, "%s", "granularity=package,"); 2448 break; 2449 case affinity_gran_node: 2450 __kmp_str_buf_print(buffer, "%s", "granularity=node,"); 2451 break; 2452 #if KMP_GROUP_AFFINITY 2453 case affinity_gran_group: 2454 __kmp_str_buf_print(buffer, "%s", "granularity=group,"); 2455 break; 2456 #endif /* KMP_GROUP_AFFINITY */ 2457 } 2458 } 2459 if (!KMP_AFFINITY_CAPABLE()) { 2460 __kmp_str_buf_print(buffer, "%s", "disabled"); 2461 } else 2462 switch (__kmp_affinity_type) { 2463 case affinity_none: 2464 __kmp_str_buf_print(buffer, "%s", "none"); 2465 break; 2466 case affinity_physical: 2467 __kmp_str_buf_print(buffer, "%s,%d", "physical", __kmp_affinity_offset); 2468 break; 2469 case affinity_logical: 2470 __kmp_str_buf_print(buffer, "%s,%d", "logical", __kmp_affinity_offset); 2471 break; 2472 case affinity_compact: 2473 __kmp_str_buf_print(buffer, "%s,%d,%d", "compact", __kmp_affinity_compact, 2474 __kmp_affinity_offset); 2475 break; 2476 case affinity_scatter: 2477 __kmp_str_buf_print(buffer, "%s,%d,%d", "scatter", __kmp_affinity_compact, 2478 __kmp_affinity_offset); 2479 break; 2480 case affinity_explicit: 2481 __kmp_str_buf_print(buffer, "%s=[%s],%s", "proclist", 2482 __kmp_affinity_proclist, "explicit"); 2483 break; 2484 case affinity_balanced: 2485 __kmp_str_buf_print(buffer, "%s,%d,%d", "balanced", 2486 __kmp_affinity_compact, __kmp_affinity_offset); 2487 break; 2488 case affinity_disabled: 2489 __kmp_str_buf_print(buffer, "%s", "disabled"); 2490 break; 2491 case affinity_default: 2492 __kmp_str_buf_print(buffer, "%s", "default"); 2493 break; 2494 default: 2495 __kmp_str_buf_print(buffer, "%s", "<unknown>"); 2496 break; 2497 } 2498 __kmp_str_buf_print(buffer, "'\n"); 2499 } //__kmp_stg_print_affinity 2500 2501 #ifdef KMP_GOMP_COMPAT 2502 2503 static void __kmp_stg_parse_gomp_cpu_affinity(char const *name, 2504 char const *value, void *data) { 2505 const char *next = NULL; 2506 char *temp_proclist; 2507 kmp_setting_t **rivals = (kmp_setting_t **)data; 2508 int rc; 2509 2510 rc = __kmp_stg_check_rivals(name, value, rivals); 2511 if (rc) { 2512 return; 2513 } 2514 2515 if (TCR_4(__kmp_init_middle)) { 2516 KMP_WARNING(EnvMiddleWarn, name); 2517 __kmp_env_toPrint(name, 0); 2518 return; 2519 } 2520 2521 __kmp_env_toPrint(name, 1); 2522 2523 if (__kmp_parse_affinity_proc_id_list(name, value, &next, &temp_proclist)) { 2524 SKIP_WS(next); 2525 if (*next == '\0') { 2526 // GOMP_CPU_AFFINITY => granularity=fine,explicit,proclist=... 2527 __kmp_affinity_proclist = temp_proclist; 2528 __kmp_affinity_type = affinity_explicit; 2529 __kmp_affinity_gran = affinity_gran_fine; 2530 #if OMP_40_ENABLED 2531 __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel; 2532 #endif 2533 } else { 2534 KMP_WARNING(AffSyntaxError, name); 2535 if (temp_proclist != NULL) { 2536 KMP_INTERNAL_FREE((void *)temp_proclist); 2537 } 2538 } 2539 } else { 2540 // Warning already emitted 2541 __kmp_affinity_type = affinity_none; 2542 #if OMP_40_ENABLED 2543 __kmp_nested_proc_bind.bind_types[0] = proc_bind_false; 2544 #endif 2545 } 2546 } // __kmp_stg_parse_gomp_cpu_affinity 2547 2548 #endif /* KMP_GOMP_COMPAT */ 2549 2550 #if OMP_40_ENABLED 2551 2552 /*----------------------------------------------------------------------------- 2553 The OMP_PLACES proc id list parser. Here is the grammar: 2554 2555 place_list := place 2556 place_list := place , place_list 2557 place := num 2558 place := place : num 2559 place := place : num : signed 2560 place := { subplacelist } 2561 place := ! place // (lowest priority) 2562 subplace_list := subplace 2563 subplace_list := subplace , subplace_list 2564 subplace := num 2565 subplace := num : num 2566 subplace := num : num : signed 2567 signed := num 2568 signed := + signed 2569 signed := - signed 2570 -----------------------------------------------------------------------------*/ 2571 2572 static int __kmp_parse_subplace_list(const char *var, const char **scan) { 2573 const char *next; 2574 2575 for (;;) { 2576 int start, count, stride; 2577 2578 // 2579 // Read in the starting proc id 2580 // 2581 SKIP_WS(*scan); 2582 if ((**scan < '0') || (**scan > '9')) { 2583 KMP_WARNING(SyntaxErrorUsing, var, "\"threads\""); 2584 return FALSE; 2585 } 2586 next = *scan; 2587 SKIP_DIGITS(next); 2588 start = __kmp_str_to_int(*scan, *next); 2589 KMP_ASSERT(start >= 0); 2590 *scan = next; 2591 2592 // valid follow sets are ',' ':' and '}' 2593 SKIP_WS(*scan); 2594 if (**scan == '}') { 2595 break; 2596 } 2597 if (**scan == ',') { 2598 (*scan)++; // skip ',' 2599 continue; 2600 } 2601 if (**scan != ':') { 2602 KMP_WARNING(SyntaxErrorUsing, var, "\"threads\""); 2603 return FALSE; 2604 } 2605 (*scan)++; // skip ':' 2606 2607 // Read count parameter 2608 SKIP_WS(*scan); 2609 if ((**scan < '0') || (**scan > '9')) { 2610 KMP_WARNING(SyntaxErrorUsing, var, "\"threads\""); 2611 return FALSE; 2612 } 2613 next = *scan; 2614 SKIP_DIGITS(next); 2615 count = __kmp_str_to_int(*scan, *next); 2616 KMP_ASSERT(count >= 0); 2617 *scan = next; 2618 2619 // valid follow sets are ',' ':' and '}' 2620 SKIP_WS(*scan); 2621 if (**scan == '}') { 2622 break; 2623 } 2624 if (**scan == ',') { 2625 (*scan)++; // skip ',' 2626 continue; 2627 } 2628 if (**scan != ':') { 2629 KMP_WARNING(SyntaxErrorUsing, var, "\"threads\""); 2630 return FALSE; 2631 } 2632 (*scan)++; // skip ':' 2633 2634 // Read stride parameter 2635 int sign = +1; 2636 for (;;) { 2637 SKIP_WS(*scan); 2638 if (**scan == '+') { 2639 (*scan)++; // skip '+' 2640 continue; 2641 } 2642 if (**scan == '-') { 2643 sign *= -1; 2644 (*scan)++; // skip '-' 2645 continue; 2646 } 2647 break; 2648 } 2649 SKIP_WS(*scan); 2650 if ((**scan < '0') || (**scan > '9')) { 2651 KMP_WARNING(SyntaxErrorUsing, var, "\"threads\""); 2652 return FALSE; 2653 } 2654 next = *scan; 2655 SKIP_DIGITS(next); 2656 stride = __kmp_str_to_int(*scan, *next); 2657 KMP_ASSERT(stride >= 0); 2658 *scan = next; 2659 stride *= sign; 2660 2661 // valid follow sets are ',' and '}' 2662 SKIP_WS(*scan); 2663 if (**scan == '}') { 2664 break; 2665 } 2666 if (**scan == ',') { 2667 (*scan)++; // skip ',' 2668 continue; 2669 } 2670 2671 KMP_WARNING(SyntaxErrorUsing, var, "\"threads\""); 2672 return FALSE; 2673 } 2674 return TRUE; 2675 } 2676 2677 static int __kmp_parse_place(const char *var, const char **scan) { 2678 const char *next; 2679 2680 // valid follow sets are '{' '!' and num 2681 SKIP_WS(*scan); 2682 if (**scan == '{') { 2683 (*scan)++; // skip '{' 2684 if (!__kmp_parse_subplace_list(var, scan)) { 2685 return FALSE; 2686 } 2687 if (**scan != '}') { 2688 KMP_WARNING(SyntaxErrorUsing, var, "\"threads\""); 2689 return FALSE; 2690 } 2691 (*scan)++; // skip '}' 2692 } else if (**scan == '!') { 2693 (*scan)++; // skip '!' 2694 return __kmp_parse_place(var, scan); //'!' has lower precedence than ':' 2695 } else if ((**scan >= '0') && (**scan <= '9')) { 2696 next = *scan; 2697 SKIP_DIGITS(next); 2698 int proc = __kmp_str_to_int(*scan, *next); 2699 KMP_ASSERT(proc >= 0); 2700 *scan = next; 2701 } else { 2702 KMP_WARNING(SyntaxErrorUsing, var, "\"threads\""); 2703 return FALSE; 2704 } 2705 return TRUE; 2706 } 2707 2708 static int __kmp_parse_place_list(const char *var, const char *env, 2709 char **place_list) { 2710 const char *scan = env; 2711 const char *next = scan; 2712 2713 for (;;) { 2714 int count, stride; 2715 2716 if (!__kmp_parse_place(var, &scan)) { 2717 return FALSE; 2718 } 2719 2720 // valid follow sets are ',' ':' and EOL 2721 SKIP_WS(scan); 2722 if (*scan == '\0') { 2723 break; 2724 } 2725 if (*scan == ',') { 2726 scan++; // skip ',' 2727 continue; 2728 } 2729 if (*scan != ':') { 2730 KMP_WARNING(SyntaxErrorUsing, var, "\"threads\""); 2731 return FALSE; 2732 } 2733 scan++; // skip ':' 2734 2735 // Read count parameter 2736 SKIP_WS(scan); 2737 if ((*scan < '0') || (*scan > '9')) { 2738 KMP_WARNING(SyntaxErrorUsing, var, "\"threads\""); 2739 return FALSE; 2740 } 2741 next = scan; 2742 SKIP_DIGITS(next); 2743 count = __kmp_str_to_int(scan, *next); 2744 KMP_ASSERT(count >= 0); 2745 scan = next; 2746 2747 // valid follow sets are ',' ':' and EOL 2748 SKIP_WS(scan); 2749 if (*scan == '\0') { 2750 break; 2751 } 2752 if (*scan == ',') { 2753 scan++; // skip ',' 2754 continue; 2755 } 2756 if (*scan != ':') { 2757 KMP_WARNING(SyntaxErrorUsing, var, "\"threads\""); 2758 return FALSE; 2759 } 2760 scan++; // skip ':' 2761 2762 // Read stride parameter 2763 int sign = +1; 2764 for (;;) { 2765 SKIP_WS(scan); 2766 if (*scan == '+') { 2767 scan++; // skip '+' 2768 continue; 2769 } 2770 if (*scan == '-') { 2771 sign *= -1; 2772 scan++; // skip '-' 2773 continue; 2774 } 2775 break; 2776 } 2777 SKIP_WS(scan); 2778 if ((*scan < '0') || (*scan > '9')) { 2779 KMP_WARNING(SyntaxErrorUsing, var, "\"threads\""); 2780 return FALSE; 2781 } 2782 next = scan; 2783 SKIP_DIGITS(next); 2784 stride = __kmp_str_to_int(scan, *next); 2785 KMP_ASSERT(stride >= 0); 2786 scan = next; 2787 stride *= sign; 2788 2789 // valid follow sets are ',' and EOL 2790 SKIP_WS(scan); 2791 if (*scan == '\0') { 2792 break; 2793 } 2794 if (*scan == ',') { 2795 scan++; // skip ',' 2796 continue; 2797 } 2798 2799 KMP_WARNING(SyntaxErrorUsing, var, "\"threads\""); 2800 return FALSE; 2801 } 2802 2803 { 2804 int len = scan - env; 2805 char *retlist = (char *)__kmp_allocate((len + 1) * sizeof(char)); 2806 KMP_MEMCPY_S(retlist, (len + 1) * sizeof(char), env, len * sizeof(char)); 2807 retlist[len] = '\0'; 2808 *place_list = retlist; 2809 } 2810 return TRUE; 2811 } 2812 2813 static void __kmp_stg_parse_places(char const *name, char const *value, 2814 void *data) { 2815 int count; 2816 const char *scan = value; 2817 const char *next = scan; 2818 const char *kind = "\"threads\""; 2819 kmp_setting_t **rivals = (kmp_setting_t **)data; 2820 int rc; 2821 2822 rc = __kmp_stg_check_rivals(name, value, rivals); 2823 if (rc) { 2824 return; 2825 } 2826 2827 // If OMP_PROC_BIND is not specified but OMP_PLACES is, 2828 // then let OMP_PROC_BIND default to true. 2829 if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_default) { 2830 __kmp_nested_proc_bind.bind_types[0] = proc_bind_true; 2831 } 2832 2833 //__kmp_affinity_num_places = 0; 2834 2835 if (__kmp_match_str("threads", scan, &next)) { 2836 scan = next; 2837 __kmp_affinity_type = affinity_compact; 2838 __kmp_affinity_gran = affinity_gran_thread; 2839 __kmp_affinity_dups = FALSE; 2840 kind = "\"threads\""; 2841 } else if (__kmp_match_str("cores", scan, &next)) { 2842 scan = next; 2843 __kmp_affinity_type = affinity_compact; 2844 __kmp_affinity_gran = affinity_gran_core; 2845 __kmp_affinity_dups = FALSE; 2846 kind = "\"cores\""; 2847 #if KMP_USE_HWLOC 2848 } else if (__kmp_match_str("tiles", scan, &next)) { 2849 scan = next; 2850 __kmp_affinity_type = affinity_compact; 2851 __kmp_affinity_gran = affinity_gran_tile; 2852 __kmp_affinity_dups = FALSE; 2853 kind = "\"tiles\""; 2854 #endif 2855 } else if (__kmp_match_str("sockets", scan, &next)) { 2856 scan = next; 2857 __kmp_affinity_type = affinity_compact; 2858 __kmp_affinity_gran = affinity_gran_package; 2859 __kmp_affinity_dups = FALSE; 2860 kind = "\"sockets\""; 2861 } else { 2862 if (__kmp_affinity_proclist != NULL) { 2863 KMP_INTERNAL_FREE((void *)__kmp_affinity_proclist); 2864 __kmp_affinity_proclist = NULL; 2865 } 2866 if (__kmp_parse_place_list(name, value, &__kmp_affinity_proclist)) { 2867 __kmp_affinity_type = affinity_explicit; 2868 __kmp_affinity_gran = affinity_gran_fine; 2869 __kmp_affinity_dups = FALSE; 2870 if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_default) { 2871 __kmp_nested_proc_bind.bind_types[0] = proc_bind_true; 2872 } 2873 } 2874 return; 2875 } 2876 2877 if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_default) { 2878 __kmp_nested_proc_bind.bind_types[0] = proc_bind_true; 2879 } 2880 2881 SKIP_WS(scan); 2882 if (*scan == '\0') { 2883 return; 2884 } 2885 2886 // Parse option count parameter in parentheses 2887 if (*scan != '(') { 2888 KMP_WARNING(SyntaxErrorUsing, name, kind); 2889 return; 2890 } 2891 scan++; // skip '(' 2892 2893 SKIP_WS(scan); 2894 next = scan; 2895 SKIP_DIGITS(next); 2896 count = __kmp_str_to_int(scan, *next); 2897 KMP_ASSERT(count >= 0); 2898 scan = next; 2899 2900 SKIP_WS(scan); 2901 if (*scan != ')') { 2902 KMP_WARNING(SyntaxErrorUsing, name, kind); 2903 return; 2904 } 2905 scan++; // skip ')' 2906 2907 SKIP_WS(scan); 2908 if (*scan != '\0') { 2909 KMP_WARNING(ParseExtraCharsWarn, name, scan); 2910 } 2911 __kmp_affinity_num_places = count; 2912 } 2913 2914 static void __kmp_stg_print_places(kmp_str_buf_t *buffer, char const *name, 2915 void *data) { 2916 if (__kmp_env_format) { 2917 KMP_STR_BUF_PRINT_NAME; 2918 } else { 2919 __kmp_str_buf_print(buffer, " %s", name); 2920 } 2921 if ((__kmp_nested_proc_bind.used == 0) || 2922 (__kmp_nested_proc_bind.bind_types == NULL) || 2923 (__kmp_nested_proc_bind.bind_types[0] == proc_bind_false)) { 2924 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined)); 2925 } else if (__kmp_affinity_type == affinity_explicit) { 2926 if (__kmp_affinity_proclist != NULL) { 2927 __kmp_str_buf_print(buffer, "='%s'\n", __kmp_affinity_proclist); 2928 } else { 2929 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined)); 2930 } 2931 } else if (__kmp_affinity_type == affinity_compact) { 2932 int num; 2933 if (__kmp_affinity_num_masks > 0) { 2934 num = __kmp_affinity_num_masks; 2935 } else if (__kmp_affinity_num_places > 0) { 2936 num = __kmp_affinity_num_places; 2937 } else { 2938 num = 0; 2939 } 2940 if (__kmp_affinity_gran == affinity_gran_thread) { 2941 if (num > 0) { 2942 __kmp_str_buf_print(buffer, "='threads(%d)'\n", num); 2943 } else { 2944 __kmp_str_buf_print(buffer, "='threads'\n"); 2945 } 2946 } else if (__kmp_affinity_gran == affinity_gran_core) { 2947 if (num > 0) { 2948 __kmp_str_buf_print(buffer, "='cores(%d)' \n", num); 2949 } else { 2950 __kmp_str_buf_print(buffer, "='cores'\n"); 2951 } 2952 #if KMP_USE_HWLOC 2953 } else if (__kmp_affinity_gran == affinity_gran_tile) { 2954 if (num > 0) { 2955 __kmp_str_buf_print(buffer, "='tiles(%d)' \n", num); 2956 } else { 2957 __kmp_str_buf_print(buffer, "='tiles'\n"); 2958 } 2959 #endif 2960 } else if (__kmp_affinity_gran == affinity_gran_package) { 2961 if (num > 0) { 2962 __kmp_str_buf_print(buffer, "='sockets(%d)'\n", num); 2963 } else { 2964 __kmp_str_buf_print(buffer, "='sockets'\n"); 2965 } 2966 } else { 2967 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined)); 2968 } 2969 } else { 2970 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined)); 2971 } 2972 } 2973 2974 #endif /* OMP_40_ENABLED */ 2975 2976 #if (!OMP_40_ENABLED) 2977 2978 static void __kmp_stg_parse_proc_bind(char const *name, char const *value, 2979 void *data) { 2980 int enabled; 2981 kmp_setting_t **rivals = (kmp_setting_t **)data; 2982 int rc; 2983 2984 rc = __kmp_stg_check_rivals(name, value, rivals); 2985 if (rc) { 2986 return; 2987 } 2988 2989 // In OMP 3.1, OMP_PROC_BIND is strictly a boolean 2990 __kmp_stg_parse_bool(name, value, &enabled); 2991 if (enabled) { 2992 // OMP_PROC_BIND => granularity=fine,scatter on MIC 2993 // OMP_PROC_BIND => granularity=core,scatter elsewhere 2994 __kmp_affinity_type = affinity_scatter; 2995 #if KMP_MIC_SUPPORTED 2996 if (__kmp_mic_type != non_mic) 2997 __kmp_affinity_gran = affinity_gran_fine; 2998 else 2999 #endif 3000 __kmp_affinity_gran = affinity_gran_core; 3001 } else { 3002 __kmp_affinity_type = affinity_none; 3003 } 3004 } // __kmp_parse_proc_bind 3005 3006 #endif /* if (! OMP_40_ENABLED) */ 3007 3008 static void __kmp_stg_parse_topology_method(char const *name, char const *value, 3009 void *data) { 3010 if (__kmp_str_match("all", 1, value)) { 3011 __kmp_affinity_top_method = affinity_top_method_all; 3012 } 3013 #if KMP_USE_HWLOC 3014 else if (__kmp_str_match("hwloc", 1, value)) { 3015 __kmp_affinity_top_method = affinity_top_method_hwloc; 3016 } 3017 #endif 3018 #if KMP_ARCH_X86 || KMP_ARCH_X86_64 3019 else if (__kmp_str_match("x2apic id", 9, value) || 3020 __kmp_str_match("x2apic_id", 9, value) || 3021 __kmp_str_match("x2apic-id", 9, value) || 3022 __kmp_str_match("x2apicid", 8, value) || 3023 __kmp_str_match("cpuid leaf 11", 13, value) || 3024 __kmp_str_match("cpuid_leaf_11", 13, value) || 3025 __kmp_str_match("cpuid-leaf-11", 13, value) || 3026 __kmp_str_match("cpuid leaf11", 12, value) || 3027 __kmp_str_match("cpuid_leaf11", 12, value) || 3028 __kmp_str_match("cpuid-leaf11", 12, value) || 3029 __kmp_str_match("cpuidleaf 11", 12, value) || 3030 __kmp_str_match("cpuidleaf_11", 12, value) || 3031 __kmp_str_match("cpuidleaf-11", 12, value) || 3032 __kmp_str_match("cpuidleaf11", 11, value) || 3033 __kmp_str_match("cpuid 11", 8, value) || 3034 __kmp_str_match("cpuid_11", 8, value) || 3035 __kmp_str_match("cpuid-11", 8, value) || 3036 __kmp_str_match("cpuid11", 7, value) || 3037 __kmp_str_match("leaf 11", 7, value) || 3038 __kmp_str_match("leaf_11", 7, value) || 3039 __kmp_str_match("leaf-11", 7, value) || 3040 __kmp_str_match("leaf11", 6, value)) { 3041 __kmp_affinity_top_method = affinity_top_method_x2apicid; 3042 } else if (__kmp_str_match("apic id", 7, value) || 3043 __kmp_str_match("apic_id", 7, value) || 3044 __kmp_str_match("apic-id", 7, value) || 3045 __kmp_str_match("apicid", 6, value) || 3046 __kmp_str_match("cpuid leaf 4", 12, value) || 3047 __kmp_str_match("cpuid_leaf_4", 12, value) || 3048 __kmp_str_match("cpuid-leaf-4", 12, value) || 3049 __kmp_str_match("cpuid leaf4", 11, value) || 3050 __kmp_str_match("cpuid_leaf4", 11, value) || 3051 __kmp_str_match("cpuid-leaf4", 11, value) || 3052 __kmp_str_match("cpuidleaf 4", 11, value) || 3053 __kmp_str_match("cpuidleaf_4", 11, value) || 3054 __kmp_str_match("cpuidleaf-4", 11, value) || 3055 __kmp_str_match("cpuidleaf4", 10, value) || 3056 __kmp_str_match("cpuid 4", 7, value) || 3057 __kmp_str_match("cpuid_4", 7, value) || 3058 __kmp_str_match("cpuid-4", 7, value) || 3059 __kmp_str_match("cpuid4", 6, value) || 3060 __kmp_str_match("leaf 4", 6, value) || 3061 __kmp_str_match("leaf_4", 6, value) || 3062 __kmp_str_match("leaf-4", 6, value) || 3063 __kmp_str_match("leaf4", 5, value)) { 3064 __kmp_affinity_top_method = affinity_top_method_apicid; 3065 } 3066 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */ 3067 else if (__kmp_str_match("/proc/cpuinfo", 2, value) || 3068 __kmp_str_match("cpuinfo", 5, value)) { 3069 __kmp_affinity_top_method = affinity_top_method_cpuinfo; 3070 } 3071 #if KMP_GROUP_AFFINITY 3072 else if (__kmp_str_match("group", 1, value)) { 3073 __kmp_affinity_top_method = affinity_top_method_group; 3074 } 3075 #endif /* KMP_GROUP_AFFINITY */ 3076 else if (__kmp_str_match("flat", 1, value)) { 3077 __kmp_affinity_top_method = affinity_top_method_flat; 3078 } else { 3079 KMP_WARNING(StgInvalidValue, name, value); 3080 } 3081 } // __kmp_stg_parse_topology_method 3082 3083 static void __kmp_stg_print_topology_method(kmp_str_buf_t *buffer, 3084 char const *name, void *data) { 3085 char const *value = NULL; 3086 3087 switch (__kmp_affinity_top_method) { 3088 case affinity_top_method_default: 3089 value = "default"; 3090 break; 3091 3092 case affinity_top_method_all: 3093 value = "all"; 3094 break; 3095 3096 #if KMP_ARCH_X86 || KMP_ARCH_X86_64 3097 case affinity_top_method_x2apicid: 3098 value = "x2APIC id"; 3099 break; 3100 3101 case affinity_top_method_apicid: 3102 value = "APIC id"; 3103 break; 3104 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */ 3105 3106 #if KMP_USE_HWLOC 3107 case affinity_top_method_hwloc: 3108 value = "hwloc"; 3109 break; 3110 #endif 3111 3112 case affinity_top_method_cpuinfo: 3113 value = "cpuinfo"; 3114 break; 3115 3116 #if KMP_GROUP_AFFINITY 3117 case affinity_top_method_group: 3118 value = "group"; 3119 break; 3120 #endif /* KMP_GROUP_AFFINITY */ 3121 3122 case affinity_top_method_flat: 3123 value = "flat"; 3124 break; 3125 } 3126 3127 if (value != NULL) { 3128 __kmp_stg_print_str(buffer, name, value); 3129 } 3130 } // __kmp_stg_print_topology_method 3131 3132 #endif /* KMP_AFFINITY_SUPPORTED */ 3133 3134 #if OMP_40_ENABLED 3135 3136 // OMP_PROC_BIND / bind-var is functional on all 4.0 builds, including OS X* 3137 // OMP_PLACES / place-partition-var is not. 3138 static void __kmp_stg_parse_proc_bind(char const *name, char const *value, 3139 void *data) { 3140 kmp_setting_t **rivals = (kmp_setting_t **)data; 3141 int rc; 3142 3143 rc = __kmp_stg_check_rivals(name, value, rivals); 3144 if (rc) { 3145 return; 3146 } 3147 3148 // In OMP 4.0 OMP_PROC_BIND is a vector of proc_bind types. 3149 KMP_DEBUG_ASSERT((__kmp_nested_proc_bind.bind_types != NULL) && 3150 (__kmp_nested_proc_bind.used > 0)); 3151 3152 const char *buf = value; 3153 const char *next; 3154 int num; 3155 SKIP_WS(buf); 3156 if ((*buf >= '0') && (*buf <= '9')) { 3157 next = buf; 3158 SKIP_DIGITS(next); 3159 num = __kmp_str_to_int(buf, *next); 3160 KMP_ASSERT(num >= 0); 3161 buf = next; 3162 SKIP_WS(buf); 3163 } else { 3164 num = -1; 3165 } 3166 3167 next = buf; 3168 if (__kmp_match_str("disabled", buf, &next)) { 3169 buf = next; 3170 SKIP_WS(buf); 3171 #if KMP_AFFINITY_SUPPORTED 3172 __kmp_affinity_type = affinity_disabled; 3173 #endif /* KMP_AFFINITY_SUPPORTED */ 3174 __kmp_nested_proc_bind.used = 1; 3175 __kmp_nested_proc_bind.bind_types[0] = proc_bind_false; 3176 } else if ((num == (int)proc_bind_false) || 3177 __kmp_match_str("false", buf, &next)) { 3178 buf = next; 3179 SKIP_WS(buf); 3180 #if KMP_AFFINITY_SUPPORTED 3181 __kmp_affinity_type = affinity_none; 3182 #endif /* KMP_AFFINITY_SUPPORTED */ 3183 __kmp_nested_proc_bind.used = 1; 3184 __kmp_nested_proc_bind.bind_types[0] = proc_bind_false; 3185 } else if ((num == (int)proc_bind_true) || 3186 __kmp_match_str("true", buf, &next)) { 3187 buf = next; 3188 SKIP_WS(buf); 3189 __kmp_nested_proc_bind.used = 1; 3190 __kmp_nested_proc_bind.bind_types[0] = proc_bind_true; 3191 } else { 3192 // Count the number of values in the env var string 3193 const char *scan; 3194 int nelem = 1; 3195 for (scan = buf; *scan != '\0'; scan++) { 3196 if (*scan == ',') { 3197 nelem++; 3198 } 3199 } 3200 3201 // Create / expand the nested proc_bind array as needed 3202 if (__kmp_nested_proc_bind.size < nelem) { 3203 __kmp_nested_proc_bind.bind_types = 3204 (kmp_proc_bind_t *)KMP_INTERNAL_REALLOC( 3205 __kmp_nested_proc_bind.bind_types, 3206 sizeof(kmp_proc_bind_t) * nelem); 3207 if (__kmp_nested_proc_bind.bind_types == NULL) { 3208 KMP_FATAL(MemoryAllocFailed); 3209 } 3210 __kmp_nested_proc_bind.size = nelem; 3211 } 3212 __kmp_nested_proc_bind.used = nelem; 3213 3214 if (nelem > 1 && !__kmp_dflt_max_active_levels_set) 3215 __kmp_dflt_max_active_levels = KMP_MAX_ACTIVE_LEVELS_LIMIT; 3216 3217 // Save values in the nested proc_bind array 3218 int i = 0; 3219 for (;;) { 3220 enum kmp_proc_bind_t bind; 3221 3222 if ((num == (int)proc_bind_master) || 3223 __kmp_match_str("master", buf, &next)) { 3224 buf = next; 3225 SKIP_WS(buf); 3226 bind = proc_bind_master; 3227 } else if ((num == (int)proc_bind_close) || 3228 __kmp_match_str("close", buf, &next)) { 3229 buf = next; 3230 SKIP_WS(buf); 3231 bind = proc_bind_close; 3232 } else if ((num == (int)proc_bind_spread) || 3233 __kmp_match_str("spread", buf, &next)) { 3234 buf = next; 3235 SKIP_WS(buf); 3236 bind = proc_bind_spread; 3237 } else { 3238 KMP_WARNING(StgInvalidValue, name, value); 3239 __kmp_nested_proc_bind.bind_types[0] = proc_bind_false; 3240 __kmp_nested_proc_bind.used = 1; 3241 return; 3242 } 3243 3244 __kmp_nested_proc_bind.bind_types[i++] = bind; 3245 if (i >= nelem) { 3246 break; 3247 } 3248 KMP_DEBUG_ASSERT(*buf == ','); 3249 buf++; 3250 SKIP_WS(buf); 3251 3252 // Read next value if it was specified as an integer 3253 if ((*buf >= '0') && (*buf <= '9')) { 3254 next = buf; 3255 SKIP_DIGITS(next); 3256 num = __kmp_str_to_int(buf, *next); 3257 KMP_ASSERT(num >= 0); 3258 buf = next; 3259 SKIP_WS(buf); 3260 } else { 3261 num = -1; 3262 } 3263 } 3264 SKIP_WS(buf); 3265 } 3266 if (*buf != '\0') { 3267 KMP_WARNING(ParseExtraCharsWarn, name, buf); 3268 } 3269 } 3270 3271 static void __kmp_stg_print_proc_bind(kmp_str_buf_t *buffer, char const *name, 3272 void *data) { 3273 int nelem = __kmp_nested_proc_bind.used; 3274 if (__kmp_env_format) { 3275 KMP_STR_BUF_PRINT_NAME; 3276 } else { 3277 __kmp_str_buf_print(buffer, " %s", name); 3278 } 3279 if (nelem == 0) { 3280 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined)); 3281 } else { 3282 int i; 3283 __kmp_str_buf_print(buffer, "='", name); 3284 for (i = 0; i < nelem; i++) { 3285 switch (__kmp_nested_proc_bind.bind_types[i]) { 3286 case proc_bind_false: 3287 __kmp_str_buf_print(buffer, "false"); 3288 break; 3289 3290 case proc_bind_true: 3291 __kmp_str_buf_print(buffer, "true"); 3292 break; 3293 3294 case proc_bind_master: 3295 __kmp_str_buf_print(buffer, "master"); 3296 break; 3297 3298 case proc_bind_close: 3299 __kmp_str_buf_print(buffer, "close"); 3300 break; 3301 3302 case proc_bind_spread: 3303 __kmp_str_buf_print(buffer, "spread"); 3304 break; 3305 3306 case proc_bind_intel: 3307 __kmp_str_buf_print(buffer, "intel"); 3308 break; 3309 3310 case proc_bind_default: 3311 __kmp_str_buf_print(buffer, "default"); 3312 break; 3313 } 3314 if (i < nelem - 1) { 3315 __kmp_str_buf_print(buffer, ","); 3316 } 3317 } 3318 __kmp_str_buf_print(buffer, "'\n"); 3319 } 3320 } 3321 3322 #endif /* OMP_40_ENABLED */ 3323 3324 #if OMP_50_ENABLED 3325 static void __kmp_stg_parse_display_affinity(char const *name, 3326 char const *value, void *data) { 3327 __kmp_stg_parse_bool(name, value, &__kmp_display_affinity); 3328 } 3329 static void __kmp_stg_print_display_affinity(kmp_str_buf_t *buffer, 3330 char const *name, void *data) { 3331 __kmp_stg_print_bool(buffer, name, __kmp_display_affinity); 3332 } 3333 static void __kmp_stg_parse_affinity_format(char const *name, char const *value, 3334 void *data) { 3335 size_t length = KMP_STRLEN(value); 3336 __kmp_strncpy_truncate(__kmp_affinity_format, KMP_AFFINITY_FORMAT_SIZE, value, 3337 length); 3338 } 3339 static void __kmp_stg_print_affinity_format(kmp_str_buf_t *buffer, 3340 char const *name, void *data) { 3341 if (__kmp_env_format) { 3342 KMP_STR_BUF_PRINT_NAME_EX(name); 3343 } else { 3344 __kmp_str_buf_print(buffer, " %s='", name); 3345 } 3346 __kmp_str_buf_print(buffer, "%s'\n", __kmp_affinity_format); 3347 } 3348 // OMP_ALLOCATOR sets default allocator 3349 static void __kmp_stg_parse_allocator(char const *name, char const *value, 3350 void *data) { 3351 /* 3352 The value can be any predefined allocator: 3353 omp_default_mem_alloc = 1; 3354 omp_large_cap_mem_alloc = 2; 3355 omp_const_mem_alloc = 3; 3356 omp_high_bw_mem_alloc = 4; 3357 omp_low_lat_mem_alloc = 5; 3358 omp_cgroup_mem_alloc = 6; 3359 omp_pteam_mem_alloc = 7; 3360 omp_thread_mem_alloc = 8; 3361 Acceptable value is either a digit or a string. 3362 */ 3363 const char *buf = value; 3364 const char *next; 3365 int num; 3366 SKIP_WS(buf); 3367 if ((*buf > '0') && (*buf < '9')) { 3368 next = buf; 3369 SKIP_DIGITS(next); 3370 num = __kmp_str_to_int(buf, *next); 3371 KMP_ASSERT(num > 0); 3372 switch (num) { 3373 case 4: 3374 if (__kmp_memkind_available) { 3375 __kmp_def_allocator = omp_high_bw_mem_alloc; 3376 } else { 3377 __kmp_msg(kmp_ms_warning, 3378 KMP_MSG(OmpNoAllocator, "omp_high_bw_mem_alloc"), 3379 __kmp_msg_null); 3380 __kmp_def_allocator = omp_default_mem_alloc; 3381 } 3382 break; 3383 case 1: 3384 __kmp_def_allocator = omp_default_mem_alloc; 3385 break; 3386 case 2: 3387 __kmp_msg(kmp_ms_warning, 3388 KMP_MSG(OmpNoAllocator, "omp_large_cap_mem_alloc"), 3389 __kmp_msg_null); 3390 __kmp_def_allocator = omp_default_mem_alloc; 3391 break; 3392 case 3: 3393 __kmp_msg(kmp_ms_warning, KMP_MSG(OmpNoAllocator, "omp_const_mem_alloc"), 3394 __kmp_msg_null); 3395 __kmp_def_allocator = omp_default_mem_alloc; 3396 break; 3397 case 5: 3398 __kmp_msg(kmp_ms_warning, 3399 KMP_MSG(OmpNoAllocator, "omp_low_lat_mem_alloc"), 3400 __kmp_msg_null); 3401 __kmp_def_allocator = omp_default_mem_alloc; 3402 break; 3403 case 6: 3404 __kmp_msg(kmp_ms_warning, KMP_MSG(OmpNoAllocator, "omp_cgroup_mem_alloc"), 3405 __kmp_msg_null); 3406 __kmp_def_allocator = omp_default_mem_alloc; 3407 break; 3408 case 7: 3409 __kmp_msg(kmp_ms_warning, KMP_MSG(OmpNoAllocator, "omp_pteam_mem_alloc"), 3410 __kmp_msg_null); 3411 __kmp_def_allocator = omp_default_mem_alloc; 3412 break; 3413 case 8: 3414 __kmp_msg(kmp_ms_warning, KMP_MSG(OmpNoAllocator, "omp_thread_mem_alloc"), 3415 __kmp_msg_null); 3416 __kmp_def_allocator = omp_default_mem_alloc; 3417 break; 3418 } 3419 return; 3420 } 3421 next = buf; 3422 if (__kmp_match_str("omp_high_bw_mem_alloc", buf, &next)) { 3423 if (__kmp_memkind_available) { 3424 __kmp_def_allocator = omp_high_bw_mem_alloc; 3425 } else { 3426 __kmp_msg(kmp_ms_warning, 3427 KMP_MSG(OmpNoAllocator, "omp_high_bw_mem_alloc"), 3428 __kmp_msg_null); 3429 __kmp_def_allocator = omp_default_mem_alloc; 3430 } 3431 } else if (__kmp_match_str("omp_default_mem_alloc", buf, &next)) { 3432 __kmp_def_allocator = omp_default_mem_alloc; 3433 } else if (__kmp_match_str("omp_large_cap_mem_alloc", buf, &next)) { 3434 __kmp_msg(kmp_ms_warning, 3435 KMP_MSG(OmpNoAllocator, "omp_large_cap_mem_alloc"), 3436 __kmp_msg_null); 3437 __kmp_def_allocator = omp_default_mem_alloc; 3438 } else if (__kmp_match_str("omp_const_mem_alloc", buf, &next)) { 3439 __kmp_msg(kmp_ms_warning, KMP_MSG(OmpNoAllocator, "omp_const_mem_alloc"), 3440 __kmp_msg_null); 3441 __kmp_def_allocator = omp_default_mem_alloc; 3442 } else if (__kmp_match_str("omp_low_lat_mem_alloc", buf, &next)) { 3443 __kmp_msg(kmp_ms_warning, KMP_MSG(OmpNoAllocator, "omp_low_lat_mem_alloc"), 3444 __kmp_msg_null); 3445 __kmp_def_allocator = omp_default_mem_alloc; 3446 } else if (__kmp_match_str("omp_cgroup_mem_alloc", buf, &next)) { 3447 __kmp_msg(kmp_ms_warning, KMP_MSG(OmpNoAllocator, "omp_cgroup_mem_alloc"), 3448 __kmp_msg_null); 3449 __kmp_def_allocator = omp_default_mem_alloc; 3450 } else if (__kmp_match_str("omp_pteam_mem_alloc", buf, &next)) { 3451 __kmp_msg(kmp_ms_warning, KMP_MSG(OmpNoAllocator, "omp_pteam_mem_alloc"), 3452 __kmp_msg_null); 3453 __kmp_def_allocator = omp_default_mem_alloc; 3454 } else if (__kmp_match_str("omp_thread_mem_alloc", buf, &next)) { 3455 __kmp_msg(kmp_ms_warning, KMP_MSG(OmpNoAllocator, "omp_thread_mem_alloc"), 3456 __kmp_msg_null); 3457 __kmp_def_allocator = omp_default_mem_alloc; 3458 } 3459 buf = next; 3460 SKIP_WS(buf); 3461 if (*buf != '\0') { 3462 KMP_WARNING(ParseExtraCharsWarn, name, buf); 3463 } 3464 } 3465 3466 static void __kmp_stg_print_allocator(kmp_str_buf_t *buffer, char const *name, 3467 void *data) { 3468 if (__kmp_def_allocator == omp_default_mem_alloc) { 3469 __kmp_stg_print_str(buffer, name, "omp_default_mem_alloc"); 3470 } else if (__kmp_def_allocator == omp_high_bw_mem_alloc) { 3471 __kmp_stg_print_str(buffer, name, "omp_high_bw_mem_alloc"); 3472 } else if (__kmp_def_allocator == omp_large_cap_mem_alloc) { 3473 __kmp_stg_print_str(buffer, name, "omp_large_cap_mem_alloc"); 3474 } else if (__kmp_def_allocator == omp_const_mem_alloc) { 3475 __kmp_stg_print_str(buffer, name, "omp_const_mem_alloc"); 3476 } else if (__kmp_def_allocator == omp_low_lat_mem_alloc) { 3477 __kmp_stg_print_str(buffer, name, "omp_low_lat_mem_alloc"); 3478 } else if (__kmp_def_allocator == omp_cgroup_mem_alloc) { 3479 __kmp_stg_print_str(buffer, name, "omp_cgroup_mem_alloc"); 3480 } else if (__kmp_def_allocator == omp_pteam_mem_alloc) { 3481 __kmp_stg_print_str(buffer, name, "omp_pteam_mem_alloc"); 3482 } else if (__kmp_def_allocator == omp_thread_mem_alloc) { 3483 __kmp_stg_print_str(buffer, name, "omp_thread_mem_alloc"); 3484 } 3485 } 3486 3487 #endif /* OMP_50_ENABLED */ 3488 3489 // ----------------------------------------------------------------------------- 3490 // OMP_DYNAMIC 3491 3492 static void __kmp_stg_parse_omp_dynamic(char const *name, char const *value, 3493 void *data) { 3494 __kmp_stg_parse_bool(name, value, &(__kmp_global.g.g_dynamic)); 3495 } // __kmp_stg_parse_omp_dynamic 3496 3497 static void __kmp_stg_print_omp_dynamic(kmp_str_buf_t *buffer, char const *name, 3498 void *data) { 3499 __kmp_stg_print_bool(buffer, name, __kmp_global.g.g_dynamic); 3500 } // __kmp_stg_print_omp_dynamic 3501 3502 static void __kmp_stg_parse_kmp_dynamic_mode(char const *name, 3503 char const *value, void *data) { 3504 if (TCR_4(__kmp_init_parallel)) { 3505 KMP_WARNING(EnvParallelWarn, name); 3506 __kmp_env_toPrint(name, 0); 3507 return; 3508 } 3509 #ifdef USE_LOAD_BALANCE 3510 else if (__kmp_str_match("load balance", 2, value) || 3511 __kmp_str_match("load_balance", 2, value) || 3512 __kmp_str_match("load-balance", 2, value) || 3513 __kmp_str_match("loadbalance", 2, value) || 3514 __kmp_str_match("balance", 1, value)) { 3515 __kmp_global.g.g_dynamic_mode = dynamic_load_balance; 3516 } 3517 #endif /* USE_LOAD_BALANCE */ 3518 else if (__kmp_str_match("thread limit", 1, value) || 3519 __kmp_str_match("thread_limit", 1, value) || 3520 __kmp_str_match("thread-limit", 1, value) || 3521 __kmp_str_match("threadlimit", 1, value) || 3522 __kmp_str_match("limit", 2, value)) { 3523 __kmp_global.g.g_dynamic_mode = dynamic_thread_limit; 3524 } else if (__kmp_str_match("random", 1, value)) { 3525 __kmp_global.g.g_dynamic_mode = dynamic_random; 3526 } else { 3527 KMP_WARNING(StgInvalidValue, name, value); 3528 } 3529 } //__kmp_stg_parse_kmp_dynamic_mode 3530 3531 static void __kmp_stg_print_kmp_dynamic_mode(kmp_str_buf_t *buffer, 3532 char const *name, void *data) { 3533 #if KMP_DEBUG 3534 if (__kmp_global.g.g_dynamic_mode == dynamic_default) { 3535 __kmp_str_buf_print(buffer, " %s: %s \n", name, KMP_I18N_STR(NotDefined)); 3536 } 3537 #ifdef USE_LOAD_BALANCE 3538 else if (__kmp_global.g.g_dynamic_mode == dynamic_load_balance) { 3539 __kmp_stg_print_str(buffer, name, "load balance"); 3540 } 3541 #endif /* USE_LOAD_BALANCE */ 3542 else if (__kmp_global.g.g_dynamic_mode == dynamic_thread_limit) { 3543 __kmp_stg_print_str(buffer, name, "thread limit"); 3544 } else if (__kmp_global.g.g_dynamic_mode == dynamic_random) { 3545 __kmp_stg_print_str(buffer, name, "random"); 3546 } else { 3547 KMP_ASSERT(0); 3548 } 3549 #endif /* KMP_DEBUG */ 3550 } // __kmp_stg_print_kmp_dynamic_mode 3551 3552 #ifdef USE_LOAD_BALANCE 3553 3554 // ----------------------------------------------------------------------------- 3555 // KMP_LOAD_BALANCE_INTERVAL 3556 3557 static void __kmp_stg_parse_ld_balance_interval(char const *name, 3558 char const *value, void *data) { 3559 double interval = __kmp_convert_to_double(value); 3560 if (interval >= 0) { 3561 __kmp_load_balance_interval = interval; 3562 } else { 3563 KMP_WARNING(StgInvalidValue, name, value); 3564 } 3565 } // __kmp_stg_parse_load_balance_interval 3566 3567 static void __kmp_stg_print_ld_balance_interval(kmp_str_buf_t *buffer, 3568 char const *name, void *data) { 3569 #if KMP_DEBUG 3570 __kmp_str_buf_print(buffer, " %s=%8.6f\n", name, 3571 __kmp_load_balance_interval); 3572 #endif /* KMP_DEBUG */ 3573 } // __kmp_stg_print_load_balance_interval 3574 3575 #endif /* USE_LOAD_BALANCE */ 3576 3577 // ----------------------------------------------------------------------------- 3578 // KMP_INIT_AT_FORK 3579 3580 static void __kmp_stg_parse_init_at_fork(char const *name, char const *value, 3581 void *data) { 3582 __kmp_stg_parse_bool(name, value, &__kmp_need_register_atfork); 3583 if (__kmp_need_register_atfork) { 3584 __kmp_need_register_atfork_specified = TRUE; 3585 } 3586 } // __kmp_stg_parse_init_at_fork 3587 3588 static void __kmp_stg_print_init_at_fork(kmp_str_buf_t *buffer, 3589 char const *name, void *data) { 3590 __kmp_stg_print_bool(buffer, name, __kmp_need_register_atfork_specified); 3591 } // __kmp_stg_print_init_at_fork 3592 3593 // ----------------------------------------------------------------------------- 3594 // KMP_SCHEDULE 3595 3596 static void __kmp_stg_parse_schedule(char const *name, char const *value, 3597 void *data) { 3598 3599 if (value != NULL) { 3600 size_t length = KMP_STRLEN(value); 3601 if (length > INT_MAX) { 3602 KMP_WARNING(LongValue, name); 3603 } else { 3604 const char *semicolon; 3605 if (value[length - 1] == '"' || value[length - 1] == '\'') 3606 KMP_WARNING(UnbalancedQuotes, name); 3607 do { 3608 char sentinel; 3609 3610 semicolon = strchr(value, ';'); 3611 if (*value && semicolon != value) { 3612 const char *comma = strchr(value, ','); 3613 3614 if (comma) { 3615 ++comma; 3616 sentinel = ','; 3617 } else 3618 sentinel = ';'; 3619 if (!__kmp_strcasecmp_with_sentinel("static", value, sentinel)) { 3620 if (!__kmp_strcasecmp_with_sentinel("greedy", comma, ';')) { 3621 __kmp_static = kmp_sch_static_greedy; 3622 continue; 3623 } else if (!__kmp_strcasecmp_with_sentinel("balanced", comma, 3624 ';')) { 3625 __kmp_static = kmp_sch_static_balanced; 3626 continue; 3627 } 3628 } else if (!__kmp_strcasecmp_with_sentinel("guided", value, 3629 sentinel)) { 3630 if (!__kmp_strcasecmp_with_sentinel("iterative", comma, ';')) { 3631 __kmp_guided = kmp_sch_guided_iterative_chunked; 3632 continue; 3633 } else if (!__kmp_strcasecmp_with_sentinel("analytical", comma, 3634 ';')) { 3635 /* analytical not allowed for too many threads */ 3636 __kmp_guided = kmp_sch_guided_analytical_chunked; 3637 continue; 3638 } 3639 } 3640 KMP_WARNING(InvalidClause, name, value); 3641 } else 3642 KMP_WARNING(EmptyClause, name); 3643 } while ((value = semicolon ? semicolon + 1 : NULL)); 3644 } 3645 } 3646 3647 } // __kmp_stg_parse__schedule 3648 3649 static void __kmp_stg_print_schedule(kmp_str_buf_t *buffer, char const *name, 3650 void *data) { 3651 if (__kmp_env_format) { 3652 KMP_STR_BUF_PRINT_NAME_EX(name); 3653 } else { 3654 __kmp_str_buf_print(buffer, " %s='", name); 3655 } 3656 if (__kmp_static == kmp_sch_static_greedy) { 3657 __kmp_str_buf_print(buffer, "%s", "static,greedy"); 3658 } else if (__kmp_static == kmp_sch_static_balanced) { 3659 __kmp_str_buf_print(buffer, "%s", "static,balanced"); 3660 } 3661 if (__kmp_guided == kmp_sch_guided_iterative_chunked) { 3662 __kmp_str_buf_print(buffer, ";%s'\n", "guided,iterative"); 3663 } else if (__kmp_guided == kmp_sch_guided_analytical_chunked) { 3664 __kmp_str_buf_print(buffer, ";%s'\n", "guided,analytical"); 3665 } 3666 } // __kmp_stg_print_schedule 3667 3668 // ----------------------------------------------------------------------------- 3669 // OMP_SCHEDULE 3670 3671 static inline void __kmp_omp_schedule_restore() { 3672 #if KMP_USE_HIER_SCHED 3673 __kmp_hier_scheds.deallocate(); 3674 #endif 3675 __kmp_chunk = 0; 3676 __kmp_sched = kmp_sch_default; 3677 } 3678 3679 // if parse_hier = true: 3680 // Parse [HW,][modifier:]kind[,chunk] 3681 // else: 3682 // Parse [modifier:]kind[,chunk] 3683 static const char *__kmp_parse_single_omp_schedule(const char *name, 3684 const char *value, 3685 bool parse_hier = false) { 3686 /* get the specified scheduling style */ 3687 const char *ptr = value; 3688 const char *delim; 3689 int chunk = 0; 3690 enum sched_type sched = kmp_sch_default; 3691 if (*ptr == '\0') 3692 return NULL; 3693 delim = ptr; 3694 while (*delim != ',' && *delim != ':' && *delim != '\0') 3695 delim++; 3696 #if KMP_USE_HIER_SCHED 3697 kmp_hier_layer_e layer = kmp_hier_layer_e::LAYER_THREAD; 3698 if (parse_hier) { 3699 if (*delim == ',') { 3700 if (!__kmp_strcasecmp_with_sentinel("L1", ptr, ',')) { 3701 layer = kmp_hier_layer_e::LAYER_L1; 3702 } else if (!__kmp_strcasecmp_with_sentinel("L2", ptr, ',')) { 3703 layer = kmp_hier_layer_e::LAYER_L2; 3704 } else if (!__kmp_strcasecmp_with_sentinel("L3", ptr, ',')) { 3705 layer = kmp_hier_layer_e::LAYER_L3; 3706 } else if (!__kmp_strcasecmp_with_sentinel("NUMA", ptr, ',')) { 3707 layer = kmp_hier_layer_e::LAYER_NUMA; 3708 } 3709 } 3710 if (layer != kmp_hier_layer_e::LAYER_THREAD && *delim != ',') { 3711 // If there is no comma after the layer, then this schedule is invalid 3712 KMP_WARNING(StgInvalidValue, name, value); 3713 __kmp_omp_schedule_restore(); 3714 return NULL; 3715 } else if (layer != kmp_hier_layer_e::LAYER_THREAD) { 3716 ptr = ++delim; 3717 while (*delim != ',' && *delim != ':' && *delim != '\0') 3718 delim++; 3719 } 3720 } 3721 #endif // KMP_USE_HIER_SCHED 3722 #if OMP_45_ENABLED 3723 // Read in schedule modifier if specified 3724 enum sched_type sched_modifier = (enum sched_type)0; 3725 if (*delim == ':') { 3726 if (!__kmp_strcasecmp_with_sentinel("monotonic", ptr, *delim)) { 3727 sched_modifier = sched_type::kmp_sch_modifier_monotonic; 3728 ptr = ++delim; 3729 while (*delim != ',' && *delim != ':' && *delim != '\0') 3730 delim++; 3731 } else if (!__kmp_strcasecmp_with_sentinel("nonmonotonic", ptr, *delim)) { 3732 sched_modifier = sched_type::kmp_sch_modifier_nonmonotonic; 3733 ptr = ++delim; 3734 while (*delim != ',' && *delim != ':' && *delim != '\0') 3735 delim++; 3736 } else if (!parse_hier) { 3737 // If there is no proper schedule modifier, then this schedule is invalid 3738 KMP_WARNING(StgInvalidValue, name, value); 3739 __kmp_omp_schedule_restore(); 3740 return NULL; 3741 } 3742 } 3743 #endif 3744 // Read in schedule kind (required) 3745 if (!__kmp_strcasecmp_with_sentinel("dynamic", ptr, *delim)) 3746 sched = kmp_sch_dynamic_chunked; 3747 else if (!__kmp_strcasecmp_with_sentinel("guided", ptr, *delim)) 3748 sched = kmp_sch_guided_chunked; 3749 // AC: TODO: probably remove TRAPEZOIDAL (OMP 3.0 does not allow it) 3750 else if (!__kmp_strcasecmp_with_sentinel("auto", ptr, *delim)) 3751 sched = kmp_sch_auto; 3752 else if (!__kmp_strcasecmp_with_sentinel("trapezoidal", ptr, *delim)) 3753 sched = kmp_sch_trapezoidal; 3754 else if (!__kmp_strcasecmp_with_sentinel("static", ptr, *delim)) 3755 sched = kmp_sch_static; 3756 #if KMP_STATIC_STEAL_ENABLED 3757 else if (!__kmp_strcasecmp_with_sentinel("static_steal", ptr, *delim)) 3758 sched = kmp_sch_static_steal; 3759 #endif 3760 else { 3761 // If there is no proper schedule kind, then this schedule is invalid 3762 KMP_WARNING(StgInvalidValue, name, value); 3763 __kmp_omp_schedule_restore(); 3764 return NULL; 3765 } 3766 3767 // Read in schedule chunk size if specified 3768 if (*delim == ',') { 3769 ptr = delim + 1; 3770 SKIP_WS(ptr); 3771 if (!isdigit(*ptr)) { 3772 // If there is no chunk after comma, then this schedule is invalid 3773 KMP_WARNING(StgInvalidValue, name, value); 3774 __kmp_omp_schedule_restore(); 3775 return NULL; 3776 } 3777 SKIP_DIGITS(ptr); 3778 // auto schedule should not specify chunk size 3779 if (sched == kmp_sch_auto) { 3780 __kmp_msg(kmp_ms_warning, KMP_MSG(IgnoreChunk, name, delim), 3781 __kmp_msg_null); 3782 } else { 3783 if (sched == kmp_sch_static) 3784 sched = kmp_sch_static_chunked; 3785 chunk = __kmp_str_to_int(delim + 1, *ptr); 3786 if (chunk < 1) { 3787 chunk = KMP_DEFAULT_CHUNK; 3788 __kmp_msg(kmp_ms_warning, KMP_MSG(InvalidChunk, name, delim), 3789 __kmp_msg_null); 3790 KMP_INFORM(Using_int_Value, name, __kmp_chunk); 3791 // AC: next block commented out until KMP_DEFAULT_CHUNK != KMP_MIN_CHUNK 3792 // (to improve code coverage :) 3793 // The default chunk size is 1 according to standard, thus making 3794 // KMP_MIN_CHUNK not 1 we would introduce mess: 3795 // wrong chunk becomes 1, but it will be impossible to explicitly set 3796 // to 1 because it becomes KMP_MIN_CHUNK... 3797 // } else if ( chunk < KMP_MIN_CHUNK ) { 3798 // chunk = KMP_MIN_CHUNK; 3799 } else if (chunk > KMP_MAX_CHUNK) { 3800 chunk = KMP_MAX_CHUNK; 3801 __kmp_msg(kmp_ms_warning, KMP_MSG(LargeChunk, name, delim), 3802 __kmp_msg_null); 3803 KMP_INFORM(Using_int_Value, name, chunk); 3804 } 3805 } 3806 } else { 3807 ptr = delim; 3808 } 3809 3810 SCHEDULE_SET_MODIFIERS(sched, sched_modifier); 3811 3812 #if KMP_USE_HIER_SCHED 3813 if (layer != kmp_hier_layer_e::LAYER_THREAD) { 3814 __kmp_hier_scheds.append(sched, chunk, layer); 3815 } else 3816 #endif 3817 { 3818 __kmp_chunk = chunk; 3819 __kmp_sched = sched; 3820 } 3821 return ptr; 3822 } 3823 3824 static void __kmp_stg_parse_omp_schedule(char const *name, char const *value, 3825 void *data) { 3826 size_t length; 3827 const char *ptr = value; 3828 SKIP_WS(ptr); 3829 if (value) { 3830 length = KMP_STRLEN(value); 3831 if (length) { 3832 if (value[length - 1] == '"' || value[length - 1] == '\'') 3833 KMP_WARNING(UnbalancedQuotes, name); 3834 /* get the specified scheduling style */ 3835 #if KMP_USE_HIER_SCHED 3836 if (!__kmp_strcasecmp_with_sentinel("EXPERIMENTAL", ptr, ' ')) { 3837 SKIP_TOKEN(ptr); 3838 SKIP_WS(ptr); 3839 while ((ptr = __kmp_parse_single_omp_schedule(name, ptr, true))) { 3840 while (*ptr == ' ' || *ptr == '\t' || *ptr == ':') 3841 ptr++; 3842 if (*ptr == '\0') 3843 break; 3844 } 3845 } else 3846 #endif 3847 __kmp_parse_single_omp_schedule(name, ptr); 3848 } else 3849 KMP_WARNING(EmptyString, name); 3850 } 3851 #if KMP_USE_HIER_SCHED 3852 __kmp_hier_scheds.sort(); 3853 #endif 3854 K_DIAG(1, ("__kmp_static == %d\n", __kmp_static)) 3855 K_DIAG(1, ("__kmp_guided == %d\n", __kmp_guided)) 3856 K_DIAG(1, ("__kmp_sched == %d\n", __kmp_sched)) 3857 K_DIAG(1, ("__kmp_chunk == %d\n", __kmp_chunk)) 3858 } // __kmp_stg_parse_omp_schedule 3859 3860 static void __kmp_stg_print_omp_schedule(kmp_str_buf_t *buffer, 3861 char const *name, void *data) { 3862 if (__kmp_env_format) { 3863 KMP_STR_BUF_PRINT_NAME_EX(name); 3864 } else { 3865 __kmp_str_buf_print(buffer, " %s='", name); 3866 } 3867 enum sched_type sched = SCHEDULE_WITHOUT_MODIFIERS(__kmp_sched); 3868 if (SCHEDULE_HAS_MONOTONIC(__kmp_sched)) { 3869 __kmp_str_buf_print(buffer, "monotonic:"); 3870 } else if (SCHEDULE_HAS_NONMONOTONIC(__kmp_sched)) { 3871 __kmp_str_buf_print(buffer, "nonmonotonic:"); 3872 } 3873 if (__kmp_chunk) { 3874 switch (sched) { 3875 case kmp_sch_dynamic_chunked: 3876 __kmp_str_buf_print(buffer, "%s,%d'\n", "dynamic", __kmp_chunk); 3877 break; 3878 case kmp_sch_guided_iterative_chunked: 3879 case kmp_sch_guided_analytical_chunked: 3880 __kmp_str_buf_print(buffer, "%s,%d'\n", "guided", __kmp_chunk); 3881 break; 3882 case kmp_sch_trapezoidal: 3883 __kmp_str_buf_print(buffer, "%s,%d'\n", "trapezoidal", __kmp_chunk); 3884 break; 3885 case kmp_sch_static: 3886 case kmp_sch_static_chunked: 3887 case kmp_sch_static_balanced: 3888 case kmp_sch_static_greedy: 3889 __kmp_str_buf_print(buffer, "%s,%d'\n", "static", __kmp_chunk); 3890 break; 3891 case kmp_sch_static_steal: 3892 __kmp_str_buf_print(buffer, "%s,%d'\n", "static_steal", __kmp_chunk); 3893 break; 3894 case kmp_sch_auto: 3895 __kmp_str_buf_print(buffer, "%s,%d'\n", "auto", __kmp_chunk); 3896 break; 3897 } 3898 } else { 3899 switch (sched) { 3900 case kmp_sch_dynamic_chunked: 3901 __kmp_str_buf_print(buffer, "%s'\n", "dynamic"); 3902 break; 3903 case kmp_sch_guided_iterative_chunked: 3904 case kmp_sch_guided_analytical_chunked: 3905 __kmp_str_buf_print(buffer, "%s'\n", "guided"); 3906 break; 3907 case kmp_sch_trapezoidal: 3908 __kmp_str_buf_print(buffer, "%s'\n", "trapezoidal"); 3909 break; 3910 case kmp_sch_static: 3911 case kmp_sch_static_chunked: 3912 case kmp_sch_static_balanced: 3913 case kmp_sch_static_greedy: 3914 __kmp_str_buf_print(buffer, "%s'\n", "static"); 3915 break; 3916 case kmp_sch_static_steal: 3917 __kmp_str_buf_print(buffer, "%s'\n", "static_steal"); 3918 break; 3919 case kmp_sch_auto: 3920 __kmp_str_buf_print(buffer, "%s'\n", "auto"); 3921 break; 3922 } 3923 } 3924 } // __kmp_stg_print_omp_schedule 3925 3926 #if KMP_USE_HIER_SCHED 3927 // ----------------------------------------------------------------------------- 3928 // KMP_DISP_HAND_THREAD 3929 static void __kmp_stg_parse_kmp_hand_thread(char const *name, char const *value, 3930 void *data) { 3931 __kmp_stg_parse_bool(name, value, &(__kmp_dispatch_hand_threading)); 3932 } // __kmp_stg_parse_kmp_hand_thread 3933 3934 static void __kmp_stg_print_kmp_hand_thread(kmp_str_buf_t *buffer, 3935 char const *name, void *data) { 3936 __kmp_stg_print_bool(buffer, name, __kmp_dispatch_hand_threading); 3937 } // __kmp_stg_print_kmp_hand_thread 3938 #endif 3939 3940 // ----------------------------------------------------------------------------- 3941 // KMP_ATOMIC_MODE 3942 3943 static void __kmp_stg_parse_atomic_mode(char const *name, char const *value, 3944 void *data) { 3945 // Modes: 0 -- do not change default; 1 -- Intel perf mode, 2 -- GOMP 3946 // compatibility mode. 3947 int mode = 0; 3948 int max = 1; 3949 #ifdef KMP_GOMP_COMPAT 3950 max = 2; 3951 #endif /* KMP_GOMP_COMPAT */ 3952 __kmp_stg_parse_int(name, value, 0, max, &mode); 3953 // TODO; parse_int is not very suitable for this case. In case of overflow it 3954 // is better to use 3955 // 0 rather that max value. 3956 if (mode > 0) { 3957 __kmp_atomic_mode = mode; 3958 } 3959 } // __kmp_stg_parse_atomic_mode 3960 3961 static void __kmp_stg_print_atomic_mode(kmp_str_buf_t *buffer, char const *name, 3962 void *data) { 3963 __kmp_stg_print_int(buffer, name, __kmp_atomic_mode); 3964 } // __kmp_stg_print_atomic_mode 3965 3966 // ----------------------------------------------------------------------------- 3967 // KMP_CONSISTENCY_CHECK 3968 3969 static void __kmp_stg_parse_consistency_check(char const *name, 3970 char const *value, void *data) { 3971 if (!__kmp_strcasecmp_with_sentinel("all", value, 0)) { 3972 // Note, this will not work from kmp_set_defaults because th_cons stack was 3973 // not allocated 3974 // for existed thread(s) thus the first __kmp_push_<construct> will break 3975 // with assertion. 3976 // TODO: allocate th_cons if called from kmp_set_defaults. 3977 __kmp_env_consistency_check = TRUE; 3978 } else if (!__kmp_strcasecmp_with_sentinel("none", value, 0)) { 3979 __kmp_env_consistency_check = FALSE; 3980 } else { 3981 KMP_WARNING(StgInvalidValue, name, value); 3982 } 3983 } // __kmp_stg_parse_consistency_check 3984 3985 static void __kmp_stg_print_consistency_check(kmp_str_buf_t *buffer, 3986 char const *name, void *data) { 3987 #if KMP_DEBUG 3988 const char *value = NULL; 3989 3990 if (__kmp_env_consistency_check) { 3991 value = "all"; 3992 } else { 3993 value = "none"; 3994 } 3995 3996 if (value != NULL) { 3997 __kmp_stg_print_str(buffer, name, value); 3998 } 3999 #endif /* KMP_DEBUG */ 4000 } // __kmp_stg_print_consistency_check 4001 4002 #if USE_ITT_BUILD 4003 // ----------------------------------------------------------------------------- 4004 // KMP_ITT_PREPARE_DELAY 4005 4006 #if USE_ITT_NOTIFY 4007 4008 static void __kmp_stg_parse_itt_prepare_delay(char const *name, 4009 char const *value, void *data) { 4010 // Experimental code: KMP_ITT_PREPARE_DELAY specifies numbert of loop 4011 // iterations. 4012 int delay = 0; 4013 __kmp_stg_parse_int(name, value, 0, INT_MAX, &delay); 4014 __kmp_itt_prepare_delay = delay; 4015 } // __kmp_str_parse_itt_prepare_delay 4016 4017 static void __kmp_stg_print_itt_prepare_delay(kmp_str_buf_t *buffer, 4018 char const *name, void *data) { 4019 __kmp_stg_print_uint64(buffer, name, __kmp_itt_prepare_delay); 4020 4021 } // __kmp_str_print_itt_prepare_delay 4022 4023 #endif // USE_ITT_NOTIFY 4024 #endif /* USE_ITT_BUILD */ 4025 4026 // ----------------------------------------------------------------------------- 4027 // KMP_MALLOC_POOL_INCR 4028 4029 static void __kmp_stg_parse_malloc_pool_incr(char const *name, 4030 char const *value, void *data) { 4031 __kmp_stg_parse_size(name, value, KMP_MIN_MALLOC_POOL_INCR, 4032 KMP_MAX_MALLOC_POOL_INCR, NULL, &__kmp_malloc_pool_incr, 4033 1); 4034 } // __kmp_stg_parse_malloc_pool_incr 4035 4036 static void __kmp_stg_print_malloc_pool_incr(kmp_str_buf_t *buffer, 4037 char const *name, void *data) { 4038 __kmp_stg_print_size(buffer, name, __kmp_malloc_pool_incr); 4039 4040 } // _kmp_stg_print_malloc_pool_incr 4041 4042 #ifdef KMP_DEBUG 4043 4044 // ----------------------------------------------------------------------------- 4045 // KMP_PAR_RANGE 4046 4047 static void __kmp_stg_parse_par_range_env(char const *name, char const *value, 4048 void *data) { 4049 __kmp_stg_parse_par_range(name, value, &__kmp_par_range, 4050 __kmp_par_range_routine, __kmp_par_range_filename, 4051 &__kmp_par_range_lb, &__kmp_par_range_ub); 4052 } // __kmp_stg_parse_par_range_env 4053 4054 static void __kmp_stg_print_par_range_env(kmp_str_buf_t *buffer, 4055 char const *name, void *data) { 4056 if (__kmp_par_range != 0) { 4057 __kmp_stg_print_str(buffer, name, par_range_to_print); 4058 } 4059 } // __kmp_stg_print_par_range_env 4060 4061 #endif 4062 4063 // ----------------------------------------------------------------------------- 4064 // KMP_GTID_MODE 4065 4066 static void __kmp_stg_parse_gtid_mode(char const *name, char const *value, 4067 void *data) { 4068 // Modes: 4069 // 0 -- do not change default 4070 // 1 -- sp search 4071 // 2 -- use "keyed" TLS var, i.e. 4072 // pthread_getspecific(Linux* OS/OS X*) or TlsGetValue(Windows* OS) 4073 // 3 -- __declspec(thread) TLS var in tdata section 4074 int mode = 0; 4075 int max = 2; 4076 #ifdef KMP_TDATA_GTID 4077 max = 3; 4078 #endif /* KMP_TDATA_GTID */ 4079 __kmp_stg_parse_int(name, value, 0, max, &mode); 4080 // TODO; parse_int is not very suitable for this case. In case of overflow it 4081 // is better to use 0 rather that max value. 4082 if (mode == 0) { 4083 __kmp_adjust_gtid_mode = TRUE; 4084 } else { 4085 __kmp_gtid_mode = mode; 4086 __kmp_adjust_gtid_mode = FALSE; 4087 } 4088 } // __kmp_str_parse_gtid_mode 4089 4090 static void __kmp_stg_print_gtid_mode(kmp_str_buf_t *buffer, char const *name, 4091 void *data) { 4092 if (__kmp_adjust_gtid_mode) { 4093 __kmp_stg_print_int(buffer, name, 0); 4094 } else { 4095 __kmp_stg_print_int(buffer, name, __kmp_gtid_mode); 4096 } 4097 } // __kmp_stg_print_gtid_mode 4098 4099 // ----------------------------------------------------------------------------- 4100 // KMP_NUM_LOCKS_IN_BLOCK 4101 4102 static void __kmp_stg_parse_lock_block(char const *name, char const *value, 4103 void *data) { 4104 __kmp_stg_parse_int(name, value, 0, KMP_INT_MAX, &__kmp_num_locks_in_block); 4105 } // __kmp_str_parse_lock_block 4106 4107 static void __kmp_stg_print_lock_block(kmp_str_buf_t *buffer, char const *name, 4108 void *data) { 4109 __kmp_stg_print_int(buffer, name, __kmp_num_locks_in_block); 4110 } // __kmp_stg_print_lock_block 4111 4112 // ----------------------------------------------------------------------------- 4113 // KMP_LOCK_KIND 4114 4115 #if KMP_USE_DYNAMIC_LOCK 4116 #define KMP_STORE_LOCK_SEQ(a) (__kmp_user_lock_seq = lockseq_##a) 4117 #else 4118 #define KMP_STORE_LOCK_SEQ(a) 4119 #endif 4120 4121 static void __kmp_stg_parse_lock_kind(char const *name, char const *value, 4122 void *data) { 4123 if (__kmp_init_user_locks) { 4124 KMP_WARNING(EnvLockWarn, name); 4125 return; 4126 } 4127 4128 if (__kmp_str_match("tas", 2, value) || 4129 __kmp_str_match("test and set", 2, value) || 4130 __kmp_str_match("test_and_set", 2, value) || 4131 __kmp_str_match("test-and-set", 2, value) || 4132 __kmp_str_match("test andset", 2, value) || 4133 __kmp_str_match("test_andset", 2, value) || 4134 __kmp_str_match("test-andset", 2, value) || 4135 __kmp_str_match("testand set", 2, value) || 4136 __kmp_str_match("testand_set", 2, value) || 4137 __kmp_str_match("testand-set", 2, value) || 4138 __kmp_str_match("testandset", 2, value)) { 4139 __kmp_user_lock_kind = lk_tas; 4140 KMP_STORE_LOCK_SEQ(tas); 4141 } 4142 #if KMP_USE_FUTEX 4143 else if (__kmp_str_match("futex", 1, value)) { 4144 if (__kmp_futex_determine_capable()) { 4145 __kmp_user_lock_kind = lk_futex; 4146 KMP_STORE_LOCK_SEQ(futex); 4147 } else { 4148 KMP_WARNING(FutexNotSupported, name, value); 4149 } 4150 } 4151 #endif 4152 else if (__kmp_str_match("ticket", 2, value)) { 4153 __kmp_user_lock_kind = lk_ticket; 4154 KMP_STORE_LOCK_SEQ(ticket); 4155 } else if (__kmp_str_match("queuing", 1, value) || 4156 __kmp_str_match("queue", 1, value)) { 4157 __kmp_user_lock_kind = lk_queuing; 4158 KMP_STORE_LOCK_SEQ(queuing); 4159 } else if (__kmp_str_match("drdpa ticket", 1, value) || 4160 __kmp_str_match("drdpa_ticket", 1, value) || 4161 __kmp_str_match("drdpa-ticket", 1, value) || 4162 __kmp_str_match("drdpaticket", 1, value) || 4163 __kmp_str_match("drdpa", 1, value)) { 4164 __kmp_user_lock_kind = lk_drdpa; 4165 KMP_STORE_LOCK_SEQ(drdpa); 4166 } 4167 #if KMP_USE_ADAPTIVE_LOCKS 4168 else if (__kmp_str_match("adaptive", 1, value)) { 4169 if (__kmp_cpuinfo.rtm) { // ??? Is cpuinfo available here? 4170 __kmp_user_lock_kind = lk_adaptive; 4171 KMP_STORE_LOCK_SEQ(adaptive); 4172 } else { 4173 KMP_WARNING(AdaptiveNotSupported, name, value); 4174 __kmp_user_lock_kind = lk_queuing; 4175 KMP_STORE_LOCK_SEQ(queuing); 4176 } 4177 } 4178 #endif // KMP_USE_ADAPTIVE_LOCKS 4179 #if KMP_USE_DYNAMIC_LOCK && KMP_USE_TSX 4180 else if (__kmp_str_match("rtm", 1, value)) { 4181 if (__kmp_cpuinfo.rtm) { 4182 __kmp_user_lock_kind = lk_rtm; 4183 KMP_STORE_LOCK_SEQ(rtm); 4184 } else { 4185 KMP_WARNING(AdaptiveNotSupported, name, value); 4186 __kmp_user_lock_kind = lk_queuing; 4187 KMP_STORE_LOCK_SEQ(queuing); 4188 } 4189 } else if (__kmp_str_match("hle", 1, value)) { 4190 __kmp_user_lock_kind = lk_hle; 4191 KMP_STORE_LOCK_SEQ(hle); 4192 } 4193 #endif 4194 else { 4195 KMP_WARNING(StgInvalidValue, name, value); 4196 } 4197 } 4198 4199 static void __kmp_stg_print_lock_kind(kmp_str_buf_t *buffer, char const *name, 4200 void *data) { 4201 const char *value = NULL; 4202 4203 switch (__kmp_user_lock_kind) { 4204 case lk_default: 4205 value = "default"; 4206 break; 4207 4208 case lk_tas: 4209 value = "tas"; 4210 break; 4211 4212 #if KMP_USE_FUTEX 4213 case lk_futex: 4214 value = "futex"; 4215 break; 4216 #endif 4217 4218 #if KMP_USE_DYNAMIC_LOCK && KMP_USE_TSX 4219 case lk_rtm: 4220 value = "rtm"; 4221 break; 4222 4223 case lk_hle: 4224 value = "hle"; 4225 break; 4226 #endif 4227 4228 case lk_ticket: 4229 value = "ticket"; 4230 break; 4231 4232 case lk_queuing: 4233 value = "queuing"; 4234 break; 4235 4236 case lk_drdpa: 4237 value = "drdpa"; 4238 break; 4239 #if KMP_USE_ADAPTIVE_LOCKS 4240 case lk_adaptive: 4241 value = "adaptive"; 4242 break; 4243 #endif 4244 } 4245 4246 if (value != NULL) { 4247 __kmp_stg_print_str(buffer, name, value); 4248 } 4249 } 4250 4251 // ----------------------------------------------------------------------------- 4252 // KMP_SPIN_BACKOFF_PARAMS 4253 4254 // KMP_SPIN_BACKOFF_PARAMS=max_backoff[,min_tick] (max backoff size, min tick 4255 // for machine pause) 4256 static void __kmp_stg_parse_spin_backoff_params(const char *name, 4257 const char *value, void *data) { 4258 const char *next = value; 4259 4260 int total = 0; // Count elements that were set. It'll be used as an array size 4261 int prev_comma = FALSE; // For correct processing sequential commas 4262 int i; 4263 4264 kmp_uint32 max_backoff = __kmp_spin_backoff_params.max_backoff; 4265 kmp_uint32 min_tick = __kmp_spin_backoff_params.min_tick; 4266 4267 // Run only 3 iterations because it is enough to read two values or find a 4268 // syntax error 4269 for (i = 0; i < 3; i++) { 4270 SKIP_WS(next); 4271 4272 if (*next == '\0') { 4273 break; 4274 } 4275 // Next character is not an integer or not a comma OR number of values > 2 4276 // => end of list 4277 if (((*next < '0' || *next > '9') && *next != ',') || total > 2) { 4278 KMP_WARNING(EnvSyntaxError, name, value); 4279 return; 4280 } 4281 // The next character is ',' 4282 if (*next == ',') { 4283 // ',' is the fisrt character 4284 if (total == 0 || prev_comma) { 4285 total++; 4286 } 4287 prev_comma = TRUE; 4288 next++; // skip ',' 4289 SKIP_WS(next); 4290 } 4291 // Next character is a digit 4292 if (*next >= '0' && *next <= '9') { 4293 int num; 4294 const char *buf = next; 4295 char const *msg = NULL; 4296 prev_comma = FALSE; 4297 SKIP_DIGITS(next); 4298 total++; 4299 4300 const char *tmp = next; 4301 SKIP_WS(tmp); 4302 if ((*next == ' ' || *next == '\t') && (*tmp >= '0' && *tmp <= '9')) { 4303 KMP_WARNING(EnvSpacesNotAllowed, name, value); 4304 return; 4305 } 4306 4307 num = __kmp_str_to_int(buf, *next); 4308 if (num <= 0) { // The number of retries should be > 0 4309 msg = KMP_I18N_STR(ValueTooSmall); 4310 num = 1; 4311 } else if (num > KMP_INT_MAX) { 4312 msg = KMP_I18N_STR(ValueTooLarge); 4313 num = KMP_INT_MAX; 4314 } 4315 if (msg != NULL) { 4316 // Message is not empty. Print warning. 4317 KMP_WARNING(ParseSizeIntWarn, name, value, msg); 4318 KMP_INFORM(Using_int_Value, name, num); 4319 } 4320 if (total == 1) { 4321 max_backoff = num; 4322 } else if (total == 2) { 4323 min_tick = num; 4324 } 4325 } 4326 } 4327 KMP_DEBUG_ASSERT(total > 0); 4328 if (total <= 0) { 4329 KMP_WARNING(EnvSyntaxError, name, value); 4330 return; 4331 } 4332 __kmp_spin_backoff_params.max_backoff = max_backoff; 4333 __kmp_spin_backoff_params.min_tick = min_tick; 4334 } 4335 4336 static void __kmp_stg_print_spin_backoff_params(kmp_str_buf_t *buffer, 4337 char const *name, void *data) { 4338 if (__kmp_env_format) { 4339 KMP_STR_BUF_PRINT_NAME_EX(name); 4340 } else { 4341 __kmp_str_buf_print(buffer, " %s='", name); 4342 } 4343 __kmp_str_buf_print(buffer, "%d,%d'\n", __kmp_spin_backoff_params.max_backoff, 4344 __kmp_spin_backoff_params.min_tick); 4345 } 4346 4347 #if KMP_USE_ADAPTIVE_LOCKS 4348 4349 // ----------------------------------------------------------------------------- 4350 // KMP_ADAPTIVE_LOCK_PROPS, KMP_SPECULATIVE_STATSFILE 4351 4352 // Parse out values for the tunable parameters from a string of the form 4353 // KMP_ADAPTIVE_LOCK_PROPS=max_soft_retries[,max_badness] 4354 static void __kmp_stg_parse_adaptive_lock_props(const char *name, 4355 const char *value, void *data) { 4356 int max_retries = 0; 4357 int max_badness = 0; 4358 4359 const char *next = value; 4360 4361 int total = 0; // Count elements that were set. It'll be used as an array size 4362 int prev_comma = FALSE; // For correct processing sequential commas 4363 int i; 4364 4365 // Save values in the structure __kmp_speculative_backoff_params 4366 // Run only 3 iterations because it is enough to read two values or find a 4367 // syntax error 4368 for (i = 0; i < 3; i++) { 4369 SKIP_WS(next); 4370 4371 if (*next == '\0') { 4372 break; 4373 } 4374 // Next character is not an integer or not a comma OR number of values > 2 4375 // => end of list 4376 if (((*next < '0' || *next > '9') && *next != ',') || total > 2) { 4377 KMP_WARNING(EnvSyntaxError, name, value); 4378 return; 4379 } 4380 // The next character is ',' 4381 if (*next == ',') { 4382 // ',' is the fisrt character 4383 if (total == 0 || prev_comma) { 4384 total++; 4385 } 4386 prev_comma = TRUE; 4387 next++; // skip ',' 4388 SKIP_WS(next); 4389 } 4390 // Next character is a digit 4391 if (*next >= '0' && *next <= '9') { 4392 int num; 4393 const char *buf = next; 4394 char const *msg = NULL; 4395 prev_comma = FALSE; 4396 SKIP_DIGITS(next); 4397 total++; 4398 4399 const char *tmp = next; 4400 SKIP_WS(tmp); 4401 if ((*next == ' ' || *next == '\t') && (*tmp >= '0' && *tmp <= '9')) { 4402 KMP_WARNING(EnvSpacesNotAllowed, name, value); 4403 return; 4404 } 4405 4406 num = __kmp_str_to_int(buf, *next); 4407 if (num < 0) { // The number of retries should be >= 0 4408 msg = KMP_I18N_STR(ValueTooSmall); 4409 num = 1; 4410 } else if (num > KMP_INT_MAX) { 4411 msg = KMP_I18N_STR(ValueTooLarge); 4412 num = KMP_INT_MAX; 4413 } 4414 if (msg != NULL) { 4415 // Message is not empty. Print warning. 4416 KMP_WARNING(ParseSizeIntWarn, name, value, msg); 4417 KMP_INFORM(Using_int_Value, name, num); 4418 } 4419 if (total == 1) { 4420 max_retries = num; 4421 } else if (total == 2) { 4422 max_badness = num; 4423 } 4424 } 4425 } 4426 KMP_DEBUG_ASSERT(total > 0); 4427 if (total <= 0) { 4428 KMP_WARNING(EnvSyntaxError, name, value); 4429 return; 4430 } 4431 __kmp_adaptive_backoff_params.max_soft_retries = max_retries; 4432 __kmp_adaptive_backoff_params.max_badness = max_badness; 4433 } 4434 4435 static void __kmp_stg_print_adaptive_lock_props(kmp_str_buf_t *buffer, 4436 char const *name, void *data) { 4437 if (__kmp_env_format) { 4438 KMP_STR_BUF_PRINT_NAME_EX(name); 4439 } else { 4440 __kmp_str_buf_print(buffer, " %s='", name); 4441 } 4442 __kmp_str_buf_print(buffer, "%d,%d'\n", 4443 __kmp_adaptive_backoff_params.max_soft_retries, 4444 __kmp_adaptive_backoff_params.max_badness); 4445 } // __kmp_stg_print_adaptive_lock_props 4446 4447 #if KMP_DEBUG_ADAPTIVE_LOCKS 4448 4449 static void __kmp_stg_parse_speculative_statsfile(char const *name, 4450 char const *value, 4451 void *data) { 4452 __kmp_stg_parse_file(name, value, "", CCAST(char**, &__kmp_speculative_statsfile)); 4453 } // __kmp_stg_parse_speculative_statsfile 4454 4455 static void __kmp_stg_print_speculative_statsfile(kmp_str_buf_t *buffer, 4456 char const *name, 4457 void *data) { 4458 if (__kmp_str_match("-", 0, __kmp_speculative_statsfile)) { 4459 __kmp_stg_print_str(buffer, name, "stdout"); 4460 } else { 4461 __kmp_stg_print_str(buffer, name, __kmp_speculative_statsfile); 4462 } 4463 4464 } // __kmp_stg_print_speculative_statsfile 4465 4466 #endif // KMP_DEBUG_ADAPTIVE_LOCKS 4467 4468 #endif // KMP_USE_ADAPTIVE_LOCKS 4469 4470 // ----------------------------------------------------------------------------- 4471 // KMP_HW_SUBSET (was KMP_PLACE_THREADS) 4472 4473 // The longest observable sequense of items is 4474 // Socket-Node-Tile-Core-Thread 4475 // So, let's limit to 5 levels for now 4476 // The input string is usually short enough, let's use 512 limit for now 4477 #define MAX_T_LEVEL 5 4478 #define MAX_STR_LEN 512 4479 static void __kmp_stg_parse_hw_subset(char const *name, char const *value, 4480 void *data) { 4481 // Value example: 1s,5c@3,2T 4482 // Which means "use 1 socket, 5 cores with offset 3, 2 threads per core" 4483 kmp_setting_t **rivals = (kmp_setting_t **)data; 4484 if (strcmp(name, "KMP_PLACE_THREADS") == 0) { 4485 KMP_INFORM(EnvVarDeprecated, name, "KMP_HW_SUBSET"); 4486 } 4487 if (__kmp_stg_check_rivals(name, value, rivals)) { 4488 return; 4489 } 4490 4491 char *components[MAX_T_LEVEL]; 4492 char const *digits = "0123456789"; 4493 char input[MAX_STR_LEN]; 4494 size_t len = 0, mlen = MAX_STR_LEN; 4495 int level = 0; 4496 // Canonize the string (remove spaces, unify delimiters, etc.) 4497 char *pos = CCAST(char *, value); 4498 while (*pos && mlen) { 4499 if (*pos != ' ') { // skip spaces 4500 if (len == 0 && *pos == ':') { 4501 __kmp_hws_abs_flag = 1; // if the first symbol is ":", skip it 4502 } else { 4503 input[len] = toupper(*pos); 4504 if (input[len] == 'X') 4505 input[len] = ','; // unify delimiters of levels 4506 if (input[len] == 'O' && strchr(digits, *(pos + 1))) 4507 input[len] = '@'; // unify delimiters of offset 4508 len++; 4509 } 4510 } 4511 mlen--; 4512 pos++; 4513 } 4514 if (len == 0 || mlen == 0) 4515 goto err; // contents is either empty or too long 4516 input[len] = '\0'; 4517 __kmp_hws_requested = 1; // mark that subset requested 4518 // Split by delimiter 4519 pos = input; 4520 components[level++] = pos; 4521 while ((pos = strchr(pos, ','))) { 4522 if (level >= MAX_T_LEVEL) 4523 goto err; // too many components provided 4524 *pos = '\0'; // modify input and avoid more copying 4525 components[level++] = ++pos; // expect something after "," 4526 } 4527 // Check each component 4528 for (int i = 0; i < level; ++i) { 4529 int offset = 0; 4530 int num = atoi(components[i]); // each component should start with a number 4531 if ((pos = strchr(components[i], '@'))) { 4532 offset = atoi(pos + 1); // save offset 4533 *pos = '\0'; // cut the offset from the component 4534 } 4535 pos = components[i] + strspn(components[i], digits); 4536 if (pos == components[i]) 4537 goto err; 4538 // detect the component type 4539 switch (*pos) { 4540 case 'S': // Socket 4541 if (__kmp_hws_socket.num > 0) 4542 goto err; // duplicate is not allowed 4543 __kmp_hws_socket.num = num; 4544 __kmp_hws_socket.offset = offset; 4545 break; 4546 case 'N': // NUMA Node 4547 if (__kmp_hws_node.num > 0) 4548 goto err; // duplicate is not allowed 4549 __kmp_hws_node.num = num; 4550 __kmp_hws_node.offset = offset; 4551 break; 4552 case 'L': // Cache 4553 if (*(pos + 1) == '2') { // L2 - Tile 4554 if (__kmp_hws_tile.num > 0) 4555 goto err; // duplicate is not allowed 4556 __kmp_hws_tile.num = num; 4557 __kmp_hws_tile.offset = offset; 4558 } else if (*(pos + 1) == '3') { // L3 - Socket 4559 if (__kmp_hws_socket.num > 0) 4560 goto err; // duplicate is not allowed 4561 __kmp_hws_socket.num = num; 4562 __kmp_hws_socket.offset = offset; 4563 } else if (*(pos + 1) == '1') { // L1 - Core 4564 if (__kmp_hws_core.num > 0) 4565 goto err; // duplicate is not allowed 4566 __kmp_hws_core.num = num; 4567 __kmp_hws_core.offset = offset; 4568 } 4569 break; 4570 case 'C': // Core (or Cache?) 4571 if (*(pos + 1) != 'A') { 4572 if (__kmp_hws_core.num > 0) 4573 goto err; // duplicate is not allowed 4574 __kmp_hws_core.num = num; 4575 __kmp_hws_core.offset = offset; 4576 } else { // Cache 4577 char *d = pos + strcspn(pos, digits); // find digit 4578 if (*d == '2') { // L2 - Tile 4579 if (__kmp_hws_tile.num > 0) 4580 goto err; // duplicate is not allowed 4581 __kmp_hws_tile.num = num; 4582 __kmp_hws_tile.offset = offset; 4583 } else if (*d == '3') { // L3 - Socket 4584 if (__kmp_hws_socket.num > 0) 4585 goto err; // duplicate is not allowed 4586 __kmp_hws_socket.num = num; 4587 __kmp_hws_socket.offset = offset; 4588 } else if (*d == '1') { // L1 - Core 4589 if (__kmp_hws_core.num > 0) 4590 goto err; // duplicate is not allowed 4591 __kmp_hws_core.num = num; 4592 __kmp_hws_core.offset = offset; 4593 } else { 4594 goto err; 4595 } 4596 } 4597 break; 4598 case 'T': // Thread 4599 if (__kmp_hws_proc.num > 0) 4600 goto err; // duplicate is not allowed 4601 __kmp_hws_proc.num = num; 4602 __kmp_hws_proc.offset = offset; 4603 break; 4604 default: 4605 goto err; 4606 } 4607 } 4608 return; 4609 err: 4610 KMP_WARNING(AffHWSubsetInvalid, name, value); 4611 __kmp_hws_requested = 0; // mark that subset not requested 4612 return; 4613 } 4614 4615 static void __kmp_stg_print_hw_subset(kmp_str_buf_t *buffer, char const *name, 4616 void *data) { 4617 if (__kmp_hws_requested) { 4618 int comma = 0; 4619 kmp_str_buf_t buf; 4620 __kmp_str_buf_init(&buf); 4621 if (__kmp_env_format) 4622 KMP_STR_BUF_PRINT_NAME_EX(name); 4623 else 4624 __kmp_str_buf_print(buffer, " %s='", name); 4625 if (__kmp_hws_socket.num) { 4626 __kmp_str_buf_print(&buf, "%ds", __kmp_hws_socket.num); 4627 if (__kmp_hws_socket.offset) 4628 __kmp_str_buf_print(&buf, "@%d", __kmp_hws_socket.offset); 4629 comma = 1; 4630 } 4631 if (__kmp_hws_node.num) { 4632 __kmp_str_buf_print(&buf, "%s%dn", comma ? "," : "", __kmp_hws_node.num); 4633 if (__kmp_hws_node.offset) 4634 __kmp_str_buf_print(&buf, "@%d", __kmp_hws_node.offset); 4635 comma = 1; 4636 } 4637 if (__kmp_hws_tile.num) { 4638 __kmp_str_buf_print(&buf, "%s%dL2", comma ? "," : "", __kmp_hws_tile.num); 4639 if (__kmp_hws_tile.offset) 4640 __kmp_str_buf_print(&buf, "@%d", __kmp_hws_tile.offset); 4641 comma = 1; 4642 } 4643 if (__kmp_hws_core.num) { 4644 __kmp_str_buf_print(&buf, "%s%dc", comma ? "," : "", __kmp_hws_core.num); 4645 if (__kmp_hws_core.offset) 4646 __kmp_str_buf_print(&buf, "@%d", __kmp_hws_core.offset); 4647 comma = 1; 4648 } 4649 if (__kmp_hws_proc.num) 4650 __kmp_str_buf_print(&buf, "%s%dt", comma ? "," : "", __kmp_hws_proc.num); 4651 __kmp_str_buf_print(buffer, "%s'\n", buf.str); 4652 __kmp_str_buf_free(&buf); 4653 } 4654 } 4655 4656 #if USE_ITT_BUILD 4657 // ----------------------------------------------------------------------------- 4658 // KMP_FORKJOIN_FRAMES 4659 4660 static void __kmp_stg_parse_forkjoin_frames(char const *name, char const *value, 4661 void *data) { 4662 __kmp_stg_parse_bool(name, value, &__kmp_forkjoin_frames); 4663 } // __kmp_stg_parse_forkjoin_frames 4664 4665 static void __kmp_stg_print_forkjoin_frames(kmp_str_buf_t *buffer, 4666 char const *name, void *data) { 4667 __kmp_stg_print_bool(buffer, name, __kmp_forkjoin_frames); 4668 } // __kmp_stg_print_forkjoin_frames 4669 4670 // ----------------------------------------------------------------------------- 4671 // KMP_FORKJOIN_FRAMES_MODE 4672 4673 static void __kmp_stg_parse_forkjoin_frames_mode(char const *name, 4674 char const *value, 4675 void *data) { 4676 __kmp_stg_parse_int(name, value, 0, 3, &__kmp_forkjoin_frames_mode); 4677 } // __kmp_stg_parse_forkjoin_frames 4678 4679 static void __kmp_stg_print_forkjoin_frames_mode(kmp_str_buf_t *buffer, 4680 char const *name, void *data) { 4681 __kmp_stg_print_int(buffer, name, __kmp_forkjoin_frames_mode); 4682 } // __kmp_stg_print_forkjoin_frames 4683 #endif /* USE_ITT_BUILD */ 4684 4685 // ----------------------------------------------------------------------------- 4686 // OMP_DISPLAY_ENV 4687 4688 #if OMP_40_ENABLED 4689 4690 static void __kmp_stg_parse_omp_display_env(char const *name, char const *value, 4691 void *data) { 4692 if (__kmp_str_match("VERBOSE", 1, value)) { 4693 __kmp_display_env_verbose = TRUE; 4694 } else { 4695 __kmp_stg_parse_bool(name, value, &__kmp_display_env); 4696 } 4697 4698 } // __kmp_stg_parse_omp_display_env 4699 4700 static void __kmp_stg_print_omp_display_env(kmp_str_buf_t *buffer, 4701 char const *name, void *data) { 4702 if (__kmp_display_env_verbose) { 4703 __kmp_stg_print_str(buffer, name, "VERBOSE"); 4704 } else { 4705 __kmp_stg_print_bool(buffer, name, __kmp_display_env); 4706 } 4707 } // __kmp_stg_print_omp_display_env 4708 4709 static void __kmp_stg_parse_omp_cancellation(char const *name, 4710 char const *value, void *data) { 4711 if (TCR_4(__kmp_init_parallel)) { 4712 KMP_WARNING(EnvParallelWarn, name); 4713 return; 4714 } // read value before first parallel only 4715 __kmp_stg_parse_bool(name, value, &__kmp_omp_cancellation); 4716 } // __kmp_stg_parse_omp_cancellation 4717 4718 static void __kmp_stg_print_omp_cancellation(kmp_str_buf_t *buffer, 4719 char const *name, void *data) { 4720 __kmp_stg_print_bool(buffer, name, __kmp_omp_cancellation); 4721 } // __kmp_stg_print_omp_cancellation 4722 4723 #endif 4724 4725 #if OMP_50_ENABLED && OMPT_SUPPORT 4726 static int __kmp_tool = 1; 4727 4728 static void __kmp_stg_parse_omp_tool(char const *name, char const *value, 4729 void *data) { 4730 __kmp_stg_parse_bool(name, value, &__kmp_tool); 4731 } // __kmp_stg_parse_omp_tool 4732 4733 static void __kmp_stg_print_omp_tool(kmp_str_buf_t *buffer, char const *name, 4734 void *data) { 4735 if (__kmp_env_format) { 4736 KMP_STR_BUF_PRINT_BOOL_EX(name, __kmp_tool, "enabled", "disabled"); 4737 } else { 4738 __kmp_str_buf_print(buffer, " %s=%s\n", name, 4739 __kmp_tool ? "enabled" : "disabled"); 4740 } 4741 } // __kmp_stg_print_omp_tool 4742 4743 static char *__kmp_tool_libraries = NULL; 4744 4745 static void __kmp_stg_parse_omp_tool_libraries(char const *name, 4746 char const *value, void *data) { 4747 __kmp_stg_parse_str(name, value, &__kmp_tool_libraries); 4748 } // __kmp_stg_parse_omp_tool_libraries 4749 4750 static void __kmp_stg_print_omp_tool_libraries(kmp_str_buf_t *buffer, 4751 char const *name, void *data) { 4752 if (__kmp_tool_libraries) 4753 __kmp_stg_print_str(buffer, name, __kmp_tool_libraries); 4754 else { 4755 if (__kmp_env_format) { 4756 KMP_STR_BUF_PRINT_NAME; 4757 } else { 4758 __kmp_str_buf_print(buffer, " %s", name); 4759 } 4760 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined)); 4761 } 4762 } // __kmp_stg_print_omp_tool_libraries 4763 4764 #endif 4765 4766 // Table. 4767 4768 static kmp_setting_t __kmp_stg_table[] = { 4769 4770 {"KMP_ALL_THREADS", __kmp_stg_parse_device_thread_limit, NULL, NULL, 0, 0}, 4771 {"KMP_BLOCKTIME", __kmp_stg_parse_blocktime, __kmp_stg_print_blocktime, 4772 NULL, 0, 0}, 4773 {"KMP_USE_YIELD", __kmp_stg_parse_use_yield, __kmp_stg_print_use_yield, 4774 NULL, 0, 0}, 4775 {"KMP_DUPLICATE_LIB_OK", __kmp_stg_parse_duplicate_lib_ok, 4776 __kmp_stg_print_duplicate_lib_ok, NULL, 0, 0}, 4777 {"KMP_LIBRARY", __kmp_stg_parse_wait_policy, __kmp_stg_print_wait_policy, 4778 NULL, 0, 0}, 4779 {"KMP_DEVICE_THREAD_LIMIT", __kmp_stg_parse_device_thread_limit, 4780 __kmp_stg_print_device_thread_limit, NULL, 0, 0}, 4781 #if KMP_USE_MONITOR 4782 {"KMP_MONITOR_STACKSIZE", __kmp_stg_parse_monitor_stacksize, 4783 __kmp_stg_print_monitor_stacksize, NULL, 0, 0}, 4784 #endif 4785 {"KMP_SETTINGS", __kmp_stg_parse_settings, __kmp_stg_print_settings, NULL, 4786 0, 0}, 4787 {"KMP_STACKOFFSET", __kmp_stg_parse_stackoffset, 4788 __kmp_stg_print_stackoffset, NULL, 0, 0}, 4789 {"KMP_STACKSIZE", __kmp_stg_parse_stacksize, __kmp_stg_print_stacksize, 4790 NULL, 0, 0}, 4791 {"KMP_STACKPAD", __kmp_stg_parse_stackpad, __kmp_stg_print_stackpad, NULL, 4792 0, 0}, 4793 {"KMP_VERSION", __kmp_stg_parse_version, __kmp_stg_print_version, NULL, 0, 4794 0}, 4795 {"KMP_WARNINGS", __kmp_stg_parse_warnings, __kmp_stg_print_warnings, NULL, 4796 0, 0}, 4797 4798 {"OMP_NESTED", __kmp_stg_parse_nested, __kmp_stg_print_nested, NULL, 0, 0}, 4799 {"OMP_NUM_THREADS", __kmp_stg_parse_num_threads, 4800 __kmp_stg_print_num_threads, NULL, 0, 0}, 4801 {"OMP_STACKSIZE", __kmp_stg_parse_stacksize, __kmp_stg_print_stacksize, 4802 NULL, 0, 0}, 4803 4804 {"KMP_TASKING", __kmp_stg_parse_tasking, __kmp_stg_print_tasking, NULL, 0, 4805 0}, 4806 {"KMP_TASK_STEALING_CONSTRAINT", __kmp_stg_parse_task_stealing, 4807 __kmp_stg_print_task_stealing, NULL, 0, 0}, 4808 {"OMP_MAX_ACTIVE_LEVELS", __kmp_stg_parse_max_active_levels, 4809 __kmp_stg_print_max_active_levels, NULL, 0, 0}, 4810 #if OMP_40_ENABLED 4811 {"OMP_DEFAULT_DEVICE", __kmp_stg_parse_default_device, 4812 __kmp_stg_print_default_device, NULL, 0, 0}, 4813 #endif 4814 #if OMP_50_ENABLED 4815 {"OMP_TARGET_OFFLOAD", __kmp_stg_parse_target_offload, 4816 __kmp_stg_print_target_offload, NULL, 0, 0}, 4817 #endif 4818 #if OMP_45_ENABLED 4819 {"OMP_MAX_TASK_PRIORITY", __kmp_stg_parse_max_task_priority, 4820 __kmp_stg_print_max_task_priority, NULL, 0, 0}, 4821 {"KMP_TASKLOOP_MIN_TASKS", __kmp_stg_parse_taskloop_min_tasks, 4822 __kmp_stg_print_taskloop_min_tasks, NULL, 0, 0}, 4823 #endif 4824 {"OMP_THREAD_LIMIT", __kmp_stg_parse_thread_limit, 4825 __kmp_stg_print_thread_limit, NULL, 0, 0}, 4826 {"KMP_TEAMS_THREAD_LIMIT", __kmp_stg_parse_teams_thread_limit, 4827 __kmp_stg_print_teams_thread_limit, NULL, 0, 0}, 4828 {"OMP_WAIT_POLICY", __kmp_stg_parse_wait_policy, 4829 __kmp_stg_print_wait_policy, NULL, 0, 0}, 4830 {"KMP_DISP_NUM_BUFFERS", __kmp_stg_parse_disp_buffers, 4831 __kmp_stg_print_disp_buffers, NULL, 0, 0}, 4832 #if KMP_NESTED_HOT_TEAMS 4833 {"KMP_HOT_TEAMS_MAX_LEVEL", __kmp_stg_parse_hot_teams_level, 4834 __kmp_stg_print_hot_teams_level, NULL, 0, 0}, 4835 {"KMP_HOT_TEAMS_MODE", __kmp_stg_parse_hot_teams_mode, 4836 __kmp_stg_print_hot_teams_mode, NULL, 0, 0}, 4837 #endif // KMP_NESTED_HOT_TEAMS 4838 4839 #if KMP_HANDLE_SIGNALS 4840 {"KMP_HANDLE_SIGNALS", __kmp_stg_parse_handle_signals, 4841 __kmp_stg_print_handle_signals, NULL, 0, 0}, 4842 #endif 4843 4844 #if KMP_ARCH_X86 || KMP_ARCH_X86_64 4845 {"KMP_INHERIT_FP_CONTROL", __kmp_stg_parse_inherit_fp_control, 4846 __kmp_stg_print_inherit_fp_control, NULL, 0, 0}, 4847 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */ 4848 4849 #ifdef KMP_GOMP_COMPAT 4850 {"GOMP_STACKSIZE", __kmp_stg_parse_stacksize, NULL, NULL, 0, 0}, 4851 #endif 4852 4853 #ifdef KMP_DEBUG 4854 {"KMP_A_DEBUG", __kmp_stg_parse_a_debug, __kmp_stg_print_a_debug, NULL, 0, 4855 0}, 4856 {"KMP_B_DEBUG", __kmp_stg_parse_b_debug, __kmp_stg_print_b_debug, NULL, 0, 4857 0}, 4858 {"KMP_C_DEBUG", __kmp_stg_parse_c_debug, __kmp_stg_print_c_debug, NULL, 0, 4859 0}, 4860 {"KMP_D_DEBUG", __kmp_stg_parse_d_debug, __kmp_stg_print_d_debug, NULL, 0, 4861 0}, 4862 {"KMP_E_DEBUG", __kmp_stg_parse_e_debug, __kmp_stg_print_e_debug, NULL, 0, 4863 0}, 4864 {"KMP_F_DEBUG", __kmp_stg_parse_f_debug, __kmp_stg_print_f_debug, NULL, 0, 4865 0}, 4866 {"KMP_DEBUG", __kmp_stg_parse_debug, NULL, /* no print */ NULL, 0, 0}, 4867 {"KMP_DEBUG_BUF", __kmp_stg_parse_debug_buf, __kmp_stg_print_debug_buf, 4868 NULL, 0, 0}, 4869 {"KMP_DEBUG_BUF_ATOMIC", __kmp_stg_parse_debug_buf_atomic, 4870 __kmp_stg_print_debug_buf_atomic, NULL, 0, 0}, 4871 {"KMP_DEBUG_BUF_CHARS", __kmp_stg_parse_debug_buf_chars, 4872 __kmp_stg_print_debug_buf_chars, NULL, 0, 0}, 4873 {"KMP_DEBUG_BUF_LINES", __kmp_stg_parse_debug_buf_lines, 4874 __kmp_stg_print_debug_buf_lines, NULL, 0, 0}, 4875 {"KMP_DIAG", __kmp_stg_parse_diag, __kmp_stg_print_diag, NULL, 0, 0}, 4876 4877 {"KMP_PAR_RANGE", __kmp_stg_parse_par_range_env, 4878 __kmp_stg_print_par_range_env, NULL, 0, 0}, 4879 #endif // KMP_DEBUG 4880 4881 {"KMP_ALIGN_ALLOC", __kmp_stg_parse_align_alloc, 4882 __kmp_stg_print_align_alloc, NULL, 0, 0}, 4883 4884 {"KMP_PLAIN_BARRIER", __kmp_stg_parse_barrier_branch_bit, 4885 __kmp_stg_print_barrier_branch_bit, NULL, 0, 0}, 4886 {"KMP_PLAIN_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern, 4887 __kmp_stg_print_barrier_pattern, NULL, 0, 0}, 4888 {"KMP_FORKJOIN_BARRIER", __kmp_stg_parse_barrier_branch_bit, 4889 __kmp_stg_print_barrier_branch_bit, NULL, 0, 0}, 4890 {"KMP_FORKJOIN_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern, 4891 __kmp_stg_print_barrier_pattern, NULL, 0, 0}, 4892 #if KMP_FAST_REDUCTION_BARRIER 4893 {"KMP_REDUCTION_BARRIER", __kmp_stg_parse_barrier_branch_bit, 4894 __kmp_stg_print_barrier_branch_bit, NULL, 0, 0}, 4895 {"KMP_REDUCTION_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern, 4896 __kmp_stg_print_barrier_pattern, NULL, 0, 0}, 4897 #endif 4898 4899 {"KMP_ABORT_DELAY", __kmp_stg_parse_abort_delay, 4900 __kmp_stg_print_abort_delay, NULL, 0, 0}, 4901 {"KMP_CPUINFO_FILE", __kmp_stg_parse_cpuinfo_file, 4902 __kmp_stg_print_cpuinfo_file, NULL, 0, 0}, 4903 {"KMP_FORCE_REDUCTION", __kmp_stg_parse_force_reduction, 4904 __kmp_stg_print_force_reduction, NULL, 0, 0}, 4905 {"KMP_DETERMINISTIC_REDUCTION", __kmp_stg_parse_force_reduction, 4906 __kmp_stg_print_force_reduction, NULL, 0, 0}, 4907 {"KMP_STORAGE_MAP", __kmp_stg_parse_storage_map, 4908 __kmp_stg_print_storage_map, NULL, 0, 0}, 4909 {"KMP_ALL_THREADPRIVATE", __kmp_stg_parse_all_threadprivate, 4910 __kmp_stg_print_all_threadprivate, NULL, 0, 0}, 4911 {"KMP_FOREIGN_THREADS_THREADPRIVATE", 4912 __kmp_stg_parse_foreign_threads_threadprivate, 4913 __kmp_stg_print_foreign_threads_threadprivate, NULL, 0, 0}, 4914 4915 #if KMP_AFFINITY_SUPPORTED 4916 {"KMP_AFFINITY", __kmp_stg_parse_affinity, __kmp_stg_print_affinity, NULL, 4917 0, 0}, 4918 #ifdef KMP_GOMP_COMPAT 4919 {"GOMP_CPU_AFFINITY", __kmp_stg_parse_gomp_cpu_affinity, NULL, 4920 /* no print */ NULL, 0, 0}, 4921 #endif /* KMP_GOMP_COMPAT */ 4922 #if OMP_40_ENABLED 4923 {"OMP_PROC_BIND", __kmp_stg_parse_proc_bind, __kmp_stg_print_proc_bind, 4924 NULL, 0, 0}, 4925 {"OMP_PLACES", __kmp_stg_parse_places, __kmp_stg_print_places, NULL, 0, 0}, 4926 #else 4927 {"OMP_PROC_BIND", __kmp_stg_parse_proc_bind, NULL, /* no print */ NULL, 0, 4928 0}, 4929 #endif /* OMP_40_ENABLED */ 4930 {"KMP_TOPOLOGY_METHOD", __kmp_stg_parse_topology_method, 4931 __kmp_stg_print_topology_method, NULL, 0, 0}, 4932 4933 #else 4934 4935 // KMP_AFFINITY is not supported on OS X*, nor is OMP_PLACES. 4936 // OMP_PROC_BIND and proc-bind-var are supported, however. 4937 #if OMP_40_ENABLED 4938 {"OMP_PROC_BIND", __kmp_stg_parse_proc_bind, __kmp_stg_print_proc_bind, 4939 NULL, 0, 0}, 4940 #endif 4941 4942 #endif // KMP_AFFINITY_SUPPORTED 4943 #if OMP_50_ENABLED 4944 {"OMP_DISPLAY_AFFINITY", __kmp_stg_parse_display_affinity, 4945 __kmp_stg_print_display_affinity, NULL, 0, 0}, 4946 {"OMP_AFFINITY_FORMAT", __kmp_stg_parse_affinity_format, 4947 __kmp_stg_print_affinity_format, NULL, 0, 0}, 4948 #endif 4949 {"KMP_INIT_AT_FORK", __kmp_stg_parse_init_at_fork, 4950 __kmp_stg_print_init_at_fork, NULL, 0, 0}, 4951 {"KMP_SCHEDULE", __kmp_stg_parse_schedule, __kmp_stg_print_schedule, NULL, 4952 0, 0}, 4953 {"OMP_SCHEDULE", __kmp_stg_parse_omp_schedule, __kmp_stg_print_omp_schedule, 4954 NULL, 0, 0}, 4955 #if KMP_USE_HIER_SCHED 4956 {"KMP_DISP_HAND_THREAD", __kmp_stg_parse_kmp_hand_thread, 4957 __kmp_stg_print_kmp_hand_thread, NULL, 0, 0}, 4958 #endif 4959 {"KMP_ATOMIC_MODE", __kmp_stg_parse_atomic_mode, 4960 __kmp_stg_print_atomic_mode, NULL, 0, 0}, 4961 {"KMP_CONSISTENCY_CHECK", __kmp_stg_parse_consistency_check, 4962 __kmp_stg_print_consistency_check, NULL, 0, 0}, 4963 4964 #if USE_ITT_BUILD && USE_ITT_NOTIFY 4965 {"KMP_ITT_PREPARE_DELAY", __kmp_stg_parse_itt_prepare_delay, 4966 __kmp_stg_print_itt_prepare_delay, NULL, 0, 0}, 4967 #endif /* USE_ITT_BUILD && USE_ITT_NOTIFY */ 4968 {"KMP_MALLOC_POOL_INCR", __kmp_stg_parse_malloc_pool_incr, 4969 __kmp_stg_print_malloc_pool_incr, NULL, 0, 0}, 4970 {"KMP_GTID_MODE", __kmp_stg_parse_gtid_mode, __kmp_stg_print_gtid_mode, 4971 NULL, 0, 0}, 4972 {"OMP_DYNAMIC", __kmp_stg_parse_omp_dynamic, __kmp_stg_print_omp_dynamic, 4973 NULL, 0, 0}, 4974 {"KMP_DYNAMIC_MODE", __kmp_stg_parse_kmp_dynamic_mode, 4975 __kmp_stg_print_kmp_dynamic_mode, NULL, 0, 0}, 4976 4977 #ifdef USE_LOAD_BALANCE 4978 {"KMP_LOAD_BALANCE_INTERVAL", __kmp_stg_parse_ld_balance_interval, 4979 __kmp_stg_print_ld_balance_interval, NULL, 0, 0}, 4980 #endif 4981 4982 {"KMP_NUM_LOCKS_IN_BLOCK", __kmp_stg_parse_lock_block, 4983 __kmp_stg_print_lock_block, NULL, 0, 0}, 4984 {"KMP_LOCK_KIND", __kmp_stg_parse_lock_kind, __kmp_stg_print_lock_kind, 4985 NULL, 0, 0}, 4986 {"KMP_SPIN_BACKOFF_PARAMS", __kmp_stg_parse_spin_backoff_params, 4987 __kmp_stg_print_spin_backoff_params, NULL, 0, 0}, 4988 #if KMP_USE_ADAPTIVE_LOCKS 4989 {"KMP_ADAPTIVE_LOCK_PROPS", __kmp_stg_parse_adaptive_lock_props, 4990 __kmp_stg_print_adaptive_lock_props, NULL, 0, 0}, 4991 #if KMP_DEBUG_ADAPTIVE_LOCKS 4992 {"KMP_SPECULATIVE_STATSFILE", __kmp_stg_parse_speculative_statsfile, 4993 __kmp_stg_print_speculative_statsfile, NULL, 0, 0}, 4994 #endif 4995 #endif // KMP_USE_ADAPTIVE_LOCKS 4996 {"KMP_PLACE_THREADS", __kmp_stg_parse_hw_subset, __kmp_stg_print_hw_subset, 4997 NULL, 0, 0}, 4998 {"KMP_HW_SUBSET", __kmp_stg_parse_hw_subset, __kmp_stg_print_hw_subset, 4999 NULL, 0, 0}, 5000 #if USE_ITT_BUILD 5001 {"KMP_FORKJOIN_FRAMES", __kmp_stg_parse_forkjoin_frames, 5002 __kmp_stg_print_forkjoin_frames, NULL, 0, 0}, 5003 {"KMP_FORKJOIN_FRAMES_MODE", __kmp_stg_parse_forkjoin_frames_mode, 5004 __kmp_stg_print_forkjoin_frames_mode, NULL, 0, 0}, 5005 #endif 5006 5007 #if OMP_40_ENABLED 5008 {"OMP_DISPLAY_ENV", __kmp_stg_parse_omp_display_env, 5009 __kmp_stg_print_omp_display_env, NULL, 0, 0}, 5010 {"OMP_CANCELLATION", __kmp_stg_parse_omp_cancellation, 5011 __kmp_stg_print_omp_cancellation, NULL, 0, 0}, 5012 #endif 5013 5014 #if OMP_50_ENABLED 5015 {"OMP_ALLOCATOR", __kmp_stg_parse_allocator, __kmp_stg_print_allocator, 5016 NULL, 0, 0}, 5017 #endif 5018 5019 #if OMP_50_ENABLED && OMPT_SUPPORT 5020 {"OMP_TOOL", __kmp_stg_parse_omp_tool, __kmp_stg_print_omp_tool, NULL, 0, 5021 0}, 5022 {"OMP_TOOL_LIBRARIES", __kmp_stg_parse_omp_tool_libraries, 5023 __kmp_stg_print_omp_tool_libraries, NULL, 0, 0}, 5024 #endif 5025 5026 {"", NULL, NULL, NULL, 0, 0}}; // settings 5027 5028 static int const __kmp_stg_count = 5029 sizeof(__kmp_stg_table) / sizeof(kmp_setting_t); 5030 5031 static inline kmp_setting_t *__kmp_stg_find(char const *name) { 5032 5033 int i; 5034 if (name != NULL) { 5035 for (i = 0; i < __kmp_stg_count; ++i) { 5036 if (strcmp(__kmp_stg_table[i].name, name) == 0) { 5037 return &__kmp_stg_table[i]; 5038 } 5039 } 5040 } 5041 return NULL; 5042 5043 } // __kmp_stg_find 5044 5045 static int __kmp_stg_cmp(void const *_a, void const *_b) { 5046 const kmp_setting_t *a = RCAST(const kmp_setting_t *, _a); 5047 const kmp_setting_t *b = RCAST(const kmp_setting_t *, _b); 5048 5049 // Process KMP_AFFINITY last. 5050 // It needs to come after OMP_PLACES and GOMP_CPU_AFFINITY. 5051 if (strcmp(a->name, "KMP_AFFINITY") == 0) { 5052 if (strcmp(b->name, "KMP_AFFINITY") == 0) { 5053 return 0; 5054 } 5055 return 1; 5056 } else if (strcmp(b->name, "KMP_AFFINITY") == 0) { 5057 return -1; 5058 } 5059 return strcmp(a->name, b->name); 5060 } // __kmp_stg_cmp 5061 5062 static void __kmp_stg_init(void) { 5063 5064 static int initialized = 0; 5065 5066 if (!initialized) { 5067 5068 // Sort table. 5069 qsort(__kmp_stg_table, __kmp_stg_count - 1, sizeof(kmp_setting_t), 5070 __kmp_stg_cmp); 5071 5072 { // Initialize *_STACKSIZE data. 5073 kmp_setting_t *kmp_stacksize = 5074 __kmp_stg_find("KMP_STACKSIZE"); // 1st priority. 5075 #ifdef KMP_GOMP_COMPAT 5076 kmp_setting_t *gomp_stacksize = 5077 __kmp_stg_find("GOMP_STACKSIZE"); // 2nd priority. 5078 #endif 5079 kmp_setting_t *omp_stacksize = 5080 __kmp_stg_find("OMP_STACKSIZE"); // 3rd priority. 5081 5082 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround. 5083 // !!! Compiler does not understand rivals is used and optimizes out 5084 // assignments 5085 // !!! rivals[ i ++ ] = ...; 5086 static kmp_setting_t *volatile rivals[4]; 5087 static kmp_stg_ss_data_t kmp_data = {1, CCAST(kmp_setting_t **, rivals)}; 5088 #ifdef KMP_GOMP_COMPAT 5089 static kmp_stg_ss_data_t gomp_data = {1024, 5090 CCAST(kmp_setting_t **, rivals)}; 5091 #endif 5092 static kmp_stg_ss_data_t omp_data = {1024, 5093 CCAST(kmp_setting_t **, rivals)}; 5094 int i = 0; 5095 5096 rivals[i++] = kmp_stacksize; 5097 #ifdef KMP_GOMP_COMPAT 5098 if (gomp_stacksize != NULL) { 5099 rivals[i++] = gomp_stacksize; 5100 } 5101 #endif 5102 rivals[i++] = omp_stacksize; 5103 rivals[i++] = NULL; 5104 5105 kmp_stacksize->data = &kmp_data; 5106 #ifdef KMP_GOMP_COMPAT 5107 if (gomp_stacksize != NULL) { 5108 gomp_stacksize->data = &gomp_data; 5109 } 5110 #endif 5111 omp_stacksize->data = &omp_data; 5112 } 5113 5114 { // Initialize KMP_LIBRARY and OMP_WAIT_POLICY data. 5115 kmp_setting_t *kmp_library = 5116 __kmp_stg_find("KMP_LIBRARY"); // 1st priority. 5117 kmp_setting_t *omp_wait_policy = 5118 __kmp_stg_find("OMP_WAIT_POLICY"); // 2nd priority. 5119 5120 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround. 5121 static kmp_setting_t *volatile rivals[3]; 5122 static kmp_stg_wp_data_t kmp_data = {0, CCAST(kmp_setting_t **, rivals)}; 5123 static kmp_stg_wp_data_t omp_data = {1, CCAST(kmp_setting_t **, rivals)}; 5124 int i = 0; 5125 5126 rivals[i++] = kmp_library; 5127 if (omp_wait_policy != NULL) { 5128 rivals[i++] = omp_wait_policy; 5129 } 5130 rivals[i++] = NULL; 5131 5132 kmp_library->data = &kmp_data; 5133 if (omp_wait_policy != NULL) { 5134 omp_wait_policy->data = &omp_data; 5135 } 5136 } 5137 5138 { // Initialize KMP_DEVICE_THREAD_LIMIT and KMP_ALL_THREADS 5139 kmp_setting_t *kmp_device_thread_limit = 5140 __kmp_stg_find("KMP_DEVICE_THREAD_LIMIT"); // 1st priority. 5141 kmp_setting_t *kmp_all_threads = 5142 __kmp_stg_find("KMP_ALL_THREADS"); // 2nd priority. 5143 5144 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround. 5145 static kmp_setting_t *volatile rivals[3]; 5146 int i = 0; 5147 5148 rivals[i++] = kmp_device_thread_limit; 5149 rivals[i++] = kmp_all_threads; 5150 rivals[i++] = NULL; 5151 5152 kmp_device_thread_limit->data = CCAST(kmp_setting_t **, rivals); 5153 kmp_all_threads->data = CCAST(kmp_setting_t **, rivals); 5154 } 5155 5156 { // Initialize KMP_HW_SUBSET and KMP_PLACE_THREADS 5157 // 1st priority 5158 kmp_setting_t *kmp_hw_subset = __kmp_stg_find("KMP_HW_SUBSET"); 5159 // 2nd priority 5160 kmp_setting_t *kmp_place_threads = __kmp_stg_find("KMP_PLACE_THREADS"); 5161 5162 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround. 5163 static kmp_setting_t *volatile rivals[3]; 5164 int i = 0; 5165 5166 rivals[i++] = kmp_hw_subset; 5167 rivals[i++] = kmp_place_threads; 5168 rivals[i++] = NULL; 5169 5170 kmp_hw_subset->data = CCAST(kmp_setting_t **, rivals); 5171 kmp_place_threads->data = CCAST(kmp_setting_t **, rivals); 5172 } 5173 5174 #if KMP_AFFINITY_SUPPORTED 5175 { // Initialize KMP_AFFINITY, GOMP_CPU_AFFINITY, and OMP_PROC_BIND data. 5176 kmp_setting_t *kmp_affinity = 5177 __kmp_stg_find("KMP_AFFINITY"); // 1st priority. 5178 KMP_DEBUG_ASSERT(kmp_affinity != NULL); 5179 5180 #ifdef KMP_GOMP_COMPAT 5181 kmp_setting_t *gomp_cpu_affinity = 5182 __kmp_stg_find("GOMP_CPU_AFFINITY"); // 2nd priority. 5183 KMP_DEBUG_ASSERT(gomp_cpu_affinity != NULL); 5184 #endif 5185 5186 kmp_setting_t *omp_proc_bind = 5187 __kmp_stg_find("OMP_PROC_BIND"); // 3rd priority. 5188 KMP_DEBUG_ASSERT(omp_proc_bind != NULL); 5189 5190 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround. 5191 static kmp_setting_t *volatile rivals[4]; 5192 int i = 0; 5193 5194 rivals[i++] = kmp_affinity; 5195 5196 #ifdef KMP_GOMP_COMPAT 5197 rivals[i++] = gomp_cpu_affinity; 5198 gomp_cpu_affinity->data = CCAST(kmp_setting_t **, rivals); 5199 #endif 5200 5201 rivals[i++] = omp_proc_bind; 5202 omp_proc_bind->data = CCAST(kmp_setting_t **, rivals); 5203 rivals[i++] = NULL; 5204 5205 #if OMP_40_ENABLED 5206 static kmp_setting_t *volatile places_rivals[4]; 5207 i = 0; 5208 5209 kmp_setting_t *omp_places = __kmp_stg_find("OMP_PLACES"); // 3rd priority. 5210 KMP_DEBUG_ASSERT(omp_places != NULL); 5211 5212 places_rivals[i++] = kmp_affinity; 5213 #ifdef KMP_GOMP_COMPAT 5214 places_rivals[i++] = gomp_cpu_affinity; 5215 #endif 5216 places_rivals[i++] = omp_places; 5217 omp_places->data = CCAST(kmp_setting_t **, places_rivals); 5218 places_rivals[i++] = NULL; 5219 #endif 5220 } 5221 #else 5222 // KMP_AFFINITY not supported, so OMP_PROC_BIND has no rivals. 5223 // OMP_PLACES not supported yet. 5224 #endif // KMP_AFFINITY_SUPPORTED 5225 5226 { // Initialize KMP_DETERMINISTIC_REDUCTION and KMP_FORCE_REDUCTION data. 5227 kmp_setting_t *kmp_force_red = 5228 __kmp_stg_find("KMP_FORCE_REDUCTION"); // 1st priority. 5229 kmp_setting_t *kmp_determ_red = 5230 __kmp_stg_find("KMP_DETERMINISTIC_REDUCTION"); // 2nd priority. 5231 5232 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround. 5233 static kmp_setting_t *volatile rivals[3]; 5234 static kmp_stg_fr_data_t force_data = {1, 5235 CCAST(kmp_setting_t **, rivals)}; 5236 static kmp_stg_fr_data_t determ_data = {0, 5237 CCAST(kmp_setting_t **, rivals)}; 5238 int i = 0; 5239 5240 rivals[i++] = kmp_force_red; 5241 if (kmp_determ_red != NULL) { 5242 rivals[i++] = kmp_determ_red; 5243 } 5244 rivals[i++] = NULL; 5245 5246 kmp_force_red->data = &force_data; 5247 if (kmp_determ_red != NULL) { 5248 kmp_determ_red->data = &determ_data; 5249 } 5250 } 5251 5252 initialized = 1; 5253 } 5254 5255 // Reset flags. 5256 int i; 5257 for (i = 0; i < __kmp_stg_count; ++i) { 5258 __kmp_stg_table[i].set = 0; 5259 } 5260 5261 } // __kmp_stg_init 5262 5263 static void __kmp_stg_parse(char const *name, char const *value) { 5264 // On Windows* OS there are some nameless variables like "C:=C:\" (yeah, 5265 // really nameless, they are presented in environment block as 5266 // "=C:=C\\\x00=D:=D:\\\x00...", so let us skip them. 5267 if (name[0] == 0) { 5268 return; 5269 } 5270 5271 if (value != NULL) { 5272 kmp_setting_t *setting = __kmp_stg_find(name); 5273 if (setting != NULL) { 5274 setting->parse(name, value, setting->data); 5275 setting->defined = 1; 5276 } 5277 } 5278 5279 } // __kmp_stg_parse 5280 5281 static int __kmp_stg_check_rivals( // 0 -- Ok, 1 -- errors found. 5282 char const *name, // Name of variable. 5283 char const *value, // Value of the variable. 5284 kmp_setting_t **rivals // List of rival settings (must include current one). 5285 ) { 5286 5287 if (rivals == NULL) { 5288 return 0; 5289 } 5290 5291 // Loop thru higher priority settings (listed before current). 5292 int i = 0; 5293 for (; strcmp(rivals[i]->name, name) != 0; i++) { 5294 KMP_DEBUG_ASSERT(rivals[i] != NULL); 5295 5296 #if KMP_AFFINITY_SUPPORTED 5297 if (rivals[i] == __kmp_affinity_notype) { 5298 // If KMP_AFFINITY is specified without a type name, 5299 // it does not rival OMP_PROC_BIND or GOMP_CPU_AFFINITY. 5300 continue; 5301 } 5302 #endif 5303 5304 if (rivals[i]->set) { 5305 KMP_WARNING(StgIgnored, name, rivals[i]->name); 5306 return 1; 5307 } 5308 } 5309 5310 ++i; // Skip current setting. 5311 return 0; 5312 5313 } // __kmp_stg_check_rivals 5314 5315 static int __kmp_env_toPrint(char const *name, int flag) { 5316 int rc = 0; 5317 kmp_setting_t *setting = __kmp_stg_find(name); 5318 if (setting != NULL) { 5319 rc = setting->defined; 5320 if (flag >= 0) { 5321 setting->defined = flag; 5322 } 5323 } 5324 return rc; 5325 } 5326 5327 static void __kmp_aux_env_initialize(kmp_env_blk_t *block) { 5328 5329 char const *value; 5330 5331 /* OMP_NUM_THREADS */ 5332 value = __kmp_env_blk_var(block, "OMP_NUM_THREADS"); 5333 if (value) { 5334 ompc_set_num_threads(__kmp_dflt_team_nth); 5335 } 5336 5337 /* KMP_BLOCKTIME */ 5338 value = __kmp_env_blk_var(block, "KMP_BLOCKTIME"); 5339 if (value) { 5340 kmpc_set_blocktime(__kmp_dflt_blocktime); 5341 } 5342 5343 /* OMP_NESTED */ 5344 value = __kmp_env_blk_var(block, "OMP_NESTED"); 5345 if (value) { 5346 ompc_set_nested(__kmp_dflt_max_active_levels > 1); 5347 } 5348 5349 /* OMP_DYNAMIC */ 5350 value = __kmp_env_blk_var(block, "OMP_DYNAMIC"); 5351 if (value) { 5352 ompc_set_dynamic(__kmp_global.g.g_dynamic); 5353 } 5354 } 5355 5356 void __kmp_env_initialize(char const *string) { 5357 5358 kmp_env_blk_t block; 5359 int i; 5360 5361 __kmp_stg_init(); 5362 5363 // Hack!!! 5364 if (string == NULL) { 5365 // __kmp_max_nth = __kmp_sys_max_nth; 5366 __kmp_threads_capacity = 5367 __kmp_initial_threads_capacity(__kmp_dflt_team_nth_ub); 5368 } 5369 __kmp_env_blk_init(&block, string); 5370 5371 // update the set flag on all entries that have an env var 5372 for (i = 0; i < block.count; ++i) { 5373 if ((block.vars[i].name == NULL) || (*block.vars[i].name == '\0')) { 5374 continue; 5375 } 5376 if (block.vars[i].value == NULL) { 5377 continue; 5378 } 5379 kmp_setting_t *setting = __kmp_stg_find(block.vars[i].name); 5380 if (setting != NULL) { 5381 setting->set = 1; 5382 } 5383 } 5384 5385 // We need to know if blocktime was set when processing OMP_WAIT_POLICY 5386 blocktime_str = __kmp_env_blk_var(&block, "KMP_BLOCKTIME"); 5387 5388 // Special case. If we parse environment, not a string, process KMP_WARNINGS 5389 // first. 5390 if (string == NULL) { 5391 char const *name = "KMP_WARNINGS"; 5392 char const *value = __kmp_env_blk_var(&block, name); 5393 __kmp_stg_parse(name, value); 5394 } 5395 5396 #if KMP_AFFINITY_SUPPORTED 5397 // Special case. KMP_AFFINITY is not a rival to other affinity env vars 5398 // if no affinity type is specified. We want to allow 5399 // KMP_AFFINITY=[no],verbose/[no]warnings/etc. to be enabled when 5400 // specifying the affinity type via GOMP_CPU_AFFINITY or the OMP 4.0 5401 // affinity mechanism. 5402 __kmp_affinity_notype = NULL; 5403 char const *aff_str = __kmp_env_blk_var(&block, "KMP_AFFINITY"); 5404 if (aff_str != NULL) { 5405 // Check if the KMP_AFFINITY type is specified in the string. 5406 // We just search the string for "compact", "scatter", etc. 5407 // without really parsing the string. The syntax of the 5408 // KMP_AFFINITY env var is such that none of the affinity 5409 // type names can appear anywhere other that the type 5410 // specifier, even as substrings. 5411 // 5412 // I can't find a case-insensitive version of strstr on Windows* OS. 5413 // Use the case-sensitive version for now. 5414 5415 #if KMP_OS_WINDOWS 5416 #define FIND strstr 5417 #else 5418 #define FIND strcasestr 5419 #endif 5420 5421 if ((FIND(aff_str, "none") == NULL) && 5422 (FIND(aff_str, "physical") == NULL) && 5423 (FIND(aff_str, "logical") == NULL) && 5424 (FIND(aff_str, "compact") == NULL) && 5425 (FIND(aff_str, "scatter") == NULL) && 5426 (FIND(aff_str, "explicit") == NULL) && 5427 (FIND(aff_str, "balanced") == NULL) && 5428 (FIND(aff_str, "disabled") == NULL)) { 5429 __kmp_affinity_notype = __kmp_stg_find("KMP_AFFINITY"); 5430 } else { 5431 // A new affinity type is specified. 5432 // Reset the affinity flags to their default values, 5433 // in case this is called from kmp_set_defaults(). 5434 __kmp_affinity_type = affinity_default; 5435 __kmp_affinity_gran = affinity_gran_default; 5436 __kmp_affinity_top_method = affinity_top_method_default; 5437 __kmp_affinity_respect_mask = affinity_respect_mask_default; 5438 } 5439 #undef FIND 5440 5441 #if OMP_40_ENABLED 5442 // Also reset the affinity flags if OMP_PROC_BIND is specified. 5443 aff_str = __kmp_env_blk_var(&block, "OMP_PROC_BIND"); 5444 if (aff_str != NULL) { 5445 __kmp_affinity_type = affinity_default; 5446 __kmp_affinity_gran = affinity_gran_default; 5447 __kmp_affinity_top_method = affinity_top_method_default; 5448 __kmp_affinity_respect_mask = affinity_respect_mask_default; 5449 } 5450 #endif /* OMP_40_ENABLED */ 5451 } 5452 5453 #endif /* KMP_AFFINITY_SUPPORTED */ 5454 5455 #if OMP_40_ENABLED 5456 // Set up the nested proc bind type vector. 5457 if (__kmp_nested_proc_bind.bind_types == NULL) { 5458 __kmp_nested_proc_bind.bind_types = 5459 (kmp_proc_bind_t *)KMP_INTERNAL_MALLOC(sizeof(kmp_proc_bind_t)); 5460 if (__kmp_nested_proc_bind.bind_types == NULL) { 5461 KMP_FATAL(MemoryAllocFailed); 5462 } 5463 __kmp_nested_proc_bind.size = 1; 5464 __kmp_nested_proc_bind.used = 1; 5465 #if KMP_AFFINITY_SUPPORTED 5466 __kmp_nested_proc_bind.bind_types[0] = proc_bind_default; 5467 #else 5468 // default proc bind is false if affinity not supported 5469 __kmp_nested_proc_bind.bind_types[0] = proc_bind_false; 5470 #endif 5471 } 5472 #endif /* OMP_40_ENABLED */ 5473 5474 #if OMP_50_ENABLED 5475 // Set up the affinity format ICV 5476 // Grab the default affinity format string from the message catalog 5477 kmp_msg_t m = 5478 __kmp_msg_format(kmp_i18n_msg_AffFormatDefault, "%P", "%i", "%n", "%A"); 5479 KMP_DEBUG_ASSERT(KMP_STRLEN(m.str) < KMP_AFFINITY_FORMAT_SIZE); 5480 5481 if (__kmp_affinity_format == NULL) { 5482 __kmp_affinity_format = 5483 (char *)KMP_INTERNAL_MALLOC(sizeof(char) * KMP_AFFINITY_FORMAT_SIZE); 5484 } 5485 KMP_STRCPY_S(__kmp_affinity_format, KMP_AFFINITY_FORMAT_SIZE, m.str); 5486 __kmp_str_free(&m.str); 5487 #endif 5488 5489 // Now process all of the settings. 5490 for (i = 0; i < block.count; ++i) { 5491 __kmp_stg_parse(block.vars[i].name, block.vars[i].value); 5492 } 5493 5494 // If user locks have been allocated yet, don't reset the lock vptr table. 5495 if (!__kmp_init_user_locks) { 5496 if (__kmp_user_lock_kind == lk_default) { 5497 __kmp_user_lock_kind = lk_queuing; 5498 } 5499 #if KMP_USE_DYNAMIC_LOCK 5500 __kmp_init_dynamic_user_locks(); 5501 #else 5502 __kmp_set_user_lock_vptrs(__kmp_user_lock_kind); 5503 #endif 5504 } else { 5505 KMP_DEBUG_ASSERT(string != NULL); // kmp_set_defaults() was called 5506 KMP_DEBUG_ASSERT(__kmp_user_lock_kind != lk_default); 5507 // Binds lock functions again to follow the transition between different 5508 // KMP_CONSISTENCY_CHECK values. Calling this again is harmless as long 5509 // as we do not allow lock kind changes after making a call to any 5510 // user lock functions (true). 5511 #if KMP_USE_DYNAMIC_LOCK 5512 __kmp_init_dynamic_user_locks(); 5513 #else 5514 __kmp_set_user_lock_vptrs(__kmp_user_lock_kind); 5515 #endif 5516 } 5517 5518 #if KMP_AFFINITY_SUPPORTED 5519 5520 if (!TCR_4(__kmp_init_middle)) { 5521 #if KMP_USE_HWLOC 5522 // Force using hwloc when either tiles or numa nodes requested within 5523 // KMP_HW_SUBSET and no other topology method is requested 5524 if ((__kmp_hws_node.num > 0 || __kmp_hws_tile.num > 0 || 5525 __kmp_affinity_gran == affinity_gran_tile) && 5526 (__kmp_affinity_top_method == affinity_top_method_default)) { 5527 __kmp_affinity_top_method = affinity_top_method_hwloc; 5528 } 5529 #endif 5530 // Determine if the machine/OS is actually capable of supporting 5531 // affinity. 5532 const char *var = "KMP_AFFINITY"; 5533 KMPAffinity::pick_api(); 5534 #if KMP_USE_HWLOC 5535 // If Hwloc topology discovery was requested but affinity was also disabled, 5536 // then tell user that Hwloc request is being ignored and use default 5537 // topology discovery method. 5538 if (__kmp_affinity_top_method == affinity_top_method_hwloc && 5539 __kmp_affinity_dispatch->get_api_type() != KMPAffinity::HWLOC) { 5540 KMP_WARNING(AffIgnoringHwloc, var); 5541 __kmp_affinity_top_method = affinity_top_method_all; 5542 } 5543 #endif 5544 if (__kmp_affinity_type == affinity_disabled) { 5545 KMP_AFFINITY_DISABLE(); 5546 } else if (!KMP_AFFINITY_CAPABLE()) { 5547 __kmp_affinity_dispatch->determine_capable(var); 5548 if (!KMP_AFFINITY_CAPABLE()) { 5549 if (__kmp_affinity_verbose || 5550 (__kmp_affinity_warnings && 5551 (__kmp_affinity_type != affinity_default) && 5552 (__kmp_affinity_type != affinity_none) && 5553 (__kmp_affinity_type != affinity_disabled))) { 5554 KMP_WARNING(AffNotSupported, var); 5555 } 5556 __kmp_affinity_type = affinity_disabled; 5557 __kmp_affinity_respect_mask = 0; 5558 __kmp_affinity_gran = affinity_gran_fine; 5559 } 5560 } 5561 5562 #if OMP_40_ENABLED 5563 if (__kmp_affinity_type == affinity_disabled) { 5564 __kmp_nested_proc_bind.bind_types[0] = proc_bind_false; 5565 } else if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_true) { 5566 // OMP_PROC_BIND=true maps to OMP_PROC_BIND=spread. 5567 __kmp_nested_proc_bind.bind_types[0] = proc_bind_spread; 5568 } 5569 #endif /* OMP_40_ENABLED */ 5570 5571 if (KMP_AFFINITY_CAPABLE()) { 5572 5573 #if KMP_GROUP_AFFINITY 5574 // This checks to see if the initial affinity mask is equal 5575 // to a single windows processor group. If it is, then we do 5576 // not respect the initial affinity mask and instead, use the 5577 // entire machine. 5578 bool exactly_one_group = false; 5579 if (__kmp_num_proc_groups > 1) { 5580 int group; 5581 bool within_one_group; 5582 // Get the initial affinity mask and determine if it is 5583 // contained within a single group. 5584 kmp_affin_mask_t *init_mask; 5585 KMP_CPU_ALLOC(init_mask); 5586 __kmp_get_system_affinity(init_mask, TRUE); 5587 group = __kmp_get_proc_group(init_mask); 5588 within_one_group = (group >= 0); 5589 // If the initial affinity is within a single group, 5590 // then determine if it is equal to that single group. 5591 if (within_one_group) { 5592 DWORD num_bits_in_group = __kmp_GetActiveProcessorCount(group); 5593 DWORD num_bits_in_mask = 0; 5594 for (int bit = init_mask->begin(); bit != init_mask->end(); 5595 bit = init_mask->next(bit)) 5596 num_bits_in_mask++; 5597 exactly_one_group = (num_bits_in_group == num_bits_in_mask); 5598 } 5599 KMP_CPU_FREE(init_mask); 5600 } 5601 5602 // Handle the Win 64 group affinity stuff if there are multiple 5603 // processor groups, or if the user requested it, and OMP 4.0 5604 // affinity is not in effect. 5605 if (((__kmp_num_proc_groups > 1) && 5606 (__kmp_affinity_type == affinity_default) 5607 #if OMP_40_ENABLED 5608 && (__kmp_nested_proc_bind.bind_types[0] == proc_bind_default)) 5609 #endif 5610 || (__kmp_affinity_top_method == affinity_top_method_group)) { 5611 if (__kmp_affinity_respect_mask == affinity_respect_mask_default && 5612 exactly_one_group) { 5613 __kmp_affinity_respect_mask = FALSE; 5614 } 5615 if (__kmp_affinity_type == affinity_default) { 5616 __kmp_affinity_type = affinity_compact; 5617 #if OMP_40_ENABLED 5618 __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel; 5619 #endif 5620 } 5621 if (__kmp_affinity_top_method == affinity_top_method_default) { 5622 if (__kmp_affinity_gran == affinity_gran_default) { 5623 __kmp_affinity_top_method = affinity_top_method_group; 5624 __kmp_affinity_gran = affinity_gran_group; 5625 } else if (__kmp_affinity_gran == affinity_gran_group) { 5626 __kmp_affinity_top_method = affinity_top_method_group; 5627 } else { 5628 __kmp_affinity_top_method = affinity_top_method_all; 5629 } 5630 } else if (__kmp_affinity_top_method == affinity_top_method_group) { 5631 if (__kmp_affinity_gran == affinity_gran_default) { 5632 __kmp_affinity_gran = affinity_gran_group; 5633 } else if ((__kmp_affinity_gran != affinity_gran_group) && 5634 (__kmp_affinity_gran != affinity_gran_fine) && 5635 (__kmp_affinity_gran != affinity_gran_thread)) { 5636 const char *str = NULL; 5637 switch (__kmp_affinity_gran) { 5638 case affinity_gran_core: 5639 str = "core"; 5640 break; 5641 case affinity_gran_package: 5642 str = "package"; 5643 break; 5644 case affinity_gran_node: 5645 str = "node"; 5646 break; 5647 case affinity_gran_tile: 5648 str = "tile"; 5649 break; 5650 default: 5651 KMP_DEBUG_ASSERT(0); 5652 } 5653 KMP_WARNING(AffGranTopGroup, var, str); 5654 __kmp_affinity_gran = affinity_gran_fine; 5655 } 5656 } else { 5657 if (__kmp_affinity_gran == affinity_gran_default) { 5658 __kmp_affinity_gran = affinity_gran_core; 5659 } else if (__kmp_affinity_gran == affinity_gran_group) { 5660 const char *str = NULL; 5661 switch (__kmp_affinity_type) { 5662 case affinity_physical: 5663 str = "physical"; 5664 break; 5665 case affinity_logical: 5666 str = "logical"; 5667 break; 5668 case affinity_compact: 5669 str = "compact"; 5670 break; 5671 case affinity_scatter: 5672 str = "scatter"; 5673 break; 5674 case affinity_explicit: 5675 str = "explicit"; 5676 break; 5677 // No MIC on windows, so no affinity_balanced case 5678 default: 5679 KMP_DEBUG_ASSERT(0); 5680 } 5681 KMP_WARNING(AffGranGroupType, var, str); 5682 __kmp_affinity_gran = affinity_gran_core; 5683 } 5684 } 5685 } else 5686 5687 #endif /* KMP_GROUP_AFFINITY */ 5688 5689 { 5690 if (__kmp_affinity_respect_mask == affinity_respect_mask_default) { 5691 #if KMP_GROUP_AFFINITY 5692 if (__kmp_num_proc_groups > 1 && exactly_one_group) { 5693 __kmp_affinity_respect_mask = FALSE; 5694 } else 5695 #endif /* KMP_GROUP_AFFINITY */ 5696 { 5697 __kmp_affinity_respect_mask = TRUE; 5698 } 5699 } 5700 #if OMP_40_ENABLED 5701 if ((__kmp_nested_proc_bind.bind_types[0] != proc_bind_intel) && 5702 (__kmp_nested_proc_bind.bind_types[0] != proc_bind_default)) { 5703 if (__kmp_affinity_type == affinity_default) { 5704 __kmp_affinity_type = affinity_compact; 5705 __kmp_affinity_dups = FALSE; 5706 } 5707 } else 5708 #endif /* OMP_40_ENABLED */ 5709 if (__kmp_affinity_type == affinity_default) { 5710 #if OMP_40_ENABLED 5711 #if KMP_MIC_SUPPORTED 5712 if (__kmp_mic_type != non_mic) { 5713 __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel; 5714 } else 5715 #endif 5716 { 5717 __kmp_nested_proc_bind.bind_types[0] = proc_bind_false; 5718 } 5719 #endif /* OMP_40_ENABLED */ 5720 #if KMP_MIC_SUPPORTED 5721 if (__kmp_mic_type != non_mic) { 5722 __kmp_affinity_type = affinity_scatter; 5723 } else 5724 #endif 5725 { 5726 __kmp_affinity_type = affinity_none; 5727 } 5728 } 5729 if ((__kmp_affinity_gran == affinity_gran_default) && 5730 (__kmp_affinity_gran_levels < 0)) { 5731 #if KMP_MIC_SUPPORTED 5732 if (__kmp_mic_type != non_mic) { 5733 __kmp_affinity_gran = affinity_gran_fine; 5734 } else 5735 #endif 5736 { 5737 __kmp_affinity_gran = affinity_gran_core; 5738 } 5739 } 5740 if (__kmp_affinity_top_method == affinity_top_method_default) { 5741 __kmp_affinity_top_method = affinity_top_method_all; 5742 } 5743 } 5744 } 5745 5746 K_DIAG(1, ("__kmp_affinity_type == %d\n", __kmp_affinity_type)); 5747 K_DIAG(1, ("__kmp_affinity_compact == %d\n", __kmp_affinity_compact)); 5748 K_DIAG(1, ("__kmp_affinity_offset == %d\n", __kmp_affinity_offset)); 5749 K_DIAG(1, ("__kmp_affinity_verbose == %d\n", __kmp_affinity_verbose)); 5750 K_DIAG(1, ("__kmp_affinity_warnings == %d\n", __kmp_affinity_warnings)); 5751 K_DIAG(1, ("__kmp_affinity_respect_mask == %d\n", 5752 __kmp_affinity_respect_mask)); 5753 K_DIAG(1, ("__kmp_affinity_gran == %d\n", __kmp_affinity_gran)); 5754 5755 KMP_DEBUG_ASSERT(__kmp_affinity_type != affinity_default); 5756 #if OMP_40_ENABLED 5757 KMP_DEBUG_ASSERT(__kmp_nested_proc_bind.bind_types[0] != proc_bind_default); 5758 K_DIAG(1, ("__kmp_nested_proc_bind.bind_types[0] == %d\n", 5759 __kmp_nested_proc_bind.bind_types[0])); 5760 #endif 5761 } 5762 5763 #endif /* KMP_AFFINITY_SUPPORTED */ 5764 5765 if (__kmp_version) { 5766 __kmp_print_version_1(); 5767 } 5768 5769 // Post-initialization step: some env. vars need their value's further 5770 // processing 5771 if (string != NULL) { // kmp_set_defaults() was called 5772 __kmp_aux_env_initialize(&block); 5773 } 5774 5775 __kmp_env_blk_free(&block); 5776 5777 KMP_MB(); 5778 5779 } // __kmp_env_initialize 5780 5781 void __kmp_env_print() { 5782 5783 kmp_env_blk_t block; 5784 int i; 5785 kmp_str_buf_t buffer; 5786 5787 __kmp_stg_init(); 5788 __kmp_str_buf_init(&buffer); 5789 5790 __kmp_env_blk_init(&block, NULL); 5791 __kmp_env_blk_sort(&block); 5792 5793 // Print real environment values. 5794 __kmp_str_buf_print(&buffer, "\n%s\n\n", KMP_I18N_STR(UserSettings)); 5795 for (i = 0; i < block.count; ++i) { 5796 char const *name = block.vars[i].name; 5797 char const *value = block.vars[i].value; 5798 if ((KMP_STRLEN(name) > 4 && strncmp(name, "KMP_", 4) == 0) || 5799 strncmp(name, "OMP_", 4) == 0 5800 #ifdef KMP_GOMP_COMPAT 5801 || strncmp(name, "GOMP_", 5) == 0 5802 #endif // KMP_GOMP_COMPAT 5803 ) { 5804 __kmp_str_buf_print(&buffer, " %s=%s\n", name, value); 5805 } 5806 } 5807 __kmp_str_buf_print(&buffer, "\n"); 5808 5809 // Print internal (effective) settings. 5810 __kmp_str_buf_print(&buffer, "%s\n\n", KMP_I18N_STR(EffectiveSettings)); 5811 for (int i = 0; i < __kmp_stg_count; ++i) { 5812 if (__kmp_stg_table[i].print != NULL) { 5813 __kmp_stg_table[i].print(&buffer, __kmp_stg_table[i].name, 5814 __kmp_stg_table[i].data); 5815 } 5816 } 5817 5818 __kmp_printf("%s", buffer.str); 5819 5820 __kmp_env_blk_free(&block); 5821 __kmp_str_buf_free(&buffer); 5822 5823 __kmp_printf("\n"); 5824 5825 } // __kmp_env_print 5826 5827 #if OMP_40_ENABLED 5828 void __kmp_env_print_2() { 5829 5830 kmp_env_blk_t block; 5831 kmp_str_buf_t buffer; 5832 5833 __kmp_env_format = 1; 5834 5835 __kmp_stg_init(); 5836 __kmp_str_buf_init(&buffer); 5837 5838 __kmp_env_blk_init(&block, NULL); 5839 __kmp_env_blk_sort(&block); 5840 5841 __kmp_str_buf_print(&buffer, "\n%s\n", KMP_I18N_STR(DisplayEnvBegin)); 5842 __kmp_str_buf_print(&buffer, " _OPENMP='%d'\n", __kmp_openmp_version); 5843 5844 for (int i = 0; i < __kmp_stg_count; ++i) { 5845 if (__kmp_stg_table[i].print != NULL && 5846 ((__kmp_display_env && 5847 strncmp(__kmp_stg_table[i].name, "OMP_", 4) == 0) || 5848 __kmp_display_env_verbose)) { 5849 __kmp_stg_table[i].print(&buffer, __kmp_stg_table[i].name, 5850 __kmp_stg_table[i].data); 5851 } 5852 } 5853 5854 __kmp_str_buf_print(&buffer, "%s\n", KMP_I18N_STR(DisplayEnvEnd)); 5855 __kmp_str_buf_print(&buffer, "\n"); 5856 5857 __kmp_printf("%s", buffer.str); 5858 5859 __kmp_env_blk_free(&block); 5860 __kmp_str_buf_free(&buffer); 5861 5862 __kmp_printf("\n"); 5863 5864 } // __kmp_env_print_2 5865 #endif // OMP_40_ENABLED 5866 5867 // end of file 5868