1 /* Copyright (C) 2005-2022 Free Software Foundation, Inc.
2 Contributed by Richard Henderson <rth@redhat.com>.
4 This file is part of the GNU Offloading and Multi Processing Library
7 Libgomp is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
26 /* This file defines the OpenMP internal control variables and arranges
27 for them to be initialized from environment variables at startup. */
31 #include "gomp-constants.h"
33 #ifndef LIBGOMP_OFFLOADED_ONLY
34 #include "libgomp_f.h"
39 #ifdef HAVE_INTTYPES_H
40 # include <inttypes.h> /* For PRIu64. */
42 #ifdef STRING_WITH_STRINGS
49 # ifdef HAVE_STRINGS_H
55 #include "thread-stacksize.h"
58 # define strtoull(ptr, eptr, base) strtoul (ptr, eptr, base)
60 #endif /* LIBGOMP_OFFLOADED_ONLY */
62 #include "secure_getenv.h"
65 /* Default values of ICVs according to the OpenMP standard. */
66 const struct gomp_default_icv gomp_default_icv_values
= {
68 .thread_limit_var
= UINT_MAX
,
69 .run_sched_var
= GFS_DYNAMIC
,
70 .run_sched_chunk_size
= 1,
71 .default_device_var
= 0,
72 .max_active_levels_var
= 1,
73 .bind_var
= omp_proc_bind_false
,
75 .teams_thread_limit_var
= 0,
79 struct gomp_task_icv gomp_global_icv
= {
80 .nthreads_var
= gomp_default_icv_values
.nthreads_var
,
81 .thread_limit_var
= gomp_default_icv_values
.thread_limit_var
,
82 .run_sched_var
= gomp_default_icv_values
.run_sched_var
,
83 .run_sched_chunk_size
= gomp_default_icv_values
.run_sched_chunk_size
,
84 .default_device_var
= gomp_default_icv_values
.default_device_var
,
85 .dyn_var
= gomp_default_icv_values
.dyn_var
,
86 .max_active_levels_var
= gomp_default_icv_values
.max_active_levels_var
,
87 .bind_var
= gomp_default_icv_values
.bind_var
,
91 /* List for initial "_DEV", "_ALL", and "_DEV_X" ICVs like OMP_NUM_TEAMS_DEV,
92 OMP_NUM_TEAMS_ALL, or OMP_NUM_TEAMS_DEV_42. */
93 struct gomp_icv_list
*gomp_initial_icv_list
= NULL
;
95 /* List for "_DEV_X" ICVs like OMP_NUM_TEAMS_DEV_42. This list contains all
96 device-specific ICVs that are copied from host to device and back. */
97 struct gomp_offload_icv_list
*gomp_offload_icv_list
= NULL
;
99 bool gomp_cancel_var
= false;
100 enum gomp_target_offload_t gomp_target_offload_var
101 = GOMP_TARGET_OFFLOAD_DEFAULT
;
102 int gomp_max_task_priority_var
= 0;
103 #ifndef HAVE_SYNC_BUILTINS
104 gomp_mutex_t gomp_managed_threads_lock
;
106 unsigned long gomp_available_cpus
= 1, gomp_managed_threads
= 1;
107 unsigned long long gomp_spin_count_var
, gomp_throttled_spin_count_var
;
108 unsigned long *gomp_nthreads_var_list
, gomp_nthreads_var_list_len
;
109 char *gomp_bind_var_list
;
110 unsigned long gomp_bind_var_list_len
;
111 void **gomp_places_list
;
112 unsigned long gomp_places_list_len
;
113 uintptr_t gomp_def_allocator
= omp_default_mem_alloc
;
115 unsigned int gomp_num_teams_var
;
117 int gomp_teams_thread_limit_var
;
118 bool gomp_display_affinity_var
;
119 char *gomp_affinity_format_var
= "level %L thread %i affinity %A";
120 size_t gomp_affinity_format_len
;
121 char *goacc_device_type
;
122 int goacc_device_num
;
123 int goacc_default_dims
[GOMP_DIM_MAX
];
125 #ifndef LIBGOMP_OFFLOADED_ONLY
127 static int wait_policy
;
128 static unsigned long stacksize
= GOMP_DEFAULT_STACKSIZE
;
131 print_env_var_error (const char *env
, const char *val
)
133 gomp_error ("Invalid value for environment variable %.*s: %s",
134 (int) (val
- env
- 1), env
, val
);
137 /* Parse the OMP_SCHEDULE environment variable. */
139 parse_schedule (const char *env
, const char *val
, void *const params
[])
141 enum gomp_schedule_type
*schedule
= (enum gomp_schedule_type
*) params
[0];
142 int *chunk_size
= (int *) params
[1];
150 while (isspace ((unsigned char) *val
))
152 if (strncasecmp (val
, "monotonic", 9) == 0)
157 else if (strncasecmp (val
, "nonmonotonic", 12) == 0)
164 while (isspace ((unsigned char) *val
))
169 while (isspace ((unsigned char) *val
))
172 if (strncasecmp (val
, "static", 6) == 0)
174 *schedule
= GFS_STATIC
;
177 else if (strncasecmp (val
, "dynamic", 7) == 0)
179 *schedule
= GFS_DYNAMIC
;
182 else if (strncasecmp (val
, "guided", 6) == 0)
184 *schedule
= GFS_GUIDED
;
187 else if (strncasecmp (val
, "auto", 4) == 0)
189 *schedule
= GFS_AUTO
;
196 || (monotonic
== 0 && *schedule
== GFS_STATIC
))
197 *schedule
|= GFS_MONOTONIC
;
199 while (isspace ((unsigned char) *val
))
203 *chunk_size
= (*schedule
& ~GFS_MONOTONIC
) != GFS_STATIC
;
208 while (isspace ((unsigned char) *val
))
214 value
= strtoul (val
, &end
, 10);
215 if (errno
|| end
== val
)
218 while (isspace ((unsigned char) *end
))
223 if ((int)value
!= value
)
226 if (value
== 0 && (*schedule
& ~GFS_MONOTONIC
) != GFS_STATIC
)
232 print_env_var_error (env
, val
);
236 char name
[val
- env
];
237 memcpy (name
, env
, val
- env
- 1);
238 name
[val
- env
- 1] = '\0';
239 gomp_error ("Invalid value for chunk size in "
240 "environment variable %s: %s", name
, val
);
244 /* Parse an unsigned long environment variable. Return true if one was
245 present and it was successfully parsed. If SECURE, use secure_getenv to the
246 environment variable. */
249 parse_unsigned_long_1 (const char *env
, const char *val
, unsigned long *pvalue
,
258 while (isspace ((unsigned char) *val
))
264 value
= strtoul (val
, &end
, 10);
265 if (errno
|| end
== val
|| (long) value
<= 0 - allow_zero
)
268 while (isspace ((unsigned char) *end
))
277 print_env_var_error (env
, val
);
281 /* As parse_unsigned_long_1, but always use getenv. */
284 parse_unsigned_long (const char *env
, const char *val
, void *const params
[])
286 unsigned long upper
= (uintptr_t) params
[2];
287 unsigned long pvalue
= 0;
288 bool ret
= parse_unsigned_long_1 (env
, val
, &pvalue
, (bool) params
[1]);
293 *(unsigned long *) params
[0] = pvalue
;
298 if (upper
<= UCHAR_MAX
)
299 *(unsigned char *) params
[0] = pvalue
;
300 else if (upper
<= UINT_MAX
)
301 *(unsigned int *) params
[0] = pvalue
;
303 *(unsigned long *) params
[0] = pvalue
;
309 /* Parse a positive int environment variable. Return true if one was
310 present and it was successfully parsed. If SECURE, use secure_getenv to the
311 environment variable. */
314 parse_int_1 (const char *env
, const char *val
, int *pvalue
, bool allow_zero
)
317 if (!parse_unsigned_long_1 (env
, val
, &value
, allow_zero
))
321 print_env_var_error (env
, val
);
324 *pvalue
= (int) value
;
329 parse_int (const char *env
, const char *val
, void *const params
[])
331 return parse_int_1 (env
, val
, (int *) params
[0], (bool) params
[1]);
334 /* As parse_int_1, but use getenv_secure. */
337 parse_int_secure (const char *env
, int *pvalue
, bool allow_zero
)
339 return parse_int_1 (env
, secure_getenv (env
), pvalue
, allow_zero
);
342 /* Parse an unsigned long list environment variable. Return true if one was
343 present and it was successfully parsed. */
346 parse_unsigned_long_list (const char *env
, const char *val
,
347 void *const params
[])
349 unsigned long *p1stvalue
= (unsigned long *) params
[0];
350 unsigned long **pvalues
= (unsigned long **) params
[1];
351 unsigned long *pnvalues
= (unsigned long *) params
[2];
353 unsigned long value
, *values
= NULL
;
358 while (isspace ((unsigned char) *val
))
364 value
= strtoul (val
, &end
, 10);
365 if (errno
|| (long) value
<= 0)
368 while (isspace ((unsigned char) *end
))
374 unsigned long nvalues
= 0, nalloced
= 0;
379 if (nvalues
== nalloced
)
382 nalloced
= nalloced
? nalloced
* 2 : 16;
383 n
= realloc (values
, nalloced
* sizeof (unsigned long));
387 char name
[val
- env
];
388 memcpy (name
, env
, val
- env
- 1);
389 name
[val
- env
- 1] = '\0';
390 gomp_error ("Out of memory while trying to parse"
391 " environment variable %s", name
);
396 values
[nvalues
++] = value
;
399 while (isspace ((unsigned char) *val
))
405 value
= strtoul (val
, &end
, 10);
406 if (errno
|| (long) value
<= 0)
409 values
[nvalues
++] = value
;
410 while (isspace ((unsigned char) *end
))
418 *p1stvalue
= values
[0];
436 print_env_var_error (env
, val
);
441 parse_target_offload (const char *env
, const char *val
, void *const params
[])
443 int new_offload
= -1;
448 while (isspace ((unsigned char) *val
))
450 if (strncasecmp (val
, "default", 7) == 0)
453 new_offload
= GOMP_TARGET_OFFLOAD_DEFAULT
;
455 else if (strncasecmp (val
, "mandatory", 9) == 0)
458 new_offload
= GOMP_TARGET_OFFLOAD_MANDATORY
;
460 else if (strncasecmp (val
, "disabled", 8) == 0)
463 new_offload
= GOMP_TARGET_OFFLOAD_DISABLED
;
465 while (isspace ((unsigned char) *val
))
467 if (new_offload
!= -1 && *val
== '\0')
469 *(enum gomp_target_offload_t
*) params
[0] = new_offload
;
473 print_env_var_error (env
, val
);
477 /* Parse environment variable set to a boolean or list of omp_proc_bind_t
478 enum values. Return true if one was present and it was successfully
482 parse_bind_var (const char *env
, const char *val
, void *const params
[])
484 char *p1stvalue
= (char *) params
[0];
485 char **pvalues
= (char **) params
[1];
486 unsigned long *pnvalues
= (unsigned long *) params
[2];
487 char value
= omp_proc_bind_false
, *values
= NULL
;
489 static struct proc_bind_kinds
493 omp_proc_bind_t kind
;
496 { "false", 5, omp_proc_bind_false
},
497 { "true", 4, omp_proc_bind_true
},
498 { "master", 6, omp_proc_bind_master
},
499 { "primary", 7, omp_proc_bind_primary
},
500 { "close", 5, omp_proc_bind_close
},
501 { "spread", 6, omp_proc_bind_spread
}
507 while (isspace ((unsigned char) *val
))
512 for (i
= 0; i
< 6; i
++)
513 if (strncasecmp (val
, kinds
[i
].name
, kinds
[i
].len
) == 0)
515 value
= kinds
[i
].kind
;
522 while (isspace ((unsigned char) *val
))
528 unsigned long nvalues
= 0, nalloced
= 0;
530 if (value
== omp_proc_bind_false
531 || value
== omp_proc_bind_true
)
537 if (nvalues
== nalloced
)
540 nalloced
= nalloced
? nalloced
* 2 : 16;
541 n
= realloc (values
, nalloced
);
545 char name
[val
- env
];
546 memcpy (name
, env
, val
- env
- 1);
547 name
[val
- env
- 1] = '\0';
548 gomp_error ("Out of memory while trying to parse"
549 " environment variable %s", name
);
554 values
[nvalues
++] = value
;
557 while (isspace ((unsigned char) *val
))
562 for (i
= 2; i
< 6; i
++)
563 if (strncasecmp (val
, kinds
[i
].name
, kinds
[i
].len
) == 0)
565 value
= kinds
[i
].kind
;
572 values
[nvalues
++] = value
;
573 while (isspace ((unsigned char) *val
))
581 *p1stvalue
= values
[0];
594 print_env_var_error (env
, val
);
599 parse_one_place (char **envp
, bool *negatep
, unsigned long *lenp
,
602 char *env
= *envp
, *start
;
603 void *p
= gomp_places_list
? gomp_places_list
[gomp_places_list_len
] : NULL
;
604 unsigned long len
= 1;
607 bool any_negate
= false;
608 bool has_braces
= true;
610 while (isspace ((unsigned char) *env
))
616 while (isspace ((unsigned char) *env
))
622 unsigned long this_num
;
625 this_num
= strtoul (env
, &end
, 10);
626 if (errno
|| end
== env
)
631 && !gomp_affinity_add_cpus (p
, this_num
, 1, 1, false))
637 while (isspace ((unsigned char) *env
))
641 for (pass
= 0; pass
< (any_negate
? 2 : has_braces
); pass
++)
646 unsigned long this_num
, this_len
= 1;
647 long this_stride
= 1;
648 bool this_negate
= (*env
== '!');
652 if (gomp_places_list
)
655 while (isspace ((unsigned char) *env
))
660 this_num
= strtoul (env
, &end
, 10);
661 if (errno
|| end
== env
)
664 while (isspace ((unsigned char) *env
))
671 while (isspace ((unsigned char) *env
))
674 this_len
= strtoul (env
, &env
, 10);
675 if (errno
|| this_len
== 0)
677 while (isspace ((unsigned char) *env
))
682 while (isspace ((unsigned char) *env
))
685 this_stride
= strtol (env
, &end
, 10);
686 if (errno
|| end
== env
)
689 while (isspace ((unsigned char) *env
))
693 if (gomp_places_list
&& pass
== this_negate
)
697 if (!gomp_affinity_remove_cpu (p
, this_num
))
700 else if (!gomp_affinity_add_cpus (p
, this_num
, this_len
,
714 while (isspace ((unsigned char) *env
))
722 while (isspace ((unsigned char) *env
))
725 len
= strtoul (env
, &env
, 10);
726 if (errno
|| len
== 0 || len
>= 65536)
728 while (isspace ((unsigned char) *env
))
733 while (isspace ((unsigned char) *env
))
736 stride
= strtol (env
, &end
, 10);
737 if (errno
|| end
== env
)
740 while (isspace ((unsigned char) *env
))
751 parse_places_var (const char *name
, bool ignore
)
753 char *env
= getenv (name
), *end
;
754 bool any_negate
= false;
756 unsigned long count
= 0;
760 while (isspace ((unsigned char) *env
))
765 if (strncasecmp (env
, "threads", 7) == 0)
770 else if (strncasecmp (env
, "cores", 5) == 0)
775 else if (strncasecmp (env
, "sockets", 7) == 0)
780 else if (strncasecmp (env
, "ll_caches", 9) == 0)
785 else if (strncasecmp (env
, "numa_domains", 12) == 0)
793 while (isspace ((unsigned char) *env
))
799 while (isspace ((unsigned char) *env
))
803 count
= strtoul (env
, &end
, 10);
804 if (errno
|| end
== env
)
807 while (isspace ((unsigned char) *env
))
812 while (isspace ((unsigned char) *env
))
821 return gomp_affinity_init_level (level
, count
, false);
831 if (!parse_one_place (&end
, &negate
, &len
, &stride
))
854 gomp_places_list_len
= 0;
855 gomp_places_list
= gomp_affinity_alloc (count
, false);
856 if (gomp_places_list
== NULL
)
864 gomp_affinity_init_place (gomp_places_list
[gomp_places_list_len
]);
865 if (!parse_one_place (&env
, &negate
, &len
, &stride
))
870 for (count
= 0; count
< gomp_places_list_len
; count
++)
871 if (gomp_affinity_same_place
872 (gomp_places_list
[count
],
873 gomp_places_list
[gomp_places_list_len
]))
875 if (count
== gomp_places_list_len
)
877 gomp_error ("Trying to remove a non-existing place from list "
881 p
= gomp_places_list
[count
];
882 memmove (&gomp_places_list
[count
],
883 &gomp_places_list
[count
+ 1],
884 (gomp_places_list_len
- count
- 1) * sizeof (void *));
885 --gomp_places_list_len
;
886 gomp_places_list
[gomp_places_list_len
] = p
;
889 ++gomp_places_list_len
;
892 for (count
= 0; count
< len
- 1; count
++)
893 if (!gomp_affinity_copy_place
894 (gomp_places_list
[gomp_places_list_len
+ count
+ 1],
895 gomp_places_list
[gomp_places_list_len
+ count
],
898 gomp_places_list_len
+= len
;
906 if (gomp_places_list_len
== 0)
908 gomp_error ("All places have been removed");
911 if (!gomp_affinity_finalize_place_list (false))
916 free (gomp_places_list
);
917 gomp_places_list
= NULL
;
918 gomp_places_list_len
= 0;
919 gomp_error ("Invalid value for environment variable %s", name
);
923 /* Parse the OMP_STACKSIZE environment varible. Return true if one was
924 present and it was successfully parsed. */
927 parse_stacksize (const char *env
, const char *val
, void *const params
[])
930 unsigned long value
, shift
= 10;
935 while (isspace ((unsigned char) *val
))
941 value
= strtoul (val
, &end
, 10);
942 if (errno
|| end
== val
)
945 while (isspace ((unsigned char) *end
))
949 switch (tolower ((unsigned char) *end
))
966 while (isspace ((unsigned char) *end
))
972 if (((value
<< shift
) >> shift
) != value
)
975 *(unsigned long *) params
[0] = value
<< shift
;
979 print_env_var_error (env
, val
);
983 /* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
984 present and it was successfully parsed. */
987 parse_spincount (const char *name
, unsigned long long *pvalue
)
990 unsigned long long value
, mult
= 1;
996 while (isspace ((unsigned char) *env
))
1001 if (strncasecmp (env
, "infinite", 8) == 0
1002 || strncasecmp (env
, "infinity", 8) == 0)
1010 value
= strtoull (env
, &end
, 10);
1011 if (errno
|| end
== env
)
1014 while (isspace ((unsigned char) *end
))
1018 switch (tolower ((unsigned char) *end
))
1024 mult
= 1000LL * 1000LL;
1027 mult
= 1000LL * 1000LL * 1000LL;
1030 mult
= 1000LL * 1000LL * 1000LL * 1000LL;
1037 while (isspace ((unsigned char) *end
))
1043 if (value
> ~0ULL / mult
)
1052 gomp_error ("Invalid value for environment variable %s", name
);
1056 /* Parse a boolean value for environment variable NAME and store the
1057 result in VALUE. Return true if one was present and it was
1058 successfully parsed. */
1060 parse_boolean (const char *env
, const char *val
, void *const params
[])
1062 bool *value
= (bool *) params
[0];
1067 while (isspace ((unsigned char) *val
))
1069 if (strncasecmp (val
, "true", 4) == 0)
1074 else if (strncasecmp (val
, "false", 5) == 0)
1081 while (isspace ((unsigned char) *val
))
1085 print_env_var_error (env
, val
);
1091 /* Parse the OMP_WAIT_POLICY environment variable and return the value. */
1094 parse_wait_policy (const char *env
, const char *val
, void *const params
[])
1096 int *pvalue
= (int *) params
[0];
1105 while (isspace ((unsigned char) *val
))
1107 if (strncasecmp (val
, "active", 6) == 0)
1112 else if (strncasecmp (val
, "passive", 7) == 0)
1119 while (isspace ((unsigned char) *val
))
1126 print_env_var_error (env
, val
);
1131 /* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
1132 present and it was successfully parsed. */
1135 parse_affinity (bool ignore
)
1137 char *env
, *end
, *start
;
1139 unsigned long cpu_beg
, cpu_end
, cpu_stride
;
1140 size_t count
= 0, needed
;
1142 env
= getenv ("GOMP_CPU_AFFINITY");
1147 for (pass
= 0; pass
< 2; pass
++)
1155 gomp_places_list_len
= 0;
1156 gomp_places_list
= gomp_affinity_alloc (count
, true);
1157 if (gomp_places_list
== NULL
)
1162 while (isspace ((unsigned char) *env
))
1166 cpu_beg
= strtoul (env
, &end
, 0);
1167 if (errno
|| end
== env
|| cpu_beg
>= 65536)
1176 cpu_end
= strtoul (++env
, &end
, 0);
1177 if (errno
|| end
== env
|| cpu_end
>= 65536 || cpu_end
< cpu_beg
)
1184 cpu_stride
= strtoul (++env
, &end
, 0);
1185 if (errno
|| cpu_stride
== 0 || cpu_stride
>= 65536)
1192 needed
= (cpu_end
- cpu_beg
) / cpu_stride
+ 1;
1199 void *p
= gomp_places_list
[gomp_places_list_len
];
1200 gomp_affinity_init_place (p
);
1201 if (gomp_affinity_add_cpus (p
, cpu_beg
, 1, 0, true))
1202 ++gomp_places_list_len
;
1203 cpu_beg
+= cpu_stride
;
1207 while (isspace ((unsigned char) *env
))
1212 else if (*env
== '\0')
1218 if (gomp_places_list_len
== 0)
1220 free (gomp_places_list
);
1221 gomp_places_list
= NULL
;
1227 gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
1231 /* Parse the OMP_ALLOCATOR environment variable and return the value. */
1233 parse_allocator (const char *env
, const char *val
, void *const params
[])
1235 uintptr_t *ret
= (uintptr_t *) params
[0];
1236 *ret
= omp_default_mem_alloc
;
1241 while (isspace ((unsigned char) *val
))
1246 else if (strncasecmp (val, #v, sizeof (#v) - 1) == 0) \
1249 val += sizeof (#v) - 1; \
1251 C (omp_default_mem_alloc
)
1252 C (omp_large_cap_mem_alloc
)
1253 C (omp_const_mem_alloc
)
1254 C (omp_high_bw_mem_alloc
)
1255 C (omp_low_lat_mem_alloc
)
1256 C (omp_cgroup_mem_alloc
)
1257 C (omp_pteam_mem_alloc
)
1258 C (omp_thread_mem_alloc
)
1262 while (isspace ((unsigned char) *val
))
1266 print_env_var_error (env
, val
);
1267 *ret
= omp_default_mem_alloc
;
1272 parse_acc_device_type (void)
1274 const char *env
= getenv ("ACC_DEVICE_TYPE");
1276 if (env
&& *env
!= '\0')
1277 goacc_device_type
= strdup (env
);
1279 goacc_device_type
= NULL
;
1283 parse_gomp_openacc_dim (void)
1285 /* The syntax is the same as for the -fopenacc-dim compilation option. */
1286 const char *var_name
= "GOMP_OPENACC_DIM";
1287 const char *env_var
= getenv (var_name
);
1288 const char *pos
= env_var
;
1294 for (i
= 0; *pos
&& i
!= GOMP_DIM_MAX
; i
++)
1299 if (i
&& *pos
++ != ':')
1306 val
= strtol (pos
, &eptr
, 10);
1307 if (errno
|| eptr
== pos
|| val
< 0 || (unsigned)val
!= val
)
1310 goacc_default_dims
[i
] = (int)val
;
1311 pos
= (const char *) eptr
;
1315 /* Helper function for omp_display_env which prints the values of run_sched_var.
1316 'device' can be 'host', 'dev', 'all' or a particular device number. */
1319 print_schedule (enum gomp_schedule_type run_sched_var
, int run_sched_chunk_size
,
1322 fprintf (stderr
, " [%s] OMP_SCHEDULE = '", device
);
1323 if ((run_sched_var
& GFS_MONOTONIC
))
1325 if (run_sched_var
!= (GFS_MONOTONIC
| GFS_STATIC
))
1326 fputs ("MONOTONIC:", stderr
);
1328 else if (run_sched_var
== GFS_STATIC
)
1329 fputs ("NONMONOTONIC:", stderr
);
1330 switch (run_sched_var
& ~GFS_MONOTONIC
)
1333 fputs ("RUNTIME", stderr
);
1334 if (run_sched_chunk_size
!= 1)
1335 fprintf (stderr
, ",%d", run_sched_chunk_size
);
1338 fputs ("STATIC", stderr
);
1339 if (run_sched_chunk_size
!= 0)
1340 fprintf (stderr
, ",%d", run_sched_chunk_size
);
1343 fputs ("DYNAMIC", stderr
);
1344 if (run_sched_chunk_size
!= 1)
1345 fprintf (stderr
, ",%d", run_sched_chunk_size
);
1348 fputs ("GUIDED", stderr
);
1349 if (run_sched_chunk_size
!= 1)
1350 fprintf (stderr
, ",%d", run_sched_chunk_size
);
1353 fputs ("AUTO", stderr
);
1356 fputs ("'\n", stderr
);
1359 /* Helper function for omp_display_env which prints the values of proc_bind_var.
1360 'device' can be 'host', 'dev', 'all', or a particular device number. */
1363 print_proc_bind (char proc_bind_var
, unsigned long len
, char **list
,
1366 fprintf (stderr
, " [%s] OMP_PROC_BIND = '", device
);
1367 switch (proc_bind_var
)
1369 case omp_proc_bind_false
:
1370 fputs ("FALSE", stderr
);
1372 case omp_proc_bind_true
:
1373 fputs ("TRUE", stderr
);
1375 case omp_proc_bind_master
:
1376 fputs ("MASTER", stderr
); /* TODO: Change to PRIMARY for OpenMP 5.1. */
1378 case omp_proc_bind_close
:
1379 fputs ("CLOSE", stderr
);
1381 case omp_proc_bind_spread
:
1382 fputs ("SPREAD", stderr
);
1385 for (int i
= 1; i
< len
; i
++)
1388 case omp_proc_bind_master
:
1389 fputs (",MASTER", stderr
); /* TODO: Change to PRIMARY for OpenMP 5.1. */
1391 case omp_proc_bind_close
:
1392 fputs (",CLOSE", stderr
);
1394 case omp_proc_bind_spread
:
1395 fputs (",SPREAD", stderr
);
1398 fputs ("'\n", stderr
);
1401 enum gomp_parse_type
1412 /* The following table contains items that help parsing environment variables
1413 and fill corresponding ICVs with values. FLAG_VARS contain all ICVS which
1414 are affected by the environment variable. FLAGS determine what variant of
1415 environment variable is allowed. */
1417 #define ENTRY(NAME) NAME, sizeof (NAME) - 1
1418 static const struct envvar
1422 uint8_t flag_vars
[3];
1424 bool (*parse_func
) (const char *, const char *, void *const[]);
1426 { ENTRY ("SCHEDULE"),
1427 { GOMP_ICV_SCHEDULE
, GOMP_ICV_SCHEDULE_CHUNK_SIZE
},
1428 GOMP_ENV_SUFFIX_DEV
| GOMP_ENV_SUFFIX_ALL
| GOMP_ENV_SUFFIX_DEV_X
,
1430 { ENTRY ("NUM_TEAMS"),
1431 { GOMP_ICV_NTEAMS
},
1432 GOMP_ENV_SUFFIX_DEV
| GOMP_ENV_SUFFIX_ALL
| GOMP_ENV_SUFFIX_DEV_X
,
1434 { ENTRY ("DYNAMIC"),
1435 { GOMP_ICV_DYNAMIC
},
1436 GOMP_ENV_SUFFIX_DEV
| GOMP_ENV_SUFFIX_ALL
| GOMP_ENV_SUFFIX_DEV_X
,
1438 { ENTRY ("TEAMS_THREAD_LIMIT"),
1439 { GOMP_ICV_TEAMS_THREAD_LIMIT
},
1440 GOMP_ENV_SUFFIX_DEV
| GOMP_ENV_SUFFIX_ALL
| GOMP_ENV_SUFFIX_DEV_X
,
1442 { ENTRY ("THREAD_LIMIT"),
1443 { GOMP_ICV_THREAD_LIMIT
},
1444 GOMP_ENV_SUFFIX_DEV
| GOMP_ENV_SUFFIX_ALL
| GOMP_ENV_SUFFIX_DEV_X
,
1445 &parse_unsigned_long
},
1446 { ENTRY ("NUM_THREADS"),
1447 { GOMP_ICV_NTHREADS
, GOMP_ICV_NTHREADS_LIST
, GOMP_ICV_NTHREADS_LIST_LEN
},
1448 GOMP_ENV_SUFFIX_DEV
| GOMP_ENV_SUFFIX_ALL
| GOMP_ENV_SUFFIX_DEV_X
,
1449 &parse_unsigned_long_list
},
1450 { ENTRY ("PROC_BIND"),
1451 { GOMP_ICV_BIND
, GOMP_ICV_BIND_LIST
, GOMP_ICV_BIND_LIST_LEN
},
1452 GOMP_ENV_SUFFIX_DEV
| GOMP_ENV_SUFFIX_ALL
| GOMP_ENV_SUFFIX_DEV_X
,
1454 { ENTRY ("MAX_ACTIVE_LEVELS"),
1455 { GOMP_ICV_MAX_ACTIVE_LEVELS
},
1456 GOMP_ENV_SUFFIX_DEV
| GOMP_ENV_SUFFIX_ALL
| GOMP_ENV_SUFFIX_DEV_X
,
1457 &parse_unsigned_long
},
1458 { ENTRY ("WAIT_POLICY"),
1459 { GOMP_ICV_WAIT_POLICY
},
1460 GOMP_ENV_SUFFIX_DEV
| GOMP_ENV_SUFFIX_ALL
| GOMP_ENV_SUFFIX_DEV_X
,
1461 &parse_wait_policy
},
1462 { ENTRY ("STACKSIZE"),
1463 { GOMP_ICV_STACKSIZE
},
1464 GOMP_ENV_SUFFIX_DEV
| GOMP_ENV_SUFFIX_ALL
| GOMP_ENV_SUFFIX_DEV_X
,
1466 { ENTRY ("CANCELLATION"), { GOMP_ICV_CANCELLATION
}, 0, &parse_boolean
},
1467 { ENTRY ("DISPLAY_AFFINITY"), { GOMP_ICV_DISPLAY_AFFINITY
}, 0,
1469 { ENTRY ("TARGET_OFFLOAD"), { GOMP_ICV_TARGET_OFFLOAD
}, 0,
1470 &parse_target_offload
},
1471 { ENTRY ("MAX_TASK_PRIORITY"), { GOMP_ICV_MAX_TASK_PRIORITY
}, 0,
1473 { ENTRY ("ALLOCATOR"), { GOMP_ICV_ALLOCATOR
}, 0, &parse_allocator
},
1474 { ENTRY ("DEFAULT_DEVICE"), { GOMP_ICV_DEFAULT_DEVICE
},
1475 GOMP_ENV_SUFFIX_DEV
| GOMP_ENV_SUFFIX_ALL
| GOMP_ENV_SUFFIX_DEV_X
,
1479 #define OMP_VAR_CNT (sizeof (envvars) / sizeof (envvars[0]))
1481 /* The following table is used to apply the hierarchy of ICV variants for host
1482 variables, e.g. nteams_var is set to OMP_NUM_TEAMS_ALL if OMP_NUM_TEAMS is
1485 static const struct host_envvar
1487 unsigned char flag_var
;
1490 } host_envvars
[] = {
1491 { GOMP_ICV_NTEAMS
, { &gomp_nteams_var
}, PARSE_INT
},
1492 { GOMP_ICV_DYNAMIC
, { &gomp_global_icv
.dyn_var
}, PARSE_BOOL
},
1493 { GOMP_ICV_DEFAULT_DEVICE
, { &gomp_global_icv
.default_device_var
},
1495 { GOMP_ICV_TEAMS_THREAD_LIMIT
, { &gomp_teams_thread_limit_var
}, PARSE_INT
},
1496 { GOMP_ICV_SCHEDULE
,
1497 { &gomp_global_icv
.run_sched_var
, &gomp_global_icv
.run_sched_chunk_size
},
1499 { GOMP_ICV_THREAD_LIMIT
, { &gomp_global_icv
.thread_limit_var
}, PARSE_UINT
},
1500 { GOMP_ICV_NTHREADS
,
1501 { &gomp_global_icv
.nthreads_var
, &gomp_nthreads_var_list
,
1502 &gomp_nthreads_var_list_len
}, PARSE_ULONG
},
1504 { &gomp_global_icv
.bind_var
, &gomp_bind_var_list
, &gomp_bind_var_list_len
},
1506 { GOMP_ICV_MAX_ACTIVE_LEVELS
, { &gomp_global_icv
.max_active_levels_var
},
1509 #define OMP_HOST_VAR_CNT (sizeof (host_envvars) / sizeof (host_envvars[0]))
1511 #define INT_MAX_STR_LEN 10
1514 gomp_get_icv_flag (uint32_t value
, enum gomp_icvs icv
)
1516 return value
& (1 << (icv
- 1));
1520 gomp_set_icv_flag (uint32_t *value
, enum gomp_icvs icv
)
1522 *value
|= 1 << (icv
- 1);
1526 print_device_specific_icvs (int icv_code
)
1528 struct gomp_icv_list
*list
= gomp_initial_icv_list
;
1530 char dev_num
[INT_MAX_STR_LEN
+ 1];
1532 while (list
!= NULL
)
1534 if (list
->device_num
< 0)
1542 case GOMP_ICV_NTEAMS
:
1543 if (gomp_get_icv_flag (list
->flags
, GOMP_ICV_NTEAMS
))
1544 fprintf (stderr
, " [%d] OMP_NUM_TEAMS = '%d'\n",
1545 list
->device_num
, list
->icvs
.nteams_var
);
1547 case GOMP_ICV_DYNAMIC
:
1548 if (gomp_get_icv_flag (list
->flags
, GOMP_ICV_DYNAMIC
))
1549 fprintf (stderr
, " [%d] OMP_DYNAMIC = '%s'\n",
1550 list
->device_num
, list
->icvs
.dyn_var
? "TRUE" : "FALSE");
1552 case GOMP_ICV_TEAMS_THREAD_LIMIT
:
1553 if (gomp_get_icv_flag (list
->flags
, GOMP_ICV_TEAMS_THREAD_LIMIT
))
1554 fprintf (stderr
, " [%d] OMP_TEAMS_THREAD_LIMIT = '%u'\n",
1555 list
->device_num
, list
->icvs
.teams_thread_limit_var
);
1557 case GOMP_ICV_SCHEDULE
:
1558 if (!(gomp_get_icv_flag (list
->flags
, GOMP_ICV_SCHEDULE
)))
1560 sprintf (dev_num
, "%d", list
->device_num
);
1561 print_schedule (list
->icvs
.run_sched_var
,
1562 list
->icvs
.run_sched_chunk_size
,
1565 case GOMP_ICV_THREAD_LIMIT
:
1566 if (gomp_get_icv_flag (list
->flags
, GOMP_ICV_THREAD_LIMIT
))
1567 fprintf (stderr
, " [%d] OMP_THREAD_LIMIT = '%d'\n",
1568 list
->device_num
, list
->icvs
.thread_limit_var
);
1570 case GOMP_ICV_NTHREADS
:
1571 if (!(gomp_get_icv_flag (list
->flags
, GOMP_ICV_NTHREADS
)))
1573 fprintf (stderr
, " [%d] OMP_NUM_THREADS = '%lu", list
->device_num
,
1574 list
->icvs
.nthreads_var
);
1575 for (i
= 1; i
< list
->icvs
.nthreads_var_list_len
; i
++)
1576 fprintf (stderr
, ",%lu", list
->icvs
.nthreads_var_list
[i
]);
1577 fputs ("'\n", stderr
);
1579 case GOMP_ICV_MAX_ACTIVE_LEVELS
:
1580 fprintf (stderr
, " [%d] OMP_MAX_ACTIVE_LEVELS = '%u'\n",
1581 list
->device_num
, list
->icvs
.max_active_levels_var
);
1584 if (!(gomp_get_icv_flag (list
->flags
, GOMP_ICV_BIND
)))
1586 sprintf (dev_num
, "%d", list
->device_num
);
1587 print_proc_bind (list
->icvs
.bind_var
, list
->icvs
.bind_var_list_len
,
1588 &list
->icvs
.bind_var_list
, dev_num
);
1590 case GOMP_ICV_WAIT_POLICY
:
1591 if (gomp_get_icv_flag (list
->flags
, GOMP_ICV_WAIT_POLICY
))
1592 fprintf (stderr
, " [%d] OMP_WAIT_POLICY = '%s'\n",
1594 list
->icvs
.wait_policy
> 0 ? "ACTIVE" : "PASSIVE");
1596 case GOMP_ICV_STACKSIZE
:
1597 if (gomp_get_icv_flag (list
->flags
, GOMP_ICV_STACKSIZE
))
1598 fprintf (stderr
, " [%d] OMP_STACKSIZE = '%lu'\n",
1599 list
->device_num
, list
->icvs
.stacksize
);
1607 omp_display_env (int verbose
)
1610 struct gomp_icv_list
*dev
1611 = gomp_get_initial_icv_item (GOMP_DEVICE_NUM_FOR_DEV
);
1612 struct gomp_icv_list
*all
1613 = gomp_get_initial_icv_item (GOMP_DEVICE_NUM_FOR_ALL
);
1614 struct gomp_icv_list
*none
1615 = gomp_get_initial_icv_item (GOMP_DEVICE_NUM_FOR_NO_SUFFIX
);
1617 fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr
);
1619 fputs (" _OPENMP = '201511'\n", stderr
);
1621 fprintf (stderr
, " [host] OMP_DYNAMIC = '%s'\n",
1622 none
->icvs
.dyn_var
? "TRUE" : "FALSE");
1623 if (all
!= NULL
&& gomp_get_icv_flag (all
->flags
, GOMP_ICV_DYNAMIC
))
1624 fprintf (stderr
, " [all] OMP_DYNAMIC = '%s'\n",
1625 all
->icvs
.dyn_var
? "TRUE" : "FALSE");
1626 if (dev
!= NULL
&& gomp_get_icv_flag (dev
->flags
, GOMP_ICV_DYNAMIC
))
1627 fprintf (stderr
, " [device] OMP_DYNAMIC = '%s'\n",
1628 dev
->icvs
.dyn_var
? "TRUE" : "FALSE");
1629 print_device_specific_icvs (GOMP_ICV_DYNAMIC
);
1631 /* The OMP_NESTED environment variable has been deprecated. */
1632 fprintf (stderr
, " [host] OMP_NESTED = '%s'\n",
1633 none
->icvs
.max_active_levels_var
> 1 ? "TRUE" : "FALSE");
1635 fprintf (stderr
, " [host] OMP_NUM_THREADS = '%lu",
1636 none
->icvs
.nthreads_var
);
1637 for (i
= 1; i
< none
->icvs
.nthreads_var_list_len
; i
++)
1638 fprintf (stderr
, ",%lu", none
->icvs
.nthreads_var_list
[i
]);
1639 fputs ("'\n", stderr
);
1640 if (all
!= NULL
&& gomp_get_icv_flag (all
->flags
, GOMP_ICV_NTHREADS
))
1642 fprintf (stderr
, " [all] OMP_NUM_THREADS = '%lu",
1643 all
->icvs
.nthreads_var
);
1644 for (i
= 1; i
< all
->icvs
.nthreads_var_list_len
; i
++)
1645 fprintf (stderr
, ",%lu", all
->icvs
.nthreads_var_list
[i
]);
1646 fputs ("'\n", stderr
);
1648 if (dev
!= NULL
&& gomp_get_icv_flag (dev
->flags
, GOMP_ICV_NTHREADS
))
1650 fprintf (stderr
, " [device] OMP_NUM_THREADS = '%lu",
1651 dev
->icvs
.nthreads_var
);
1652 for (i
= 1; i
< dev
->icvs
.nthreads_var_list_len
; i
++)
1653 fprintf (stderr
, ",%lu", dev
->icvs
.nthreads_var_list
[i
]);
1654 fputs ("'\n", stderr
);
1656 print_device_specific_icvs (GOMP_ICV_NTHREADS
);
1659 print_schedule (none
->icvs
.run_sched_var
,
1660 none
->icvs
.run_sched_chunk_size
, "host");
1661 if (all
!= NULL
&& gomp_get_icv_flag (all
->flags
, GOMP_ICV_SCHEDULE
))
1662 print_schedule (all
->icvs
.run_sched_var
,
1663 all
->icvs
.run_sched_chunk_size
, "all");
1664 if (dev
!= NULL
&& gomp_get_icv_flag (dev
->flags
, GOMP_ICV_SCHEDULE
))
1665 print_schedule (dev
->icvs
.run_sched_var
,
1666 dev
->icvs
.run_sched_chunk_size
, "device");
1667 print_device_specific_icvs (GOMP_ICV_SCHEDULE
);
1669 print_proc_bind (none
->icvs
.bind_var
,
1670 none
->icvs
.bind_var_list_len
,
1671 &none
->icvs
.bind_var_list
, "host");
1672 if (all
!= NULL
&& gomp_get_icv_flag (all
->flags
, GOMP_ICV_BIND
))
1673 print_proc_bind (all
->icvs
.bind_var
,
1674 all
->icvs
.bind_var_list_len
,
1675 &all
->icvs
.bind_var_list
, "all");
1676 if (dev
!= NULL
&& gomp_get_icv_flag (dev
->flags
, GOMP_ICV_BIND
))
1677 print_proc_bind (dev
->icvs
.bind_var
,
1678 dev
->icvs
.bind_var_list_len
,
1679 &dev
->icvs
.bind_var_list
, "device");
1680 print_device_specific_icvs (GOMP_ICV_BIND
);
1682 fputs (" [host] OMP_PLACES = '", stderr
);
1683 for (i
= 0; i
< gomp_places_list_len
; i
++)
1685 fputs ("{", stderr
);
1686 gomp_affinity_print_place (gomp_places_list
[i
]);
1687 fputs (i
+ 1 == gomp_places_list_len
? "}" : "},", stderr
);
1689 fputs ("'\n", stderr
);
1691 fprintf (stderr
, " [host] OMP_STACKSIZE = '%lu'\n",
1692 none
->icvs
.stacksize
);
1693 if (all
!= NULL
&& gomp_get_icv_flag (all
->flags
, GOMP_ICV_STACKSIZE
))
1694 fprintf (stderr
, " [all] OMP_STACKSIZE = '%lu'\n",
1695 all
->icvs
.stacksize
);
1696 if (dev
!= NULL
&& gomp_get_icv_flag (dev
->flags
, GOMP_ICV_STACKSIZE
))
1697 fprintf (stderr
, " [device] OMP_STACKSIZE = '%lu'\n",
1698 dev
->icvs
.stacksize
);
1699 print_device_specific_icvs (GOMP_ICV_STACKSIZE
);
1701 /* GOMP's default value is actually neither active nor passive. */
1702 fprintf (stderr
, " [host] OMP_WAIT_POLICY = '%s'\n",
1703 none
->icvs
.wait_policy
> 0 ? "ACTIVE" : "PASSIVE");
1704 if (all
!= NULL
&& gomp_get_icv_flag (all
->flags
, GOMP_ICV_WAIT_POLICY
))
1705 fprintf (stderr
, " [all] OMP_WAIT_POLICY = '%s'\n",
1706 all
->icvs
.wait_policy
> 0 ? "ACTIVE" : "PASSIVE");
1707 if (dev
!= NULL
&& gomp_get_icv_flag (dev
->flags
, GOMP_ICV_WAIT_POLICY
))
1708 fprintf (stderr
, " [device] OMP_WAIT_POLICY = '%s'\n",
1709 dev
->icvs
.wait_policy
> 0 ? "ACTIVE" : "PASSIVE");
1710 print_device_specific_icvs (GOMP_ICV_WAIT_POLICY
);
1712 fprintf (stderr
, " [host] OMP_THREAD_LIMIT = '%u'\n",
1713 none
->icvs
.thread_limit_var
);
1714 if (all
!= NULL
&& gomp_get_icv_flag (all
->flags
, GOMP_ICV_THREAD_LIMIT
))
1715 fprintf (stderr
, " [all] OMP_THREAD_LIMIT = '%d'\n",
1716 all
->icvs
.thread_limit_var
);
1717 if (dev
!= NULL
&& gomp_get_icv_flag (dev
->flags
, GOMP_ICV_THREAD_LIMIT
))
1718 fprintf (stderr
, " [device] OMP_THREAD_LIMIT = '%d'\n",
1719 dev
->icvs
.thread_limit_var
);
1720 print_device_specific_icvs (GOMP_ICV_THREAD_LIMIT
);
1722 fprintf (stderr
, " [host] OMP_MAX_ACTIVE_LEVELS = '%u'\n",
1723 none
->icvs
.max_active_levels_var
);
1724 if (all
!= NULL
&& gomp_get_icv_flag (all
->flags
,
1725 GOMP_ICV_MAX_ACTIVE_LEVELS
))
1726 fprintf (stderr
, " [all] OMP_MAX_ACTIVE_LEVELS = '%u'\n",
1727 all
->icvs
.max_active_levels_var
);
1728 if (dev
!= NULL
&& gomp_get_icv_flag (dev
->flags
,
1729 GOMP_ICV_MAX_ACTIVE_LEVELS
))
1730 fprintf (stderr
, " [device] OMP_MAX_ACTIVE_LEVELS = '%u'\n",
1731 dev
->icvs
.max_active_levels_var
);
1732 print_device_specific_icvs (GOMP_ICV_MAX_ACTIVE_LEVELS
);
1735 fprintf (stderr
, " [host] OMP_NUM_TEAMS = '%d'\n",
1736 none
->icvs
.nteams_var
);
1737 if (all
!= NULL
&& gomp_get_icv_flag (all
->flags
, GOMP_ICV_NTEAMS
))
1738 fprintf (stderr
, " [all] OMP_NUM_TEAMS = '%d'\n",
1739 all
->icvs
.nteams_var
);
1740 if (dev
!= NULL
&& gomp_get_icv_flag (dev
->flags
, GOMP_ICV_NTEAMS
))
1741 fprintf (stderr
, " [device] OMP_NUM_TEAMS = '%d'\n",
1742 dev
->icvs
.nteams_var
);
1743 print_device_specific_icvs (GOMP_ICV_NTEAMS
);
1745 fprintf (stderr
, " [host] OMP_TEAMS_THREAD_LIMIT = '%u'\n",
1746 none
->icvs
.teams_thread_limit_var
);
1747 if (all
!= NULL
&& gomp_get_icv_flag (all
->flags
,
1748 GOMP_ICV_TEAMS_THREAD_LIMIT
))
1749 fprintf (stderr
, " [all] OMP_TEAMS_THREAD_LIMIT = '%u'\n",
1750 all
->icvs
.teams_thread_limit_var
);
1751 if (dev
!= NULL
&& gomp_get_icv_flag (dev
->flags
,
1752 GOMP_ICV_TEAMS_THREAD_LIMIT
))
1753 fprintf (stderr
, " [device] OMP_TEAMS_THREAD_LIMIT = '%u'\n",
1754 dev
->icvs
.teams_thread_limit_var
);
1755 print_device_specific_icvs (GOMP_ICV_TEAMS_THREAD_LIMIT
);
1757 fprintf (stderr
, " [all] OMP_CANCELLATION = '%s'\n",
1758 gomp_cancel_var
? "TRUE" : "FALSE");
1760 fprintf (stderr
, " [all] OMP_DEFAULT_DEVICE = '%d'\n",
1761 none
->icvs
.default_device_var
);
1763 fprintf (stderr
, " [all] OMP_MAX_TASK_PRIORITY = '%d'\n",
1764 gomp_max_task_priority_var
);
1765 fprintf (stderr
, " [all] OMP_DISPLAY_AFFINITY = '%s'\n",
1766 gomp_display_affinity_var
? "TRUE" : "FALSE");
1767 fprintf (stderr
, " [host] OMP_AFFINITY_FORMAT = '%s'\n",
1768 gomp_affinity_format_var
);
1769 fprintf (stderr
, " [host] OMP_ALLOCATOR = '");
1770 switch (gomp_def_allocator
)
1772 #define C(v) case v: fputs (#v, stderr); break;
1773 C (omp_default_mem_alloc
)
1774 C (omp_large_cap_mem_alloc
)
1775 C (omp_const_mem_alloc
)
1776 C (omp_high_bw_mem_alloc
)
1777 C (omp_low_lat_mem_alloc
)
1778 C (omp_cgroup_mem_alloc
)
1779 C (omp_pteam_mem_alloc
)
1780 C (omp_thread_mem_alloc
)
1784 fputs ("'\n", stderr
);
1786 fputs (" [all] OMP_TARGET_OFFLOAD = '", stderr
);
1787 switch (gomp_target_offload_var
)
1789 case GOMP_TARGET_OFFLOAD_DEFAULT
:
1790 fputs ("DEFAULT", stderr
);
1792 case GOMP_TARGET_OFFLOAD_MANDATORY
:
1793 fputs ("MANDATORY", stderr
);
1795 case GOMP_TARGET_OFFLOAD_DISABLED
:
1796 fputs ("DISABLED", stderr
);
1799 fputs ("'\n", stderr
);
1803 fputs (" [host] GOMP_CPU_AFFINITY = ''\n", stderr
);
1804 fprintf (stderr
, " [host] GOMP_STACKSIZE = '%lu'\n", stacksize
);
1805 #ifdef HAVE_INTTYPES_H
1806 fprintf (stderr
, " [host] GOMP_SPINCOUNT = '%"PRIu64
"'\n",
1807 (uint64_t) gomp_spin_count_var
);
1809 fprintf (stderr
, " [host] GOMP_SPINCOUNT = '%lu'\n",
1810 (unsigned long) gomp_spin_count_var
);
1814 fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr
);
1816 ialias (omp_display_env
)
1819 handle_omp_display_env (void)
1822 bool display
= false;
1823 bool verbose
= false;
1825 env
= getenv ("OMP_DISPLAY_ENV");
1829 while (isspace ((unsigned char) *env
))
1831 if (strncasecmp (env
, "true", 4) == 0)
1836 else if (strncasecmp (env
, "false", 5) == 0)
1841 else if (strncasecmp (env
, "verbose", 7) == 0)
1849 while (isspace ((unsigned char) *env
))
1852 gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
1855 ialias_call (omp_display_env
) (verbose
);
1858 /* Helper function for initialize_env. Extracts the device number from
1859 an environment variable name. ENV is the complete environment variable.
1860 DEV_NUM_PTR points to the start of the device number in the environment
1861 variable string. DEV_NUM_LEN is the returned length of the device num
1865 get_device_num (char *env
, char *dev_num_ptr
, int *dev_num
, int *dev_num_len
)
1868 unsigned long val
= strtoul (dev_num_ptr
, &end
, 10);
1871 || (dev_num_ptr
[0] == '0' && end
!= dev_num_ptr
+ 1)
1872 || (dev_num_ptr
[0] < '0' || dev_num_ptr
[0] > '9'))
1874 gomp_error ("Invalid device number in %s", env
);
1878 *dev_num_len
= end
- dev_num_ptr
;
1883 get_icv_member_addr (struct gomp_initial_icvs
*icvs
, int icv_code
,
1886 if (icv_code
== 0 || icv_addr
== NULL
)
1889 icv_addr
[0] = icv_addr
[1] = icv_addr
[2] = NULL
;
1893 case GOMP_ICV_NTEAMS
:
1894 icv_addr
[0] = &icvs
->nteams_var
;
1895 /* icv_addr[1] = (void *) false; */
1897 case GOMP_ICV_DYNAMIC
:
1898 icv_addr
[0] = &(*icvs
).dyn_var
;
1900 case GOMP_ICV_TEAMS_THREAD_LIMIT
:
1901 icv_addr
[0] = &icvs
->teams_thread_limit_var
;
1902 /* icv_addr[1] = (void *) false; */
1904 case GOMP_ICV_SCHEDULE
:
1905 icv_addr
[0] = &icvs
->run_sched_var
;
1906 icv_addr
[1] = &icvs
->run_sched_chunk_size
;
1908 case GOMP_ICV_THREAD_LIMIT
:
1909 icv_addr
[0] = &icvs
->thread_limit_var
;
1910 /* icv_addr[1] = (void *) false; */
1911 icv_addr
[2] = (void *) UINT_MAX
;
1913 case GOMP_ICV_NTHREADS
:
1914 icv_addr
[0] = &icvs
->nthreads_var
;
1915 icv_addr
[1] = &icvs
->nthreads_var_list
;
1916 icv_addr
[2] = &icvs
->nthreads_var_list_len
;
1918 case GOMP_ICV_MAX_ACTIVE_LEVELS
:
1919 icv_addr
[0] = &icvs
->max_active_levels_var
;
1920 icv_addr
[1] = (void *) true;
1921 icv_addr
[2] = (void *) gomp_supported_active_levels
;
1924 icv_addr
[0] = &icvs
->bind_var
;
1925 icv_addr
[1] = &icvs
->bind_var_list
;
1926 icv_addr
[2] = &icvs
->bind_var_list_len
;
1928 case GOMP_ICV_WAIT_POLICY
:
1929 icv_addr
[0] = &icvs
->wait_policy
;
1931 case GOMP_ICV_STACKSIZE
:
1932 icv_addr
[0] = &icvs
->stacksize
;
1934 case GOMP_ICV_CANCELLATION
:
1935 icv_addr
[0] = &gomp_cancel_var
;
1937 case GOMP_ICV_DISPLAY_AFFINITY
:
1938 icv_addr
[0] = &gomp_display_affinity_var
;
1940 case GOMP_ICV_TARGET_OFFLOAD
:
1941 icv_addr
[0] = &gomp_target_offload_var
;
1943 case GOMP_ICV_MAX_TASK_PRIORITY
:
1944 icv_addr
[0] = &gomp_max_task_priority_var
;
1946 case GOMP_ICV_ALLOCATOR
:
1947 icv_addr
[0] = &gomp_def_allocator
;
1949 case GOMP_ICV_DEFAULT_DEVICE
:
1950 icv_addr
[0] = &icvs
->default_device_var
;
1951 icv_addr
[1] = (void *) true;
1956 struct gomp_icv_list
*
1957 gomp_get_initial_icv_item (int dev_num
)
1959 struct gomp_icv_list
*l
= gomp_initial_icv_list
;
1960 while (l
!= NULL
&& l
->device_num
!= dev_num
)
1967 initialize_icvs (struct gomp_initial_icvs
*icvs
)
1969 icvs
->nthreads_var_list
= NULL
;
1970 icvs
->bind_var_list
= NULL
;
1971 icvs
->nthreads_var
= gomp_default_icv_values
.nthreads_var
;
1972 icvs
->nthreads_var_list_len
= 0;
1973 icvs
->bind_var_list_len
= 0;
1974 icvs
->stacksize
= 0;
1975 icvs
->thread_limit_var
= gomp_default_icv_values
.thread_limit_var
;
1976 icvs
->run_sched_var
= gomp_default_icv_values
.run_sched_var
;
1977 icvs
->run_sched_chunk_size
= gomp_default_icv_values
.run_sched_chunk_size
;
1978 icvs
->default_device_var
= gomp_default_icv_values
.default_device_var
;
1979 icvs
->dyn_var
= gomp_default_icv_values
.dyn_var
;
1980 icvs
->max_active_levels_var
= gomp_default_icv_values
.max_active_levels_var
;
1981 icvs
->bind_var
= gomp_default_icv_values
.bind_var
;
1982 icvs
->nteams_var
= gomp_default_icv_values
.nteams_var
;
1983 icvs
->teams_thread_limit_var
= gomp_default_icv_values
.teams_thread_limit_var
;
1984 icvs
->wait_policy
= 0;
1987 /* Helper function for initialize_env to add a device specific ICV value
1988 to gomp_initial_icv_list. */
1991 add_initial_icv_to_list (int dev_num
, int icv_code
, void *icv_addr
[3])
1993 struct gomp_icv_list
*last
= NULL
, *l
= gomp_initial_icv_list
;
1994 while (l
!= NULL
&& l
->device_num
!= dev_num
)
2002 l
= ((struct gomp_icv_list
*)
2003 gomp_malloc_cleared (sizeof (struct gomp_icv_list
)));
2004 l
->device_num
= dev_num
;
2005 initialize_icvs (&l
->icvs
);
2008 l
->next
= gomp_initial_icv_list
;
2009 gomp_initial_icv_list
= l
;
2015 gomp_initial_icv_list
= l
;
2021 get_icv_member_addr (&l
->icvs
, icv_code
, icv_addr
);
2026 /* Return true if STR string starts with PREFIX. */
2029 startswith (const char *str
, const char *prefix
)
2031 return strncmp (str
, prefix
, strlen (prefix
)) == 0;
2034 static void __attribute__((constructor
))
2035 initialize_env (void)
2038 int omp_var
, dev_num
= 0, dev_num_len
= 0, i
;
2039 bool ignore
= false;
2042 uint32_t *flag_var_addr
= NULL
;
2044 struct gomp_icv_list
*all
, *none
;
2046 /* Do a compile time check that mkomp_h.pl did good job. */
2047 omp_check_defines ();
2049 #ifndef HAVE_SYNC_BUILTINS
2050 gomp_mutex_init (&gomp_managed_threads_lock
);
2052 gomp_init_num_threads ();
2053 gomp_available_cpus
= gomp_global_icv
.nthreads_var
;
2055 /* Initial values for host environment variables should always exist even if
2056 there is no explicitly set host environment variable. Moreover, they are
2057 set to the initial global values. */
2058 add_initial_icv_to_list (GOMP_DEVICE_NUM_FOR_NO_SUFFIX
, 0, NULL
);
2059 none
= gomp_get_initial_icv_item (GOMP_DEVICE_NUM_FOR_NO_SUFFIX
);
2060 initialize_icvs (&none
->icvs
);
2062 for (env
= environ
; *env
!= 0; env
++)
2064 if (!startswith (*env
, "OMP_"))
2067 /* Name of the environment variable without suffix "OMP_". */
2068 char *name
= *env
+ sizeof ("OMP_") - 1;
2069 for (omp_var
= 0; omp_var
< OMP_VAR_CNT
; omp_var
++)
2071 if (startswith (name
, envvars
[omp_var
].name
))
2073 pos
= envvars
[omp_var
].name_len
;
2074 if (name
[pos
] == '=')
2078 = add_initial_icv_to_list (GOMP_DEVICE_NUM_FOR_NO_SUFFIX
,
2079 envvars
[omp_var
].flag_vars
[0],
2082 else if (startswith (&name
[pos
], "_DEV=")
2083 && envvars
[omp_var
].flag
& GOMP_ENV_SUFFIX_DEV
)
2087 = add_initial_icv_to_list (GOMP_DEVICE_NUM_FOR_DEV
,
2088 envvars
[omp_var
].flag_vars
[0],
2091 else if (startswith (&name
[pos
], "_ALL=")
2092 && envvars
[omp_var
].flag
& GOMP_ENV_SUFFIX_ALL
)
2096 = add_initial_icv_to_list (GOMP_DEVICE_NUM_FOR_ALL
,
2097 envvars
[omp_var
].flag_vars
[0],
2100 else if (startswith (&name
[pos
], "_DEV_")
2101 && envvars
[omp_var
].flag
& GOMP_ENV_SUFFIX_DEV_X
)
2104 if (!get_device_num (*env
, &name
[pos
], &dev_num
,
2108 pos
+= dev_num_len
+ 1;
2110 = add_initial_icv_to_list (dev_num
,
2111 envvars
[omp_var
].flag_vars
[0],
2116 gomp_error ("Invalid environment variable in %s", *env
);
2119 env_val
= &name
[pos
];
2121 if (envvars
[omp_var
].parse_func (*env
, env_val
, params
))
2123 for (i
= 0; i
< 3; ++i
)
2124 if (envvars
[omp_var
].flag_vars
[i
])
2125 gomp_set_icv_flag (flag_var_addr
,
2126 envvars
[omp_var
].flag_vars
[i
]);
2136 all
= gomp_get_initial_icv_item (GOMP_DEVICE_NUM_FOR_ALL
);
2137 for (omp_var
= 0; omp_var
< OMP_HOST_VAR_CNT
; omp_var
++)
2140 && gomp_get_icv_flag (none
->flags
, host_envvars
[omp_var
].flag_var
))
2141 get_icv_member_addr (&none
->icvs
,
2142 host_envvars
[omp_var
].flag_var
, params
);
2143 else if (all
!= NULL
2144 && gomp_get_icv_flag (all
->flags
,
2145 host_envvars
[omp_var
].flag_var
))
2146 get_icv_member_addr (&all
->icvs
, host_envvars
[omp_var
].flag_var
,
2151 switch (host_envvars
[omp_var
].type_code
)
2154 for (i
= 0; i
< 3; ++i
)
2155 if (host_envvars
[omp_var
].dest
[i
] != NULL
&& params
[i
] != NULL
)
2156 *(int *) (host_envvars
[omp_var
].dest
[i
]) = *(int *) params
[i
];
2159 for (i
= 0; i
< 3; ++i
)
2160 if (host_envvars
[omp_var
].dest
[i
] != NULL
&& params
[i
] != NULL
)
2161 *(bool *) (host_envvars
[omp_var
].dest
[i
]) = *(bool *) params
[i
];
2164 for (i
= 0; i
< 3; ++i
)
2165 if (host_envvars
[omp_var
].dest
[i
] != NULL
&& params
[i
] != NULL
)
2166 *(unsigned int *) (host_envvars
[omp_var
].dest
[i
])
2167 = *(unsigned int *) params
[i
];
2170 for (i
= 0; i
< 3; ++i
)
2171 if (host_envvars
[omp_var
].dest
[i
] != NULL
&& params
[i
] != NULL
)
2172 *(unsigned long *) (host_envvars
[omp_var
].dest
[i
])
2173 = *(unsigned long *) params
[i
];
2176 for (i
= 0; i
< 3; ++i
)
2177 if (host_envvars
[omp_var
].dest
[i
] != NULL
&& params
[i
] != NULL
)
2178 *(unsigned char *) (host_envvars
[omp_var
].dest
[i
])
2179 = *(unsigned char *) params
[i
];
2181 case PARSE_SCHEDULE
:
2182 *(enum gomp_schedule_type
*) (host_envvars
[omp_var
].dest
[0])
2183 = *(enum gomp_schedule_type
*) params
[0];
2184 *(int *) (host_envvars
[omp_var
].dest
[1]) = *(int *) params
[1];
2187 *(char *) (host_envvars
[omp_var
].dest
[0]) = *(char *) params
[0];
2188 *(char **) (host_envvars
[omp_var
].dest
[1]) = *(char **) params
[1];
2189 *(unsigned long *) (host_envvars
[omp_var
].dest
[2])
2190 = *(unsigned long *) params
[2];
2195 if (((none
!= NULL
&& gomp_get_icv_flag (none
->flags
, GOMP_ICV_BIND
))
2196 || (all
!= NULL
&& gomp_get_icv_flag (all
->flags
, GOMP_ICV_BIND
)))
2197 && gomp_global_icv
.bind_var
== omp_proc_bind_false
)
2201 && gomp_get_icv_flag (none
->flags
, GOMP_ICV_MAX_ACTIVE_LEVELS
))
2203 && gomp_get_icv_flag (all
->flags
, GOMP_ICV_MAX_ACTIVE_LEVELS
))))
2206 const char *env
= getenv ("OMP_NESTED");
2208 /* OMP_NESTED is deprecated in OpenMP 5.0. */
2209 if (parse_boolean ("OMP_NESTED", env
, (void *[]) {&nested
}))
2210 gomp_global_icv
.max_active_levels_var
2211 = nested
? gomp_supported_active_levels
: 1;
2212 else if (gomp_nthreads_var_list_len
> 1 || gomp_bind_var_list_len
> 1)
2213 gomp_global_icv
.max_active_levels_var
= gomp_supported_active_levels
;
2216 /* Process GOMP_* variables and dependencies between parsed ICVs. */
2217 parse_int_secure ("GOMP_DEBUG", &gomp_debug_var
, true);
2219 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
2220 parsed if present in the environment. If OMP_PROC_BIND was set
2221 explicitly to false, don't populate places list though. If places
2222 list was successfully set from OMP_PLACES, only parse but don't process
2223 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
2224 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
2225 was successfully parsed into a places list, otherwise to
2226 OMP_PROC_BIND=false. */
2227 if (parse_places_var ("OMP_PLACES", ignore
))
2229 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
2230 gomp_global_icv
.bind_var
= true;
2233 if (parse_affinity (ignore
))
2235 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
2236 gomp_global_icv
.bind_var
= true;
2239 if (gomp_global_icv
.bind_var
!= omp_proc_bind_false
)
2240 gomp_init_affinity ();
2243 const char *env
= getenv ("OMP_AFFINITY_FORMAT");
2245 gomp_set_affinity_format (env
, strlen (env
));
2248 if (none
!= NULL
&& gomp_get_icv_flag (none
->flags
, GOMP_ICV_WAIT_POLICY
))
2249 wait_policy
= none
->icvs
.wait_policy
;
2250 else if (all
!= NULL
&& gomp_get_icv_flag (all
->flags
, GOMP_ICV_WAIT_POLICY
))
2251 wait_policy
= all
->icvs
.wait_policy
;
2253 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var
))
2255 /* Using a rough estimation of 100000 spins per msec,
2256 use 5 min blocking for OMP_WAIT_POLICY=active,
2257 3 msec blocking when OMP_WAIT_POLICY is not specificed
2258 and 0 when OMP_WAIT_POLICY=passive.
2259 Depending on the CPU speed, this can be e.g. 5 times longer
2260 or 5 times shorter. */
2261 if (wait_policy
> 0)
2262 gomp_spin_count_var
= 30000000000LL;
2263 else if (wait_policy
< 0)
2264 gomp_spin_count_var
= 300000LL;
2266 /* gomp_throttled_spin_count_var is used when there are more libgomp
2267 managed threads than available CPUs. Use very short spinning. */
2268 if (wait_policy
> 0)
2269 gomp_throttled_spin_count_var
= 1000LL;
2270 else if (wait_policy
< 0)
2271 gomp_throttled_spin_count_var
= 100LL;
2272 if (gomp_throttled_spin_count_var
> gomp_spin_count_var
)
2273 gomp_throttled_spin_count_var
= gomp_spin_count_var
;
2275 /* Not strictly environment related, but ordering constructors is tricky. */
2276 pthread_attr_init (&gomp_thread_attr
);
2278 if (!(none
!= NULL
&& gomp_get_icv_flag (none
->flags
, GOMP_ICV_STACKSIZE
)))
2280 const char *env
= getenv ("GOMP_STACKSIZE");
2282 && parse_stacksize ("GOMP_STACKSIZE", env
,
2283 (void *[3]) {&none
->icvs
.stacksize
}))
2284 gomp_set_icv_flag (&none
->flags
, GOMP_ICV_STACKSIZE
);
2286 if (none
!= NULL
&& gomp_get_icv_flag (none
->flags
, GOMP_ICV_STACKSIZE
))
2287 stacksize
= none
->icvs
.stacksize
;
2288 else if (all
!= NULL
&& gomp_get_icv_flag (all
->flags
, GOMP_ICV_STACKSIZE
))
2289 stacksize
= all
->icvs
.stacksize
;
2291 if ((none
!= NULL
&& gomp_get_icv_flag (none
->flags
, GOMP_ICV_STACKSIZE
))
2292 || (all
!= NULL
&& gomp_get_icv_flag (all
->flags
, GOMP_ICV_STACKSIZE
))
2293 || GOMP_DEFAULT_STACKSIZE
)
2297 err
= pthread_attr_setstacksize (&gomp_thread_attr
, stacksize
);
2299 #ifdef PTHREAD_STACK_MIN
2302 if (stacksize
< PTHREAD_STACK_MIN
)
2303 gomp_error ("Stack size less than minimum of %luk",
2304 PTHREAD_STACK_MIN
/ 1024ul
2305 + (PTHREAD_STACK_MIN
% 1024 != 0));
2307 gomp_error ("Stack size larger than system limit");
2312 gomp_error ("Stack size change failed: %s", strerror (err
));
2315 handle_omp_display_env ();
2319 if (!parse_int ("ACC_DEVICE_NUM", getenv ("ACC_DEVICE_NUM"),
2320 (void *[]) {&goacc_device_num
, (void *) true}))
2321 goacc_device_num
= 0;
2323 parse_acc_device_type ();
2324 parse_gomp_openacc_dim ();
2326 goacc_runtime_initialize ();
2328 goacc_profiling_initialize ();
2330 #endif /* LIBGOMP_OFFLOADED_ONLY */