2 * kmp_settings.cpp -- Initialize environment variables
5 //===----------------------------------------------------------------------===//
7 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
8 // See https://llvm.org/LICENSE.txt for license information.
9 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
11 //===----------------------------------------------------------------------===//
14 #include "kmp_affinity.h"
15 #include "kmp_atomic.h"
16 #if KMP_USE_HIER_SCHED
17 #include "kmp_dispatch_hier.h"
19 #include "kmp_environment.h"
24 #include "kmp_settings.h"
26 #include "kmp_wrapper_getpid.h"
27 #include <ctype.h> // toupper()
29 #include "ompd-specific.h"
32 static int __kmp_env_toPrint(char const *name
, int flag
);
34 bool __kmp_env_format
= 0; // 0 - old format; 1 - new format
36 // -----------------------------------------------------------------------------
37 // Helper string functions. Subject to move to kmp_str.
39 #ifdef USE_LOAD_BALANCE
40 static double __kmp_convert_to_double(char const *s
) {
43 if (KMP_SSCANF(s
, "%lf", &result
) < 1) {
52 static unsigned int __kmp_readstr_with_sentinel(char *dest
, char const *src
,
53 size_t len
, char sentinel
) {
55 for (i
= 0; i
< len
; i
++) {
56 if ((*src
== '\0') || (*src
== sentinel
)) {
66 static int __kmp_match_with_sentinel(char const *a
, char const *b
, size_t len
,
74 while (*a
&& *b
&& *b
!= sentinel
) {
75 char ca
= *a
, cb
= *b
;
77 if (ca
>= 'a' && ca
<= 'z')
79 if (cb
>= 'a' && cb
<= 'z')
91 // token is the token to check for.
92 // buf is the string being parsed.
93 // *end returns the char after the end of the token.
94 // it is not modified unless a match occurs.
98 // if (__kmp_match_str("token", buf, *end) {
105 // if (__kmp_match_str("token", buf, *end) {
106 // char *save = **end;
108 // <use any of the __kmp*_with_sentinel() functions>
113 static int __kmp_match_str(char const *token
, char const *buf
,
116 KMP_ASSERT(token
!= NULL
);
117 KMP_ASSERT(buf
!= NULL
);
118 KMP_ASSERT(end
!= NULL
);
120 while (*token
&& *buf
) {
121 char ct
= *token
, cb
= *buf
;
123 if (ct
>= 'a' && ct
<= 'z')
125 if (cb
>= 'a' && cb
<= 'z')
140 static size_t __kmp_round4k(size_t size
) {
141 size_t _4k
= 4 * 1024;
142 if (size
& (_4k
- 1)) {
144 if (size
<= KMP_SIZE_T_MAX
- _4k
) {
145 size
+= _4k
; // Round up if there is no overflow.
152 static int __kmp_strcasecmp_with_sentinel(char const *a
, char const *b
,
158 while (*a
&& *b
&& *b
!= sentinel
) {
159 char ca
= *a
, cb
= *b
;
161 if (ca
>= 'a' && ca
<= 'z')
163 if (cb
>= 'a' && cb
<= 'z')
166 return (int)(unsigned char)*a
- (int)(unsigned char)*b
;
170 return *a
? (*b
&& *b
!= sentinel
)
171 ? (int)(unsigned char)*a
- (int)(unsigned char)*b
173 : (*b
&& *b
!= sentinel
) ? -1
177 // =============================================================================
178 // Table structures and helper functions.
180 typedef struct __kmp_setting kmp_setting_t
;
181 typedef struct __kmp_stg_ss_data kmp_stg_ss_data_t
;
182 typedef struct __kmp_stg_wp_data kmp_stg_wp_data_t
;
183 typedef struct __kmp_stg_fr_data kmp_stg_fr_data_t
;
185 typedef void (*kmp_stg_parse_func_t
)(char const *name
, char const *value
,
187 typedef void (*kmp_stg_print_func_t
)(kmp_str_buf_t
*buffer
, char const *name
,
190 struct __kmp_setting
{
191 char const *name
; // Name of setting (environment variable).
192 kmp_stg_parse_func_t parse
; // Parser function.
193 kmp_stg_print_func_t print
; // Print function.
194 void *data
; // Data passed to parser and printer.
195 int set
; // Variable set during this "session"
196 // (__kmp_env_initialize() or kmp_set_defaults() call).
197 int defined
; // Variable set in any "session".
198 }; // struct __kmp_setting
200 struct __kmp_stg_ss_data
{
201 size_t factor
; // Default factor: 1 for KMP_STACKSIZE, 1024 for others.
202 kmp_setting_t
**rivals
; // Array of pointers to rivals (including itself).
203 }; // struct __kmp_stg_ss_data
205 struct __kmp_stg_wp_data
{
206 int omp
; // 0 -- KMP_LIBRARY, 1 -- OMP_WAIT_POLICY.
207 kmp_setting_t
**rivals
; // Array of pointers to rivals (including itself).
208 }; // struct __kmp_stg_wp_data
210 struct __kmp_stg_fr_data
{
211 int force
; // 0 -- KMP_DETERMINISTIC_REDUCTION, 1 -- KMP_FORCE_REDUCTION.
212 kmp_setting_t
**rivals
; // Array of pointers to rivals (including itself).
213 }; // struct __kmp_stg_fr_data
215 static int __kmp_stg_check_rivals( // 0 -- Ok, 1 -- errors found.
216 char const *name
, // Name of variable.
217 char const *value
, // Value of the variable.
218 kmp_setting_t
**rivals
// List of rival settings (must include current one).
221 // Helper struct that trims heading/trailing white spaces
222 struct kmp_trimmed_str_t
{
224 kmp_trimmed_str_t(const char *str
) {
225 __kmp_str_buf_init(&buf
);
226 size_t len
= KMP_STRLEN(str
);
229 const char *begin
= str
;
230 const char *end
= str
+ KMP_STRLEN(str
) - 1;
232 while (begin
< end
&& *end
== ' ')
234 __kmp_str_buf_cat(&buf
, begin
, end
- begin
+ 1);
236 ~kmp_trimmed_str_t() { __kmp_str_buf_free(&buf
); }
237 const char *get() { return buf
.str
; }
240 // -----------------------------------------------------------------------------
241 // Helper parse functions.
243 static void __kmp_stg_parse_bool(char const *name
, char const *value
,
245 if (__kmp_str_match_true(value
)) {
247 } else if (__kmp_str_match_false(value
)) {
250 __kmp_msg(kmp_ms_warning
, KMP_MSG(BadBoolValue
, name
, value
),
251 KMP_HNT(ValidBoolValues
), __kmp_msg_null
);
253 } // __kmp_stg_parse_bool
255 // placed here in order to use __kmp_round4k static function
256 void __kmp_check_stksize(size_t *val
) {
257 // if system stack size is too big then limit the size for worker threads
259 if (*val
> KMP_DEFAULT_STKSIZE
* 2) // Use 2 times, 16 is too large for AIX.
260 *val
= KMP_DEFAULT_STKSIZE
* 2;
262 if (*val
> KMP_DEFAULT_STKSIZE
* 16) // just a heuristics...
263 *val
= KMP_DEFAULT_STKSIZE
* 16;
265 if (*val
< __kmp_sys_min_stksize
)
266 *val
= __kmp_sys_min_stksize
;
267 if (*val
> KMP_MAX_STKSIZE
)
268 *val
= KMP_MAX_STKSIZE
; // dead code currently, but may work in future
270 *val
= __kmp_round4k(*val
);
271 #endif // KMP_OS_DARWIN
274 static void __kmp_stg_parse_size(char const *name
, char const *value
,
275 size_t size_min
, size_t size_max
,
276 int *is_specified
, size_t *out
,
278 char const *msg
= NULL
;
280 size_min
= __kmp_round4k(size_min
);
281 size_max
= __kmp_round4k(size_max
);
282 #endif // KMP_OS_DARWIN
284 if (is_specified
!= NULL
) {
287 __kmp_str_to_size(value
, out
, factor
, &msg
);
289 if (*out
> size_max
) {
291 msg
= KMP_I18N_STR(ValueTooLarge
);
292 } else if (*out
< size_min
) {
294 msg
= KMP_I18N_STR(ValueTooSmall
);
297 size_t round4k
= __kmp_round4k(*out
);
298 if (*out
!= round4k
) {
300 msg
= KMP_I18N_STR(NotMultiple4K
);
305 // If integer overflow occurred, * out == KMP_SIZE_T_MAX. Cut it to
306 // size_max silently.
307 if (*out
< size_min
) {
309 } else if (*out
> size_max
) {
314 // Message is not empty. Print warning.
316 __kmp_str_buf_init(&buf
);
317 __kmp_str_buf_print_size(&buf
, *out
);
318 KMP_WARNING(ParseSizeIntWarn
, name
, value
, msg
);
319 KMP_INFORM(Using_str_Value
, name
, buf
.str
);
320 __kmp_str_buf_free(&buf
);
323 } // __kmp_stg_parse_size
325 static void __kmp_stg_parse_str(char const *name
, char const *value
,
328 *out
= __kmp_str_format("%s", value
);
329 } // __kmp_stg_parse_str
331 static void __kmp_stg_parse_int(
333 *name
, // I: Name of environment variable (used in warning messages).
334 char const *value
, // I: Value of environment variable to parse.
335 int min
, // I: Minimum allowed value.
336 int max
, // I: Maximum allowed value.
337 int *out
// O: Output (parsed) value.
339 char const *msg
= NULL
;
340 kmp_uint64 uint
= *out
;
341 __kmp_str_to_uint(value
, &uint
, &msg
);
343 if (uint
< (unsigned int)min
) {
344 msg
= KMP_I18N_STR(ValueTooSmall
);
346 } else if (uint
> (unsigned int)max
) {
347 msg
= KMP_I18N_STR(ValueTooLarge
);
351 // If overflow occurred msg contains error message and uint is very big. Cut
352 // tmp it to INT_MAX.
353 if (uint
< (unsigned int)min
) {
355 } else if (uint
> (unsigned int)max
) {
360 // Message is not empty. Print warning.
362 KMP_WARNING(ParseSizeIntWarn
, name
, value
, msg
);
363 __kmp_str_buf_init(&buf
);
364 __kmp_str_buf_print(&buf
, "%" KMP_UINT64_SPEC
"", uint
);
365 KMP_INFORM(Using_uint64_Value
, name
, buf
.str
);
366 __kmp_str_buf_free(&buf
);
368 __kmp_type_convert(uint
, out
);
369 } // __kmp_stg_parse_int
371 #if KMP_DEBUG_ADAPTIVE_LOCKS
372 static void __kmp_stg_parse_file(char const *name
, char const *value
,
373 const char *suffix
, char **out
) {
378 t
= (char *)strrchr(value
, '.');
379 hasSuffix
= t
&& __kmp_str_eqf(t
, suffix
);
380 t
= __kmp_str_format("%s%s", value
, hasSuffix
? "" : suffix
);
381 __kmp_expand_file_name(buffer
, sizeof(buffer
), t
);
383 *out
= __kmp_str_format("%s", buffer
);
384 } // __kmp_stg_parse_file
388 static char *par_range_to_print
= NULL
;
390 static void __kmp_stg_parse_par_range(char const *name
, char const *value
,
391 int *out_range
, char *out_routine
,
392 char *out_file
, int *out_lb
,
394 const char *par_range_value
;
395 size_t len
= KMP_STRLEN(value
) + 1;
396 par_range_to_print
= (char *)KMP_INTERNAL_MALLOC(len
+ 1);
397 KMP_STRNCPY_S(par_range_to_print
, len
+ 1, value
, len
+ 1);
398 __kmp_par_range
= +1;
399 __kmp_par_range_lb
= 0;
400 __kmp_par_range_ub
= INT_MAX
;
403 if (!value
|| *value
== '\0') {
406 if (!__kmp_strcasecmp_with_sentinel("routine", value
, '=')) {
407 par_range_value
= strchr(value
, '=') + 1;
408 if (!par_range_value
)
409 goto par_range_error
;
410 value
= par_range_value
;
411 len
= __kmp_readstr_with_sentinel(out_routine
, value
,
412 KMP_PAR_RANGE_ROUTINE_LEN
- 1, ',');
414 goto par_range_error
;
416 value
= strchr(value
, ',');
422 if (!__kmp_strcasecmp_with_sentinel("filename", value
, '=')) {
423 par_range_value
= strchr(value
, '=') + 1;
424 if (!par_range_value
)
425 goto par_range_error
;
426 value
= par_range_value
;
427 len
= __kmp_readstr_with_sentinel(out_file
, value
,
428 KMP_PAR_RANGE_FILENAME_LEN
- 1, ',');
430 goto par_range_error
;
432 value
= strchr(value
, ',');
438 if ((!__kmp_strcasecmp_with_sentinel("range", value
, '=')) ||
439 (!__kmp_strcasecmp_with_sentinel("incl_range", value
, '='))) {
440 par_range_value
= strchr(value
, '=') + 1;
441 if (!par_range_value
)
442 goto par_range_error
;
443 value
= par_range_value
;
444 if (KMP_SSCANF(value
, "%d:%d", out_lb
, out_ub
) != 2) {
445 goto par_range_error
;
448 value
= strchr(value
, ',');
454 if (!__kmp_strcasecmp_with_sentinel("excl_range", value
, '=')) {
455 par_range_value
= strchr(value
, '=') + 1;
456 if (!par_range_value
)
457 goto par_range_error
;
458 value
= par_range_value
;
459 if (KMP_SSCANF(value
, "%d:%d", out_lb
, out_ub
) != 2) {
460 goto par_range_error
;
463 value
= strchr(value
, ',');
470 KMP_WARNING(ParRangeSyntax
, name
);
474 } // __kmp_stg_parse_par_range
477 int __kmp_initial_threads_capacity(int req_nproc
) {
480 /* MIN( MAX( 32, 4 * $OMP_NUM_THREADS, 4 * omp_get_num_procs() ),
482 if (nth
< (4 * req_nproc
))
483 nth
= (4 * req_nproc
);
484 if (nth
< (4 * __kmp_xproc
))
485 nth
= (4 * __kmp_xproc
);
487 // If hidden helper task is enabled, we initialize the thread capacity with
488 // extra __kmp_hidden_helper_threads_num.
489 if (__kmp_enable_hidden_helper
) {
490 nth
+= __kmp_hidden_helper_threads_num
;
493 if (nth
> __kmp_max_nth
)
499 int __kmp_default_tp_capacity(int req_nproc
, int max_nth
,
500 int all_threads_specified
) {
503 if (all_threads_specified
)
505 /* MIN( MAX (128, 4 * $OMP_NUM_THREADS, 4 * omp_get_num_procs() ),
507 if (nth
< (4 * req_nproc
))
508 nth
= (4 * req_nproc
);
509 if (nth
< (4 * __kmp_xproc
))
510 nth
= (4 * __kmp_xproc
);
512 if (nth
> __kmp_max_nth
)
518 // -----------------------------------------------------------------------------
519 // Helper print functions.
521 static void __kmp_stg_print_bool(kmp_str_buf_t
*buffer
, char const *name
,
523 if (__kmp_env_format
) {
524 KMP_STR_BUF_PRINT_BOOL
;
526 __kmp_str_buf_print(buffer
, " %s=%s\n", name
, value
? "true" : "false");
528 } // __kmp_stg_print_bool
530 static void __kmp_stg_print_int(kmp_str_buf_t
*buffer
, char const *name
,
532 if (__kmp_env_format
) {
533 KMP_STR_BUF_PRINT_INT
;
535 __kmp_str_buf_print(buffer
, " %s=%d\n", name
, value
);
537 } // __kmp_stg_print_int
539 static void __kmp_stg_print_uint64(kmp_str_buf_t
*buffer
, char const *name
,
541 if (__kmp_env_format
) {
542 KMP_STR_BUF_PRINT_UINT64
;
544 __kmp_str_buf_print(buffer
, " %s=%" KMP_UINT64_SPEC
"\n", name
, value
);
546 } // __kmp_stg_print_uint64
548 static void __kmp_stg_print_str(kmp_str_buf_t
*buffer
, char const *name
,
550 if (__kmp_env_format
) {
551 KMP_STR_BUF_PRINT_STR
;
553 __kmp_str_buf_print(buffer
, " %s=%s\n", name
, value
);
555 } // __kmp_stg_print_str
557 static void __kmp_stg_print_size(kmp_str_buf_t
*buffer
, char const *name
,
559 if (__kmp_env_format
) {
560 KMP_STR_BUF_PRINT_NAME_EX(name
);
561 __kmp_str_buf_print_size(buffer
, value
);
562 __kmp_str_buf_print(buffer
, "'\n");
564 __kmp_str_buf_print(buffer
, " %s=", name
);
565 __kmp_str_buf_print_size(buffer
, value
);
566 __kmp_str_buf_print(buffer
, "\n");
569 } // __kmp_stg_print_size
571 // =============================================================================
572 // Parse and print functions.
574 // -----------------------------------------------------------------------------
575 // KMP_DEVICE_THREAD_LIMIT, KMP_ALL_THREADS
577 static void __kmp_stg_parse_device_thread_limit(char const *name
,
578 char const *value
, void *data
) {
579 kmp_setting_t
**rivals
= (kmp_setting_t
**)data
;
581 if (strcmp(name
, "KMP_ALL_THREADS") == 0) {
582 KMP_INFORM(EnvVarDeprecated
, name
, "KMP_DEVICE_THREAD_LIMIT");
584 rc
= __kmp_stg_check_rivals(name
, value
, rivals
);
588 if (!__kmp_strcasecmp_with_sentinel("all", value
, 0)) {
589 __kmp_max_nth
= __kmp_xproc
;
590 __kmp_allThreadsSpecified
= 1;
592 __kmp_stg_parse_int(name
, value
, 1, __kmp_sys_max_nth
, &__kmp_max_nth
);
593 __kmp_allThreadsSpecified
= 0;
595 K_DIAG(1, ("__kmp_max_nth == %d\n", __kmp_max_nth
));
597 } // __kmp_stg_parse_device_thread_limit
599 static void __kmp_stg_print_device_thread_limit(kmp_str_buf_t
*buffer
,
600 char const *name
, void *data
) {
601 __kmp_stg_print_int(buffer
, name
, __kmp_max_nth
);
602 } // __kmp_stg_print_device_thread_limit
604 // -----------------------------------------------------------------------------
606 static void __kmp_stg_parse_thread_limit(char const *name
, char const *value
,
608 __kmp_stg_parse_int(name
, value
, 1, __kmp_sys_max_nth
, &__kmp_cg_max_nth
);
609 K_DIAG(1, ("__kmp_cg_max_nth == %d\n", __kmp_cg_max_nth
));
611 } // __kmp_stg_parse_thread_limit
613 static void __kmp_stg_print_thread_limit(kmp_str_buf_t
*buffer
,
614 char const *name
, void *data
) {
615 __kmp_stg_print_int(buffer
, name
, __kmp_cg_max_nth
);
616 } // __kmp_stg_print_thread_limit
618 // -----------------------------------------------------------------------------
620 static void __kmp_stg_parse_nteams(char const *name
, char const *value
,
622 __kmp_stg_parse_int(name
, value
, 1, __kmp_sys_max_nth
, &__kmp_nteams
);
623 K_DIAG(1, ("__kmp_nteams == %d\n", __kmp_nteams
));
624 } // __kmp_stg_parse_nteams
626 static void __kmp_stg_print_nteams(kmp_str_buf_t
*buffer
, char const *name
,
628 __kmp_stg_print_int(buffer
, name
, __kmp_nteams
);
629 } // __kmp_stg_print_nteams
631 // -----------------------------------------------------------------------------
632 // OMP_TEAMS_THREAD_LIMIT
633 static void __kmp_stg_parse_teams_th_limit(char const *name
, char const *value
,
635 __kmp_stg_parse_int(name
, value
, 1, __kmp_sys_max_nth
,
636 &__kmp_teams_thread_limit
);
637 K_DIAG(1, ("__kmp_teams_thread_limit == %d\n", __kmp_teams_thread_limit
));
638 } // __kmp_stg_parse_teams_th_limit
640 static void __kmp_stg_print_teams_th_limit(kmp_str_buf_t
*buffer
,
641 char const *name
, void *data
) {
642 __kmp_stg_print_int(buffer
, name
, __kmp_teams_thread_limit
);
643 } // __kmp_stg_print_teams_th_limit
645 // -----------------------------------------------------------------------------
646 // KMP_TEAMS_THREAD_LIMIT
647 static void __kmp_stg_parse_teams_thread_limit(char const *name
,
648 char const *value
, void *data
) {
649 __kmp_stg_parse_int(name
, value
, 1, __kmp_sys_max_nth
, &__kmp_teams_max_nth
);
650 } // __kmp_stg_teams_thread_limit
652 static void __kmp_stg_print_teams_thread_limit(kmp_str_buf_t
*buffer
,
653 char const *name
, void *data
) {
654 __kmp_stg_print_int(buffer
, name
, __kmp_teams_max_nth
);
655 } // __kmp_stg_print_teams_thread_limit
657 // -----------------------------------------------------------------------------
659 static void __kmp_stg_parse_use_yield(char const *name
, char const *value
,
661 __kmp_stg_parse_int(name
, value
, 0, 2, &__kmp_use_yield
);
662 __kmp_use_yield_exp_set
= 1;
663 } // __kmp_stg_parse_use_yield
665 static void __kmp_stg_print_use_yield(kmp_str_buf_t
*buffer
, char const *name
,
667 __kmp_stg_print_int(buffer
, name
, __kmp_use_yield
);
668 } // __kmp_stg_print_use_yield
670 // -----------------------------------------------------------------------------
673 static void __kmp_stg_parse_blocktime(char const *name
, char const *value
,
675 const char *buf
= value
;
677 const int ms_mult
= 1000;
681 // Read integer blocktime value
683 if ((*buf
>= '0') && (*buf
<= '9')) {
686 num
= __kmp_basic_str_to_int(buf
);
687 KMP_ASSERT(num
>= 0);
694 // Read units: note that __kmp_dflt_blocktime units is now us
696 if (*buf
== '\0' || __kmp_match_str("ms", buf
, &next
)) {
697 // units are in ms; convert
698 __kmp_dflt_blocktime
= ms_mult
* num
;
699 __kmp_blocktime_units
= 'm';
700 multiplier
= ms_mult
;
701 } else if (__kmp_match_str("us", buf
, &next
)) {
703 __kmp_dflt_blocktime
= num
;
704 __kmp_blocktime_units
= 'u';
705 } else if (__kmp_match_str("infinite", buf
, &next
) ||
706 __kmp_match_str("infinity", buf
, &next
)) {
708 __kmp_dflt_blocktime
= KMP_MAX_BLOCKTIME
;
709 __kmp_blocktime_units
= 'm';
710 multiplier
= ms_mult
;
712 KMP_WARNING(StgInvalidValue
, name
, value
);
713 // default units are in ms
714 __kmp_dflt_blocktime
= ms_mult
* num
;
715 __kmp_blocktime_units
= 'm';
716 multiplier
= ms_mult
;
719 if (num
< 0 && __kmp_dflt_blocktime
< 0) { // num out of range
720 __kmp_dflt_blocktime
= KMP_DEFAULT_BLOCKTIME
; // now in us
721 __kmp_msg(kmp_ms_warning
, KMP_MSG(InvalidValue
, name
, value
),
723 // Inform in appropriate units
724 KMP_INFORM(Using_int_Value
, name
, __kmp_dflt_blocktime
/ multiplier
);
725 __kmp_env_blocktime
= FALSE
; // Revert to default as if var not set.
726 } else if (num
> 0 && __kmp_dflt_blocktime
< 0) { // overflow
727 __kmp_dflt_blocktime
= KMP_MAX_BLOCKTIME
;
728 __kmp_msg(kmp_ms_warning
, KMP_MSG(LargeValue
, name
, value
), __kmp_msg_null
);
729 KMP_INFORM(MaxValueUsing
, name
, __kmp_dflt_blocktime
/ multiplier
);
730 __kmp_env_blocktime
= TRUE
; // KMP_BLOCKTIME was specified.
732 if (__kmp_dflt_blocktime
< KMP_MIN_BLOCKTIME
) {
733 __kmp_dflt_blocktime
= KMP_MIN_BLOCKTIME
;
734 __kmp_msg(kmp_ms_warning
, KMP_MSG(SmallValue
, name
, value
),
736 KMP_INFORM(MinValueUsing
, name
, __kmp_dflt_blocktime
/ multiplier
);
737 } else if (__kmp_dflt_blocktime
> KMP_MAX_BLOCKTIME
) {
738 __kmp_dflt_blocktime
= KMP_MAX_BLOCKTIME
;
739 __kmp_msg(kmp_ms_warning
, KMP_MSG(LargeValue
, name
, value
),
741 KMP_INFORM(MaxValueUsing
, name
, __kmp_dflt_blocktime
/ multiplier
);
743 __kmp_env_blocktime
= TRUE
; // KMP_BLOCKTIME was specified.
746 // calculate number of monitor thread wakeup intervals corresponding to
748 __kmp_monitor_wakeups
=
749 KMP_WAKEUPS_FROM_BLOCKTIME(__kmp_dflt_blocktime
, __kmp_monitor_wakeups
);
751 KMP_INTERVALS_FROM_BLOCKTIME(__kmp_dflt_blocktime
, __kmp_monitor_wakeups
);
753 K_DIAG(1, ("__kmp_env_blocktime == %d\n", __kmp_env_blocktime
));
754 if (__kmp_env_blocktime
) {
755 K_DIAG(1, ("__kmp_dflt_blocktime == %d\n", __kmp_dflt_blocktime
));
757 } // __kmp_stg_parse_blocktime
759 static void __kmp_stg_print_blocktime(kmp_str_buf_t
*buffer
, char const *name
,
761 int num
= __kmp_dflt_blocktime
;
762 if (__kmp_blocktime_units
== 'm') {
765 if (__kmp_env_format
) {
766 KMP_STR_BUF_PRINT_NAME_EX(name
);
768 __kmp_str_buf_print(buffer
, " %s=", name
);
770 __kmp_str_buf_print(buffer
, "%d", num
);
771 __kmp_str_buf_print(buffer
, "%cs\n", __kmp_blocktime_units
);
772 } // __kmp_stg_print_blocktime
774 // -----------------------------------------------------------------------------
775 // KMP_DUPLICATE_LIB_OK
777 static void __kmp_stg_parse_duplicate_lib_ok(char const *name
,
778 char const *value
, void *data
) {
779 /* actually this variable is not supported, put here for compatibility with
780 earlier builds and for static/dynamic combination */
781 __kmp_stg_parse_bool(name
, value
, &__kmp_duplicate_library_ok
);
782 } // __kmp_stg_parse_duplicate_lib_ok
784 static void __kmp_stg_print_duplicate_lib_ok(kmp_str_buf_t
*buffer
,
785 char const *name
, void *data
) {
786 __kmp_stg_print_bool(buffer
, name
, __kmp_duplicate_library_ok
);
787 } // __kmp_stg_print_duplicate_lib_ok
789 // -----------------------------------------------------------------------------
790 // KMP_INHERIT_FP_CONTROL
792 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
794 static void __kmp_stg_parse_inherit_fp_control(char const *name
,
795 char const *value
, void *data
) {
796 __kmp_stg_parse_bool(name
, value
, &__kmp_inherit_fp_control
);
797 } // __kmp_stg_parse_inherit_fp_control
799 static void __kmp_stg_print_inherit_fp_control(kmp_str_buf_t
*buffer
,
800 char const *name
, void *data
) {
802 __kmp_stg_print_bool(buffer
, name
, __kmp_inherit_fp_control
);
803 #endif /* KMP_DEBUG */
804 } // __kmp_stg_print_inherit_fp_control
806 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
808 // Used for OMP_WAIT_POLICY
809 static char const *blocktime_str
= NULL
;
811 // -----------------------------------------------------------------------------
812 // KMP_LIBRARY, OMP_WAIT_POLICY
814 static void __kmp_stg_parse_wait_policy(char const *name
, char const *value
,
817 kmp_stg_wp_data_t
*wait
= (kmp_stg_wp_data_t
*)data
;
820 rc
= __kmp_stg_check_rivals(name
, value
, wait
->rivals
);
826 if (__kmp_str_match("ACTIVE", 1, value
)) {
827 __kmp_library
= library_turnaround
;
828 if (blocktime_str
== NULL
) {
829 // KMP_BLOCKTIME not specified, so set default to "infinite".
830 __kmp_dflt_blocktime
= KMP_MAX_BLOCKTIME
;
832 } else if (__kmp_str_match("PASSIVE", 1, value
)) {
833 __kmp_library
= library_throughput
;
834 __kmp_wpolicy_passive
= true; /* allow sleep while active tasking */
835 if (blocktime_str
== NULL
) {
836 // KMP_BLOCKTIME not specified, so set default to 0.
837 __kmp_dflt_blocktime
= 0;
840 KMP_WARNING(StgInvalidValue
, name
, value
);
843 if (__kmp_str_match("serial", 1, value
)) { /* S */
844 __kmp_library
= library_serial
;
845 } else if (__kmp_str_match("throughput", 2, value
)) { /* TH */
846 __kmp_library
= library_throughput
;
847 if (blocktime_str
== NULL
) {
848 // KMP_BLOCKTIME not specified, so set default to 0.
849 __kmp_dflt_blocktime
= 0;
851 } else if (__kmp_str_match("turnaround", 2, value
)) { /* TU */
852 __kmp_library
= library_turnaround
;
853 } else if (__kmp_str_match("dedicated", 1, value
)) { /* D */
854 __kmp_library
= library_turnaround
;
855 } else if (__kmp_str_match("multiuser", 1, value
)) { /* M */
856 __kmp_library
= library_throughput
;
857 if (blocktime_str
== NULL
) {
858 // KMP_BLOCKTIME not specified, so set default to 0.
859 __kmp_dflt_blocktime
= 0;
862 KMP_WARNING(StgInvalidValue
, name
, value
);
865 } // __kmp_stg_parse_wait_policy
867 static void __kmp_stg_print_wait_policy(kmp_str_buf_t
*buffer
, char const *name
,
870 kmp_stg_wp_data_t
*wait
= (kmp_stg_wp_data_t
*)data
;
871 char const *value
= NULL
;
874 switch (__kmp_library
) {
875 case library_turnaround
: {
878 case library_throughput
: {
882 case library_serial
: {
887 switch (__kmp_library
) {
888 case library_serial
: {
891 case library_turnaround
: {
892 value
= "turnaround";
894 case library_throughput
: {
895 value
= "throughput";
903 __kmp_stg_print_str(buffer
, name
, value
);
906 } // __kmp_stg_print_wait_policy
909 // -----------------------------------------------------------------------------
910 // KMP_MONITOR_STACKSIZE
912 static void __kmp_stg_parse_monitor_stacksize(char const *name
,
913 char const *value
, void *data
) {
914 __kmp_stg_parse_size(name
, value
, __kmp_sys_min_stksize
, KMP_MAX_STKSIZE
,
915 NULL
, &__kmp_monitor_stksize
, 1);
916 } // __kmp_stg_parse_monitor_stacksize
918 static void __kmp_stg_print_monitor_stacksize(kmp_str_buf_t
*buffer
,
919 char const *name
, void *data
) {
920 if (__kmp_env_format
) {
921 if (__kmp_monitor_stksize
> 0)
922 KMP_STR_BUF_PRINT_NAME_EX(name
);
924 KMP_STR_BUF_PRINT_NAME
;
926 __kmp_str_buf_print(buffer
, " %s", name
);
928 if (__kmp_monitor_stksize
> 0) {
929 __kmp_str_buf_print_size(buffer
, __kmp_monitor_stksize
);
931 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
933 if (__kmp_env_format
&& __kmp_monitor_stksize
) {
934 __kmp_str_buf_print(buffer
, "'\n");
936 } // __kmp_stg_print_monitor_stacksize
937 #endif // KMP_USE_MONITOR
939 // -----------------------------------------------------------------------------
942 static void __kmp_stg_parse_settings(char const *name
, char const *value
,
944 __kmp_stg_parse_bool(name
, value
, &__kmp_settings
);
945 } // __kmp_stg_parse_settings
947 static void __kmp_stg_print_settings(kmp_str_buf_t
*buffer
, char const *name
,
949 __kmp_stg_print_bool(buffer
, name
, __kmp_settings
);
950 } // __kmp_stg_print_settings
952 // -----------------------------------------------------------------------------
955 static void __kmp_stg_parse_stackpad(char const *name
, char const *value
,
957 __kmp_stg_parse_int(name
, // Env var name
958 value
, // Env var value
959 KMP_MIN_STKPADDING
, // Min value
960 KMP_MAX_STKPADDING
, // Max value
961 &__kmp_stkpadding
// Var to initialize
963 } // __kmp_stg_parse_stackpad
965 static void __kmp_stg_print_stackpad(kmp_str_buf_t
*buffer
, char const *name
,
967 __kmp_stg_print_int(buffer
, name
, __kmp_stkpadding
);
968 } // __kmp_stg_print_stackpad
970 // -----------------------------------------------------------------------------
973 static void __kmp_stg_parse_stackoffset(char const *name
, char const *value
,
975 __kmp_stg_parse_size(name
, // Env var name
976 value
, // Env var value
977 KMP_MIN_STKOFFSET
, // Min value
978 KMP_MAX_STKOFFSET
, // Max value
980 &__kmp_stkoffset
, // Var to initialize
982 } // __kmp_stg_parse_stackoffset
984 static void __kmp_stg_print_stackoffset(kmp_str_buf_t
*buffer
, char const *name
,
986 __kmp_stg_print_size(buffer
, name
, __kmp_stkoffset
);
987 } // __kmp_stg_print_stackoffset
989 // -----------------------------------------------------------------------------
990 // KMP_STACKSIZE, OMP_STACKSIZE, GOMP_STACKSIZE
992 static void __kmp_stg_parse_stacksize(char const *name
, char const *value
,
995 kmp_stg_ss_data_t
*stacksize
= (kmp_stg_ss_data_t
*)data
;
998 rc
= __kmp_stg_check_rivals(name
, value
, stacksize
->rivals
);
1002 __kmp_stg_parse_size(name
, // Env var name
1003 value
, // Env var value
1004 __kmp_sys_min_stksize
, // Min value
1005 KMP_MAX_STKSIZE
, // Max value
1006 &__kmp_env_stksize
, //
1007 &__kmp_stksize
, // Var to initialize
1010 } // __kmp_stg_parse_stacksize
1012 // This function is called for printing both KMP_STACKSIZE (factor is 1) and
1013 // OMP_STACKSIZE (factor is 1024). Currently it is not possible to print
1014 // OMP_STACKSIZE value in bytes. We can consider adding this possibility by a
1015 // customer request in future.
1016 static void __kmp_stg_print_stacksize(kmp_str_buf_t
*buffer
, char const *name
,
1018 kmp_stg_ss_data_t
*stacksize
= (kmp_stg_ss_data_t
*)data
;
1019 if (__kmp_env_format
) {
1020 KMP_STR_BUF_PRINT_NAME_EX(name
);
1021 __kmp_str_buf_print_size(buffer
, (__kmp_stksize
% 1024)
1022 ? __kmp_stksize
/ stacksize
->factor
1024 __kmp_str_buf_print(buffer
, "'\n");
1026 __kmp_str_buf_print(buffer
, " %s=", name
);
1027 __kmp_str_buf_print_size(buffer
, (__kmp_stksize
% 1024)
1028 ? __kmp_stksize
/ stacksize
->factor
1030 __kmp_str_buf_print(buffer
, "\n");
1032 } // __kmp_stg_print_stacksize
1034 // -----------------------------------------------------------------------------
1037 static void __kmp_stg_parse_version(char const *name
, char const *value
,
1039 __kmp_stg_parse_bool(name
, value
, &__kmp_version
);
1040 } // __kmp_stg_parse_version
1042 static void __kmp_stg_print_version(kmp_str_buf_t
*buffer
, char const *name
,
1044 __kmp_stg_print_bool(buffer
, name
, __kmp_version
);
1045 } // __kmp_stg_print_version
1047 // -----------------------------------------------------------------------------
1050 static void __kmp_stg_parse_warnings(char const *name
, char const *value
,
1052 __kmp_stg_parse_bool(name
, value
, &__kmp_generate_warnings
);
1053 if (__kmp_generate_warnings
!= kmp_warnings_off
) {
1054 // AC: only 0/1 values documented, so reset to explicit to distinguish from
1056 __kmp_generate_warnings
= kmp_warnings_explicit
;
1058 } // __kmp_stg_parse_warnings
1060 static void __kmp_stg_print_warnings(kmp_str_buf_t
*buffer
, char const *name
,
1062 // AC: TODO: change to print_int? (needs documentation change)
1063 __kmp_stg_print_bool(buffer
, name
, __kmp_generate_warnings
);
1064 } // __kmp_stg_print_warnings
1066 // -----------------------------------------------------------------------------
1069 static void __kmp_stg_parse_nesting_mode(char const *name
, char const *value
,
1071 __kmp_stg_parse_int(name
, value
, 0, INT_MAX
, &__kmp_nesting_mode
);
1072 #if KMP_AFFINITY_SUPPORTED && KMP_USE_HWLOC
1073 if (__kmp_nesting_mode
> 0)
1074 __kmp_affinity_top_method
= affinity_top_method_hwloc
;
1076 } // __kmp_stg_parse_nesting_mode
1078 static void __kmp_stg_print_nesting_mode(kmp_str_buf_t
*buffer
,
1079 char const *name
, void *data
) {
1080 if (__kmp_env_format
) {
1081 KMP_STR_BUF_PRINT_NAME
;
1083 __kmp_str_buf_print(buffer
, " %s", name
);
1085 __kmp_str_buf_print(buffer
, "=%d\n", __kmp_nesting_mode
);
1086 } // __kmp_stg_print_nesting_mode
1088 // -----------------------------------------------------------------------------
1089 // OMP_NESTED, OMP_NUM_THREADS
1091 static void __kmp_stg_parse_nested(char const *name
, char const *value
,
1094 KMP_INFORM(EnvVarDeprecated
, name
, "OMP_MAX_ACTIVE_LEVELS");
1095 __kmp_stg_parse_bool(name
, value
, &nested
);
1097 if (!__kmp_dflt_max_active_levels_set
)
1098 __kmp_dflt_max_active_levels
= KMP_MAX_ACTIVE_LEVELS_LIMIT
;
1099 } else { // nesting explicitly turned off
1100 __kmp_dflt_max_active_levels
= 1;
1101 __kmp_dflt_max_active_levels_set
= true;
1103 } // __kmp_stg_parse_nested
1105 static void __kmp_stg_print_nested(kmp_str_buf_t
*buffer
, char const *name
,
1107 if (__kmp_env_format
) {
1108 KMP_STR_BUF_PRINT_NAME
;
1110 __kmp_str_buf_print(buffer
, " %s", name
);
1112 __kmp_str_buf_print(buffer
, ": deprecated; max-active-levels-var=%d\n",
1113 __kmp_dflt_max_active_levels
);
1114 } // __kmp_stg_print_nested
1116 static void __kmp_parse_nested_num_threads(const char *var
, const char *env
,
1117 kmp_nested_nthreads_t
*nth_array
) {
1118 const char *next
= env
;
1119 const char *scan
= next
;
1121 int total
= 0; // Count elements that were set. It'll be used as an array size
1122 int prev_comma
= FALSE
; // For correct processing sequential commas
1124 // Count the number of values in the env. var string
1128 if (*next
== '\0') {
1131 // Next character is not an integer or not a comma => end of list
1132 if (((*next
< '0') || (*next
> '9')) && (*next
!= ',')) {
1133 KMP_WARNING(NthSyntaxError
, var
, env
);
1136 // The next character is ','
1138 // ',' is the first character
1139 if (total
== 0 || prev_comma
) {
1146 // Next character is a digit
1147 if (*next
>= '0' && *next
<= '9') {
1151 const char *tmp
= next
;
1153 if ((*next
== ' ' || *next
== '\t') && (*tmp
>= '0' && *tmp
<= '9')) {
1154 KMP_WARNING(NthSpacesNotAllowed
, var
, env
);
1159 if (!__kmp_dflt_max_active_levels_set
&& total
> 1)
1160 __kmp_dflt_max_active_levels
= KMP_MAX_ACTIVE_LEVELS_LIMIT
;
1161 KMP_DEBUG_ASSERT(total
> 0);
1163 KMP_WARNING(NthSyntaxError
, var
, env
);
1167 // Check if the nested nthreads array exists
1168 if (!nth_array
->nth
) {
1169 // Allocate an array of double size
1170 nth_array
->nth
= (int *)KMP_INTERNAL_MALLOC(sizeof(int) * total
* 2);
1171 if (nth_array
->nth
== NULL
) {
1172 KMP_FATAL(MemoryAllocFailed
);
1174 nth_array
->size
= total
* 2;
1176 if (nth_array
->size
< total
) {
1177 // Increase the array size
1179 nth_array
->size
*= 2;
1180 } while (nth_array
->size
< total
);
1182 nth_array
->nth
= (int *)KMP_INTERNAL_REALLOC(
1183 nth_array
->nth
, sizeof(int) * nth_array
->size
);
1184 if (nth_array
->nth
== NULL
) {
1185 KMP_FATAL(MemoryAllocFailed
);
1189 nth_array
->used
= total
;
1194 // Save values in the array
1197 if (*scan
== '\0') {
1200 // The next character is ','
1202 // ',' in the beginning of the list
1204 // The value is supposed to be equal to __kmp_avail_proc but it is
1205 // unknown at the moment.
1206 // So let's put a placeholder (#threads = 0) to correct it later.
1207 nth_array
->nth
[i
++] = 0;
1209 } else if (prev_comma
) {
1210 // Num threads is inherited from the previous level
1211 nth_array
->nth
[i
] = nth_array
->nth
[i
- 1];
1219 // Next character is a digit
1220 if (*scan
>= '0' && *scan
<= '9') {
1222 const char *buf
= scan
;
1223 char const *msg
= NULL
;
1228 num
= __kmp_str_to_int(buf
, *scan
);
1229 if (num
< KMP_MIN_NTH
) {
1230 msg
= KMP_I18N_STR(ValueTooSmall
);
1232 } else if (num
> __kmp_sys_max_nth
) {
1233 msg
= KMP_I18N_STR(ValueTooLarge
);
1234 num
= __kmp_sys_max_nth
;
1237 // Message is not empty. Print warning.
1238 KMP_WARNING(ParseSizeIntWarn
, var
, env
, msg
);
1239 KMP_INFORM(Using_int_Value
, var
, num
);
1241 nth_array
->nth
[i
++] = num
;
1246 static void __kmp_stg_parse_num_threads(char const *name
, char const *value
,
1248 // TODO: Remove this option. OMP_NUM_THREADS is a list of positive integers!
1249 if (!__kmp_strcasecmp_with_sentinel("all", value
, 0)) {
1250 // The array of 1 element
1251 __kmp_nested_nth
.nth
= (int *)KMP_INTERNAL_MALLOC(sizeof(int));
1252 __kmp_nested_nth
.size
= __kmp_nested_nth
.used
= 1;
1253 __kmp_nested_nth
.nth
[0] = __kmp_dflt_team_nth
= __kmp_dflt_team_nth_ub
=
1256 __kmp_parse_nested_num_threads(name
, value
, &__kmp_nested_nth
);
1257 if (__kmp_nested_nth
.nth
) {
1258 __kmp_dflt_team_nth
= __kmp_nested_nth
.nth
[0];
1259 if (__kmp_dflt_team_nth_ub
< __kmp_dflt_team_nth
) {
1260 __kmp_dflt_team_nth_ub
= __kmp_dflt_team_nth
;
1264 K_DIAG(1, ("__kmp_dflt_team_nth == %d\n", __kmp_dflt_team_nth
));
1265 } // __kmp_stg_parse_num_threads
1268 static void __kmp_stg_parse_max_tdgs(char const *name
, char const *value
,
1270 __kmp_stg_parse_int(name
, value
, 0, INT_MAX
, &__kmp_max_tdgs
);
1271 } // __kmp_stg_parse_max_tdgs
1273 static void __kmp_std_print_max_tdgs(kmp_str_buf_t
*buffer
, char const *name
,
1275 __kmp_stg_print_int(buffer
, name
, __kmp_max_tdgs
);
1276 } // __kmp_std_print_max_tdgs
1278 static void __kmp_stg_parse_tdg_dot(char const *name
, char const *value
,
1280 __kmp_stg_parse_bool(name
, value
, &__kmp_tdg_dot
);
1281 } // __kmp_stg_parse_tdg_dot
1283 static void __kmp_stg_print_tdg_dot(kmp_str_buf_t
*buffer
, char const *name
,
1285 __kmp_stg_print_bool(buffer
, name
, __kmp_tdg_dot
);
1286 } // __kmp_stg_print_tdg_dot
1289 static void __kmp_stg_parse_num_hidden_helper_threads(char const *name
,
1292 __kmp_stg_parse_int(name
, value
, 0, 16, &__kmp_hidden_helper_threads_num
);
1293 // If the number of hidden helper threads is zero, we disable hidden helper
1295 if (__kmp_hidden_helper_threads_num
== 0) {
1296 __kmp_enable_hidden_helper
= FALSE
;
1298 // Since the main thread of hidden helper team does not participate
1299 // in tasks execution let's increment the number of threads by one
1300 // so that requested number of threads do actual job.
1301 __kmp_hidden_helper_threads_num
++;
1303 } // __kmp_stg_parse_num_hidden_helper_threads
1305 static void __kmp_stg_print_num_hidden_helper_threads(kmp_str_buf_t
*buffer
,
1308 if (__kmp_hidden_helper_threads_num
== 0) {
1309 __kmp_stg_print_int(buffer
, name
, __kmp_hidden_helper_threads_num
);
1311 KMP_DEBUG_ASSERT(__kmp_hidden_helper_threads_num
> 1);
1312 // Let's exclude the main thread of hidden helper team and print
1313 // number of worker threads those do actual job.
1314 __kmp_stg_print_int(buffer
, name
, __kmp_hidden_helper_threads_num
- 1);
1316 } // __kmp_stg_print_num_hidden_helper_threads
1318 static void __kmp_stg_parse_use_hidden_helper(char const *name
,
1319 char const *value
, void *data
) {
1320 __kmp_stg_parse_bool(name
, value
, &__kmp_enable_hidden_helper
);
1322 __kmp_enable_hidden_helper
= FALSE
;
1324 ("__kmp_stg_parse_use_hidden_helper: Disable hidden helper task on "
1325 "non-Linux platform although it is enabled by user explicitly.\n"));
1327 } // __kmp_stg_parse_use_hidden_helper
1329 static void __kmp_stg_print_use_hidden_helper(kmp_str_buf_t
*buffer
,
1330 char const *name
, void *data
) {
1331 __kmp_stg_print_bool(buffer
, name
, __kmp_enable_hidden_helper
);
1332 } // __kmp_stg_print_use_hidden_helper
1334 static void __kmp_stg_print_num_threads(kmp_str_buf_t
*buffer
, char const *name
,
1336 if (__kmp_env_format
) {
1337 KMP_STR_BUF_PRINT_NAME
;
1339 __kmp_str_buf_print(buffer
, " %s", name
);
1341 if (__kmp_nested_nth
.used
) {
1343 __kmp_str_buf_init(&buf
);
1344 for (int i
= 0; i
< __kmp_nested_nth
.used
; i
++) {
1345 __kmp_str_buf_print(&buf
, "%d", __kmp_nested_nth
.nth
[i
]);
1346 if (i
< __kmp_nested_nth
.used
- 1) {
1347 __kmp_str_buf_print(&buf
, ",");
1350 __kmp_str_buf_print(buffer
, "='%s'\n", buf
.str
);
1351 __kmp_str_buf_free(&buf
);
1353 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
1355 } // __kmp_stg_print_num_threads
1357 // -----------------------------------------------------------------------------
1358 // OpenMP 3.0: KMP_TASKING, OMP_MAX_ACTIVE_LEVELS,
1360 static void __kmp_stg_parse_tasking(char const *name
, char const *value
,
1362 __kmp_stg_parse_int(name
, value
, 0, (int)tskm_max
,
1363 (int *)&__kmp_tasking_mode
);
1364 } // __kmp_stg_parse_tasking
1366 static void __kmp_stg_print_tasking(kmp_str_buf_t
*buffer
, char const *name
,
1368 __kmp_stg_print_int(buffer
, name
, __kmp_tasking_mode
);
1369 } // __kmp_stg_print_tasking
1371 static void __kmp_stg_parse_task_stealing(char const *name
, char const *value
,
1373 __kmp_stg_parse_int(name
, value
, 0, 1,
1374 (int *)&__kmp_task_stealing_constraint
);
1375 } // __kmp_stg_parse_task_stealing
1377 static void __kmp_stg_print_task_stealing(kmp_str_buf_t
*buffer
,
1378 char const *name
, void *data
) {
1379 __kmp_stg_print_int(buffer
, name
, __kmp_task_stealing_constraint
);
1380 } // __kmp_stg_print_task_stealing
1382 static void __kmp_stg_parse_max_active_levels(char const *name
,
1383 char const *value
, void *data
) {
1384 kmp_uint64 tmp_dflt
= 0;
1385 char const *msg
= NULL
;
1386 if (!__kmp_dflt_max_active_levels_set
) {
1387 // Don't overwrite __kmp_dflt_max_active_levels if we get an invalid setting
1388 __kmp_str_to_uint(value
, &tmp_dflt
, &msg
);
1389 if (msg
!= NULL
) { // invalid setting; print warning and ignore
1390 KMP_WARNING(ParseSizeIntWarn
, name
, value
, msg
);
1391 } else if (tmp_dflt
> KMP_MAX_ACTIVE_LEVELS_LIMIT
) {
1392 // invalid setting; print warning and ignore
1393 msg
= KMP_I18N_STR(ValueTooLarge
);
1394 KMP_WARNING(ParseSizeIntWarn
, name
, value
, msg
);
1395 } else { // valid setting
1396 __kmp_type_convert(tmp_dflt
, &(__kmp_dflt_max_active_levels
));
1397 __kmp_dflt_max_active_levels_set
= true;
1400 } // __kmp_stg_parse_max_active_levels
1402 static void __kmp_stg_print_max_active_levels(kmp_str_buf_t
*buffer
,
1403 char const *name
, void *data
) {
1404 __kmp_stg_print_int(buffer
, name
, __kmp_dflt_max_active_levels
);
1405 } // __kmp_stg_print_max_active_levels
1407 // -----------------------------------------------------------------------------
1408 // OpenMP 4.0: OMP_DEFAULT_DEVICE
1409 static void __kmp_stg_parse_default_device(char const *name
, char const *value
,
1411 __kmp_stg_parse_int(name
, value
, 0, KMP_MAX_DEFAULT_DEVICE_LIMIT
,
1412 &__kmp_default_device
);
1413 } // __kmp_stg_parse_default_device
1415 static void __kmp_stg_print_default_device(kmp_str_buf_t
*buffer
,
1416 char const *name
, void *data
) {
1417 __kmp_stg_print_int(buffer
, name
, __kmp_default_device
);
1418 } // __kmp_stg_print_default_device
1420 // -----------------------------------------------------------------------------
1421 // OpenMP 5.0: OMP_TARGET_OFFLOAD
1422 static void __kmp_stg_parse_target_offload(char const *name
, char const *value
,
1424 kmp_trimmed_str_t
value_str(value
);
1425 const char *scan
= value_str
.get();
1426 __kmp_target_offload
= tgt_default
;
1431 if (!__kmp_strcasecmp_with_sentinel("mandatory", scan
, 0)) {
1432 __kmp_target_offload
= tgt_mandatory
;
1433 } else if (!__kmp_strcasecmp_with_sentinel("disabled", scan
, 0)) {
1434 __kmp_target_offload
= tgt_disabled
;
1435 } else if (!__kmp_strcasecmp_with_sentinel("default", scan
, 0)) {
1436 __kmp_target_offload
= tgt_default
;
1438 KMP_WARNING(SyntaxErrorUsing
, name
, "DEFAULT");
1440 } // __kmp_stg_parse_target_offload
1442 static void __kmp_stg_print_target_offload(kmp_str_buf_t
*buffer
,
1443 char const *name
, void *data
) {
1444 const char *value
= NULL
;
1445 if (__kmp_target_offload
== tgt_default
)
1447 else if (__kmp_target_offload
== tgt_mandatory
)
1448 value
= "MANDATORY";
1449 else if (__kmp_target_offload
== tgt_disabled
)
1451 KMP_DEBUG_ASSERT(value
);
1452 if (__kmp_env_format
) {
1453 KMP_STR_BUF_PRINT_NAME
;
1455 __kmp_str_buf_print(buffer
, " %s", name
);
1457 __kmp_str_buf_print(buffer
, "=%s\n", value
);
1458 } // __kmp_stg_print_target_offload
1460 // -----------------------------------------------------------------------------
1461 // OpenMP 4.5: OMP_MAX_TASK_PRIORITY
1462 static void __kmp_stg_parse_max_task_priority(char const *name
,
1463 char const *value
, void *data
) {
1464 __kmp_stg_parse_int(name
, value
, 0, KMP_MAX_TASK_PRIORITY_LIMIT
,
1465 &__kmp_max_task_priority
);
1466 } // __kmp_stg_parse_max_task_priority
1468 static void __kmp_stg_print_max_task_priority(kmp_str_buf_t
*buffer
,
1469 char const *name
, void *data
) {
1470 __kmp_stg_print_int(buffer
, name
, __kmp_max_task_priority
);
1471 } // __kmp_stg_print_max_task_priority
1473 // KMP_TASKLOOP_MIN_TASKS
1474 // taskloop threshold to switch from recursive to linear tasks creation
1475 static void __kmp_stg_parse_taskloop_min_tasks(char const *name
,
1476 char const *value
, void *data
) {
1478 __kmp_stg_parse_int(name
, value
, 0, INT_MAX
, &tmp
);
1479 __kmp_taskloop_min_tasks
= tmp
;
1480 } // __kmp_stg_parse_taskloop_min_tasks
1482 static void __kmp_stg_print_taskloop_min_tasks(kmp_str_buf_t
*buffer
,
1483 char const *name
, void *data
) {
1484 __kmp_stg_print_uint64(buffer
, name
, __kmp_taskloop_min_tasks
);
1485 } // __kmp_stg_print_taskloop_min_tasks
1487 // -----------------------------------------------------------------------------
1488 // KMP_DISP_NUM_BUFFERS
1489 static void __kmp_stg_parse_disp_buffers(char const *name
, char const *value
,
1491 if (TCR_4(__kmp_init_serial
)) {
1492 KMP_WARNING(EnvSerialWarn
, name
);
1494 } // read value before serial initialization only
1495 __kmp_stg_parse_int(name
, value
, KMP_MIN_DISP_NUM_BUFF
, KMP_MAX_DISP_NUM_BUFF
,
1496 &__kmp_dispatch_num_buffers
);
1497 } // __kmp_stg_parse_disp_buffers
1499 static void __kmp_stg_print_disp_buffers(kmp_str_buf_t
*buffer
,
1500 char const *name
, void *data
) {
1501 __kmp_stg_print_int(buffer
, name
, __kmp_dispatch_num_buffers
);
1502 } // __kmp_stg_print_disp_buffers
1504 #if KMP_NESTED_HOT_TEAMS
1505 // -----------------------------------------------------------------------------
1506 // KMP_HOT_TEAMS_MAX_LEVEL, KMP_HOT_TEAMS_MODE
1508 static void __kmp_stg_parse_hot_teams_level(char const *name
, char const *value
,
1510 if (TCR_4(__kmp_init_parallel
)) {
1511 KMP_WARNING(EnvParallelWarn
, name
);
1513 } // read value before first parallel only
1514 __kmp_stg_parse_int(name
, value
, 0, KMP_MAX_ACTIVE_LEVELS_LIMIT
,
1515 &__kmp_hot_teams_max_level
);
1516 } // __kmp_stg_parse_hot_teams_level
1518 static void __kmp_stg_print_hot_teams_level(kmp_str_buf_t
*buffer
,
1519 char const *name
, void *data
) {
1520 __kmp_stg_print_int(buffer
, name
, __kmp_hot_teams_max_level
);
1521 } // __kmp_stg_print_hot_teams_level
1523 static void __kmp_stg_parse_hot_teams_mode(char const *name
, char const *value
,
1525 if (TCR_4(__kmp_init_parallel
)) {
1526 KMP_WARNING(EnvParallelWarn
, name
);
1528 } // read value before first parallel only
1529 __kmp_stg_parse_int(name
, value
, 0, KMP_MAX_ACTIVE_LEVELS_LIMIT
,
1530 &__kmp_hot_teams_mode
);
1531 } // __kmp_stg_parse_hot_teams_mode
1533 static void __kmp_stg_print_hot_teams_mode(kmp_str_buf_t
*buffer
,
1534 char const *name
, void *data
) {
1535 __kmp_stg_print_int(buffer
, name
, __kmp_hot_teams_mode
);
1536 } // __kmp_stg_print_hot_teams_mode
1538 #endif // KMP_NESTED_HOT_TEAMS
1540 // -----------------------------------------------------------------------------
1541 // KMP_HANDLE_SIGNALS
1543 #if KMP_HANDLE_SIGNALS
1545 static void __kmp_stg_parse_handle_signals(char const *name
, char const *value
,
1547 __kmp_stg_parse_bool(name
, value
, &__kmp_handle_signals
);
1548 } // __kmp_stg_parse_handle_signals
1550 static void __kmp_stg_print_handle_signals(kmp_str_buf_t
*buffer
,
1551 char const *name
, void *data
) {
1552 __kmp_stg_print_bool(buffer
, name
, __kmp_handle_signals
);
1553 } // __kmp_stg_print_handle_signals
1555 #endif // KMP_HANDLE_SIGNALS
1557 // -----------------------------------------------------------------------------
1558 // KMP_X_DEBUG, KMP_DEBUG, KMP_DEBUG_BUF_*, KMP_DIAG
1562 #define KMP_STG_X_DEBUG(x) \
1563 static void __kmp_stg_parse_##x##_debug(char const *name, char const *value, \
1565 __kmp_stg_parse_int(name, value, 0, INT_MAX, &kmp_##x##_debug); \
1566 } /* __kmp_stg_parse_x_debug */ \
1567 static void __kmp_stg_print_##x##_debug(kmp_str_buf_t *buffer, \
1568 char const *name, void *data) { \
1569 __kmp_stg_print_int(buffer, name, kmp_##x##_debug); \
1570 } /* __kmp_stg_print_x_debug */
1579 #undef KMP_STG_X_DEBUG
1581 static void __kmp_stg_parse_debug(char const *name
, char const *value
,
1584 __kmp_stg_parse_int(name
, value
, 0, INT_MAX
, &debug
);
1585 if (kmp_a_debug
< debug
) {
1586 kmp_a_debug
= debug
;
1588 if (kmp_b_debug
< debug
) {
1589 kmp_b_debug
= debug
;
1591 if (kmp_c_debug
< debug
) {
1592 kmp_c_debug
= debug
;
1594 if (kmp_d_debug
< debug
) {
1595 kmp_d_debug
= debug
;
1597 if (kmp_e_debug
< debug
) {
1598 kmp_e_debug
= debug
;
1600 if (kmp_f_debug
< debug
) {
1601 kmp_f_debug
= debug
;
1603 } // __kmp_stg_parse_debug
1605 static void __kmp_stg_parse_debug_buf(char const *name
, char const *value
,
1607 __kmp_stg_parse_bool(name
, value
, &__kmp_debug_buf
);
1608 // !!! TODO: Move buffer initialization of this file! It may works
1609 // incorrectly if KMP_DEBUG_BUF is parsed before KMP_DEBUG_BUF_LINES or
1610 // KMP_DEBUG_BUF_CHARS.
1611 if (__kmp_debug_buf
) {
1613 int elements
= __kmp_debug_buf_lines
* __kmp_debug_buf_chars
;
1615 /* allocate and initialize all entries in debug buffer to empty */
1616 __kmp_debug_buffer
= (char *)__kmp_page_allocate(elements
* sizeof(char));
1617 for (i
= 0; i
< elements
; i
+= __kmp_debug_buf_chars
)
1618 __kmp_debug_buffer
[i
] = '\0';
1620 __kmp_debug_count
= 0;
1622 K_DIAG(1, ("__kmp_debug_buf = %d\n", __kmp_debug_buf
));
1623 } // __kmp_stg_parse_debug_buf
1625 static void __kmp_stg_print_debug_buf(kmp_str_buf_t
*buffer
, char const *name
,
1627 __kmp_stg_print_bool(buffer
, name
, __kmp_debug_buf
);
1628 } // __kmp_stg_print_debug_buf
1630 static void __kmp_stg_parse_debug_buf_atomic(char const *name
,
1631 char const *value
, void *data
) {
1632 __kmp_stg_parse_bool(name
, value
, &__kmp_debug_buf_atomic
);
1633 } // __kmp_stg_parse_debug_buf_atomic
1635 static void __kmp_stg_print_debug_buf_atomic(kmp_str_buf_t
*buffer
,
1636 char const *name
, void *data
) {
1637 __kmp_stg_print_bool(buffer
, name
, __kmp_debug_buf_atomic
);
1638 } // __kmp_stg_print_debug_buf_atomic
1640 static void __kmp_stg_parse_debug_buf_chars(char const *name
, char const *value
,
1642 __kmp_stg_parse_int(name
, value
, KMP_DEBUG_BUF_CHARS_MIN
, INT_MAX
,
1643 &__kmp_debug_buf_chars
);
1644 } // __kmp_stg_debug_parse_buf_chars
1646 static void __kmp_stg_print_debug_buf_chars(kmp_str_buf_t
*buffer
,
1647 char const *name
, void *data
) {
1648 __kmp_stg_print_int(buffer
, name
, __kmp_debug_buf_chars
);
1649 } // __kmp_stg_print_debug_buf_chars
1651 static void __kmp_stg_parse_debug_buf_lines(char const *name
, char const *value
,
1653 __kmp_stg_parse_int(name
, value
, KMP_DEBUG_BUF_LINES_MIN
, INT_MAX
,
1654 &__kmp_debug_buf_lines
);
1655 } // __kmp_stg_parse_debug_buf_lines
1657 static void __kmp_stg_print_debug_buf_lines(kmp_str_buf_t
*buffer
,
1658 char const *name
, void *data
) {
1659 __kmp_stg_print_int(buffer
, name
, __kmp_debug_buf_lines
);
1660 } // __kmp_stg_print_debug_buf_lines
1662 static void __kmp_stg_parse_diag(char const *name
, char const *value
,
1664 __kmp_stg_parse_int(name
, value
, 0, INT_MAX
, &kmp_diag
);
1665 } // __kmp_stg_parse_diag
1667 static void __kmp_stg_print_diag(kmp_str_buf_t
*buffer
, char const *name
,
1669 __kmp_stg_print_int(buffer
, name
, kmp_diag
);
1670 } // __kmp_stg_print_diag
1674 // -----------------------------------------------------------------------------
1677 static void __kmp_stg_parse_align_alloc(char const *name
, char const *value
,
1679 __kmp_stg_parse_size(name
, value
, CACHE_LINE
, INT_MAX
, NULL
,
1680 &__kmp_align_alloc
, 1);
1681 } // __kmp_stg_parse_align_alloc
1683 static void __kmp_stg_print_align_alloc(kmp_str_buf_t
*buffer
, char const *name
,
1685 __kmp_stg_print_size(buffer
, name
, __kmp_align_alloc
);
1686 } // __kmp_stg_print_align_alloc
1688 // -----------------------------------------------------------------------------
1689 // KMP_PLAIN_BARRIER, KMP_FORKJOIN_BARRIER, KMP_REDUCTION_BARRIER
1691 // TODO: Remove __kmp_barrier_branch_bit_env_name varibale, remove loops from
1692 // parse and print functions, pass required info through data argument.
1694 static void __kmp_stg_parse_barrier_branch_bit(char const *name
,
1695 char const *value
, void *data
) {
1698 /* ---------- Barrier branch bit control ------------ */
1699 for (int i
= bs_plain_barrier
; i
< bs_last_barrier
; i
++) {
1700 var
= __kmp_barrier_branch_bit_env_name
[i
];
1701 if ((strcmp(var
, name
) == 0) && (value
!= 0)) {
1704 comma
= CCAST(char *, strchr(value
, ','));
1705 __kmp_barrier_gather_branch_bits
[i
] =
1706 (kmp_uint32
)__kmp_str_to_int(value
, ',');
1707 /* is there a specified release parameter? */
1708 if (comma
== NULL
) {
1709 __kmp_barrier_release_branch_bits
[i
] = __kmp_barrier_release_bb_dflt
;
1711 __kmp_barrier_release_branch_bits
[i
] =
1712 (kmp_uint32
)__kmp_str_to_int(comma
+ 1, 0);
1714 if (__kmp_barrier_release_branch_bits
[i
] > KMP_MAX_BRANCH_BITS
) {
1715 __kmp_msg(kmp_ms_warning
,
1716 KMP_MSG(BarrReleaseValueInvalid
, name
, comma
+ 1),
1718 __kmp_barrier_release_branch_bits
[i
] = __kmp_barrier_release_bb_dflt
;
1721 if (__kmp_barrier_gather_branch_bits
[i
] > KMP_MAX_BRANCH_BITS
) {
1722 KMP_WARNING(BarrGatherValueInvalid
, name
, value
);
1723 KMP_INFORM(Using_uint_Value
, name
, __kmp_barrier_gather_bb_dflt
);
1724 __kmp_barrier_gather_branch_bits
[i
] = __kmp_barrier_gather_bb_dflt
;
1727 K_DIAG(1, ("%s == %d,%d\n", __kmp_barrier_branch_bit_env_name
[i
],
1728 __kmp_barrier_gather_branch_bits
[i
],
1729 __kmp_barrier_release_branch_bits
[i
]))
1731 } // __kmp_stg_parse_barrier_branch_bit
1733 static void __kmp_stg_print_barrier_branch_bit(kmp_str_buf_t
*buffer
,
1734 char const *name
, void *data
) {
1736 for (int i
= bs_plain_barrier
; i
< bs_last_barrier
; i
++) {
1737 var
= __kmp_barrier_branch_bit_env_name
[i
];
1738 if (strcmp(var
, name
) == 0) {
1739 if (__kmp_env_format
) {
1740 KMP_STR_BUF_PRINT_NAME_EX(__kmp_barrier_branch_bit_env_name
[i
]);
1742 __kmp_str_buf_print(buffer
, " %s='",
1743 __kmp_barrier_branch_bit_env_name
[i
]);
1745 __kmp_str_buf_print(buffer
, "%d,%d'\n",
1746 __kmp_barrier_gather_branch_bits
[i
],
1747 __kmp_barrier_release_branch_bits
[i
]);
1750 } // __kmp_stg_print_barrier_branch_bit
1752 // ----------------------------------------------------------------------------
1753 // KMP_PLAIN_BARRIER_PATTERN, KMP_FORKJOIN_BARRIER_PATTERN,
1754 // KMP_REDUCTION_BARRIER_PATTERN
1756 // TODO: Remove __kmp_barrier_pattern_name variable, remove loops from parse and
1757 // print functions, pass required data to functions through data argument.
1759 static void __kmp_stg_parse_barrier_pattern(char const *name
, char const *value
,
1762 /* ---------- Barrier method control ------------ */
1764 static int dist_req
= 0, non_dist_req
= 0;
1765 static bool warn
= 1;
1766 for (int i
= bs_plain_barrier
; i
< bs_last_barrier
; i
++) {
1767 var
= __kmp_barrier_pattern_env_name
[i
];
1769 if ((strcmp(var
, name
) == 0) && (value
!= 0)) {
1771 char *comma
= CCAST(char *, strchr(value
, ','));
1773 /* handle first parameter: gather pattern */
1774 for (j
= bp_linear_bar
; j
< bp_last_bar
; j
++) {
1775 if (__kmp_match_with_sentinel(__kmp_barrier_pattern_name
[j
], value
, 1,
1777 if (j
== bp_dist_bar
) {
1782 __kmp_barrier_gather_pattern
[i
] = (kmp_bar_pat_e
)j
;
1786 if (j
== bp_last_bar
) {
1787 KMP_WARNING(BarrGatherValueInvalid
, name
, value
);
1788 KMP_INFORM(Using_str_Value
, name
,
1789 __kmp_barrier_pattern_name
[bp_linear_bar
]);
1792 /* handle second parameter: release pattern */
1793 if (comma
!= NULL
) {
1794 for (j
= bp_linear_bar
; j
< bp_last_bar
; j
++) {
1795 if (__kmp_str_match(__kmp_barrier_pattern_name
[j
], 1, comma
+ 1)) {
1796 if (j
== bp_dist_bar
) {
1801 __kmp_barrier_release_pattern
[i
] = (kmp_bar_pat_e
)j
;
1805 if (j
== bp_last_bar
) {
1806 __kmp_msg(kmp_ms_warning
,
1807 KMP_MSG(BarrReleaseValueInvalid
, name
, comma
+ 1),
1809 KMP_INFORM(Using_str_Value
, name
,
1810 __kmp_barrier_pattern_name
[bp_linear_bar
]);
1815 if (dist_req
!= 0) {
1816 // set all barriers to dist
1817 if ((non_dist_req
!= 0) && warn
) {
1818 KMP_INFORM(BarrierPatternOverride
, name
,
1819 __kmp_barrier_pattern_name
[bp_dist_bar
]);
1822 for (int i
= bs_plain_barrier
; i
< bs_last_barrier
; i
++) {
1823 if (__kmp_barrier_release_pattern
[i
] != bp_dist_bar
)
1824 __kmp_barrier_release_pattern
[i
] = bp_dist_bar
;
1825 if (__kmp_barrier_gather_pattern
[i
] != bp_dist_bar
)
1826 __kmp_barrier_gather_pattern
[i
] = bp_dist_bar
;
1829 } // __kmp_stg_parse_barrier_pattern
1831 static void __kmp_stg_print_barrier_pattern(kmp_str_buf_t
*buffer
,
1832 char const *name
, void *data
) {
1834 for (int i
= bs_plain_barrier
; i
< bs_last_barrier
; i
++) {
1835 var
= __kmp_barrier_pattern_env_name
[i
];
1836 if (strcmp(var
, name
) == 0) {
1837 int j
= __kmp_barrier_gather_pattern
[i
];
1838 int k
= __kmp_barrier_release_pattern
[i
];
1839 if (__kmp_env_format
) {
1840 KMP_STR_BUF_PRINT_NAME_EX(__kmp_barrier_pattern_env_name
[i
]);
1842 __kmp_str_buf_print(buffer
, " %s='",
1843 __kmp_barrier_pattern_env_name
[i
]);
1845 KMP_DEBUG_ASSERT(j
< bp_last_bar
&& k
< bp_last_bar
);
1846 __kmp_str_buf_print(buffer
, "%s,%s'\n", __kmp_barrier_pattern_name
[j
],
1847 __kmp_barrier_pattern_name
[k
]);
1850 } // __kmp_stg_print_barrier_pattern
1852 // -----------------------------------------------------------------------------
1855 static void __kmp_stg_parse_abort_delay(char const *name
, char const *value
,
1857 // Units of KMP_DELAY_ABORT are seconds, units of __kmp_abort_delay is
1859 int delay
= __kmp_abort_delay
/ 1000;
1860 __kmp_stg_parse_int(name
, value
, 0, INT_MAX
/ 1000, &delay
);
1861 __kmp_abort_delay
= delay
* 1000;
1862 } // __kmp_stg_parse_abort_delay
1864 static void __kmp_stg_print_abort_delay(kmp_str_buf_t
*buffer
, char const *name
,
1866 __kmp_stg_print_int(buffer
, name
, __kmp_abort_delay
);
1867 } // __kmp_stg_print_abort_delay
1869 // -----------------------------------------------------------------------------
1872 static void __kmp_stg_parse_cpuinfo_file(char const *name
, char const *value
,
1874 #if KMP_AFFINITY_SUPPORTED
1875 __kmp_stg_parse_str(name
, value
, &__kmp_cpuinfo_file
);
1876 K_DIAG(1, ("__kmp_cpuinfo_file == %s\n", __kmp_cpuinfo_file
));
1878 } //__kmp_stg_parse_cpuinfo_file
1880 static void __kmp_stg_print_cpuinfo_file(kmp_str_buf_t
*buffer
,
1881 char const *name
, void *data
) {
1882 #if KMP_AFFINITY_SUPPORTED
1883 if (__kmp_env_format
) {
1884 KMP_STR_BUF_PRINT_NAME
;
1886 __kmp_str_buf_print(buffer
, " %s", name
);
1888 if (__kmp_cpuinfo_file
) {
1889 __kmp_str_buf_print(buffer
, "='%s'\n", __kmp_cpuinfo_file
);
1891 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
1894 } //__kmp_stg_print_cpuinfo_file
1896 // -----------------------------------------------------------------------------
1897 // KMP_FORCE_REDUCTION, KMP_DETERMINISTIC_REDUCTION
1899 static void __kmp_stg_parse_force_reduction(char const *name
, char const *value
,
1901 kmp_stg_fr_data_t
*reduction
= (kmp_stg_fr_data_t
*)data
;
1904 rc
= __kmp_stg_check_rivals(name
, value
, reduction
->rivals
);
1908 if (reduction
->force
) {
1910 if (__kmp_str_match("critical", 0, value
))
1911 __kmp_force_reduction_method
= critical_reduce_block
;
1912 else if (__kmp_str_match("atomic", 0, value
))
1913 __kmp_force_reduction_method
= atomic_reduce_block
;
1914 else if (__kmp_str_match("tree", 0, value
))
1915 __kmp_force_reduction_method
= tree_reduce_block
;
1917 KMP_FATAL(UnknownForceReduction
, name
, value
);
1921 __kmp_stg_parse_bool(name
, value
, &__kmp_determ_red
);
1922 if (__kmp_determ_red
) {
1923 __kmp_force_reduction_method
= tree_reduce_block
;
1925 __kmp_force_reduction_method
= reduction_method_not_defined
;
1928 K_DIAG(1, ("__kmp_force_reduction_method == %d\n",
1929 __kmp_force_reduction_method
));
1930 } // __kmp_stg_parse_force_reduction
1932 static void __kmp_stg_print_force_reduction(kmp_str_buf_t
*buffer
,
1933 char const *name
, void *data
) {
1935 kmp_stg_fr_data_t
*reduction
= (kmp_stg_fr_data_t
*)data
;
1936 if (reduction
->force
) {
1937 if (__kmp_force_reduction_method
== critical_reduce_block
) {
1938 __kmp_stg_print_str(buffer
, name
, "critical");
1939 } else if (__kmp_force_reduction_method
== atomic_reduce_block
) {
1940 __kmp_stg_print_str(buffer
, name
, "atomic");
1941 } else if (__kmp_force_reduction_method
== tree_reduce_block
) {
1942 __kmp_stg_print_str(buffer
, name
, "tree");
1944 if (__kmp_env_format
) {
1945 KMP_STR_BUF_PRINT_NAME
;
1947 __kmp_str_buf_print(buffer
, " %s", name
);
1949 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
1952 __kmp_stg_print_bool(buffer
, name
, __kmp_determ_red
);
1955 } // __kmp_stg_print_force_reduction
1957 // -----------------------------------------------------------------------------
1960 static void __kmp_stg_parse_storage_map(char const *name
, char const *value
,
1962 if (__kmp_str_match("verbose", 1, value
)) {
1963 __kmp_storage_map
= TRUE
;
1964 __kmp_storage_map_verbose
= TRUE
;
1965 __kmp_storage_map_verbose_specified
= TRUE
;
1968 __kmp_storage_map_verbose
= FALSE
;
1969 __kmp_stg_parse_bool(name
, value
, &__kmp_storage_map
); // !!!
1971 } // __kmp_stg_parse_storage_map
1973 static void __kmp_stg_print_storage_map(kmp_str_buf_t
*buffer
, char const *name
,
1975 if (__kmp_storage_map_verbose
|| __kmp_storage_map_verbose_specified
) {
1976 __kmp_stg_print_str(buffer
, name
, "verbose");
1978 __kmp_stg_print_bool(buffer
, name
, __kmp_storage_map
);
1980 } // __kmp_stg_print_storage_map
1982 // -----------------------------------------------------------------------------
1983 // KMP_ALL_THREADPRIVATE
1985 static void __kmp_stg_parse_all_threadprivate(char const *name
,
1986 char const *value
, void *data
) {
1987 __kmp_stg_parse_int(name
, value
,
1988 __kmp_allThreadsSpecified
? __kmp_max_nth
: 1,
1989 __kmp_max_nth
, &__kmp_tp_capacity
);
1990 } // __kmp_stg_parse_all_threadprivate
1992 static void __kmp_stg_print_all_threadprivate(kmp_str_buf_t
*buffer
,
1993 char const *name
, void *data
) {
1994 __kmp_stg_print_int(buffer
, name
, __kmp_tp_capacity
);
1997 // -----------------------------------------------------------------------------
1998 // KMP_FOREIGN_THREADS_THREADPRIVATE
2000 static void __kmp_stg_parse_foreign_threads_threadprivate(char const *name
,
2003 __kmp_stg_parse_bool(name
, value
, &__kmp_foreign_tp
);
2004 } // __kmp_stg_parse_foreign_threads_threadprivate
2006 static void __kmp_stg_print_foreign_threads_threadprivate(kmp_str_buf_t
*buffer
,
2009 __kmp_stg_print_bool(buffer
, name
, __kmp_foreign_tp
);
2010 } // __kmp_stg_print_foreign_threads_threadprivate
2012 // -----------------------------------------------------------------------------
2013 // KMP_AFFINITY, GOMP_CPU_AFFINITY, KMP_TOPOLOGY_METHOD
2015 static inline const char *
2016 __kmp_hw_get_core_type_keyword(kmp_hw_core_type_t type
) {
2018 case KMP_HW_CORE_TYPE_UNKNOWN
:
2019 case KMP_HW_MAX_NUM_CORE_TYPES
:
2021 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
2022 case KMP_HW_CORE_TYPE_ATOM
:
2023 return "intel_atom";
2024 case KMP_HW_CORE_TYPE_CORE
:
2025 return "intel_core";
2028 KMP_ASSERT2(false, "Unhandled kmp_hw_core_type_t enumeration");
2029 KMP_BUILTIN_UNREACHABLE
;
2032 #if KMP_AFFINITY_SUPPORTED
2033 // Parse the proc id list. Return TRUE if successful, FALSE otherwise.
2034 static int __kmp_parse_affinity_proc_id_list(const char *var
, const char *env
,
2035 const char **nextEnv
,
2037 const char *scan
= env
;
2038 const char *next
= scan
;
2044 int start
, end
, stride
;
2048 if (*next
== '\0') {
2058 // Read the first integer in the set.
2059 if ((*next
< '0') || (*next
> '9')) {
2060 KMP_WARNING(AffSyntaxError
, var
);
2064 num
= __kmp_str_to_int(scan
, *next
);
2065 KMP_ASSERT(num
>= 0);
2068 // Check for end of set.
2075 // Skip optional comma.
2081 // Read the next integer in the set.
2083 if ((*next
< '0') || (*next
> '9')) {
2084 KMP_WARNING(AffSyntaxError
, var
);
2089 num
= __kmp_str_to_int(scan
, *next
);
2090 KMP_ASSERT(num
>= 0);
2102 // Next character is not an integer => end of list
2103 if ((*next
< '0') || (*next
> '9')) {
2105 KMP_WARNING(AffSyntaxError
, var
);
2111 // Read the first integer.
2113 start
= __kmp_str_to_int(scan
, *next
);
2114 KMP_ASSERT(start
>= 0);
2117 // If this isn't a range, then go on.
2121 // Skip optional comma.
2129 // This is a range. Skip over the '-' and read in the 2nd int.
2133 if ((*next
< '0') || (*next
> '9')) {
2134 KMP_WARNING(AffSyntaxError
, var
);
2138 end
= __kmp_str_to_int(scan
, *next
);
2139 KMP_ASSERT(end
>= 0);
2141 // Check for a stride parameter
2145 // A stride is specified. Skip over the ':" and read the 3rd int.
2156 if ((*next
< '0') || (*next
> '9')) {
2157 KMP_WARNING(AffSyntaxError
, var
);
2161 stride
= __kmp_str_to_int(scan
, *next
);
2162 KMP_ASSERT(stride
>= 0);
2166 // Do some range checks.
2168 KMP_WARNING(AffZeroStride
, var
);
2173 KMP_WARNING(AffStartGreaterEnd
, var
, start
, end
);
2178 KMP_WARNING(AffStrideLessZero
, var
, start
, end
);
2182 if ((end
- start
) / stride
> 65536) {
2183 KMP_WARNING(AffRangeTooBig
, var
, end
, start
, stride
);
2189 // Skip optional comma.
2200 ptrdiff_t len
= next
- env
;
2201 char *retlist
= (char *)__kmp_allocate((len
+ 1) * sizeof(char));
2202 KMP_MEMCPY_S(retlist
, (len
+ 1) * sizeof(char), env
, len
* sizeof(char));
2203 retlist
[len
] = '\0';
2204 *proclist
= retlist
;
2209 // If KMP_AFFINITY is specified without a type, then
2210 // __kmp_affinity_notype should point to its setting.
2211 static kmp_setting_t
*__kmp_affinity_notype
= NULL
;
2213 static void __kmp_parse_affinity_env(char const *name
, char const *value
,
2214 kmp_affinity_t
*out_affinity
) {
2215 char *buffer
= NULL
; // Copy of env var value.
2216 char *buf
= NULL
; // Buffer for strtok_r() function.
2217 char *next
= NULL
; // end of token / start of next.
2218 const char *start
; // start of current token (for err msgs)
2219 int count
= 0; // Counter of parsed integer numbers.
2220 int number
[2]; // Parsed numbers.
2233 KMP_ASSERT(value
!= NULL
);
2235 if (TCR_4(__kmp_init_middle
)) {
2236 KMP_WARNING(EnvMiddleWarn
, name
);
2237 __kmp_env_toPrint(name
, 0);
2240 __kmp_env_toPrint(name
, 1);
2243 __kmp_str_format("%s", value
); // Copy env var to keep original intact.
2249 // If we see a parse error, emit a warning and scan to the next ",".
2251 // FIXME - there's got to be a better way to print an error
2252 // message, hopefully without overwriting peices of buf.
2253 #define EMIT_WARN(skip, errlist) \
2257 SKIP_TO(next, ','); \
2261 KMP_WARNING errlist; \
2270 #define _set_param(_guard, _var, _val) \
2272 if (_guard == 0) { \
2275 EMIT_WARN(FALSE, (AffParamDefined, name, start)); \
2280 #define set_type(val) _set_param(type, out_affinity->type, val)
2281 #define set_verbose(val) _set_param(verbose, out_affinity->flags.verbose, val)
2282 #define set_warnings(val) \
2283 _set_param(warnings, out_affinity->flags.warnings, val)
2284 #define set_respect(val) _set_param(respect, out_affinity->flags.respect, val)
2285 #define set_dups(val) _set_param(dups, out_affinity->flags.dups, val)
2286 #define set_proclist(val) _set_param(proclist, out_affinity->proclist, val)
2287 #define set_reset(val) _set_param(reset, out_affinity->flags.reset, val)
2289 #define set_gran(val, levels) \
2292 out_affinity->gran = val; \
2293 out_affinity->gran_levels = levels; \
2295 EMIT_WARN(FALSE, (AffParamDefined, name, start)); \
2300 KMP_DEBUG_ASSERT((__kmp_nested_proc_bind
.bind_types
!= NULL
) &&
2301 (__kmp_nested_proc_bind
.used
> 0));
2303 while (*buf
!= '\0') {
2306 if (__kmp_match_str("none", buf
, CCAST(const char **, &next
))) {
2307 set_type(affinity_none
);
2308 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_false
;
2310 } else if (__kmp_match_str("scatter", buf
, CCAST(const char **, &next
))) {
2311 set_type(affinity_scatter
);
2312 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_intel
;
2314 } else if (__kmp_match_str("compact", buf
, CCAST(const char **, &next
))) {
2315 set_type(affinity_compact
);
2316 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_intel
;
2318 } else if (__kmp_match_str("logical", buf
, CCAST(const char **, &next
))) {
2319 set_type(affinity_logical
);
2320 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_intel
;
2322 } else if (__kmp_match_str("physical", buf
, CCAST(const char **, &next
))) {
2323 set_type(affinity_physical
);
2324 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_intel
;
2326 } else if (__kmp_match_str("explicit", buf
, CCAST(const char **, &next
))) {
2327 set_type(affinity_explicit
);
2328 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_intel
;
2330 } else if (__kmp_match_str("balanced", buf
, CCAST(const char **, &next
))) {
2331 set_type(affinity_balanced
);
2332 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_intel
;
2334 } else if (__kmp_match_str("disabled", buf
, CCAST(const char **, &next
))) {
2335 set_type(affinity_disabled
);
2336 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_false
;
2338 } else if (__kmp_match_str("verbose", buf
, CCAST(const char **, &next
))) {
2341 } else if (__kmp_match_str("noverbose", buf
, CCAST(const char **, &next
))) {
2344 } else if (__kmp_match_str("warnings", buf
, CCAST(const char **, &next
))) {
2347 } else if (__kmp_match_str("nowarnings", buf
,
2348 CCAST(const char **, &next
))) {
2349 set_warnings(FALSE
);
2351 } else if (__kmp_match_str("respect", buf
, CCAST(const char **, &next
))) {
2354 } else if (__kmp_match_str("norespect", buf
, CCAST(const char **, &next
))) {
2357 } else if (__kmp_match_str("reset", buf
, CCAST(const char **, &next
))) {
2360 } else if (__kmp_match_str("noreset", buf
, CCAST(const char **, &next
))) {
2363 } else if (__kmp_match_str("duplicates", buf
,
2364 CCAST(const char **, &next
)) ||
2365 __kmp_match_str("dups", buf
, CCAST(const char **, &next
))) {
2368 } else if (__kmp_match_str("noduplicates", buf
,
2369 CCAST(const char **, &next
)) ||
2370 __kmp_match_str("nodups", buf
, CCAST(const char **, &next
))) {
2373 } else if (__kmp_match_str("granularity", buf
,
2374 CCAST(const char **, &next
)) ||
2375 __kmp_match_str("gran", buf
, CCAST(const char **, &next
))) {
2378 EMIT_WARN(TRUE
, (AffInvalidParam
, name
, start
));
2386 // Have to try core_type and core_efficiency matches first since "core"
2387 // will register as core granularity with "extra chars"
2388 if (__kmp_match_str("core_type", buf
, CCAST(const char **, &next
))) {
2389 set_gran(KMP_HW_CORE
, -1);
2390 out_affinity
->flags
.core_types_gran
= 1;
2393 } else if (__kmp_match_str("core_efficiency", buf
,
2394 CCAST(const char **, &next
)) ||
2395 __kmp_match_str("core_eff", buf
,
2396 CCAST(const char **, &next
))) {
2397 set_gran(KMP_HW_CORE
, -1);
2398 out_affinity
->flags
.core_effs_gran
= 1;
2403 // Try any hardware topology type for granularity
2404 KMP_FOREACH_HW_TYPE(type
) {
2405 const char *name
= __kmp_hw_get_keyword(type
);
2406 if (__kmp_match_str(name
, buf
, CCAST(const char **, &next
))) {
2415 // Support older names for different granularity layers
2416 if (__kmp_match_str("fine", buf
, CCAST(const char **, &next
))) {
2417 set_gran(KMP_HW_THREAD
, -1);
2420 } else if (__kmp_match_str("package", buf
,
2421 CCAST(const char **, &next
))) {
2422 set_gran(KMP_HW_SOCKET
, -1);
2425 } else if (__kmp_match_str("node", buf
, CCAST(const char **, &next
))) {
2426 set_gran(KMP_HW_NUMA
, -1);
2429 #if KMP_GROUP_AFFINITY
2430 } else if (__kmp_match_str("group", buf
, CCAST(const char **, &next
))) {
2431 set_gran(KMP_HW_PROC_GROUP
, -1);
2434 #endif /* KMP_GROUP AFFINITY */
2435 } else if ((*buf
>= '0') && (*buf
<= '9')) {
2439 n
= __kmp_str_to_int(buf
, *next
);
2442 set_gran(KMP_HW_UNKNOWN
, n
);
2445 EMIT_WARN(TRUE
, (AffInvalidParam
, name
, start
));
2449 } else if (__kmp_match_str("proclist", buf
, CCAST(const char **, &next
))) {
2450 char *temp_proclist
;
2454 EMIT_WARN(TRUE
, (AffInvalidParam
, name
, start
));
2460 EMIT_WARN(TRUE
, (AffInvalidParam
, name
, start
));
2465 if (!__kmp_parse_affinity_proc_id_list(
2466 name
, buf
, CCAST(const char **, &next
), &temp_proclist
)) {
2467 // warning already emitted.
2478 EMIT_WARN(TRUE
, (AffInvalidParam
, name
, start
));
2482 set_proclist(temp_proclist
);
2483 } else if ((*buf
>= '0') && (*buf
<= '9')) {
2484 // Parse integer numbers -- permute and offset.
2488 n
= __kmp_str_to_int(buf
, *next
);
2494 KMP_WARNING(AffManyParams
, name
, start
);
2498 EMIT_WARN(TRUE
, (AffInvalidParam
, name
, start
));
2506 } else if (*next
!= '\0') {
2507 const char *temp
= next
;
2508 EMIT_WARN(TRUE
, (ParseExtraCharsWarn
, name
, temp
));
2520 #undef set_granularity
2523 __kmp_str_free(&buffer
);
2527 KMP_WARNING(AffProcListNoType
, name
);
2528 out_affinity
->type
= affinity_explicit
;
2529 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_intel
;
2530 } else if (out_affinity
->type
!= affinity_explicit
) {
2531 KMP_WARNING(AffProcListNotExplicit
, name
);
2532 KMP_ASSERT(out_affinity
->proclist
!= NULL
);
2533 KMP_INTERNAL_FREE(out_affinity
->proclist
);
2534 out_affinity
->proclist
= NULL
;
2537 switch (out_affinity
->type
) {
2538 case affinity_logical
:
2539 case affinity_physical
: {
2541 out_affinity
->offset
= number
[0];
2544 KMP_WARNING(AffManyParamsForLogic
, name
, number
[1]);
2547 case affinity_balanced
: {
2549 out_affinity
->compact
= number
[0];
2552 out_affinity
->offset
= number
[1];
2555 if (__kmp_affinity
.gran
== KMP_HW_UNKNOWN
) {
2556 int verbose
= out_affinity
->flags
.verbose
;
2557 int warnings
= out_affinity
->flags
.warnings
;
2558 #if KMP_MIC_SUPPORTED
2559 if (__kmp_mic_type
!= non_mic
) {
2560 if (verbose
|| warnings
) {
2561 KMP_WARNING(AffGranUsing
, out_affinity
->env_var
, "fine");
2563 out_affinity
->gran
= KMP_HW_THREAD
;
2567 if (verbose
|| warnings
) {
2568 KMP_WARNING(AffGranUsing
, out_affinity
->env_var
, "core");
2570 out_affinity
->gran
= KMP_HW_CORE
;
2574 case affinity_scatter
:
2575 case affinity_compact
: {
2577 out_affinity
->compact
= number
[0];
2580 out_affinity
->offset
= number
[1];
2583 case affinity_explicit
: {
2584 if (out_affinity
->proclist
== NULL
) {
2585 KMP_WARNING(AffNoProcList
, name
);
2586 out_affinity
->type
= affinity_none
;
2589 KMP_WARNING(AffNoParam
, name
, "explicit");
2592 case affinity_none
: {
2594 KMP_WARNING(AffNoParam
, name
, "none");
2597 case affinity_disabled
: {
2599 KMP_WARNING(AffNoParam
, name
, "disabled");
2602 case affinity_default
: {
2604 KMP_WARNING(AffNoParam
, name
, "default");
2611 } // __kmp_parse_affinity_env
2613 static void __kmp_stg_parse_affinity(char const *name
, char const *value
,
2615 kmp_setting_t
**rivals
= (kmp_setting_t
**)data
;
2618 rc
= __kmp_stg_check_rivals(name
, value
, rivals
);
2623 __kmp_parse_affinity_env(name
, value
, &__kmp_affinity
);
2625 } // __kmp_stg_parse_affinity
2626 static void __kmp_stg_parse_hh_affinity(char const *name
, char const *value
,
2628 __kmp_parse_affinity_env(name
, value
, &__kmp_hh_affinity
);
2629 // Warn about unused parts of hidden helper affinity settings if specified.
2630 if (__kmp_hh_affinity
.flags
.reset
) {
2631 KMP_WARNING(AffInvalidParam
, name
, "reset");
2633 if (__kmp_hh_affinity
.flags
.respect
!= affinity_respect_mask_default
) {
2634 KMP_WARNING(AffInvalidParam
, name
, "respect");
2638 static void __kmp_print_affinity_env(kmp_str_buf_t
*buffer
, char const *name
,
2639 const kmp_affinity_t
&affinity
) {
2640 bool is_hh_affinity
= (&affinity
== &__kmp_hh_affinity
);
2641 if (__kmp_env_format
) {
2642 KMP_STR_BUF_PRINT_NAME_EX(name
);
2644 __kmp_str_buf_print(buffer
, " %s='", name
);
2646 if (affinity
.flags
.verbose
) {
2647 __kmp_str_buf_print(buffer
, "%s,", "verbose");
2649 __kmp_str_buf_print(buffer
, "%s,", "noverbose");
2651 if (affinity
.flags
.warnings
) {
2652 __kmp_str_buf_print(buffer
, "%s,", "warnings");
2654 __kmp_str_buf_print(buffer
, "%s,", "nowarnings");
2656 if (KMP_AFFINITY_CAPABLE()) {
2657 // Hidden helper affinity does not affect global reset
2658 // or respect flags. That is still solely controlled by KMP_AFFINITY.
2659 if (!is_hh_affinity
) {
2660 if (affinity
.flags
.respect
) {
2661 __kmp_str_buf_print(buffer
, "%s,", "respect");
2663 __kmp_str_buf_print(buffer
, "%s,", "norespect");
2665 if (affinity
.flags
.reset
) {
2666 __kmp_str_buf_print(buffer
, "%s,", "reset");
2668 __kmp_str_buf_print(buffer
, "%s,", "noreset");
2671 __kmp_str_buf_print(buffer
, "granularity=");
2672 if (affinity
.flags
.core_types_gran
)
2673 __kmp_str_buf_print(buffer
, "core_type,");
2674 else if (affinity
.flags
.core_effs_gran
) {
2675 __kmp_str_buf_print(buffer
, "core_eff,");
2677 __kmp_str_buf_print(
2678 buffer
, "%s,", __kmp_hw_get_keyword(affinity
.gran
, /*plural=*/false));
2681 if (!KMP_AFFINITY_CAPABLE()) {
2682 __kmp_str_buf_print(buffer
, "%s", "disabled");
2684 int compact
= affinity
.compact
;
2685 int offset
= affinity
.offset
;
2686 switch (affinity
.type
) {
2688 __kmp_str_buf_print(buffer
, "%s", "none");
2690 case affinity_physical
:
2691 __kmp_str_buf_print(buffer
, "%s,%d", "physical", offset
);
2693 case affinity_logical
:
2694 __kmp_str_buf_print(buffer
, "%s,%d", "logical", offset
);
2696 case affinity_compact
:
2697 __kmp_str_buf_print(buffer
, "%s,%d,%d", "compact", compact
, offset
);
2699 case affinity_scatter
:
2700 __kmp_str_buf_print(buffer
, "%s,%d,%d", "scatter", compact
, offset
);
2702 case affinity_explicit
:
2703 __kmp_str_buf_print(buffer
, "%s=[%s],%s", "proclist", affinity
.proclist
,
2706 case affinity_balanced
:
2707 __kmp_str_buf_print(buffer
, "%s,%d,%d", "balanced", compact
, offset
);
2709 case affinity_disabled
:
2710 __kmp_str_buf_print(buffer
, "%s", "disabled");
2712 case affinity_default
:
2713 __kmp_str_buf_print(buffer
, "%s", "default");
2716 __kmp_str_buf_print(buffer
, "%s", "<unknown>");
2720 __kmp_str_buf_print(buffer
, "'\n");
2721 } //__kmp_stg_print_affinity
2723 static void __kmp_stg_print_affinity(kmp_str_buf_t
*buffer
, char const *name
,
2725 __kmp_print_affinity_env(buffer
, name
, __kmp_affinity
);
2727 static void __kmp_stg_print_hh_affinity(kmp_str_buf_t
*buffer
, char const *name
,
2729 __kmp_print_affinity_env(buffer
, name
, __kmp_hh_affinity
);
2732 #ifdef KMP_GOMP_COMPAT
2734 static void __kmp_stg_parse_gomp_cpu_affinity(char const *name
,
2735 char const *value
, void *data
) {
2736 const char *next
= NULL
;
2737 char *temp_proclist
;
2738 kmp_setting_t
**rivals
= (kmp_setting_t
**)data
;
2741 rc
= __kmp_stg_check_rivals(name
, value
, rivals
);
2746 if (TCR_4(__kmp_init_middle
)) {
2747 KMP_WARNING(EnvMiddleWarn
, name
);
2748 __kmp_env_toPrint(name
, 0);
2752 __kmp_env_toPrint(name
, 1);
2754 if (__kmp_parse_affinity_proc_id_list(name
, value
, &next
, &temp_proclist
)) {
2756 if (*next
== '\0') {
2757 // GOMP_CPU_AFFINITY => granularity=fine,explicit,proclist=...
2758 __kmp_affinity
.proclist
= temp_proclist
;
2759 __kmp_affinity
.type
= affinity_explicit
;
2760 __kmp_affinity
.gran
= KMP_HW_THREAD
;
2761 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_intel
;
2763 KMP_WARNING(AffSyntaxError
, name
);
2764 if (temp_proclist
!= NULL
) {
2765 KMP_INTERNAL_FREE((void *)temp_proclist
);
2769 // Warning already emitted
2770 __kmp_affinity
.type
= affinity_none
;
2771 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_false
;
2773 } // __kmp_stg_parse_gomp_cpu_affinity
2775 #endif /* KMP_GOMP_COMPAT */
2777 /*-----------------------------------------------------------------------------
2778 The OMP_PLACES proc id list parser. Here is the grammar:
2781 place_list := place , place_list
2783 place := place : num
2784 place := place : num : signed
2785 place := { subplacelist }
2786 place := ! place // (lowest priority)
2787 subplace_list := subplace
2788 subplace_list := subplace , subplace_list
2790 subplace := num : num
2791 subplace := num : num : signed
2795 -----------------------------------------------------------------------------*/
2797 // Return TRUE if successful parse, FALSE otherwise
2798 static int __kmp_parse_subplace_list(const char *var
, const char **scan
) {
2802 int start
, count
, stride
;
2805 // Read in the starting proc id
2808 if ((**scan
< '0') || (**scan
> '9')) {
2813 start
= __kmp_str_to_int(*scan
, *next
);
2814 KMP_ASSERT(start
>= 0);
2817 // valid follow sets are ',' ':' and '}'
2819 if (**scan
== '}') {
2822 if (**scan
== ',') {
2823 (*scan
)++; // skip ','
2826 if (**scan
!= ':') {
2829 (*scan
)++; // skip ':'
2831 // Read count parameter
2833 if ((**scan
< '0') || (**scan
> '9')) {
2838 count
= __kmp_str_to_int(*scan
, *next
);
2839 KMP_ASSERT(count
>= 0);
2842 // valid follow sets are ',' ':' and '}'
2844 if (**scan
== '}') {
2847 if (**scan
== ',') {
2848 (*scan
)++; // skip ','
2851 if (**scan
!= ':') {
2854 (*scan
)++; // skip ':'
2856 // Read stride parameter
2860 if (**scan
== '+') {
2861 (*scan
)++; // skip '+'
2864 if (**scan
== '-') {
2866 (*scan
)++; // skip '-'
2872 if ((**scan
< '0') || (**scan
> '9')) {
2877 stride
= __kmp_str_to_int(*scan
, *next
);
2878 KMP_ASSERT(stride
>= 0);
2882 // valid follow sets are ',' and '}'
2884 if (**scan
== '}') {
2887 if (**scan
== ',') {
2888 (*scan
)++; // skip ','
2896 // Return TRUE if successful parse, FALSE otherwise
2897 static int __kmp_parse_place(const char *var
, const char **scan
) {
2900 // valid follow sets are '{' '!' and num
2902 if (**scan
== '{') {
2903 (*scan
)++; // skip '{'
2904 if (!__kmp_parse_subplace_list(var
, scan
)) {
2907 if (**scan
!= '}') {
2910 (*scan
)++; // skip '}'
2911 } else if (**scan
== '!') {
2912 (*scan
)++; // skip '!'
2913 return __kmp_parse_place(var
, scan
); //'!' has lower precedence than ':'
2914 } else if ((**scan
>= '0') && (**scan
<= '9')) {
2917 int proc
= __kmp_str_to_int(*scan
, *next
);
2918 KMP_ASSERT(proc
>= 0);
2926 // Return TRUE if successful parse, FALSE otherwise
2927 static int __kmp_parse_place_list(const char *var
, const char *env
,
2928 char **place_list
) {
2929 const char *scan
= env
;
2930 const char *next
= scan
;
2935 if (!__kmp_parse_place(var
, &scan
)) {
2939 // valid follow sets are ',' ':' and EOL
2941 if (*scan
== '\0') {
2953 // Read count parameter
2955 if ((*scan
< '0') || (*scan
> '9')) {
2960 count
= __kmp_str_to_int(scan
, *next
);
2961 KMP_ASSERT(count
>= 0);
2964 // valid follow sets are ',' ':' and EOL
2966 if (*scan
== '\0') {
2978 // Read stride parameter
2994 if ((*scan
< '0') || (*scan
> '9')) {
2999 stride
= __kmp_str_to_int(scan
, *next
);
3000 KMP_ASSERT(stride
>= 0);
3004 // valid follow sets are ',' and EOL
3006 if (*scan
== '\0') {
3018 ptrdiff_t len
= scan
- env
;
3019 char *retlist
= (char *)__kmp_allocate((len
+ 1) * sizeof(char));
3020 KMP_MEMCPY_S(retlist
, (len
+ 1) * sizeof(char), env
, len
* sizeof(char));
3021 retlist
[len
] = '\0';
3022 *place_list
= retlist
;
3027 static inline void __kmp_places_set(enum affinity_type type
, kmp_hw_t kind
) {
3028 __kmp_affinity
.type
= type
;
3029 __kmp_affinity
.gran
= kind
;
3030 __kmp_affinity
.flags
.dups
= FALSE
;
3031 __kmp_affinity
.flags
.omp_places
= TRUE
;
3034 static void __kmp_places_syntax_error_fallback(char const *name
,
3036 const char *str
= __kmp_hw_get_catalog_string(kind
, /*plural=*/true);
3037 KMP_WARNING(SyntaxErrorUsing
, name
, str
);
3038 __kmp_places_set(affinity_compact
, kind
);
3039 if (__kmp_nested_proc_bind
.bind_types
[0] == proc_bind_default
)
3040 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_true
;
3043 static void __kmp_stg_parse_places(char const *name
, char const *value
,
3045 struct kmp_place_t
{
3051 const char *scan
= value
;
3052 const char *next
= scan
;
3053 kmp_place_t std_places
[] = {{"threads", KMP_HW_THREAD
},
3054 {"cores", KMP_HW_CORE
},
3055 {"numa_domains", KMP_HW_NUMA
},
3056 {"ll_caches", KMP_HW_LLC
},
3057 {"sockets", KMP_HW_SOCKET
}};
3058 kmp_setting_t
**rivals
= (kmp_setting_t
**)data
;
3061 rc
= __kmp_stg_check_rivals(name
, value
, rivals
);
3067 for (size_t i
= 0; i
< sizeof(std_places
) / sizeof(std_places
[0]); ++i
) {
3068 const kmp_place_t
&place
= std_places
[i
];
3069 if (__kmp_match_str(place
.name
, scan
, &next
)) {
3071 __kmp_places_set(affinity_compact
, place
.type
);
3073 // Parse core attribute if it exists
3074 if (KMP_HW_MAX_NUM_CORE_TYPES
> 1) {
3077 if (place
.type
!= KMP_HW_CORE
) {
3078 __kmp_places_syntax_error_fallback(name
, place
.type
);
3083 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
3084 if (__kmp_match_str("intel_core", scan
, &next
)) {
3085 __kmp_affinity
.core_attr_gran
.core_type
= KMP_HW_CORE_TYPE_CORE
;
3086 __kmp_affinity
.core_attr_gran
.valid
= 1;
3088 } else if (__kmp_match_str("intel_atom", scan
, &next
)) {
3089 __kmp_affinity
.core_attr_gran
.core_type
= KMP_HW_CORE_TYPE_ATOM
;
3090 __kmp_affinity
.core_attr_gran
.valid
= 1;
3094 if (__kmp_match_str("eff", scan
, &next
)) {
3096 if (!isdigit(*next
)) {
3097 __kmp_places_syntax_error_fallback(name
, place
.type
);
3102 eff
= __kmp_str_to_int(scan
, *next
);
3104 __kmp_places_syntax_error_fallback(name
, place
.type
);
3107 if (eff
>= KMP_HW_MAX_NUM_CORE_EFFS
)
3108 eff
= KMP_HW_MAX_NUM_CORE_EFFS
- 1;
3109 __kmp_affinity
.core_attr_gran
.core_eff
= eff
;
3110 __kmp_affinity
.core_attr_gran
.valid
= 1;
3113 if (!__kmp_affinity
.core_attr_gran
.valid
) {
3114 __kmp_places_syntax_error_fallback(name
, place
.type
);
3122 // Implementation choices for OMP_PLACES based on internal types
3124 KMP_FOREACH_HW_TYPE(type
) {
3125 const char *name
= __kmp_hw_get_keyword(type
, true);
3126 if (__kmp_match_str("unknowns", scan
, &next
))
3128 if (__kmp_match_str(name
, scan
, &next
)) {
3130 __kmp_places_set(affinity_compact
, type
);
3136 // Implementation choices for OMP_PLACES based on core attributes
3138 if (__kmp_match_str("core_types", scan
, &next
)) {
3140 if (*scan
!= '\0') {
3141 KMP_WARNING(ParseExtraCharsWarn
, name
, scan
);
3143 __kmp_places_set(affinity_compact
, KMP_HW_CORE
);
3144 __kmp_affinity
.flags
.core_types_gran
= 1;
3146 } else if (__kmp_match_str("core_effs", scan
, &next
) ||
3147 __kmp_match_str("core_efficiencies", scan
, &next
)) {
3149 if (*scan
!= '\0') {
3150 KMP_WARNING(ParseExtraCharsWarn
, name
, scan
);
3152 __kmp_places_set(affinity_compact
, KMP_HW_CORE
);
3153 __kmp_affinity
.flags
.core_effs_gran
= 1;
3157 // Explicit place list
3159 if (__kmp_affinity
.proclist
!= NULL
) {
3160 KMP_INTERNAL_FREE((void *)__kmp_affinity
.proclist
);
3161 __kmp_affinity
.proclist
= NULL
;
3163 if (__kmp_parse_place_list(name
, value
, &__kmp_affinity
.proclist
)) {
3164 __kmp_places_set(affinity_explicit
, KMP_HW_THREAD
);
3166 // Syntax error fallback
3167 __kmp_places_syntax_error_fallback(name
, KMP_HW_CORE
);
3169 if (__kmp_nested_proc_bind
.bind_types
[0] == proc_bind_default
) {
3170 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_true
;
3175 kmp_hw_t gran
= __kmp_affinity
.gran
;
3176 if (__kmp_affinity
.gran
!= KMP_HW_UNKNOWN
) {
3177 gran
= __kmp_affinity
.gran
;
3182 if (__kmp_nested_proc_bind
.bind_types
[0] == proc_bind_default
) {
3183 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_true
;
3187 if (*scan
== '\0') {
3191 // Parse option count parameter in parentheses
3193 __kmp_places_syntax_error_fallback(name
, gran
);
3201 count
= __kmp_str_to_int(scan
, *next
);
3202 KMP_ASSERT(count
>= 0);
3207 __kmp_places_syntax_error_fallback(name
, gran
);
3213 if (*scan
!= '\0') {
3214 KMP_WARNING(ParseExtraCharsWarn
, name
, scan
);
3216 __kmp_affinity_num_places
= count
;
3219 static void __kmp_stg_print_places(kmp_str_buf_t
*buffer
, char const *name
,
3221 enum affinity_type type
= __kmp_affinity
.type
;
3222 const char *proclist
= __kmp_affinity
.proclist
;
3223 kmp_hw_t gran
= __kmp_affinity
.gran
;
3225 if (__kmp_env_format
) {
3226 KMP_STR_BUF_PRINT_NAME
;
3228 __kmp_str_buf_print(buffer
, " %s", name
);
3230 if ((__kmp_nested_proc_bind
.used
== 0) ||
3231 (__kmp_nested_proc_bind
.bind_types
== NULL
) ||
3232 (__kmp_nested_proc_bind
.bind_types
[0] == proc_bind_false
)) {
3233 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
3234 } else if (type
== affinity_explicit
) {
3235 if (proclist
!= NULL
) {
3236 __kmp_str_buf_print(buffer
, "='%s'\n", proclist
);
3238 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
3240 } else if (type
== affinity_compact
) {
3242 if (__kmp_affinity
.num_masks
> 0) {
3243 num
= __kmp_affinity
.num_masks
;
3244 } else if (__kmp_affinity_num_places
> 0) {
3245 num
= __kmp_affinity_num_places
;
3249 if (gran
!= KMP_HW_UNKNOWN
) {
3250 // If core_types or core_effs, just print and return
3251 if (__kmp_affinity
.flags
.core_types_gran
) {
3252 __kmp_str_buf_print(buffer
, "='%s'\n", "core_types");
3255 if (__kmp_affinity
.flags
.core_effs_gran
) {
3256 __kmp_str_buf_print(buffer
, "='%s'\n", "core_effs");
3260 // threads, cores, sockets, cores:<attribute>, etc.
3261 const char *name
= __kmp_hw_get_keyword(gran
, true);
3262 __kmp_str_buf_print(buffer
, "='%s", name
);
3264 // Add core attributes if it exists
3265 if (__kmp_affinity
.core_attr_gran
.valid
) {
3266 kmp_hw_core_type_t ct
=
3267 (kmp_hw_core_type_t
)__kmp_affinity
.core_attr_gran
.core_type
;
3268 int eff
= __kmp_affinity
.core_attr_gran
.core_eff
;
3269 if (ct
!= KMP_HW_CORE_TYPE_UNKNOWN
) {
3270 const char *ct_name
= __kmp_hw_get_core_type_keyword(ct
);
3271 __kmp_str_buf_print(buffer
, ":%s", name
, ct_name
);
3272 } else if (eff
>= 0 && eff
< KMP_HW_MAX_NUM_CORE_EFFS
) {
3273 __kmp_str_buf_print(buffer
, ":eff%d", name
, eff
);
3277 // Add the '(#)' part if it exists
3279 __kmp_str_buf_print(buffer
, "(%d)", num
);
3280 __kmp_str_buf_print(buffer
, "'\n");
3282 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
3285 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
3289 static void __kmp_stg_parse_topology_method(char const *name
, char const *value
,
3291 if (__kmp_str_match("all", 1, value
)) {
3292 __kmp_affinity_top_method
= affinity_top_method_all
;
3295 else if (__kmp_str_match("hwloc", 1, value
)) {
3296 __kmp_affinity_top_method
= affinity_top_method_hwloc
;
3299 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
3300 else if (__kmp_str_match("cpuid_leaf31", 12, value
) ||
3301 __kmp_str_match("cpuid 1f", 8, value
) ||
3302 __kmp_str_match("cpuid 31", 8, value
) ||
3303 __kmp_str_match("cpuid1f", 7, value
) ||
3304 __kmp_str_match("cpuid31", 7, value
) ||
3305 __kmp_str_match("leaf 1f", 7, value
) ||
3306 __kmp_str_match("leaf 31", 7, value
) ||
3307 __kmp_str_match("leaf1f", 6, value
) ||
3308 __kmp_str_match("leaf31", 6, value
)) {
3309 __kmp_affinity_top_method
= affinity_top_method_x2apicid_1f
;
3310 } else if (__kmp_str_match("x2apic id", 9, value
) ||
3311 __kmp_str_match("x2apic_id", 9, value
) ||
3312 __kmp_str_match("x2apic-id", 9, value
) ||
3313 __kmp_str_match("x2apicid", 8, value
) ||
3314 __kmp_str_match("cpuid leaf 11", 13, value
) ||
3315 __kmp_str_match("cpuid_leaf_11", 13, value
) ||
3316 __kmp_str_match("cpuid-leaf-11", 13, value
) ||
3317 __kmp_str_match("cpuid leaf11", 12, value
) ||
3318 __kmp_str_match("cpuid_leaf11", 12, value
) ||
3319 __kmp_str_match("cpuid-leaf11", 12, value
) ||
3320 __kmp_str_match("cpuidleaf 11", 12, value
) ||
3321 __kmp_str_match("cpuidleaf_11", 12, value
) ||
3322 __kmp_str_match("cpuidleaf-11", 12, value
) ||
3323 __kmp_str_match("cpuidleaf11", 11, value
) ||
3324 __kmp_str_match("cpuid 11", 8, value
) ||
3325 __kmp_str_match("cpuid_11", 8, value
) ||
3326 __kmp_str_match("cpuid-11", 8, value
) ||
3327 __kmp_str_match("cpuid11", 7, value
) ||
3328 __kmp_str_match("leaf 11", 7, value
) ||
3329 __kmp_str_match("leaf_11", 7, value
) ||
3330 __kmp_str_match("leaf-11", 7, value
) ||
3331 __kmp_str_match("leaf11", 6, value
)) {
3332 __kmp_affinity_top_method
= affinity_top_method_x2apicid
;
3333 } else if (__kmp_str_match("apic id", 7, value
) ||
3334 __kmp_str_match("apic_id", 7, value
) ||
3335 __kmp_str_match("apic-id", 7, value
) ||
3336 __kmp_str_match("apicid", 6, value
) ||
3337 __kmp_str_match("cpuid leaf 4", 12, value
) ||
3338 __kmp_str_match("cpuid_leaf_4", 12, value
) ||
3339 __kmp_str_match("cpuid-leaf-4", 12, value
) ||
3340 __kmp_str_match("cpuid leaf4", 11, value
) ||
3341 __kmp_str_match("cpuid_leaf4", 11, value
) ||
3342 __kmp_str_match("cpuid-leaf4", 11, value
) ||
3343 __kmp_str_match("cpuidleaf 4", 11, value
) ||
3344 __kmp_str_match("cpuidleaf_4", 11, value
) ||
3345 __kmp_str_match("cpuidleaf-4", 11, value
) ||
3346 __kmp_str_match("cpuidleaf4", 10, value
) ||
3347 __kmp_str_match("cpuid 4", 7, value
) ||
3348 __kmp_str_match("cpuid_4", 7, value
) ||
3349 __kmp_str_match("cpuid-4", 7, value
) ||
3350 __kmp_str_match("cpuid4", 6, value
) ||
3351 __kmp_str_match("leaf 4", 6, value
) ||
3352 __kmp_str_match("leaf_4", 6, value
) ||
3353 __kmp_str_match("leaf-4", 6, value
) ||
3354 __kmp_str_match("leaf4", 5, value
)) {
3355 __kmp_affinity_top_method
= affinity_top_method_apicid
;
3357 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
3358 else if (__kmp_str_match("/proc/cpuinfo", 2, value
) ||
3359 __kmp_str_match("cpuinfo", 5, value
)) {
3360 __kmp_affinity_top_method
= affinity_top_method_cpuinfo
;
3362 #if KMP_GROUP_AFFINITY
3363 else if (__kmp_str_match("group", 1, value
)) {
3364 KMP_WARNING(StgDeprecatedValue
, name
, value
, "all");
3365 __kmp_affinity_top_method
= affinity_top_method_group
;
3367 #endif /* KMP_GROUP_AFFINITY */
3368 else if (__kmp_str_match("flat", 1, value
)) {
3369 __kmp_affinity_top_method
= affinity_top_method_flat
;
3371 KMP_WARNING(StgInvalidValue
, name
, value
);
3373 } // __kmp_stg_parse_topology_method
3375 static void __kmp_stg_print_topology_method(kmp_str_buf_t
*buffer
,
3376 char const *name
, void *data
) {
3377 char const *value
= NULL
;
3379 switch (__kmp_affinity_top_method
) {
3380 case affinity_top_method_default
:
3384 case affinity_top_method_all
:
3388 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
3389 case affinity_top_method_x2apicid_1f
:
3390 value
= "x2APIC id leaf 0x1f";
3393 case affinity_top_method_x2apicid
:
3394 value
= "x2APIC id leaf 0xb";
3397 case affinity_top_method_apicid
:
3400 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
3403 case affinity_top_method_hwloc
:
3408 case affinity_top_method_cpuinfo
:
3412 #if KMP_GROUP_AFFINITY
3413 case affinity_top_method_group
:
3416 #endif /* KMP_GROUP_AFFINITY */
3418 case affinity_top_method_flat
:
3423 if (value
!= NULL
) {
3424 __kmp_stg_print_str(buffer
, name
, value
);
3426 } // __kmp_stg_print_topology_method
3428 // KMP_TEAMS_PROC_BIND
3429 struct kmp_proc_bind_info_t
{
3431 kmp_proc_bind_t proc_bind
;
3433 static kmp_proc_bind_info_t proc_bind_table
[] = {
3434 {"spread", proc_bind_spread
},
3435 {"true", proc_bind_spread
},
3436 {"close", proc_bind_close
},
3437 // teams-bind = false means "replicate the primary thread's affinity"
3438 {"false", proc_bind_primary
},
3439 {"primary", proc_bind_primary
}};
3440 static void __kmp_stg_parse_teams_proc_bind(char const *name
, char const *value
,
3445 for (size_t i
= 0; i
< sizeof(proc_bind_table
) / sizeof(proc_bind_table
[0]);
3447 if (__kmp_match_str(proc_bind_table
[i
].name
, value
, &end
)) {
3448 __kmp_teams_proc_bind
= proc_bind_table
[i
].proc_bind
;
3454 KMP_WARNING(StgInvalidValue
, name
, value
);
3457 static void __kmp_stg_print_teams_proc_bind(kmp_str_buf_t
*buffer
,
3458 char const *name
, void *data
) {
3459 const char *value
= KMP_I18N_STR(NotDefined
);
3460 for (size_t i
= 0; i
< sizeof(proc_bind_table
) / sizeof(proc_bind_table
[0]);
3462 if (__kmp_teams_proc_bind
== proc_bind_table
[i
].proc_bind
) {
3463 value
= proc_bind_table
[i
].name
;
3467 __kmp_stg_print_str(buffer
, name
, value
);
3469 #endif /* KMP_AFFINITY_SUPPORTED */
3471 // OMP_PROC_BIND / bind-var is functional on all 4.0 builds, including OS X*
3472 // OMP_PLACES / place-partition-var is not.
3473 static void __kmp_stg_parse_proc_bind(char const *name
, char const *value
,
3475 kmp_setting_t
**rivals
= (kmp_setting_t
**)data
;
3478 rc
= __kmp_stg_check_rivals(name
, value
, rivals
);
3483 // In OMP 4.0 OMP_PROC_BIND is a vector of proc_bind types.
3484 KMP_DEBUG_ASSERT((__kmp_nested_proc_bind
.bind_types
!= NULL
) &&
3485 (__kmp_nested_proc_bind
.used
> 0));
3487 const char *buf
= value
;
3491 if ((*buf
>= '0') && (*buf
<= '9')) {
3494 num
= __kmp_str_to_int(buf
, *next
);
3495 KMP_ASSERT(num
>= 0);
3503 if (__kmp_match_str("disabled", buf
, &next
)) {
3506 #if KMP_AFFINITY_SUPPORTED
3507 __kmp_affinity
.type
= affinity_disabled
;
3508 #endif /* KMP_AFFINITY_SUPPORTED */
3509 __kmp_nested_proc_bind
.used
= 1;
3510 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_false
;
3511 } else if ((num
== (int)proc_bind_false
) ||
3512 __kmp_match_str("false", buf
, &next
)) {
3515 #if KMP_AFFINITY_SUPPORTED
3516 __kmp_affinity
.type
= affinity_none
;
3517 #endif /* KMP_AFFINITY_SUPPORTED */
3518 __kmp_nested_proc_bind
.used
= 1;
3519 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_false
;
3520 } else if ((num
== (int)proc_bind_true
) ||
3521 __kmp_match_str("true", buf
, &next
)) {
3524 __kmp_nested_proc_bind
.used
= 1;
3525 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_true
;
3527 // Count the number of values in the env var string
3530 for (scan
= buf
; *scan
!= '\0'; scan
++) {
3536 // Create / expand the nested proc_bind array as needed
3537 if (__kmp_nested_proc_bind
.size
< nelem
) {
3538 __kmp_nested_proc_bind
.bind_types
=
3539 (kmp_proc_bind_t
*)KMP_INTERNAL_REALLOC(
3540 __kmp_nested_proc_bind
.bind_types
,
3541 sizeof(kmp_proc_bind_t
) * nelem
);
3542 if (__kmp_nested_proc_bind
.bind_types
== NULL
) {
3543 KMP_FATAL(MemoryAllocFailed
);
3545 __kmp_nested_proc_bind
.size
= nelem
;
3547 __kmp_nested_proc_bind
.used
= nelem
;
3549 if (nelem
> 1 && !__kmp_dflt_max_active_levels_set
)
3550 __kmp_dflt_max_active_levels
= KMP_MAX_ACTIVE_LEVELS_LIMIT
;
3552 // Save values in the nested proc_bind array
3555 enum kmp_proc_bind_t bind
;
3557 if ((num
== (int)proc_bind_primary
) ||
3558 __kmp_match_str("master", buf
, &next
) ||
3559 __kmp_match_str("primary", buf
, &next
)) {
3562 bind
= proc_bind_primary
;
3563 } else if ((num
== (int)proc_bind_close
) ||
3564 __kmp_match_str("close", buf
, &next
)) {
3567 bind
= proc_bind_close
;
3568 } else if ((num
== (int)proc_bind_spread
) ||
3569 __kmp_match_str("spread", buf
, &next
)) {
3572 bind
= proc_bind_spread
;
3574 KMP_WARNING(StgInvalidValue
, name
, value
);
3575 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_false
;
3576 __kmp_nested_proc_bind
.used
= 1;
3580 __kmp_nested_proc_bind
.bind_types
[i
++] = bind
;
3584 KMP_DEBUG_ASSERT(*buf
== ',');
3588 // Read next value if it was specified as an integer
3589 if ((*buf
>= '0') && (*buf
<= '9')) {
3592 num
= __kmp_str_to_int(buf
, *next
);
3593 KMP_ASSERT(num
>= 0);
3603 KMP_WARNING(ParseExtraCharsWarn
, name
, buf
);
3607 static void __kmp_stg_print_proc_bind(kmp_str_buf_t
*buffer
, char const *name
,
3609 int nelem
= __kmp_nested_proc_bind
.used
;
3610 if (__kmp_env_format
) {
3611 KMP_STR_BUF_PRINT_NAME
;
3613 __kmp_str_buf_print(buffer
, " %s", name
);
3616 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
3619 __kmp_str_buf_print(buffer
, "='", name
);
3620 for (i
= 0; i
< nelem
; i
++) {
3621 switch (__kmp_nested_proc_bind
.bind_types
[i
]) {
3622 case proc_bind_false
:
3623 __kmp_str_buf_print(buffer
, "false");
3626 case proc_bind_true
:
3627 __kmp_str_buf_print(buffer
, "true");
3630 case proc_bind_primary
:
3631 __kmp_str_buf_print(buffer
, "primary");
3634 case proc_bind_close
:
3635 __kmp_str_buf_print(buffer
, "close");
3638 case proc_bind_spread
:
3639 __kmp_str_buf_print(buffer
, "spread");
3642 case proc_bind_intel
:
3643 __kmp_str_buf_print(buffer
, "intel");
3646 case proc_bind_default
:
3647 __kmp_str_buf_print(buffer
, "default");
3650 if (i
< nelem
- 1) {
3651 __kmp_str_buf_print(buffer
, ",");
3654 __kmp_str_buf_print(buffer
, "'\n");
3658 static void __kmp_stg_parse_display_affinity(char const *name
,
3659 char const *value
, void *data
) {
3660 __kmp_stg_parse_bool(name
, value
, &__kmp_display_affinity
);
3662 static void __kmp_stg_print_display_affinity(kmp_str_buf_t
*buffer
,
3663 char const *name
, void *data
) {
3664 __kmp_stg_print_bool(buffer
, name
, __kmp_display_affinity
);
3666 static void __kmp_stg_parse_affinity_format(char const *name
, char const *value
,
3668 size_t length
= KMP_STRLEN(value
);
3669 __kmp_strncpy_truncate(__kmp_affinity_format
, KMP_AFFINITY_FORMAT_SIZE
, value
,
3672 static void __kmp_stg_print_affinity_format(kmp_str_buf_t
*buffer
,
3673 char const *name
, void *data
) {
3674 if (__kmp_env_format
) {
3675 KMP_STR_BUF_PRINT_NAME_EX(name
);
3677 __kmp_str_buf_print(buffer
, " %s='", name
);
3679 __kmp_str_buf_print(buffer
, "%s'\n", __kmp_affinity_format
);
3682 /*-----------------------------------------------------------------------------
3683 OMP_ALLOCATOR sets default allocator. Here is the grammar:
3685 <allocator> |= <predef-allocator> | <predef-mem-space> |
3686 <predef-mem-space>:<traits>
3687 <traits> |= <trait>=<value> | <trait>=<value>,<traits>
3688 <predef-allocator> |= omp_default_mem_alloc | omp_large_cap_mem_alloc |
3689 omp_const_mem_alloc | omp_high_bw_mem_alloc |
3690 omp_low_lat_mem_alloc | omp_cgroup_mem_alloc |
3691 omp_pteam_mem_alloc | omp_thread_mem_alloc
3692 <predef-mem-space> |= omp_default_mem_space | omp_large_cap_mem_space |
3693 omp_const_mem_space | omp_high_bw_mem_space |
3694 omp_low_lat_mem_space
3695 <trait> |= sync_hint | alignment | access | pool_size | fallback |
3696 fb_data | pinned | partition
3697 <value> |= one of the allowed values of trait |
3698 non-negative integer | <predef-allocator>
3699 -----------------------------------------------------------------------------*/
3701 static void __kmp_stg_parse_allocator(char const *name
, char const *value
,
3703 const char *buf
= value
;
3704 const char *next
, *scan
, *start
;
3706 omp_allocator_handle_t al
;
3707 omp_memspace_handle_t ms
= omp_default_mem_space
;
3708 bool is_memspace
= false;
3709 int ntraits
= 0, count
= 0;
3713 const char *delim
= strchr(buf
, ':');
3714 const char *predef_mem_space
= strstr(buf
, "mem_space");
3716 bool is_memalloc
= (!predef_mem_space
&& !delim
) ? true : false;
3718 // Count the number of traits in the env var string
3721 for (scan
= buf
; *scan
!= '\0'; scan
++) {
3726 omp_alloctrait_t
*traits
=
3727 (omp_alloctrait_t
*)KMP_ALLOCA(ntraits
* sizeof(omp_alloctrait_t
));
3730 #define IS_POWER_OF_TWO(n) (((n) & ((n)-1)) == 0)
3732 #define GET_NEXT(sentinel) \
3735 if (*next == sentinel) \
3741 #define SKIP_PAIR(key) \
3743 char const str_delimiter[] = {',', 0}; \
3744 char *value = __kmp_str_token(CCAST(char *, scan), str_delimiter, \
3745 CCAST(char **, &next)); \
3746 KMP_WARNING(StgInvalidValue, key, value); \
3754 char const str_delimiter[] = {'=', 0}; \
3755 key = __kmp_str_token(CCAST(char *, start), str_delimiter, \
3756 CCAST(char **, &next)); \
3761 while (*next
!= '\0') {
3763 __kmp_match_str("fb_data", scan
, &next
)) { // allocator check
3766 // check HBW and LCAP first as the only non-default supported
3767 if (__kmp_match_str("omp_high_bw_mem_alloc", scan
, &next
)) {
3770 if (__kmp_memkind_available
) {
3771 __kmp_def_allocator
= omp_high_bw_mem_alloc
;
3774 KMP_WARNING(OmpNoAllocator
, "omp_high_bw_mem_alloc");
3777 traits
[count
].key
= omp_atk_fb_data
;
3778 traits
[count
].value
= RCAST(omp_uintptr_t
, omp_high_bw_mem_alloc
);
3780 } else if (__kmp_match_str("omp_large_cap_mem_alloc", scan
, &next
)) {
3783 if (__kmp_memkind_available
) {
3784 __kmp_def_allocator
= omp_large_cap_mem_alloc
;
3787 KMP_WARNING(OmpNoAllocator
, "omp_large_cap_mem_alloc");
3790 traits
[count
].key
= omp_atk_fb_data
;
3791 traits
[count
].value
= RCAST(omp_uintptr_t
, omp_large_cap_mem_alloc
);
3793 } else if (__kmp_match_str("omp_default_mem_alloc", scan
, &next
)) {
3794 // default requested
3797 traits
[count
].key
= omp_atk_fb_data
;
3798 traits
[count
].value
= RCAST(omp_uintptr_t
, omp_default_mem_alloc
);
3800 } else if (__kmp_match_str("omp_const_mem_alloc", scan
, &next
)) {
3803 KMP_WARNING(OmpNoAllocator
, "omp_const_mem_alloc");
3805 traits
[count
].key
= omp_atk_fb_data
;
3806 traits
[count
].value
= RCAST(omp_uintptr_t
, omp_const_mem_alloc
);
3808 } else if (__kmp_match_str("omp_low_lat_mem_alloc", scan
, &next
)) {
3811 KMP_WARNING(OmpNoAllocator
, "omp_low_lat_mem_alloc");
3813 traits
[count
].key
= omp_atk_fb_data
;
3814 traits
[count
].value
= RCAST(omp_uintptr_t
, omp_low_lat_mem_alloc
);
3816 } else if (__kmp_match_str("omp_cgroup_mem_alloc", scan
, &next
)) {
3819 KMP_WARNING(OmpNoAllocator
, "omp_cgroup_mem_alloc");
3821 traits
[count
].key
= omp_atk_fb_data
;
3822 traits
[count
].value
= RCAST(omp_uintptr_t
, omp_cgroup_mem_alloc
);
3824 } else if (__kmp_match_str("omp_pteam_mem_alloc", scan
, &next
)) {
3827 KMP_WARNING(OmpNoAllocator
, "omp_pteam_mem_alloc");
3829 traits
[count
].key
= omp_atk_fb_data
;
3830 traits
[count
].value
= RCAST(omp_uintptr_t
, omp_pteam_mem_alloc
);
3832 } else if (__kmp_match_str("omp_thread_mem_alloc", scan
, &next
)) {
3835 KMP_WARNING(OmpNoAllocator
, "omp_thread_mem_alloc");
3837 traits
[count
].key
= omp_atk_fb_data
;
3838 traits
[count
].value
= RCAST(omp_uintptr_t
, omp_thread_mem_alloc
);
3848 __kmp_def_allocator
= omp_default_mem_alloc
;
3849 if (next
== buf
|| *next
!= '\0') {
3850 // either no match or extra symbols present after the matched token
3851 KMP_WARNING(StgInvalidValue
, name
, value
);
3856 if (count
== ntraits
)
3860 } else { // memspace
3862 if (__kmp_match_str("omp_default_mem_space", scan
, &next
)) {
3864 ms
= omp_default_mem_space
;
3865 } else if (__kmp_match_str("omp_large_cap_mem_space", scan
, &next
)) {
3867 ms
= omp_large_cap_mem_space
;
3868 } else if (__kmp_match_str("omp_const_mem_space", scan
, &next
)) {
3870 ms
= omp_const_mem_space
;
3871 } else if (__kmp_match_str("omp_high_bw_mem_space", scan
, &next
)) {
3873 ms
= omp_high_bw_mem_space
;
3874 } else if (__kmp_match_str("omp_low_lat_mem_space", scan
, &next
)) {
3876 ms
= omp_low_lat_mem_space
;
3878 __kmp_def_allocator
= omp_default_mem_alloc
;
3879 if (next
== buf
|| *next
!= '\0') {
3880 // either no match or extra symbols present after the matched token
3881 KMP_WARNING(StgInvalidValue
, name
, value
);
3887 if (delim
) { // traits
3890 if (__kmp_match_str("sync_hint", scan
, &next
)) {
3892 traits
[count
].key
= omp_atk_sync_hint
;
3893 if (__kmp_match_str("contended", scan
, &next
)) {
3894 traits
[count
].value
= omp_atv_contended
;
3895 } else if (__kmp_match_str("uncontended", scan
, &next
)) {
3896 traits
[count
].value
= omp_atv_uncontended
;
3897 } else if (__kmp_match_str("serialized", scan
, &next
)) {
3898 traits
[count
].value
= omp_atv_serialized
;
3899 } else if (__kmp_match_str("private", scan
, &next
)) {
3900 traits
[count
].value
= omp_atv_private
;
3906 } else if (__kmp_match_str("alignment", scan
, &next
)) {
3908 if (!isdigit(*next
)) {
3914 int n
= __kmp_str_to_int(scan
, ',');
3915 if (n
< 0 || !IS_POWER_OF_TWO(n
)) {
3920 traits
[count
].key
= omp_atk_alignment
;
3921 traits
[count
].value
= n
;
3922 } else if (__kmp_match_str("access", scan
, &next
)) {
3924 traits
[count
].key
= omp_atk_access
;
3925 if (__kmp_match_str("all", scan
, &next
)) {
3926 traits
[count
].value
= omp_atv_all
;
3927 } else if (__kmp_match_str("cgroup", scan
, &next
)) {
3928 traits
[count
].value
= omp_atv_cgroup
;
3929 } else if (__kmp_match_str("pteam", scan
, &next
)) {
3930 traits
[count
].value
= omp_atv_pteam
;
3931 } else if (__kmp_match_str("thread", scan
, &next
)) {
3932 traits
[count
].value
= omp_atv_thread
;
3938 } else if (__kmp_match_str("pool_size", scan
, &next
)) {
3940 if (!isdigit(*next
)) {
3946 int n
= __kmp_str_to_int(scan
, ',');
3952 traits
[count
].key
= omp_atk_pool_size
;
3953 traits
[count
].value
= n
;
3954 } else if (__kmp_match_str("fallback", scan
, &next
)) {
3956 traits
[count
].key
= omp_atk_fallback
;
3957 if (__kmp_match_str("default_mem_fb", scan
, &next
)) {
3958 traits
[count
].value
= omp_atv_default_mem_fb
;
3959 } else if (__kmp_match_str("null_fb", scan
, &next
)) {
3960 traits
[count
].value
= omp_atv_null_fb
;
3961 } else if (__kmp_match_str("abort_fb", scan
, &next
)) {
3962 traits
[count
].value
= omp_atv_abort_fb
;
3963 } else if (__kmp_match_str("allocator_fb", scan
, &next
)) {
3964 traits
[count
].value
= omp_atv_allocator_fb
;
3970 } else if (__kmp_match_str("pinned", scan
, &next
)) {
3972 traits
[count
].key
= omp_atk_pinned
;
3973 if (__kmp_str_match_true(next
)) {
3974 traits
[count
].value
= omp_atv_true
;
3975 } else if (__kmp_str_match_false(next
)) {
3976 traits
[count
].value
= omp_atv_false
;
3982 } else if (__kmp_match_str("partition", scan
, &next
)) {
3984 traits
[count
].key
= omp_atk_partition
;
3985 if (__kmp_match_str("environment", scan
, &next
)) {
3986 traits
[count
].value
= omp_atv_environment
;
3987 } else if (__kmp_match_str("nearest", scan
, &next
)) {
3988 traits
[count
].value
= omp_atv_nearest
;
3989 } else if (__kmp_match_str("blocked", scan
, &next
)) {
3990 traits
[count
].value
= omp_atv_blocked
;
3991 } else if (__kmp_match_str("interleaved", scan
, &next
)) {
3992 traits
[count
].value
= omp_atv_interleaved
;
4005 if (count
== ntraits
)
4011 al
= __kmpc_init_allocator(__kmp_get_gtid(), ms
, ntraits
, traits
);
4012 __kmp_def_allocator
= (al
== omp_null_allocator
) ? omp_default_mem_alloc
: al
;
4015 static void __kmp_stg_print_allocator(kmp_str_buf_t
*buffer
, char const *name
,
4017 if (__kmp_def_allocator
== omp_default_mem_alloc
) {
4018 __kmp_stg_print_str(buffer
, name
, "omp_default_mem_alloc");
4019 } else if (__kmp_def_allocator
== omp_high_bw_mem_alloc
) {
4020 __kmp_stg_print_str(buffer
, name
, "omp_high_bw_mem_alloc");
4021 } else if (__kmp_def_allocator
== omp_large_cap_mem_alloc
) {
4022 __kmp_stg_print_str(buffer
, name
, "omp_large_cap_mem_alloc");
4023 } else if (__kmp_def_allocator
== omp_const_mem_alloc
) {
4024 __kmp_stg_print_str(buffer
, name
, "omp_const_mem_alloc");
4025 } else if (__kmp_def_allocator
== omp_low_lat_mem_alloc
) {
4026 __kmp_stg_print_str(buffer
, name
, "omp_low_lat_mem_alloc");
4027 } else if (__kmp_def_allocator
== omp_cgroup_mem_alloc
) {
4028 __kmp_stg_print_str(buffer
, name
, "omp_cgroup_mem_alloc");
4029 } else if (__kmp_def_allocator
== omp_pteam_mem_alloc
) {
4030 __kmp_stg_print_str(buffer
, name
, "omp_pteam_mem_alloc");
4031 } else if (__kmp_def_allocator
== omp_thread_mem_alloc
) {
4032 __kmp_stg_print_str(buffer
, name
, "omp_thread_mem_alloc");
4036 // -----------------------------------------------------------------------------
4039 static void __kmp_stg_parse_omp_dynamic(char const *name
, char const *value
,
4041 __kmp_stg_parse_bool(name
, value
, &(__kmp_global
.g
.g_dynamic
));
4042 } // __kmp_stg_parse_omp_dynamic
4044 static void __kmp_stg_print_omp_dynamic(kmp_str_buf_t
*buffer
, char const *name
,
4046 __kmp_stg_print_bool(buffer
, name
, __kmp_global
.g
.g_dynamic
);
4047 } // __kmp_stg_print_omp_dynamic
4049 static void __kmp_stg_parse_kmp_dynamic_mode(char const *name
,
4050 char const *value
, void *data
) {
4051 if (TCR_4(__kmp_init_parallel
)) {
4052 KMP_WARNING(EnvParallelWarn
, name
);
4053 __kmp_env_toPrint(name
, 0);
4056 #ifdef USE_LOAD_BALANCE
4057 else if (__kmp_str_match("load balance", 2, value
) ||
4058 __kmp_str_match("load_balance", 2, value
) ||
4059 __kmp_str_match("load-balance", 2, value
) ||
4060 __kmp_str_match("loadbalance", 2, value
) ||
4061 __kmp_str_match("balance", 1, value
)) {
4062 __kmp_global
.g
.g_dynamic_mode
= dynamic_load_balance
;
4064 #endif /* USE_LOAD_BALANCE */
4065 else if (__kmp_str_match("thread limit", 1, value
) ||
4066 __kmp_str_match("thread_limit", 1, value
) ||
4067 __kmp_str_match("thread-limit", 1, value
) ||
4068 __kmp_str_match("threadlimit", 1, value
) ||
4069 __kmp_str_match("limit", 2, value
)) {
4070 __kmp_global
.g
.g_dynamic_mode
= dynamic_thread_limit
;
4071 } else if (__kmp_str_match("random", 1, value
)) {
4072 __kmp_global
.g
.g_dynamic_mode
= dynamic_random
;
4074 KMP_WARNING(StgInvalidValue
, name
, value
);
4076 } //__kmp_stg_parse_kmp_dynamic_mode
4078 static void __kmp_stg_print_kmp_dynamic_mode(kmp_str_buf_t
*buffer
,
4079 char const *name
, void *data
) {
4081 if (__kmp_global
.g
.g_dynamic_mode
== dynamic_default
) {
4082 __kmp_str_buf_print(buffer
, " %s: %s \n", name
, KMP_I18N_STR(NotDefined
));
4084 #ifdef USE_LOAD_BALANCE
4085 else if (__kmp_global
.g
.g_dynamic_mode
== dynamic_load_balance
) {
4086 __kmp_stg_print_str(buffer
, name
, "load balance");
4088 #endif /* USE_LOAD_BALANCE */
4089 else if (__kmp_global
.g
.g_dynamic_mode
== dynamic_thread_limit
) {
4090 __kmp_stg_print_str(buffer
, name
, "thread limit");
4091 } else if (__kmp_global
.g
.g_dynamic_mode
== dynamic_random
) {
4092 __kmp_stg_print_str(buffer
, name
, "random");
4096 #endif /* KMP_DEBUG */
4097 } // __kmp_stg_print_kmp_dynamic_mode
4099 #ifdef USE_LOAD_BALANCE
4101 // -----------------------------------------------------------------------------
4102 // KMP_LOAD_BALANCE_INTERVAL
4104 static void __kmp_stg_parse_ld_balance_interval(char const *name
,
4105 char const *value
, void *data
) {
4106 double interval
= __kmp_convert_to_double(value
);
4107 if (interval
>= 0) {
4108 __kmp_load_balance_interval
= interval
;
4110 KMP_WARNING(StgInvalidValue
, name
, value
);
4112 } // __kmp_stg_parse_load_balance_interval
4114 static void __kmp_stg_print_ld_balance_interval(kmp_str_buf_t
*buffer
,
4115 char const *name
, void *data
) {
4117 __kmp_str_buf_print(buffer
, " %s=%8.6f\n", name
,
4118 __kmp_load_balance_interval
);
4119 #endif /* KMP_DEBUG */
4120 } // __kmp_stg_print_load_balance_interval
4122 #endif /* USE_LOAD_BALANCE */
4124 // -----------------------------------------------------------------------------
4127 static void __kmp_stg_parse_init_at_fork(char const *name
, char const *value
,
4129 __kmp_stg_parse_bool(name
, value
, &__kmp_need_register_atfork
);
4130 if (__kmp_need_register_atfork
) {
4131 __kmp_need_register_atfork_specified
= TRUE
;
4133 } // __kmp_stg_parse_init_at_fork
4135 static void __kmp_stg_print_init_at_fork(kmp_str_buf_t
*buffer
,
4136 char const *name
, void *data
) {
4137 __kmp_stg_print_bool(buffer
, name
, __kmp_need_register_atfork_specified
);
4138 } // __kmp_stg_print_init_at_fork
4140 // -----------------------------------------------------------------------------
4143 static void __kmp_stg_parse_schedule(char const *name
, char const *value
,
4146 if (value
!= NULL
) {
4147 size_t length
= KMP_STRLEN(value
);
4148 if (length
> INT_MAX
) {
4149 KMP_WARNING(LongValue
, name
);
4151 const char *semicolon
;
4152 if (value
[length
- 1] == '"' || value
[length
- 1] == '\'')
4153 KMP_WARNING(UnbalancedQuotes
, name
);
4157 semicolon
= strchr(value
, ';');
4158 if (*value
&& semicolon
!= value
) {
4159 const char *comma
= strchr(value
, ',');
4166 if (!__kmp_strcasecmp_with_sentinel("static", value
, sentinel
)) {
4167 if (!__kmp_strcasecmp_with_sentinel("greedy", comma
, ';')) {
4168 __kmp_static
= kmp_sch_static_greedy
;
4170 } else if (!__kmp_strcasecmp_with_sentinel("balanced", comma
,
4172 __kmp_static
= kmp_sch_static_balanced
;
4175 } else if (!__kmp_strcasecmp_with_sentinel("guided", value
,
4177 if (!__kmp_strcasecmp_with_sentinel("iterative", comma
, ';')) {
4178 __kmp_guided
= kmp_sch_guided_iterative_chunked
;
4180 } else if (!__kmp_strcasecmp_with_sentinel("analytical", comma
,
4182 /* analytical not allowed for too many threads */
4183 __kmp_guided
= kmp_sch_guided_analytical_chunked
;
4187 KMP_WARNING(InvalidClause
, name
, value
);
4189 KMP_WARNING(EmptyClause
, name
);
4190 } while ((value
= semicolon
? semicolon
+ 1 : NULL
));
4194 } // __kmp_stg_parse__schedule
4196 static void __kmp_stg_print_schedule(kmp_str_buf_t
*buffer
, char const *name
,
4198 if (__kmp_env_format
) {
4199 KMP_STR_BUF_PRINT_NAME_EX(name
);
4201 __kmp_str_buf_print(buffer
, " %s='", name
);
4203 if (__kmp_static
== kmp_sch_static_greedy
) {
4204 __kmp_str_buf_print(buffer
, "%s", "static,greedy");
4205 } else if (__kmp_static
== kmp_sch_static_balanced
) {
4206 __kmp_str_buf_print(buffer
, "%s", "static,balanced");
4208 if (__kmp_guided
== kmp_sch_guided_iterative_chunked
) {
4209 __kmp_str_buf_print(buffer
, ";%s'\n", "guided,iterative");
4210 } else if (__kmp_guided
== kmp_sch_guided_analytical_chunked
) {
4211 __kmp_str_buf_print(buffer
, ";%s'\n", "guided,analytical");
4213 } // __kmp_stg_print_schedule
4215 // -----------------------------------------------------------------------------
4218 static inline void __kmp_omp_schedule_restore() {
4219 #if KMP_USE_HIER_SCHED
4220 __kmp_hier_scheds
.deallocate();
4223 __kmp_sched
= kmp_sch_default
;
4226 // if parse_hier = true:
4227 // Parse [HW,][modifier:]kind[,chunk]
4229 // Parse [modifier:]kind[,chunk]
4230 static const char *__kmp_parse_single_omp_schedule(const char *name
,
4232 bool parse_hier
= false) {
4233 /* get the specified scheduling style */
4234 const char *ptr
= value
;
4237 enum sched_type sched
= kmp_sch_default
;
4241 while (*delim
!= ',' && *delim
!= ':' && *delim
!= '\0')
4243 #if KMP_USE_HIER_SCHED
4244 kmp_hier_layer_e layer
= kmp_hier_layer_e::LAYER_THREAD
;
4246 if (*delim
== ',') {
4247 if (!__kmp_strcasecmp_with_sentinel("L1", ptr
, ',')) {
4248 layer
= kmp_hier_layer_e::LAYER_L1
;
4249 } else if (!__kmp_strcasecmp_with_sentinel("L2", ptr
, ',')) {
4250 layer
= kmp_hier_layer_e::LAYER_L2
;
4251 } else if (!__kmp_strcasecmp_with_sentinel("L3", ptr
, ',')) {
4252 layer
= kmp_hier_layer_e::LAYER_L3
;
4253 } else if (!__kmp_strcasecmp_with_sentinel("NUMA", ptr
, ',')) {
4254 layer
= kmp_hier_layer_e::LAYER_NUMA
;
4257 if (layer
!= kmp_hier_layer_e::LAYER_THREAD
&& *delim
!= ',') {
4258 // If there is no comma after the layer, then this schedule is invalid
4259 KMP_WARNING(StgInvalidValue
, name
, value
);
4260 __kmp_omp_schedule_restore();
4262 } else if (layer
!= kmp_hier_layer_e::LAYER_THREAD
) {
4264 while (*delim
!= ',' && *delim
!= ':' && *delim
!= '\0')
4268 #endif // KMP_USE_HIER_SCHED
4269 // Read in schedule modifier if specified
4270 enum sched_type sched_modifier
= (enum sched_type
)0;
4271 if (*delim
== ':') {
4272 if (!__kmp_strcasecmp_with_sentinel("monotonic", ptr
, *delim
)) {
4273 sched_modifier
= sched_type::kmp_sch_modifier_monotonic
;
4275 while (*delim
!= ',' && *delim
!= ':' && *delim
!= '\0')
4277 } else if (!__kmp_strcasecmp_with_sentinel("nonmonotonic", ptr
, *delim
)) {
4278 sched_modifier
= sched_type::kmp_sch_modifier_nonmonotonic
;
4280 while (*delim
!= ',' && *delim
!= ':' && *delim
!= '\0')
4282 } else if (!parse_hier
) {
4283 // If there is no proper schedule modifier, then this schedule is invalid
4284 KMP_WARNING(StgInvalidValue
, name
, value
);
4285 __kmp_omp_schedule_restore();
4289 // Read in schedule kind (required)
4290 if (!__kmp_strcasecmp_with_sentinel("dynamic", ptr
, *delim
))
4291 sched
= kmp_sch_dynamic_chunked
;
4292 else if (!__kmp_strcasecmp_with_sentinel("guided", ptr
, *delim
))
4293 sched
= kmp_sch_guided_chunked
;
4294 // AC: TODO: probably remove TRAPEZOIDAL (OMP 3.0 does not allow it)
4295 else if (!__kmp_strcasecmp_with_sentinel("auto", ptr
, *delim
))
4296 sched
= kmp_sch_auto
;
4297 else if (!__kmp_strcasecmp_with_sentinel("trapezoidal", ptr
, *delim
))
4298 sched
= kmp_sch_trapezoidal
;
4299 else if (!__kmp_strcasecmp_with_sentinel("static", ptr
, *delim
))
4300 sched
= kmp_sch_static
;
4301 #if KMP_STATIC_STEAL_ENABLED
4302 else if (!__kmp_strcasecmp_with_sentinel("static_steal", ptr
, *delim
)) {
4303 // replace static_steal with dynamic to better cope with ordered loops
4304 sched
= kmp_sch_dynamic_chunked
;
4305 sched_modifier
= sched_type::kmp_sch_modifier_nonmonotonic
;
4309 // If there is no proper schedule kind, then this schedule is invalid
4310 KMP_WARNING(StgInvalidValue
, name
, value
);
4311 __kmp_omp_schedule_restore();
4315 // Read in schedule chunk size if specified
4316 if (*delim
== ',') {
4319 if (!isdigit(*ptr
)) {
4320 // If there is no chunk after comma, then this schedule is invalid
4321 KMP_WARNING(StgInvalidValue
, name
, value
);
4322 __kmp_omp_schedule_restore();
4326 // auto schedule should not specify chunk size
4327 if (sched
== kmp_sch_auto
) {
4328 __kmp_msg(kmp_ms_warning
, KMP_MSG(IgnoreChunk
, name
, delim
),
4331 if (sched
== kmp_sch_static
)
4332 sched
= kmp_sch_static_chunked
;
4333 chunk
= __kmp_str_to_int(delim
+ 1, *ptr
);
4335 chunk
= KMP_DEFAULT_CHUNK
;
4336 __kmp_msg(kmp_ms_warning
, KMP_MSG(InvalidChunk
, name
, delim
),
4338 KMP_INFORM(Using_int_Value
, name
, __kmp_chunk
);
4339 // AC: next block commented out until KMP_DEFAULT_CHUNK != KMP_MIN_CHUNK
4340 // (to improve code coverage :)
4341 // The default chunk size is 1 according to standard, thus making
4342 // KMP_MIN_CHUNK not 1 we would introduce mess:
4343 // wrong chunk becomes 1, but it will be impossible to explicitly set
4344 // to 1 because it becomes KMP_MIN_CHUNK...
4345 // } else if ( chunk < KMP_MIN_CHUNK ) {
4346 // chunk = KMP_MIN_CHUNK;
4347 } else if (chunk
> KMP_MAX_CHUNK
) {
4348 chunk
= KMP_MAX_CHUNK
;
4349 __kmp_msg(kmp_ms_warning
, KMP_MSG(LargeChunk
, name
, delim
),
4351 KMP_INFORM(Using_int_Value
, name
, chunk
);
4358 SCHEDULE_SET_MODIFIERS(sched
, sched_modifier
);
4360 #if KMP_USE_HIER_SCHED
4361 if (layer
!= kmp_hier_layer_e::LAYER_THREAD
) {
4362 __kmp_hier_scheds
.append(sched
, chunk
, layer
);
4366 __kmp_chunk
= chunk
;
4367 __kmp_sched
= sched
;
4372 static void __kmp_stg_parse_omp_schedule(char const *name
, char const *value
,
4375 const char *ptr
= value
;
4378 length
= KMP_STRLEN(value
);
4380 if (value
[length
- 1] == '"' || value
[length
- 1] == '\'')
4381 KMP_WARNING(UnbalancedQuotes
, name
);
4382 /* get the specified scheduling style */
4383 #if KMP_USE_HIER_SCHED
4384 if (!__kmp_strcasecmp_with_sentinel("EXPERIMENTAL", ptr
, ' ')) {
4387 while ((ptr
= __kmp_parse_single_omp_schedule(name
, ptr
, true))) {
4388 while (*ptr
== ' ' || *ptr
== '\t' || *ptr
== ':')
4395 __kmp_parse_single_omp_schedule(name
, ptr
);
4397 KMP_WARNING(EmptyString
, name
);
4399 #if KMP_USE_HIER_SCHED
4400 __kmp_hier_scheds
.sort();
4402 K_DIAG(1, ("__kmp_static == %d\n", __kmp_static
))
4403 K_DIAG(1, ("__kmp_guided == %d\n", __kmp_guided
))
4404 K_DIAG(1, ("__kmp_sched == %d\n", __kmp_sched
))
4405 K_DIAG(1, ("__kmp_chunk == %d\n", __kmp_chunk
))
4406 } // __kmp_stg_parse_omp_schedule
4408 static void __kmp_stg_print_omp_schedule(kmp_str_buf_t
*buffer
,
4409 char const *name
, void *data
) {
4410 if (__kmp_env_format
) {
4411 KMP_STR_BUF_PRINT_NAME_EX(name
);
4413 __kmp_str_buf_print(buffer
, " %s='", name
);
4415 enum sched_type sched
= SCHEDULE_WITHOUT_MODIFIERS(__kmp_sched
);
4416 if (SCHEDULE_HAS_MONOTONIC(__kmp_sched
)) {
4417 __kmp_str_buf_print(buffer
, "monotonic:");
4418 } else if (SCHEDULE_HAS_NONMONOTONIC(__kmp_sched
)) {
4419 __kmp_str_buf_print(buffer
, "nonmonotonic:");
4423 case kmp_sch_dynamic_chunked
:
4424 __kmp_str_buf_print(buffer
, "%s,%d'\n", "dynamic", __kmp_chunk
);
4426 case kmp_sch_guided_iterative_chunked
:
4427 case kmp_sch_guided_analytical_chunked
:
4428 __kmp_str_buf_print(buffer
, "%s,%d'\n", "guided", __kmp_chunk
);
4430 case kmp_sch_trapezoidal
:
4431 __kmp_str_buf_print(buffer
, "%s,%d'\n", "trapezoidal", __kmp_chunk
);
4433 case kmp_sch_static
:
4434 case kmp_sch_static_chunked
:
4435 case kmp_sch_static_balanced
:
4436 case kmp_sch_static_greedy
:
4437 __kmp_str_buf_print(buffer
, "%s,%d'\n", "static", __kmp_chunk
);
4439 case kmp_sch_static_steal
:
4440 __kmp_str_buf_print(buffer
, "%s,%d'\n", "static_steal", __kmp_chunk
);
4443 __kmp_str_buf_print(buffer
, "%s,%d'\n", "auto", __kmp_chunk
);
4446 KMP_ASSERT2(false, "Unhandled sched_type enumeration");
4447 KMP_BUILTIN_UNREACHABLE
;
4452 case kmp_sch_dynamic_chunked
:
4453 __kmp_str_buf_print(buffer
, "%s'\n", "dynamic");
4455 case kmp_sch_guided_iterative_chunked
:
4456 case kmp_sch_guided_analytical_chunked
:
4457 __kmp_str_buf_print(buffer
, "%s'\n", "guided");
4459 case kmp_sch_trapezoidal
:
4460 __kmp_str_buf_print(buffer
, "%s'\n", "trapezoidal");
4462 case kmp_sch_static
:
4463 case kmp_sch_static_chunked
:
4464 case kmp_sch_static_balanced
:
4465 case kmp_sch_static_greedy
:
4466 __kmp_str_buf_print(buffer
, "%s'\n", "static");
4468 case kmp_sch_static_steal
:
4469 __kmp_str_buf_print(buffer
, "%s'\n", "static_steal");
4472 __kmp_str_buf_print(buffer
, "%s'\n", "auto");
4475 KMP_ASSERT2(false, "Unhandled sched_type enumeration");
4476 KMP_BUILTIN_UNREACHABLE
;
4480 } // __kmp_stg_print_omp_schedule
4482 #if KMP_USE_HIER_SCHED
4483 // -----------------------------------------------------------------------------
4484 // KMP_DISP_HAND_THREAD
4485 static void __kmp_stg_parse_kmp_hand_thread(char const *name
, char const *value
,
4487 __kmp_stg_parse_bool(name
, value
, &(__kmp_dispatch_hand_threading
));
4488 } // __kmp_stg_parse_kmp_hand_thread
4490 static void __kmp_stg_print_kmp_hand_thread(kmp_str_buf_t
*buffer
,
4491 char const *name
, void *data
) {
4492 __kmp_stg_print_bool(buffer
, name
, __kmp_dispatch_hand_threading
);
4493 } // __kmp_stg_print_kmp_hand_thread
4496 // -----------------------------------------------------------------------------
4497 // KMP_FORCE_MONOTONIC_DYNAMIC_SCHEDULE
4498 static void __kmp_stg_parse_kmp_force_monotonic(char const *name
,
4499 char const *value
, void *data
) {
4500 __kmp_stg_parse_bool(name
, value
, &(__kmp_force_monotonic
));
4501 } // __kmp_stg_parse_kmp_force_monotonic
4503 static void __kmp_stg_print_kmp_force_monotonic(kmp_str_buf_t
*buffer
,
4504 char const *name
, void *data
) {
4505 __kmp_stg_print_bool(buffer
, name
, __kmp_force_monotonic
);
4506 } // __kmp_stg_print_kmp_force_monotonic
4508 // -----------------------------------------------------------------------------
4511 static void __kmp_stg_parse_atomic_mode(char const *name
, char const *value
,
4513 // Modes: 0 -- do not change default; 1 -- Intel perf mode, 2 -- GOMP
4514 // compatibility mode.
4517 #ifdef KMP_GOMP_COMPAT
4519 #endif /* KMP_GOMP_COMPAT */
4520 __kmp_stg_parse_int(name
, value
, 0, max
, &mode
);
4521 // TODO; parse_int is not very suitable for this case. In case of overflow it
4523 // 0 rather that max value.
4525 __kmp_atomic_mode
= mode
;
4527 } // __kmp_stg_parse_atomic_mode
4529 static void __kmp_stg_print_atomic_mode(kmp_str_buf_t
*buffer
, char const *name
,
4531 __kmp_stg_print_int(buffer
, name
, __kmp_atomic_mode
);
4532 } // __kmp_stg_print_atomic_mode
4534 // -----------------------------------------------------------------------------
4535 // KMP_CONSISTENCY_CHECK
4537 static void __kmp_stg_parse_consistency_check(char const *name
,
4538 char const *value
, void *data
) {
4539 if (!__kmp_strcasecmp_with_sentinel("all", value
, 0)) {
4540 // Note, this will not work from kmp_set_defaults because th_cons stack was
4542 // for existed thread(s) thus the first __kmp_push_<construct> will break
4544 // TODO: allocate th_cons if called from kmp_set_defaults.
4545 __kmp_env_consistency_check
= TRUE
;
4546 } else if (!__kmp_strcasecmp_with_sentinel("none", value
, 0)) {
4547 __kmp_env_consistency_check
= FALSE
;
4549 KMP_WARNING(StgInvalidValue
, name
, value
);
4551 } // __kmp_stg_parse_consistency_check
4553 static void __kmp_stg_print_consistency_check(kmp_str_buf_t
*buffer
,
4554 char const *name
, void *data
) {
4556 const char *value
= NULL
;
4558 if (__kmp_env_consistency_check
) {
4564 if (value
!= NULL
) {
4565 __kmp_stg_print_str(buffer
, name
, value
);
4567 #endif /* KMP_DEBUG */
4568 } // __kmp_stg_print_consistency_check
4571 // -----------------------------------------------------------------------------
4572 // KMP_ITT_PREPARE_DELAY
4576 static void __kmp_stg_parse_itt_prepare_delay(char const *name
,
4577 char const *value
, void *data
) {
4578 // Experimental code: KMP_ITT_PREPARE_DELAY specifies numbert of loop
4581 __kmp_stg_parse_int(name
, value
, 0, INT_MAX
, &delay
);
4582 __kmp_itt_prepare_delay
= delay
;
4583 } // __kmp_str_parse_itt_prepare_delay
4585 static void __kmp_stg_print_itt_prepare_delay(kmp_str_buf_t
*buffer
,
4586 char const *name
, void *data
) {
4587 __kmp_stg_print_uint64(buffer
, name
, __kmp_itt_prepare_delay
);
4589 } // __kmp_str_print_itt_prepare_delay
4591 #endif // USE_ITT_NOTIFY
4592 #endif /* USE_ITT_BUILD */
4594 // -----------------------------------------------------------------------------
4595 // KMP_MALLOC_POOL_INCR
4597 static void __kmp_stg_parse_malloc_pool_incr(char const *name
,
4598 char const *value
, void *data
) {
4599 __kmp_stg_parse_size(name
, value
, KMP_MIN_MALLOC_POOL_INCR
,
4600 KMP_MAX_MALLOC_POOL_INCR
, NULL
, &__kmp_malloc_pool_incr
,
4602 } // __kmp_stg_parse_malloc_pool_incr
4604 static void __kmp_stg_print_malloc_pool_incr(kmp_str_buf_t
*buffer
,
4605 char const *name
, void *data
) {
4606 __kmp_stg_print_size(buffer
, name
, __kmp_malloc_pool_incr
);
4608 } // _kmp_stg_print_malloc_pool_incr
4612 // -----------------------------------------------------------------------------
4615 static void __kmp_stg_parse_par_range_env(char const *name
, char const *value
,
4617 __kmp_stg_parse_par_range(name
, value
, &__kmp_par_range
,
4618 __kmp_par_range_routine
, __kmp_par_range_filename
,
4619 &__kmp_par_range_lb
, &__kmp_par_range_ub
);
4620 } // __kmp_stg_parse_par_range_env
4622 static void __kmp_stg_print_par_range_env(kmp_str_buf_t
*buffer
,
4623 char const *name
, void *data
) {
4624 if (__kmp_par_range
!= 0) {
4625 __kmp_stg_print_str(buffer
, name
, par_range_to_print
);
4627 } // __kmp_stg_print_par_range_env
4631 // -----------------------------------------------------------------------------
4634 static void __kmp_stg_parse_gtid_mode(char const *name
, char const *value
,
4637 // 0 -- do not change default
4639 // 2 -- use "keyed" TLS var, i.e.
4640 // pthread_getspecific(Linux* OS/OS X*) or TlsGetValue(Windows* OS)
4641 // 3 -- __declspec(thread) TLS var in tdata section
4644 #ifdef KMP_TDATA_GTID
4646 #endif /* KMP_TDATA_GTID */
4647 __kmp_stg_parse_int(name
, value
, 0, max
, &mode
);
4648 // TODO; parse_int is not very suitable for this case. In case of overflow it
4649 // is better to use 0 rather that max value.
4651 __kmp_adjust_gtid_mode
= TRUE
;
4653 __kmp_gtid_mode
= mode
;
4654 __kmp_adjust_gtid_mode
= FALSE
;
4656 } // __kmp_str_parse_gtid_mode
4658 static void __kmp_stg_print_gtid_mode(kmp_str_buf_t
*buffer
, char const *name
,
4660 if (__kmp_adjust_gtid_mode
) {
4661 __kmp_stg_print_int(buffer
, name
, 0);
4663 __kmp_stg_print_int(buffer
, name
, __kmp_gtid_mode
);
4665 } // __kmp_stg_print_gtid_mode
4667 // -----------------------------------------------------------------------------
4668 // KMP_NUM_LOCKS_IN_BLOCK
4670 static void __kmp_stg_parse_lock_block(char const *name
, char const *value
,
4672 __kmp_stg_parse_int(name
, value
, 0, KMP_INT_MAX
, &__kmp_num_locks_in_block
);
4673 } // __kmp_str_parse_lock_block
4675 static void __kmp_stg_print_lock_block(kmp_str_buf_t
*buffer
, char const *name
,
4677 __kmp_stg_print_int(buffer
, name
, __kmp_num_locks_in_block
);
4678 } // __kmp_stg_print_lock_block
4680 // -----------------------------------------------------------------------------
4683 #if KMP_USE_DYNAMIC_LOCK
4684 #define KMP_STORE_LOCK_SEQ(a) (__kmp_user_lock_seq = lockseq_##a)
4686 #define KMP_STORE_LOCK_SEQ(a)
4689 static void __kmp_stg_parse_lock_kind(char const *name
, char const *value
,
4691 if (__kmp_init_user_locks
) {
4692 KMP_WARNING(EnvLockWarn
, name
);
4696 if (__kmp_str_match("tas", 2, value
) ||
4697 __kmp_str_match("test and set", 2, value
) ||
4698 __kmp_str_match("test_and_set", 2, value
) ||
4699 __kmp_str_match("test-and-set", 2, value
) ||
4700 __kmp_str_match("test andset", 2, value
) ||
4701 __kmp_str_match("test_andset", 2, value
) ||
4702 __kmp_str_match("test-andset", 2, value
) ||
4703 __kmp_str_match("testand set", 2, value
) ||
4704 __kmp_str_match("testand_set", 2, value
) ||
4705 __kmp_str_match("testand-set", 2, value
) ||
4706 __kmp_str_match("testandset", 2, value
)) {
4707 __kmp_user_lock_kind
= lk_tas
;
4708 KMP_STORE_LOCK_SEQ(tas
);
4711 else if (__kmp_str_match("futex", 1, value
)) {
4712 if (__kmp_futex_determine_capable()) {
4713 __kmp_user_lock_kind
= lk_futex
;
4714 KMP_STORE_LOCK_SEQ(futex
);
4716 KMP_WARNING(FutexNotSupported
, name
, value
);
4720 else if (__kmp_str_match("ticket", 2, value
)) {
4721 __kmp_user_lock_kind
= lk_ticket
;
4722 KMP_STORE_LOCK_SEQ(ticket
);
4723 } else if (__kmp_str_match("queuing", 1, value
) ||
4724 __kmp_str_match("queue", 1, value
)) {
4725 __kmp_user_lock_kind
= lk_queuing
;
4726 KMP_STORE_LOCK_SEQ(queuing
);
4727 } else if (__kmp_str_match("drdpa ticket", 1, value
) ||
4728 __kmp_str_match("drdpa_ticket", 1, value
) ||
4729 __kmp_str_match("drdpa-ticket", 1, value
) ||
4730 __kmp_str_match("drdpaticket", 1, value
) ||
4731 __kmp_str_match("drdpa", 1, value
)) {
4732 __kmp_user_lock_kind
= lk_drdpa
;
4733 KMP_STORE_LOCK_SEQ(drdpa
);
4735 #if KMP_USE_ADAPTIVE_LOCKS
4736 else if (__kmp_str_match("adaptive", 1, value
)) {
4737 if (__kmp_cpuinfo
.flags
.rtm
) { // ??? Is cpuinfo available here?
4738 __kmp_user_lock_kind
= lk_adaptive
;
4739 KMP_STORE_LOCK_SEQ(adaptive
);
4741 KMP_WARNING(AdaptiveNotSupported
, name
, value
);
4742 __kmp_user_lock_kind
= lk_queuing
;
4743 KMP_STORE_LOCK_SEQ(queuing
);
4746 #endif // KMP_USE_ADAPTIVE_LOCKS
4747 #if KMP_USE_DYNAMIC_LOCK && KMP_USE_TSX
4748 else if (__kmp_str_match("rtm_queuing", 1, value
)) {
4749 if (__kmp_cpuinfo
.flags
.rtm
) {
4750 __kmp_user_lock_kind
= lk_rtm_queuing
;
4751 KMP_STORE_LOCK_SEQ(rtm_queuing
);
4753 KMP_WARNING(AdaptiveNotSupported
, name
, value
);
4754 __kmp_user_lock_kind
= lk_queuing
;
4755 KMP_STORE_LOCK_SEQ(queuing
);
4757 } else if (__kmp_str_match("rtm_spin", 1, value
)) {
4758 if (__kmp_cpuinfo
.flags
.rtm
) {
4759 __kmp_user_lock_kind
= lk_rtm_spin
;
4760 KMP_STORE_LOCK_SEQ(rtm_spin
);
4762 KMP_WARNING(AdaptiveNotSupported
, name
, value
);
4763 __kmp_user_lock_kind
= lk_tas
;
4764 KMP_STORE_LOCK_SEQ(queuing
);
4766 } else if (__kmp_str_match("hle", 1, value
)) {
4767 __kmp_user_lock_kind
= lk_hle
;
4768 KMP_STORE_LOCK_SEQ(hle
);
4772 KMP_WARNING(StgInvalidValue
, name
, value
);
4776 static void __kmp_stg_print_lock_kind(kmp_str_buf_t
*buffer
, char const *name
,
4778 const char *value
= NULL
;
4780 switch (__kmp_user_lock_kind
) {
4795 #if KMP_USE_DYNAMIC_LOCK && KMP_USE_TSX
4796 case lk_rtm_queuing
:
4797 value
= "rtm_queuing";
4820 #if KMP_USE_ADAPTIVE_LOCKS
4827 if (value
!= NULL
) {
4828 __kmp_stg_print_str(buffer
, name
, value
);
4832 // -----------------------------------------------------------------------------
4833 // KMP_SPIN_BACKOFF_PARAMS
4835 // KMP_SPIN_BACKOFF_PARAMS=max_backoff[,min_tick] (max backoff size, min tick
4836 // for machine pause)
4837 static void __kmp_stg_parse_spin_backoff_params(const char *name
,
4838 const char *value
, void *data
) {
4839 const char *next
= value
;
4841 int total
= 0; // Count elements that were set. It'll be used as an array size
4842 int prev_comma
= FALSE
; // For correct processing sequential commas
4845 kmp_uint32 max_backoff
= __kmp_spin_backoff_params
.max_backoff
;
4846 kmp_uint32 min_tick
= __kmp_spin_backoff_params
.min_tick
;
4848 // Run only 3 iterations because it is enough to read two values or find a
4850 for (i
= 0; i
< 3; i
++) {
4853 if (*next
== '\0') {
4856 // Next character is not an integer or not a comma OR number of values > 2
4858 if (((*next
< '0' || *next
> '9') && *next
!= ',') || total
> 2) {
4859 KMP_WARNING(EnvSyntaxError
, name
, value
);
4862 // The next character is ','
4864 // ',' is the first character
4865 if (total
== 0 || prev_comma
) {
4872 // Next character is a digit
4873 if (*next
>= '0' && *next
<= '9') {
4875 const char *buf
= next
;
4876 char const *msg
= NULL
;
4881 const char *tmp
= next
;
4883 if ((*next
== ' ' || *next
== '\t') && (*tmp
>= '0' && *tmp
<= '9')) {
4884 KMP_WARNING(EnvSpacesNotAllowed
, name
, value
);
4888 num
= __kmp_str_to_int(buf
, *next
);
4889 if (num
<= 0) { // The number of retries should be > 0
4890 msg
= KMP_I18N_STR(ValueTooSmall
);
4894 // Message is not empty. Print warning.
4895 KMP_WARNING(ParseSizeIntWarn
, name
, value
, msg
);
4896 KMP_INFORM(Using_int_Value
, name
, num
);
4900 } else if (total
== 2) {
4905 KMP_DEBUG_ASSERT(total
> 0);
4907 KMP_WARNING(EnvSyntaxError
, name
, value
);
4910 __kmp_spin_backoff_params
.max_backoff
= max_backoff
;
4911 __kmp_spin_backoff_params
.min_tick
= min_tick
;
4914 static void __kmp_stg_print_spin_backoff_params(kmp_str_buf_t
*buffer
,
4915 char const *name
, void *data
) {
4916 if (__kmp_env_format
) {
4917 KMP_STR_BUF_PRINT_NAME_EX(name
);
4919 __kmp_str_buf_print(buffer
, " %s='", name
);
4921 __kmp_str_buf_print(buffer
, "%d,%d'\n", __kmp_spin_backoff_params
.max_backoff
,
4922 __kmp_spin_backoff_params
.min_tick
);
4925 #if KMP_USE_ADAPTIVE_LOCKS
4927 // -----------------------------------------------------------------------------
4928 // KMP_ADAPTIVE_LOCK_PROPS, KMP_SPECULATIVE_STATSFILE
4930 // Parse out values for the tunable parameters from a string of the form
4931 // KMP_ADAPTIVE_LOCK_PROPS=max_soft_retries[,max_badness]
4932 static void __kmp_stg_parse_adaptive_lock_props(const char *name
,
4933 const char *value
, void *data
) {
4934 int max_retries
= 0;
4935 int max_badness
= 0;
4937 const char *next
= value
;
4939 int total
= 0; // Count elements that were set. It'll be used as an array size
4940 int prev_comma
= FALSE
; // For correct processing sequential commas
4943 // Save values in the structure __kmp_speculative_backoff_params
4944 // Run only 3 iterations because it is enough to read two values or find a
4946 for (i
= 0; i
< 3; i
++) {
4949 if (*next
== '\0') {
4952 // Next character is not an integer or not a comma OR number of values > 2
4954 if (((*next
< '0' || *next
> '9') && *next
!= ',') || total
> 2) {
4955 KMP_WARNING(EnvSyntaxError
, name
, value
);
4958 // The next character is ','
4960 // ',' is the first character
4961 if (total
== 0 || prev_comma
) {
4968 // Next character is a digit
4969 if (*next
>= '0' && *next
<= '9') {
4971 const char *buf
= next
;
4972 char const *msg
= NULL
;
4977 const char *tmp
= next
;
4979 if ((*next
== ' ' || *next
== '\t') && (*tmp
>= '0' && *tmp
<= '9')) {
4980 KMP_WARNING(EnvSpacesNotAllowed
, name
, value
);
4984 num
= __kmp_str_to_int(buf
, *next
);
4985 if (num
< 0) { // The number of retries should be >= 0
4986 msg
= KMP_I18N_STR(ValueTooSmall
);
4990 // Message is not empty. Print warning.
4991 KMP_WARNING(ParseSizeIntWarn
, name
, value
, msg
);
4992 KMP_INFORM(Using_int_Value
, name
, num
);
4996 } else if (total
== 2) {
5001 KMP_DEBUG_ASSERT(total
> 0);
5003 KMP_WARNING(EnvSyntaxError
, name
, value
);
5006 __kmp_adaptive_backoff_params
.max_soft_retries
= max_retries
;
5007 __kmp_adaptive_backoff_params
.max_badness
= max_badness
;
5010 static void __kmp_stg_print_adaptive_lock_props(kmp_str_buf_t
*buffer
,
5011 char const *name
, void *data
) {
5012 if (__kmp_env_format
) {
5013 KMP_STR_BUF_PRINT_NAME_EX(name
);
5015 __kmp_str_buf_print(buffer
, " %s='", name
);
5017 __kmp_str_buf_print(buffer
, "%d,%d'\n",
5018 __kmp_adaptive_backoff_params
.max_soft_retries
,
5019 __kmp_adaptive_backoff_params
.max_badness
);
5020 } // __kmp_stg_print_adaptive_lock_props
5022 #if KMP_DEBUG_ADAPTIVE_LOCKS
5024 static void __kmp_stg_parse_speculative_statsfile(char const *name
,
5027 __kmp_stg_parse_file(name
, value
, "",
5028 CCAST(char **, &__kmp_speculative_statsfile
));
5029 } // __kmp_stg_parse_speculative_statsfile
5031 static void __kmp_stg_print_speculative_statsfile(kmp_str_buf_t
*buffer
,
5034 if (__kmp_str_match("-", 0, __kmp_speculative_statsfile
)) {
5035 __kmp_stg_print_str(buffer
, name
, "stdout");
5037 __kmp_stg_print_str(buffer
, name
, __kmp_speculative_statsfile
);
5040 } // __kmp_stg_print_speculative_statsfile
5042 #endif // KMP_DEBUG_ADAPTIVE_LOCKS
5044 #endif // KMP_USE_ADAPTIVE_LOCKS
5046 // -----------------------------------------------------------------------------
5047 // KMP_HW_SUBSET (was KMP_PLACE_THREADS)
5048 // 2s16c,2t => 2S16C,2T => 2S16C \0 2T
5050 // Return KMP_HW_SUBSET preferred hardware type in case a token is ambiguously
5051 // short. The original KMP_HW_SUBSET environment variable had single letters:
5052 // s, c, t for sockets, cores, threads repsectively.
5053 static kmp_hw_t
__kmp_hw_subset_break_tie(const kmp_hw_t
*possible
,
5054 size_t num_possible
) {
5055 for (size_t i
= 0; i
< num_possible
; ++i
) {
5056 if (possible
[i
] == KMP_HW_THREAD
)
5057 return KMP_HW_THREAD
;
5058 else if (possible
[i
] == KMP_HW_CORE
)
5060 else if (possible
[i
] == KMP_HW_SOCKET
)
5061 return KMP_HW_SOCKET
;
5063 return KMP_HW_UNKNOWN
;
5066 // Return hardware type from string or HW_UNKNOWN if string cannot be parsed
5067 // This algorithm is very forgiving to the user in that, the instant it can
5068 // reduce the search space to one, it assumes that is the topology level the
5069 // user wanted, even if it is misspelled later in the token.
5070 static kmp_hw_t
__kmp_stg_parse_hw_subset_name(char const *token
) {
5071 size_t index
, num_possible
, token_length
;
5072 kmp_hw_t possible
[KMP_HW_LAST
];
5075 // Find the end of the hardware token string
5078 while (isalnum(*end
) || *end
== '_') {
5083 // Set the possibilities to all hardware types
5085 KMP_FOREACH_HW_TYPE(type
) { possible
[num_possible
++] = type
; }
5087 // Eliminate hardware types by comparing the front of the token
5088 // with hardware names
5089 // In most cases, the first letter in the token will indicate exactly
5090 // which hardware type is parsed, e.g., 'C' = Core
5092 while (num_possible
> 1 && index
< token_length
) {
5093 size_t n
= num_possible
;
5094 char token_char
= (char)toupper(token
[index
]);
5095 for (size_t i
= 0; i
< n
; ++i
) {
5097 kmp_hw_t type
= possible
[i
];
5098 s
= __kmp_hw_get_keyword(type
, false);
5099 if (index
< KMP_STRLEN(s
)) {
5100 char c
= (char)toupper(s
[index
]);
5101 // Mark hardware types for removal when the characters do not match
5102 if (c
!= token_char
) {
5103 possible
[i
] = KMP_HW_UNKNOWN
;
5108 // Remove hardware types that this token cannot be
5110 for (size_t i
= 0; i
< n
; ++i
) {
5111 if (possible
[i
] != KMP_HW_UNKNOWN
) {
5112 kmp_hw_t temp
= possible
[i
];
5113 possible
[i
] = possible
[start
];
5114 possible
[start
] = temp
;
5118 KMP_ASSERT(start
== num_possible
);
5122 // Attempt to break a tie if user has very short token
5123 // (e.g., is 'T' tile or thread?)
5124 if (num_possible
> 1)
5125 return __kmp_hw_subset_break_tie(possible
, num_possible
);
5126 if (num_possible
== 1)
5128 return KMP_HW_UNKNOWN
;
5131 // The longest observable sequence of items can only be HW_LAST length
5132 // The input string is usually short enough, let's use 512 limit for now
5133 #define MAX_T_LEVEL KMP_HW_LAST
5134 #define MAX_STR_LEN 512
5135 static void __kmp_stg_parse_hw_subset(char const *name
, char const *value
,
5137 // Value example: 1s,5c@3,2T
5138 // Which means "use 1 socket, 5 cores with offset 3, 2 threads per core"
5139 kmp_setting_t
**rivals
= (kmp_setting_t
**)data
;
5140 if (strcmp(name
, "KMP_PLACE_THREADS") == 0) {
5141 KMP_INFORM(EnvVarDeprecated
, name
, "KMP_HW_SUBSET");
5143 if (__kmp_stg_check_rivals(name
, value
, rivals
)) {
5147 char *components
[MAX_T_LEVEL
];
5148 char const *digits
= "0123456789";
5149 char input
[MAX_STR_LEN
];
5150 size_t len
= 0, mlen
= MAX_STR_LEN
;
5152 bool absolute
= false;
5153 // Canonicalize the string (remove spaces, unify delimiters, etc.)
5154 char *pos
= CCAST(char *, value
);
5155 while (*pos
&& mlen
) {
5156 if (*pos
!= ' ') { // skip spaces
5157 if (len
== 0 && *pos
== ':') {
5160 input
[len
] = (char)(toupper(*pos
));
5161 if (input
[len
] == 'X')
5162 input
[len
] = ','; // unify delimiters of levels
5163 if (input
[len
] == 'O' && strchr(digits
, *(pos
+ 1)))
5164 input
[len
] = '@'; // unify delimiters of offset
5171 if (len
== 0 || mlen
== 0) {
5172 goto err
; // contents is either empty or too long
5175 // Split by delimiter
5177 components
[level
++] = pos
;
5178 while ((pos
= strchr(pos
, ','))) {
5179 if (level
>= MAX_T_LEVEL
)
5180 goto err
; // too many components provided
5181 *pos
= '\0'; // modify input and avoid more copying
5182 components
[level
++] = ++pos
; // expect something after ","
5185 __kmp_hw_subset
= kmp_hw_subset_t::allocate();
5187 __kmp_hw_subset
->set_absolute();
5189 // Check each component
5190 for (int i
= 0; i
< level
; ++i
) {
5192 char *core_components
[MAX_T_LEVEL
];
5193 // Split possible core components by '&' delimiter
5194 pos
= components
[i
];
5195 core_components
[core_level
++] = pos
;
5196 while ((pos
= strchr(pos
, '&'))) {
5197 if (core_level
>= MAX_T_LEVEL
)
5198 goto err
; // too many different core types
5199 *pos
= '\0'; // modify input and avoid more copying
5200 core_components
[core_level
++] = ++pos
; // expect something after '&'
5203 for (int j
= 0; j
< core_level
; ++j
) {
5209 // components may begin with an optional count of the number of resources
5210 if (isdigit(*core_components
[j
])) {
5211 num
= atoi(core_components
[j
]);
5213 goto err
; // only positive integers are valid for count
5215 pos
= core_components
[j
] + strspn(core_components
[j
], digits
);
5216 } else if (*core_components
[j
] == '*') {
5217 num
= kmp_hw_subset_t::USE_ALL
;
5218 pos
= core_components
[j
] + 1;
5220 num
= kmp_hw_subset_t::USE_ALL
;
5221 pos
= core_components
[j
];
5224 offset_ptr
= strchr(core_components
[j
], '@');
5225 attr_ptr
= strchr(core_components
[j
], ':');
5228 offset
= atoi(offset_ptr
+ 1); // save offset
5229 *offset_ptr
= '\0'; // cut the offset from the component
5233 // save the attribute
5234 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
5235 if (__kmp_str_match("intel_core", -1, attr_ptr
+ 1)) {
5236 attr
.set_core_type(KMP_HW_CORE_TYPE_CORE
);
5237 } else if (__kmp_str_match("intel_atom", -1, attr_ptr
+ 1)) {
5238 attr
.set_core_type(KMP_HW_CORE_TYPE_ATOM
);
5241 if (__kmp_str_match("eff", 3, attr_ptr
+ 1)) {
5242 const char *number
= attr_ptr
+ 1;
5243 // skip the eff[iciency] token
5244 while (isalpha(*number
))
5246 if (!isdigit(*number
)) {
5249 int efficiency
= atoi(number
);
5250 attr
.set_core_eff(efficiency
);
5254 *attr_ptr
= '\0'; // cut the attribute from the component
5256 // detect the component type
5257 kmp_hw_t type
= __kmp_stg_parse_hw_subset_name(pos
);
5258 if (type
== KMP_HW_UNKNOWN
) {
5261 // Only the core type can have attributes
5262 if (attr
&& type
!= KMP_HW_CORE
)
5264 // Must allow core be specified more than once
5265 if (type
!= KMP_HW_CORE
&& __kmp_hw_subset
->specified(type
)) {
5268 __kmp_hw_subset
->push_back(num
, type
, offset
, attr
);
5273 KMP_WARNING(AffHWSubsetInvalid
, name
, value
);
5274 if (__kmp_hw_subset
) {
5275 kmp_hw_subset_t::deallocate(__kmp_hw_subset
);
5276 __kmp_hw_subset
= nullptr;
5281 static void __kmp_stg_print_hw_subset(kmp_str_buf_t
*buffer
, char const *name
,
5285 if (!__kmp_hw_subset
)
5287 __kmp_str_buf_init(&buf
);
5288 if (__kmp_env_format
)
5289 KMP_STR_BUF_PRINT_NAME_EX(name
);
5291 __kmp_str_buf_print(buffer
, " %s='", name
);
5293 depth
= __kmp_hw_subset
->get_depth();
5294 for (int i
= 0; i
< depth
; ++i
) {
5295 const auto &item
= __kmp_hw_subset
->at(i
);
5297 __kmp_str_buf_print(&buf
, "%c", ',');
5298 for (int j
= 0; j
< item
.num_attrs
; ++j
) {
5299 __kmp_str_buf_print(&buf
, "%s%d%s", (j
> 0 ? "&" : ""), item
.num
[j
],
5300 __kmp_hw_get_keyword(item
.type
));
5301 if (item
.attr
[j
].is_core_type_valid())
5302 __kmp_str_buf_print(
5304 __kmp_hw_get_core_type_keyword(item
.attr
[j
].get_core_type()));
5305 if (item
.attr
[j
].is_core_eff_valid())
5306 __kmp_str_buf_print(&buf
, ":eff%d", item
.attr
[j
].get_core_eff());
5308 __kmp_str_buf_print(&buf
, "@%d", item
.offset
[j
]);
5311 __kmp_str_buf_print(buffer
, "%s'\n", buf
.str
);
5312 __kmp_str_buf_free(&buf
);
5316 // -----------------------------------------------------------------------------
5317 // KMP_FORKJOIN_FRAMES
5319 static void __kmp_stg_parse_forkjoin_frames(char const *name
, char const *value
,
5321 __kmp_stg_parse_bool(name
, value
, &__kmp_forkjoin_frames
);
5322 } // __kmp_stg_parse_forkjoin_frames
5324 static void __kmp_stg_print_forkjoin_frames(kmp_str_buf_t
*buffer
,
5325 char const *name
, void *data
) {
5326 __kmp_stg_print_bool(buffer
, name
, __kmp_forkjoin_frames
);
5327 } // __kmp_stg_print_forkjoin_frames
5329 // -----------------------------------------------------------------------------
5330 // KMP_FORKJOIN_FRAMES_MODE
5332 static void __kmp_stg_parse_forkjoin_frames_mode(char const *name
,
5335 __kmp_stg_parse_int(name
, value
, 0, 3, &__kmp_forkjoin_frames_mode
);
5336 } // __kmp_stg_parse_forkjoin_frames
5338 static void __kmp_stg_print_forkjoin_frames_mode(kmp_str_buf_t
*buffer
,
5339 char const *name
, void *data
) {
5340 __kmp_stg_print_int(buffer
, name
, __kmp_forkjoin_frames_mode
);
5341 } // __kmp_stg_print_forkjoin_frames
5342 #endif /* USE_ITT_BUILD */
5344 // -----------------------------------------------------------------------------
5345 // KMP_ENABLE_TASK_THROTTLING
5347 static void __kmp_stg_parse_task_throttling(char const *name
, char const *value
,
5349 __kmp_stg_parse_bool(name
, value
, &__kmp_enable_task_throttling
);
5350 } // __kmp_stg_parse_task_throttling
5352 static void __kmp_stg_print_task_throttling(kmp_str_buf_t
*buffer
,
5353 char const *name
, void *data
) {
5354 __kmp_stg_print_bool(buffer
, name
, __kmp_enable_task_throttling
);
5355 } // __kmp_stg_print_task_throttling
5357 #if KMP_HAVE_MWAIT || KMP_HAVE_UMWAIT
5358 // -----------------------------------------------------------------------------
5359 // KMP_USER_LEVEL_MWAIT
5361 static void __kmp_stg_parse_user_level_mwait(char const *name
,
5362 char const *value
, void *data
) {
5363 __kmp_stg_parse_bool(name
, value
, &__kmp_user_level_mwait
);
5364 } // __kmp_stg_parse_user_level_mwait
5366 static void __kmp_stg_print_user_level_mwait(kmp_str_buf_t
*buffer
,
5367 char const *name
, void *data
) {
5368 __kmp_stg_print_bool(buffer
, name
, __kmp_user_level_mwait
);
5369 } // __kmp_stg_print_user_level_mwait
5371 // -----------------------------------------------------------------------------
5374 static void __kmp_stg_parse_mwait_hints(char const *name
, char const *value
,
5376 __kmp_stg_parse_int(name
, value
, 0, INT_MAX
, &__kmp_mwait_hints
);
5377 } // __kmp_stg_parse_mwait_hints
5379 static void __kmp_stg_print_mwait_hints(kmp_str_buf_t
*buffer
, char const *name
,
5381 __kmp_stg_print_int(buffer
, name
, __kmp_mwait_hints
);
5382 } // __kmp_stg_print_mwait_hints
5384 #endif // KMP_HAVE_MWAIT || KMP_HAVE_UMWAIT
5387 // -----------------------------------------------------------------------------
5389 // 0 = don't use TPAUSE, 1 = use C0.1 state, 2 = use C0.2 state
5391 static void __kmp_stg_parse_tpause(char const *name
, char const *value
,
5393 __kmp_stg_parse_int(name
, value
, 0, INT_MAX
, &__kmp_tpause_state
);
5394 if (__kmp_tpause_state
!= 0) {
5395 // The actual hint passed to tpause is: 0 for C0.2 and 1 for C0.1
5396 if (__kmp_tpause_state
== 2) // use C0.2
5397 __kmp_tpause_hint
= 0; // default was set to 1 for C0.1
5399 } // __kmp_stg_parse_tpause
5401 static void __kmp_stg_print_tpause(kmp_str_buf_t
*buffer
, char const *name
,
5403 __kmp_stg_print_int(buffer
, name
, __kmp_tpause_state
);
5404 } // __kmp_stg_print_tpause
5405 #endif // KMP_HAVE_UMWAIT
5407 // -----------------------------------------------------------------------------
5410 static void __kmp_stg_parse_omp_display_env(char const *name
, char const *value
,
5412 if (__kmp_str_match("VERBOSE", 1, value
)) {
5413 __kmp_display_env_verbose
= TRUE
;
5415 __kmp_stg_parse_bool(name
, value
, &__kmp_display_env
);
5417 } // __kmp_stg_parse_omp_display_env
5419 static void __kmp_stg_print_omp_display_env(kmp_str_buf_t
*buffer
,
5420 char const *name
, void *data
) {
5421 if (__kmp_display_env_verbose
) {
5422 __kmp_stg_print_str(buffer
, name
, "VERBOSE");
5424 __kmp_stg_print_bool(buffer
, name
, __kmp_display_env
);
5426 } // __kmp_stg_print_omp_display_env
5428 static void __kmp_stg_parse_omp_cancellation(char const *name
,
5429 char const *value
, void *data
) {
5430 if (TCR_4(__kmp_init_parallel
)) {
5431 KMP_WARNING(EnvParallelWarn
, name
);
5433 } // read value before first parallel only
5434 __kmp_stg_parse_bool(name
, value
, &__kmp_omp_cancellation
);
5435 } // __kmp_stg_parse_omp_cancellation
5437 static void __kmp_stg_print_omp_cancellation(kmp_str_buf_t
*buffer
,
5438 char const *name
, void *data
) {
5439 __kmp_stg_print_bool(buffer
, name
, __kmp_omp_cancellation
);
5440 } // __kmp_stg_print_omp_cancellation
5445 static void __kmp_stg_parse_omp_tool(char const *name
, char const *value
,
5447 __kmp_stg_parse_bool(name
, value
, &__kmp_tool
);
5448 } // __kmp_stg_parse_omp_tool
5450 static void __kmp_stg_print_omp_tool(kmp_str_buf_t
*buffer
, char const *name
,
5452 if (__kmp_env_format
) {
5453 KMP_STR_BUF_PRINT_BOOL_EX(name
, __kmp_tool
, "enabled", "disabled");
5455 __kmp_str_buf_print(buffer
, " %s=%s\n", name
,
5456 __kmp_tool
? "enabled" : "disabled");
5458 } // __kmp_stg_print_omp_tool
5460 char *__kmp_tool_libraries
= NULL
;
5462 static void __kmp_stg_parse_omp_tool_libraries(char const *name
,
5463 char const *value
, void *data
) {
5464 __kmp_stg_parse_str(name
, value
, &__kmp_tool_libraries
);
5465 } // __kmp_stg_parse_omp_tool_libraries
5467 static void __kmp_stg_print_omp_tool_libraries(kmp_str_buf_t
*buffer
,
5468 char const *name
, void *data
) {
5469 if (__kmp_tool_libraries
)
5470 __kmp_stg_print_str(buffer
, name
, __kmp_tool_libraries
);
5472 if (__kmp_env_format
) {
5473 KMP_STR_BUF_PRINT_NAME
;
5475 __kmp_str_buf_print(buffer
, " %s", name
);
5477 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
5479 } // __kmp_stg_print_omp_tool_libraries
5481 char *__kmp_tool_verbose_init
= NULL
;
5483 static void __kmp_stg_parse_omp_tool_verbose_init(char const *name
,
5486 __kmp_stg_parse_str(name
, value
, &__kmp_tool_verbose_init
);
5487 } // __kmp_stg_parse_omp_tool_libraries
5489 static void __kmp_stg_print_omp_tool_verbose_init(kmp_str_buf_t
*buffer
,
5492 if (__kmp_tool_verbose_init
)
5493 __kmp_stg_print_str(buffer
, name
, __kmp_tool_verbose_init
);
5495 if (__kmp_env_format
) {
5496 KMP_STR_BUF_PRINT_NAME
;
5498 __kmp_str_buf_print(buffer
, " %s", name
);
5500 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
5502 } // __kmp_stg_print_omp_tool_verbose_init
5508 static kmp_setting_t __kmp_stg_table
[] = {
5510 {"KMP_ALL_THREADS", __kmp_stg_parse_device_thread_limit
, NULL
, NULL
, 0, 0},
5511 {"KMP_BLOCKTIME", __kmp_stg_parse_blocktime
, __kmp_stg_print_blocktime
,
5513 {"KMP_USE_YIELD", __kmp_stg_parse_use_yield
, __kmp_stg_print_use_yield
,
5515 {"KMP_DUPLICATE_LIB_OK", __kmp_stg_parse_duplicate_lib_ok
,
5516 __kmp_stg_print_duplicate_lib_ok
, NULL
, 0, 0},
5517 {"KMP_LIBRARY", __kmp_stg_parse_wait_policy
, __kmp_stg_print_wait_policy
,
5519 {"KMP_DEVICE_THREAD_LIMIT", __kmp_stg_parse_device_thread_limit
,
5520 __kmp_stg_print_device_thread_limit
, NULL
, 0, 0},
5522 {"KMP_MONITOR_STACKSIZE", __kmp_stg_parse_monitor_stacksize
,
5523 __kmp_stg_print_monitor_stacksize
, NULL
, 0, 0},
5525 {"KMP_SETTINGS", __kmp_stg_parse_settings
, __kmp_stg_print_settings
, NULL
,
5527 {"KMP_STACKOFFSET", __kmp_stg_parse_stackoffset
,
5528 __kmp_stg_print_stackoffset
, NULL
, 0, 0},
5529 {"KMP_STACKSIZE", __kmp_stg_parse_stacksize
, __kmp_stg_print_stacksize
,
5531 {"KMP_STACKPAD", __kmp_stg_parse_stackpad
, __kmp_stg_print_stackpad
, NULL
,
5533 {"KMP_VERSION", __kmp_stg_parse_version
, __kmp_stg_print_version
, NULL
, 0,
5535 {"KMP_WARNINGS", __kmp_stg_parse_warnings
, __kmp_stg_print_warnings
, NULL
,
5538 {"KMP_NESTING_MODE", __kmp_stg_parse_nesting_mode
,
5539 __kmp_stg_print_nesting_mode
, NULL
, 0, 0},
5540 {"OMP_NESTED", __kmp_stg_parse_nested
, __kmp_stg_print_nested
, NULL
, 0, 0},
5541 {"OMP_NUM_THREADS", __kmp_stg_parse_num_threads
,
5542 __kmp_stg_print_num_threads
, NULL
, 0, 0},
5543 {"OMP_STACKSIZE", __kmp_stg_parse_stacksize
, __kmp_stg_print_stacksize
,
5546 {"KMP_TASKING", __kmp_stg_parse_tasking
, __kmp_stg_print_tasking
, NULL
, 0,
5548 {"KMP_TASK_STEALING_CONSTRAINT", __kmp_stg_parse_task_stealing
,
5549 __kmp_stg_print_task_stealing
, NULL
, 0, 0},
5550 {"OMP_MAX_ACTIVE_LEVELS", __kmp_stg_parse_max_active_levels
,
5551 __kmp_stg_print_max_active_levels
, NULL
, 0, 0},
5552 {"OMP_DEFAULT_DEVICE", __kmp_stg_parse_default_device
,
5553 __kmp_stg_print_default_device
, NULL
, 0, 0},
5554 {"OMP_TARGET_OFFLOAD", __kmp_stg_parse_target_offload
,
5555 __kmp_stg_print_target_offload
, NULL
, 0, 0},
5556 {"OMP_MAX_TASK_PRIORITY", __kmp_stg_parse_max_task_priority
,
5557 __kmp_stg_print_max_task_priority
, NULL
, 0, 0},
5558 {"KMP_TASKLOOP_MIN_TASKS", __kmp_stg_parse_taskloop_min_tasks
,
5559 __kmp_stg_print_taskloop_min_tasks
, NULL
, 0, 0},
5560 {"OMP_THREAD_LIMIT", __kmp_stg_parse_thread_limit
,
5561 __kmp_stg_print_thread_limit
, NULL
, 0, 0},
5562 {"KMP_TEAMS_THREAD_LIMIT", __kmp_stg_parse_teams_thread_limit
,
5563 __kmp_stg_print_teams_thread_limit
, NULL
, 0, 0},
5564 {"OMP_NUM_TEAMS", __kmp_stg_parse_nteams
, __kmp_stg_print_nteams
, NULL
, 0,
5566 {"OMP_TEAMS_THREAD_LIMIT", __kmp_stg_parse_teams_th_limit
,
5567 __kmp_stg_print_teams_th_limit
, NULL
, 0, 0},
5568 {"OMP_WAIT_POLICY", __kmp_stg_parse_wait_policy
,
5569 __kmp_stg_print_wait_policy
, NULL
, 0, 0},
5570 {"KMP_DISP_NUM_BUFFERS", __kmp_stg_parse_disp_buffers
,
5571 __kmp_stg_print_disp_buffers
, NULL
, 0, 0},
5572 #if KMP_NESTED_HOT_TEAMS
5573 {"KMP_HOT_TEAMS_MAX_LEVEL", __kmp_stg_parse_hot_teams_level
,
5574 __kmp_stg_print_hot_teams_level
, NULL
, 0, 0},
5575 {"KMP_HOT_TEAMS_MODE", __kmp_stg_parse_hot_teams_mode
,
5576 __kmp_stg_print_hot_teams_mode
, NULL
, 0, 0},
5577 #endif // KMP_NESTED_HOT_TEAMS
5579 #if KMP_HANDLE_SIGNALS
5580 {"KMP_HANDLE_SIGNALS", __kmp_stg_parse_handle_signals
,
5581 __kmp_stg_print_handle_signals
, NULL
, 0, 0},
5584 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
5585 {"KMP_INHERIT_FP_CONTROL", __kmp_stg_parse_inherit_fp_control
,
5586 __kmp_stg_print_inherit_fp_control
, NULL
, 0, 0},
5587 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
5589 #ifdef KMP_GOMP_COMPAT
5590 {"GOMP_STACKSIZE", __kmp_stg_parse_stacksize
, NULL
, NULL
, 0, 0},
5594 {"KMP_A_DEBUG", __kmp_stg_parse_a_debug
, __kmp_stg_print_a_debug
, NULL
, 0,
5596 {"KMP_B_DEBUG", __kmp_stg_parse_b_debug
, __kmp_stg_print_b_debug
, NULL
, 0,
5598 {"KMP_C_DEBUG", __kmp_stg_parse_c_debug
, __kmp_stg_print_c_debug
, NULL
, 0,
5600 {"KMP_D_DEBUG", __kmp_stg_parse_d_debug
, __kmp_stg_print_d_debug
, NULL
, 0,
5602 {"KMP_E_DEBUG", __kmp_stg_parse_e_debug
, __kmp_stg_print_e_debug
, NULL
, 0,
5604 {"KMP_F_DEBUG", __kmp_stg_parse_f_debug
, __kmp_stg_print_f_debug
, NULL
, 0,
5606 {"KMP_DEBUG", __kmp_stg_parse_debug
, NULL
, /* no print */ NULL
, 0, 0},
5607 {"KMP_DEBUG_BUF", __kmp_stg_parse_debug_buf
, __kmp_stg_print_debug_buf
,
5609 {"KMP_DEBUG_BUF_ATOMIC", __kmp_stg_parse_debug_buf_atomic
,
5610 __kmp_stg_print_debug_buf_atomic
, NULL
, 0, 0},
5611 {"KMP_DEBUG_BUF_CHARS", __kmp_stg_parse_debug_buf_chars
,
5612 __kmp_stg_print_debug_buf_chars
, NULL
, 0, 0},
5613 {"KMP_DEBUG_BUF_LINES", __kmp_stg_parse_debug_buf_lines
,
5614 __kmp_stg_print_debug_buf_lines
, NULL
, 0, 0},
5615 {"KMP_DIAG", __kmp_stg_parse_diag
, __kmp_stg_print_diag
, NULL
, 0, 0},
5617 {"KMP_PAR_RANGE", __kmp_stg_parse_par_range_env
,
5618 __kmp_stg_print_par_range_env
, NULL
, 0, 0},
5621 {"KMP_ALIGN_ALLOC", __kmp_stg_parse_align_alloc
,
5622 __kmp_stg_print_align_alloc
, NULL
, 0, 0},
5624 {"KMP_PLAIN_BARRIER", __kmp_stg_parse_barrier_branch_bit
,
5625 __kmp_stg_print_barrier_branch_bit
, NULL
, 0, 0},
5626 {"KMP_PLAIN_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern
,
5627 __kmp_stg_print_barrier_pattern
, NULL
, 0, 0},
5628 {"KMP_FORKJOIN_BARRIER", __kmp_stg_parse_barrier_branch_bit
,
5629 __kmp_stg_print_barrier_branch_bit
, NULL
, 0, 0},
5630 {"KMP_FORKJOIN_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern
,
5631 __kmp_stg_print_barrier_pattern
, NULL
, 0, 0},
5632 #if KMP_FAST_REDUCTION_BARRIER
5633 {"KMP_REDUCTION_BARRIER", __kmp_stg_parse_barrier_branch_bit
,
5634 __kmp_stg_print_barrier_branch_bit
, NULL
, 0, 0},
5635 {"KMP_REDUCTION_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern
,
5636 __kmp_stg_print_barrier_pattern
, NULL
, 0, 0},
5639 {"KMP_ABORT_DELAY", __kmp_stg_parse_abort_delay
,
5640 __kmp_stg_print_abort_delay
, NULL
, 0, 0},
5641 {"KMP_CPUINFO_FILE", __kmp_stg_parse_cpuinfo_file
,
5642 __kmp_stg_print_cpuinfo_file
, NULL
, 0, 0},
5643 {"KMP_FORCE_REDUCTION", __kmp_stg_parse_force_reduction
,
5644 __kmp_stg_print_force_reduction
, NULL
, 0, 0},
5645 {"KMP_DETERMINISTIC_REDUCTION", __kmp_stg_parse_force_reduction
,
5646 __kmp_stg_print_force_reduction
, NULL
, 0, 0},
5647 {"KMP_STORAGE_MAP", __kmp_stg_parse_storage_map
,
5648 __kmp_stg_print_storage_map
, NULL
, 0, 0},
5649 {"KMP_ALL_THREADPRIVATE", __kmp_stg_parse_all_threadprivate
,
5650 __kmp_stg_print_all_threadprivate
, NULL
, 0, 0},
5651 {"KMP_FOREIGN_THREADS_THREADPRIVATE",
5652 __kmp_stg_parse_foreign_threads_threadprivate
,
5653 __kmp_stg_print_foreign_threads_threadprivate
, NULL
, 0, 0},
5655 #if KMP_AFFINITY_SUPPORTED
5656 {"KMP_AFFINITY", __kmp_stg_parse_affinity
, __kmp_stg_print_affinity
, NULL
,
5658 {"KMP_HIDDEN_HELPER_AFFINITY", __kmp_stg_parse_hh_affinity
,
5659 __kmp_stg_print_hh_affinity
, NULL
, 0, 0},
5660 #ifdef KMP_GOMP_COMPAT
5661 {"GOMP_CPU_AFFINITY", __kmp_stg_parse_gomp_cpu_affinity
, NULL
,
5662 /* no print */ NULL
, 0, 0},
5663 #endif /* KMP_GOMP_COMPAT */
5664 {"OMP_PROC_BIND", __kmp_stg_parse_proc_bind
, __kmp_stg_print_proc_bind
,
5666 {"KMP_TEAMS_PROC_BIND", __kmp_stg_parse_teams_proc_bind
,
5667 __kmp_stg_print_teams_proc_bind
, NULL
, 0, 0},
5668 {"OMP_PLACES", __kmp_stg_parse_places
, __kmp_stg_print_places
, NULL
, 0, 0},
5669 {"KMP_TOPOLOGY_METHOD", __kmp_stg_parse_topology_method
,
5670 __kmp_stg_print_topology_method
, NULL
, 0, 0},
5674 // KMP_AFFINITY is not supported on OS X*, nor is OMP_PLACES.
5675 // OMP_PROC_BIND and proc-bind-var are supported, however.
5676 {"OMP_PROC_BIND", __kmp_stg_parse_proc_bind
, __kmp_stg_print_proc_bind
,
5679 #endif // KMP_AFFINITY_SUPPORTED
5680 {"OMP_DISPLAY_AFFINITY", __kmp_stg_parse_display_affinity
,
5681 __kmp_stg_print_display_affinity
, NULL
, 0, 0},
5682 {"OMP_AFFINITY_FORMAT", __kmp_stg_parse_affinity_format
,
5683 __kmp_stg_print_affinity_format
, NULL
, 0, 0},
5684 {"KMP_INIT_AT_FORK", __kmp_stg_parse_init_at_fork
,
5685 __kmp_stg_print_init_at_fork
, NULL
, 0, 0},
5686 {"KMP_SCHEDULE", __kmp_stg_parse_schedule
, __kmp_stg_print_schedule
, NULL
,
5688 {"OMP_SCHEDULE", __kmp_stg_parse_omp_schedule
, __kmp_stg_print_omp_schedule
,
5690 #if KMP_USE_HIER_SCHED
5691 {"KMP_DISP_HAND_THREAD", __kmp_stg_parse_kmp_hand_thread
,
5692 __kmp_stg_print_kmp_hand_thread
, NULL
, 0, 0},
5694 {"KMP_FORCE_MONOTONIC_DYNAMIC_SCHEDULE",
5695 __kmp_stg_parse_kmp_force_monotonic
, __kmp_stg_print_kmp_force_monotonic
,
5697 {"KMP_ATOMIC_MODE", __kmp_stg_parse_atomic_mode
,
5698 __kmp_stg_print_atomic_mode
, NULL
, 0, 0},
5699 {"KMP_CONSISTENCY_CHECK", __kmp_stg_parse_consistency_check
,
5700 __kmp_stg_print_consistency_check
, NULL
, 0, 0},
5702 #if USE_ITT_BUILD && USE_ITT_NOTIFY
5703 {"KMP_ITT_PREPARE_DELAY", __kmp_stg_parse_itt_prepare_delay
,
5704 __kmp_stg_print_itt_prepare_delay
, NULL
, 0, 0},
5705 #endif /* USE_ITT_BUILD && USE_ITT_NOTIFY */
5706 {"KMP_MALLOC_POOL_INCR", __kmp_stg_parse_malloc_pool_incr
,
5707 __kmp_stg_print_malloc_pool_incr
, NULL
, 0, 0},
5708 {"KMP_GTID_MODE", __kmp_stg_parse_gtid_mode
, __kmp_stg_print_gtid_mode
,
5710 {"OMP_DYNAMIC", __kmp_stg_parse_omp_dynamic
, __kmp_stg_print_omp_dynamic
,
5712 {"KMP_DYNAMIC_MODE", __kmp_stg_parse_kmp_dynamic_mode
,
5713 __kmp_stg_print_kmp_dynamic_mode
, NULL
, 0, 0},
5715 #ifdef USE_LOAD_BALANCE
5716 {"KMP_LOAD_BALANCE_INTERVAL", __kmp_stg_parse_ld_balance_interval
,
5717 __kmp_stg_print_ld_balance_interval
, NULL
, 0, 0},
5720 {"KMP_NUM_LOCKS_IN_BLOCK", __kmp_stg_parse_lock_block
,
5721 __kmp_stg_print_lock_block
, NULL
, 0, 0},
5722 {"KMP_LOCK_KIND", __kmp_stg_parse_lock_kind
, __kmp_stg_print_lock_kind
,
5724 {"KMP_SPIN_BACKOFF_PARAMS", __kmp_stg_parse_spin_backoff_params
,
5725 __kmp_stg_print_spin_backoff_params
, NULL
, 0, 0},
5726 #if KMP_USE_ADAPTIVE_LOCKS
5727 {"KMP_ADAPTIVE_LOCK_PROPS", __kmp_stg_parse_adaptive_lock_props
,
5728 __kmp_stg_print_adaptive_lock_props
, NULL
, 0, 0},
5729 #if KMP_DEBUG_ADAPTIVE_LOCKS
5730 {"KMP_SPECULATIVE_STATSFILE", __kmp_stg_parse_speculative_statsfile
,
5731 __kmp_stg_print_speculative_statsfile
, NULL
, 0, 0},
5733 #endif // KMP_USE_ADAPTIVE_LOCKS
5734 {"KMP_PLACE_THREADS", __kmp_stg_parse_hw_subset
, __kmp_stg_print_hw_subset
,
5736 {"KMP_HW_SUBSET", __kmp_stg_parse_hw_subset
, __kmp_stg_print_hw_subset
,
5739 {"KMP_FORKJOIN_FRAMES", __kmp_stg_parse_forkjoin_frames
,
5740 __kmp_stg_print_forkjoin_frames
, NULL
, 0, 0},
5741 {"KMP_FORKJOIN_FRAMES_MODE", __kmp_stg_parse_forkjoin_frames_mode
,
5742 __kmp_stg_print_forkjoin_frames_mode
, NULL
, 0, 0},
5744 {"KMP_ENABLE_TASK_THROTTLING", __kmp_stg_parse_task_throttling
,
5745 __kmp_stg_print_task_throttling
, NULL
, 0, 0},
5747 {"OMP_DISPLAY_ENV", __kmp_stg_parse_omp_display_env
,
5748 __kmp_stg_print_omp_display_env
, NULL
, 0, 0},
5749 {"OMP_CANCELLATION", __kmp_stg_parse_omp_cancellation
,
5750 __kmp_stg_print_omp_cancellation
, NULL
, 0, 0},
5751 {"OMP_ALLOCATOR", __kmp_stg_parse_allocator
, __kmp_stg_print_allocator
,
5753 {"LIBOMP_USE_HIDDEN_HELPER_TASK", __kmp_stg_parse_use_hidden_helper
,
5754 __kmp_stg_print_use_hidden_helper
, NULL
, 0, 0},
5755 {"LIBOMP_NUM_HIDDEN_HELPER_THREADS",
5756 __kmp_stg_parse_num_hidden_helper_threads
,
5757 __kmp_stg_print_num_hidden_helper_threads
, NULL
, 0, 0},
5759 {"KMP_MAX_TDGS", __kmp_stg_parse_max_tdgs
, __kmp_std_print_max_tdgs
, NULL
,
5761 {"KMP_TDG_DOT", __kmp_stg_parse_tdg_dot
, __kmp_stg_print_tdg_dot
, NULL
, 0, 0},
5765 {"OMP_TOOL", __kmp_stg_parse_omp_tool
, __kmp_stg_print_omp_tool
, NULL
, 0,
5767 {"OMP_TOOL_LIBRARIES", __kmp_stg_parse_omp_tool_libraries
,
5768 __kmp_stg_print_omp_tool_libraries
, NULL
, 0, 0},
5769 {"OMP_TOOL_VERBOSE_INIT", __kmp_stg_parse_omp_tool_verbose_init
,
5770 __kmp_stg_print_omp_tool_verbose_init
, NULL
, 0, 0},
5773 #if KMP_HAVE_MWAIT || KMP_HAVE_UMWAIT
5774 {"KMP_USER_LEVEL_MWAIT", __kmp_stg_parse_user_level_mwait
,
5775 __kmp_stg_print_user_level_mwait
, NULL
, 0, 0},
5776 {"KMP_MWAIT_HINTS", __kmp_stg_parse_mwait_hints
,
5777 __kmp_stg_print_mwait_hints
, NULL
, 0, 0},
5781 {"KMP_TPAUSE", __kmp_stg_parse_tpause
, __kmp_stg_print_tpause
, NULL
, 0, 0},
5783 {"", NULL
, NULL
, NULL
, 0, 0}}; // settings
5785 static int const __kmp_stg_count
=
5786 sizeof(__kmp_stg_table
) / sizeof(kmp_setting_t
);
5788 static inline kmp_setting_t
*__kmp_stg_find(char const *name
) {
5792 for (i
= 0; i
< __kmp_stg_count
; ++i
) {
5793 if (strcmp(__kmp_stg_table
[i
].name
, name
) == 0) {
5794 return &__kmp_stg_table
[i
];
5802 static int __kmp_stg_cmp(void const *_a
, void const *_b
) {
5803 const kmp_setting_t
*a
= RCAST(const kmp_setting_t
*, _a
);
5804 const kmp_setting_t
*b
= RCAST(const kmp_setting_t
*, _b
);
5806 // Process KMP_AFFINITY last.
5807 // It needs to come after OMP_PLACES and GOMP_CPU_AFFINITY.
5808 if (strcmp(a
->name
, "KMP_AFFINITY") == 0) {
5809 if (strcmp(b
->name
, "KMP_AFFINITY") == 0) {
5813 } else if (strcmp(b
->name
, "KMP_AFFINITY") == 0) {
5816 return strcmp(a
->name
, b
->name
);
5819 static void __kmp_stg_init(void) {
5821 static int initialized
= 0;
5826 qsort(__kmp_stg_table
, __kmp_stg_count
- 1, sizeof(kmp_setting_t
),
5829 { // Initialize *_STACKSIZE data.
5830 kmp_setting_t
*kmp_stacksize
=
5831 __kmp_stg_find("KMP_STACKSIZE"); // 1st priority.
5832 #ifdef KMP_GOMP_COMPAT
5833 kmp_setting_t
*gomp_stacksize
=
5834 __kmp_stg_find("GOMP_STACKSIZE"); // 2nd priority.
5836 kmp_setting_t
*omp_stacksize
=
5837 __kmp_stg_find("OMP_STACKSIZE"); // 3rd priority.
5839 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5840 // !!! Compiler does not understand rivals is used and optimizes out
5842 // !!! rivals[ i ++ ] = ...;
5843 static kmp_setting_t
*volatile rivals
[4];
5844 static kmp_stg_ss_data_t kmp_data
= {1, CCAST(kmp_setting_t
**, rivals
)};
5845 #ifdef KMP_GOMP_COMPAT
5846 static kmp_stg_ss_data_t gomp_data
= {1024,
5847 CCAST(kmp_setting_t
**, rivals
)};
5849 static kmp_stg_ss_data_t omp_data
= {1024,
5850 CCAST(kmp_setting_t
**, rivals
)};
5853 rivals
[i
++] = kmp_stacksize
;
5854 #ifdef KMP_GOMP_COMPAT
5855 if (gomp_stacksize
!= NULL
) {
5856 rivals
[i
++] = gomp_stacksize
;
5859 rivals
[i
++] = omp_stacksize
;
5862 kmp_stacksize
->data
= &kmp_data
;
5863 #ifdef KMP_GOMP_COMPAT
5864 if (gomp_stacksize
!= NULL
) {
5865 gomp_stacksize
->data
= &gomp_data
;
5868 omp_stacksize
->data
= &omp_data
;
5871 { // Initialize KMP_LIBRARY and OMP_WAIT_POLICY data.
5872 kmp_setting_t
*kmp_library
=
5873 __kmp_stg_find("KMP_LIBRARY"); // 1st priority.
5874 kmp_setting_t
*omp_wait_policy
=
5875 __kmp_stg_find("OMP_WAIT_POLICY"); // 2nd priority.
5877 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5878 static kmp_setting_t
*volatile rivals
[3];
5879 static kmp_stg_wp_data_t kmp_data
= {0, CCAST(kmp_setting_t
**, rivals
)};
5880 static kmp_stg_wp_data_t omp_data
= {1, CCAST(kmp_setting_t
**, rivals
)};
5883 rivals
[i
++] = kmp_library
;
5884 if (omp_wait_policy
!= NULL
) {
5885 rivals
[i
++] = omp_wait_policy
;
5889 kmp_library
->data
= &kmp_data
;
5890 if (omp_wait_policy
!= NULL
) {
5891 omp_wait_policy
->data
= &omp_data
;
5895 { // Initialize KMP_DEVICE_THREAD_LIMIT and KMP_ALL_THREADS
5896 kmp_setting_t
*kmp_device_thread_limit
=
5897 __kmp_stg_find("KMP_DEVICE_THREAD_LIMIT"); // 1st priority.
5898 kmp_setting_t
*kmp_all_threads
=
5899 __kmp_stg_find("KMP_ALL_THREADS"); // 2nd priority.
5901 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5902 static kmp_setting_t
*volatile rivals
[3];
5905 rivals
[i
++] = kmp_device_thread_limit
;
5906 rivals
[i
++] = kmp_all_threads
;
5909 kmp_device_thread_limit
->data
= CCAST(kmp_setting_t
**, rivals
);
5910 kmp_all_threads
->data
= CCAST(kmp_setting_t
**, rivals
);
5913 { // Initialize KMP_HW_SUBSET and KMP_PLACE_THREADS
5915 kmp_setting_t
*kmp_hw_subset
= __kmp_stg_find("KMP_HW_SUBSET");
5917 kmp_setting_t
*kmp_place_threads
= __kmp_stg_find("KMP_PLACE_THREADS");
5919 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5920 static kmp_setting_t
*volatile rivals
[3];
5923 rivals
[i
++] = kmp_hw_subset
;
5924 rivals
[i
++] = kmp_place_threads
;
5927 kmp_hw_subset
->data
= CCAST(kmp_setting_t
**, rivals
);
5928 kmp_place_threads
->data
= CCAST(kmp_setting_t
**, rivals
);
5931 #if KMP_AFFINITY_SUPPORTED
5932 { // Initialize KMP_AFFINITY, GOMP_CPU_AFFINITY, and OMP_PROC_BIND data.
5933 kmp_setting_t
*kmp_affinity
=
5934 __kmp_stg_find("KMP_AFFINITY"); // 1st priority.
5935 KMP_DEBUG_ASSERT(kmp_affinity
!= NULL
);
5937 #ifdef KMP_GOMP_COMPAT
5938 kmp_setting_t
*gomp_cpu_affinity
=
5939 __kmp_stg_find("GOMP_CPU_AFFINITY"); // 2nd priority.
5940 KMP_DEBUG_ASSERT(gomp_cpu_affinity
!= NULL
);
5943 kmp_setting_t
*omp_proc_bind
=
5944 __kmp_stg_find("OMP_PROC_BIND"); // 3rd priority.
5945 KMP_DEBUG_ASSERT(omp_proc_bind
!= NULL
);
5947 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5948 static kmp_setting_t
*volatile rivals
[4];
5951 rivals
[i
++] = kmp_affinity
;
5953 #ifdef KMP_GOMP_COMPAT
5954 rivals
[i
++] = gomp_cpu_affinity
;
5955 gomp_cpu_affinity
->data
= CCAST(kmp_setting_t
**, rivals
);
5958 rivals
[i
++] = omp_proc_bind
;
5959 omp_proc_bind
->data
= CCAST(kmp_setting_t
**, rivals
);
5962 static kmp_setting_t
*volatile places_rivals
[4];
5965 kmp_setting_t
*omp_places
= __kmp_stg_find("OMP_PLACES"); // 3rd priority.
5966 KMP_DEBUG_ASSERT(omp_places
!= NULL
);
5968 places_rivals
[i
++] = kmp_affinity
;
5969 #ifdef KMP_GOMP_COMPAT
5970 places_rivals
[i
++] = gomp_cpu_affinity
;
5972 places_rivals
[i
++] = omp_places
;
5973 omp_places
->data
= CCAST(kmp_setting_t
**, places_rivals
);
5974 places_rivals
[i
++] = NULL
;
5977 // KMP_AFFINITY not supported, so OMP_PROC_BIND has no rivals.
5978 // OMP_PLACES not supported yet.
5979 #endif // KMP_AFFINITY_SUPPORTED
5981 { // Initialize KMP_DETERMINISTIC_REDUCTION and KMP_FORCE_REDUCTION data.
5982 kmp_setting_t
*kmp_force_red
=
5983 __kmp_stg_find("KMP_FORCE_REDUCTION"); // 1st priority.
5984 kmp_setting_t
*kmp_determ_red
=
5985 __kmp_stg_find("KMP_DETERMINISTIC_REDUCTION"); // 2nd priority.
5987 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5988 static kmp_setting_t
*volatile rivals
[3];
5989 static kmp_stg_fr_data_t force_data
= {1,
5990 CCAST(kmp_setting_t
**, rivals
)};
5991 static kmp_stg_fr_data_t determ_data
= {0,
5992 CCAST(kmp_setting_t
**, rivals
)};
5995 rivals
[i
++] = kmp_force_red
;
5996 if (kmp_determ_red
!= NULL
) {
5997 rivals
[i
++] = kmp_determ_red
;
6001 kmp_force_red
->data
= &force_data
;
6002 if (kmp_determ_red
!= NULL
) {
6003 kmp_determ_red
->data
= &determ_data
;
6012 for (i
= 0; i
< __kmp_stg_count
; ++i
) {
6013 __kmp_stg_table
[i
].set
= 0;
6018 static void __kmp_stg_parse(char const *name
, char const *value
) {
6019 // On Windows* OS there are some nameless variables like "C:=C:\" (yeah,
6020 // really nameless, they are presented in environment block as
6021 // "=C:=C\\\x00=D:=D:\\\x00...", so let us skip them.
6026 if (value
!= NULL
) {
6027 kmp_setting_t
*setting
= __kmp_stg_find(name
);
6028 if (setting
!= NULL
) {
6029 setting
->parse(name
, value
, setting
->data
);
6030 setting
->defined
= 1;
6034 } // __kmp_stg_parse
6036 static int __kmp_stg_check_rivals( // 0 -- Ok, 1 -- errors found.
6037 char const *name
, // Name of variable.
6038 char const *value
, // Value of the variable.
6039 kmp_setting_t
**rivals
// List of rival settings (must include current one).
6042 if (rivals
== NULL
) {
6046 // Loop thru higher priority settings (listed before current).
6048 for (; strcmp(rivals
[i
]->name
, name
) != 0; i
++) {
6049 KMP_DEBUG_ASSERT(rivals
[i
] != NULL
);
6051 #if KMP_AFFINITY_SUPPORTED
6052 if (rivals
[i
] == __kmp_affinity_notype
) {
6053 // If KMP_AFFINITY is specified without a type name,
6054 // it does not rival OMP_PROC_BIND or GOMP_CPU_AFFINITY.
6059 if (rivals
[i
]->set
) {
6060 KMP_WARNING(StgIgnored
, name
, rivals
[i
]->name
);
6065 ++i
; // Skip current setting.
6068 } // __kmp_stg_check_rivals
6070 static int __kmp_env_toPrint(char const *name
, int flag
) {
6072 kmp_setting_t
*setting
= __kmp_stg_find(name
);
6073 if (setting
!= NULL
) {
6074 rc
= setting
->defined
;
6076 setting
->defined
= flag
;
6082 #if defined(KMP_DEBUG) && KMP_AFFINITY_SUPPORTED
6083 static void __kmp_print_affinity_settings(const kmp_affinity_t
*affinity
) {
6084 K_DIAG(1, ("%s:\n", affinity
->env_var
));
6085 K_DIAG(1, (" type : %d\n", affinity
->type
));
6086 K_DIAG(1, (" compact : %d\n", affinity
->compact
));
6087 K_DIAG(1, (" offset : %d\n", affinity
->offset
));
6088 K_DIAG(1, (" verbose : %u\n", affinity
->flags
.verbose
));
6089 K_DIAG(1, (" warnings : %u\n", affinity
->flags
.warnings
));
6090 K_DIAG(1, (" respect : %u\n", affinity
->flags
.respect
));
6091 K_DIAG(1, (" reset : %u\n", affinity
->flags
.reset
));
6092 K_DIAG(1, (" dups : %u\n", affinity
->flags
.dups
));
6093 K_DIAG(1, (" gran : %d\n", (int)affinity
->gran
));
6094 KMP_DEBUG_ASSERT(affinity
->type
!= affinity_default
);
6098 static void __kmp_aux_env_initialize(kmp_env_blk_t
*block
) {
6102 /* OMP_NUM_THREADS */
6103 value
= __kmp_env_blk_var(block
, "OMP_NUM_THREADS");
6105 ompc_set_num_threads(__kmp_dflt_team_nth
);
6109 value
= __kmp_env_blk_var(block
, "KMP_BLOCKTIME");
6114 gtid
= __kmp_entry_gtid();
6115 tid
= __kmp_tid_from_gtid(gtid
);
6116 thread
= __kmp_thread_from_gtid(gtid
);
6117 __kmp_aux_set_blocktime(__kmp_dflt_blocktime
, thread
, tid
);
6121 value
= __kmp_env_blk_var(block
, "OMP_NESTED");
6123 ompc_set_nested(__kmp_dflt_max_active_levels
> 1);
6127 value
= __kmp_env_blk_var(block
, "OMP_DYNAMIC");
6129 ompc_set_dynamic(__kmp_global
.g
.g_dynamic
);
6133 void __kmp_env_initialize(char const *string
) {
6135 kmp_env_blk_t block
;
6141 if (string
== NULL
) {
6142 // __kmp_max_nth = __kmp_sys_max_nth;
6143 __kmp_threads_capacity
=
6144 __kmp_initial_threads_capacity(__kmp_dflt_team_nth_ub
);
6146 __kmp_env_blk_init(&block
, string
);
6148 // update the set flag on all entries that have an env var
6149 for (i
= 0; i
< block
.count
; ++i
) {
6150 if ((block
.vars
[i
].name
== NULL
) || (*block
.vars
[i
].name
== '\0')) {
6153 if (block
.vars
[i
].value
== NULL
) {
6156 kmp_setting_t
*setting
= __kmp_stg_find(block
.vars
[i
].name
);
6157 if (setting
!= NULL
) {
6162 // We need to know if blocktime was set when processing OMP_WAIT_POLICY
6163 blocktime_str
= __kmp_env_blk_var(&block
, "KMP_BLOCKTIME");
6165 // Special case. If we parse environment, not a string, process KMP_WARNINGS
6167 if (string
== NULL
) {
6168 char const *name
= "KMP_WARNINGS";
6169 char const *value
= __kmp_env_blk_var(&block
, name
);
6170 __kmp_stg_parse(name
, value
);
6173 #if KMP_AFFINITY_SUPPORTED
6174 // Special case. KMP_AFFINITY is not a rival to other affinity env vars
6175 // if no affinity type is specified. We want to allow
6176 // KMP_AFFINITY=[no],verbose/[no]warnings/etc. to be enabled when
6177 // specifying the affinity type via GOMP_CPU_AFFINITY or the OMP 4.0
6178 // affinity mechanism.
6179 __kmp_affinity_notype
= NULL
;
6180 char const *aff_str
= __kmp_env_blk_var(&block
, "KMP_AFFINITY");
6181 if (aff_str
!= NULL
) {
6182 // Check if the KMP_AFFINITY type is specified in the string.
6183 // We just search the string for "compact", "scatter", etc.
6184 // without really parsing the string. The syntax of the
6185 // KMP_AFFINITY env var is such that none of the affinity
6186 // type names can appear anywhere other that the type
6187 // specifier, even as substrings.
6189 // I can't find a case-insensitive version of strstr on Windows* OS.
6190 // Use the case-sensitive version for now. AIX does the same.
6192 #if KMP_OS_WINDOWS || KMP_OS_AIX
6195 #define FIND strcasestr
6198 if ((FIND(aff_str
, "none") == NULL
) &&
6199 (FIND(aff_str
, "physical") == NULL
) &&
6200 (FIND(aff_str
, "logical") == NULL
) &&
6201 (FIND(aff_str
, "compact") == NULL
) &&
6202 (FIND(aff_str
, "scatter") == NULL
) &&
6203 (FIND(aff_str
, "explicit") == NULL
) &&
6204 (FIND(aff_str
, "balanced") == NULL
) &&
6205 (FIND(aff_str
, "disabled") == NULL
)) {
6206 __kmp_affinity_notype
= __kmp_stg_find("KMP_AFFINITY");
6208 // A new affinity type is specified.
6209 // Reset the affinity flags to their default values,
6210 // in case this is called from kmp_set_defaults().
6211 __kmp_affinity
.type
= affinity_default
;
6212 __kmp_affinity
.gran
= KMP_HW_UNKNOWN
;
6213 __kmp_affinity_top_method
= affinity_top_method_default
;
6214 __kmp_affinity
.flags
.respect
= affinity_respect_mask_default
;
6218 // Also reset the affinity flags if OMP_PROC_BIND is specified.
6219 aff_str
= __kmp_env_blk_var(&block
, "OMP_PROC_BIND");
6220 if (aff_str
!= NULL
) {
6221 __kmp_affinity
.type
= affinity_default
;
6222 __kmp_affinity
.gran
= KMP_HW_UNKNOWN
;
6223 __kmp_affinity_top_method
= affinity_top_method_default
;
6224 __kmp_affinity
.flags
.respect
= affinity_respect_mask_default
;
6228 #endif /* KMP_AFFINITY_SUPPORTED */
6230 // Set up the nested proc bind type vector.
6231 if (__kmp_nested_proc_bind
.bind_types
== NULL
) {
6232 __kmp_nested_proc_bind
.bind_types
=
6233 (kmp_proc_bind_t
*)KMP_INTERNAL_MALLOC(sizeof(kmp_proc_bind_t
));
6234 if (__kmp_nested_proc_bind
.bind_types
== NULL
) {
6235 KMP_FATAL(MemoryAllocFailed
);
6237 __kmp_nested_proc_bind
.size
= 1;
6238 __kmp_nested_proc_bind
.used
= 1;
6239 #if KMP_AFFINITY_SUPPORTED
6240 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_default
;
6242 // default proc bind is false if affinity not supported
6243 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_false
;
6247 // Set up the affinity format ICV
6248 // Grab the default affinity format string from the message catalog
6250 __kmp_msg_format(kmp_i18n_msg_AffFormatDefault
, "%P", "%i", "%n", "%A");
6251 KMP_DEBUG_ASSERT(KMP_STRLEN(m
.str
) < KMP_AFFINITY_FORMAT_SIZE
);
6253 if (__kmp_affinity_format
== NULL
) {
6254 __kmp_affinity_format
=
6255 (char *)KMP_INTERNAL_MALLOC(sizeof(char) * KMP_AFFINITY_FORMAT_SIZE
);
6257 KMP_STRCPY_S(__kmp_affinity_format
, KMP_AFFINITY_FORMAT_SIZE
, m
.str
);
6258 __kmp_str_free(&m
.str
);
6260 // Now process all of the settings.
6261 for (i
= 0; i
< block
.count
; ++i
) {
6262 __kmp_stg_parse(block
.vars
[i
].name
, block
.vars
[i
].value
);
6265 // If user locks have been allocated yet, don't reset the lock vptr table.
6266 if (!__kmp_init_user_locks
) {
6267 if (__kmp_user_lock_kind
== lk_default
) {
6268 __kmp_user_lock_kind
= lk_queuing
;
6270 #if KMP_USE_DYNAMIC_LOCK
6271 __kmp_init_dynamic_user_locks();
6273 __kmp_set_user_lock_vptrs(__kmp_user_lock_kind
);
6276 KMP_DEBUG_ASSERT(string
!= NULL
); // kmp_set_defaults() was called
6277 KMP_DEBUG_ASSERT(__kmp_user_lock_kind
!= lk_default
);
6278 // Binds lock functions again to follow the transition between different
6279 // KMP_CONSISTENCY_CHECK values. Calling this again is harmless as long
6280 // as we do not allow lock kind changes after making a call to any
6281 // user lock functions (true).
6282 #if KMP_USE_DYNAMIC_LOCK
6283 __kmp_init_dynamic_user_locks();
6285 __kmp_set_user_lock_vptrs(__kmp_user_lock_kind
);
6289 #if KMP_AFFINITY_SUPPORTED
6291 if (!TCR_4(__kmp_init_middle
)) {
6293 // Force using hwloc when either tiles or numa nodes requested within
6294 // KMP_HW_SUBSET or granularity setting and no other topology method
6296 if (__kmp_hw_subset
&&
6297 __kmp_affinity_top_method
== affinity_top_method_default
)
6298 if (__kmp_hw_subset
->specified(KMP_HW_NUMA
) ||
6299 __kmp_hw_subset
->specified(KMP_HW_TILE
) ||
6300 __kmp_affinity
.gran
== KMP_HW_TILE
||
6301 __kmp_affinity
.gran
== KMP_HW_NUMA
)
6302 __kmp_affinity_top_method
= affinity_top_method_hwloc
;
6303 // Force using hwloc when tiles or numa nodes requested for OMP_PLACES
6304 if (__kmp_affinity
.gran
== KMP_HW_NUMA
||
6305 __kmp_affinity
.gran
== KMP_HW_TILE
)
6306 __kmp_affinity_top_method
= affinity_top_method_hwloc
;
6308 // Determine if the machine/OS is actually capable of supporting
6310 const char *var
= "KMP_AFFINITY";
6311 KMPAffinity::pick_api();
6313 // If Hwloc topology discovery was requested but affinity was also disabled,
6314 // then tell user that Hwloc request is being ignored and use default
6315 // topology discovery method.
6316 if (__kmp_affinity_top_method
== affinity_top_method_hwloc
&&
6317 __kmp_affinity_dispatch
->get_api_type() != KMPAffinity::HWLOC
) {
6318 KMP_WARNING(AffIgnoringHwloc
, var
);
6319 __kmp_affinity_top_method
= affinity_top_method_all
;
6322 if (__kmp_affinity
.type
== affinity_disabled
) {
6323 KMP_AFFINITY_DISABLE();
6324 } else if (!KMP_AFFINITY_CAPABLE()) {
6325 __kmp_affinity_dispatch
->determine_capable(var
);
6326 if (!KMP_AFFINITY_CAPABLE()) {
6327 if (__kmp_affinity
.flags
.verbose
||
6328 (__kmp_affinity
.flags
.warnings
&&
6329 (__kmp_affinity
.type
!= affinity_default
) &&
6330 (__kmp_affinity
.type
!= affinity_none
) &&
6331 (__kmp_affinity
.type
!= affinity_disabled
))) {
6332 KMP_WARNING(AffNotSupported
, var
);
6334 __kmp_affinity
.type
= affinity_disabled
;
6335 __kmp_affinity
.flags
.respect
= FALSE
;
6336 __kmp_affinity
.gran
= KMP_HW_THREAD
;
6340 if (__kmp_affinity
.type
== affinity_disabled
) {
6341 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_false
;
6342 } else if (__kmp_nested_proc_bind
.bind_types
[0] == proc_bind_true
) {
6343 // OMP_PROC_BIND=true maps to OMP_PROC_BIND=spread.
6344 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_spread
;
6347 if (KMP_AFFINITY_CAPABLE()) {
6349 #if KMP_GROUP_AFFINITY
6350 // This checks to see if the initial affinity mask is equal
6351 // to a single windows processor group. If it is, then we do
6352 // not respect the initial affinity mask and instead, use the
6354 bool exactly_one_group
= false;
6355 if (__kmp_num_proc_groups
> 1) {
6357 bool within_one_group
;
6358 // Get the initial affinity mask and determine if it is
6359 // contained within a single group.
6360 kmp_affin_mask_t
*init_mask
;
6361 KMP_CPU_ALLOC(init_mask
);
6362 __kmp_get_system_affinity(init_mask
, TRUE
);
6363 group
= __kmp_get_proc_group(init_mask
);
6364 within_one_group
= (group
>= 0);
6365 // If the initial affinity is within a single group,
6366 // then determine if it is equal to that single group.
6367 if (within_one_group
) {
6368 DWORD num_bits_in_group
= __kmp_GetActiveProcessorCount(group
);
6369 DWORD num_bits_in_mask
= 0;
6370 for (int bit
= init_mask
->begin(); bit
!= init_mask
->end();
6371 bit
= init_mask
->next(bit
))
6373 exactly_one_group
= (num_bits_in_group
== num_bits_in_mask
);
6375 KMP_CPU_FREE(init_mask
);
6378 // Handle the Win 64 group affinity stuff if there are multiple
6379 // processor groups, or if the user requested it, and OMP 4.0
6380 // affinity is not in effect.
6381 if (__kmp_num_proc_groups
> 1 &&
6382 __kmp_affinity
.type
== affinity_default
&&
6383 __kmp_nested_proc_bind
.bind_types
[0] == proc_bind_default
) {
6384 // Do not respect the initial processor affinity mask if it is assigned
6385 // exactly one Windows Processor Group since this is interpreted as the
6386 // default OS assignment. Not respecting the mask allows the runtime to
6387 // use all the logical processors in all groups.
6388 if (__kmp_affinity
.flags
.respect
== affinity_respect_mask_default
&&
6389 exactly_one_group
) {
6390 __kmp_affinity
.flags
.respect
= FALSE
;
6392 // Use compact affinity with anticipation of pinning to at least the
6393 // group granularity since threads can only be bound to one group.
6394 if (__kmp_affinity
.type
== affinity_default
) {
6395 __kmp_affinity
.type
= affinity_compact
;
6396 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_intel
;
6398 if (__kmp_hh_affinity
.type
== affinity_default
)
6399 __kmp_hh_affinity
.type
= affinity_compact
;
6400 if (__kmp_affinity_top_method
== affinity_top_method_default
)
6401 __kmp_affinity_top_method
= affinity_top_method_all
;
6402 if (__kmp_affinity
.gran
== KMP_HW_UNKNOWN
)
6403 __kmp_affinity
.gran
= KMP_HW_PROC_GROUP
;
6404 if (__kmp_hh_affinity
.gran
== KMP_HW_UNKNOWN
)
6405 __kmp_hh_affinity
.gran
= KMP_HW_PROC_GROUP
;
6408 #endif /* KMP_GROUP_AFFINITY */
6411 if (__kmp_affinity
.flags
.respect
== affinity_respect_mask_default
) {
6412 #if KMP_GROUP_AFFINITY
6413 if (__kmp_num_proc_groups
> 1 && exactly_one_group
) {
6414 __kmp_affinity
.flags
.respect
= FALSE
;
6416 #endif /* KMP_GROUP_AFFINITY */
6418 __kmp_affinity
.flags
.respect
= TRUE
;
6421 if ((__kmp_nested_proc_bind
.bind_types
[0] != proc_bind_intel
) &&
6422 (__kmp_nested_proc_bind
.bind_types
[0] != proc_bind_default
)) {
6423 if (__kmp_nested_proc_bind
.bind_types
[0] == proc_bind_false
)
6424 __kmp_affinity
.type
= affinity_none
;
6425 if (__kmp_affinity
.type
== affinity_default
) {
6426 __kmp_affinity
.type
= affinity_compact
;
6427 __kmp_affinity
.flags
.dups
= FALSE
;
6429 } else if (__kmp_affinity
.type
== affinity_default
) {
6430 #if KMP_MIC_SUPPORTED
6431 if (__kmp_mic_type
!= non_mic
) {
6432 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_intel
;
6436 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_false
;
6438 #if KMP_MIC_SUPPORTED
6439 if (__kmp_mic_type
!= non_mic
) {
6440 __kmp_affinity
.type
= affinity_scatter
;
6444 __kmp_affinity
.type
= affinity_none
;
6447 if (__kmp_hh_affinity
.type
== affinity_default
)
6448 __kmp_hh_affinity
.type
= affinity_none
;
6449 if ((__kmp_affinity
.gran
== KMP_HW_UNKNOWN
) &&
6450 (__kmp_affinity
.gran_levels
< 0)) {
6451 #if KMP_MIC_SUPPORTED
6452 if (__kmp_mic_type
!= non_mic
) {
6453 __kmp_affinity
.gran
= KMP_HW_THREAD
;
6457 __kmp_affinity
.gran
= KMP_HW_CORE
;
6460 if ((__kmp_hh_affinity
.gran
== KMP_HW_UNKNOWN
) &&
6461 (__kmp_hh_affinity
.gran_levels
< 0)) {
6462 #if KMP_MIC_SUPPORTED
6463 if (__kmp_mic_type
!= non_mic
) {
6464 __kmp_hh_affinity
.gran
= KMP_HW_THREAD
;
6468 __kmp_hh_affinity
.gran
= KMP_HW_CORE
;
6471 if (__kmp_affinity_top_method
== affinity_top_method_default
) {
6472 __kmp_affinity_top_method
= affinity_top_method_all
;
6476 // If affinity is disabled, then still need to assign topology method
6477 // to attempt machine detection and affinity types
6478 if (__kmp_affinity_top_method
== affinity_top_method_default
)
6479 __kmp_affinity_top_method
= affinity_top_method_all
;
6480 if (__kmp_affinity
.type
== affinity_default
)
6481 __kmp_affinity
.type
= affinity_disabled
;
6482 if (__kmp_hh_affinity
.type
== affinity_default
)
6483 __kmp_hh_affinity
.type
= affinity_disabled
;
6487 for (const kmp_affinity_t
*affinity
: __kmp_affinities
)
6488 __kmp_print_affinity_settings(affinity
);
6489 KMP_DEBUG_ASSERT(__kmp_nested_proc_bind
.bind_types
[0] != proc_bind_default
);
6490 K_DIAG(1, ("__kmp_nested_proc_bind.bind_types[0] == %d\n",
6491 __kmp_nested_proc_bind
.bind_types
[0]));
6495 #endif /* KMP_AFFINITY_SUPPORTED */
6497 // Post-initialization step: some env. vars need their value's further
6499 if (string
!= NULL
) { // kmp_set_defaults() was called
6500 __kmp_aux_env_initialize(&block
);
6503 __kmp_env_blk_free(&block
);
6507 } // __kmp_env_initialize
6509 void __kmp_env_print() {
6511 kmp_env_blk_t block
;
6513 kmp_str_buf_t buffer
;
6516 __kmp_str_buf_init(&buffer
);
6518 __kmp_env_blk_init(&block
, NULL
);
6519 __kmp_env_blk_sort(&block
);
6521 // Print real environment values.
6522 __kmp_str_buf_print(&buffer
, "\n%s\n\n", KMP_I18N_STR(UserSettings
));
6523 for (i
= 0; i
< block
.count
; ++i
) {
6524 char const *name
= block
.vars
[i
].name
;
6525 char const *value
= block
.vars
[i
].value
;
6526 if ((KMP_STRLEN(name
) > 4 && strncmp(name
, "KMP_", 4) == 0) ||
6527 strncmp(name
, "OMP_", 4) == 0
6528 #ifdef KMP_GOMP_COMPAT
6529 || strncmp(name
, "GOMP_", 5) == 0
6530 #endif // KMP_GOMP_COMPAT
6532 __kmp_str_buf_print(&buffer
, " %s=%s\n", name
, value
);
6535 __kmp_str_buf_print(&buffer
, "\n");
6537 // Print internal (effective) settings.
6538 __kmp_str_buf_print(&buffer
, "%s\n\n", KMP_I18N_STR(EffectiveSettings
));
6539 for (int i
= 0; i
< __kmp_stg_count
; ++i
) {
6540 if (__kmp_stg_table
[i
].print
!= NULL
) {
6541 __kmp_stg_table
[i
].print(&buffer
, __kmp_stg_table
[i
].name
,
6542 __kmp_stg_table
[i
].data
);
6546 __kmp_printf("%s", buffer
.str
);
6548 __kmp_env_blk_free(&block
);
6549 __kmp_str_buf_free(&buffer
);
6553 } // __kmp_env_print
6555 void __kmp_env_print_2() {
6556 __kmp_display_env_impl(__kmp_display_env
, __kmp_display_env_verbose
);
6557 } // __kmp_env_print_2
6559 void __kmp_display_env_impl(int display_env
, int display_env_verbose
) {
6560 kmp_env_blk_t block
;
6561 kmp_str_buf_t buffer
;
6563 __kmp_env_format
= 1;
6566 __kmp_str_buf_init(&buffer
);
6568 __kmp_env_blk_init(&block
, NULL
);
6569 __kmp_env_blk_sort(&block
);
6571 __kmp_str_buf_print(&buffer
, "\n%s\n", KMP_I18N_STR(DisplayEnvBegin
));
6572 __kmp_str_buf_print(&buffer
, " _OPENMP='%d'\n", __kmp_openmp_version
);
6574 for (int i
= 0; i
< __kmp_stg_count
; ++i
) {
6575 if (__kmp_stg_table
[i
].print
!= NULL
&&
6576 ((display_env
&& strncmp(__kmp_stg_table
[i
].name
, "OMP_", 4) == 0) ||
6577 display_env_verbose
)) {
6578 __kmp_stg_table
[i
].print(&buffer
, __kmp_stg_table
[i
].name
,
6579 __kmp_stg_table
[i
].data
);
6583 __kmp_str_buf_print(&buffer
, "%s\n", KMP_I18N_STR(DisplayEnvEnd
));
6584 __kmp_str_buf_print(&buffer
, "\n");
6586 __kmp_printf("%s", buffer
.str
);
6588 __kmp_env_blk_free(&block
);
6589 __kmp_str_buf_free(&buffer
);
6595 // Dump environment variables for OMPD
6596 void __kmp_env_dump() {
6598 kmp_env_blk_t block
;
6599 kmp_str_buf_t buffer
, env
, notdefined
;
6602 __kmp_str_buf_init(&buffer
);
6603 __kmp_str_buf_init(&env
);
6604 __kmp_str_buf_init(¬defined
);
6606 __kmp_env_blk_init(&block
, NULL
);
6607 __kmp_env_blk_sort(&block
);
6609 __kmp_str_buf_print(¬defined
, ": %s", KMP_I18N_STR(NotDefined
));
6611 for (int i
= 0; i
< __kmp_stg_count
; ++i
) {
6612 if (__kmp_stg_table
[i
].print
== NULL
)
6614 __kmp_str_buf_clear(&env
);
6615 __kmp_stg_table
[i
].print(&env
, __kmp_stg_table
[i
].name
,
6616 __kmp_stg_table
[i
].data
);
6617 if (env
.used
< 4) // valid definition must have indents (3) and a new line
6619 if (strstr(env
.str
, notdefined
.str
))
6620 // normalize the string
6621 __kmp_str_buf_print(&buffer
, "%s=undefined\n", __kmp_stg_table
[i
].name
);
6623 __kmp_str_buf_cat(&buffer
, env
.str
+ 3, env
.used
- 3);
6626 ompd_env_block
= (char *)__kmp_allocate(buffer
.used
+ 1);
6627 KMP_MEMCPY(ompd_env_block
, buffer
.str
, buffer
.used
+ 1);
6628 ompd_env_block_size
= (ompd_size_t
)KMP_STRLEN(ompd_env_block
);
6630 __kmp_env_blk_free(&block
);
6631 __kmp_str_buf_free(&buffer
);
6632 __kmp_str_buf_free(&env
);
6633 __kmp_str_buf_free(¬defined
);
6635 #endif // OMPD_SUPPORT