NAME
OpenMP::Environment::Validation - portable OpenMP 5.2 and GNU libgomp environment validation
SYNOPSIS
use OpenMP::Environment::Validation qw/
validate_value assert_environment analyze_environment
/;
my $schedule = validate_value(
q{OMP_SCHEDULE},
q{nonmonotonic:dynamic,4},
);
assert_environment(\%ENV); # dies on malformed or conflicting settings
my $report = analyze_environment(\%ENV);
print $report->{valid} ? "valid\n" : "needs attention\n";
PURPOSE
OpenMP::Environment::Validation contains the validation policy used by OpenMP::Environment. It is intentionally separate from the public accessor/DSL module so the policy can be read, tested, and reused on its own.
The validation reference point is OpenMP 5.2 together with GNU libgomp as shipped/documented with GCC 16.2.0. The module distinguishes between:
INVALID
A value does not satisfy this module's selected validation profile: the OpenMP 5.2 grammar, plus an explicitly documented GCC/libgomp restriction when GNU's documented grammar is narrower. Such GNU-profile restrictions are called out individually rather than being presented as portable OpenMP requirements.
CONFLICT / IMPLEMENTATION-DEFINED COMBINATION
Each individual value is syntactically valid, but OpenMP explicitly says the combination is implementation-defined. The principal 5.2 case handled here is
OMP_NESTED=FALSEtogether withOMP_MAX_ACTIVE_LEVELSgreater than one.VALID BUT RUNTIME-DEPENDENT
The syntax is valid but whether the request can be honored depends on runtime resources, topology, target devices, allocators, or implementation limits. These values pass validation and are reported by
analyze_environment.
PORTABILITY SCOPE AND NON-GOALS
This module is deliberately not system-aware. It does not inspect CPU counts, CPU identifiers, NUMA topology, hwloc, GPUs, target devices, available allocators, /proc, compiler executables, runtime state, or operating-system resources. Such checks can be useful, but they introduce portability and load-time concerns that belong in a future, explicitly system-aware layer.
Consequently, values such as these are syntactically valid here even though a particular runtime may be unable to honor them:
OMP_DEFAULT_DEVICE=7
OMP_PLACES={0,1,2,3}
OMP_STACKSIZE=64G
OMP_THREAD_LIMIT=100000
OPENMP VALUE SYNTAX AND NORMALIZATION
OpenMP 5.2 Chapter 21 states that OpenMP environment-variable values are generally case-insensitive and may contain leading and trailing whitespace. Strict validation therefore ignores surrounding whitespace for supported OMP_* variables before validating them. The established upper-case normalization used by OpenMP::Environment is retained for its historical boolean/token fields.
OMP_AFFINITY_FORMAT is the important exception. Section 21.2.5 explicitly states that its value is case-sensitive and that leading and trailing whitespace is significant. This module therefore preserves that string exactly.
The GOMP_* variables are GNU extensions rather than OpenMP Chapter 21 variables; their syntax follows the libgomp documentation rather than assuming that every general OpenMP lexical rule applies to them.
API
validate_value NAME, VALUE
Validates one supported OMP_* or GOMP_* value and returns the value after normalization. For OMP_* values, surrounding whitespace is ignored except for OMP_AFFINITY_FORMAT, where it is significant. The same six variables upper-cased by older OpenMP::Environment releases continue to be upper-cased. Dies on invalid input.
validate_assignment NAME, VALUE
Applies the validation policy used by ordinary/lvalue assignment in OpenMP::Environment. To preserve pre-1.5.0 compatibility, variables that were historically pass-through remain pass-through here. Use validate_value or assert for strict grammar validation of all supported variables.
assert_variable ENV, NAME
Validates one value from a hash reference and checks cross-variable conflicts that involve that variable. An unset variable is valid.
assert_environment ENV
Validates every supported variable present in the supplied hash and then checks portable cross-variable conflicts. As with historical assert_omp_environment, normalized values are written back to the hash.
analyze_environment ENV
Returns a machine-readable hash reference with these keys:
valid
errors
conflicts
runtime_dependent
notes
It never performs host/resource discovery.
validation_rules
Returns introspection metadata describing the supported fields, historical upper-case normalization, variables validated on ordinary assignment, fields whose whitespace is significant, validator routines, and the validation profile. This is intended to make the policy useful to machine consumers as well as to human readers of this POD.
PER-VARIABLE REFERENCE
OMP_NUM_THREADS
OpenMP 5.2 Section 21.1.2 permits one positive integer or a comma-separated list for nested parallel levels. GCC/libgomp implements that syntax. Values larger than runtime capability are implementation-dependent, so this module checks only the positive-integer grammar.
Valid: OMP_NUM_THREADS=8
Valid: OMP_NUM_THREADS=8,4,2
Invalid: OMP_NUM_THREADS=8,0,2
GCC/libgomp: https://gcc.gnu.org/onlinedocs/gcc-16.2.0/libgomp/OMP_005fNUM_005fTHREADS.html
OpenMP 5.2: https://www.openmp.org/spec-html/5.2/openmp.html, Section 21.1.2.
OMP_MAX_ACTIVE_LEVELS
OpenMP 5.2 Section 21.1.4 permits a non-negative integer, so zero is valid according to the OpenMP grammar. GCC/libgomp documents this environment variable more narrowly as a positive integer. Earlier OpenMP::Environment releases also rejected zero. Because this distribution is explicitly profiled against GCC 16.2/libgomp, strict validation retains the GNU/legacy positive-integer rule.
Valid in this GCC/libgomp profile: OMP_MAX_ACTIVE_LEVELS=1
OpenMP-valid but rejected here: OMP_MAX_ACTIVE_LEVELS=0
Invalid: OMP_MAX_ACTIVE_LEVELS=-1
Values above the maximum nesting level supported by a particular runtime are implementation-defined and are not system-probed here.
GCC/libgomp: https://gcc.gnu.org/onlinedocs/gcc-16.2.0/libgomp/OMP_005fMAX_005fACTIVE_005fLEVELS.html
OpenMP 5.2: Section 21.1.4 and Appendix A.
OMP_PROC_BIND
OpenMP 5.2 Section 21.1.7 specifies TRUE, FALSE, or a list of PRIMARY, CLOSE, and SPREAD. OpenMP deprecates the older MASTER spelling; GNU libgomp deliberately retains it, so this module accepts it. Binding to actual places and the policy chosen for TRUE remain implementation-dependent.
Valid: OMP_PROC_BIND=close
Valid: OMP_PROC_BIND=spread,close,primary
GNU: OMP_PROC_BIND=master,close,spread
Invalid: OMP_PROC_BIND=near
GCC/libgomp: https://gcc.gnu.org/onlinedocs/gcc-16.2.0/libgomp/OMP_005fPROC_005fBIND.html
OpenMP 5.2: Section 21.1.7 and Appendix A.
OMP_PLACES
OpenMP 5.2 Section 21.1.6 defines abstract names, explicit place/resource lists, intervals, strides, and exclusions. It intentionally leaves resource numbering, exact abstract-name meaning, and additional abstract names to the implementation. GNU libgomp documents threads, cores, sockets, ll_caches, and numa_domains plus explicit list syntax.
Valid: OMP_PLACES=cores
Valid: OMP_PLACES=cores(4)
Valid: OMP_PLACES={0,1,2},{3,4,5}
Valid: OMP_PLACES={0:4},{4:4}
Valid: OMP_PLACES=!{0},1:3
Invalid: OMP_PLACES={0,,2}
This module checks grammar but does not decide whether processor 4 exists or what cores means on the current machine.
GCC/libgomp: https://gcc.gnu.org/onlinedocs/gcc-16.2.0/libgomp/OMP_005fPLACES.html
OpenMP 5.2: Section 21.1.6 and Appendix A.
OMP_SCHEDULE
OpenMP 5.2 Section 21.2.1 defines:
[modifier:]kind[,chunk]
where modifier is MONOTONIC or NONMONOTONIC, kind is STATIC, DYNAMIC, GUIDED, or AUTO, and chunk is a positive integer. GNU libgomp documentation emphasizes the simpler type[,chunk] spelling; the full OpenMP 5.2 grammar is accepted here because it includes all GNU-documented forms.
Valid: OMP_SCHEDULE=dynamic,4
Valid: OMP_SCHEDULE=monotonic:guided,8
Invalid: OMP_SCHEDULE=banana
Invalid: OMP_SCHEDULE=dynamic,0
OpenMP specifies implementation-defined behavior for malformed values; this module instead rejects malformed values early.
OMP_STACKSIZE and GOMP_STACKSIZE
OpenMP 5.2 Section 21.2.2 specifies a positive size with optional B, K, M, or G unit for OMP_STACKSIZE; libgomp uses kilobytes when the unit is omitted. Whether the requested stack can actually be provided is implementation-dependent and is not checked.
GNU GOMP_STACKSIZE is an extension documented as a positive numeric value in kilobytes, with no unit suffix. Older OpenMP::Environment releases did not validate this variable, and the unchanged regression suite includes and asserts a unit-suffixed value. Version 1.5.0 therefore accepts B, K, M, and G suffixes as an explicit OpenMP::Environment compatibility extension in both assignment and assertion. This POD does not claim those suffixes are valid libgomp GOMP_STACKSIZE syntax; the GNU-native spelling is an unsuffixed positive integer interpreted as kilobytes.
OMP_ALLOCATOR
OpenMP 5.2 Section 21.5.1 and Sections 6.1-6.2 define predefined allocators, predefined memory spaces, and allocator traits. This module checks the trait vocabulary and intrinsic constraints including positive power-of-two alignment, positive pool_size, booleans, fallback values, and predefined allocator traits. OpenMP permits fb_data for allocator_fb. GNU libgomp still lists allocator_fb as an allowed fallback token, but explicitly marks fb_data unsupported in the OMP_ALLOCATOR environment string because it requires an allocator handle. Strict validation therefore accepts the documented fallback=allocator_fb token, rejects an explicit fb_data trait, and deliberately does not infer whether a useful allocator fallback can be constructed without fb_data. Ordinary assignment remains pass-through for compatibility.
Valid: OMP_ALLOCATOR=omp_high_bw_mem_alloc
Valid: OMP_ALLOCATOR=omp_large_cap_mem_space:alignment=16,pinned=true
Valid: OMP_ALLOCATOR=omp_low_lat_mem_space:fallback=allocator_fb
GNU: OMP_ALLOCATOR=ompx_gnu_pinned_mem_alloc
Invalid: OMP_ALLOCATOR=omp_low_lat_mem_space:alignment=3
libgomp-invalid: OMP_ALLOCATOR=omp_default_mem_space:fb_data=omp_default_mem_alloc
OpenMP explicitly leaves actual storage-resource mappings, some predefined allocator memory-space associations, partition minimums, and the default pool size implementation-defined. GNU libgomp maps the cgroup/pteam/thread allocators to omp_low_lat_mem_space as an implementation choice and also provides ompx_gnu_pinned_mem_alloc, ompx_gnu_managed_mem_alloc, and ompx_gnu_managed_mem_space as GNU extensions. Availability is not probed.
Memory allocator trait definitions: https://www.openmp.org/spec-html/5.2/openmpse35.html
OMP_AFFINITY_FORMAT
OpenMP 5.2 Section 21.2.5 specifies a percent-field format and permits implementation-defined additional field types. A field width is a positive decimal integer and can be written as a bare minimum width (%4L), as a right-justified width (%.4L), or with zero padding for numeric fields (%0.4L). GNU libgomp documents the same width forms and the standard short and long field names. Syntactically valid unknown alphabetic field names are accepted as possible implementation extensions.
The value is case-sensitive and leading/trailing whitespace is significant; strict validation preserves it rather than applying the general OpenMP whitespace normalization. OpenMP says the result is unspecified when the zero-padding modifier is used for a nonnumeric field; that is not a syntax error, so this validator does not reject it.
Valid: OMP_AFFINITY_FORMAT=thread %n affinity %A
Valid: OMP_AFFINITY_FORMAT=level %4L thread %0.2n
Valid: OMP_AFFINITY_FORMAT=host %.12{host}
Valid: OMP_AFFINITY_FORMAT=%% %n
Invalid: OMP_AFFINITY_FORMAT=thread %
Invalid: OMP_AFFINITY_FORMAT=level %.0L
GOMP_CPU_AFFINITY
This is a GNU extension, not an OpenMP environment variable. libgomp accepts space/comma-separated CPU numbers, ranges M-N, and stride ranges M-N:S. OMP_PROC_BIND has precedence when both variables are set.
Valid: GOMP_CPU_AFFINITY=0 3 1-2 4-15:2
Invalid: GOMP_CPU_AFFINITY=cpu0
CPU existence is not checked.
GOMP_SPINCOUNT
This GNU extension accepts INFINITE, INFINITY, or a non-negative integer optionally suffixed by k, M, G, or T. Effective busy-wait behavior can depend on OMP_WAIT_POLICY and available CPUs; only syntax is checked.
Valid: GOMP_SPINCOUNT=300000
Valid: GOMP_SPINCOUNT=30G
Valid: GOMP_SPINCOUNT=INFINITY
Invalid: GOMP_SPINCOUNT=forever
GOMP_RTEMS_THREAD_POOLS
This GNU/RTEMS-only variable uses colon-separated count[$priority]@scheduler configurations. The documented libgomp example 1@WRK0:3$4@WRK1 is valid. Scheduler existence and permissible RTEMS priority ranges are not queried.
Other scalar and token variables
The remaining standard variables use smaller grammars but still have implementation-defined edges worth distinguishing from syntax errors:
OMP_CANCELLATIONandOMP_DISPLAY_AFFINITYTRUEorFALSE. OpenMP makes other values implementation-defined forOMP_CANCELLATIONand makes the display action implementation-defined for otherOMP_DISPLAY_AFFINITYvalues.OMP_DISPLAY_ENVTRUE,FALSE, orVERBOSE. OpenMP says the displayed information is unspecified for other values.OMP_DEFAULT_DEVICEandOMP_MAX_TASK_PRIORITYNon-negative integers. Device existence and runtime priority capability are not probed.
OMP_DYNAMICand deprecatedOMP_NESTEDOpenMP defines boolean values.
OpenMP::Environmentadditionally retains its historical1/0compatibility.OMP_NESTEDalso participates in the cross-variable rule documented below.OMP_NUM_TEAMS,OMP_TEAMS_THREAD_LIMIT, andOMP_THREAD_LIMITPositive integers. OpenMP makes behavior implementation-defined when a value is invalid or exceeds an implementation limit; this module validates syntax but does not query those limits.
OMP_TARGET_OFFLOADMANDATORY,DISABLED, orDEFAULT. OpenMP 5.2 makes support ofDISABLEDimplementation-defined; GCC/libgomp explicitly implements all three values.OMP_WAIT_POLICYACTIVEorPASSIVE. The detailed waiting behavior is implementation- defined.GOMP_DEBUGGNU extension accepting
0or1.
CROSS-VARIABLE RULES
OMP_NESTED and OMP_MAX_ACTIVE_LEVELS
OpenMP 5.2 explicitly says behavior is implementation-defined when both are set, OMP_NESTED is false, and OMP_MAX_ACTIVE_LEVELS is greater than one. assert_environment treats this as a conflict:
OMP_NESTED=FALSE
OMP_MAX_ACTIVE_LEVELS=4
If both are set without that conflict, OpenMP says OMP_NESTED has no effect.
OMP_NUM_THREADS / OMP_PROC_BIND nesting lists
Multiple list elements can affect initialization of max-active-levels-var. OpenMP 5.2 Section 2.2 describes that ICV as depending on OMP_MAX_ACTIVE_LEVELS, OMP_NESTED, OMP_NUM_THREADS, and OMP_PROC_BIND. A list is not itself an error; analyze_environment records the relationship as a note.
OMP_PROC_BIND and GOMP_CPU_AFFINITY
GNU libgomp gives OMP_PROC_BIND precedence if both are set. This is a valid configuration, not a conflict; analyze_environment records the precedence.
IMPLEMENTATION-DEFINED VERSUS GNU CHOICES
OpenMP deliberately leaves several matters to implementations. Important examples include processor numbering and abstract OMP_PLACES meanings, actual affinity policy for OMP_PROC_BIND=TRUE, maximum supported thread and active-level counts, ability to provide a requested stack, memory-space mappings for several predefined allocators, allocator pool defaults, and the details of active/passive waiting.
GNU libgomp necessarily chooses concrete behavior in many of those areas and also provides GOMP_* extensions. This module validates GNU-documented syntax where it is portable to do so, but it does not turn a GNU runtime choice into a supposed cross-platform OpenMP guarantee.
The OpenMP implementation-defined behavior index is: https://www.openmp.org/spec-html/5.2/openmpap1.html.
The GCC/libgomp environment-variable index is: https://gcc.gnu.org/onlinedocs/gcc-16.2.0/libgomp/Environment-Variables.html.
COPYRIGHT AND LICENSE
Same as Perl.