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