LLVM OpenMP
kmp_settings.cpp
Go to the documentation of this file.
1/*
2 * kmp_settings.cpp -- Initialize environment variables
3 */
4
5//===----------------------------------------------------------------------===//
6//
7// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
8// See https://llvm.org/LICENSE.txt for license information.
9// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
10//
11//===----------------------------------------------------------------------===//
12
13#include "kmp.h"
14#include "kmp_affinity.h"
15#include "kmp_atomic.h"
16#if KMP_USE_HIER_SCHED
17#include "kmp_dispatch_hier.h"
18#endif
19#include "kmp_device_env.h"
20#include "kmp_environment.h"
21#include "kmp_i18n.h"
22#include "kmp_io.h"
23#include "kmp_itt.h"
24#include "kmp_lock.h"
25#include "kmp_settings.h"
26#include "kmp_str.h"
27#include "kmp_traits.h"
28#include "kmp_wrapper_getpid.h"
29#include <ctype.h> // toupper()
30#if OMPD_SUPPORT
31#include "ompd-specific.h"
32#endif
33
34static int __kmp_env_toPrint(char const *name, int flag);
35
36bool __kmp_env_format = 0; // 0 - old format; 1 - new format
37
38// -----------------------------------------------------------------------------
39// Helper string functions. Subject to move to kmp_str.
40
41#ifdef USE_LOAD_BALANCE
42static double __kmp_convert_to_double(char const *s) {
43 double result;
44
45 if (KMP_SSCANF(s, "%lf", &result) < 1) {
46 result = 0.0;
47 }
48
49 return result;
50}
51#endif
52
53#ifdef KMP_DEBUG
54static unsigned int __kmp_readstr_with_sentinel(char *dest, char const *src,
55 size_t len, char sentinel) {
56 unsigned int i;
57 for (i = 0; i < len; i++) {
58 if ((*src == '\0') || (*src == sentinel)) {
59 break;
60 }
61 *(dest++) = *(src++);
62 }
63 *dest = '\0';
64 return i;
65}
66#endif
67
68static int __kmp_match_with_sentinel(char const *a, char const *b, size_t len,
69 char sentinel) {
70 size_t l = 0;
71
72 if (a == NULL)
73 a = "";
74 if (b == NULL)
75 b = "";
76 while (*a && *b && *b != sentinel) {
77 char ca = *a, cb = *b;
78
79 if (ca >= 'a' && ca <= 'z')
80 ca -= 'a' - 'A';
81 if (cb >= 'a' && cb <= 'z')
82 cb -= 'a' - 'A';
83 if (ca != cb)
84 return FALSE;
85 ++l;
86 ++a;
87 ++b;
88 }
89 return l >= len;
90}
91
92// Expected usage:
93// token is the token to check for.
94// buf is the string being parsed.
95// *end returns the char after the end of the token.
96// it is not modified unless a match occurs.
97//
98// Example 1:
99//
100// if (__kmp_match_str("token", buf, *end) {
101// <do something>
102// buf = end;
103// }
104//
105// Example 2:
106//
107// if (__kmp_match_str("token", buf, *end) {
108// char *save = **end;
109// **end = sentinel;
110// <use any of the __kmp*_with_sentinel() functions>
111// **end = save;
112// buf = end;
113// }
114
115static int __kmp_match_str(char const *token, char const *buf,
116 const char **end) {
117
118 KMP_ASSERT(token != NULL);
119 KMP_ASSERT(buf != NULL);
120 KMP_ASSERT(end != NULL);
121
122 while (*token && *buf) {
123 char ct = *token, cb = *buf;
124
125 if (ct >= 'a' && ct <= 'z')
126 ct -= 'a' - 'A';
127 if (cb >= 'a' && cb <= 'z')
128 cb -= 'a' - 'A';
129 if (ct != cb)
130 return FALSE;
131 ++token;
132 ++buf;
133 }
134 if (*token) {
135 return FALSE;
136 }
137 *end = buf;
138 return TRUE;
139}
140
141#if KMP_OS_DARWIN
142static size_t __kmp_round4k(size_t size) {
143 size_t _4k = 4 * 1024;
144 if (size & (_4k - 1)) {
145 size &= ~(_4k - 1);
146 if (size <= KMP_SIZE_T_MAX - _4k) {
147 size += _4k; // Round up if there is no overflow.
148 }
149 }
150 return size;
151} // __kmp_round4k
152#endif
153
154static int __kmp_strcasecmp_with_sentinel(char const *a, char const *b,
155 char sentinel) {
156 if (a == NULL)
157 a = "";
158 if (b == NULL)
159 b = "";
160 while (*a && *b && *b != sentinel) {
161 char ca = *a, cb = *b;
162
163 if (ca >= 'a' && ca <= 'z')
164 ca -= 'a' - 'A';
165 if (cb >= 'a' && cb <= 'z')
166 cb -= 'a' - 'A';
167 if (ca != cb)
168 return (int)(unsigned char)*a - (int)(unsigned char)*b;
169 ++a;
170 ++b;
171 }
172 return *a ? (*b && *b != sentinel)
173 ? (int)(unsigned char)*a - (int)(unsigned char)*b
174 : 1
175 : (*b && *b != sentinel) ? -1
176 : 0;
177}
178
179// =============================================================================
180// Table structures and helper functions.
181
186
187typedef void (*kmp_stg_parse_func_t)(char const *name, char const *value,
188 void *data);
189typedef void (*kmp_stg_print_func_t)(kmp_str_buf_t *buffer, char const *name,
190 void *data);
191
193 char const *name; // Name of setting (environment variable).
194 kmp_stg_parse_func_t parse; // Parser function.
195 kmp_stg_print_func_t print; // Print function.
196 void *data; // Data passed to parser and printer.
197 int set; // Variable set during this "session"
198 // (__kmp_env_initialize() or kmp_set_defaults() call).
199 int defined; // Variable set in any "session".
200}; // struct __kmp_setting
201
203 size_t factor; // Default factor: 1 for KMP_STACKSIZE, 1024 for others.
204 kmp_setting_t **rivals; // Array of pointers to rivals (including itself).
205}; // struct __kmp_stg_ss_data
206
208 int omp; // 0 -- KMP_LIBRARY, 1 -- OMP_WAIT_POLICY.
209 kmp_setting_t **rivals; // Array of pointers to rivals (including itself).
210}; // struct __kmp_stg_wp_data
211
213 int force; // 0 -- KMP_DETERMINISTIC_REDUCTION, 1 -- KMP_FORCE_REDUCTION.
214 kmp_setting_t **rivals; // Array of pointers to rivals (including itself).
215}; // struct __kmp_stg_fr_data
216
217static int __kmp_stg_check_rivals( // 0 -- Ok, 1 -- errors found.
218 char const *name, // Name of variable.
219 char const *value, // Value of the variable.
220 kmp_setting_t **rivals // List of rival settings (must include current one).
221);
222
223// Helper struct that trims heading/trailing white spaces
226 kmp_trimmed_str_t(const char *str) {
228 size_t len = KMP_STRLEN(str);
229 if (len == 0)
230 return;
231 const char *begin = str;
232 const char *end = str + KMP_STRLEN(str) - 1;
233 SKIP_WS(begin);
234 while (begin < end && *end == ' ')
235 end--;
237 }
239 const char *get() { return buf.str; }
240};
241
242// -----------------------------------------------------------------------------
243// Helper parse functions.
244
245static void __kmp_stg_parse_bool(char const *name, char const *value,
246 int *out) {
248 *out = TRUE;
249 } else if (__kmp_str_match_false(value)) {
250 *out = FALSE;
251 } else {
252 __kmp_msg(kmp_ms_warning, KMP_MSG(BadBoolValue, name, value),
253 KMP_HNT(ValidBoolValues), __kmp_msg_null);
254 }
255} // __kmp_stg_parse_bool
256
257// placed here in order to use __kmp_round4k static function
259 // if system stack size is too big then limit the size for worker threads
260#if KMP_OS_AIX
261 if (*val > KMP_DEFAULT_STKSIZE * 2) // Use 2 times, 16 is too large for AIX.
263#else
264 if (*val > KMP_DEFAULT_STKSIZE * 16) // just a heuristics...
265 *val = KMP_DEFAULT_STKSIZE * 16;
266#endif
269 if (*val > KMP_MAX_STKSIZE)
270 *val = KMP_MAX_STKSIZE; // dead code currently, but may work in future
271#if KMP_OS_DARWIN
272 *val = __kmp_round4k(*val);
273#endif // KMP_OS_DARWIN
274}
275
276static void __kmp_stg_parse_size(char const *name, char const *value,
277 size_t size_min, size_t size_max,
278 int *is_specified, size_t *out,
279 size_t factor) {
280 char const *msg = NULL;
281#if KMP_OS_DARWIN
282 size_min = __kmp_round4k(size_min);
283 size_max = __kmp_round4k(size_max);
284#endif // KMP_OS_DARWIN
285 if (value) {
286 if (is_specified != NULL) {
287 *is_specified = 1;
288 }
289 __kmp_str_to_size(value, out, factor, &msg);
290 if (msg == NULL) {
291 if (*out > size_max) {
292 *out = size_max;
293 msg = KMP_I18N_STR(ValueTooLarge);
294 } else if (*out < size_min) {
295 *out = size_min;
296 msg = KMP_I18N_STR(ValueTooSmall);
297 } else {
298#if KMP_OS_DARWIN
299 size_t round4k = __kmp_round4k(*out);
300 if (*out != round4k) {
301 *out = round4k;
302 msg = KMP_I18N_STR(NotMultiple4K);
303 }
304#endif
305 }
306 } else {
307 // If integer overflow occurred, * out == KMP_SIZE_T_MAX. Cut it to
308 // size_max silently.
309 if (*out < size_min) {
310 *out = size_max;
311 } else if (*out > size_max) {
312 *out = size_max;
313 }
314 }
315 if (msg != NULL) {
316 // Message is not empty. Print warning.
320 KMP_WARNING(ParseSizeIntWarn, name, value, msg);
321 KMP_INFORM(Using_str_Value, name, buf.str);
323 }
324 }
325} // __kmp_stg_parse_size
326
327static void __kmp_stg_parse_str(char const *name, char const *value,
328 char **out) {
329 __kmp_str_free(out);
330 *out = __kmp_str_format("%s", value);
331} // __kmp_stg_parse_str
332
334 char const
335 *name, // I: Name of environment variable (used in warning messages).
336 char const *value, // I: Value of environment variable to parse.
337 int min, // I: Minimum allowed value.
338 int max, // I: Maximum allowed value.
339 int *out // O: Output (parsed) value.
340) {
341 char const *msg = NULL;
342 kmp_uint64 uint = *out;
343 __kmp_str_to_uint(value, &uint, &msg);
344 if (msg == NULL) {
345 if (uint < (unsigned int)min) {
346 msg = KMP_I18N_STR(ValueTooSmall);
347 uint = min;
348 } else if (uint > (unsigned int)max) {
349 msg = KMP_I18N_STR(ValueTooLarge);
350 uint = max;
351 }
352 } else {
353 // If overflow occurred msg contains error message and uint is very big. Cut
354 // tmp it to INT_MAX.
355 if (uint < (unsigned int)min) {
356 uint = min;
357 } else if (uint > (unsigned int)max) {
358 uint = max;
359 }
360 }
361 if (msg != NULL) {
362 // Message is not empty. Print warning.
364 KMP_WARNING(ParseSizeIntWarn, name, value, msg);
366 __kmp_str_buf_print(&buf, "%" KMP_UINT64_SPEC "", uint);
367 KMP_INFORM(Using_uint64_Value, name, buf.str);
369 }
370 __kmp_type_convert(uint, out);
371} // __kmp_stg_parse_int
372
373#if KMP_DEBUG_ADAPTIVE_LOCKS
374static void __kmp_stg_parse_file(char const *name, char const *value,
375 const char *suffix, char **out) {
376 char buffer[256];
377 char *t;
378 int hasSuffix;
379 __kmp_str_free(out);
380 t = (char *)strrchr(value, '.');
381 hasSuffix = t && __kmp_str_eqf(t, suffix);
382 t = __kmp_str_format("%s%s", value, hasSuffix ? "" : suffix);
383 __kmp_expand_file_name(buffer, sizeof(buffer), t);
384 __kmp_str_free(&t);
385 *out = __kmp_str_format("%s", buffer);
386} // __kmp_stg_parse_file
387#endif
388
389#ifdef KMP_DEBUG
390static char *par_range_to_print = NULL;
391
392static void __kmp_stg_parse_par_range(char const *name, char const *value,
393 int *out_range, char *out_routine,
394 char *out_file, int *out_lb,
395 int *out_ub) {
396 const char *par_range_value;
397 size_t len = KMP_STRLEN(value) + 1;
398 par_range_to_print = (char *)KMP_INTERNAL_MALLOC(len + 1);
399 KMP_STRNCPY_S(par_range_to_print, len + 1, value, len + 1);
400 __kmp_par_range = +1;
401 __kmp_par_range_lb = 0;
402 __kmp_par_range_ub = INT_MAX;
403 for (;;) {
404 unsigned int len;
405 if (!value || *value == '\0') {
406 break;
407 }
408 if (!__kmp_strcasecmp_with_sentinel("routine", value, '=')) {
409 par_range_value = strchr(value, '=') + 1;
410 if (!par_range_value)
411 goto par_range_error;
412 value = par_range_value;
413 len = __kmp_readstr_with_sentinel(out_routine, value,
414 KMP_PAR_RANGE_ROUTINE_LEN - 1, ',');
415 if (len == 0) {
416 goto par_range_error;
417 }
418 value = strchr(value, ',');
419 if (value != NULL) {
420 value++;
421 }
422 continue;
423 }
424 if (!__kmp_strcasecmp_with_sentinel("filename", value, '=')) {
425 par_range_value = strchr(value, '=') + 1;
426 if (!par_range_value)
427 goto par_range_error;
428 value = par_range_value;
429 len = __kmp_readstr_with_sentinel(out_file, value,
430 KMP_PAR_RANGE_FILENAME_LEN - 1, ',');
431 if (len == 0) {
432 goto par_range_error;
433 }
434 value = strchr(value, ',');
435 if (value != NULL) {
436 value++;
437 }
438 continue;
439 }
440 if ((!__kmp_strcasecmp_with_sentinel("range", value, '=')) ||
441 (!__kmp_strcasecmp_with_sentinel("incl_range", value, '='))) {
442 par_range_value = strchr(value, '=') + 1;
443 if (!par_range_value)
444 goto par_range_error;
445 value = par_range_value;
446 if (KMP_SSCANF(value, "%d:%d", out_lb, out_ub) != 2) {
447 goto par_range_error;
448 }
449 *out_range = +1;
450 value = strchr(value, ',');
451 if (value != NULL) {
452 value++;
453 }
454 continue;
455 }
456 if (!__kmp_strcasecmp_with_sentinel("excl_range", value, '=')) {
457 par_range_value = strchr(value, '=') + 1;
458 if (!par_range_value)
459 goto par_range_error;
460 value = par_range_value;
461 if (KMP_SSCANF(value, "%d:%d", out_lb, out_ub) != 2) {
462 goto par_range_error;
463 }
464 *out_range = -1;
465 value = strchr(value, ',');
466 if (value != NULL) {
467 value++;
468 }
469 continue;
470 }
471 par_range_error:
472 KMP_WARNING(ParRangeSyntax, name);
473 __kmp_par_range = 0;
474 break;
475 }
476} // __kmp_stg_parse_par_range
477#endif
478
480 int nth = 32;
481
482 /* MIN( MAX( 32, 4 * $OMP_NUM_THREADS, 4 * omp_get_num_procs() ),
483 * __kmp_max_nth) */
484 if (nth < (4 * req_nproc))
485 nth = (4 * req_nproc);
486 if (nth < (4 * __kmp_xproc))
487 nth = (4 * __kmp_xproc);
488
489 // If hidden helper task is enabled, we initialize the thread capacity with
490 // extra __kmp_hidden_helper_threads_num.
493 }
494
495 if (nth > __kmp_max_nth)
496 nth = __kmp_max_nth;
497
498 return nth;
499}
500
501int __kmp_default_tp_capacity(int req_nproc, int max_nth,
502 int all_threads_specified) {
503 int nth = 128;
504
505 if (all_threads_specified)
506 return max_nth;
507 /* MIN( MAX (128, 4 * $OMP_NUM_THREADS, 4 * omp_get_num_procs() ),
508 * __kmp_max_nth ) */
509 if (nth < (4 * req_nproc))
510 nth = (4 * req_nproc);
511 if (nth < (4 * __kmp_xproc))
512 nth = (4 * __kmp_xproc);
513
514 if (nth > __kmp_max_nth)
515 nth = __kmp_max_nth;
516
517 return nth;
518}
519
520// -----------------------------------------------------------------------------
521// Helper print functions.
522
523static void __kmp_stg_print_bool(kmp_str_buf_t *buffer, char const *name,
524 int value) {
525 if (__kmp_env_format) {
527 } else {
528 __kmp_str_buf_print(buffer, " %s=%s\n", name, value ? "true" : "false");
529 }
530} // __kmp_stg_print_bool
531
532static void __kmp_stg_print_int(kmp_str_buf_t *buffer, char const *name,
533 int value) {
534 if (__kmp_env_format) {
536 } else {
537 __kmp_str_buf_print(buffer, " %s=%d\n", name, value);
538 }
539} // __kmp_stg_print_int
540
541static void __kmp_stg_print_uint64(kmp_str_buf_t *buffer, char const *name,
543 if (__kmp_env_format) {
545 } else {
546 __kmp_str_buf_print(buffer, " %s=%" KMP_UINT64_SPEC "\n", name, value);
547 }
548} // __kmp_stg_print_uint64
549
550static void __kmp_stg_print_str(kmp_str_buf_t *buffer, char const *name,
551 char const *value) {
552 if (__kmp_env_format) {
554 } else {
555 __kmp_str_buf_print(buffer, " %s=%s\n", name, value);
556 }
557} // __kmp_stg_print_str
558
559static void __kmp_stg_print_size(kmp_str_buf_t *buffer, char const *name,
560 size_t value) {
561 if (__kmp_env_format) {
564 __kmp_str_buf_print(buffer, "'\n");
565 } else {
566 __kmp_str_buf_print(buffer, " %s=", name);
568 __kmp_str_buf_print(buffer, "\n");
569 return;
570 }
571} // __kmp_stg_print_size
572
573// =============================================================================
574// Parse and print functions.
575
576// -----------------------------------------------------------------------------
577// KMP_DEVICE_THREAD_LIMIT, KMP_ALL_THREADS
578
580 char const *value, void *data) {
581 kmp_setting_t **rivals = (kmp_setting_t **)data;
582 int rc;
583 if (strcmp(name, "KMP_ALL_THREADS") == 0) {
584 KMP_INFORM(EnvVarDeprecated, name, "KMP_DEVICE_THREAD_LIMIT");
585 }
586 rc = __kmp_stg_check_rivals(name, value, rivals);
587 if (rc) {
588 return;
589 }
590 if (!__kmp_strcasecmp_with_sentinel("all", value, 0)) {
593 } else {
596 }
597 K_DIAG(1, ("__kmp_max_nth == %d\n", __kmp_max_nth));
598
599} // __kmp_stg_parse_device_thread_limit
600
602 char const *name, void *data) {
604} // __kmp_stg_print_device_thread_limit
605
606// -----------------------------------------------------------------------------
607// OMP_THREAD_LIMIT
608static void __kmp_stg_parse_thread_limit(char const *name, char const *value,
609 void *data) {
611 K_DIAG(1, ("__kmp_cg_max_nth == %d\n", __kmp_cg_max_nth));
612
613} // __kmp_stg_parse_thread_limit
614
616 char const *name, void *data) {
618} // __kmp_stg_print_thread_limit
619
620// -----------------------------------------------------------------------------
621// OMP_NUM_TEAMS
622static void __kmp_stg_parse_nteams(char const *name, char const *value,
623 void *data) {
625 K_DIAG(1, ("__kmp_nteams == %d\n", __kmp_nteams));
626} // __kmp_stg_parse_nteams
627
628static void __kmp_stg_print_nteams(kmp_str_buf_t *buffer, char const *name,
629 void *data) {
631} // __kmp_stg_print_nteams
632
633// -----------------------------------------------------------------------------
634// OMP_TEAMS_THREAD_LIMIT
635static void __kmp_stg_parse_teams_th_limit(char const *name, char const *value,
636 void *data) {
639 K_DIAG(1, ("__kmp_teams_thread_limit == %d\n", __kmp_teams_thread_limit));
640} // __kmp_stg_parse_teams_th_limit
641
643 char const *name, void *data) {
645} // __kmp_stg_print_teams_th_limit
646
647// -----------------------------------------------------------------------------
648// KMP_TEAMS_THREAD_LIMIT
650 char const *value, void *data) {
652} // __kmp_stg_teams_thread_limit
653
655 char const *name, void *data) {
657} // __kmp_stg_print_teams_thread_limit
658
659// -----------------------------------------------------------------------------
660// KMP_USE_YIELD
661static void __kmp_stg_parse_use_yield(char const *name, char const *value,
662 void *data) {
665} // __kmp_stg_parse_use_yield
666
667static void __kmp_stg_print_use_yield(kmp_str_buf_t *buffer, char const *name,
668 void *data) {
670} // __kmp_stg_print_use_yield
671
672// -----------------------------------------------------------------------------
673// KMP_BLOCKTIME
674
675static void __kmp_stg_parse_blocktime(char const *name, char const *value,
676 void *data) {
677 const char *buf = value;
678 const char *next;
679 const int ms_mult = 1000;
680 int multiplier = 1;
681 int num;
682
683 // Read integer blocktime value
684 SKIP_WS(buf);
685 if ((*buf >= '0') && (*buf <= '9')) {
686 next = buf;
687 SKIP_DIGITS(next);
689 KMP_ASSERT(num >= 0);
690 buf = next;
691 SKIP_WS(buf);
692 } else {
693 num = -1;
694 }
695
696 // Read units: note that __kmp_dflt_blocktime units is now us
697 next = buf;
698 if (*buf == '\0' || __kmp_match_str("ms", buf, &next)) {
699 // units are in ms; convert
700 __kmp_dflt_blocktime = ms_mult * num;
702 multiplier = ms_mult;
703 } else if (__kmp_match_str("us", buf, &next)) {
704 // units are in us
707 } else if (__kmp_match_str("infinite", buf, &next) ||
708 __kmp_match_str("infinity", buf, &next)) {
709 // units are in ms
712 multiplier = ms_mult;
713 } else {
714 KMP_WARNING(StgInvalidValue, name, value);
715 // default units are in ms
716 __kmp_dflt_blocktime = ms_mult * num;
718 multiplier = ms_mult;
719 }
720
721 if (num < 0 && __kmp_dflt_blocktime < 0) { // num out of range
723 __kmp_msg(kmp_ms_warning, KMP_MSG(InvalidValue, name, value),
725 // Inform in appropriate units
726 KMP_INFORM(Using_int_Value, name, __kmp_dflt_blocktime / multiplier);
727 __kmp_env_blocktime = FALSE; // Revert to default as if var not set.
728 } else if (num > 0 && __kmp_dflt_blocktime < 0) { // overflow
731 KMP_INFORM(MaxValueUsing, name, __kmp_dflt_blocktime / multiplier);
732 __kmp_env_blocktime = TRUE; // KMP_BLOCKTIME was specified.
733 } else {
738 KMP_INFORM(MinValueUsing, name, __kmp_dflt_blocktime / multiplier);
743 KMP_INFORM(MaxValueUsing, name, __kmp_dflt_blocktime / multiplier);
744 }
745 __kmp_env_blocktime = TRUE; // KMP_BLOCKTIME was specified.
746 }
747#if KMP_USE_MONITOR
748 // calculate number of monitor thread wakeup intervals corresponding to
749 // blocktime.
750 __kmp_monitor_wakeups =
751 KMP_WAKEUPS_FROM_BLOCKTIME(__kmp_dflt_blocktime, __kmp_monitor_wakeups);
752 __kmp_bt_intervals =
753 KMP_INTERVALS_FROM_BLOCKTIME(__kmp_dflt_blocktime, __kmp_monitor_wakeups);
754#endif
755 K_DIAG(1, ("__kmp_env_blocktime == %d\n", __kmp_env_blocktime));
757 K_DIAG(1, ("__kmp_dflt_blocktime == %d\n", __kmp_dflt_blocktime));
758 }
759} // __kmp_stg_parse_blocktime
760
761static void __kmp_stg_print_blocktime(kmp_str_buf_t *buffer, char const *name,
762 void *data) {
763 int num = __kmp_dflt_blocktime;
764 if (__kmp_blocktime_units == 'm') {
765 num = num / 1000;
766 }
767 if (__kmp_env_format) {
769 } else {
770 __kmp_str_buf_print(buffer, " %s=", name);
771 }
772 __kmp_str_buf_print(buffer, "%d", num);
774} // __kmp_stg_print_blocktime
775
776// -----------------------------------------------------------------------------
777// KMP_DUPLICATE_LIB_OK
778
780 char const *value, void *data) {
781 /* actually this variable is not supported, put here for compatibility with
782 earlier builds and for static/dynamic combination */
784} // __kmp_stg_parse_duplicate_lib_ok
785
787 char const *name, void *data) {
789} // __kmp_stg_print_duplicate_lib_ok
790
791// -----------------------------------------------------------------------------
792// KMP_INHERIT_FP_CONTROL
793
794#if KMP_ARCH_X86 || KMP_ARCH_X86_64
795
796static void __kmp_stg_parse_inherit_fp_control(char const *name,
797 char const *value, void *data) {
798 __kmp_stg_parse_bool(name, value, &__kmp_inherit_fp_control);
799} // __kmp_stg_parse_inherit_fp_control
800
801static void __kmp_stg_print_inherit_fp_control(kmp_str_buf_t *buffer,
802 char const *name, void *data) {
803#if KMP_DEBUG
804 __kmp_stg_print_bool(buffer, name, __kmp_inherit_fp_control);
805#endif /* KMP_DEBUG */
806} // __kmp_stg_print_inherit_fp_control
807
808#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
809
810// Used for OMP_WAIT_POLICY
811static char const *blocktime_str = NULL;
812static char const *use_yield_str = NULL;
813
814// -----------------------------------------------------------------------------
815// KMP_LIBRARY, OMP_WAIT_POLICY
816
817static void __kmp_stg_parse_wait_policy(char const *name, char const *value,
818 void *data) {
819
821 int rc;
822
824 if (rc) {
825 return;
826 }
827
828 if (wait->omp) {
829 if (__kmp_str_match("ACTIVE", 1, value)) {
831 if (blocktime_str == NULL) {
832 // KMP_BLOCKTIME not specified, so set default to "infinite".
834 }
835 if (use_yield_str == NULL) {
836 // KMP_USE_YIELD not specified, so set default to 2.
837 __kmp_use_yield = 2;
838 }
839 } else if (__kmp_str_match("PASSIVE", 1, value)) {
841 __kmp_wpolicy_passive = true; /* allow sleep while active tasking */
842 if (blocktime_str == NULL) {
843 // KMP_BLOCKTIME not specified, so set default to 0.
845 }
846 } else {
847 KMP_WARNING(StgInvalidValue, name, value);
848 }
849 } else {
850 if (__kmp_str_match("serial", 1, value)) { /* S */
852 } else if (__kmp_str_match("throughput", 2, value)) { /* TH */
854 if (blocktime_str == NULL) {
855 // KMP_BLOCKTIME not specified, so set default to 0.
857 }
858 } else if (__kmp_str_match("turnaround", 2, value)) { /* TU */
860 } else if (__kmp_str_match("dedicated", 1, value)) { /* D */
862 } else if (__kmp_str_match("multiuser", 1, value)) { /* M */
864 if (blocktime_str == NULL) {
865 // KMP_BLOCKTIME not specified, so set default to 0.
867 }
868 } else {
869 KMP_WARNING(StgInvalidValue, name, value);
870 }
871 }
872} // __kmp_stg_parse_wait_policy
873
874static void __kmp_stg_print_wait_policy(kmp_str_buf_t *buffer, char const *name,
875 void *data) {
876
878 char const *value = NULL;
879
880 if (wait->omp) {
881 switch (__kmp_library) {
882 case library_turnaround: {
883 value = "ACTIVE";
884 } break;
885 case library_throughput: {
886 value = "PASSIVE";
887 } break;
888 case library_none:
889 case library_serial: {
890 value = NULL;
891 } break;
892 }
893 } else {
894 switch (__kmp_library) {
895 case library_serial: {
896 value = "serial";
897 } break;
898 case library_turnaround: {
899 value = "turnaround";
900 } break;
901 case library_throughput: {
902 value = "throughput";
903 } break;
904 case library_none: {
905 value = NULL;
906 } break;
907 }
908 }
909 if (value != NULL) {
911 }
912
913} // __kmp_stg_print_wait_policy
914
915#if KMP_USE_MONITOR
916// -----------------------------------------------------------------------------
917// KMP_MONITOR_STACKSIZE
918
919static void __kmp_stg_parse_monitor_stacksize(char const *name,
920 char const *value, void *data) {
922 NULL, &__kmp_monitor_stksize, 1);
923} // __kmp_stg_parse_monitor_stacksize
924
925static void __kmp_stg_print_monitor_stacksize(kmp_str_buf_t *buffer,
926 char const *name, void *data) {
927 if (__kmp_env_format) {
928 if (__kmp_monitor_stksize > 0)
930 else
932 } else {
933 __kmp_str_buf_print(buffer, " %s", name);
934 }
935 if (__kmp_monitor_stksize > 0) {
936 __kmp_str_buf_print_size(buffer, __kmp_monitor_stksize);
937 } else {
938 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
939 }
940 if (__kmp_env_format && __kmp_monitor_stksize) {
941 __kmp_str_buf_print(buffer, "'\n");
942 }
943} // __kmp_stg_print_monitor_stacksize
944#endif // KMP_USE_MONITOR
945
946// -----------------------------------------------------------------------------
947// KMP_SETTINGS
948
949static void __kmp_stg_parse_settings(char const *name, char const *value,
950 void *data) {
952} // __kmp_stg_parse_settings
953
954static void __kmp_stg_print_settings(kmp_str_buf_t *buffer, char const *name,
955 void *data) {
957} // __kmp_stg_print_settings
958
959// -----------------------------------------------------------------------------
960// KMP_STACKPAD
961
962static void __kmp_stg_parse_stackpad(char const *name, char const *value,
963 void *data) {
964 __kmp_stg_parse_int(name, // Env var name
965 value, // Env var value
966 KMP_MIN_STKPADDING, // Min value
967 KMP_MAX_STKPADDING, // Max value
968 &__kmp_stkpadding // Var to initialize
969 );
970} // __kmp_stg_parse_stackpad
971
972static void __kmp_stg_print_stackpad(kmp_str_buf_t *buffer, char const *name,
973 void *data) {
975} // __kmp_stg_print_stackpad
976
977// -----------------------------------------------------------------------------
978// KMP_STACKOFFSET
979
980static void __kmp_stg_parse_stackoffset(char const *name, char const *value,
981 void *data) {
982 __kmp_stg_parse_size(name, // Env var name
983 value, // Env var value
984 KMP_MIN_STKOFFSET, // Min value
985 KMP_MAX_STKOFFSET, // Max value
986 NULL, //
987 &__kmp_stkoffset, // Var to initialize
988 1);
989} // __kmp_stg_parse_stackoffset
990
991static void __kmp_stg_print_stackoffset(kmp_str_buf_t *buffer, char const *name,
992 void *data) {
994} // __kmp_stg_print_stackoffset
995
996// -----------------------------------------------------------------------------
997// KMP_STACKSIZE, OMP_STACKSIZE, GOMP_STACKSIZE
998
999static void __kmp_stg_parse_stacksize(char const *name, char const *value,
1000 void *data) {
1001
1003 int rc;
1004
1005 rc = __kmp_stg_check_rivals(name, value, stacksize->rivals);
1006 if (rc) {
1007 return;
1008 }
1009 __kmp_stg_parse_size(name, // Env var name
1010 value, // Env var value
1011 __kmp_sys_min_stksize, // Min value
1012 KMP_MAX_STKSIZE, // Max value
1014 &__kmp_stksize, // Var to initialize
1015 stacksize->factor);
1016
1017} // __kmp_stg_parse_stacksize
1018
1019// This function is called for printing both KMP_STACKSIZE (factor is 1) and
1020// OMP_STACKSIZE (factor is 1024). Currently it is not possible to print
1021// OMP_STACKSIZE value in bytes. We can consider adding this possibility by a
1022// customer request in future.
1023static void __kmp_stg_print_stacksize(kmp_str_buf_t *buffer, char const *name,
1024 void *data) {
1026 if (__kmp_env_format) {
1029 ? __kmp_stksize / stacksize->factor
1030 : __kmp_stksize);
1031 __kmp_str_buf_print(buffer, "'\n");
1032 } else {
1033 __kmp_str_buf_print(buffer, " %s=", name);
1035 ? __kmp_stksize / stacksize->factor
1036 : __kmp_stksize);
1037 __kmp_str_buf_print(buffer, "\n");
1038 }
1039} // __kmp_stg_print_stacksize
1040
1041// -----------------------------------------------------------------------------
1042// KMP_VERSION
1043
1044static void __kmp_stg_parse_version(char const *name, char const *value,
1045 void *data) {
1047} // __kmp_stg_parse_version
1048
1049static void __kmp_stg_print_version(kmp_str_buf_t *buffer, char const *name,
1050 void *data) {
1052} // __kmp_stg_print_version
1053
1054// -----------------------------------------------------------------------------
1055// KMP_WARNINGS
1056
1057static void __kmp_stg_parse_warnings(char const *name, char const *value,
1058 void *data) {
1061 // AC: only 0/1 values documented, so reset to explicit to distinguish from
1062 // default setting
1064 }
1065} // __kmp_stg_parse_warnings
1066
1067static void __kmp_stg_print_warnings(kmp_str_buf_t *buffer, char const *name,
1068 void *data) {
1069 // AC: TODO: change to print_int? (needs documentation change)
1071} // __kmp_stg_print_warnings
1072
1073// -----------------------------------------------------------------------------
1074// KMP_NESTING_MODE
1075
1076static void __kmp_stg_parse_nesting_mode(char const *name, char const *value,
1077 void *data) {
1079#if KMP_HWLOC_ENABLED
1080 if (__kmp_nesting_mode > 0)
1081 __kmp_affinity_top_method = affinity_top_method_hwloc;
1082#endif // KMP_HWLOC_ENABLED
1083} // __kmp_stg_parse_nesting_mode
1084
1086 char const *name, void *data) {
1087 if (__kmp_env_format) {
1089 } else {
1090 __kmp_str_buf_print(buffer, " %s", name);
1091 }
1092 __kmp_str_buf_print(buffer, "=%d\n", __kmp_nesting_mode);
1093} // __kmp_stg_print_nesting_mode
1094
1095// -----------------------------------------------------------------------------
1096// OMP_NESTED, OMP_NUM_THREADS
1097
1098static void __kmp_stg_parse_nested(char const *name, char const *value,
1099 void *data) {
1100 int nested;
1101 KMP_INFORM(EnvVarDeprecated, name, "OMP_MAX_ACTIVE_LEVELS");
1102 __kmp_stg_parse_bool(name, value, &nested);
1103 if (nested) {
1106 } else { // nesting explicitly turned off
1109 }
1110} // __kmp_stg_parse_nested
1111
1112static void __kmp_stg_print_nested(kmp_str_buf_t *buffer, char const *name,
1113 void *data) {
1114 if (__kmp_env_format) {
1116 } else {
1117 __kmp_str_buf_print(buffer, " %s", name);
1118 }
1119 __kmp_str_buf_print(buffer, ": deprecated; max-active-levels-var=%d\n",
1121} // __kmp_stg_print_nested
1122
1123static void __kmp_parse_nested_num_threads(const char *var, const char *env,
1124 kmp_nested_nthreads_t *nth_array) {
1125 const char *next = env;
1126 const char *scan = next;
1127
1128 int total = 0; // Count elements that were set. It'll be used as an array size
1129 int prev_comma = FALSE; // For correct processing sequential commas
1130
1131 // Count the number of values in the env. var string
1132 for (;;) {
1133 SKIP_WS(next);
1134
1135 if (*next == '\0') {
1136 break;
1137 }
1138 // Next character is not an integer or not a comma => end of list
1139 if (((*next < '0') || (*next > '9')) && (*next != ',')) {
1140 KMP_WARNING(NthSyntaxError, var, env);
1141 return;
1142 }
1143 // The next character is ','
1144 if (*next == ',') {
1145 // ',' is the first character
1146 if (total == 0 || prev_comma) {
1147 total++;
1148 }
1149 prev_comma = TRUE;
1150 next++; // skip ','
1151 SKIP_WS(next);
1152 }
1153 // Next character is a digit
1154 if (*next >= '0' && *next <= '9') {
1155 prev_comma = FALSE;
1156 SKIP_DIGITS(next);
1157 total++;
1158 const char *tmp = next;
1159 SKIP_WS(tmp);
1160 if ((*next == ' ' || *next == '\t') && (*tmp >= '0' && *tmp <= '9')) {
1161 KMP_WARNING(NthSpacesNotAllowed, var, env);
1162 return;
1163 }
1164 }
1165 }
1166 if (!__kmp_dflt_max_active_levels_set && total > 1)
1168 if (total <= 0) {
1169 KMP_WARNING(NthSyntaxError, var, env);
1170 return;
1171 }
1172
1173 // Check if the nested nthreads array exists
1174 if (!nth_array->nth) {
1175 // Allocate an array of double size
1176 nth_array->nth = (int *)KMP_INTERNAL_MALLOC(sizeof(int) * total * 2);
1177 if (nth_array->nth == NULL) {
1178 KMP_FATAL(MemoryAllocFailed);
1179 }
1180 nth_array->size = total * 2;
1181 } else {
1182 if (nth_array->size < total) {
1183 // Increase the array size
1184 do {
1185 nth_array->size *= 2;
1186 } while (nth_array->size < total);
1187
1188 nth_array->nth = (int *)KMP_INTERNAL_REALLOC(
1189 nth_array->nth, sizeof(int) * nth_array->size);
1190 if (nth_array->nth == NULL) {
1191 KMP_FATAL(MemoryAllocFailed);
1192 }
1193 }
1194 }
1195 nth_array->used = total;
1196 int i = 0;
1197
1198 prev_comma = FALSE;
1199 total = 0;
1200 // Save values in the array
1201 for (;;) {
1202 SKIP_WS(scan);
1203 if (*scan == '\0') {
1204 break;
1205 }
1206 // The next character is ','
1207 if (*scan == ',') {
1208 // ',' in the beginning of the list
1209 if (total == 0) {
1210 // The value is supposed to be equal to __kmp_avail_proc but it is
1211 // unknown at the moment.
1212 // So let's put a placeholder (#threads = 0) to correct it later.
1213 nth_array->nth[i++] = 0;
1214 total++;
1215 } else if (prev_comma) {
1216 // Num threads is inherited from the previous level
1217 nth_array->nth[i] = nth_array->nth[i - 1];
1218 i++;
1219 total++;
1220 }
1221 prev_comma = TRUE;
1222 scan++; // skip ','
1223 SKIP_WS(scan);
1224 }
1225 // Next character is a digit
1226 if (*scan >= '0' && *scan <= '9') {
1227 int num;
1228 const char *buf = scan;
1229 char const *msg = NULL;
1230 prev_comma = FALSE;
1231 SKIP_DIGITS(scan);
1232 total++;
1233
1234 num = __kmp_str_to_int(buf, *scan);
1235 if (num < KMP_MIN_NTH) {
1236 msg = KMP_I18N_STR(ValueTooSmall);
1237 num = KMP_MIN_NTH;
1238 } else if (num > __kmp_sys_max_nth) {
1239 msg = KMP_I18N_STR(ValueTooLarge);
1240 num = __kmp_sys_max_nth;
1241 }
1242 if (msg != NULL) {
1243 // Message is not empty. Print warning.
1244 KMP_WARNING(ParseSizeIntWarn, var, env, msg);
1245 KMP_INFORM(Using_int_Value, var, num);
1246 }
1247 nth_array->nth[i++] = num;
1248 }
1249 }
1250}
1251
1252static void __kmp_stg_parse_num_threads(char const *name, char const *value,
1253 void *data) {
1254 // TODO: Remove this option. OMP_NUM_THREADS is a list of positive integers!
1255 if (!__kmp_strcasecmp_with_sentinel("all", value, 0)) {
1256 // The array of 1 element
1257 if (!__kmp_nested_nth.nth) {
1258 __kmp_nested_nth.nth = (int *)KMP_INTERNAL_MALLOC(sizeof(int));
1259 __kmp_nested_nth.size = 1;
1260 }
1261 __kmp_nested_nth.used = 1;
1264 } else {
1266 if (__kmp_nested_nth.nth) {
1270 }
1271 }
1272 }
1273 K_DIAG(1, ("__kmp_dflt_team_nth == %d\n", __kmp_dflt_team_nth));
1274} // __kmp_stg_parse_num_threads
1275
1276#if OMP_TASKGRAPH_EXPERIMENTAL
1277static void __kmp_stg_parse_max_tdgs(char const *name, char const *value,
1278 void *data) {
1279 __kmp_stg_parse_int(name, value, 0, INT_MAX, &__kmp_max_tdgs);
1280} // __kmp_stg_parse_max_tdgs
1281
1282static void __kmp_std_print_max_tdgs(kmp_str_buf_t *buffer, char const *name,
1283 void *data) {
1284 __kmp_stg_print_int(buffer, name, __kmp_max_tdgs);
1285} // __kmp_std_print_max_tdgs
1286
1287static void __kmp_stg_parse_tdg_dot(char const *name, char const *value,
1288 void *data) {
1289 __kmp_stg_parse_bool(name, value, &__kmp_tdg_dot);
1290} // __kmp_stg_parse_tdg_dot
1291
1292static void __kmp_stg_print_tdg_dot(kmp_str_buf_t *buffer, char const *name,
1293 void *data) {
1294 __kmp_stg_print_bool(buffer, name, __kmp_tdg_dot);
1295} // __kmp_stg_print_tdg_dot
1296#endif
1297
1299 char const *value,
1300 void *data) {
1302 // If the number of hidden helper threads is zero, we disable hidden helper
1303 // task
1306 } else {
1307 // Since the main thread of hidden helper team does not participate
1308 // in tasks execution let's increment the number of threads by one
1309 // so that requested number of threads do actual job.
1311 }
1312} // __kmp_stg_parse_num_hidden_helper_threads
1313
1315 char const *name,
1316 void *data) {
1319 } else {
1321 // Let's exclude the main thread of hidden helper team and print
1322 // number of worker threads those do actual job.
1324 }
1325} // __kmp_stg_print_num_hidden_helper_threads
1326
1328 char const *value, void *data) {
1330#if !KMP_OS_LINUX
1332 K_DIAG(1,
1333 ("__kmp_stg_parse_use_hidden_helper: Disable hidden helper task on "
1334 "non-Linux platform although it is enabled by user explicitly.\n"));
1335#endif
1336} // __kmp_stg_parse_use_hidden_helper
1337
1339 char const *name, void *data) {
1341} // __kmp_stg_print_use_hidden_helper
1342
1343static void __kmp_stg_print_num_threads(kmp_str_buf_t *buffer, char const *name,
1344 void *data) {
1345 if (__kmp_env_format) {
1347 } else {
1348 __kmp_str_buf_print(buffer, " %s", name);
1349 }
1350 if (__kmp_nested_nth.used) {
1353 for (int i = 0; i < __kmp_nested_nth.used; i++) {
1355 if (i < __kmp_nested_nth.used - 1) {
1356 __kmp_str_buf_print(&buf, ",");
1357 }
1358 }
1359 __kmp_str_buf_print(buffer, "='%s'\n", buf.str);
1361 } else {
1362 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
1363 }
1364} // __kmp_stg_print_num_threads
1365
1366// -----------------------------------------------------------------------------
1367// OpenMP 3.0: KMP_TASKING, OMP_MAX_ACTIVE_LEVELS,
1368
1369static void __kmp_stg_parse_tasking(char const *name, char const *value,
1370 void *data) {
1372 (int *)&__kmp_tasking_mode);
1373 // KMP_TASKING=1 (task barrier) doesn't work anymore, change to task_teams (2)
1375 KMP_WARNING(StgInvalidValue, name, value);
1377 }
1378} // __kmp_stg_parse_tasking
1379
1380static void __kmp_stg_print_tasking(kmp_str_buf_t *buffer, char const *name,
1381 void *data) {
1383} // __kmp_stg_print_tasking
1384
1385static void __kmp_stg_parse_task_stealing(char const *name, char const *value,
1386 void *data) {
1389} // __kmp_stg_parse_task_stealing
1390
1392 char const *name, void *data) {
1394} // __kmp_stg_print_task_stealing
1395
1397 char const *value, void *data) {
1398 kmp_uint64 tmp_dflt = 0;
1399 char const *msg = NULL;
1401 // Don't overwrite __kmp_dflt_max_active_levels if we get an invalid setting
1402 __kmp_str_to_uint(value, &tmp_dflt, &msg);
1403 if (msg != NULL) { // invalid setting; print warning and ignore
1404 KMP_WARNING(ParseSizeIntWarn, name, value, msg);
1405 } else if (tmp_dflt > KMP_MAX_ACTIVE_LEVELS_LIMIT) {
1406 // invalid setting; print warning and ignore
1407 msg = KMP_I18N_STR(ValueTooLarge);
1408 KMP_WARNING(ParseSizeIntWarn, name, value, msg);
1409 } else { // valid setting
1412 }
1413 }
1414} // __kmp_stg_parse_max_active_levels
1415
1417 char const *name, void *data) {
1419} // __kmp_stg_print_max_active_levels
1420
1421// -----------------------------------------------------------------------------
1422// OpenMP 4.0: OMP_DEFAULT_DEVICE
1423static void __kmp_stg_parse_default_device(char const *name, char const *value,
1424 void *data) {
1426 value, /*device_num_min=*/0, KMP_MAX_DEFAULT_DEVICE_LIMIT, name);
1427} // __kmp_stg_parse_default_device
1428
1430 char const *name, void *data) {
1432} // __kmp_stg_print_default_device
1433
1434// -----------------------------------------------------------------------------
1435// OpenMP 5.0: OMP_TARGET_OFFLOAD
1436static void __kmp_stg_parse_target_offload(char const *name, char const *value,
1437 void *data) {
1438 kmp_trimmed_str_t value_str(value);
1439 const char *scan = value_str.get();
1441
1442 if (*scan == '\0')
1443 return;
1444
1445 if (!__kmp_strcasecmp_with_sentinel("mandatory", scan, 0)) {
1447 } else if (!__kmp_strcasecmp_with_sentinel("disabled", scan, 0)) {
1449 } else if (!__kmp_strcasecmp_with_sentinel("default", scan, 0)) {
1451 } else {
1452 KMP_WARNING(SyntaxErrorUsing, name, "DEFAULT");
1453 }
1454} // __kmp_stg_parse_target_offload
1455
1457 char const *name, void *data) {
1458 const char *value = NULL;
1460 value = "DEFAULT";
1462 value = "MANDATORY";
1464 value = "DISABLED";
1466 if (__kmp_env_format) {
1468 } else {
1469 __kmp_str_buf_print(buffer, " %s", name);
1470 }
1471 __kmp_str_buf_print(buffer, "=%s\n", value);
1472} // __kmp_stg_print_target_offload
1473
1474// -----------------------------------------------------------------------------
1475// OpenMP 4.5: OMP_MAX_TASK_PRIORITY
1477 char const *value, void *data) {
1480} // __kmp_stg_parse_max_task_priority
1481
1483 char const *name, void *data) {
1485} // __kmp_stg_print_max_task_priority
1486
1487// KMP_TASKLOOP_MIN_TASKS
1488// taskloop threshold to switch from recursive to linear tasks creation
1490 char const *value, void *data) {
1491 int tmp = 0;
1492 __kmp_stg_parse_int(name, value, 0, INT_MAX, &tmp);
1494} // __kmp_stg_parse_taskloop_min_tasks
1495
1497 char const *name, void *data) {
1499} // __kmp_stg_print_taskloop_min_tasks
1500
1501// -----------------------------------------------------------------------------
1502// KMP_DISP_NUM_BUFFERS
1503static void __kmp_stg_parse_disp_buffers(char const *name, char const *value,
1504 void *data) {
1505 if (TCR_4(__kmp_init_serial)) {
1506 KMP_WARNING(EnvSerialWarn, name);
1507 return;
1508 } // read value before serial initialization only
1511} // __kmp_stg_parse_disp_buffers
1512
1514 char const *name, void *data) {
1516} // __kmp_stg_print_disp_buffers
1517
1518// -----------------------------------------------------------------------------
1519// KMP_HOT_TEAMS_MAX_LEVEL, KMP_HOT_TEAMS_MODE
1520
1521static void __kmp_stg_parse_hot_teams_level(char const *name, char const *value,
1522 void *data) {
1524 KMP_WARNING(EnvParallelWarn, name);
1525 return;
1526 } // read value before first parallel only
1528
1529} // __kmp_stg_parse_hot_teams_level
1530
1532 char const *name, void *data) {
1534} // __kmp_stg_print_hot_teams_level
1535
1536static void __kmp_stg_parse_hot_teams_mode(char const *name, char const *value,
1537 void *data) {
1539 KMP_WARNING(EnvParallelWarn, name);
1540 return;
1541 } // read value before first parallel only
1544} // __kmp_stg_parse_hot_teams_mode
1545
1547 char const *name, void *data) {
1549} // __kmp_stg_print_hot_teams_mode
1550
1551// -----------------------------------------------------------------------------
1552// KMP_HANDLE_SIGNALS
1553
1554#if KMP_HANDLE_SIGNALS
1555
1556static void __kmp_stg_parse_handle_signals(char const *name, char const *value,
1557 void *data) {
1558 __kmp_stg_parse_bool(name, value, &__kmp_handle_signals);
1559} // __kmp_stg_parse_handle_signals
1560
1561static void __kmp_stg_print_handle_signals(kmp_str_buf_t *buffer,
1562 char const *name, void *data) {
1563 __kmp_stg_print_bool(buffer, name, __kmp_handle_signals);
1564} // __kmp_stg_print_handle_signals
1565
1566#endif // KMP_HANDLE_SIGNALS
1567
1568// -----------------------------------------------------------------------------
1569// KMP_X_DEBUG, KMP_DEBUG, KMP_DEBUG_BUF_*, KMP_DIAG
1570
1571#ifdef KMP_DEBUG
1572
1573#define KMP_STG_X_DEBUG(x) \
1574 static void __kmp_stg_parse_##x##_debug(char const *name, char const *value, \
1575 void *data) { \
1576 __kmp_stg_parse_int(name, value, 0, INT_MAX, &kmp_##x##_debug); \
1577 } /* __kmp_stg_parse_x_debug */ \
1578 static void __kmp_stg_print_##x##_debug(kmp_str_buf_t *buffer, \
1579 char const *name, void *data) { \
1580 __kmp_stg_print_int(buffer, name, kmp_##x##_debug); \
1581 } /* __kmp_stg_print_x_debug */
1582
1583KMP_STG_X_DEBUG(a)
1584KMP_STG_X_DEBUG(b)
1585KMP_STG_X_DEBUG(c)
1586KMP_STG_X_DEBUG(d)
1587KMP_STG_X_DEBUG(e)
1588KMP_STG_X_DEBUG(f)
1589
1590#undef KMP_STG_X_DEBUG
1591
1592static void __kmp_stg_parse_debug(char const *name, char const *value,
1593 void *data) {
1594 int debug = 0;
1595 __kmp_stg_parse_int(name, value, 0, INT_MAX, &debug);
1596 if (kmp_a_debug < debug) {
1597 kmp_a_debug = debug;
1598 }
1599 if (kmp_b_debug < debug) {
1600 kmp_b_debug = debug;
1601 }
1602 if (kmp_c_debug < debug) {
1603 kmp_c_debug = debug;
1604 }
1605 if (kmp_d_debug < debug) {
1606 kmp_d_debug = debug;
1607 }
1608 if (kmp_e_debug < debug) {
1609 kmp_e_debug = debug;
1610 }
1611 if (kmp_f_debug < debug) {
1612 kmp_f_debug = debug;
1613 }
1614} // __kmp_stg_parse_debug
1615
1616static void __kmp_stg_parse_debug_buf(char const *name, char const *value,
1617 void *data) {
1619 // !!! TODO: Move buffer initialization of this file! It may works
1620 // incorrectly if KMP_DEBUG_BUF is parsed before KMP_DEBUG_BUF_LINES or
1621 // KMP_DEBUG_BUF_CHARS.
1622 if (__kmp_debug_buf) {
1623 int i;
1625
1626 /* allocate and initialize all entries in debug buffer to empty */
1627 __kmp_debug_buffer = (char *)__kmp_page_allocate(elements * sizeof(char));
1628 for (i = 0; i < elements; i += __kmp_debug_buf_chars)
1629 __kmp_debug_buffer[i] = '\0';
1630
1632 }
1633 K_DIAG(1, ("__kmp_debug_buf = %d\n", __kmp_debug_buf));
1634} // __kmp_stg_parse_debug_buf
1635
1636static void __kmp_stg_print_debug_buf(kmp_str_buf_t *buffer, char const *name,
1637 void *data) {
1639} // __kmp_stg_print_debug_buf
1640
1641static void __kmp_stg_parse_debug_buf_atomic(char const *name,
1642 char const *value, void *data) {
1644} // __kmp_stg_parse_debug_buf_atomic
1645
1646static void __kmp_stg_print_debug_buf_atomic(kmp_str_buf_t *buffer,
1647 char const *name, void *data) {
1649} // __kmp_stg_print_debug_buf_atomic
1650
1651static void __kmp_stg_parse_debug_buf_chars(char const *name, char const *value,
1652 void *data) {
1655} // __kmp_stg_debug_parse_buf_chars
1656
1657static void __kmp_stg_print_debug_buf_chars(kmp_str_buf_t *buffer,
1658 char const *name, void *data) {
1660} // __kmp_stg_print_debug_buf_chars
1661
1662static void __kmp_stg_parse_debug_buf_lines(char const *name, char const *value,
1663 void *data) {
1666} // __kmp_stg_parse_debug_buf_lines
1667
1668static void __kmp_stg_print_debug_buf_lines(kmp_str_buf_t *buffer,
1669 char const *name, void *data) {
1671} // __kmp_stg_print_debug_buf_lines
1672
1673static void __kmp_stg_parse_diag(char const *name, char const *value,
1674 void *data) {
1675 __kmp_stg_parse_int(name, value, 0, INT_MAX, &kmp_diag);
1676} // __kmp_stg_parse_diag
1677
1678static void __kmp_stg_print_diag(kmp_str_buf_t *buffer, char const *name,
1679 void *data) {
1680 __kmp_stg_print_int(buffer, name, kmp_diag);
1681} // __kmp_stg_print_diag
1682
1683#endif // KMP_DEBUG
1684
1685// -----------------------------------------------------------------------------
1686// KMP_ALIGN_ALLOC
1687
1688static void __kmp_stg_parse_align_alloc(char const *name, char const *value,
1689 void *data) {
1690 __kmp_stg_parse_size(name, value, CACHE_LINE, INT_MAX, NULL,
1691 &__kmp_align_alloc, 1);
1692 // Must be power of 2
1694 KMP_WARNING(StgInvalidValue, name, value);
1696 }
1697} // __kmp_stg_parse_align_alloc
1698
1699static void __kmp_stg_print_align_alloc(kmp_str_buf_t *buffer, char const *name,
1700 void *data) {
1702} // __kmp_stg_print_align_alloc
1703
1704// -----------------------------------------------------------------------------
1705// KMP_PLAIN_BARRIER, KMP_FORKJOIN_BARRIER, KMP_REDUCTION_BARRIER
1706
1707// TODO: Remove __kmp_barrier_branch_bit_env_name varibale, remove loops from
1708// parse and print functions, pass required info through data argument.
1709
1711 char const *value, void *data) {
1712 const char *var;
1713
1714 /* ---------- Barrier branch bit control ------------ */
1715 for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {
1717 if ((strcmp(var, name) == 0) && (value != 0)) {
1718 char *comma;
1719
1720 comma = CCAST(char *, strchr(value, ','));
1723 /* is there a specified release parameter? */
1724 if (comma == NULL) {
1726 } else {
1728 (kmp_uint32)__kmp_str_to_int(comma + 1, 0);
1732 KMP_MSG(BarrReleaseValueInvalid, name, comma + 1),
1735 }
1736 }
1739 KMP_WARNING(BarrGatherValueInvalid, name, value);
1740 KMP_INFORM(Using_uint_Value, name, __kmp_barrier_gather_bb_dflt);
1742 }
1743 }
1744 K_DIAG(1, ("%s == %d,%d\n", __kmp_barrier_branch_bit_env_name[i],
1747 }
1748} // __kmp_stg_parse_barrier_branch_bit
1749
1751 char const *name, void *data) {
1752 const char *var;
1753 for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {
1755 if (strcmp(var, name) == 0) {
1756 if (__kmp_env_format) {
1758 } else {
1759 __kmp_str_buf_print(buffer, " %s='",
1761 }
1762 __kmp_str_buf_print(buffer, "%d,%d'\n",
1765 }
1766 }
1767} // __kmp_stg_print_barrier_branch_bit
1768
1769// ----------------------------------------------------------------------------
1770// KMP_PLAIN_BARRIER_PATTERN, KMP_FORKJOIN_BARRIER_PATTERN,
1771// KMP_REDUCTION_BARRIER_PATTERN
1772
1773// TODO: Remove __kmp_barrier_pattern_name variable, remove loops from parse and
1774// print functions, pass required data to functions through data argument.
1775
1776static void __kmp_stg_parse_barrier_pattern(char const *name, char const *value,
1777 void *data) {
1778 const char *var;
1779 /* ---------- Barrier method control ------------ */
1780
1781 static int dist_req = 0, non_dist_req = 0;
1782 static bool warn = 1;
1783 for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {
1785
1786 if ((strcmp(var, name) == 0) && (value != 0)) {
1787 int j;
1788 char *comma = CCAST(char *, strchr(value, ','));
1789
1790 /* handle first parameter: gather pattern */
1791 for (j = bp_linear_bar; j < bp_last_bar; j++) {
1793 ',')) {
1794 if (j == bp_dist_bar) {
1795 dist_req++;
1796 } else {
1797 non_dist_req++;
1798 }
1800 break;
1801 }
1802 }
1803 if (j == bp_last_bar) {
1804 KMP_WARNING(BarrGatherValueInvalid, name, value);
1805 KMP_INFORM(Using_str_Value, name,
1807 }
1808
1809 /* handle second parameter: release pattern */
1810 if (comma != NULL) {
1811 for (j = bp_linear_bar; j < bp_last_bar; j++) {
1812 if (__kmp_str_match(__kmp_barrier_pattern_name[j], 1, comma + 1)) {
1813 if (j == bp_dist_bar) {
1814 dist_req++;
1815 } else {
1816 non_dist_req++;
1817 }
1819 break;
1820 }
1821 }
1822 if (j == bp_last_bar) {
1824 KMP_MSG(BarrReleaseValueInvalid, name, comma + 1),
1826 KMP_INFORM(Using_str_Value, name,
1828 }
1829 }
1830 }
1831 }
1832 if (dist_req != 0) {
1833 // set all barriers to dist
1834 if ((non_dist_req != 0) && warn) {
1835 KMP_INFORM(BarrierPatternOverride, name,
1837 warn = 0;
1838 }
1839 for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {
1844 }
1845 }
1846} // __kmp_stg_parse_barrier_pattern
1847
1849 char const *name, void *data) {
1850 const char *var;
1851 for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {
1853 if (strcmp(var, name) == 0) {
1856 if (__kmp_env_format) {
1858 } else {
1859 __kmp_str_buf_print(buffer, " %s='",
1861 }
1865 }
1866 }
1867} // __kmp_stg_print_barrier_pattern
1868
1869// -----------------------------------------------------------------------------
1870// KMP_ABORT_DELAY
1871
1872static void __kmp_stg_parse_abort_delay(char const *name, char const *value,
1873 void *data) {
1874 // Units of KMP_DELAY_ABORT are seconds, units of __kmp_abort_delay is
1875 // milliseconds.
1876 int delay = __kmp_abort_delay / 1000;
1877 __kmp_stg_parse_int(name, value, 0, INT_MAX / 1000, &delay);
1878 __kmp_abort_delay = delay * 1000;
1879} // __kmp_stg_parse_abort_delay
1880
1881static void __kmp_stg_print_abort_delay(kmp_str_buf_t *buffer, char const *name,
1882 void *data) {
1884} // __kmp_stg_print_abort_delay
1885
1886// -----------------------------------------------------------------------------
1887// KMP_CPUINFO_FILE
1888
1889static void __kmp_stg_parse_cpuinfo_file(char const *name, char const *value,
1890 void *data) {
1891#if KMP_AFFINITY_SUPPORTED
1892 __kmp_stg_parse_str(name, value, &__kmp_cpuinfo_file);
1893 K_DIAG(1, ("__kmp_cpuinfo_file == %s\n", __kmp_cpuinfo_file));
1894#endif
1895} //__kmp_stg_parse_cpuinfo_file
1896
1898 char const *name, void *data) {
1899#if KMP_AFFINITY_SUPPORTED
1900 if (__kmp_env_format) {
1902 } else {
1903 __kmp_str_buf_print(buffer, " %s", name);
1904 }
1905 if (__kmp_cpuinfo_file) {
1906 __kmp_str_buf_print(buffer, "='%s'\n", __kmp_cpuinfo_file);
1907 } else {
1908 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
1909 }
1910#endif
1911} //__kmp_stg_print_cpuinfo_file
1912
1913// -----------------------------------------------------------------------------
1914// KMP_FORCE_REDUCTION, KMP_DETERMINISTIC_REDUCTION
1915
1916static void __kmp_stg_parse_force_reduction(char const *name, char const *value,
1917 void *data) {
1919 int rc;
1920
1921 rc = __kmp_stg_check_rivals(name, value, reduction->rivals);
1922 if (rc) {
1923 return;
1924 }
1925 if (reduction->force) {
1926 if (value != 0) {
1927 if (__kmp_str_match("critical", 0, value))
1929 else if (__kmp_str_match("atomic", 0, value))
1931 else if (__kmp_str_match("tree", 0, value))
1933 else {
1934 KMP_FATAL(UnknownForceReduction, name, value);
1935 }
1936 }
1937 } else {
1939 if (__kmp_determ_red) {
1941 } else {
1943 }
1944 }
1945 K_DIAG(1, ("__kmp_force_reduction_method == %d\n",
1947} // __kmp_stg_parse_force_reduction
1948
1950 char const *name, void *data) {
1951
1953 if (reduction->force) {
1955 __kmp_stg_print_str(buffer, name, "critical");
1957 __kmp_stg_print_str(buffer, name, "atomic");
1959 __kmp_stg_print_str(buffer, name, "tree");
1960 } else {
1961 if (__kmp_env_format) {
1963 } else {
1964 __kmp_str_buf_print(buffer, " %s", name);
1965 }
1966 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
1967 }
1968 } else {
1970 }
1971
1972} // __kmp_stg_print_force_reduction
1973
1974// -----------------------------------------------------------------------------
1975// KMP_STORAGE_MAP
1976
1977static void __kmp_stg_parse_storage_map(char const *name, char const *value,
1978 void *data) {
1979 if (__kmp_str_match("verbose", 1, value)) {
1983
1984 } else {
1987 }
1988} // __kmp_stg_parse_storage_map
1989
1990static void __kmp_stg_print_storage_map(kmp_str_buf_t *buffer, char const *name,
1991 void *data) {
1993 __kmp_stg_print_str(buffer, name, "verbose");
1994 } else {
1996 }
1997} // __kmp_stg_print_storage_map
1998
1999// -----------------------------------------------------------------------------
2000// KMP_ALL_THREADPRIVATE
2001
2003 char const *value, void *data) {
2007} // __kmp_stg_parse_all_threadprivate
2008
2010 char const *name, void *data) {
2012}
2013
2014// -----------------------------------------------------------------------------
2015// KMP_FOREIGN_THREADS_THREADPRIVATE
2016
2018 char const *value,
2019 void *data) {
2021} // __kmp_stg_parse_foreign_threads_threadprivate
2022
2024 char const *name,
2025 void *data) {
2027} // __kmp_stg_print_foreign_threads_threadprivate
2028
2029// -----------------------------------------------------------------------------
2030// KMP_AFFINITY, GOMP_CPU_AFFINITY, KMP_TOPOLOGY_METHOD
2031
2032static inline const char *
2034 switch (type) {
2037 return "unknown";
2038#if KMP_ARCH_X86 || KMP_ARCH_X86_64
2039 case KMP_HW_CORE_TYPE_ATOM:
2040 return "intel_atom";
2041 case KMP_HW_CORE_TYPE_CORE:
2042 return "intel_core";
2043#endif
2044 }
2045 KMP_ASSERT2(false, "Unhandled kmp_hw_core_type_t enumeration");
2047}
2048
2049#if KMP_AFFINITY_SUPPORTED
2050// Parse the proc id list. Return TRUE if successful, FALSE otherwise.
2051static int __kmp_parse_affinity_proc_id_list(const char *var, const char *env,
2052 const char **nextEnv,
2053 char **proclist) {
2054 const char *scan = env;
2055 const char *next = scan;
2056 int empty = TRUE;
2057
2058 *proclist = NULL;
2059
2060 for (;;) {
2061 int start, end, stride;
2062
2063 SKIP_WS(scan);
2064 next = scan;
2065 if (*next == '\0') {
2066 break;
2067 }
2068
2069 if (*next == '{') {
2070 int num;
2071 next++; // skip '{'
2072 SKIP_WS(next);
2073 scan = next;
2074
2075 // Read the first integer in the set.
2076 if ((*next < '0') || (*next > '9')) {
2077 KMP_WARNING(AffSyntaxError, var);
2078 return FALSE;
2079 }
2080 SKIP_DIGITS(next);
2081 num = __kmp_str_to_int(scan, *next);
2082 KMP_ASSERT(num >= 0);
2083
2084 for (;;) {
2085 // Check for end of set.
2086 SKIP_WS(next);
2087 if (*next == '}') {
2088 next++; // skip '}'
2089 break;
2090 }
2091
2092 // Skip optional comma.
2093 if (*next == ',') {
2094 next++;
2095 }
2096 SKIP_WS(next);
2097
2098 // Read the next integer in the set.
2099 scan = next;
2100 if ((*next < '0') || (*next > '9')) {
2101 KMP_WARNING(AffSyntaxError, var);
2102 return FALSE;
2103 }
2104
2105 SKIP_DIGITS(next);
2106 num = __kmp_str_to_int(scan, *next);
2107 KMP_ASSERT(num >= 0);
2108 }
2109 empty = FALSE;
2110
2111 SKIP_WS(next);
2112 if (*next == ',') {
2113 next++;
2114 }
2115 scan = next;
2116 continue;
2117 }
2118
2119 // Next character is not an integer => end of list
2120 if ((*next < '0') || (*next > '9')) {
2121 if (empty) {
2122 KMP_WARNING(AffSyntaxError, var);
2123 return FALSE;
2124 }
2125 break;
2126 }
2127
2128 // Read the first integer.
2129 SKIP_DIGITS(next);
2130 start = __kmp_str_to_int(scan, *next);
2131 KMP_ASSERT(start >= 0);
2132 SKIP_WS(next);
2133
2134 // If this isn't a range, then go on.
2135 if (*next != '-') {
2136 empty = FALSE;
2137
2138 // Skip optional comma.
2139 if (*next == ',') {
2140 next++;
2141 }
2142 scan = next;
2143 continue;
2144 }
2145
2146 // This is a range. Skip over the '-' and read in the 2nd int.
2147 next++; // skip '-'
2148 SKIP_WS(next);
2149 scan = next;
2150 if ((*next < '0') || (*next > '9')) {
2151 KMP_WARNING(AffSyntaxError, var);
2152 return FALSE;
2153 }
2154 SKIP_DIGITS(next);
2155 end = __kmp_str_to_int(scan, *next);
2156 KMP_ASSERT(end >= 0);
2157
2158 // Check for a stride parameter
2159 stride = 1;
2160 SKIP_WS(next);
2161 if (*next == ':') {
2162 // A stride is specified. Skip over the ':" and read the 3rd int.
2163 int sign = +1;
2164 next++; // skip ':'
2165 SKIP_WS(next);
2166 scan = next;
2167 if (*next == '-') {
2168 sign = -1;
2169 next++;
2170 SKIP_WS(next);
2171 scan = next;
2172 }
2173 if ((*next < '0') || (*next > '9')) {
2174 KMP_WARNING(AffSyntaxError, var);
2175 return FALSE;
2176 }
2177 SKIP_DIGITS(next);
2178 stride = __kmp_str_to_int(scan, *next);
2179 KMP_ASSERT(stride >= 0);
2180 stride *= sign;
2181 }
2182
2183 // Do some range checks.
2184 if (stride == 0) {
2185 KMP_WARNING(AffZeroStride, var);
2186 return FALSE;
2187 }
2188 if (stride > 0) {
2189 if (start > end) {
2190 KMP_WARNING(AffStartGreaterEnd, var, start, end);
2191 return FALSE;
2192 }
2193 } else {
2194 if (start < end) {
2195 KMP_WARNING(AffStrideLessZero, var, start, end);
2196 return FALSE;
2197 }
2198 }
2199 if ((end - start) / stride > 65536) {
2200 KMP_WARNING(AffRangeTooBig, var, end, start, stride);
2201 return FALSE;
2202 }
2203
2204 empty = FALSE;
2205
2206 // Skip optional comma.
2207 SKIP_WS(next);
2208 if (*next == ',') {
2209 next++;
2210 }
2211 scan = next;
2212 }
2213
2214 *nextEnv = next;
2215
2216 {
2217 ptrdiff_t len = next - env;
2218 char *retlist = (char *)KMP_INTERNAL_MALLOC((len + 1) * sizeof(char));
2219 KMP_MEMCPY_S(retlist, (len + 1) * sizeof(char), env, len * sizeof(char));
2220 retlist[len] = '\0';
2221 *proclist = retlist;
2222 }
2223 return TRUE;
2224}
2225
2226// If KMP_AFFINITY is specified without a type, then
2227// __kmp_affinity_notype should point to its setting.
2228static kmp_setting_t *__kmp_affinity_notype = NULL;
2229
2230static void __kmp_parse_affinity_env(char const *name, char const *value,
2231 kmp_affinity_t *out_affinity) {
2232 char *buffer = NULL; // Copy of env var value.
2233 char *buf = NULL; // Buffer for strtok_r() function.
2234 char *next = NULL; // end of token / start of next.
2235 const char *start; // start of current token (for err msgs)
2236 int count = 0; // Counter of parsed integer numbers.
2237 int number[2]; // Parsed numbers.
2238
2239 // Guards.
2240 int type = 0;
2241 int proclist = 0;
2242 int verbose = 0;
2243 int warnings = 0;
2244 int respect = 0;
2245 int gran = 0;
2246 int dups = 0;
2247 int reset = 0;
2248 bool set = false;
2249
2250 KMP_ASSERT(value != NULL);
2251
2252 if (TCR_4(__kmp_init_middle)) {
2253 KMP_WARNING(EnvMiddleWarn, name);
2255 return;
2256 }
2258
2259 buffer =
2260 __kmp_str_format("%s", value); // Copy env var to keep original intact.
2261 buf = buffer;
2262 SKIP_WS(buf);
2263
2264// Helper macros.
2265
2266// If we see a parse error, emit a warning and scan to the next ",".
2267//
2268// FIXME - there's got to be a better way to print an error
2269// message, hopefully without overwriting peices of buf.
2270#define EMIT_WARN(skip, errlist) \
2271 { \
2272 char ch; \
2273 if (skip) { \
2274 SKIP_TO(next, ','); \
2275 } \
2276 ch = *next; \
2277 *next = '\0'; \
2278 KMP_WARNING errlist; \
2279 *next = ch; \
2280 if (skip) { \
2281 if (ch == ',') \
2282 next++; \
2283 } \
2284 buf = next; \
2285 }
2286
2287#define _set_param(_guard, _var, _val) \
2288 { \
2289 if (_guard == 0) { \
2290 _var = _val; \
2291 } else { \
2292 EMIT_WARN(FALSE, (AffParamDefined, name, start)); \
2293 } \
2294 ++_guard; \
2295 }
2296
2297#define set_type(val) _set_param(type, out_affinity->type, val)
2298#define set_verbose(val) _set_param(verbose, out_affinity->flags.verbose, val)
2299#define set_warnings(val) \
2300 _set_param(warnings, out_affinity->flags.warnings, val)
2301#define set_respect(val) _set_param(respect, out_affinity->flags.respect, val)
2302#define set_dups(val) _set_param(dups, out_affinity->flags.dups, val)
2303#define set_proclist(val) _set_param(proclist, out_affinity->proclist, val)
2304#define set_reset(val) _set_param(reset, out_affinity->flags.reset, val)
2305
2306#define set_gran(val, levels) \
2307 { \
2308 if (gran == 0) { \
2309 out_affinity->gran = val; \
2310 out_affinity->gran_levels = levels; \
2311 } else { \
2312 EMIT_WARN(FALSE, (AffParamDefined, name, start)); \
2313 } \
2314 ++gran; \
2315 }
2316
2317 KMP_DEBUG_ASSERT((__kmp_nested_proc_bind.bind_types != NULL) &&
2318 (__kmp_nested_proc_bind.used > 0));
2319
2320 while (*buf != '\0') {
2321 start = next = buf;
2322
2323 if (__kmp_match_str("none", buf, CCAST(const char **, &next))) {
2324 set_type(affinity_none);
2326 buf = next;
2327 } else if (__kmp_match_str("scatter", buf, CCAST(const char **, &next))) {
2328 set_type(affinity_scatter);
2330 buf = next;
2331 } else if (__kmp_match_str("compact", buf, CCAST(const char **, &next))) {
2332 set_type(affinity_compact);
2334 buf = next;
2335 } else if (__kmp_match_str("logical", buf, CCAST(const char **, &next))) {
2336 set_type(affinity_logical);
2338 buf = next;
2339 } else if (__kmp_match_str("physical", buf, CCAST(const char **, &next))) {
2340 set_type(affinity_physical);
2342 buf = next;
2343 } else if (__kmp_match_str("explicit", buf, CCAST(const char **, &next))) {
2344 set_type(affinity_explicit);
2346 buf = next;
2347 } else if (__kmp_match_str("balanced", buf, CCAST(const char **, &next))) {
2348 set_type(affinity_balanced);
2350 buf = next;
2351 } else if (__kmp_match_str("disabled", buf, CCAST(const char **, &next))) {
2352 set_type(affinity_disabled);
2354 buf = next;
2355 } else if (__kmp_match_str("verbose", buf, CCAST(const char **, &next))) {
2356 set_verbose(TRUE);
2357 buf = next;
2358 } else if (__kmp_match_str("noverbose", buf, CCAST(const char **, &next))) {
2359 set_verbose(FALSE);
2360 buf = next;
2361 } else if (__kmp_match_str("warnings", buf, CCAST(const char **, &next))) {
2362 set_warnings(TRUE);
2363 buf = next;
2364 } else if (__kmp_match_str("nowarnings", buf,
2365 CCAST(const char **, &next))) {
2366 set_warnings(FALSE);
2367 buf = next;
2368 } else if (__kmp_match_str("respect", buf, CCAST(const char **, &next))) {
2369 set_respect(TRUE);
2370 buf = next;
2371 } else if (__kmp_match_str("norespect", buf, CCAST(const char **, &next))) {
2372 set_respect(FALSE);
2373 buf = next;
2374 } else if (__kmp_match_str("reset", buf, CCAST(const char **, &next))) {
2375 set_reset(TRUE);
2376 buf = next;
2377 } else if (__kmp_match_str("noreset", buf, CCAST(const char **, &next))) {
2378 set_reset(FALSE);
2379 buf = next;
2380 } else if (__kmp_match_str("duplicates", buf,
2381 CCAST(const char **, &next)) ||
2382 __kmp_match_str("dups", buf, CCAST(const char **, &next))) {
2383 set_dups(TRUE);
2384 buf = next;
2385 } else if (__kmp_match_str("noduplicates", buf,
2386 CCAST(const char **, &next)) ||
2387 __kmp_match_str("nodups", buf, CCAST(const char **, &next))) {
2388 set_dups(FALSE);
2389 buf = next;
2390 } else if (__kmp_match_str("granularity", buf,
2391 CCAST(const char **, &next)) ||
2392 __kmp_match_str("gran", buf, CCAST(const char **, &next))) {
2393 SKIP_WS(next);
2394 if (*next != '=') {
2395 EMIT_WARN(TRUE, (AffInvalidParam, name, start));
2396 continue;
2397 }
2398 next++; // skip '='
2399 SKIP_WS(next);
2400
2401 buf = next;
2402
2403 // Have to try core_type and core_efficiency matches first since "core"
2404 // will register as core granularity with "extra chars"
2405 if (__kmp_match_str("core_type", buf, CCAST(const char **, &next))) {
2406 set_gran(KMP_HW_CORE, -1);
2407 out_affinity->flags.core_types_gran = 1;
2408 buf = next;
2409 set = true;
2410 } else if (__kmp_match_str("core_efficiency", buf,
2411 CCAST(const char **, &next)) ||
2412 __kmp_match_str("core_eff", buf,
2413 CCAST(const char **, &next))) {
2414 set_gran(KMP_HW_CORE, -1);
2415 out_affinity->flags.core_effs_gran = 1;
2416 buf = next;
2417 set = true;
2418 }
2419 if (!set) {
2420 // Try any hardware topology type for granularity
2422 const char *name = __kmp_hw_get_keyword(type);
2423 if (__kmp_match_str(name, buf, CCAST(const char **, &next))) {
2424 set_gran(type, -1);
2425 buf = next;
2426 set = true;
2427 break;
2428 }
2429 }
2430 }
2431 if (!set) {
2432 // Support older names for different granularity layers
2433 if (__kmp_match_str("fine", buf, CCAST(const char **, &next))) {
2434 set_gran(KMP_HW_THREAD, -1);
2435 buf = next;
2436 set = true;
2437 } else if (__kmp_match_str("package", buf,
2438 CCAST(const char **, &next))) {
2439 set_gran(KMP_HW_SOCKET, -1);
2440 buf = next;
2441 set = true;
2442 } else if (__kmp_match_str("node", buf, CCAST(const char **, &next))) {
2443 set_gran(KMP_HW_NUMA, -1);
2444 buf = next;
2445 set = true;
2446#if KMP_GROUP_AFFINITY
2447 } else if (__kmp_match_str("group", buf, CCAST(const char **, &next))) {
2448 set_gran(KMP_HW_PROC_GROUP, -1);
2449 buf = next;
2450 set = true;
2451#endif /* KMP_GROUP AFFINITY */
2452 } else if ((*buf >= '0') && (*buf <= '9')) {
2453 int n;
2454 next = buf;
2455 SKIP_DIGITS(next);
2456 n = __kmp_str_to_int(buf, *next);
2457 KMP_ASSERT(n >= 0);
2458 buf = next;
2459 set_gran(KMP_HW_UNKNOWN, n);
2460 set = true;
2461 } else {
2462 EMIT_WARN(TRUE, (AffInvalidParam, name, start));
2463 continue;
2464 }
2465 }
2466 } else if (__kmp_match_str("proclist", buf, CCAST(const char **, &next))) {
2467 char *temp_proclist;
2468
2469 SKIP_WS(next);
2470 if (*next != '=') {
2471 EMIT_WARN(TRUE, (AffInvalidParam, name, start));
2472 continue;
2473 }
2474 next++; // skip '='
2475 SKIP_WS(next);
2476 if (*next != '[') {
2477 EMIT_WARN(TRUE, (AffInvalidParam, name, start));
2478 continue;
2479 }
2480 next++; // skip '['
2481 buf = next;
2482 if (!__kmp_parse_affinity_proc_id_list(
2483 name, buf, CCAST(const char **, &next), &temp_proclist)) {
2484 // warning already emitted.
2485 SKIP_TO(next, ']');
2486 if (*next == ']')
2487 next++;
2488 SKIP_TO(next, ',');
2489 if (*next == ',')
2490 next++;
2491 buf = next;
2492 continue;
2493 }
2494 if (*next != ']') {
2495 EMIT_WARN(TRUE, (AffInvalidParam, name, start));
2496 continue;
2497 }
2498 next++; // skip ']'
2499 set_proclist(temp_proclist);
2500 } else if ((*buf >= '0') && (*buf <= '9')) {
2501 // Parse integer numbers -- permute and offset.
2502 int n;
2503 next = buf;
2504 SKIP_DIGITS(next);
2505 n = __kmp_str_to_int(buf, *next);
2506 KMP_ASSERT(n >= 0);
2507 buf = next;
2508 if (count < 2) {
2509 number[count] = n;
2510 } else {
2511 KMP_WARNING(AffManyParams, name, start);
2512 }
2513 ++count;
2514 } else {
2515 EMIT_WARN(TRUE, (AffInvalidParam, name, start));
2516 continue;
2517 }
2518
2519 SKIP_WS(next);
2520 if (*next == ',') {
2521 next++;
2522 SKIP_WS(next);
2523 } else if (*next != '\0') {
2524 const char *temp = next;
2525 EMIT_WARN(TRUE, (ParseExtraCharsWarn, name, temp));
2526 continue;
2527 }
2528 buf = next;
2529 } // while
2530
2531#undef EMIT_WARN
2532#undef _set_param
2533#undef set_type
2534#undef set_verbose
2535#undef set_warnings
2536#undef set_respect
2537#undef set_granularity
2538#undef set_reset
2539
2540 __kmp_str_free(&buffer);
2541
2542 if (proclist) {
2543 if (!type) {
2544 KMP_WARNING(AffProcListNoType, name);
2545 out_affinity->type = affinity_explicit;
2547 } else if (out_affinity->type != affinity_explicit) {
2548 KMP_WARNING(AffProcListNotExplicit, name);
2549 KMP_ASSERT(out_affinity->proclist != NULL);
2550 KMP_INTERNAL_FREE(out_affinity->proclist);
2551 out_affinity->proclist = NULL;
2552 }
2553 }
2554 switch (out_affinity->type) {
2555 case affinity_logical:
2556 case affinity_physical: {
2557 if (count > 0) {
2558 out_affinity->offset = number[0];
2559 }
2560 if (count > 1) {
2561 KMP_WARNING(AffManyParamsForLogic, name, number[1]);
2562 }
2563 } break;
2564 case affinity_balanced: {
2565 if (count > 0) {
2566 out_affinity->compact = number[0];
2567 }
2568 if (count > 1) {
2569 out_affinity->offset = number[1];
2570 }
2571
2572 if (__kmp_affinity.gran == KMP_HW_UNKNOWN) {
2573 int verbose = out_affinity->flags.verbose;
2574 int warnings = out_affinity->flags.warnings;
2575#if KMP_MIC_SUPPORTED
2576 if (__kmp_mic_type != non_mic) {
2577 if (verbose || warnings) {
2578 KMP_WARNING(AffGranUsing, out_affinity->env_var, "fine");
2579 }
2580 out_affinity->gran = KMP_HW_THREAD;
2581 } else
2582#endif
2583 {
2584 if (verbose || warnings) {
2585 KMP_WARNING(AffGranUsing, out_affinity->env_var, "core");
2586 }
2587 out_affinity->gran = KMP_HW_CORE;
2588 }
2589 }
2590 } break;
2591 case affinity_scatter:
2592 case affinity_compact: {
2593 if (count > 0) {
2594 out_affinity->compact = number[0];
2595 }
2596 if (count > 1) {
2597 out_affinity->offset = number[1];
2598 }
2599 } break;
2600 case affinity_explicit: {
2601 if (out_affinity->proclist == NULL) {
2602 KMP_WARNING(AffNoProcList, name);
2603 out_affinity->type = affinity_none;
2604 }
2605 if (count > 0) {
2606 KMP_WARNING(AffNoParam, name, "explicit");
2607 }
2608 } break;
2609 case affinity_none: {
2610 if (count > 0) {
2611 KMP_WARNING(AffNoParam, name, "none");
2612 }
2613 } break;
2614 case affinity_disabled: {
2615 if (count > 0) {
2616 KMP_WARNING(AffNoParam, name, "disabled");
2617 }
2618 } break;
2619 case affinity_default: {
2620 if (count > 0) {
2621 KMP_WARNING(AffNoParam, name, "default");
2622 }
2623 } break;
2624 default: {
2625 KMP_ASSERT(0);
2626 }
2627 }
2628} // __kmp_parse_affinity_env
2629
2630static void __kmp_stg_parse_affinity(char const *name, char const *value,
2631 void *data) {
2632 kmp_setting_t **rivals = (kmp_setting_t **)data;
2633 int rc;
2634
2635 rc = __kmp_stg_check_rivals(name, value, rivals);
2636 if (rc) {
2637 return;
2638 }
2639
2640 __kmp_parse_affinity_env(name, value, &__kmp_affinity);
2641
2642} // __kmp_stg_parse_affinity
2643static void __kmp_stg_parse_hh_affinity(char const *name, char const *value,
2644 void *data) {
2645 __kmp_parse_affinity_env(name, value, &__kmp_hh_affinity);
2646 // Warn about unused parts of hidden helper affinity settings if specified.
2647 if (__kmp_hh_affinity.flags.reset) {
2648 KMP_WARNING(AffInvalidParam, name, "reset");
2649 }
2650 if (__kmp_hh_affinity.flags.respect != affinity_respect_mask_default) {
2651 KMP_WARNING(AffInvalidParam, name, "respect");
2652 }
2653}
2654
2655static void __kmp_print_affinity_env(kmp_str_buf_t *buffer, char const *name,
2656 const kmp_affinity_t &affinity) {
2657 bool is_hh_affinity = (&affinity == &__kmp_hh_affinity);
2658 if (__kmp_env_format) {
2660 } else {
2661 __kmp_str_buf_print(buffer, " %s='", name);
2662 }
2663 if (affinity.flags.verbose) {
2664 __kmp_str_buf_print(buffer, "%s,", "verbose");
2665 } else {
2666 __kmp_str_buf_print(buffer, "%s,", "noverbose");
2667 }
2668 if (affinity.flags.warnings) {
2669 __kmp_str_buf_print(buffer, "%s,", "warnings");
2670 } else {
2671 __kmp_str_buf_print(buffer, "%s,", "nowarnings");
2672 }
2673 if (KMP_AFFINITY_CAPABLE()) {
2674 // Hidden helper affinity does not affect global reset
2675 // or respect flags. That is still solely controlled by KMP_AFFINITY.
2676 if (!is_hh_affinity) {
2677 if (affinity.flags.respect) {
2678 __kmp_str_buf_print(buffer, "%s,", "respect");
2679 } else {
2680 __kmp_str_buf_print(buffer, "%s,", "norespect");
2681 }
2682 if (affinity.flags.reset) {
2683 __kmp_str_buf_print(buffer, "%s,", "reset");
2684 } else {
2685 __kmp_str_buf_print(buffer, "%s,", "noreset");
2686 }
2687 }
2688 __kmp_str_buf_print(buffer, "granularity=");
2689 if (affinity.flags.core_types_gran)
2690 __kmp_str_buf_print(buffer, "core_type,");
2691 else if (affinity.flags.core_effs_gran) {
2692 __kmp_str_buf_print(buffer, "core_eff,");
2693 } else {
2695 buffer, "%s,", __kmp_hw_get_keyword(affinity.gran, /*plural=*/false));
2696 }
2697 }
2698 if (!KMP_AFFINITY_CAPABLE()) {
2699 __kmp_str_buf_print(buffer, "%s", "disabled");
2700 } else {
2701 int compact = affinity.compact;
2702 int offset = affinity.offset;
2703 switch (affinity.type) {
2704 case affinity_none:
2705 __kmp_str_buf_print(buffer, "%s", "none");
2706 break;
2707 case affinity_physical:
2708 __kmp_str_buf_print(buffer, "%s,%d", "physical", offset);
2709 break;
2710 case affinity_logical:
2711 __kmp_str_buf_print(buffer, "%s,%d", "logical", offset);
2712 break;
2713 case affinity_compact:
2714 __kmp_str_buf_print(buffer, "%s,%d,%d", "compact", compact, offset);
2715 break;
2716 case affinity_scatter:
2717 __kmp_str_buf_print(buffer, "%s,%d,%d", "scatter", compact, offset);
2718 break;
2719 case affinity_explicit:
2720 __kmp_str_buf_print(buffer, "%s=[%s],%s", "proclist", affinity.proclist,
2721 "explicit");
2722 break;
2723 case affinity_balanced:
2724 __kmp_str_buf_print(buffer, "%s,%d,%d", "balanced", compact, offset);
2725 break;
2726 case affinity_disabled:
2727 __kmp_str_buf_print(buffer, "%s", "disabled");
2728 break;
2729 case affinity_default:
2730 __kmp_str_buf_print(buffer, "%s", "default");
2731 break;
2732 default:
2733 __kmp_str_buf_print(buffer, "%s", "<unknown>");
2734 break;
2735 }
2736 }
2737 __kmp_str_buf_print(buffer, "'\n");
2738} //__kmp_stg_print_affinity
2739
2740static void __kmp_stg_print_affinity(kmp_str_buf_t *buffer, char const *name,
2741 void *data) {
2742 __kmp_print_affinity_env(buffer, name, __kmp_affinity);
2743}
2744static void __kmp_stg_print_hh_affinity(kmp_str_buf_t *buffer, char const *name,
2745 void *data) {
2746 __kmp_print_affinity_env(buffer, name, __kmp_hh_affinity);
2747}
2748
2749#ifdef KMP_GOMP_COMPAT
2750
2751static void __kmp_stg_parse_gomp_cpu_affinity(char const *name,
2752 char const *value, void *data) {
2753 const char *next = NULL;
2754 char *temp_proclist;
2755 kmp_setting_t **rivals = (kmp_setting_t **)data;
2756 int rc;
2757
2758 rc = __kmp_stg_check_rivals(name, value, rivals);
2759 if (rc) {
2760 return;
2761 }
2762
2763 if (TCR_4(__kmp_init_middle)) {
2764 KMP_WARNING(EnvMiddleWarn, name);
2766 return;
2767 }
2768
2770
2771 if (__kmp_parse_affinity_proc_id_list(name, value, &next, &temp_proclist)) {
2772 SKIP_WS(next);
2773 if (*next == '\0') {
2774 // GOMP_CPU_AFFINITY => granularity=fine,explicit,proclist=...
2775 __kmp_affinity.proclist = temp_proclist;
2776 __kmp_affinity.type = affinity_explicit;
2777 __kmp_affinity.gran = KMP_HW_THREAD;
2779 } else {
2780 KMP_WARNING(AffSyntaxError, name);
2781 if (temp_proclist != NULL) {
2782 KMP_INTERNAL_FREE((void *)temp_proclist);
2783 }
2784 }
2785 } else {
2786 // Warning already emitted
2787 __kmp_affinity.type = affinity_none;
2789 }
2790} // __kmp_stg_parse_gomp_cpu_affinity
2791
2792#endif /* KMP_GOMP_COMPAT */
2793
2794/*-----------------------------------------------------------------------------
2795The OMP_PLACES proc id list parser. Here is the grammar:
2796
2797place_list := place
2798place_list := place , place_list
2799place := num
2800place := place : num
2801place := place : num : signed
2802place := { subplacelist }
2803place := ! place // (lowest priority)
2804subplace_list := subplace
2805subplace_list := subplace , subplace_list
2806subplace := num
2807subplace := num : num
2808subplace := num : num : signed
2809signed := num
2810signed := + signed
2811signed := - signed
2812-----------------------------------------------------------------------------*/
2813
2814// Return TRUE if successful parse, FALSE otherwise
2815static int __kmp_parse_subplace_list(const char *var, const char **scan) {
2816 const char *next;
2817
2818 for (;;) {
2819 int start, count, stride;
2820
2821 //
2822 // Read in the starting proc id
2823 //
2824 SKIP_WS(*scan);
2825 if ((**scan < '0') || (**scan > '9')) {
2826 return FALSE;
2827 }
2828 next = *scan;
2829 SKIP_DIGITS(next);
2830 start = __kmp_str_to_int(*scan, *next);
2831 KMP_ASSERT(start >= 0);
2832 *scan = next;
2833
2834 // valid follow sets are ',' ':' and '}'
2835 SKIP_WS(*scan);
2836 if (**scan == '}') {
2837 break;
2838 }
2839 if (**scan == ',') {
2840 (*scan)++; // skip ','
2841 continue;
2842 }
2843 if (**scan != ':') {
2844 return FALSE;
2845 }
2846 (*scan)++; // skip ':'
2847
2848 // Read count parameter
2849 SKIP_WS(*scan);
2850 if ((**scan < '0') || (**scan > '9')) {
2851 return FALSE;
2852 }
2853 next = *scan;
2854 SKIP_DIGITS(next);
2855 count = __kmp_str_to_int(*scan, *next);
2856 KMP_ASSERT(count >= 0);
2857 *scan = next;
2858
2859 // valid follow sets are ',' ':' and '}'
2860 SKIP_WS(*scan);
2861 if (**scan == '}') {
2862 break;
2863 }
2864 if (**scan == ',') {
2865 (*scan)++; // skip ','
2866 continue;
2867 }
2868 if (**scan != ':') {
2869 return FALSE;
2870 }
2871 (*scan)++; // skip ':'
2872
2873 // Read stride parameter
2874 int sign = +1;
2875 for (;;) {
2876 SKIP_WS(*scan);
2877 if (**scan == '+') {
2878 (*scan)++; // skip '+'
2879 continue;
2880 }
2881 if (**scan == '-') {
2882 sign *= -1;
2883 (*scan)++; // skip '-'
2884 continue;
2885 }
2886 break;
2887 }
2888 SKIP_WS(*scan);
2889 if ((**scan < '0') || (**scan > '9')) {
2890 return FALSE;
2891 }
2892 next = *scan;
2893 SKIP_DIGITS(next);
2894 stride = __kmp_str_to_int(*scan, *next);
2895 KMP_ASSERT(stride >= 0);
2896 *scan = next;
2897 stride *= sign;
2898
2899 // valid follow sets are ',' and '}'
2900 SKIP_WS(*scan);
2901 if (**scan == '}') {
2902 break;
2903 }
2904 if (**scan == ',') {
2905 (*scan)++; // skip ','
2906 continue;
2907 }
2908 return FALSE;
2909 }
2910 return TRUE;
2911}
2912
2913// Return TRUE if successful parse, FALSE otherwise
2914static int __kmp_parse_place(const char *var, const char **scan) {
2915 const char *next;
2916
2917 // valid follow sets are '{' '!' and num
2918 SKIP_WS(*scan);
2919 if (**scan == '{') {
2920 (*scan)++; // skip '{'
2921 if (!__kmp_parse_subplace_list(var, scan)) {
2922 return FALSE;
2923 }
2924 if (**scan != '}') {
2925 return FALSE;
2926 }
2927 (*scan)++; // skip '}'
2928 } else if (**scan == '!') {
2929 (*scan)++; // skip '!'
2930 return __kmp_parse_place(var, scan); //'!' has lower precedence than ':'
2931 } else if ((**scan >= '0') && (**scan <= '9')) {
2932 next = *scan;
2933 SKIP_DIGITS(next);
2934 int proc = __kmp_str_to_int(*scan, *next);
2935 KMP_ASSERT(proc >= 0);
2936 *scan = next;
2937 } else {
2938 return FALSE;
2939 }
2940 return TRUE;
2941}
2942
2943// Return TRUE if successful parse, FALSE otherwise
2944static int __kmp_parse_place_list(const char *var, const char *env,
2945 char **place_list) {
2946 const char *scan = env;
2947 const char *next = scan;
2948
2949 for (;;) {
2950 int count, stride;
2951
2952 if (!__kmp_parse_place(var, &scan)) {
2953 return FALSE;
2954 }
2955
2956 // valid follow sets are ',' ':' and EOL
2957 SKIP_WS(scan);
2958 if (*scan == '\0') {
2959 break;
2960 }
2961 if (*scan == ',') {
2962 scan++; // skip ','
2963 continue;
2964 }
2965 if (*scan != ':') {
2966 return FALSE;
2967 }
2968 scan++; // skip ':'
2969
2970 // Read count parameter
2971 SKIP_WS(scan);
2972 if ((*scan < '0') || (*scan > '9')) {
2973 return FALSE;
2974 }
2975 next = scan;
2976 SKIP_DIGITS(next);
2977 count = __kmp_str_to_int(scan, *next);
2978 KMP_ASSERT(count >= 0);
2979 scan = next;
2980
2981 // valid follow sets are ',' ':' and EOL
2982 SKIP_WS(scan);
2983 if (*scan == '\0') {
2984 break;
2985 }
2986 if (*scan == ',') {
2987 scan++; // skip ','
2988 continue;
2989 }
2990 if (*scan != ':') {
2991 return FALSE;
2992 }
2993 scan++; // skip ':'
2994
2995 // Read stride parameter
2996 int sign = +1;
2997 for (;;) {
2998 SKIP_WS(scan);
2999 if (*scan == '+') {
3000 scan++; // skip '+'
3001 continue;
3002 }
3003 if (*scan == '-') {
3004 sign *= -1;
3005 scan++; // skip '-'
3006 continue;
3007 }
3008 break;
3009 }
3010 SKIP_WS(scan);
3011 if ((*scan < '0') || (*scan > '9')) {
3012 return FALSE;
3013 }
3014 next = scan;
3015 SKIP_DIGITS(next);
3016 stride = __kmp_str_to_int(scan, *next);
3017 KMP_ASSERT(stride >= 0);
3018 scan = next;
3019 stride *= sign;
3020
3021 // valid follow sets are ',' and EOL
3022 SKIP_WS(scan);
3023 if (*scan == '\0') {
3024 break;
3025 }
3026 if (*scan == ',') {
3027 scan++; // skip ','
3028 continue;
3029 }
3030
3031 return FALSE;
3032 }
3033
3034 {
3035 ptrdiff_t len = scan - env;
3036 char *retlist = (char *)KMP_INTERNAL_MALLOC((len + 1) * sizeof(char));
3037 KMP_MEMCPY_S(retlist, (len + 1) * sizeof(char), env, len * sizeof(char));
3038 retlist[len] = '\0';
3039 *place_list = retlist;
3040 }
3041 return TRUE;
3042}
3043
3044static inline void __kmp_places_set(enum affinity_type type, kmp_hw_t kind) {
3045 __kmp_affinity.type = type;
3046 __kmp_affinity.gran = kind;
3047 __kmp_affinity.flags.dups = FALSE;
3048 __kmp_affinity.flags.omp_places = TRUE;
3049}
3050
3051static void __kmp_places_syntax_error_fallback(char const *name,
3052 kmp_hw_t kind) {
3053 const char *str = __kmp_hw_get_catalog_string(kind, /*plural=*/true);
3054 KMP_WARNING(SyntaxErrorUsing, name, str);
3055 __kmp_places_set(affinity_compact, kind);
3056 if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_default)
3057 __kmp_nested_proc_bind.bind_types[0] = proc_bind_true;
3058}
3059
3060static void __kmp_stg_parse_places(char const *name, char const *value,
3061 void *data) {
3062 struct kmp_place_t {
3063 const char *name;
3064 kmp_hw_t type;
3065 };
3066 int count;
3067 bool set = false;
3068 const char *scan = value;
3069 const char *next = scan;
3070 kmp_place_t std_places[] = {{"threads", KMP_HW_THREAD},
3071 {"cores", KMP_HW_CORE},
3072 {"numa_domains", KMP_HW_NUMA},
3073 {"ll_caches", KMP_HW_LLC},
3074 {"sockets", KMP_HW_SOCKET}};
3075 kmp_setting_t **rivals = (kmp_setting_t **)data;
3076 int rc;
3077
3078 rc = __kmp_stg_check_rivals(name, value, rivals);
3079 if (rc) {
3080 return;
3081 }
3082
3083 // Standard choices
3084 for (size_t i = 0; i < sizeof(std_places) / sizeof(std_places[0]); ++i) {
3085 const kmp_place_t &place = std_places[i];
3086 if (__kmp_match_str(place.name, scan, &next)) {
3087 scan = next;
3088 __kmp_places_set(affinity_compact, place.type);
3089 set = true;
3090 // Parse core attribute if it exists
3091 if (KMP_HW_MAX_NUM_CORE_TYPES > 1) {
3092 SKIP_WS(scan);
3093 if (*scan == ':') {
3094 if (place.type != KMP_HW_CORE) {
3095 __kmp_places_syntax_error_fallback(name, place.type);
3096 return;
3097 }
3098 scan++; // skip ':'
3099 SKIP_WS(scan);
3100#if KMP_ARCH_X86 || KMP_ARCH_X86_64
3101 if (__kmp_match_str("intel_core", scan, &next)) {
3102 __kmp_affinity.core_attr_gran.core_type = KMP_HW_CORE_TYPE_CORE;
3103 __kmp_affinity.core_attr_gran.valid = 1;
3104 scan = next;
3105 } else if (__kmp_match_str("intel_atom", scan, &next)) {
3106 __kmp_affinity.core_attr_gran.core_type = KMP_HW_CORE_TYPE_ATOM;
3107 __kmp_affinity.core_attr_gran.valid = 1;
3108 scan = next;
3109 } else
3110#endif
3111 if (__kmp_match_str("eff", scan, &next)) {
3112 int eff;
3113 if (!isdigit(*next)) {
3114 __kmp_places_syntax_error_fallback(name, place.type);
3115 return;
3116 }
3117 scan = next;
3118 SKIP_DIGITS(next);
3119 eff = __kmp_str_to_int(scan, *next);
3120 if (eff < 0) {
3121 __kmp_places_syntax_error_fallback(name, place.type);
3122 return;
3123 }
3124 if (eff >= KMP_HW_MAX_NUM_CORE_EFFS)
3125 eff = KMP_HW_MAX_NUM_CORE_EFFS - 1;
3126 __kmp_affinity.core_attr_gran.core_eff = eff;
3127 __kmp_affinity.core_attr_gran.valid = 1;
3128 scan = next;
3129 }
3130 if (!__kmp_affinity.core_attr_gran.valid) {
3131 __kmp_places_syntax_error_fallback(name, place.type);
3132 return;
3133 }
3134 }
3135 }
3136 break;
3137 }
3138 }
3139 // Implementation choices for OMP_PLACES based on internal types
3140 if (!set) {
3142 const char *name = __kmp_hw_get_keyword(type, true);
3143 if (__kmp_match_str("unknowns", scan, &next))
3144 continue;
3145 if (__kmp_match_str(name, scan, &next)) {
3146 scan = next;
3147 __kmp_places_set(affinity_compact, type);
3148 set = true;
3149 break;
3150 }
3151 }
3152 }
3153 // Implementation choices for OMP_PLACES based on core attributes
3154 if (!set) {
3155 if (__kmp_match_str("core_types", scan, &next)) {
3156 scan = next;
3157 if (*scan != '\0') {
3158 KMP_WARNING(ParseExtraCharsWarn, name, scan);
3159 }
3160 __kmp_places_set(affinity_compact, KMP_HW_CORE);
3161 __kmp_affinity.flags.core_types_gran = 1;
3162 set = true;
3163 } else if (__kmp_match_str("core_effs", scan, &next) ||
3164 __kmp_match_str("core_efficiencies", scan, &next)) {
3165 scan = next;
3166 if (*scan != '\0') {
3167 KMP_WARNING(ParseExtraCharsWarn, name, scan);
3168 }
3169 __kmp_places_set(affinity_compact, KMP_HW_CORE);
3170 __kmp_affinity.flags.core_effs_gran = 1;
3171 set = true;
3172 }
3173 }
3174 // Explicit place list
3175 if (!set) {
3176 if (__kmp_affinity.proclist != NULL) {
3177 KMP_INTERNAL_FREE((void *)__kmp_affinity.proclist);
3178 __kmp_affinity.proclist = NULL;
3179 }
3180 if (__kmp_parse_place_list(name, value, &__kmp_affinity.proclist)) {
3181 __kmp_places_set(affinity_explicit, KMP_HW_THREAD);
3182 } else {
3183 // Syntax error fallback
3184 __kmp_places_syntax_error_fallback(name, KMP_HW_CORE);
3185 }
3186 if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_default) {
3187 __kmp_nested_proc_bind.bind_types[0] = proc_bind_true;
3188 }
3189 return;
3190 }
3191
3192 kmp_hw_t gran = __kmp_affinity.gran;
3193 if (__kmp_affinity.gran != KMP_HW_UNKNOWN) {
3194 gran = __kmp_affinity.gran;
3195 } else {
3196 gran = KMP_HW_CORE;
3197 }
3198
3199 if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_default) {
3200 __kmp_nested_proc_bind.bind_types[0] = proc_bind_true;
3201 }
3202
3203 SKIP_WS(scan);
3204 if (*scan == '\0') {
3205 return;
3206 }
3207
3208 // Parse option count parameter in parentheses
3209 if (*scan != '(') {
3210 __kmp_places_syntax_error_fallback(name, gran);
3211 return;
3212 }
3213 scan++; // skip '('
3214
3215 SKIP_WS(scan);
3216 next = scan;
3217 SKIP_DIGITS(next);
3218 count = __kmp_str_to_int(scan, *next);
3219 KMP_ASSERT(count >= 0);
3220 scan = next;
3221
3222 SKIP_WS(scan);
3223 if (*scan != ')') {
3224 __kmp_places_syntax_error_fallback(name, gran);
3225 return;
3226 }
3227 scan++; // skip ')'
3228
3229 SKIP_WS(scan);
3230 if (*scan != '\0') {
3231 KMP_WARNING(ParseExtraCharsWarn, name, scan);
3232 }
3234}
3235
3236static void __kmp_stg_print_places(kmp_str_buf_t *buffer, char const *name,
3237 void *data) {
3238 enum affinity_type type = __kmp_affinity.type;
3239 const char *proclist = __kmp_affinity.proclist;
3240 kmp_hw_t gran = __kmp_affinity.gran;
3241
3242 if (__kmp_env_format) {
3244 } else {
3245 __kmp_str_buf_print(buffer, " %s", name);
3246 }
3247 if ((__kmp_nested_proc_bind.used == 0) ||
3248 (__kmp_nested_proc_bind.bind_types == NULL) ||
3249 (__kmp_nested_proc_bind.bind_types[0] == proc_bind_false)) {
3250 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
3251 } else if (type == affinity_explicit) {
3252 if (proclist != NULL) {
3253 __kmp_str_buf_print(buffer, "='%s'\n", proclist);
3254 } else {
3255 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
3256 }
3257 } else if (type == affinity_compact) {
3258 int num;
3259 if (__kmp_affinity.num_masks > 0) {
3260 num = __kmp_affinity.num_masks;
3261 } else if (__kmp_affinity_num_places > 0) {
3263 } else {
3264 num = 0;
3265 }
3266 if (gran != KMP_HW_UNKNOWN) {
3267 // If core_types or core_effs, just print and return
3268 if (__kmp_affinity.flags.core_types_gran) {
3269 __kmp_str_buf_print(buffer, "='%s'\n", "core_types");
3270 return;
3271 }
3272 if (__kmp_affinity.flags.core_effs_gran) {
3273 __kmp_str_buf_print(buffer, "='%s'\n", "core_effs");
3274 return;
3275 }
3276
3277 // threads, cores, sockets, cores:<attribute>, etc.
3278 const char *name = __kmp_hw_get_keyword(gran, true);
3279 __kmp_str_buf_print(buffer, "='%s", name);
3280
3281 // Add core attributes if it exists
3282 if (__kmp_affinity.core_attr_gran.valid) {
3284 (kmp_hw_core_type_t)__kmp_affinity.core_attr_gran.core_type;
3285 int eff = __kmp_affinity.core_attr_gran.core_eff;
3286 if (ct != KMP_HW_CORE_TYPE_UNKNOWN) {
3287 const char *ct_name = __kmp_hw_get_core_type_keyword(ct);
3288 __kmp_str_buf_print(buffer, ":%s", ct_name);
3289 } else if (eff >= 0 && eff < KMP_HW_MAX_NUM_CORE_EFFS) {
3290 __kmp_str_buf_print(buffer, ":eff%d", eff);
3291 }
3292 }
3293
3294 // Add the '(#)' part if it exists
3295 if (num > 0)
3296 __kmp_str_buf_print(buffer, "(%d)", num);
3297 __kmp_str_buf_print(buffer, "'\n");
3298 } else {
3299 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
3300 }
3301 } else {
3302 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
3303 }
3304}
3305
3306static void __kmp_stg_parse_topology_method(char const *name, char const *value,
3307 void *data) {
3308 if (__kmp_str_match("all", 1, value)) {
3309 __kmp_affinity_top_method = affinity_top_method_all;
3310 }
3311#if KMP_HWLOC_ENABLED
3312 else if (__kmp_str_match("hwloc", 1, value)) {
3313 __kmp_affinity_top_method = affinity_top_method_hwloc;
3314 }
3315#endif // KMP_HWLOC_ENABLED
3316#if KMP_ARCH_X86 || KMP_ARCH_X86_64
3317 else if (__kmp_str_match("cpuid_leaf31", 12, value) ||
3318 __kmp_str_match("cpuid 1f", 8, value) ||
3319 __kmp_str_match("cpuid 31", 8, value) ||
3320 __kmp_str_match("cpuid1f", 7, value) ||
3321 __kmp_str_match("cpuid31", 7, value) ||
3322 __kmp_str_match("leaf 1f", 7, value) ||
3323 __kmp_str_match("leaf 31", 7, value) ||
3324 __kmp_str_match("leaf1f", 6, value) ||
3325 __kmp_str_match("leaf31", 6, value)) {
3326 __kmp_affinity_top_method = affinity_top_method_x2apicid_1f;
3327 } else if (__kmp_str_match("x2apic id", 9, value) ||
3328 __kmp_str_match("x2apic_id", 9, value) ||
3329 __kmp_str_match("x2apic-id", 9, value) ||
3330 __kmp_str_match("x2apicid", 8, value) ||
3331 __kmp_str_match("cpuid leaf 11", 13, value) ||
3332 __kmp_str_match("cpuid_leaf_11", 13, value) ||
3333 __kmp_str_match("cpuid-leaf-11", 13, value) ||
3334 __kmp_str_match("cpuid leaf11", 12, value) ||
3335 __kmp_str_match("cpuid_leaf11", 12, value) ||
3336 __kmp_str_match("cpuid-leaf11", 12, value) ||
3337 __kmp_str_match("cpuidleaf 11", 12, value) ||
3338 __kmp_str_match("cpuidleaf_11", 12, value) ||
3339 __kmp_str_match("cpuidleaf-11", 12, value) ||
3340 __kmp_str_match("cpuidleaf11", 11, value) ||
3341 __kmp_str_match("cpuid 11", 8, value) ||
3342 __kmp_str_match("cpuid_11", 8, value) ||
3343 __kmp_str_match("cpuid-11", 8, value) ||
3344 __kmp_str_match("cpuid11", 7, value) ||
3345 __kmp_str_match("leaf 11", 7, value) ||
3346 __kmp_str_match("leaf_11", 7, value) ||
3347 __kmp_str_match("leaf-11", 7, value) ||
3348 __kmp_str_match("leaf11", 6, value)) {
3349 __kmp_affinity_top_method = affinity_top_method_x2apicid;
3350 } else if (__kmp_str_match("apic id", 7, value) ||
3351 __kmp_str_match("apic_id", 7, value) ||
3352 __kmp_str_match("apic-id", 7, value) ||
3353 __kmp_str_match("apicid", 6, value) ||
3354 __kmp_str_match("cpuid leaf 4", 12, value) ||
3355 __kmp_str_match("cpuid_leaf_4", 12, value) ||
3356 __kmp_str_match("cpuid-leaf-4", 12, value) ||
3357 __kmp_str_match("cpuid leaf4", 11, value) ||
3358 __kmp_str_match("cpuid_leaf4", 11, value) ||
3359 __kmp_str_match("cpuid-leaf4", 11, value) ||
3360 __kmp_str_match("cpuidleaf 4", 11, value) ||
3361 __kmp_str_match("cpuidleaf_4", 11, value) ||
3362 __kmp_str_match("cpuidleaf-4", 11, value) ||
3363 __kmp_str_match("cpuidleaf4", 10, value) ||
3364 __kmp_str_match("cpuid 4", 7, value) ||
3365 __kmp_str_match("cpuid_4", 7, value) ||
3366 __kmp_str_match("cpuid-4", 7, value) ||
3367 __kmp_str_match("cpuid4", 6, value) ||
3368 __kmp_str_match("leaf 4", 6, value) ||
3369 __kmp_str_match("leaf_4", 6, value) ||
3370 __kmp_str_match("leaf-4", 6, value) ||
3371 __kmp_str_match("leaf4", 5, value)) {
3372 __kmp_affinity_top_method = affinity_top_method_apicid;
3373 }
3374#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
3375 else if (__kmp_str_match("/proc/cpuinfo", 2, value) ||
3376 __kmp_str_match("cpuinfo", 5, value)) {
3377 __kmp_affinity_top_method = affinity_top_method_cpuinfo;
3378 }
3379#if KMP_GROUP_AFFINITY
3380 else if (__kmp_str_match("group", 1, value)) {
3381 KMP_WARNING(StgDeprecatedValue, name, value, "all");
3382 __kmp_affinity_top_method = affinity_top_method_group;
3383 }
3384#endif /* KMP_GROUP_AFFINITY */
3385 else if (__kmp_str_match("flat", 1, value)) {
3386 __kmp_affinity_top_method = affinity_top_method_flat;
3387 } else {
3388 KMP_WARNING(StgInvalidValue, name, value);
3389 }
3390} // __kmp_stg_parse_topology_method
3391
3392static void __kmp_stg_print_topology_method(kmp_str_buf_t *buffer,
3393 char const *name, void *data) {
3394 char const *value = NULL;
3395
3396 switch (__kmp_affinity_top_method) {
3397 case affinity_top_method_default:
3398 value = "default";
3399 break;
3400
3401 case affinity_top_method_all:
3402 value = "all";
3403 break;
3404
3405#if KMP_ARCH_X86 || KMP_ARCH_X86_64
3406 case affinity_top_method_x2apicid_1f:
3407 value = "x2APIC id leaf 0x1f";
3408 break;
3409
3410 case affinity_top_method_x2apicid:
3411 value = "x2APIC id leaf 0xb";
3412 break;
3413
3414 case affinity_top_method_apicid:
3415 value = "APIC id";
3416 break;
3417#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
3418
3419#if KMP_HWLOC_ENABLED
3420 case affinity_top_method_hwloc:
3421 value = "hwloc";
3422 break;
3423#endif // KMP_HWLOC_ENABLED
3424
3425 case affinity_top_method_cpuinfo:
3426 value = "cpuinfo";
3427 break;
3428
3429#if KMP_GROUP_AFFINITY
3430 case affinity_top_method_group:
3431 value = "group";
3432 break;
3433#endif /* KMP_GROUP_AFFINITY */
3434
3435 case affinity_top_method_flat:
3436 value = "flat";
3437 break;
3438 }
3439
3440 if (value != NULL) {
3441 __kmp_stg_print_str(buffer, name, value);
3442 }
3443} // __kmp_stg_print_topology_method
3444
3445// KMP_TEAMS_PROC_BIND
3446struct kmp_proc_bind_info_t {
3447 const char *name;
3448 kmp_proc_bind_t proc_bind;
3449};
3450static kmp_proc_bind_info_t proc_bind_table[] = {
3451 {"spread", proc_bind_spread},
3452 {"true", proc_bind_spread},
3453 {"close", proc_bind_close},
3454 // teams-bind = false means "replicate the primary thread's affinity"
3455 {"false", proc_bind_primary},
3456 {"primary", proc_bind_primary}};
3457static void __kmp_stg_parse_teams_proc_bind(char const *name, char const *value,
3458 void *data) {
3459 int valid;
3460 const char *end;
3461 valid = 0;
3462 for (size_t i = 0; i < sizeof(proc_bind_table) / sizeof(proc_bind_table[0]);
3463 ++i) {
3464 if (__kmp_match_str(proc_bind_table[i].name, value, &end)) {
3465 __kmp_teams_proc_bind = proc_bind_table[i].proc_bind;
3466 valid = 1;
3467 break;
3468 }
3469 }
3470 if (!valid) {
3471 KMP_WARNING(StgInvalidValue, name, value);
3472 }
3473}
3474static void __kmp_stg_print_teams_proc_bind(kmp_str_buf_t *buffer,
3475 char const *name, void *data) {
3476 const char *value = KMP_I18N_STR(NotDefined);
3477 for (size_t i = 0; i < sizeof(proc_bind_table) / sizeof(proc_bind_table[0]);
3478 ++i) {
3479 if (__kmp_teams_proc_bind == proc_bind_table[i].proc_bind) {
3480 value = proc_bind_table[i].name;
3481 break;
3482 }
3483 }
3484 __kmp_stg_print_str(buffer, name, value);
3485}
3486#endif /* KMP_AFFINITY_SUPPORTED */
3487
3488// OMP_PROC_BIND / bind-var is functional on all 4.0 builds, including OS X*
3489// OMP_PLACES / place-partition-var is not.
3490static void __kmp_stg_parse_proc_bind(char const *name, char const *value,
3491 void *data) {
3492 kmp_setting_t **rivals = (kmp_setting_t **)data;
3493 int rc;
3494
3495 rc = __kmp_stg_check_rivals(name, value, rivals);
3496 if (rc) {
3497 return;
3498 }
3499
3500 // In OMP 4.0 OMP_PROC_BIND is a vector of proc_bind types.
3501 KMP_DEBUG_ASSERT((__kmp_nested_proc_bind.bind_types != NULL) &&
3502 (__kmp_nested_proc_bind.used > 0));
3503
3504 const char *buf = value;
3505 const char *next;
3506
3507 SKIP_WS(buf);
3508
3509 next = buf;
3510 if (__kmp_match_str("disabled", buf, &next)) {
3511 buf = next;
3512 SKIP_WS(buf);
3513#if KMP_AFFINITY_SUPPORTED
3514 __kmp_affinity.type = affinity_disabled;
3515#endif /* KMP_AFFINITY_SUPPORTED */
3516 __kmp_nested_proc_bind.used = 1;
3518 } else if (__kmp_match_str("false", buf, &next)) {
3519 buf = next;
3520 SKIP_WS(buf);
3521#if KMP_AFFINITY_SUPPORTED
3522 __kmp_affinity.type = affinity_none;
3523#endif /* KMP_AFFINITY_SUPPORTED */
3524 __kmp_nested_proc_bind.used = 1;
3526 } else if (__kmp_match_str("true", buf, &next)) {
3527 buf = next;
3528 SKIP_WS(buf);
3529 __kmp_nested_proc_bind.used = 1;
3530 __kmp_nested_proc_bind.bind_types[0] = proc_bind_true;
3531 } else {
3532 // Count the number of values in the env var string
3533 const char *scan;
3534 int nelem = 1;
3535 for (scan = buf; *scan != '\0'; scan++) {
3536 if (*scan == ',') {
3537 nelem++;
3538 }
3539 }
3540
3541 // Create / expand the nested proc_bind array as needed
3542 if (__kmp_nested_proc_bind.size < nelem) {
3543 __kmp_nested_proc_bind.bind_types =
3545 __kmp_nested_proc_bind.bind_types,
3546 sizeof(kmp_proc_bind_t) * nelem);
3547 if (__kmp_nested_proc_bind.bind_types == NULL) {
3548 KMP_FATAL(MemoryAllocFailed);
3549 }
3550 __kmp_nested_proc_bind.size = nelem;
3551 }
3552 __kmp_nested_proc_bind.used = nelem;
3553
3554 if (nelem > 1 && !__kmp_dflt_max_active_levels_set)
3556
3557 // Save values in the nested proc_bind array
3558 int i = 0;
3559 for (;;) {
3560 enum kmp_proc_bind_t bind;
3561
3562 if (__kmp_match_str("master", buf, &next) ||
3563 __kmp_match_str("primary", buf, &next)) {
3564 buf = next;
3565 SKIP_WS(buf);
3566 bind = proc_bind_primary;
3567 } else if (__kmp_match_str("close", buf, &next)) {
3568 buf = next;
3569 SKIP_WS(buf);
3570 bind = proc_bind_close;
3571 } else if (__kmp_match_str("spread", buf, &next)) {
3572 buf = next;
3573 SKIP_WS(buf);
3574 bind = proc_bind_spread;
3575 } else {
3576 KMP_WARNING(StgInvalidValue, name, value);
3578 __kmp_nested_proc_bind.used = 1;
3579 return;
3580 }
3581
3582 __kmp_nested_proc_bind.bind_types[i++] = bind;
3583 if (i >= nelem) {
3584 break;
3585 }
3586 if (*buf != ',') {
3587 KMP_WARNING(ParseExtraCharsWarn, name, buf);
3588 while (*buf != ',')
3589 buf++;
3590 }
3591 buf++;
3592 SKIP_WS(buf);
3593 }
3594 SKIP_WS(buf);
3595 }
3596 if (*buf != '\0') {
3597 KMP_WARNING(ParseExtraCharsWarn, name, buf);
3598 }
3599}
3600
3601static void __kmp_stg_print_proc_bind(kmp_str_buf_t *buffer, char const *name,
3602 void *data) {
3603 int nelem = __kmp_nested_proc_bind.used;
3604 if (__kmp_env_format) {
3606 } else {
3607 __kmp_str_buf_print(buffer, " %s", name);
3608 }
3609 if (nelem == 0) {
3610 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
3611 } else {
3612 int i;
3613 __kmp_str_buf_print(buffer, "='", name);
3614 for (i = 0; i < nelem; i++) {
3615 switch (__kmp_nested_proc_bind.bind_types[i]) {
3616 case proc_bind_false:
3617 __kmp_str_buf_print(buffer, "false");
3618 break;
3619
3620 case proc_bind_true:
3621 __kmp_str_buf_print(buffer, "true");
3622 break;
3623
3624 case proc_bind_primary:
3625 __kmp_str_buf_print(buffer, "primary");
3626 break;
3627
3628 case proc_bind_close:
3629 __kmp_str_buf_print(buffer, "close");
3630 break;
3631
3632 case proc_bind_spread:
3633 __kmp_str_buf_print(buffer, "spread");
3634 break;
3635
3636 case proc_bind_intel:
3637 __kmp_str_buf_print(buffer, "intel");
3638 break;
3639
3640 case proc_bind_default:
3641 __kmp_str_buf_print(buffer, "default");
3642 break;
3643 }
3644 if (i < nelem - 1) {
3645 __kmp_str_buf_print(buffer, ",");
3646 }
3647 }
3648 __kmp_str_buf_print(buffer, "'\n");
3649 }
3650}
3651
3653 char const *value, void *data) {
3655}
3657 char const *name, void *data) {
3659}
3660static void __kmp_stg_parse_affinity_format(char const *name, char const *value,
3661 void *data) {
3662 size_t length = KMP_STRLEN(value);
3664 length);
3665}
3667 char const *name, void *data) {
3668 if (__kmp_env_format) {
3670 } else {
3671 __kmp_str_buf_print(buffer, " %s='", name);
3672 }
3674}
3675
3676/*-----------------------------------------------------------------------------
3677OMP_ALLOCATOR sets default allocator. Here is the grammar:
3678
3679<allocator> |= <predef-allocator> | <predef-mem-space> |
3680 <predef-mem-space>:<traits>
3681<traits> |= <trait>=<value> | <trait>=<value>,<traits>
3682<predef-allocator> |= omp_default_mem_alloc | omp_large_cap_mem_alloc |
3683 omp_const_mem_alloc | omp_high_bw_mem_alloc |
3684 omp_low_lat_mem_alloc | omp_cgroup_mem_alloc |
3685 omp_pteam_mem_alloc | omp_thread_mem_alloc
3686<predef-mem-space> |= omp_default_mem_space | omp_large_cap_mem_space |
3687 omp_const_mem_space | omp_high_bw_mem_space |
3688 omp_low_lat_mem_space
3689<trait> |= sync_hint | alignment | access | pool_size | fallback |
3690 fb_data | pinned | partition
3691<value> |= one of the allowed values of trait |
3692 non-negative integer | <predef-allocator>
3693-----------------------------------------------------------------------------*/
3694
3695static void __kmp_stg_parse_allocator(char const *name, char const *value,
3696 void *data) {
3697 const char *buf = value;
3698 const char *next, *scan, *start;
3699 char *key;
3702 bool is_memspace = false;
3703 int ntraits = 0, count = 0;
3704
3705 SKIP_WS(buf);
3706 next = buf;
3707 const char *delim = strchr(buf, ':');
3708 const char *predef_mem_space = strstr(buf, "mem_space");
3709
3710 bool is_memalloc = (!predef_mem_space && !delim) ? true : false;
3711
3712 // Count the number of traits in the env var string
3713 if (delim) {
3714 ntraits = 1;
3715 for (scan = buf; *scan != '\0'; scan++) {
3716 if (*scan == ',')
3717 ntraits++;
3718 }
3719 }
3720 omp_alloctrait_t *traits =
3721 (omp_alloctrait_t *)KMP_ALLOCA(ntraits * sizeof(omp_alloctrait_t));
3722
3723// Helper macros
3724#define IS_POWER_OF_TWO(n) (((n) & ((n)-1)) == 0)
3725
3726#define GET_NEXT(sentinel) \
3727 { \
3728 SKIP_WS(next); \
3729 if (*next == sentinel) \
3730 next++; \
3731 SKIP_WS(next); \
3732 scan = next; \
3733 }
3734
3735#define SKIP_PAIR(key) \
3736 { \
3737 char const str_delimiter[] = {',', 0}; \
3738 char *value = __kmp_str_token(CCAST(char *, scan), str_delimiter, \
3739 CCAST(char **, &next)); \
3740 KMP_WARNING(StgInvalidValue, key, value); \
3741 ntraits--; \
3742 SKIP_WS(next); \
3743 scan = next; \
3744 }
3745
3746#define SET_KEY() \
3747 { \
3748 char const str_delimiter[] = {'=', 0}; \
3749 key = __kmp_str_token(CCAST(char *, start), str_delimiter, \
3750 CCAST(char **, &next)); \
3751 scan = next; \
3752 }
3753
3754 scan = next;
3755 while (*next != '\0') {
3756 if (is_memalloc ||
3757 __kmp_match_str("fb_data", scan, &next)) { // allocator check
3758 start = scan;
3759 GET_NEXT('=');
3760 // check HBW and LCAP first as the only non-default supported
3761 if (__kmp_match_str("omp_high_bw_mem_alloc", scan, &next)) {
3762 SKIP_WS(next);
3763 if (is_memalloc) {
3766 return;
3767 } else {
3768 KMP_WARNING(OmpNoAllocator, "omp_high_bw_mem_alloc");
3769 }
3770 } else {
3771 traits[count].key = omp_atk_fb_data;
3773 }
3774 } else if (__kmp_match_str("omp_large_cap_mem_alloc", scan, &next)) {
3775 SKIP_WS(next);
3776 if (is_memalloc) {
3779 return;
3780 } else {
3781 KMP_WARNING(OmpNoAllocator, "omp_large_cap_mem_alloc");
3782 }
3783 } else {
3784 traits[count].key = omp_atk_fb_data;
3786 }
3787 } else if (__kmp_match_str("omp_default_mem_alloc", scan, &next)) {
3788 // default requested
3789 SKIP_WS(next);
3790 if (!is_memalloc) {
3791 traits[count].key = omp_atk_fb_data;
3793 }
3794 } else if (__kmp_match_str("omp_const_mem_alloc", scan, &next)) {
3795 SKIP_WS(next);
3796 if (is_memalloc) {
3797 KMP_WARNING(OmpNoAllocator, "omp_const_mem_alloc");
3798 } else {
3799 traits[count].key = omp_atk_fb_data;
3801 }
3802 } else if (__kmp_match_str("omp_low_lat_mem_alloc", scan, &next)) {
3803 SKIP_WS(next);
3804 if (is_memalloc) {
3805 KMP_WARNING(OmpNoAllocator, "omp_low_lat_mem_alloc");
3806 } else {
3807 traits[count].key = omp_atk_fb_data;
3809 }
3810 } else if (__kmp_match_str("omp_cgroup_mem_alloc", scan, &next)) {
3811 SKIP_WS(next);
3812 if (is_memalloc) {
3813 KMP_WARNING(OmpNoAllocator, "omp_cgroup_mem_alloc");
3814 } else {
3815 traits[count].key = omp_atk_fb_data;
3817 }
3818 } else if (__kmp_match_str("omp_pteam_mem_alloc", scan, &next)) {
3819 SKIP_WS(next);
3820 if (is_memalloc) {
3821 KMP_WARNING(OmpNoAllocator, "omp_pteam_mem_alloc");
3822 } else {
3823 traits[count].key = omp_atk_fb_data;
3825 }
3826 } else if (__kmp_match_str("omp_thread_mem_alloc", scan, &next)) {
3827 SKIP_WS(next);
3828 if (is_memalloc) {
3829 KMP_WARNING(OmpNoAllocator, "omp_thread_mem_alloc");
3830 } else {
3831 traits[count].key = omp_atk_fb_data;
3833 }
3834 } else {
3835 if (!is_memalloc) {
3836 SET_KEY();
3837 SKIP_PAIR(key);
3838 continue;
3839 }
3840 }
3841 if (is_memalloc) {
3843 if (next == buf || *next != '\0') {
3844 // either no match or extra symbols present after the matched token
3845 KMP_WARNING(StgInvalidValue, name, value);
3846 }
3847 return;
3848 } else {
3849 ++count;
3850 if (count == ntraits)
3851 break;
3852 GET_NEXT(',');
3853 }
3854 } else { // memspace
3855 if (!is_memspace) {
3856 if (__kmp_match_str("omp_default_mem_space", scan, &next)) {
3857 SKIP_WS(next);
3859 } else if (__kmp_match_str("omp_large_cap_mem_space", scan, &next)) {
3860 SKIP_WS(next);
3862 } else if (__kmp_match_str("omp_const_mem_space", scan, &next)) {
3863 SKIP_WS(next);
3865 } else if (__kmp_match_str("omp_high_bw_mem_space", scan, &next)) {
3866 SKIP_WS(next);
3868 } else if (__kmp_match_str("omp_low_lat_mem_space", scan, &next)) {
3869 SKIP_WS(next);
3871 } else {
3873 if (next == buf || *next != '\0') {
3874 // either no match or extra symbols present after the matched token
3875 KMP_WARNING(StgInvalidValue, name, value);
3876 }
3877 return;
3878 }
3879 is_memspace = true;
3880 }
3881 if (delim) { // traits
3882 GET_NEXT(':');
3883 start = scan;
3884 if (__kmp_match_str("sync_hint", scan, &next)) {
3885 GET_NEXT('=');
3886 traits[count].key = omp_atk_sync_hint;
3887 if (__kmp_match_str("contended", scan, &next)) {
3888 traits[count].value = omp_atv_contended;
3889 } else if (__kmp_match_str("uncontended", scan, &next)) {
3891 } else if (__kmp_match_str("serialized", scan, &next)) {
3892 traits[count].value = omp_atv_serialized;
3893 } else if (__kmp_match_str("private", scan, &next)) {
3894 traits[count].value = omp_atv_private;
3895 } else {
3896 SET_KEY();
3897 SKIP_PAIR(key);
3898 continue;
3899 }
3900 } else if (__kmp_match_str("alignment", scan, &next)) {
3901 GET_NEXT('=');
3902 if (!isdigit(*next)) {
3903 SET_KEY();
3904 SKIP_PAIR(key);
3905 continue;
3906 }
3907 SKIP_DIGITS(next);
3908 int n = __kmp_str_to_int(scan, ',');
3909 if (n < 0 || !IS_POWER_OF_TWO(n)) {
3910 SET_KEY();
3911 SKIP_PAIR(key);
3912 continue;
3913 }
3914 traits[count].key = omp_atk_alignment;
3915 traits[count].value = n;
3916 } else if (__kmp_match_str("access", scan, &next)) {
3917 GET_NEXT('=');
3918 traits[count].key = omp_atk_access;
3919 if (__kmp_match_str("all", scan, &next)) {
3920 traits[count].value = omp_atv_all;
3921 } else if (__kmp_match_str("cgroup", scan, &next)) {
3922 traits[count].value = omp_atv_cgroup;
3923 } else if (__kmp_match_str("pteam", scan, &next)) {
3924 traits[count].value = omp_atv_pteam;
3925 } else if (__kmp_match_str("thread", scan, &next)) {
3926 traits[count].value = omp_atv_thread;
3927 } else {
3928 SET_KEY();
3929 SKIP_PAIR(key);
3930 continue;
3931 }
3932 } else if (__kmp_match_str("pool_size", scan, &next)) {
3933 GET_NEXT('=');
3934 if (!isdigit(*next)) {
3935 SET_KEY();
3936 SKIP_PAIR(key);
3937 continue;
3938 }
3939 SKIP_DIGITS(next);
3940 int n = __kmp_str_to_int(scan, ',');
3941 if (n < 0) {
3942 SET_KEY();
3943 SKIP_PAIR(key);
3944 continue;
3945 }
3946 traits[count].key = omp_atk_pool_size;
3947 traits[count].value = n;
3948 } else if (__kmp_match_str("fallback", scan, &next)) {
3949 GET_NEXT('=');
3950 traits[count].key = omp_atk_fallback;
3951 if (__kmp_match_str("default_mem_fb", scan, &next)) {
3953 } else if (__kmp_match_str("null_fb", scan, &next)) {
3954 traits[count].value = omp_atv_null_fb;
3955 } else if (__kmp_match_str("abort_fb", scan, &next)) {
3956 traits[count].value = omp_atv_abort_fb;
3957 } else if (__kmp_match_str("allocator_fb", scan, &next)) {
3959 } else {
3960 SET_KEY();
3961 SKIP_PAIR(key);
3962 continue;
3963 }
3964 } else if (__kmp_match_str("pinned", scan, &next)) {
3965 GET_NEXT('=');
3966 traits[count].key = omp_atk_pinned;
3967 if (__kmp_str_match_true(next)) {
3968 traits[count].value = omp_atv_true;
3969 } else if (__kmp_str_match_false(next)) {
3970 traits[count].value = omp_atv_false;
3971 } else {
3972 SET_KEY();
3973 SKIP_PAIR(key);
3974 continue;
3975 }
3976 } else if (__kmp_match_str("partition", scan, &next)) {
3977 GET_NEXT('=');
3978 traits[count].key = omp_atk_partition;
3979 if (__kmp_match_str("environment", scan, &next)) {
3981 } else if (__kmp_match_str("nearest", scan, &next)) {
3982 traits[count].value = omp_atv_nearest;
3983 } else if (__kmp_match_str("blocked", scan, &next)) {
3984 traits[count].value = omp_atv_blocked;
3985 } else if (__kmp_match_str("interleaved", scan, &next)) {
3987 } else {
3988 SET_KEY();
3989 SKIP_PAIR(key);
3990 continue;
3991 }
3992 } else {
3993 SET_KEY();
3994 SKIP_PAIR(key);
3995 continue;
3996 }
3997 SKIP_WS(next);
3998 ++count;
3999 if (count == ntraits)
4000 break;
4001 GET_NEXT(',');
4002 } // traits
4003 } // memspace
4004 } // while
4005 al = __kmpc_init_allocator(__kmp_get_gtid(), ms, ntraits, traits);
4007}
4008
4009static void __kmp_stg_print_allocator(kmp_str_buf_t *buffer, char const *name,
4010 void *data) {
4012 __kmp_stg_print_str(buffer, name, "omp_default_mem_alloc");
4014 __kmp_stg_print_str(buffer, name, "omp_high_bw_mem_alloc");
4016 __kmp_stg_print_str(buffer, name, "omp_large_cap_mem_alloc");
4018 __kmp_stg_print_str(buffer, name, "omp_const_mem_alloc");
4020 __kmp_stg_print_str(buffer, name, "omp_low_lat_mem_alloc");
4022 __kmp_stg_print_str(buffer, name, "omp_cgroup_mem_alloc");
4024 __kmp_stg_print_str(buffer, name, "omp_pteam_mem_alloc");
4026 __kmp_stg_print_str(buffer, name, "omp_thread_mem_alloc");
4027 }
4028}
4029
4030// -----------------------------------------------------------------------------
4031// OMP_DYNAMIC
4032
4033static void __kmp_stg_parse_omp_dynamic(char const *name, char const *value,
4034 void *data) {
4035 __kmp_stg_parse_bool(name, value, &(__kmp_global.g.g_dynamic));
4036} // __kmp_stg_parse_omp_dynamic
4037
4038static void __kmp_stg_print_omp_dynamic(kmp_str_buf_t *buffer, char const *name,
4039 void *data) {
4040 __kmp_stg_print_bool(buffer, name, __kmp_global.g.g_dynamic);
4041} // __kmp_stg_print_omp_dynamic
4042
4044 char const *value, void *data) {
4046 KMP_WARNING(EnvParallelWarn, name);
4048 return;
4049 }
4050#ifdef USE_LOAD_BALANCE
4051 else if (__kmp_str_match("load balance", 2, value) ||
4052 __kmp_str_match("load_balance", 2, value) ||
4053 __kmp_str_match("load-balance", 2, value) ||
4054 __kmp_str_match("loadbalance", 2, value) ||
4055 __kmp_str_match("balance", 1, value)) {
4056 __kmp_global.g.g_dynamic_mode = dynamic_load_balance;
4057 }
4058#endif /* USE_LOAD_BALANCE */
4059 else if (__kmp_str_match("thread limit", 1, value) ||
4060 __kmp_str_match("thread_limit", 1, value) ||
4061 __kmp_str_match("thread-limit", 1, value) ||
4062 __kmp_str_match("threadlimit", 1, value) ||
4063 __kmp_str_match("limit", 2, value)) {
4064 __kmp_global.g.g_dynamic_mode = dynamic_thread_limit;
4065 } else if (__kmp_str_match("random", 1, value)) {
4066 __kmp_global.g.g_dynamic_mode = dynamic_random;
4067 } else {
4068 KMP_WARNING(StgInvalidValue, name, value);
4069 }
4070} //__kmp_stg_parse_kmp_dynamic_mode
4071
4073 char const *name, void *data) {
4074#if KMP_DEBUG
4075 if (__kmp_global.g.g_dynamic_mode == dynamic_default) {
4076 __kmp_str_buf_print(buffer, " %s: %s \n", name, KMP_I18N_STR(NotDefined));
4077 }
4078#ifdef USE_LOAD_BALANCE
4079 else if (__kmp_global.g.g_dynamic_mode == dynamic_load_balance) {
4080 __kmp_stg_print_str(buffer, name, "load balance");
4081 }
4082#endif /* USE_LOAD_BALANCE */
4083 else if (__kmp_global.g.g_dynamic_mode == dynamic_thread_limit) {
4084 __kmp_stg_print_str(buffer, name, "thread limit");
4085 } else if (__kmp_global.g.g_dynamic_mode == dynamic_random) {
4086 __kmp_stg_print_str(buffer, name, "random");
4087 } else {
4088 KMP_ASSERT(0);
4089 }
4090#endif /* KMP_DEBUG */
4091} // __kmp_stg_print_kmp_dynamic_mode
4092
4093#ifdef USE_LOAD_BALANCE
4094
4095// -----------------------------------------------------------------------------
4096// KMP_LOAD_BALANCE_INTERVAL
4097
4098static void __kmp_stg_parse_ld_balance_interval(char const *name,
4099 char const *value, void *data) {
4100 double interval = __kmp_convert_to_double(value);
4101 if (interval >= 0) {
4102 __kmp_load_balance_interval = interval;
4103 } else {
4104 KMP_WARNING(StgInvalidValue, name, value);
4105 }
4106} // __kmp_stg_parse_load_balance_interval
4107
4108static void __kmp_stg_print_ld_balance_interval(kmp_str_buf_t *buffer,
4109 char const *name, void *data) {
4110#if KMP_DEBUG
4111 __kmp_str_buf_print(buffer, " %s=%8.6f\n", name,
4112 __kmp_load_balance_interval);
4113#endif /* KMP_DEBUG */
4114} // __kmp_stg_print_load_balance_interval
4115
4116#endif /* USE_LOAD_BALANCE */
4117
4118// -----------------------------------------------------------------------------
4119// KMP_INIT_AT_FORK
4120
4121static void __kmp_stg_parse_init_at_fork(char const *name, char const *value,
4122 void *data) {
4126 }
4127} // __kmp_stg_parse_init_at_fork
4128
4130 char const *name, void *data) {
4132} // __kmp_stg_print_init_at_fork
4133
4134// -----------------------------------------------------------------------------
4135// KMP_SCHEDULE
4136
4137static void __kmp_stg_parse_schedule(char const *name, char const *value,
4138 void *data) {
4139
4140 if (value != NULL) {
4141 size_t length = KMP_STRLEN(value);
4142 if (length > INT_MAX) {
4143 KMP_WARNING(LongValue, name);
4144 } else {
4145 const char *semicolon;
4146 if (value[length - 1] == '"' || value[length - 1] == '\'')
4147 KMP_WARNING(UnbalancedQuotes, name);
4148 do {
4149 char sentinel;
4150
4151 semicolon = strchr(value, ';');
4152 if (*value && semicolon != value) {
4153 const char *comma = strchr(value, ',');
4154
4155 if (comma) {
4156 ++comma;
4157 sentinel = ',';
4158 } else
4159 sentinel = ';';
4160 if (!__kmp_strcasecmp_with_sentinel("static", value, sentinel)) {
4161 if (!__kmp_strcasecmp_with_sentinel("greedy", comma, ';')) {
4163 continue;
4164 } else if (!__kmp_strcasecmp_with_sentinel("balanced", comma,
4165 ';')) {
4167 continue;
4168 }
4169 } else if (!__kmp_strcasecmp_with_sentinel("guided", value,
4170 sentinel)) {
4171 if (!__kmp_strcasecmp_with_sentinel("iterative", comma, ';')) {
4173 continue;
4174 } else if (!__kmp_strcasecmp_with_sentinel("analytical", comma,
4175 ';')) {
4176 /* analytical not allowed for too many threads */
4178 continue;
4179 }
4180 }
4181 KMP_WARNING(InvalidClause, name, value);
4182 } else
4183 KMP_WARNING(EmptyClause, name);
4184 } while ((value = semicolon ? semicolon + 1 : NULL));
4185 }
4186 }
4187
4188} // __kmp_stg_parse__schedule
4189
4190static void __kmp_stg_print_schedule(kmp_str_buf_t *buffer, char const *name,
4191 void *data) {
4192 if (__kmp_env_format) {
4194 } else {
4195 __kmp_str_buf_print(buffer, " %s='", name);
4196 }
4198 __kmp_str_buf_print(buffer, "%s", "static,greedy");
4199 } else if (__kmp_static == kmp_sch_static_balanced) {
4200 __kmp_str_buf_print(buffer, "%s", "static,balanced");
4201 }
4203 __kmp_str_buf_print(buffer, ";%s'\n", "guided,iterative");
4205 __kmp_str_buf_print(buffer, ";%s'\n", "guided,analytical");
4206 }
4207} // __kmp_stg_print_schedule
4208
4209// -----------------------------------------------------------------------------
4210// OMP_SCHEDULE
4211
4212static inline void __kmp_omp_schedule_restore() {
4213#if KMP_USE_HIER_SCHED
4214 __kmp_hier_scheds.deallocate();
4215#endif
4216 __kmp_chunk = 0;
4218}
4219
4220// if parse_hier = true:
4221// Parse [HW,][modifier:]kind[,chunk]
4222// else:
4223// Parse [modifier:]kind[,chunk]
4224static const char *__kmp_parse_single_omp_schedule(const char *name,
4225 const char *value,
4226 bool parse_hier = false) {
4227 /* get the specified scheduling style */
4228 const char *ptr = value;
4229 const char *delim;
4230 int chunk = 0;
4232 if (*ptr == '\0')
4233 return NULL;
4234 delim = ptr;
4235 while (*delim != ',' && *delim != ':' && *delim != '\0')
4236 delim++;
4237#if KMP_USE_HIER_SCHED
4239 if (parse_hier) {
4240 if (*delim == ',') {
4241 if (!__kmp_strcasecmp_with_sentinel("L1", ptr, ',')) {
4243 } else if (!__kmp_strcasecmp_with_sentinel("L2", ptr, ',')) {
4245 } else if (!__kmp_strcasecmp_with_sentinel("L3", ptr, ',')) {
4247 } else if (!__kmp_strcasecmp_with_sentinel("NUMA", ptr, ',')) {
4249 }
4250 }
4251 if (layer != kmp_hier_layer_e::LAYER_THREAD && *delim != ',') {
4252 // If there is no comma after the layer, then this schedule is invalid
4253 KMP_WARNING(StgInvalidValue, name, value);
4255 return NULL;
4256 } else if (layer != kmp_hier_layer_e::LAYER_THREAD) {
4257 ptr = ++delim;
4258 while (*delim != ',' && *delim != ':' && *delim != '\0')
4259 delim++;
4260 }
4261 }
4262#endif // KMP_USE_HIER_SCHED
4263 // Read in schedule modifier if specified
4264 enum sched_type sched_modifier = (enum sched_type)0;
4265 if (*delim == ':') {
4266 if (!__kmp_strcasecmp_with_sentinel("monotonic", ptr, *delim)) {
4268 ptr = ++delim;
4269 while (*delim != ',' && *delim != ':' && *delim != '\0')
4270 delim++;
4271 } else if (!__kmp_strcasecmp_with_sentinel("nonmonotonic", ptr, *delim)) {
4273 ptr = ++delim;
4274 while (*delim != ',' && *delim != ':' && *delim != '\0')
4275 delim++;
4276 } else if (!parse_hier) {
4277 // If there is no proper schedule modifier, then this schedule is invalid
4278 KMP_WARNING(StgInvalidValue, name, value);
4280 return NULL;
4281 }
4282 }
4283 // Read in schedule kind (required)
4284 if (!__kmp_strcasecmp_with_sentinel("dynamic", ptr, *delim))
4286 else if (!__kmp_strcasecmp_with_sentinel("guided", ptr, *delim))
4288 // AC: TODO: probably remove TRAPEZOIDAL (OMP 3.0 does not allow it)
4289 else if (!__kmp_strcasecmp_with_sentinel("auto", ptr, *delim))
4291 else if (!__kmp_strcasecmp_with_sentinel("trapezoidal", ptr, *delim))
4293 else if (!__kmp_strcasecmp_with_sentinel("static", ptr, *delim))
4295#if KMP_STATIC_STEAL_ENABLED
4296 else if (!__kmp_strcasecmp_with_sentinel("static_steal", ptr, *delim)) {
4297 // replace static_steal with dynamic to better cope with ordered loops
4300 }
4301#endif
4302 else {
4303 // If there is no proper schedule kind, then this schedule is invalid
4304 KMP_WARNING(StgInvalidValue, name, value);
4306 return NULL;
4307 }
4308
4309 // Read in schedule chunk size if specified
4310 if (*delim == ',') {
4311 ptr = delim + 1;
4312 SKIP_WS(ptr);
4313 if (!isdigit(*ptr)) {
4314 // If there is no chunk after comma, then this schedule is invalid
4315 KMP_WARNING(StgInvalidValue, name, value);
4317 return NULL;
4318 }
4319 SKIP_DIGITS(ptr);
4320 // auto schedule should not specify chunk size
4321 if (sched == kmp_sch_auto) {
4322 __kmp_msg(kmp_ms_warning, KMP_MSG(IgnoreChunk, name, delim),
4324 } else {
4325 if (sched == kmp_sch_static)
4327 chunk = __kmp_str_to_int(delim + 1, *ptr);
4328 if (chunk < 1) {
4329 chunk = KMP_DEFAULT_CHUNK;
4330 __kmp_msg(kmp_ms_warning, KMP_MSG(InvalidChunk, name, delim),
4332 KMP_INFORM(Using_int_Value, name, __kmp_chunk);
4333 // AC: next block commented out until KMP_DEFAULT_CHUNK != KMP_MIN_CHUNK
4334 // (to improve code coverage :)
4335 // The default chunk size is 1 according to standard, thus making
4336 // KMP_MIN_CHUNK not 1 we would introduce mess:
4337 // wrong chunk becomes 1, but it will be impossible to explicitly set
4338 // to 1 because it becomes KMP_MIN_CHUNK...
4339 // } else if ( chunk < KMP_MIN_CHUNK ) {
4340 // chunk = KMP_MIN_CHUNK;
4341 } else if (chunk > KMP_MAX_CHUNK) {
4342 chunk = KMP_MAX_CHUNK;
4343 __kmp_msg(kmp_ms_warning, KMP_MSG(LargeChunk, name, delim),
4345 KMP_INFORM(Using_int_Value, name, chunk);
4346 }
4347 }
4348 } else {
4349 ptr = delim;
4350 }
4351
4352 SCHEDULE_SET_MODIFIERS(sched, sched_modifier);
4353
4354#if KMP_USE_HIER_SCHED
4355 if (layer != kmp_hier_layer_e::LAYER_THREAD) {
4356 __kmp_hier_scheds.append(sched, chunk, layer);
4357 } else
4358#endif
4359 {
4360 __kmp_chunk = chunk;
4362 }
4363 return ptr;
4364}
4365
4366static void __kmp_stg_parse_omp_schedule(char const *name, char const *value,
4367 void *data) {
4368 size_t length;
4369 const char *ptr = value;
4370 if (ptr) {
4371 SKIP_WS(ptr);
4373 if (length) {
4374 if (value[length - 1] == '"' || value[length - 1] == '\'')
4375 KMP_WARNING(UnbalancedQuotes, name);
4376/* get the specified scheduling style */
4377#if KMP_USE_HIER_SCHED
4378 if (!__kmp_strcasecmp_with_sentinel("EXPERIMENTAL", ptr, ' ')) {
4379 SKIP_TOKEN(ptr);
4380 SKIP_WS(ptr);
4381 while ((ptr = __kmp_parse_single_omp_schedule(name, ptr, true))) {
4382 while (*ptr == ' ' || *ptr == '\t' || *ptr == ':')
4383 ptr++;
4384 if (*ptr == '\0')
4385 break;
4386 }
4387 } else
4388#endif
4390 } else
4391 KMP_WARNING(EmptyString, name);
4392 }
4393#if KMP_USE_HIER_SCHED
4394 __kmp_hier_scheds.sort();
4395#endif
4396 K_DIAG(1, ("__kmp_static == %d\n", __kmp_static))
4397 K_DIAG(1, ("__kmp_guided == %d\n", __kmp_guided))
4398 K_DIAG(1, ("__kmp_sched == %d\n", __kmp_sched))
4399 K_DIAG(1, ("__kmp_chunk == %d\n", __kmp_chunk))
4400} // __kmp_stg_parse_omp_schedule
4401
4403 char const *name, void *data) {
4404 if (__kmp_env_format) {
4406 } else {
4407 __kmp_str_buf_print(buffer, " %s='", name);
4408 }
4411 __kmp_str_buf_print(buffer, "monotonic:");
4413 __kmp_str_buf_print(buffer, "nonmonotonic:");
4414 }
4415 if (__kmp_chunk) {
4416 switch (sched) {
4418 __kmp_str_buf_print(buffer, "%s,%d'\n", "dynamic", __kmp_chunk);
4419 break;
4422 __kmp_str_buf_print(buffer, "%s,%d'\n", "guided", __kmp_chunk);
4423 break;
4425 __kmp_str_buf_print(buffer, "%s,%d'\n", "trapezoidal", __kmp_chunk);
4426 break;
4427 case kmp_sch_static:
4431 __kmp_str_buf_print(buffer, "%s,%d'\n", "static", __kmp_chunk);
4432 break;
4434 __kmp_str_buf_print(buffer, "%s,%d'\n", "static_steal", __kmp_chunk);
4435 break;
4436 case kmp_sch_auto:
4437 __kmp_str_buf_print(buffer, "%s,%d'\n", "auto", __kmp_chunk);
4438 break;
4439 default:
4440 KMP_ASSERT2(false, "Unhandled sched_type enumeration");
4442 break;
4443 }
4444 } else {
4445 switch (sched) {
4447 __kmp_str_buf_print(buffer, "%s'\n", "dynamic");
4448 break;
4451 __kmp_str_buf_print(buffer, "%s'\n", "guided");
4452 break;
4454 __kmp_str_buf_print(buffer, "%s'\n", "trapezoidal");
4455 break;
4456 case kmp_sch_static:
4460 __kmp_str_buf_print(buffer, "%s'\n", "static");
4461 break;
4463 __kmp_str_buf_print(buffer, "%s'\n", "static_steal");
4464 break;
4465 case kmp_sch_auto:
4466 __kmp_str_buf_print(buffer, "%s'\n", "auto");
4467 break;
4468 default:
4469 KMP_ASSERT2(false, "Unhandled sched_type enumeration");
4471 break;
4472 }
4473 }
4474} // __kmp_stg_print_omp_schedule
4475
4476#if KMP_USE_HIER_SCHED
4477// -----------------------------------------------------------------------------
4478// KMP_DISP_HAND_THREAD
4479static void __kmp_stg_parse_kmp_hand_thread(char const *name, char const *value,
4480 void *data) {
4482} // __kmp_stg_parse_kmp_hand_thread
4483
4484static void __kmp_stg_print_kmp_hand_thread(kmp_str_buf_t *buffer,
4485 char const *name, void *data) {
4487} // __kmp_stg_print_kmp_hand_thread
4488#endif
4489
4490// -----------------------------------------------------------------------------
4491// KMP_FORCE_MONOTONIC_DYNAMIC_SCHEDULE
4493 char const *value, void *data) {
4495} // __kmp_stg_parse_kmp_force_monotonic
4496
4498 char const *name, void *data) {
4500} // __kmp_stg_print_kmp_force_monotonic
4501
4502// -----------------------------------------------------------------------------
4503// KMP_ATOMIC_MODE
4504
4505static void __kmp_stg_parse_atomic_mode(char const *name, char const *value,
4506 void *data) {
4507 // Modes: 0 -- do not change default; 1 -- Intel perf mode, 2 -- GOMP
4508 // compatibility mode.
4509 int mode = 0;
4510 int max = 1;
4511#ifdef KMP_GOMP_COMPAT
4512 max = 2;
4513#endif /* KMP_GOMP_COMPAT */
4514 __kmp_stg_parse_int(name, value, 0, max, &mode);
4515 // TODO; parse_int is not very suitable for this case. In case of overflow it
4516 // is better to use
4517 // 0 rather that max value.
4518 if (mode > 0) {
4520 }
4521} // __kmp_stg_parse_atomic_mode
4522
4523static void __kmp_stg_print_atomic_mode(kmp_str_buf_t *buffer, char const *name,
4524 void *data) {
4526} // __kmp_stg_print_atomic_mode
4527
4528// -----------------------------------------------------------------------------
4529// KMP_CONSISTENCY_CHECK
4530
4532 char const *value, void *data) {
4533 if (TCR_4(__kmp_init_serial)) {
4534 KMP_WARNING(EnvSerialWarn, name);
4535 return;
4536 } // read value before serial initialization only
4537 if (!__kmp_strcasecmp_with_sentinel("all", value, 0)) {
4538 // Note, this will not work from kmp_set_defaults because th_cons stack was
4539 // not allocated
4540 // for existed thread(s) thus the first __kmp_push_<construct> will break
4541 // with assertion.
4542 // TODO: allocate th_cons if called from kmp_set_defaults.
4544 } else if (!__kmp_strcasecmp_with_sentinel("none", value, 0)) {
4546 } else {
4547 KMP_WARNING(StgInvalidValue, name, value);
4548 }
4549} // __kmp_stg_parse_consistency_check
4550
4552 char const *name, void *data) {
4553#if KMP_DEBUG
4554 const char *value = NULL;
4555
4557 value = "all";
4558 } else {
4559 value = "none";
4560 }
4561
4562 if (value != NULL) {
4563 __kmp_stg_print_str(buffer, name, value);
4564 }
4565#endif /* KMP_DEBUG */
4566} // __kmp_stg_print_consistency_check
4567
4568#if USE_ITT_BUILD
4569// -----------------------------------------------------------------------------
4570// KMP_ITT_PREPARE_DELAY
4571
4572#if USE_ITT_NOTIFY
4573
4574static void __kmp_stg_parse_itt_prepare_delay(char const *name,
4575 char const *value, void *data) {
4576 // Experimental code: KMP_ITT_PREPARE_DELAY specifies numbert of loop
4577 // iterations.
4578 int delay = 0;
4579 __kmp_stg_parse_int(name, value, 0, INT_MAX, &delay);
4580 __kmp_itt_prepare_delay = delay;
4581} // __kmp_str_parse_itt_prepare_delay
4582
4583static void __kmp_stg_print_itt_prepare_delay(kmp_str_buf_t *buffer,
4584 char const *name, void *data) {
4585 __kmp_stg_print_uint64(buffer, name, __kmp_itt_prepare_delay);
4586
4587} // __kmp_str_print_itt_prepare_delay
4588
4589#endif // USE_ITT_NOTIFY
4590#endif /* USE_ITT_BUILD */
4591
4592// -----------------------------------------------------------------------------
4593// KMP_MALLOC_POOL_INCR
4594
4596 char const *value, void *data) {
4599 1);
4600} // __kmp_stg_parse_malloc_pool_incr
4601
4603 char const *name, void *data) {
4605
4606} // _kmp_stg_print_malloc_pool_incr
4607
4608#ifdef KMP_DEBUG
4609
4610// -----------------------------------------------------------------------------
4611// KMP_PAR_RANGE
4612
4613static void __kmp_stg_parse_par_range_env(char const *name, char const *value,
4614 void *data) {
4615 __kmp_stg_parse_par_range(name, value, &__kmp_par_range,
4616 __kmp_par_range_routine, __kmp_par_range_filename,
4617 &__kmp_par_range_lb, &__kmp_par_range_ub);
4618} // __kmp_stg_parse_par_range_env
4619
4620static void __kmp_stg_print_par_range_env(kmp_str_buf_t *buffer,
4621 char const *name, void *data) {
4622 if (__kmp_par_range != 0) {
4623 __kmp_stg_print_str(buffer, name, par_range_to_print);
4624 }
4625} // __kmp_stg_print_par_range_env
4626
4627#endif
4628
4629// -----------------------------------------------------------------------------
4630// KMP_GTID_MODE
4631
4632static void __kmp_stg_parse_gtid_mode(char const *name, char const *value,
4633 void *data) {
4634 // Modes:
4635 // 0 -- do not change default
4636 // 1 -- sp search
4637 // 2 -- use "keyed" TLS var, i.e.
4638 // pthread_getspecific(Linux* OS/OS X*) or TlsGetValue(Windows* OS)
4639 // 3 -- __declspec(thread) TLS var in tdata section
4640 int mode = 0;
4641 int max = 2;
4642#ifdef KMP_TDATA_GTID
4643 max = 3;
4644#endif /* KMP_TDATA_GTID */
4645 __kmp_stg_parse_int(name, value, 0, max, &mode);
4646 // TODO; parse_int is not very suitable for this case. In case of overflow it
4647 // is better to use 0 rather that max value.
4648 if (mode == 0) {
4650 } else {
4653 }
4654} // __kmp_str_parse_gtid_mode
4655
4656static void __kmp_stg_print_gtid_mode(kmp_str_buf_t *buffer, char const *name,
4657 void *data) {
4659 __kmp_stg_print_int(buffer, name, 0);
4660 } else {
4662 }
4663} // __kmp_stg_print_gtid_mode
4664
4665// -----------------------------------------------------------------------------
4666// KMP_NUM_LOCKS_IN_BLOCK
4667
4668static void __kmp_stg_parse_lock_block(char const *name, char const *value,
4669 void *data) {
4671} // __kmp_str_parse_lock_block
4672
4673static void __kmp_stg_print_lock_block(kmp_str_buf_t *buffer, char const *name,
4674 void *data) {
4676} // __kmp_stg_print_lock_block
4677
4678// -----------------------------------------------------------------------------
4679// KMP_LOCK_KIND
4680
4681#if KMP_USE_DYNAMIC_LOCK
4682#define KMP_STORE_LOCK_SEQ(a) (__kmp_user_lock_seq = lockseq_##a)
4683#else
4684#define KMP_STORE_LOCK_SEQ(a)
4685#endif
4686
4687static void __kmp_stg_parse_lock_kind(char const *name, char const *value,
4688 void *data) {
4690 KMP_WARNING(EnvLockWarn, name);
4691 return;
4692 }
4693
4694 if (__kmp_str_match("tas", 2, value) ||
4695 __kmp_str_match("test and set", 2, value) ||
4696 __kmp_str_match("test_and_set", 2, value) ||
4697 __kmp_str_match("test-and-set", 2, value) ||
4698 __kmp_str_match("test andset", 2, value) ||
4699 __kmp_str_match("test_andset", 2, value) ||
4700 __kmp_str_match("test-andset", 2, value) ||
4701 __kmp_str_match("testand set", 2, value) ||
4702 __kmp_str_match("testand_set", 2, value) ||
4703 __kmp_str_match("testand-set", 2, value) ||
4704 __kmp_str_match("testandset", 2, value)) {
4706 KMP_STORE_LOCK_SEQ(tas);
4707 }
4708#if KMP_USE_FUTEX
4709 else if (__kmp_str_match("futex", 1, value)) {
4710 if (__kmp_futex_determine_capable()) {
4711 __kmp_user_lock_kind = lk_futex;
4712 KMP_STORE_LOCK_SEQ(futex);
4713 } else {
4714 KMP_WARNING(FutexNotSupported, name, value);
4715 }
4716 }
4717#endif
4718 else if (__kmp_str_match("ticket", 2, value)) {
4720 KMP_STORE_LOCK_SEQ(ticket);
4721 } else if (__kmp_str_match("queuing", 1, value) ||
4722 __kmp_str_match("queue", 1, value)) {
4724 KMP_STORE_LOCK_SEQ(queuing);
4725 } else if (__kmp_str_match("drdpa ticket", 1, value) ||
4726 __kmp_str_match("drdpa_ticket", 1, value) ||
4727 __kmp_str_match("drdpa-ticket", 1, value) ||
4728 __kmp_str_match("drdpaticket", 1, value) ||
4729 __kmp_str_match("drdpa", 1, value)) {
4731 KMP_STORE_LOCK_SEQ(drdpa);
4732 }
4733#if KMP_USE_ADAPTIVE_LOCKS
4734 else if (__kmp_str_match("adaptive", 1, value)) {
4735 if (__kmp_cpuinfo.flags.rtm) { // ??? Is cpuinfo available here?
4736 __kmp_user_lock_kind = lk_adaptive;
4737 KMP_STORE_LOCK_SEQ(adaptive);
4738 } else {
4739 KMP_WARNING(AdaptiveNotSupported, name, value);
4741 KMP_STORE_LOCK_SEQ(queuing);
4742 }
4743 }
4744#endif // KMP_USE_ADAPTIVE_LOCKS
4745#if KMP_USE_DYNAMIC_LOCK && KMP_USE_TSX
4746 else if (__kmp_str_match("rtm_queuing", 1, value)) {
4747 if (__kmp_cpuinfo.flags.rtm) {
4748 __kmp_user_lock_kind = lk_rtm_queuing;
4749 KMP_STORE_LOCK_SEQ(rtm_queuing);
4750 } else {
4751 KMP_WARNING(AdaptiveNotSupported, name, value);
4753 KMP_STORE_LOCK_SEQ(queuing);
4754 }
4755 } else if (__kmp_str_match("rtm_spin", 1, value)) {
4756 if (__kmp_cpuinfo.flags.rtm) {
4757 __kmp_user_lock_kind = lk_rtm_spin;
4758 KMP_STORE_LOCK_SEQ(rtm_spin);
4759 } else {
4760 KMP_WARNING(AdaptiveNotSupported, name, value);
4762 KMP_STORE_LOCK_SEQ(queuing);
4763 }
4764 } else if (__kmp_str_match("hle", 1, value)) {
4765 __kmp_user_lock_kind = lk_hle;
4766 KMP_STORE_LOCK_SEQ(hle);
4767 }
4768#endif
4769 else {
4770 KMP_WARNING(StgInvalidValue, name, value);
4771 }
4772}
4773
4774static void __kmp_stg_print_lock_kind(kmp_str_buf_t *buffer, char const *name,
4775 void *data) {
4776 const char *value = NULL;
4777
4778 switch (__kmp_user_lock_kind) {
4779 case lk_default:
4780 value = "default";
4781 break;
4782
4783 case lk_tas:
4784 value = "tas";
4785 break;
4786
4787#if KMP_USE_FUTEX
4788 case lk_futex:
4789 value = "futex";
4790 break;
4791#endif
4792
4793#if KMP_USE_DYNAMIC_LOCK && KMP_USE_TSX
4794 case lk_rtm_queuing:
4795 value = "rtm_queuing";
4796 break;
4797
4798 case lk_rtm_spin:
4799 value = "rtm_spin";
4800 break;
4801
4802 case lk_hle:
4803 value = "hle";
4804 break;
4805#endif
4806
4807 case lk_ticket:
4808 value = "ticket";
4809 break;
4810
4811 case lk_queuing:
4812 value = "queuing";
4813 break;
4814
4815 case lk_drdpa:
4816 value = "drdpa";
4817 break;
4818#if KMP_USE_ADAPTIVE_LOCKS
4819 case lk_adaptive:
4820 value = "adaptive";
4821 break;
4822#endif
4823 }
4824
4825 if (value != NULL) {
4826 __kmp_stg_print_str(buffer, name, value);
4827 }
4828}
4829
4830// -----------------------------------------------------------------------------
4831// KMP_SPIN_BACKOFF_PARAMS
4832
4833// KMP_SPIN_BACKOFF_PARAMS=max_backoff[,min_tick] (max backoff size, min tick
4834// for machine pause)
4836 const char *value, void *data) {
4837 const char *next = value;
4838
4839 int total = 0; // Count elements that were set. It'll be used as an array size
4840 int prev_comma = FALSE; // For correct processing sequential commas
4841 int i;
4842
4843 kmp_uint32 max_backoff = __kmp_spin_backoff_params.max_backoff;
4844 kmp_uint32 min_tick = __kmp_spin_backoff_params.min_tick;
4845
4846 // Run only 3 iterations because it is enough to read two values or find a
4847 // syntax error
4848 for (i = 0; i < 3; i++) {
4849 SKIP_WS(next);
4850
4851 if (*next == '\0') {
4852 break;
4853 }
4854 // Next character is not an integer or not a comma OR number of values > 2
4855 // => end of list
4856 if (((*next < '0' || *next > '9') && *next != ',') || total > 2) {
4857 KMP_WARNING(EnvSyntaxError, name, value);
4858 return;
4859 }
4860 // The next character is ','
4861 if (*next == ',') {
4862 // ',' is the first character
4863 if (total == 0 || prev_comma) {
4864 total++;
4865 }
4866 prev_comma = TRUE;
4867 next++; // skip ','
4868 SKIP_WS(next);
4869 }
4870 // Next character is a digit
4871 if (*next >= '0' && *next <= '9') {
4872 int num;
4873 const char *buf = next;
4874 char const *msg = NULL;
4875 prev_comma = FALSE;
4876 SKIP_DIGITS(next);
4877 total++;
4878
4879 const char *tmp = next;
4880 SKIP_WS(tmp);
4881 if ((*next == ' ' || *next == '\t') && (*tmp >= '0' && *tmp <= '9')) {
4882 KMP_WARNING(EnvSpacesNotAllowed, name, value);
4883 return;
4884 }
4885
4886 num = __kmp_str_to_int(buf, *next);
4887 if (num <= 0) { // The number of retries should be > 0
4888 msg = KMP_I18N_STR(ValueTooSmall);
4889 num = 1;
4890 }
4891 if (msg != NULL) {
4892 // Message is not empty. Print warning.
4893 KMP_WARNING(ParseSizeIntWarn, name, value, msg);
4894 KMP_INFORM(Using_int_Value, name, num);
4895 }
4896 if (total == 1) {
4897 max_backoff = num;
4898 } else if (total == 2) {
4899 min_tick = num;
4900 }
4901 }
4902 }
4903 if (total <= 0) {
4904 KMP_WARNING(EnvSyntaxError, name, value);
4905 return;
4906 }
4907 __kmp_spin_backoff_params.max_backoff = max_backoff;
4908 __kmp_spin_backoff_params.min_tick = min_tick;
4909}
4910
4912 char const *name, void *data) {
4913 if (__kmp_env_format) {
4915 } else {
4916 __kmp_str_buf_print(buffer, " %s='", name);
4917 }
4918 __kmp_str_buf_print(buffer, "%d,%d'\n", __kmp_spin_backoff_params.max_backoff,
4919 __kmp_spin_backoff_params.min_tick);
4920}
4921
4922#if KMP_USE_ADAPTIVE_LOCKS
4923
4924// -----------------------------------------------------------------------------
4925// KMP_ADAPTIVE_LOCK_PROPS, KMP_SPECULATIVE_STATSFILE
4926
4927// Parse out values for the tunable parameters from a string of the form
4928// KMP_ADAPTIVE_LOCK_PROPS=max_soft_retries[,max_badness]
4929static void __kmp_stg_parse_adaptive_lock_props(const char *name,
4930 const char *value, void *data) {
4931 int max_retries = 0;
4932 int max_badness = 0;
4933
4934 const char *next = value;
4935
4936 int total = 0; // Count elements that were set. It'll be used as an array size
4937 int prev_comma = FALSE; // For correct processing sequential commas
4938 int i;
4939
4940 // Save values in the structure __kmp_speculative_backoff_params
4941 // Run only 3 iterations because it is enough to read two values or find a
4942 // syntax error
4943 for (i = 0; i < 3; i++) {
4944 SKIP_WS(next);
4945
4946 if (*next == '\0') {
4947 break;
4948 }
4949 // Next character is not an integer or not a comma OR number of values > 2
4950 // => end of list
4951 if (((*next < '0' || *next > '9') && *next != ',') || total > 2) {
4952 KMP_WARNING(EnvSyntaxError, name, value);
4953 return;
4954 }
4955 // The next character is ','
4956 if (*next == ',') {
4957 // ',' is the first character
4958 if (total == 0 || prev_comma) {
4959 total++;
4960 }
4961 prev_comma = TRUE;
4962 next++; // skip ','
4963 SKIP_WS(next);
4964 }
4965 // Next character is a digit
4966 if (*next >= '0' && *next <= '9') {
4967 int num;
4968 const char *buf = next;
4969 char const *msg = NULL;
4970 prev_comma = FALSE;
4971 SKIP_DIGITS(next);
4972 total++;
4973
4974 const char *tmp = next;
4975 SKIP_WS(tmp);
4976 if ((*next == ' ' || *next == '\t') && (*tmp >= '0' && *tmp <= '9')) {
4977 KMP_WARNING(EnvSpacesNotAllowed, name, value);
4978 return;
4979 }
4980
4981 num = __kmp_str_to_int(buf, *next);
4982 if (num < 0) { // The number of retries should be >= 0
4983 msg = KMP_I18N_STR(ValueTooSmall);
4984 num = 1;
4985 }
4986 if (msg != NULL) {
4987 // Message is not empty. Print warning.
4988 KMP_WARNING(ParseSizeIntWarn, name, value, msg);
4989 KMP_INFORM(Using_int_Value, name, num);
4990 }
4991 if (total == 1) {
4992 max_retries = num;
4993 } else if (total == 2) {
4994 max_badness = num;
4995 }
4996 }
4997 }
4998 if (total <= 0) {
4999 KMP_WARNING(EnvSyntaxError, name, value);
5000 return;
5001 }
5002 __kmp_adaptive_backoff_params.max_soft_retries = max_retries;
5003 __kmp_adaptive_backoff_params.max_badness = max_badness;
5004}
5005
5006static void __kmp_stg_print_adaptive_lock_props(kmp_str_buf_t *buffer,
5007 char const *name, void *data) {
5008 if (__kmp_env_format) {
5010 } else {
5011 __kmp_str_buf_print(buffer, " %s='", name);
5012 }
5013 __kmp_str_buf_print(buffer, "%d,%d'\n",
5014 __kmp_adaptive_backoff_params.max_soft_retries,
5015 __kmp_adaptive_backoff_params.max_badness);
5016} // __kmp_stg_print_adaptive_lock_props
5017
5018#if KMP_DEBUG_ADAPTIVE_LOCKS
5019
5020static void __kmp_stg_parse_speculative_statsfile(char const *name,
5021 char const *value,
5022 void *data) {
5023 __kmp_stg_parse_file(name, value, "",
5024 CCAST(char **, &__kmp_speculative_statsfile));
5025} // __kmp_stg_parse_speculative_statsfile
5026
5027static void __kmp_stg_print_speculative_statsfile(kmp_str_buf_t *buffer,
5028 char const *name,
5029 void *data) {
5030 if (__kmp_str_match("-", 0, __kmp_speculative_statsfile)) {
5031 __kmp_stg_print_str(buffer, name, "stdout");
5032 } else {
5033 __kmp_stg_print_str(buffer, name, __kmp_speculative_statsfile);
5034 }
5035
5036} // __kmp_stg_print_speculative_statsfile
5037
5038#endif // KMP_DEBUG_ADAPTIVE_LOCKS
5039
5040#endif // KMP_USE_ADAPTIVE_LOCKS
5041
5042// -----------------------------------------------------------------------------
5043// KMP_HW_SUBSET (was KMP_PLACE_THREADS)
5044// 2s16c,2t => 2S16C,2T => 2S16C \0 2T
5045
5046// Return KMP_HW_SUBSET preferred hardware type in case a token is ambiguously
5047// short. The original KMP_HW_SUBSET environment variable had single letters:
5048// s, c, t for sockets, cores, threads repsectively.
5050 size_t num_possible) {
5051 for (size_t i = 0; i < num_possible; ++i) {
5052 if (possible[i] == KMP_HW_THREAD)
5053 return KMP_HW_THREAD;
5054 else if (possible[i] == KMP_HW_CORE)
5055 return KMP_HW_CORE;
5056 else if (possible[i] == KMP_HW_SOCKET)
5057 return KMP_HW_SOCKET;
5058 }
5059 return KMP_HW_UNKNOWN;
5060}
5061
5062// Return hardware type from string or HW_UNKNOWN if string cannot be parsed
5063// This algorithm is very forgiving to the user in that, the instant it can
5064// reduce the search space to one, it assumes that is the topology level the
5065// user wanted, even if it is misspelled later in the token.
5066static kmp_hw_t __kmp_stg_parse_hw_subset_name(char const *token) {
5067 size_t index, num_possible, token_length;
5068 kmp_hw_t possible[KMP_HW_LAST];
5069 const char *end;
5070
5071 // Find the end of the hardware token string
5072 end = token;
5073 token_length = 0;
5074 while (isalnum(*end) || *end == '_') {
5075 token_length++;
5076 end++;
5077 }
5078
5079 // Set the possibilities to all hardware types
5080 num_possible = 0;
5081 KMP_FOREACH_HW_TYPE(type) { possible[num_possible++] = type; }
5082
5083 // Eliminate hardware types by comparing the front of the token
5084 // with hardware names
5085 // In most cases, the first letter in the token will indicate exactly
5086 // which hardware type is parsed, e.g., 'C' = Core
5087 index = 0;
5088 while (num_possible > 1 && index < token_length) {
5089 size_t n = num_possible;
5090 char token_char = (char)toupper(token[index]);
5091 for (size_t i = 0; i < n; ++i) {
5092 const char *s;
5093 kmp_hw_t type = possible[i];
5094 s = __kmp_hw_get_keyword(type, false);
5095 if (index < KMP_STRLEN(s)) {
5096 char c = (char)toupper(s[index]);
5097 // Mark hardware types for removal when the characters do not match
5098 if (c != token_char) {
5099 possible[i] = KMP_HW_UNKNOWN;
5100 num_possible--;
5101 }
5102 }
5103 }
5104 // Remove hardware types that this token cannot be
5105 size_t start = 0;
5106 for (size_t i = 0; i < n; ++i) {
5107 if (possible[i] != KMP_HW_UNKNOWN) {
5108 kmp_hw_t temp = possible[i];
5109 possible[i] = possible[start];
5110 possible[start] = temp;
5111 start++;
5112 }
5113 }
5114 KMP_ASSERT(start == num_possible);
5115 index++;
5116 }
5117
5118 // Attempt to break a tie if user has very short token
5119 // (e.g., is 'T' tile or thread?)
5120 if (num_possible > 1)
5121 return __kmp_hw_subset_break_tie(possible, num_possible);
5122 if (num_possible == 1)
5123 return possible[0];
5124 return KMP_HW_UNKNOWN;
5125}
5126
5127// The longest observable sequence of items can only be HW_LAST length
5128// The input string is usually short enough, let's use 512 limit for now
5129#define MAX_T_LEVEL KMP_HW_LAST
5130#define MAX_STR_LEN 512
5131static void __kmp_stg_parse_hw_subset(char const *name, char const *value,
5132 void *data) {
5133 // Value example: 1s,5c@3,2T
5134 // Which means "use 1 socket, 5 cores with offset 3, 2 threads per core"
5135 kmp_setting_t **rivals = (kmp_setting_t **)data;
5136 if (strcmp(name, "KMP_PLACE_THREADS") == 0) {
5137 KMP_INFORM(EnvVarDeprecated, name, "KMP_HW_SUBSET");
5138 }
5139 if (__kmp_stg_check_rivals(name, value, rivals)) {
5140 return;
5141 }
5142
5143 char *components[MAX_T_LEVEL];
5144 char const *digits = "0123456789";
5145 char input[MAX_STR_LEN];
5146 size_t len = 0, mlen = MAX_STR_LEN;
5147 int level = 0;
5148 bool absolute = false;
5149 // Canonicalize the string (remove spaces, unify delimiters, etc.)
5150 char *pos = CCAST(char *, value);
5151 while (*pos && mlen) {
5152 if (*pos != ' ') { // skip spaces
5153 if (len == 0 && *pos == ':') {
5154 absolute = true;
5155 } else {
5156 input[len] = (char)(toupper(*pos));
5157 if (input[len] == 'X')
5158 input[len] = ','; // unify delimiters of levels
5159 if (input[len] == 'O' && strchr(digits, *(pos + 1)))
5160 input[len] = '@'; // unify delimiters of offset
5161 len++;
5162 }
5163 }
5164 mlen--;
5165 pos++;
5166 }
5167 if (len == 0 || mlen == 0) {
5168 goto err; // contents is either empty or too long
5169 }
5170 input[len] = '\0';
5171 // Split by delimiter
5172 pos = input;
5173 components[level++] = pos;
5174 while ((pos = strchr(pos, ','))) {
5175 if (level >= MAX_T_LEVEL)
5176 goto err; // too many components provided
5177 *pos = '\0'; // modify input and avoid more copying
5178 components[level++] = ++pos; // expect something after ","
5179 }
5180
5182 if (absolute)
5183 __kmp_hw_subset->set_absolute();
5184
5185 // Check each component
5186 for (int i = 0; i < level; ++i) {
5187 int core_level = 0;
5188 char *core_components[MAX_T_LEVEL];
5189 // Split possible core components by '&' delimiter
5190 pos = components[i];
5191 core_components[core_level++] = pos;
5192 while ((pos = strchr(pos, '&'))) {
5193 if (core_level >= MAX_T_LEVEL)
5194 goto err; // too many different core types
5195 *pos = '\0'; // modify input and avoid more copying
5196 core_components[core_level++] = ++pos; // expect something after '&'
5197 }
5198
5199 for (int j = 0; j < core_level; ++j) {
5200 char *offset_ptr;
5201 char *attr_ptr;
5202 int offset = 0;
5203 kmp_hw_attr_t attr;
5204 int num;
5205 // components may begin with an optional count of the number of resources
5206 if (isdigit(*core_components[j])) {
5207 num = atoi(core_components[j]);
5208 if (num <= 0) {
5209 goto err; // only positive integers are valid for count
5210 }
5211 pos = core_components[j] + strspn(core_components[j], digits);
5212 } else if (*core_components[j] == '*') {
5214 pos = core_components[j] + 1;
5215 } else {
5217 pos = core_components[j];
5218 }
5219
5220 offset_ptr = strchr(core_components[j], '@');
5221 attr_ptr = strchr(core_components[j], ':');
5222
5223 if (offset_ptr) {
5224 offset = atoi(offset_ptr + 1); // save offset
5225 *offset_ptr = '\0'; // cut the offset from the component
5226 }
5227 if (attr_ptr) {
5228 attr.clear();
5229 // save the attribute
5230#if KMP_ARCH_X86 || KMP_ARCH_X86_64
5231 if (__kmp_str_match("intel_core", -1, attr_ptr + 1)) {
5232 attr.set_core_type(KMP_HW_CORE_TYPE_CORE);
5233 } else if (__kmp_str_match("intel_atom", -1, attr_ptr + 1)) {
5234 attr.set_core_type(KMP_HW_CORE_TYPE_ATOM);
5235 } else
5236#endif
5237 if (__kmp_str_match("eff", 3, attr_ptr + 1)) {
5238 const char *number = attr_ptr + 1;
5239 // skip the eff[iciency] token
5240 while (isalpha(*number))
5241 number++;
5242 if (!isdigit(*number)) {
5243 goto err;
5244 }
5245 int efficiency = atoi(number);
5246 attr.set_core_eff(efficiency);
5247 } else {
5248 goto err;
5249 }
5250 *attr_ptr = '\0'; // cut the attribute from the component
5251 }
5252 // detect the component type
5254 if (type == KMP_HW_UNKNOWN) {
5255 goto err;
5256 }
5257 // Only the core type can have attributes
5258 if (attr && type != KMP_HW_CORE)
5259 goto err;
5260 // Must allow core be specified more than once
5261 if (type != KMP_HW_CORE && __kmp_hw_subset->specified(type)) {
5262 goto err;
5263 }
5264 __kmp_hw_subset->push_back(num, type, offset, attr);
5265 }
5266 }
5267 return;
5268err:
5269 KMP_WARNING(AffHWSubsetInvalid, name, value);
5270 if (__kmp_hw_subset) {
5272 __kmp_hw_subset = nullptr;
5273 }
5274 return;
5275}
5276
5277static void __kmp_stg_print_hw_subset(kmp_str_buf_t *buffer, char const *name,
5278 void *data) {
5280 int depth;
5281 if (!__kmp_hw_subset)
5282 return;
5284 if (__kmp_env_format)
5286 else
5287 __kmp_str_buf_print(buffer, " %s='", name);
5288
5289 depth = __kmp_hw_subset->get_depth();
5290 for (int i = 0; i < depth; ++i) {
5291 const auto &item = __kmp_hw_subset->at(i);
5292 if (i > 0)
5293 __kmp_str_buf_print(&buf, "%c", ',');
5294 for (int j = 0; j < item.num_attrs; ++j) {
5295 __kmp_str_buf_print(&buf, "%s%d%s", (j > 0 ? "&" : ""), item.num[j],
5296 __kmp_hw_get_keyword(item.type));
5297 if (item.attr[j].is_core_type_valid())
5299 &buf, ":%s",
5300 __kmp_hw_get_core_type_keyword(item.attr[j].get_core_type()));
5301 if (item.attr[j].is_core_eff_valid())
5302 __kmp_str_buf_print(&buf, ":eff%d", item.attr[j].get_core_eff());
5303 if (item.offset[j])
5304 __kmp_str_buf_print(&buf, "@%d", item.offset[j]);
5305 }
5306 }
5307 __kmp_str_buf_print(buffer, "%s'\n", buf.str);
5309}
5310
5311#if USE_ITT_BUILD
5312// -----------------------------------------------------------------------------
5313// KMP_FORKJOIN_FRAMES
5314
5315static void __kmp_stg_parse_forkjoin_frames(char const *name, char const *value,
5316 void *data) {
5317 __kmp_stg_parse_bool(name, value, &__kmp_forkjoin_frames);
5318} // __kmp_stg_parse_forkjoin_frames
5319
5320static void __kmp_stg_print_forkjoin_frames(kmp_str_buf_t *buffer,
5321 char const *name, void *data) {
5322 __kmp_stg_print_bool(buffer, name, __kmp_forkjoin_frames);
5323} // __kmp_stg_print_forkjoin_frames
5324
5325// -----------------------------------------------------------------------------
5326// KMP_FORKJOIN_FRAMES_MODE
5327
5328static void __kmp_stg_parse_forkjoin_frames_mode(char const *name,
5329 char const *value,
5330 void *data) {
5331 __kmp_stg_parse_int(name, value, 0, 3, &__kmp_forkjoin_frames_mode);
5332} // __kmp_stg_parse_forkjoin_frames
5333
5334static void __kmp_stg_print_forkjoin_frames_mode(kmp_str_buf_t *buffer,
5335 char const *name, void *data) {
5336 __kmp_stg_print_int(buffer, name, __kmp_forkjoin_frames_mode);
5337} // __kmp_stg_print_forkjoin_frames
5338#endif /* USE_ITT_BUILD */
5339
5340// -----------------------------------------------------------------------------
5341// KMP_ENABLE_TASK_THROTTLING
5342
5343static void __kmp_stg_parse_task_throttling(char const *name, char const *value,
5344 void *data) {
5346} // __kmp_stg_parse_task_throttling
5347
5349 char const *name, void *data) {
5351} // __kmp_stg_print_task_throttling
5352
5353#if KMP_HAVE_MWAIT || KMP_HAVE_UMWAIT
5354// -----------------------------------------------------------------------------
5355// KMP_USER_LEVEL_MWAIT
5356
5357static void __kmp_stg_parse_user_level_mwait(char const *name,
5358 char const *value, void *data) {
5359 __kmp_stg_parse_bool(name, value, &__kmp_user_level_mwait);
5360} // __kmp_stg_parse_user_level_mwait
5361
5362static void __kmp_stg_print_user_level_mwait(kmp_str_buf_t *buffer,
5363 char const *name, void *data) {
5364 __kmp_stg_print_bool(buffer, name, __kmp_user_level_mwait);
5365} // __kmp_stg_print_user_level_mwait
5366
5367// -----------------------------------------------------------------------------
5368// KMP_MWAIT_HINTS
5369
5370static void __kmp_stg_parse_mwait_hints(char const *name, char const *value,
5371 void *data) {
5372 __kmp_stg_parse_int(name, value, 0, INT_MAX, &__kmp_mwait_hints);
5373} // __kmp_stg_parse_mwait_hints
5374
5375static void __kmp_stg_print_mwait_hints(kmp_str_buf_t *buffer, char const *name,
5376 void *data) {
5377 __kmp_stg_print_int(buffer, name, __kmp_mwait_hints);
5378} // __kmp_stg_print_mwait_hints
5379
5380#endif // KMP_HAVE_MWAIT || KMP_HAVE_UMWAIT
5381
5382#if KMP_HAVE_UMWAIT
5383// -----------------------------------------------------------------------------
5384// KMP_TPAUSE
5385// 0 = don't use TPAUSE, 1 = use C0.1 state, 2 = use C0.2 state
5386
5387static void __kmp_stg_parse_tpause(char const *name, char const *value,
5388 void *data) {
5389 __kmp_stg_parse_int(name, value, 0, INT_MAX, &__kmp_tpause_state);
5390 if (__kmp_tpause_state != 0) {
5391 // The actual hint passed to tpause is: 0 for C0.2 and 1 for C0.1
5392 if (__kmp_tpause_state == 2) // use C0.2
5393 __kmp_tpause_hint = 0; // default was set to 1 for C0.1
5394 }
5395} // __kmp_stg_parse_tpause
5396
5397static void __kmp_stg_print_tpause(kmp_str_buf_t *buffer, char const *name,
5398 void *data) {
5399 __kmp_stg_print_int(buffer, name, __kmp_tpause_state);
5400} // __kmp_stg_print_tpause
5401#endif // KMP_HAVE_UMWAIT
5402
5403// -----------------------------------------------------------------------------
5404// OMP_DISPLAY_ENV
5405
5406static void __kmp_stg_parse_omp_display_env(char const *name, char const *value,
5407 void *data) {
5408 if (__kmp_str_match("VERBOSE", 1, value)) {
5410 } else {
5412 }
5413} // __kmp_stg_parse_omp_display_env
5414
5416 char const *name, void *data) {
5418 __kmp_stg_print_str(buffer, name, "VERBOSE");
5419 } else {
5421 }
5422} // __kmp_stg_print_omp_display_env
5423
5425 char const *value, void *data) {
5427 KMP_WARNING(EnvParallelWarn, name);
5428 return;
5429 } // read value before first parallel only
5431} // __kmp_stg_parse_omp_cancellation
5432
5434 char const *name, void *data) {
5436} // __kmp_stg_print_omp_cancellation
5437
5438#if OMPT_SUPPORT
5439int __kmp_tool = 1;
5440
5441static void __kmp_stg_parse_omp_tool(char const *name, char const *value,
5442 void *data) {
5443 __kmp_stg_parse_bool(name, value, &__kmp_tool);
5444} // __kmp_stg_parse_omp_tool
5445
5446static void __kmp_stg_print_omp_tool(kmp_str_buf_t *buffer, char const *name,
5447 void *data) {
5448 if (__kmp_env_format) {
5449 KMP_STR_BUF_PRINT_BOOL_EX(name, __kmp_tool, "enabled", "disabled");
5450 } else {
5451 __kmp_str_buf_print(buffer, " %s=%s\n", name,
5452 __kmp_tool ? "enabled" : "disabled");
5453 }
5454} // __kmp_stg_print_omp_tool
5455
5456char *__kmp_tool_libraries = NULL;
5457
5458static void __kmp_stg_parse_omp_tool_libraries(char const *name,
5459 char const *value, void *data) {
5460 __kmp_stg_parse_str(name, value, &__kmp_tool_libraries);
5461} // __kmp_stg_parse_omp_tool_libraries
5462
5463static void __kmp_stg_print_omp_tool_libraries(kmp_str_buf_t *buffer,
5464 char const *name, void *data) {
5465 if (__kmp_tool_libraries)
5466 __kmp_stg_print_str(buffer, name, __kmp_tool_libraries);
5467 else {
5468 if (__kmp_env_format) {
5470 } else {
5471 __kmp_str_buf_print(buffer, " %s", name);
5472 }
5473 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
5474 }
5475} // __kmp_stg_print_omp_tool_libraries
5476
5477char *__kmp_tool_verbose_init = NULL;
5478
5479static void __kmp_stg_parse_omp_tool_verbose_init(char const *name,
5480 char const *value,
5481 void *data) {
5482 __kmp_stg_parse_str(name, value, &__kmp_tool_verbose_init);
5483} // __kmp_stg_parse_omp_tool_libraries
5484
5485static void __kmp_stg_print_omp_tool_verbose_init(kmp_str_buf_t *buffer,
5486 char const *name,
5487 void *data) {
5488 if (__kmp_tool_verbose_init)
5489 __kmp_stg_print_str(buffer, name, __kmp_tool_verbose_init);
5490 else {
5491 if (__kmp_env_format) {
5493 } else {
5494 __kmp_str_buf_print(buffer, " %s", name);
5495 }
5496 __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
5497 }
5498} // __kmp_stg_print_omp_tool_verbose_init
5499
5500#endif
5501
5502// Table.
5503
5505
5506 {"KMP_ALL_THREADS", __kmp_stg_parse_device_thread_limit, NULL, NULL, 0, 0},
5508 NULL, 0, 0},
5510 NULL, 0, 0},
5511 {"KMP_DUPLICATE_LIB_OK", __kmp_stg_parse_duplicate_lib_ok,
5514 NULL, 0, 0},
5515 {"KMP_DEVICE_THREAD_LIMIT", __kmp_stg_parse_device_thread_limit,
5517#if KMP_USE_MONITOR
5518 {"KMP_MONITOR_STACKSIZE", __kmp_stg_parse_monitor_stacksize,
5519 __kmp_stg_print_monitor_stacksize, NULL, 0, 0},
5520#endif
5521 {"KMP_SETTINGS", __kmp_stg_parse_settings, __kmp_stg_print_settings, NULL,
5522 0, 0},
5523 {"KMP_STACKOFFSET", __kmp_stg_parse_stackoffset,
5524 __kmp_stg_print_stackoffset, NULL, 0, 0},
5526 NULL, 0, 0},
5527 {"KMP_STACKPAD", __kmp_stg_parse_stackpad, __kmp_stg_print_stackpad, NULL,
5528 0, 0},
5529 {"KMP_VERSION", __kmp_stg_parse_version, __kmp_stg_print_version, NULL, 0,
5530 0},
5531 {"KMP_WARNINGS", __kmp_stg_parse_warnings, __kmp_stg_print_warnings, NULL,
5532 0, 0},
5533
5534 {"KMP_NESTING_MODE", __kmp_stg_parse_nesting_mode,
5535 __kmp_stg_print_nesting_mode, NULL, 0, 0},
5536 {"OMP_NESTED", __kmp_stg_parse_nested, __kmp_stg_print_nested, NULL, 0, 0},
5537 {"OMP_NUM_THREADS", __kmp_stg_parse_num_threads,
5538 __kmp_stg_print_num_threads, NULL, 0, 0},
5540 NULL, 0, 0},
5541
5542 {"KMP_TASKING", __kmp_stg_parse_tasking, __kmp_stg_print_tasking, NULL, 0,
5543 0},
5544 {"KMP_TASK_STEALING_CONSTRAINT", __kmp_stg_parse_task_stealing,
5545 __kmp_stg_print_task_stealing, NULL, 0, 0},
5546 {"OMP_MAX_ACTIVE_LEVELS", __kmp_stg_parse_max_active_levels,
5548 {"OMP_DEFAULT_DEVICE", __kmp_stg_parse_default_device,
5549 __kmp_stg_print_default_device, NULL, 0, 0},
5550 {"OMP_TARGET_OFFLOAD", __kmp_stg_parse_target_offload,
5551 __kmp_stg_print_target_offload, NULL, 0, 0},
5552 {"OMP_MAX_TASK_PRIORITY", __kmp_stg_parse_max_task_priority,
5554 {"KMP_TASKLOOP_MIN_TASKS", __kmp_stg_parse_taskloop_min_tasks,
5556 {"OMP_THREAD_LIMIT", __kmp_stg_parse_thread_limit,
5557 __kmp_stg_print_thread_limit, NULL, 0, 0},
5558 {"KMP_TEAMS_THREAD_LIMIT", __kmp_stg_parse_teams_thread_limit,
5560 {"OMP_NUM_TEAMS", __kmp_stg_parse_nteams, __kmp_stg_print_nteams, NULL, 0,
5561 0},
5562 {"OMP_TEAMS_THREAD_LIMIT", __kmp_stg_parse_teams_th_limit,
5563 __kmp_stg_print_teams_th_limit, NULL, 0, 0},
5564 {"OMP_WAIT_POLICY", __kmp_stg_parse_wait_policy,
5565 __kmp_stg_print_wait_policy, NULL, 0, 0},
5566 {"KMP_DISP_NUM_BUFFERS", __kmp_stg_parse_disp_buffers,
5567 __kmp_stg_print_disp_buffers, NULL, 0, 0},
5568 {"KMP_HOT_TEAMS_MAX_LEVEL", __kmp_stg_parse_hot_teams_level,
5570 {"KMP_HOT_TEAMS_MODE", __kmp_stg_parse_hot_teams_mode,
5571 __kmp_stg_print_hot_teams_mode, NULL, 0, 0},
5572
5573#if KMP_HANDLE_SIGNALS
5574 {"KMP_HANDLE_SIGNALS", __kmp_stg_parse_handle_signals,
5575 __kmp_stg_print_handle_signals, NULL, 0, 0},
5576#endif
5577
5578#if KMP_ARCH_X86 || KMP_ARCH_X86_64
5579 {"KMP_INHERIT_FP_CONTROL", __kmp_stg_parse_inherit_fp_control,
5580 __kmp_stg_print_inherit_fp_control, NULL, 0, 0},
5581#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
5582
5583#ifdef KMP_GOMP_COMPAT
5584 {"GOMP_STACKSIZE", __kmp_stg_parse_stacksize, NULL, NULL, 0, 0},
5585#endif
5586
5587#ifdef KMP_DEBUG
5588 {"KMP_A_DEBUG", __kmp_stg_parse_a_debug, __kmp_stg_print_a_debug, NULL, 0,
5589 0},
5590 {"KMP_B_DEBUG", __kmp_stg_parse_b_debug, __kmp_stg_print_b_debug, NULL, 0,
5591 0},
5592 {"KMP_C_DEBUG", __kmp_stg_parse_c_debug, __kmp_stg_print_c_debug, NULL, 0,
5593 0},
5594 {"KMP_D_DEBUG", __kmp_stg_parse_d_debug, __kmp_stg_print_d_debug, NULL, 0,
5595 0},
5596 {"KMP_E_DEBUG", __kmp_stg_parse_e_debug, __kmp_stg_print_e_debug, NULL, 0,
5597 0},
5598 {"KMP_F_DEBUG", __kmp_stg_parse_f_debug, __kmp_stg_print_f_debug, NULL, 0,
5599 0},
5600 {"KMP_DEBUG", __kmp_stg_parse_debug, NULL, /* no print */ NULL, 0, 0},
5601 {"KMP_DEBUG_BUF", __kmp_stg_parse_debug_buf, __kmp_stg_print_debug_buf,
5602 NULL, 0, 0},
5603 {"KMP_DEBUG_BUF_ATOMIC", __kmp_stg_parse_debug_buf_atomic,
5604 __kmp_stg_print_debug_buf_atomic, NULL, 0, 0},
5605 {"KMP_DEBUG_BUF_CHARS", __kmp_stg_parse_debug_buf_chars,
5606 __kmp_stg_print_debug_buf_chars, NULL, 0, 0},
5607 {"KMP_DEBUG_BUF_LINES", __kmp_stg_parse_debug_buf_lines,
5608 __kmp_stg_print_debug_buf_lines, NULL, 0, 0},
5609 {"KMP_DIAG", __kmp_stg_parse_diag, __kmp_stg_print_diag, NULL, 0, 0},
5610
5611 {"KMP_PAR_RANGE", __kmp_stg_parse_par_range_env,
5612 __kmp_stg_print_par_range_env, NULL, 0, 0},
5613#endif // KMP_DEBUG
5614
5615 {"KMP_ALIGN_ALLOC", __kmp_stg_parse_align_alloc,
5616 __kmp_stg_print_align_alloc, NULL, 0, 0},
5617
5618 {"KMP_PLAIN_BARRIER", __kmp_stg_parse_barrier_branch_bit,
5620 {"KMP_PLAIN_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern,
5622 {"KMP_FORKJOIN_BARRIER", __kmp_stg_parse_barrier_branch_bit,
5624 {"KMP_FORKJOIN_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern,
5626#if KMP_FAST_REDUCTION_BARRIER
5627 {"KMP_REDUCTION_BARRIER", __kmp_stg_parse_barrier_branch_bit,
5629 {"KMP_REDUCTION_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern,
5631#endif
5632
5633 {"KMP_ABORT_DELAY", __kmp_stg_parse_abort_delay,
5634 __kmp_stg_print_abort_delay, NULL, 0, 0},
5635 {"KMP_CPUINFO_FILE", __kmp_stg_parse_cpuinfo_file,
5636 __kmp_stg_print_cpuinfo_file, NULL, 0, 0},
5637 {"KMP_FORCE_REDUCTION", __kmp_stg_parse_force_reduction,
5639 {"KMP_DETERMINISTIC_REDUCTION", __kmp_stg_parse_force_reduction,
5641 {"KMP_STORAGE_MAP", __kmp_stg_parse_storage_map,
5642 __kmp_stg_print_storage_map, NULL, 0, 0},
5643 {"KMP_ALL_THREADPRIVATE", __kmp_stg_parse_all_threadprivate,
5645 {"KMP_FOREIGN_THREADS_THREADPRIVATE",
5648
5649#if KMP_AFFINITY_SUPPORTED
5650 {"KMP_AFFINITY", __kmp_stg_parse_affinity, __kmp_stg_print_affinity, NULL,
5651 0, 0},
5652 {"KMP_HIDDEN_HELPER_AFFINITY", __kmp_stg_parse_hh_affinity,
5653 __kmp_stg_print_hh_affinity, NULL, 0, 0},
5654#ifdef KMP_GOMP_COMPAT
5655 {"GOMP_CPU_AFFINITY", __kmp_stg_parse_gomp_cpu_affinity, NULL,
5656 /* no print */ NULL, 0, 0},
5657#endif /* KMP_GOMP_COMPAT */
5659 NULL, 0, 0},
5660 {"KMP_TEAMS_PROC_BIND", __kmp_stg_parse_teams_proc_bind,
5661 __kmp_stg_print_teams_proc_bind, NULL, 0, 0},
5662 {"OMP_PLACES", __kmp_stg_parse_places, __kmp_stg_print_places, NULL, 0, 0},
5663 {"KMP_TOPOLOGY_METHOD", __kmp_stg_parse_topology_method,
5664 __kmp_stg_print_topology_method, NULL, 0, 0},
5665
5666#else
5667
5668 // KMP_AFFINITY is not supported on OS X*, nor is OMP_PLACES.
5669 // OMP_PROC_BIND and proc-bind-var are supported, however.
5671 NULL, 0, 0},
5672
5673#endif // KMP_AFFINITY_SUPPORTED
5674 {"OMP_DISPLAY_AFFINITY", __kmp_stg_parse_display_affinity,
5676 {"OMP_AFFINITY_FORMAT", __kmp_stg_parse_affinity_format,
5678 {"KMP_INIT_AT_FORK", __kmp_stg_parse_init_at_fork,
5679 __kmp_stg_print_init_at_fork, NULL, 0, 0},
5680 {"KMP_SCHEDULE", __kmp_stg_parse_schedule, __kmp_stg_print_schedule, NULL,
5681 0, 0},
5683 NULL, 0, 0},
5684#if KMP_USE_HIER_SCHED
5685 {"KMP_DISP_HAND_THREAD", __kmp_stg_parse_kmp_hand_thread,
5686 __kmp_stg_print_kmp_hand_thread, NULL, 0, 0},
5687#endif
5688 {"KMP_FORCE_MONOTONIC_DYNAMIC_SCHEDULE",
5690 NULL, 0, 0},
5691 {"KMP_ATOMIC_MODE", __kmp_stg_parse_atomic_mode,
5692 __kmp_stg_print_atomic_mode, NULL, 0, 0},
5693 {"KMP_CONSISTENCY_CHECK", __kmp_stg_parse_consistency_check,
5695
5696#if USE_ITT_BUILD && USE_ITT_NOTIFY
5697 {"KMP_ITT_PREPARE_DELAY", __kmp_stg_parse_itt_prepare_delay,
5698 __kmp_stg_print_itt_prepare_delay, NULL, 0, 0},
5699#endif /* USE_ITT_BUILD && USE_ITT_NOTIFY */
5700 {"KMP_MALLOC_POOL_INCR", __kmp_stg_parse_malloc_pool_incr,
5703 NULL, 0, 0},
5705 NULL, 0, 0},
5706 {"KMP_DYNAMIC_MODE", __kmp_stg_parse_kmp_dynamic_mode,
5708
5709#ifdef USE_LOAD_BALANCE
5710 {"KMP_LOAD_BALANCE_INTERVAL", __kmp_stg_parse_ld_balance_interval,
5711 __kmp_stg_print_ld_balance_interval, NULL, 0, 0},
5712#endif
5713
5714 {"KMP_NUM_LOCKS_IN_BLOCK", __kmp_stg_parse_lock_block,
5715 __kmp_stg_print_lock_block, NULL, 0, 0},
5717 NULL, 0, 0},
5718 {"KMP_SPIN_BACKOFF_PARAMS", __kmp_stg_parse_spin_backoff_params,
5720#if KMP_USE_ADAPTIVE_LOCKS
5721 {"KMP_ADAPTIVE_LOCK_PROPS", __kmp_stg_parse_adaptive_lock_props,
5722 __kmp_stg_print_adaptive_lock_props, NULL, 0, 0},
5723#if KMP_DEBUG_ADAPTIVE_LOCKS
5724 {"KMP_SPECULATIVE_STATSFILE", __kmp_stg_parse_speculative_statsfile,
5725 __kmp_stg_print_speculative_statsfile, NULL, 0, 0},
5726#endif
5727#endif // KMP_USE_ADAPTIVE_LOCKS
5729 NULL, 0, 0},
5731 NULL, 0, 0},
5732#if USE_ITT_BUILD
5733 {"KMP_FORKJOIN_FRAMES", __kmp_stg_parse_forkjoin_frames,
5734 __kmp_stg_print_forkjoin_frames, NULL, 0, 0},
5735 {"KMP_FORKJOIN_FRAMES_MODE", __kmp_stg_parse_forkjoin_frames_mode,
5736 __kmp_stg_print_forkjoin_frames_mode, NULL, 0, 0},
5737#endif
5738 {"KMP_ENABLE_TASK_THROTTLING", __kmp_stg_parse_task_throttling,
5740
5741 {"OMP_DISPLAY_ENV", __kmp_stg_parse_omp_display_env,
5743 {"OMP_CANCELLATION", __kmp_stg_parse_omp_cancellation,
5746 NULL, 0, 0},
5747 {"LIBOMP_USE_HIDDEN_HELPER_TASK", __kmp_stg_parse_use_hidden_helper,
5749 {"LIBOMP_NUM_HIDDEN_HELPER_THREADS",
5752#if OMP_TASKGRAPH_EXPERIMENTAL
5753 {"KMP_MAX_TDGS", __kmp_stg_parse_max_tdgs, __kmp_std_print_max_tdgs, NULL,
5754 0, 0},
5755 {"KMP_TDG_DOT", __kmp_stg_parse_tdg_dot, __kmp_stg_print_tdg_dot, NULL, 0,
5756 0},
5757#endif
5758
5759#if OMPT_SUPPORT
5760 {"OMP_TOOL", __kmp_stg_parse_omp_tool, __kmp_stg_print_omp_tool, NULL, 0,
5761 0},
5762 {"OMP_TOOL_LIBRARIES", __kmp_stg_parse_omp_tool_libraries,
5763 __kmp_stg_print_omp_tool_libraries, NULL, 0, 0},
5764 {"OMP_TOOL_VERBOSE_INIT", __kmp_stg_parse_omp_tool_verbose_init,
5765 __kmp_stg_print_omp_tool_verbose_init, NULL, 0, 0},
5766#endif
5767
5768#if KMP_HAVE_MWAIT || KMP_HAVE_UMWAIT
5769 {"KMP_USER_LEVEL_MWAIT", __kmp_stg_parse_user_level_mwait,
5770 __kmp_stg_print_user_level_mwait, NULL, 0, 0},
5771 {"KMP_MWAIT_HINTS", __kmp_stg_parse_mwait_hints,
5772 __kmp_stg_print_mwait_hints, NULL, 0, 0},
5773#endif
5774
5775#if KMP_HAVE_UMWAIT
5776 {"KMP_TPAUSE", __kmp_stg_parse_tpause, __kmp_stg_print_tpause, NULL, 0, 0},
5777#endif
5778 {"", NULL, NULL, NULL, 0, 0}}; // settings
5779
5780static int const __kmp_stg_count =
5781 sizeof(__kmp_stg_table) / sizeof(kmp_setting_t);
5782
5783static inline kmp_setting_t *__kmp_stg_find(char const *name) {
5784
5785 int i;
5786 if (name != NULL) {
5787 for (i = 0; i < __kmp_stg_count; ++i) {
5788 if (strcmp(__kmp_stg_table[i].name, name) == 0) {
5789 return &__kmp_stg_table[i];
5790 }
5791 }
5792 }
5793 return NULL;
5794
5795} // __kmp_stg_find
5796
5797static int __kmp_stg_cmp(void const *_a, void const *_b) {
5798 const kmp_setting_t *a = RCAST(const kmp_setting_t *, _a);
5799 const kmp_setting_t *b = RCAST(const kmp_setting_t *, _b);
5800
5801 // Process KMP_AFFINITY last.
5802 // It needs to come after OMP_PLACES and GOMP_CPU_AFFINITY.
5803 if (strcmp(a->name, "KMP_AFFINITY") == 0) {
5804 if (strcmp(b->name, "KMP_AFFINITY") == 0) {
5805 return 0;
5806 }
5807 return 1;
5808 } else if (strcmp(b->name, "KMP_AFFINITY") == 0) {
5809 return -1;
5810 }
5811 return strcmp(a->name, b->name);
5812} // __kmp_stg_cmp
5813
5814static void __kmp_stg_init(void) {
5815
5816 static int initialized = 0;
5817
5818 if (!initialized) {
5819
5820 // Sort table.
5821 qsort(__kmp_stg_table, __kmp_stg_count - 1, sizeof(kmp_setting_t),
5823
5824 { // Initialize *_STACKSIZE data.
5825 kmp_setting_t *kmp_stacksize =
5826 __kmp_stg_find("KMP_STACKSIZE"); // 1st priority.
5827#ifdef KMP_GOMP_COMPAT
5828 kmp_setting_t *gomp_stacksize =
5829 __kmp_stg_find("GOMP_STACKSIZE"); // 2nd priority.
5830#endif
5831 kmp_setting_t *omp_stacksize =
5832 __kmp_stg_find("OMP_STACKSIZE"); // 3rd priority.
5833
5834 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5835 // !!! Compiler does not understand rivals is used and optimizes out
5836 // assignments
5837 // !!! rivals[ i ++ ] = ...;
5838 static kmp_setting_t *volatile rivals[4];
5839 static kmp_stg_ss_data_t kmp_data = {1, CCAST(kmp_setting_t **, rivals)};
5840#ifdef KMP_GOMP_COMPAT
5841 static kmp_stg_ss_data_t gomp_data = {1024,
5842 CCAST(kmp_setting_t **, rivals)};
5843#endif
5844 static kmp_stg_ss_data_t omp_data = {1024,
5845 CCAST(kmp_setting_t **, rivals)};
5846 int i = 0;
5847
5848 rivals[i++] = kmp_stacksize;
5849#ifdef KMP_GOMP_COMPAT
5850 if (gomp_stacksize != NULL) {
5851 rivals[i++] = gomp_stacksize;
5852 }
5853#endif
5854 rivals[i++] = omp_stacksize;
5855 rivals[i++] = NULL;
5856
5857 kmp_stacksize->data = &kmp_data;
5858#ifdef KMP_GOMP_COMPAT
5859 if (gomp_stacksize != NULL) {
5860 gomp_stacksize->data = &gomp_data;
5861 }
5862#endif
5863 omp_stacksize->data = &omp_data;
5864 }
5865
5866 { // Initialize KMP_LIBRARY and OMP_WAIT_POLICY data.
5867 kmp_setting_t *kmp_library =
5868 __kmp_stg_find("KMP_LIBRARY"); // 1st priority.
5869 kmp_setting_t *omp_wait_policy =
5870 __kmp_stg_find("OMP_WAIT_POLICY"); // 2nd priority.
5871
5872 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5873 static kmp_setting_t *volatile rivals[3];
5874 static kmp_stg_wp_data_t kmp_data = {0, CCAST(kmp_setting_t **, rivals)};
5875 static kmp_stg_wp_data_t omp_data = {1, CCAST(kmp_setting_t **, rivals)};
5876 int i = 0;
5877
5878 rivals[i++] = kmp_library;
5879 if (omp_wait_policy != NULL) {
5880 rivals[i++] = omp_wait_policy;
5881 }
5882 rivals[i++] = NULL;
5883
5884 kmp_library->data = &kmp_data;
5885 if (omp_wait_policy != NULL) {
5886 omp_wait_policy->data = &omp_data;
5887 }
5888 }
5889
5890 { // Initialize KMP_DEVICE_THREAD_LIMIT and KMP_ALL_THREADS
5891 kmp_setting_t *kmp_device_thread_limit =
5892 __kmp_stg_find("KMP_DEVICE_THREAD_LIMIT"); // 1st priority.
5893 kmp_setting_t *kmp_all_threads =
5894 __kmp_stg_find("KMP_ALL_THREADS"); // 2nd priority.
5895
5896 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5897 static kmp_setting_t *volatile rivals[3];
5898 int i = 0;
5899
5900 rivals[i++] = kmp_device_thread_limit;
5901 rivals[i++] = kmp_all_threads;
5902 rivals[i++] = NULL;
5903
5904 kmp_device_thread_limit->data = CCAST(kmp_setting_t **, rivals);
5905 kmp_all_threads->data = CCAST(kmp_setting_t **, rivals);
5906 }
5907
5908 { // Initialize KMP_HW_SUBSET and KMP_PLACE_THREADS
5909 // 1st priority
5910 kmp_setting_t *kmp_hw_subset = __kmp_stg_find("KMP_HW_SUBSET");
5911 // 2nd priority
5912 kmp_setting_t *kmp_place_threads = __kmp_stg_find("KMP_PLACE_THREADS");
5913
5914 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5915 static kmp_setting_t *volatile rivals[3];
5916 int i = 0;
5917
5918 rivals[i++] = kmp_hw_subset;
5919 rivals[i++] = kmp_place_threads;
5920 rivals[i++] = NULL;
5921
5922 kmp_hw_subset->data = CCAST(kmp_setting_t **, rivals);
5923 kmp_place_threads->data = CCAST(kmp_setting_t **, rivals);
5924 }
5925
5926#if KMP_AFFINITY_SUPPORTED
5927 { // Initialize KMP_AFFINITY, GOMP_CPU_AFFINITY, and OMP_PROC_BIND data.
5928 kmp_setting_t *kmp_affinity =
5929 __kmp_stg_find("KMP_AFFINITY"); // 1st priority.
5930 KMP_DEBUG_ASSERT(kmp_affinity != NULL);
5931
5932#ifdef KMP_GOMP_COMPAT
5933 kmp_setting_t *gomp_cpu_affinity =
5934 __kmp_stg_find("GOMP_CPU_AFFINITY"); // 2nd priority.
5935 KMP_DEBUG_ASSERT(gomp_cpu_affinity != NULL);
5936#endif
5937
5938 kmp_setting_t *omp_proc_bind =
5939 __kmp_stg_find("OMP_PROC_BIND"); // 3rd priority.
5940 KMP_DEBUG_ASSERT(omp_proc_bind != NULL);
5941
5942 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5943 static kmp_setting_t *volatile rivals[4];
5944 int i = 0;
5945
5946 rivals[i++] = kmp_affinity;
5947
5948#ifdef KMP_GOMP_COMPAT
5949 rivals[i++] = gomp_cpu_affinity;
5950 gomp_cpu_affinity->data = CCAST(kmp_setting_t **, rivals);
5951#endif
5952
5953 rivals[i++] = omp_proc_bind;
5954 omp_proc_bind->data = CCAST(kmp_setting_t **, rivals);
5955 rivals[i++] = NULL;
5956
5957 static kmp_setting_t *volatile places_rivals[4];
5958 i = 0;
5959
5960 kmp_setting_t *omp_places = __kmp_stg_find("OMP_PLACES"); // 3rd priority.
5961 KMP_DEBUG_ASSERT(omp_places != NULL);
5962
5963 places_rivals[i++] = kmp_affinity;
5964#ifdef KMP_GOMP_COMPAT
5965 places_rivals[i++] = gomp_cpu_affinity;
5966#endif
5967 places_rivals[i++] = omp_places;
5968 omp_places->data = CCAST(kmp_setting_t **, places_rivals);
5969 places_rivals[i++] = NULL;
5970 }
5971#else
5972// KMP_AFFINITY not supported, so OMP_PROC_BIND has no rivals.
5973// OMP_PLACES not supported yet.
5974#endif // KMP_AFFINITY_SUPPORTED
5975
5976 { // Initialize KMP_DETERMINISTIC_REDUCTION and KMP_FORCE_REDUCTION data.
5977 kmp_setting_t *kmp_force_red =
5978 __kmp_stg_find("KMP_FORCE_REDUCTION"); // 1st priority.
5979 kmp_setting_t *kmp_determ_red =
5980 __kmp_stg_find("KMP_DETERMINISTIC_REDUCTION"); // 2nd priority.
5981
5982 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5983 static kmp_setting_t *volatile rivals[3];
5984 static kmp_stg_fr_data_t force_data = {1,
5985 CCAST(kmp_setting_t **, rivals)};
5986 static kmp_stg_fr_data_t determ_data = {0,
5987 CCAST(kmp_setting_t **, rivals)};
5988 int i = 0;
5989
5990 rivals[i++] = kmp_force_red;
5991 if (kmp_determ_red != NULL) {
5992 rivals[i++] = kmp_determ_red;
5993 }
5994 rivals[i++] = NULL;
5995
5996 kmp_force_red->data = &force_data;
5997 if (kmp_determ_red != NULL) {
5998 kmp_determ_red->data = &determ_data;
5999 }
6000 }
6001
6002 initialized = 1;
6003 }
6004
6005 // Reset flags.
6006 int i;
6007 for (i = 0; i < __kmp_stg_count; ++i) {
6008 __kmp_stg_table[i].set = 0;
6009 }
6010
6011} // __kmp_stg_init
6012
6013static void __kmp_stg_parse(char const *name, char const *value) {
6014 // On Windows* OS there are some nameless variables like "C:=C:\" (yeah,
6015 // really nameless, they are presented in environment block as
6016 // "=C:=C\\\x00=D:=D:\\\x00...", so let us skip them.
6017 if (name[0] == 0) {
6018 return;
6019 }
6020
6021 if (value != NULL) {
6022 kmp_setting_t *setting = __kmp_stg_find(name);
6023 if (setting != NULL) {
6024 setting->parse(name, value, setting->data);
6025 setting->defined = 1;
6026 }
6027 }
6028
6029} // __kmp_stg_parse
6030
6031static int __kmp_stg_check_rivals( // 0 -- Ok, 1 -- errors found.
6032 char const *name, // Name of variable.
6033 char const *value, // Value of the variable.
6034 kmp_setting_t **rivals // List of rival settings (must include current one).
6035) {
6036
6037 if (rivals == NULL) {
6038 return 0;
6039 }
6040
6041 // Loop thru higher priority settings (listed before current).
6042 int i = 0;
6043 for (; strcmp(rivals[i]->name, name) != 0; i++) {
6044 KMP_DEBUG_ASSERT(rivals[i] != NULL);
6045
6046#if KMP_AFFINITY_SUPPORTED
6047 if (rivals[i] == __kmp_affinity_notype) {
6048 // If KMP_AFFINITY is specified without a type name,
6049 // it does not rival OMP_PROC_BIND or GOMP_CPU_AFFINITY.
6050 continue;
6051 }
6052#endif
6053
6054 if (rivals[i]->set) {
6055 KMP_WARNING(StgIgnored, name, rivals[i]->name);
6056 return 1;
6057 }
6058 }
6059
6060 ++i; // Skip current setting.
6061 return 0;
6062
6063} // __kmp_stg_check_rivals
6064
6065static int __kmp_env_toPrint(char const *name, int flag) {
6066 int rc = 0;
6067 kmp_setting_t *setting = __kmp_stg_find(name);
6068 if (setting != NULL) {
6069 rc = setting->defined;
6070 if (flag >= 0) {
6071 setting->defined = flag;
6072 }
6073 }
6074 return rc;
6075}
6076
6077#if defined(KMP_DEBUG) && KMP_AFFINITY_SUPPORTED
6078static void __kmp_print_affinity_settings(const kmp_affinity_t *affinity) {
6079 K_DIAG(1, ("%s:\n", affinity->env_var));
6080 K_DIAG(1, (" type : %d\n", affinity->type));
6081 K_DIAG(1, (" compact : %d\n", affinity->compact));
6082 K_DIAG(1, (" offset : %d\n", affinity->offset));
6083 K_DIAG(1, (" verbose : %u\n", affinity->flags.verbose));
6084 K_DIAG(1, (" warnings : %u\n", affinity->flags.warnings));
6085 K_DIAG(1, (" respect : %u\n", affinity->flags.respect));
6086 K_DIAG(1, (" reset : %u\n", affinity->flags.reset));
6087 K_DIAG(1, (" dups : %u\n", affinity->flags.dups));
6088 K_DIAG(1, (" gran : %d\n", (int)affinity->gran));
6089 KMP_DEBUG_ASSERT(affinity->type != affinity_default);
6090}
6091#endif
6092
6093// If `base_name` is on the device-scope eligible list, return the value of
6094// `<base_name>_ALL` from `block` (or NULL). Returns NULL for non-eligible
6095// names.
6097 char const *base_name) {
6098 for (int e = 0;; ++e) {
6099 char const *base = __kmp_device_env_eligible_name(e);
6100 if (base == NULL)
6101 return NULL;
6102 if (strcmp(base, base_name) != 0)
6103 continue;
6104 char *all_name = __kmp_str_format("%s_ALL", base_name);
6105 char const *value = __kmp_env_blk_var(block, all_name);
6106 __kmp_str_free(&all_name);
6107 return value;
6108 }
6109}
6110
6112
6113 char const *value;
6114
6115 /* OMP_NUM_THREADS */
6116 value = __kmp_env_blk_var(block, "OMP_NUM_THREADS");
6117 if (value == NULL)
6118 value = __kmp_aux_env_blk_all_fallback(block, "OMP_NUM_THREADS");
6119 if (value) {
6121 }
6122
6123 /* KMP_BLOCKTIME */
6124 value = __kmp_env_blk_var(block, "KMP_BLOCKTIME");
6125 if (value) {
6126 int gtid, tid;
6127 kmp_info_t *thread;
6128
6129 gtid = __kmp_entry_gtid();
6130 tid = __kmp_tid_from_gtid(gtid);
6131 thread = __kmp_thread_from_gtid(gtid);
6133 }
6134
6135 /* OMP_NESTED */
6136 value = __kmp_env_blk_var(block, "OMP_NESTED");
6137 if (value) {
6139 }
6140
6141 /* OMP_DYNAMIC */
6142 value = __kmp_env_blk_var(block, "OMP_DYNAMIC");
6143 if (value) {
6144 ompc_set_dynamic(__kmp_global.g.g_dynamic);
6145 }
6146}
6147
6148void __kmp_env_initialize(char const *string) {
6149
6150 kmp_env_blk_t block;
6151 int i;
6152
6154
6155 // Hack!!!
6156 if (string == NULL) {
6157 // __kmp_max_nth = __kmp_sys_max_nth;
6160 }
6161 __kmp_env_blk_init(&block, string);
6162
6163 // We need to know if blocktime and use_yield were set when processing
6164 // OMP_WAIT_POLICY
6165 blocktime_str = __kmp_env_blk_var(&block, "KMP_BLOCKTIME");
6166 use_yield_str = __kmp_env_blk_var(&block, "KMP_USE_YIELD");
6167
6168 // Special case. If we parse environment, not a string, process KMP_WARNINGS
6169 // first.
6170 if (string == NULL) {
6171 char const *name = "KMP_WARNINGS";
6172 char const *value = __kmp_env_blk_var(&block, name);
6174 }
6175
6176#if KMP_AFFINITY_SUPPORTED
6177 // Special case. KMP_AFFINITY is not a rival to other affinity env vars
6178 // if no affinity type is specified. We want to allow
6179 // KMP_AFFINITY=[no],verbose/[no]warnings/etc. to be enabled when
6180 // specifying the affinity type via GOMP_CPU_AFFINITY or the OMP 4.0
6181 // affinity mechanism.
6182 __kmp_affinity_notype = NULL;
6183 char const *aff_str = __kmp_env_blk_var(&block, "KMP_AFFINITY");
6184 if (aff_str != NULL) {
6185 // Check if the KMP_AFFINITY type is specified in the string.
6186 // We just search the string for "compact", "scatter", etc.
6187 // without really parsing the string. The syntax of the
6188 // KMP_AFFINITY env var is such that none of the affinity
6189 // type names can appear anywhere other that the type
6190 // specifier, even as substrings.
6191 //
6192 // I can't find a case-insensitive version of strstr on Windows* OS.
6193 // Use the case-sensitive version for now. AIX does the same.
6194
6195#if KMP_OS_WINDOWS || KMP_OS_AIX
6196#define FIND strstr
6197#else
6198#define FIND strcasestr
6199#endif
6200
6201 if ((FIND(aff_str, "none") == NULL) &&
6202 (FIND(aff_str, "physical") == NULL) &&
6203 (FIND(aff_str, "logical") == NULL) &&
6204 (FIND(aff_str, "compact") == NULL) &&
6205 (FIND(aff_str, "scatter") == NULL) &&
6206 (FIND(aff_str, "explicit") == NULL) &&
6207 (FIND(aff_str, "balanced") == NULL) &&
6208 (FIND(aff_str, "disabled") == NULL)) {
6209 __kmp_affinity_notype = __kmp_stg_find("KMP_AFFINITY");
6210 } else {
6211 // A new affinity type is specified.
6212 // Reset the affinity flags to their default values,
6213 // in case this is called from kmp_set_defaults().
6214 __kmp_affinity.type = affinity_default;
6215 __kmp_affinity.gran = KMP_HW_UNKNOWN;
6216 __kmp_affinity_top_method = affinity_top_method_default;
6217 __kmp_affinity.flags.respect = affinity_respect_mask_default;
6218 }
6219#undef FIND
6220
6221 // Also reset the affinity flags if OMP_PROC_BIND is specified.
6222 aff_str = __kmp_env_blk_var(&block, "OMP_PROC_BIND");
6223 if (aff_str != NULL) {
6224 __kmp_affinity.type = affinity_default;
6225 __kmp_affinity.gran = KMP_HW_UNKNOWN;
6226 __kmp_affinity_top_method = affinity_top_method_default;
6227 __kmp_affinity.flags.respect = affinity_respect_mask_default;
6228 }
6229 }
6230
6231#endif /* KMP_AFFINITY_SUPPORTED */
6232
6233 // Deliberately placed AFTER the KMP_WARNINGS special case above so that any
6234 // warnings the pre-pass emits (MalformedDeviceEnvVar /
6235 // DeviceEnvVarOnGlobalScope) honour the user-requested warning level.
6236 for (i = 0; i < block.count; ++i) {
6237 if ((block.vars[i].name == NULL) || (*block.vars[i].name == '\0')) {
6238 continue;
6239 }
6240 if (block.vars[i].value == NULL) {
6241 continue;
6242 }
6243 if (__kmp_device_env_record(block.vars[i].name, block.vars[i].value))
6244 continue;
6245
6246 kmp_setting_t *setting = __kmp_stg_find(block.vars[i].name);
6247 if (setting != NULL) {
6248 setting->set = 1;
6249 }
6250 }
6251
6252 // Set up the nested proc bind type vector.
6253 if (__kmp_nested_proc_bind.bind_types == NULL) {
6254 __kmp_nested_proc_bind.bind_types =
6256 if (__kmp_nested_proc_bind.bind_types == NULL) {
6257 KMP_FATAL(MemoryAllocFailed);
6258 }
6259 __kmp_nested_proc_bind.size = 1;
6260 __kmp_nested_proc_bind.used = 1;
6261#if KMP_AFFINITY_SUPPORTED
6263#else
6264 // default proc bind is false if affinity not supported
6266#endif
6267 }
6268
6269 // Set up the affinity format ICV
6270 // Grab the default affinity format string from the message catalog
6271 kmp_msg_t m =
6272 __kmp_msg_format(kmp_i18n_msg_AffFormatDefault, "%P", "%i", "%n", "%A");
6274
6275 if (__kmp_affinity_format == NULL) {
6277 (char *)KMP_INTERNAL_MALLOC(sizeof(char) * KMP_AFFINITY_FORMAT_SIZE);
6278 }
6280 __kmp_str_free(&m.str);
6281
6282 // Now process all of the settings.
6283 for (i = 0; i < block.count; ++i) {
6284 __kmp_stg_parse(block.vars[i].name, block.vars[i].value);
6285 }
6286
6287 // Device-scope env-var post-pass: when the current block has `<ENV>_ALL` but
6288 // no unsuffixed `<ENV>`, replay `_ALL` so the host ICV picks it up. We query
6289 // the block (not the registry) so an unrelated kmp_set_defaults does not
6290 // accidentally replay a stale `_ALL`.
6291 for (int e = 0;; ++e) {
6292 char const *base = __kmp_device_env_eligible_name(e);
6293 if (base == NULL)
6294 break;
6295 if (__kmp_env_blk_var(&block, base) != NULL)
6296 continue;
6297 char *all_name = __kmp_str_format("%s_ALL", base);
6298 char const *all_v = __kmp_env_blk_var(&block, all_name);
6299 __kmp_str_free(&all_name);
6300 if (all_v != NULL)
6301 __kmp_stg_parse(base, all_v);
6302 }
6303
6304 // If user locks have been allocated yet, don't reset the lock vptr table.
6305 if (!__kmp_init_user_locks) {
6308 }
6309#if KMP_USE_DYNAMIC_LOCK
6310 __kmp_init_dynamic_user_locks();
6311#else
6313#endif
6314 } else {
6315 KMP_DEBUG_ASSERT(string != NULL); // kmp_set_defaults() was called
6317// Binds lock functions again to follow the transition between different
6318// KMP_CONSISTENCY_CHECK values. Calling this again is harmless as long
6319// as we do not allow lock kind changes after making a call to any
6320// user lock functions (true).
6321#if KMP_USE_DYNAMIC_LOCK
6322 __kmp_init_dynamic_user_locks();
6323#else
6325#endif
6326 }
6327
6328#if KMP_AFFINITY_SUPPORTED
6329
6330 if (!TCR_4(__kmp_init_middle)) {
6331#if KMP_HWLOC_ENABLED
6332 // Force using hwloc when either tiles or numa nodes requested within
6333 // KMP_HW_SUBSET or granularity setting and no other topology method
6334 // is requested
6335 if (__kmp_hw_subset &&
6336 __kmp_affinity_top_method == affinity_top_method_default)
6337 if (__kmp_hw_subset->specified(KMP_HW_NUMA) ||
6338 __kmp_hw_subset->specified(KMP_HW_TILE) ||
6339 __kmp_affinity.gran == KMP_HW_TILE ||
6340 __kmp_affinity.gran == KMP_HW_NUMA)
6341 __kmp_affinity_top_method = affinity_top_method_hwloc;
6342 // Force using hwloc when tiles or numa nodes requested for OMP_PLACES
6343 if (__kmp_affinity.gran == KMP_HW_NUMA ||
6344 __kmp_affinity.gran == KMP_HW_TILE)
6345 __kmp_affinity_top_method = affinity_top_method_hwloc;
6346#endif // KMP_HWLOC_ENABLED
6347 // Determine if the machine/OS is actually capable of supporting
6348 // affinity.
6349 const char *var = "KMP_AFFINITY";
6350 KMPAffinity::pick_api();
6351#if KMP_HWLOC_ENABLED
6352 // If Hwloc topology discovery was requested but affinity was also disabled,
6353 // then tell user that Hwloc request is being ignored and use default
6354 // topology discovery method.
6355 if (__kmp_affinity_top_method == affinity_top_method_hwloc &&
6356 __kmp_affinity_dispatch->get_api_type() != KMPAffinity::HWLOC) {
6357 KMP_WARNING(AffIgnoringHwloc, var);
6358 __kmp_affinity_top_method = affinity_top_method_all;
6359 }
6360#endif // KMP_HWLOC_ENABLED
6361 if (__kmp_affinity.type == affinity_disabled) {
6362 KMP_AFFINITY_DISABLE();
6363 } else if (!KMP_AFFINITY_CAPABLE()) {
6364 __kmp_affinity_dispatch->determine_capable(var);
6365 if (!KMP_AFFINITY_CAPABLE()) {
6366 if (__kmp_affinity.flags.verbose ||
6367 (__kmp_affinity.flags.warnings &&
6368 (__kmp_affinity.type != affinity_default) &&
6369 (__kmp_affinity.type != affinity_none) &&
6370 (__kmp_affinity.type != affinity_disabled))) {
6371 KMP_WARNING(AffNotSupported, var);
6372 }
6373 __kmp_affinity.type = affinity_disabled;
6374 __kmp_affinity.flags.respect = FALSE;
6375 __kmp_affinity.gran = KMP_HW_THREAD;
6376 }
6377 }
6378
6379 if (__kmp_affinity.type == affinity_disabled) {
6381 } else if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_true) {
6382 // OMP_PROC_BIND=true maps to OMP_PROC_BIND=spread.
6384 }
6385
6386 if (KMP_AFFINITY_CAPABLE()) {
6387
6388#if KMP_GROUP_AFFINITY
6389 // This checks to see if the initial affinity mask is equal
6390 // to a single windows processor group. If it is, then we do
6391 // not respect the initial affinity mask and instead, use the
6392 // entire machine.
6393 bool exactly_one_group = false;
6394 if (__kmp_num_proc_groups > 1) {
6395 int group;
6396 bool within_one_group;
6397 // Get the initial affinity mask and determine if it is
6398 // contained within a single group.
6399 kmp_affin_mask_t *init_mask;
6400 KMP_CPU_ALLOC(init_mask);
6401 __kmp_get_system_affinity(init_mask, TRUE);
6402 group = __kmp_get_proc_group(init_mask);
6403 within_one_group = (group >= 0);
6404 // If the initial affinity is within a single group,
6405 // then determine if it is equal to that single group.
6406 if (within_one_group) {
6407 DWORD num_bits_in_group = __kmp_GetActiveProcessorCount(group);
6408 DWORD num_bits_in_mask = 0;
6409 for (int bit = init_mask->begin(); bit != init_mask->end();
6410 bit = init_mask->next(bit))
6411 num_bits_in_mask++;
6412 exactly_one_group = (num_bits_in_group == num_bits_in_mask);
6413 }
6414 KMP_CPU_FREE(init_mask);
6415 }
6416
6417 // Handle the Win 64 group affinity stuff if there are multiple
6418 // processor groups, or if the user requested it, and OMP 4.0
6419 // affinity is not in effect.
6420 if (__kmp_num_proc_groups > 1 &&
6421 __kmp_affinity.type == affinity_default &&
6422 __kmp_nested_proc_bind.bind_types[0] == proc_bind_default) {
6423 // Do not respect the initial processor affinity mask if it is assigned
6424 // exactly one Windows Processor Group since this is interpreted as the
6425 // default OS assignment. Not respecting the mask allows the runtime to
6426 // use all the logical processors in all groups.
6427 if (__kmp_affinity.flags.respect == affinity_respect_mask_default &&
6428 exactly_one_group) {
6429 __kmp_affinity.flags.respect = FALSE;
6430 }
6431 // Use compact affinity with anticipation of pinning to at least the
6432 // group granularity since threads can only be bound to one group.
6433 if (__kmp_affinity.type == affinity_default) {
6434 __kmp_affinity.type = affinity_compact;
6436 }
6437 if (__kmp_hh_affinity.type == affinity_default)
6438 __kmp_hh_affinity.type = affinity_compact;
6439 if (__kmp_affinity_top_method == affinity_top_method_default)
6440 __kmp_affinity_top_method = affinity_top_method_all;
6441 if (__kmp_affinity.gran == KMP_HW_UNKNOWN)
6442 __kmp_affinity.gran = KMP_HW_PROC_GROUP;
6443 if (__kmp_hh_affinity.gran == KMP_HW_UNKNOWN)
6444 __kmp_hh_affinity.gran = KMP_HW_PROC_GROUP;
6445 } else
6446
6447#endif /* KMP_GROUP_AFFINITY */
6448
6449 {
6450 if (__kmp_affinity.flags.respect == affinity_respect_mask_default) {
6451#if KMP_GROUP_AFFINITY
6452 if (__kmp_num_proc_groups > 1 && exactly_one_group) {
6453 __kmp_affinity.flags.respect = FALSE;
6454 } else
6455#endif /* KMP_GROUP_AFFINITY */
6456 {
6457 __kmp_affinity.flags.respect = TRUE;
6458 }
6459 }
6460 if ((__kmp_nested_proc_bind.bind_types[0] != proc_bind_intel) &&
6461 (__kmp_nested_proc_bind.bind_types[0] != proc_bind_default)) {
6462 if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_false)
6463 __kmp_affinity.type = affinity_none;
6464 if (__kmp_affinity.type == affinity_default) {
6465 __kmp_affinity.type = affinity_compact;
6466 __kmp_affinity.flags.dups = FALSE;
6467 }
6468 } else if (__kmp_affinity.type == affinity_default) {
6469#if KMP_MIC_SUPPORTED
6470 if (__kmp_mic_type != non_mic) {
6472 } else
6473#endif
6474 {
6476 }
6477#if KMP_MIC_SUPPORTED
6478 if (__kmp_mic_type != non_mic) {
6479 __kmp_affinity.type = affinity_scatter;
6480 } else
6481#endif
6482 {
6483 __kmp_affinity.type = affinity_none;
6484 }
6485 }
6486 if (__kmp_hh_affinity.type == affinity_default)
6487 __kmp_hh_affinity.type = affinity_none;
6488 if ((__kmp_affinity.gran == KMP_HW_UNKNOWN) &&
6489 (__kmp_affinity.gran_levels < 0)) {
6490#if KMP_MIC_SUPPORTED
6491 if (__kmp_mic_type != non_mic) {
6492 __kmp_affinity.gran = KMP_HW_THREAD;
6493 } else
6494#endif
6495 {
6496 __kmp_affinity.gran = KMP_HW_CORE;
6497 }
6498 }
6499 if ((__kmp_hh_affinity.gran == KMP_HW_UNKNOWN) &&
6500 (__kmp_hh_affinity.gran_levels < 0)) {
6501#if KMP_MIC_SUPPORTED
6502 if (__kmp_mic_type != non_mic) {
6503 __kmp_hh_affinity.gran = KMP_HW_THREAD;
6504 } else
6505#endif
6506 {
6507 __kmp_hh_affinity.gran = KMP_HW_CORE;
6508 }
6509 }
6510 if (__kmp_affinity_top_method == affinity_top_method_default) {
6511 __kmp_affinity_top_method = affinity_top_method_all;
6512 }
6513 }
6514 } else {
6515 // If affinity is disabled, then still need to assign topology method
6516 // to attempt machine detection and affinity types
6517 if (__kmp_affinity_top_method == affinity_top_method_default)
6518 __kmp_affinity_top_method = affinity_top_method_all;
6519 if (__kmp_affinity.type == affinity_default)
6520 __kmp_affinity.type = affinity_disabled;
6521 if (__kmp_hh_affinity.type == affinity_default)
6522 __kmp_hh_affinity.type = affinity_disabled;
6523 }
6524
6525#ifdef KMP_DEBUG
6526 for (const kmp_affinity_t *affinity : __kmp_affinities)
6527 __kmp_print_affinity_settings(affinity);
6529 K_DIAG(1, ("__kmp_nested_proc_bind.bind_types[0] == %d\n",
6530 __kmp_nested_proc_bind.bind_types[0]));
6531#endif
6532 }
6533
6534#endif /* KMP_AFFINITY_SUPPORTED */
6535
6536 // Post-initialization step: some env. vars need their value's further
6537 // processing
6538 if (string != NULL) { // kmp_set_defaults() was called
6540 }
6541
6542 __kmp_env_blk_free(&block);
6543
6544 KMP_MB();
6545
6546} // __kmp_env_initialize
6547
6549
6550 kmp_env_blk_t block;
6551 int i;
6552 kmp_str_buf_t buffer;
6553
6555 __kmp_str_buf_init(&buffer);
6556
6557 __kmp_env_blk_init(&block, NULL);
6558 __kmp_env_blk_sort(&block);
6559
6560 // Print real environment values.
6561 __kmp_str_buf_print(&buffer, "\n%s\n\n", KMP_I18N_STR(UserSettings));
6562 for (i = 0; i < block.count; ++i) {
6563 char const *name = block.vars[i].name;
6564 char const *value = block.vars[i].value;
6565 if ((KMP_STRLEN(name) > 4 && strncmp(name, "KMP_", 4) == 0) ||
6566 strncmp(name, "OMP_", 4) == 0
6567#ifdef KMP_GOMP_COMPAT
6568 || strncmp(name, "GOMP_", 5) == 0
6569#endif // KMP_GOMP_COMPAT
6570 ) {
6571 __kmp_str_buf_print(&buffer, " %s=%s\n", name, value);
6572 }
6573 }
6574 __kmp_str_buf_print(&buffer, "\n");
6575
6576 // Print internal (effective) settings.
6577 __kmp_str_buf_print(&buffer, "%s\n\n", KMP_I18N_STR(EffectiveSettings));
6578 for (int i = 0; i < __kmp_stg_count; ++i) {
6579 if (__kmp_stg_table[i].print != NULL) {
6580 __kmp_stg_table[i].print(&buffer, __kmp_stg_table[i].name,
6582 }
6583 }
6584
6585 __kmp_printf("%s", buffer.str);
6586
6587 __kmp_env_blk_free(&block);
6588 __kmp_str_buf_free(&buffer);
6589
6590 __kmp_printf("\n");
6591
6592} // __kmp_env_print
6593
6597
6598void __kmp_display_env_impl(int display_env, int display_env_verbose) {
6599 kmp_env_blk_t block;
6600 kmp_str_buf_t buffer;
6601
6602 __kmp_env_format = 1;
6603
6605 __kmp_str_buf_init(&buffer);
6606
6607 __kmp_env_blk_init(&block, NULL);
6608 __kmp_env_blk_sort(&block);
6609
6610 __kmp_str_buf_print(&buffer, "\n%s\n", KMP_I18N_STR(DisplayEnvBegin));
6611 __kmp_str_buf_print(&buffer, " _OPENMP='%d'\n", __kmp_openmp_version);
6612
6613 for (int i = 0; i < __kmp_stg_count; ++i) {
6614 if (__kmp_stg_table[i].print != NULL &&
6615 ((display_env && strncmp(__kmp_stg_table[i].name, "OMP_", 4) == 0) ||
6616 display_env_verbose)) {
6617 __kmp_stg_table[i].print(&buffer, __kmp_stg_table[i].name,
6619 }
6620 }
6621
6622 __kmp_str_buf_print(&buffer, "%s\n", KMP_I18N_STR(DisplayEnvEnd));
6623 __kmp_str_buf_print(&buffer, "\n");
6624
6625 __kmp_printf("%s", buffer.str);
6626
6627 __kmp_env_blk_free(&block);
6628 __kmp_str_buf_free(&buffer);
6629
6630 __kmp_printf("\n");
6631}
6632
6633#if OMPD_SUPPORT
6634// Dump environment variables for OMPD
6635void __kmp_env_dump() {
6636
6637 kmp_env_blk_t block;
6638 kmp_str_buf_t buffer, env, notdefined;
6639
6641 __kmp_str_buf_init(&buffer);
6642 __kmp_str_buf_init(&env);
6643 __kmp_str_buf_init(&notdefined);
6644
6645 __kmp_env_blk_init(&block, NULL);
6646 __kmp_env_blk_sort(&block);
6647
6648 __kmp_str_buf_print(&notdefined, ": %s", KMP_I18N_STR(NotDefined));
6649
6650 for (int i = 0; i < __kmp_stg_count; ++i) {
6651 if (__kmp_stg_table[i].print == NULL)
6652 continue;
6653 __kmp_str_buf_clear(&env);
6654 __kmp_stg_table[i].print(&env, __kmp_stg_table[i].name,
6656 if (env.used < 4) // valid definition must have indents (3) and a new line
6657 continue;
6658 if (strstr(env.str, notdefined.str))
6659 // normalize the string
6660 __kmp_str_buf_print(&buffer, "%s=undefined\n", __kmp_stg_table[i].name);
6661 else
6662 __kmp_str_buf_cat(&buffer, env.str + 3, env.used - 3);
6663 }
6664
6665 ompd_env_block = (char *)__kmp_allocate(buffer.used + 1);
6666 KMP_MEMCPY(ompd_env_block, buffer.str, buffer.used + 1);
6667 ompd_env_block_size = (ompd_size_t)KMP_STRLEN(ompd_env_block);
6668
6669 __kmp_env_blk_free(&block);
6670 __kmp_str_buf_free(&buffer);
6671 __kmp_str_buf_free(&env);
6672 __kmp_str_buf_free(&notdefined);
6673}
6674#endif // OMPD_SUPPORT
6675
6676// end of file
char buf[BUFFER_SIZE]
int result[2]
static kmp_hw_subset_t * allocate()
static void deallocate(kmp_hw_subset_t *subset)
static const int USE_ALL
static int parse_single_device(kmp_str_ref spec, int device_num_min, int device_num_max, const char *dbg_name=nullptr)
int __kmp_atomic_mode
sched_type
Describes the loop schedule to be used for a parallel for loop.
Definition kmp.h:340
@ kmp_sch_auto
auto
Definition kmp.h:347
@ kmp_sch_static
static unspecialized
Definition kmp.h:343
@ kmp_sch_modifier_monotonic
Set if the monotonic schedule modifier was present.
Definition kmp.h:428
@ kmp_sch_default
default scheduling algorithm
Definition kmp.h:448
@ kmp_sch_modifier_nonmonotonic
Set if the nonmonotonic schedule modifier was present.
Definition kmp.h:430
@ kmp_sch_guided_chunked
guided unspecialized
Definition kmp.h:345
@ kmp_sch_dynamic_chunked
Definition kmp.h:344
@ kmp_sch_guided_analytical_chunked
Definition kmp.h:355
@ kmp_sch_static_balanced
Definition kmp.h:352
@ kmp_sch_static_greedy
Definition kmp.h:351
@ kmp_sch_static_chunked
Definition kmp.h:342
@ kmp_sch_trapezoidal
Definition kmp.h:348
@ kmp_sch_guided_iterative_chunked
Definition kmp.h:354
@ kmp_sch_static_steal
Definition kmp.h:357
__itt_string_handle * name
Definition ittnotify.h:3305
void
Definition ittnotify.h:3324
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type size_t void * data
void const char const char int ITT_FORMAT __itt_group_sync s
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp end
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int initialized
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp begin
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t count
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type size_t void ITT_FORMAT p const __itt_domain __itt_id __itt_string_handle const wchar_t size_t length
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long value
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t mode
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t size
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type type
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle * key
int __kmp_memkind_available
omp_memspace_handle_t const omp_default_mem_space
int __kmp_hot_teams_max_level
void * omp_memspace_handle_t
Definition kmp.h:1055
void * omp_allocator_handle_t
Definition kmp.h:1073
#define KMP_HW_MAX_NUM_CORE_EFFS
Definition kmp.h:619
int __kmp_generate_warnings
volatile int __kmp_init_user_locks
int __kmp_debug_buf_lines
omp_allocator_handle_t __kmpc_init_allocator(int gtid, omp_memspace_handle_t, int ntraits, omp_alloctrait_t traits[])
int __kmp_cg_max_nth
int __kmp_abort_delay
kmp_proc_bind_t __kmp_teams_proc_bind
#define KMP_INTERNAL_MALLOC(sz)
Definition kmp.h:103
#define KMP_DEFAULT_CHUNK
Definition kmp.h:1305
void ompc_set_dynamic(int flag)
int __kmp_version
#define KMP_MAX_STKSIZE
Definition kmp.h:1207
#define KMP_MAX_STKPADDING
Definition kmp.h:1240
int __kmp_display_env_verbose
omp_allocator_handle_t const omp_cgroup_mem_alloc
kmp_global_t __kmp_global
@ omp_atk_fallback
Definition kmp.h:1016
@ omp_atk_pinned
Definition kmp.h:1018
@ omp_atk_access
Definition kmp.h:1014
@ omp_atk_alignment
Definition kmp.h:1013
@ omp_atk_pool_size
Definition kmp.h:1015
@ omp_atk_fb_data
Definition kmp.h:1017
@ omp_atk_partition
Definition kmp.h:1019
@ omp_atk_sync_hint
Definition kmp.h:1012
size_t __kmp_align_alloc
#define KMP_MAX_BLOCKTIME
Definition kmp.h:1245
int __kmp_teams_max_nth
#define KMP_MAX_CHUNK
Definition kmp.h:1304
kmp_int32 __kmp_use_yield
@ tgt_mandatory
Definition kmp.h:4523
@ tgt_disabled
Definition kmp.h:4521
@ tgt_default
Definition kmp.h:4522
char const * __kmp_barrier_pattern_name[bp_last_bar]
int __kmp_dflt_team_nth_ub
#define KMP_MIN_STKOFFSET
Definition kmp.h:1231
#define KMP_INTERNAL_REALLOC(p, sz)
Definition kmp.h:105
#define SKIP_TO(_x, _c)
Definition kmp.h:281
int __kmp_dflt_max_active_levels
int __kmp_xproc
int __kmp_debug_buf
omp_memspace_handle_t const omp_low_lat_mem_space
int __kmp_storage_map_verbose_specified
#define KMP_FOREACH_HW_TYPE(type)
Definition kmp.h:626
kmp_bar_pat_e __kmp_barrier_gather_pattern[bs_last_barrier]
kmp_tasking_mode_t __kmp_tasking_mode
char * __kmp_affinity_format
int __kmp_dflt_blocktime
omp_allocator_handle_t __kmp_def_allocator
int __kmp_omp_cancellation
size_t __kmp_stksize
kmp_nested_proc_bind_t __kmp_nested_proc_bind
kmp_nested_nthreads_t __kmp_nested_nth
int __kmp_max_nth
omp_allocator_handle_t const omp_default_mem_alloc
int __kmp_chunk
@ omp_atv_cgroup
Definition kmp.h:1039
@ omp_atv_all
Definition kmp.h:1048
@ omp_atv_interleaved
Definition kmp.h:1047
@ omp_atv_false
Definition kmp.h:1029
@ omp_atv_environment
Definition kmp.h:1044
@ omp_atv_serialized
Definition kmp.h:1033
@ omp_atv_blocked
Definition kmp.h:1046
@ omp_atv_thread
Definition kmp.h:1037
@ omp_atv_default_mem_fb
Definition kmp.h:1040
@ omp_atv_allocator_fb
Definition kmp.h:1043
@ omp_atv_pteam
Definition kmp.h:1038
@ omp_atv_contended
Definition kmp.h:1031
@ omp_atv_null_fb
Definition kmp.h:1041
@ omp_atv_nearest
Definition kmp.h:1045
@ omp_atv_uncontended
Definition kmp.h:1032
@ omp_atv_true
Definition kmp.h:1030
@ omp_atv_private
Definition kmp.h:1035
@ omp_atv_abort_fb
Definition kmp.h:1042
kmp_target_offload_kind_t __kmp_target_offload
int __kmp_debug_buf_chars
#define KMP_MAX_TASK_PRIORITY_LIMIT
Definition kmp.h:1321
#define SCHEDULE_HAS_MONOTONIC(s)
Definition kmp.h:436
#define KMP_MIN_NTH
Definition kmp.h:1181
#define KMP_MAX_BRANCH_BITS
Definition kmp.h:1315
int __kmp_adjust_gtid_mode
int __kmp_env_blocktime
#define __kmp_entry_gtid()
Definition kmp.h:3594
static int __kmp_tid_from_gtid(int gtid)
Definition kmp.h:3612
int __kmp_display_env
kmp_int32 __kmp_use_yield_exp_set
omp_allocator_handle_t const omp_large_cap_mem_alloc
const char * __kmp_hw_get_catalog_string(kmp_hw_t type, bool plural=false)
omp_allocator_handle_t const omp_low_lat_mem_alloc
#define KMP_DEFAULT_STKSIZE
Definition kmp.h:1223
volatile int __kmp_init_middle
omp_allocator_handle_t const omp_high_bw_mem_alloc
int __kmp_storage_map_verbose
int __kmp_allThreadsSpecified
enum sched_type __kmp_static
const char * __kmp_hw_get_keyword(kmp_hw_t type, bool plural=false)
int __kmp_affinity_num_places
int __kmp_duplicate_library_ok
#define KMP_MAX_STKOFFSET
Definition kmp.h:1232
omp_memspace_handle_t const omp_const_mem_space
kmp_uint32 __kmp_barrier_release_branch_bits[bs_last_barrier]
kmp_int32 __kmp_default_device
omp_memspace_handle_t const omp_large_cap_mem_space
int __kmp_force_monotonic
enum sched_type __kmp_sched
uintptr_t omp_uintptr_t
Definition kmp.h:1009
int __kmp_enable_task_throttling
kmp_uint32 __kmp_barrier_gather_bb_dflt
kmp_uint32 __kmp_barrier_release_bb_dflt
int __kmp_task_stealing_constraint
int __kmp_need_register_atfork
int __kmp_dispatch_num_buffers
#define SCHEDULE_WITHOUT_MODIFIERS(s)
Definition kmp.h:433
int __kmp_nesting_mode
bool __kmp_dflt_max_active_levels_set
char * __kmp_debug_buffer
omp_memspace_handle_t const omp_high_bw_mem_space
int __kmp_nteams
int __kmp_storage_map
omp_allocator_handle_t const omp_const_mem_alloc
volatile int __kmp_init_parallel
omp_allocator_handle_t const omp_pteam_mem_alloc
int __kmp_sys_max_nth
int __kmp_need_register_atfork_specified
kmp_int32 __kmp_enable_hidden_helper
#define KMP_DEFAULT_BLOCKTIME
Definition kmp.h:1249
#define __kmp_allocate(size)
Definition kmp.h:3747
#define KMP_DEBUG_BUF_LINES_MIN
Definition kmp.h:3317
static const size_t KMP_AFFINITY_FORMAT_SIZE
Definition kmp.h:951
#define TRUE
Definition kmp.h:1341
enum library_type __kmp_library
#define FALSE
Definition kmp.h:1340
int __kmp_tp_capacity
int __kmp_settings
@ tskm_extra_barrier
Definition kmp.h:2439
@ tskm_max
Definition kmp.h:2441
@ tskm_task_teams
Definition kmp.h:2440
int __kmp_env_consistency_check
kmp_uint64 __kmp_taskloop_min_tasks
char const * __kmp_barrier_branch_bit_env_name[bs_last_barrier]
#define SCHEDULE_HAS_NONMONOTONIC(s)
Definition kmp.h:437
int __kmp_determ_red
int __kmp_hot_teams_mode
size_t __kmp_sys_min_stksize
char __kmp_blocktime_units
void ompc_set_nested(int flag)
kmp_uint32 __kmp_barrier_gather_branch_bits[bs_last_barrier]
size_t __kmp_stkoffset
size_t __kmp_malloc_pool_incr
#define KMP_INTERNAL_FREE(p)
Definition kmp.h:104
int __kmp_threads_capacity
int __kmp_foreign_tp
bool __kmp_wpolicy_passive
@ bs_plain_barrier
Definition kmp.h:2153
@ bs_last_barrier
Definition kmp.h:2159
#define KMP_MAX_DEFAULT_DEVICE_LIMIT
Definition kmp.h:1319
int __kmp_display_affinity
enum sched_type __kmp_guided
#define SKIP_WS(_x)
Definition kmp.h:265
#define __kmp_get_gtid()
Definition kmp.h:3593
PACKED_REDUCTION_METHOD_T __kmp_force_reduction_method
#define KMP_MIN_MALLOC_POOL_INCR
Definition kmp.h:1227
omp_allocator_handle_t const omp_thread_mem_alloc
#define KMP_MAX_MALLOC_POOL_INCR
Definition kmp.h:1228
#define __kmp_page_allocate(size)
Definition kmp.h:3748
#define SKIP_DIGITS(_x)
Definition kmp.h:270
kmp_int32 __kmp_max_task_priority
int __kmp_teams_thread_limit
int __kmp_stkpadding
int __kmp_dflt_team_nth
#define KMP_DEBUG_BUF_CHARS_MIN
Definition kmp.h:3320
void ompc_set_num_threads(int arg)
char const * __kmp_barrier_pattern_env_name[bs_last_barrier]
std::atomic< int > __kmp_debug_count
kmp_proc_bind_t
Definition kmp.h:930
@ proc_bind_false
Definition kmp.h:931
@ proc_bind_true
Definition kmp.h:932
@ proc_bind_close
Definition kmp.h:934
@ proc_bind_intel
Definition kmp.h:936
@ proc_bind_primary
Definition kmp.h:933
@ proc_bind_spread
Definition kmp.h:935
@ proc_bind_default
Definition kmp.h:937
kmp_hw_t
Definition kmp.h:591
@ KMP_HW_UNKNOWN
Definition kmp.h:592
@ KMP_HW_NUMA
Definition kmp.h:595
@ KMP_HW_SOCKET
Definition kmp.h:593
@ KMP_HW_CORE
Definition kmp.h:603
@ KMP_HW_PROC_GROUP
Definition kmp.h:594
@ KMP_HW_TILE
Definition kmp.h:599
@ KMP_HW_THREAD
Definition kmp.h:604
@ KMP_HW_LAST
Definition kmp.h:605
@ KMP_HW_LLC
Definition kmp.h:597
static kmp_info_t * __kmp_thread_from_gtid(int gtid)
Definition kmp.h:3627
#define KMP_MIN_DISP_NUM_BUFF
Definition kmp.h:1307
void __kmp_expand_file_name(char *result, size_t rlen, char *pattern)
int __kmp_gtid_mode
#define KMP_MIN_BLOCKTIME
Definition kmp.h:1244
#define SCHEDULE_SET_MODIFIERS(s, m)
Definition kmp.h:443
kmp_hw_core_type_t
Definition kmp.h:608
@ KMP_HW_MAX_NUM_CORE_TYPES
Definition kmp.h:615
@ KMP_HW_CORE_TYPE_UNKNOWN
Definition kmp.h:609
#define KMP_MIN_STKPADDING
Definition kmp.h:1239
@ library_none
Definition kmp.h:488
@ library_turnaround
Definition kmp.h:490
@ library_throughput
Definition kmp.h:491
@ library_serial
Definition kmp.h:489
volatile int __kmp_init_serial
@ critical_reduce_block
Definition kmp.h:519
@ tree_reduce_block
Definition kmp.h:521
@ reduction_method_not_defined
Definition kmp.h:518
@ atomic_reduce_block
Definition kmp.h:520
#define KMP_MAX_DISP_NUM_BUFF
Definition kmp.h:1309
kmp_int32 __kmp_hidden_helper_threads_num
#define KMP_MAX_ACTIVE_LEVELS_LIMIT
Definition kmp.h:1317
static void __kmp_type_convert(T1 src, T2 *dest)
Definition kmp.h:4879
enum kmp_bar_pat kmp_bar_pat_e
#define SKIP_TOKEN(_x)
Definition kmp.h:275
int __kmp_debug_buf_atomic
kmp_bar_pat_e __kmp_barrier_release_pattern[bs_last_barrier]
int __kmp_env_stksize
@ bp_dist_bar
Definition kmp.h:2175
@ bp_linear_bar
Definition kmp.h:2168
@ bp_last_bar
Definition kmp.h:2176
@ dynamic_thread_limit
Definition kmp.h:309
@ dynamic_default
Definition kmp.h:304
@ dynamic_random
Definition kmp.h:308
bool __kmp_hwloc_available
union KMP_ALIGN_CACHE kmp_info kmp_info_t
omp_allocator_handle_t const omp_null_allocator
void __kmp_aux_set_blocktime(int arg, kmp_info_t *thread, int tid)
kmp_hw_subset_t * __kmp_hw_subset
KMP_ARCH_X86 KMP_ARCH_X86 KMP_ARCH_X86 KMP_ARCH_X86 KMP_ARCH_X86 KMP_ARCH_X86 KMP_ARCH_X86 KMP_ARCH_X86 KMP_ARCH_X86<<, 2i, 1, KMP_ARCH_X86) ATOMIC_CMPXCHG(fixed2, shr, kmp_int16, 16, > KMP_ARCH_X86 KMP_ARCH_X86 kmp_uint32
#define K_DIAG(d, x)
Definition kmp_debug.h:163
#define KMP_ASSERT(cond)
Definition kmp_debug.h:59
#define KMP_DEBUG_ASSERT(cond)
Definition kmp_debug.h:61
#define KMP_ASSERT2(cond, msg)
Definition kmp_debug.h:60
unsigned long long kmp_uint64
char const * __kmp_device_env_eligible_name(int index)
int __kmp_device_env_record(char const *full_name, char const *value)
kmp_hier_sched_env_t __kmp_hier_scheds
kmp_hier_layer_e
@ LAYER_THREAD
@ LAYER_NUMA
@ LAYER_L1
@ LAYER_L2
@ LAYER_L3
int __kmp_dispatch_hand_threading
char const * __kmp_env_blk_var(kmp_env_blk_t *block, char const *name)
void __kmp_env_blk_sort(kmp_env_blk_t *block)
void __kmp_env_blk_init(kmp_env_blk_t *block, char const *bulk)
void __kmp_env_blk_free(kmp_env_blk_t *block)
struct __kmp_env_blk kmp_env_blk_t
kmp_msg_t __kmp_msg_null
Definition kmp_i18n.cpp:36
static void __kmp_msg(kmp_msg_severity_t severity, kmp_msg_t message, va_list ap)
Definition kmp_i18n.cpp:787
kmp_msg_t __kmp_msg_format(unsigned id_arg,...)
Definition kmp_i18n.cpp:624
#define KMP_INFORM(...)
Definition kmp_i18n.h:142
#define KMP_WARNING(...)
Definition kmp_i18n.h:144
#define KMP_MSG(...)
Definition kmp_i18n.h:121
struct kmp_msg kmp_msg_t
Definition kmp_i18n.h:108
@ kmp_ms_warning
Definition kmp_i18n.h:130
#define KMP_I18N_STR(id)
Definition kmp_i18n.h:46
#define KMP_FATAL(...)
Definition kmp_i18n.h:146
#define KMP_HNT(...)
Definition kmp_i18n.h:122
void __kmp_printf(char const *format,...)
Definition kmp_io.cpp:186
kmp_backoff_t __kmp_spin_backoff_params
enum kmp_lock_kind __kmp_user_lock_kind
void __kmp_set_user_lock_vptrs(kmp_lock_kind_t user_lock_kind)
int __kmp_num_locks_in_block
@ lk_default
Definition kmp_lock.h:587
@ lk_ticket
Definition kmp_lock.h:597
@ lk_drdpa
Definition kmp_lock.h:599
@ lk_queuing
Definition kmp_lock.h:598
@ lk_tas
Definition kmp_lock.h:588
#define KMP_SIZE_T_MAX
Definition kmp_os.h:196
#define KMP_BUILTIN_UNREACHABLE
Definition kmp_os.h:1321
@ kmp_warnings_off
Definition kmp_os.h:1245
@ kmp_warnings_explicit
Definition kmp_os.h:1247
#define RCAST(type, var)
Definition kmp_os.h:294
#define CACHE_LINE
Definition kmp_os.h:342
#define KMP_INT_MAX
Definition kmp_os.h:218
#define CCAST(type, var)
Definition kmp_os.h:293
#define KMP_MB()
Definition kmp_os.h:1070
#define TCR_4(a)
Definition kmp_os.h:1141
#define KMP_ALLOCA
#define KMP_STRNCPY_S(dst, bsz, src, cnt)
#define KMP_STRCPY_S(dst, bsz, src)
#define KMP_SSCANF
#define KMP_MEMCPY
#define KMP_MEMCPY_S(dst, bsz, src, cnt)
static void __kmp_strncpy_truncate(char *buffer, size_t buf_size, char const *src, size_t src_size)
#define KMP_STRLEN
static void __kmp_stg_parse_nteams(char const *name, char const *value, void *data)
static void __kmp_stg_print_cpuinfo_file(kmp_str_buf_t *buffer, char const *name, void *data)
static kmp_setting_t __kmp_stg_table[]
static void __kmp_stg_parse_max_active_levels(char const *name, char const *value, void *data)
static const char * __kmp_parse_single_omp_schedule(const char *name, const char *value, bool parse_hier=false)
static void __kmp_stg_parse_nested(char const *name, char const *value, void *data)
static void __kmp_stg_print_barrier_pattern(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_parse_gtid_mode(char const *name, char const *value, void *data)
static void __kmp_stg_print_force_reduction(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_warnings(kmp_str_buf_t *buffer, char const *name, void *data)
void __kmp_env_print_2()
#define KMP_STORE_LOCK_SEQ(a)
static char const * blocktime_str
static void __kmp_stg_print_max_task_priority(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_use_yield(kmp_str_buf_t *buffer, char const *name, void *data)
#define IS_POWER_OF_TWO(n)
static void __kmp_stg_print_taskloop_min_tasks(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_wait_policy(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_parse_align_alloc(char const *name, char const *value, void *data)
static void __kmp_stg_parse_init_at_fork(char const *name, char const *value, void *data)
static void __kmp_stg_print_affinity_format(kmp_str_buf_t *buffer, char const *name, void *data)
struct __kmp_stg_wp_data kmp_stg_wp_data_t
static void __kmp_stg_parse_lock_block(char const *name, char const *value, void *data)
static void __kmp_stg_parse_stackpad(char const *name, char const *value, void *data)
static void __kmp_stg_parse_target_offload(char const *name, char const *value, void *data)
static void __kmp_stg_parse_kmp_dynamic_mode(char const *name, char const *value, void *data)
static void __kmp_stg_parse_affinity_format(char const *name, char const *value, void *data)
#define SKIP_PAIR(key)
static void __kmp_stg_parse_omp_schedule(char const *name, char const *value, void *data)
static void __kmp_stg_parse_num_threads(char const *name, char const *value, void *data)
static void __kmp_stg_print_settings(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_parse_teams_th_limit(char const *name, char const *value, void *data)
static void __kmp_stg_parse_use_yield(char const *name, char const *value, void *data)
static void __kmp_stg_parse_schedule(char const *name, char const *value, void *data)
static void __kmp_stg_print_proc_bind(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_parse_omp_display_env(char const *name, char const *value, void *data)
static void __kmp_stg_parse_duplicate_lib_ok(char const *name, char const *value, void *data)
static kmp_hw_t __kmp_hw_subset_break_tie(const kmp_hw_t *possible, size_t num_possible)
static void __kmp_stg_print_storage_map(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_parse_kmp_force_monotonic(char const *name, char const *value, void *data)
static void __kmp_stg_print_align_alloc(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_display_affinity(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_parse_consistency_check(char const *name, char const *value, void *data)
static void __kmp_stg_print_num_hidden_helper_threads(kmp_str_buf_t *buffer, char const *name, void *data)
int __kmp_default_tp_capacity(int req_nproc, int max_nth, int all_threads_specified)
static void __kmp_stg_print_all_threadprivate(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_omp_display_env(kmp_str_buf_t *buffer, char const *name, void *data)
void(* kmp_stg_parse_func_t)(char const *name, char const *value, void *data)
static void __kmp_stg_print_version(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_task_throttling(kmp_str_buf_t *buffer, char const *name, void *data)
static int const __kmp_stg_count
static void __kmp_stg_parse_allocator(char const *name, char const *value, void *data)
int __kmp_initial_threads_capacity(int req_nproc)
static void __kmp_stg_print_uint64(kmp_str_buf_t *buffer, char const *name, kmp_uint64 value)
static void __kmp_stg_print_use_hidden_helper(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_parse_stacksize(char const *name, char const *value, void *data)
static void __kmp_stg_parse_abort_delay(char const *name, char const *value, void *data)
static void __kmp_stg_parse_device_thread_limit(char const *name, char const *value, void *data)
static void __kmp_stg_parse_storage_map(char const *name, char const *value, void *data)
static int __kmp_strcasecmp_with_sentinel(char const *a, char const *b, char sentinel)
static void __kmp_stg_parse_all_threadprivate(char const *name, char const *value, void *data)
static void __kmp_stg_parse_omp_cancellation(char const *name, char const *value, void *data)
static char const * __kmp_aux_env_blk_all_fallback(kmp_env_blk_t *block, char const *base_name)
static void __kmp_stg_parse_lock_kind(char const *name, char const *value, void *data)
static void __kmp_stg_print_omp_cancellation(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_abort_delay(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_parse_hw_subset(char const *name, char const *value, void *data)
void __kmp_check_stksize(size_t *val)
struct __kmp_stg_ss_data kmp_stg_ss_data_t
static void __kmp_stg_parse_proc_bind(char const *name, char const *value, void *data)
static void __kmp_stg_print_stacksize(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_parse_size(char const *name, char const *value, size_t size_min, size_t size_max, int *is_specified, size_t *out, size_t factor)
struct __kmp_stg_fr_data kmp_stg_fr_data_t
static void __kmp_stg_parse_omp_dynamic(char const *name, char const *value, void *data)
#define MAX_STR_LEN
static void __kmp_stg_print_atomic_mode(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_parse_version(char const *name, char const *value, void *data)
static void __kmp_stg_print_bool(kmp_str_buf_t *buffer, char const *name, int value)
static void __kmp_stg_print_int(kmp_str_buf_t *buffer, char const *name, int value)
static void __kmp_stg_parse_disp_buffers(char const *name, char const *value, void *data)
static void __kmp_stg_print_allocator(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_parse_task_throttling(char const *name, char const *value, void *data)
static void __kmp_stg_print_thread_limit(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_hot_teams_level(kmp_str_buf_t *buffer, char const *name, void *data)
#define SET_KEY()
static void __kmp_stg_print_teams_th_limit(kmp_str_buf_t *buffer, char const *name, void *data)
void __kmp_env_initialize(char const *string)
static void __kmp_stg_parse_task_stealing(char const *name, char const *value, void *data)
static void __kmp_stg_print_stackoffset(kmp_str_buf_t *buffer, char const *name, void *data)
struct __kmp_setting kmp_setting_t
static void __kmp_stg_print_schedule(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_malloc_pool_incr(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_nested(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_parse_taskloop_min_tasks(char const *name, char const *value, void *data)
static void __kmp_stg_print_omp_dynamic(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_parse_hot_teams_level(char const *name, char const *value, void *data)
static char const * use_yield_str
static void __kmp_stg_print_hw_subset(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_str(kmp_str_buf_t *buffer, char const *name, char const *value)
void __kmp_display_env_impl(int display_env, int display_env_verbose)
static void __kmp_stg_print_num_threads(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_parse_nesting_mode(char const *name, char const *value, void *data)
static int __kmp_match_str(char const *token, char const *buf, const char **end)
static void __kmp_stg_print_spin_backoff_params(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_lock_kind(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_parse_wait_policy(char const *name, char const *value, void *data)
static void __kmp_stg_print_hot_teams_mode(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_lock_block(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_default_device(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_aux_env_initialize(kmp_env_blk_t *block)
static void __kmp_stg_print_duplicate_lib_ok(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_foreign_threads_threadprivate(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_kmp_dynamic_mode(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_parse_spin_backoff_params(const char *name, const char *value, void *data)
static void __kmp_stg_print_barrier_branch_bit(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_parse_num_hidden_helper_threads(char const *name, char const *value, void *data)
static void __kmp_stg_print_disp_buffers(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_target_offload(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_parse_blocktime(char const *name, char const *value, void *data)
static void __kmp_stg_print_nesting_mode(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_consistency_check(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_init(void)
static void __kmp_stg_parse_teams_thread_limit(char const *name, char const *value, void *data)
static void __kmp_stg_print_task_stealing(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_parse_nested_num_threads(const char *var, const char *env, kmp_nested_nthreads_t *nth_array)
static void __kmp_stg_parse_atomic_mode(char const *name, char const *value, void *data)
static void __kmp_stg_parse_max_task_priority(char const *name, char const *value, void *data)
static void __kmp_stg_print_init_at_fork(kmp_str_buf_t *buffer, char const *name, void *data)
void(* kmp_stg_print_func_t)(kmp_str_buf_t *buffer, char const *name, void *data)
bool __kmp_env_format
static void __kmp_stg_print_tasking(kmp_str_buf_t *buffer, char const *name, void *data)
static kmp_setting_t * __kmp_stg_find(char const *name)
#define GET_NEXT(sentinel)
static int __kmp_stg_cmp(void const *_a, void const *_b)
static void __kmp_stg_print_kmp_force_monotonic(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_gtid_mode(kmp_str_buf_t *buffer, char const *name, void *data)
static int __kmp_match_with_sentinel(char const *a, char const *b, size_t len, char sentinel)
static void __kmp_stg_parse_foreign_threads_threadprivate(char const *name, char const *value, void *data)
static void __kmp_stg_parse_str(char const *name, char const *value, char **out)
static void __kmp_stg_parse_display_affinity(char const *name, char const *value, void *data)
static void __kmp_stg_parse_malloc_pool_incr(char const *name, char const *value, void *data)
static void __kmp_stg_parse_hot_teams_mode(char const *name, char const *value, void *data)
static void __kmp_stg_parse_bool(char const *name, char const *value, int *out)
static void __kmp_stg_parse_stackoffset(char const *name, char const *value, void *data)
static void __kmp_stg_parse_tasking(char const *name, char const *value, void *data)
static void __kmp_stg_print_omp_schedule(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_teams_thread_limit(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_stackpad(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_parse_barrier_pattern(char const *name, char const *value, void *data)
#define MAX_T_LEVEL
static void __kmp_stg_parse_settings(char const *name, char const *value, void *data)
static void __kmp_stg_parse_cpuinfo_file(char const *name, char const *value, void *data)
static int __kmp_stg_check_rivals(char const *name, char const *value, kmp_setting_t **rivals)
static void __kmp_stg_parse_thread_limit(char const *name, char const *value, void *data)
static void __kmp_stg_print_blocktime(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_print_nteams(kmp_str_buf_t *buffer, char const *name, void *data)
static kmp_hw_t __kmp_stg_parse_hw_subset_name(char const *token)
static void __kmp_stg_print_size(kmp_str_buf_t *buffer, char const *name, size_t value)
static void __kmp_stg_parse_int(char const *name, char const *value, int min, int max, int *out)
static void __kmp_stg_parse(char const *name, char const *value)
static int __kmp_env_toPrint(char const *name, int flag)
static void __kmp_omp_schedule_restore()
static void __kmp_stg_print_device_thread_limit(kmp_str_buf_t *buffer, char const *name, void *data)
static void __kmp_stg_parse_barrier_branch_bit(char const *name, char const *value, void *data)
static void __kmp_stg_parse_force_reduction(char const *name, char const *value, void *data)
static void __kmp_stg_parse_default_device(char const *name, char const *value, void *data)
static void __kmp_stg_print_max_active_levels(kmp_str_buf_t *buffer, char const *name, void *data)
static const char * __kmp_hw_get_core_type_keyword(kmp_hw_core_type_t type)
static void __kmp_stg_parse_use_hidden_helper(char const *name, char const *value, void *data)
static void __kmp_stg_parse_warnings(char const *name, char const *value, void *data)
void __kmp_env_print()
#define KMP_STR_BUF_PRINT_BOOL_EX(n, v, t, f)
#define KMP_STR_BUF_PRINT_NAME
#define KMP_STR_BUF_PRINT_STR
#define KMP_STR_BUF_PRINT_UINT64
#define KMP_STR_BUF_PRINT_BOOL
#define KMP_STR_BUF_PRINT_NAME_EX(x)
#define KMP_STR_BUF_PRINT_INT
int __kmp_str_to_int(char const *str, char sentinel)
Definition kmp_str.cpp:642
void __kmp_str_to_uint(char const *str, kmp_uint64 *out, char const **error)
Definition kmp_str.cpp:807
void __kmp_str_to_size(char const *str, size_t *out, size_t dfactor, char const **error)
Definition kmp_str.cpp:706
void __kmp_str_buf_clear(kmp_str_buf_t *buffer)
Definition kmp_str.cpp:71
int __kmp_str_eqf(char const *lhs, char const *rhs)
Definition kmp_str.cpp:404
int __kmp_str_match(char const *target, int len, char const *data)
Definition kmp_str.cpp:505
int __kmp_basic_str_to_int(char const *str, size_t maxlen)
Definition kmp_str.cpp:622
void __kmp_str_buf_free(kmp_str_buf_t *buffer)
Definition kmp_str.cpp:123
char * __kmp_str_format(char const *format,...)
Definition kmp_str.cpp:448
int __kmp_str_match_true(char const *data)
Definition kmp_str.cpp:552
void __kmp_str_buf_cat(kmp_str_buf_t *buffer, char const *str, size_t len)
Definition kmp_str.cpp:134
int __kmp_str_buf_print(kmp_str_buf_t *buffer, char const *format,...)
Definition kmp_str.cpp:221
int __kmp_str_match_false(char const *data)
Definition kmp_str.cpp:543
void __kmp_str_free(char **str)
Definition kmp_str.cpp:494
void __kmp_str_buf_print_size(kmp_str_buf_t *buf, size_t size)
Definition kmp_str.cpp:232
struct kmp_str_buf kmp_str_buf_t
Definition kmp_str.h:39
#define __kmp_str_buf_init(b)
Definition kmp_str.h:41
#define i
Definition kmp_stub.cpp:88
int const __kmp_openmp_version
int a
dest
Definition check.py:82
volatile int flag
#define delay(t)
Definition ompt-signal.h:6
kmp_env_var_t * vars
kmp_stg_print_func_t print
kmp_stg_parse_func_t parse
char const * name
kmp_setting_t ** rivals
kmp_setting_t ** rivals
kmp_setting_t ** rivals
void set_core_type(kmp_hw_core_type_t type)
void set_core_eff(int eff)
char * str
Definition kmp_i18n.h:105
char * str
Definition kmp_str.h:34
kmp_str_buf_t buf
const char * get()
kmp_trimmed_str_t(const char *str)
omp_alloctrait_key_t key
Definition kmp.h:1069
omp_uintptr_t value
Definition kmp.h:1070
static int err