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