NAME
OpenMP::Environment - manage OpenMP and GNU libgomp environment variables from Perl
SYNOPSIS
OpenMP::Environment is intended for two closely related jobs:
Preparing
%ENVbefore launching an external executable compiled with OpenMP.Managing the Perl-side OpenMP environment used with OpenMP::Simple and OpenMP-enabled C code loaded into a Perl process.
Launching an external OpenMP executable
An external executable reads its OpenMP environment when the process starts, which makes this the most direct use of OpenMP::Environment:
use strict;
use warnings;
use OpenMP::Environment;
my $env = OpenMP::Environment->new;
my $program = q{/path/to/my-openmp-program};
for my $threads ( 1, 2, 4, 8, 16 ) {
$env->omp_num_threads = $threads;
$env->omp_proc_bind = q{CLOSE};
$env->omp_places = q{cores};
# Optional guard before starting the child process.
$env->assert_omp_environment;
my $status = system { $program } $program, q{--input}, q{data.in};
die qq{$program failed: status=$status\n} if $status != 0;
}
Every system, exec, IPC, scheduler, or similar child-process launch inherits the current %ENV unless the caller deliberately replaces it. This makes the module useful for benchmark drivers, parameter sweeps, test harnesses, HPC launcher scripts, and production workflows around OpenMP executables.
Using OpenMP::Environment with OpenMP::Simple
OpenMP::Simple provides C macros that re-read selected values from %ENV and apply them through OpenMP runtime setter functions. This is useful because an OpenMP runtime linked into a shared library is normally initialized once, when that library is loaded into the Perl process.
use strict;
use warnings;
use OpenMP::Simple;
use OpenMP::Environment;
use Inline (
C => 'DATA',
with => qw/OpenMP::Simple/,
);
my $env = OpenMP::Environment->new;
for my $want_num_threads ( 1 .. 8 ) {
$env->omp_num_threads = $want_num_threads;
$env->assert_omp_environment;
my $got_num_threads = _check_num_threads();
printf "%d threads spawned; expected %d\n",
$got_num_threads, $want_num_threads;
}
__DATA__
__C__
int _check_num_threads() {
int ret = 0;
PerlOMP_UPDATE_WITH_ENV__NUM_THREADS
#pragma omp parallel
{
#pragma omp single
ret = omp_get_num_threads();
}
return ret;
}
The runtime-update macros in OpenMP::Simple only apply to OpenMP settings for which a corresponding runtime setter exists. Settings that are only read at OpenMP runtime initialization still need to be established before the OpenMP-enabled shared library is loaded.
OpenMP 5.x examples
OMP_NUM_THREADS may be a comma-separated list for nested parallel levels. Version 1.5.0 accepts this standard form in addition to the single integer form accepted by earlier releases:
$env->omp_num_threads = q{8,4,2};
GCC libgomp also supports affinity-display controls introduced in OpenMP 5.0:
$env->omp_display_affinity = q{true};
$env->omp_affinity_format = q{thread %n affinity %A};
And the OpenMP default allocator may be selected through OMP_ALLOCATOR:
$env->omp_allocator = q{omp_high_bw_mem_alloc};
Ordinary assignment to OMP_ALLOCATOR and OMP_AFFINITY_FORMAT remains pass-through for backward compatibility with releases that did not validate those grammars. The assert DSL, assert_omp_environment, and OpenMP::Environment::Validation provide strict portable/libgomp grammar validation when requested.
Assertion and unset DSL
Because %ENV is process-global, version 1.5.0 adds an opt-in functional DSL for operations that do not need object-local state:
use OpenMP::Environment qw/:dsl/;
my $env = OpenMP::Environment->new;
$env->omp_num_threads = 16;
$env->omp_schedule = q{dynamic,4};
assert omp_num_threads;
assert omp_schedule;
unset omp_schedule;
unset omp_num_threads;
The constants are imported only when requested. Existing callers that simply say use OpenMP::Environment; receive no new symbols.
:unset imports unset plus all environment constants, :assert imports assert plus the constants, and :dsl imports both functions plus the constants. Individual symbols can also be requested explicitly:
use OpenMP::Environment qw/unset omp_target_offload/;
unset omp_target_offload;
The constants live in OpenMP::Environment::Constants so lower-case names such as omp_num_threads do not collide with the accessor methods of the same name in this package.
DESCRIPTION
OpenMP::Environment provides lvalue-capable getter/setter methods and explicit unsetters for the OpenMP and GNU libgomp environment variables documented by GCC 16.2.0. The module changes %ENV; it does not implement OpenMP itself.
GCC 16.2.0 reports _OPENMP=202111, corresponding to OpenMP 5.2. The GCC/libgomp OpenMP Environment Variables chapter lists 25 OMP_* and GOMP_* variables, and this release exposes that complete 25-variable libgomp set while retaining the accessors and semantics from earlier OpenMP::Environment releases.
OpenMP 5.2 itself defines additional tool/debugging environment variables, including OMP_TOOL, OMP_TOOL_LIBRARIES, OMP_TOOL_VERBOSE_INIT, and OMP_DEBUG. They are not part of libgomp's 25-variable environment chapter and are outside the API scope of this release; the phrase "all 25" in this document always means the 25 variables listed by libgomp, not every environment variable appearing anywhere in OpenMP 5.2.
The current API supports:
OMP_ALLOCATOROMP_AFFINITY_FORMATOMP_DISPLAY_AFFINITYcomma-separated positive-integer lists for
OMP_NUM_THREADSlvalue assignment for all
omp_*andgomp_*accessors, routed through the same compatibility validation policy as traditional setters
The GNU libgomp manual for GCC 16.2.0 is the implementation reference for this module:
https://gcc.gnu.org/onlinedocs/gcc-16.2.0/libgomp/
GCC 16.2 AND DEVICE-SPECIFIC ENVIRONMENT FORMS
OpenMP 5.1 added device-specific forms for many environment variables that set internal control variables. GCC 16.2 libgomp recognizes applicable forms such as:
OMP_NUM_THREADS=8
OMP_NUM_THREADS_DEV=4
OMP_NUM_THREADS_DEV_0=2
OMP_NUM_THREADS_ALL=1
The named methods in this module deliberately continue to represent the canonical variable names, preserving the existing API. Device-specific forms can be placed directly in %ENV when needed. assert_omp_environment and the summary methods operate on the canonical variables exposed by vars.
This distinction is especially useful for external executable launchers: set the device-specific form directly in %ENV, use the normal accessors for the host/canonical values, then start the OpenMP executable.
VALIDATION
Version 1.5.0 moves validation policy into OpenMP::Environment::Validation. That module documents the OpenMP 5.2 rule, the GCC 16.2/libgomp interpretation or extension, valid and invalid examples, and the implementation-defined areas for each supported variable.
There are deliberately two validation modes so existing programs are not broken.
Assignment compatibility
Traditional setters and lvalue assignment retain every value and behavior accepted by the pre-1.5.0 validation contract. Variables that were already validated continue to be validated and normalized. Version 1.5.0 additionally recognizes the OpenMP rule that surrounding whitespace is permitted for OpenMP environment values (except OMP_AFFINITY_FORMAT, where whitespace is significant). Variables that historically accepted arbitrary strings continue to accept them on assignment:
$env->gomp_spincount = q{legacy application value};
This preserves existing code and is especially important because earlier releases explicitly documented several complex grammars as pass-through.
Strict assertion
The new assert DSL and the existing assert_omp_environment method use the strict validation engine for all 25 variables listed in GCC/libgomp's OpenMP environment-variable chapter:
use OpenMP::Environment qw/:assert/;
$ENV{OMP_SCHEDULE} = q{nonmonotonic:dynamic,4};
assert omp_schedule;
$env->assert_omp_environment;
Strict validation covers complex grammars including OMP_PROC_BIND, OMP_PLACES, OMP_SCHEDULE, OMP_STACKSIZE, OMP_ALLOCATOR, OMP_AFFINITY_FORMAT, and the GNU GOMP_* extensions.
It also detects portable cross-variable conditions that OpenMP explicitly classifies as implementation-defined. In particular:
OMP_NESTED=FALSE
OMP_MAX_ACTIVE_LEVELS=4
is reported as a conflict. Non-conflicting relationships, such as OMP_PROC_BIND taking precedence over GOMP_CPU_AFFINITY in libgomp, are available through the machine-readable analysis API in OpenMP::Environment::Validation.
No system probing
Validation is intentionally system-agnostic. It does not inspect processors, NUMA topology, GPUs, target devices, allocator availability, runtime state, /proc, hwloc, compiler executables, or operating-system resources. A value can therefore be syntactically valid while depending on runtime resources:
OMP_DEFAULT_DEVICE=7
OMP_PLACES={0,1,2,3}
OMP_STACKSIZE=64G
See OpenMP::Environment::Validation for the detailed human- and machine-readable validation reference.
METHODS
Construction and inspection
new-
my $env = OpenMP::Environment->new;Creates a new environment manager.
vars-
Returns the canonical
OMP_*andGOMP_*variable names supported by this release. Existing variable ordering from version 1.2.3 is retained, with new GCC 16.2 variables appended for compatibility. vars_set-
Returns hash references for supported variables currently considered set.
vars_unset-
Returns supported variables currently considered unset.
assert_omp_environment-
Strictly validates supported canonical variables already set in
%ENV, including the complex grammars introduced in the 1.5.0 validation module and portable cross-variable conflicts. Dies on the first validation failure or conflict and returns true when validation succeeds. print_omp_summary-
Prints all supported canonical variables and their current values or unset status.
print_omp_summary_set-
Prints supported canonical variables currently set.
print_omp_summary_unset-
Prints supported canonical variables currently unset.
Functional DSL
unset CONSTANT-
use OpenMP::Environment qw/:unset/; $env->omp_target_offload = q{MANDATORY}; unset omp_target_offload;Deletes one supported environment variable through a static Dispatch::Fu dispatch table and returns the previous value, matching Perl
deletesemantics. Unsupported names are rejected. assert CONSTANT-
use OpenMP::Environment qw/:assert/; $ENV{OMP_SCHEDULE} = q{dynamic,4}; assert omp_schedule;Strictly validates the selected supported variable and any portable cross-variable conflict involving it. An unset supported variable is valid.
Environment-variable accessors
Each omp_* or gomp_* method is an lvalue-capable getter/setter. New code may use normal Perl assignment syntax, which is the preferred form in this documentation:
$env->omp_num_threads = 8;
$env->omp_proc_bind = q{spread};
$env->omp_places = q{cores};
Lvalue assignment uses the same validation and filtering as the traditional setter form. Compound operations therefore also pass their resulting value through the accessor:
$env->omp_num_threads++;
$env->gomp_spincount += 1000;
$env->omp_affinity_format .= q{ %n};
Invalid lvalue assignments die without replacing the previous valid value.
Traditional getter/setter usage
The pre-1.4.0 call-style API remains fully supported for backward compatibility. Existing code does not need to change:
$env->omp_num_threads(8); # traditional setter
my $threads = $env->omp_num_threads(); # traditional getter
$env->unset_omp_num_threads(); # explicit unsetter
The corresponding unset_* method deletes the variable and returns its previous value, following Perl's normal delete semantics.
For OMP_DYNAMIC and OMP_NESTED, the historical behavior is retained in both forms: assigning or passing a false value unsets the environment variable.
omp_allocator([$value])-
Getter/setter for
OMP_ALLOCATOR. Assignment remains pass-through for backward compatibility; strictassertvalidates allocator/memory-space/trait grammar. unset_omp_allocator-
Deletes
OMP_ALLOCATOR. omp_affinity_format([$value])-
Getter/setter for
OMP_AFFINITY_FORMAT. Assignment remains pass-through for backward compatibility; strictassertvalidates affinity-format field syntax. unset_omp_affinity_format-
Deletes
OMP_AFFINITY_FORMAT. omp_cancellation([$value])-
Getter/setter for
OMP_CANCELLATION. AcceptsTRUEorFALSE, case-insensitively. unset_omp_cancellation-
Deletes
OMP_CANCELLATION. omp_display_affinity([$value])-
Getter/setter for
OMP_DISPLAY_AFFINITY. AcceptsTRUEorFALSE, case-insensitively. unset_omp_display_affinity-
Deletes
OMP_DISPLAY_AFFINITY. omp_display_env([$value])-
Getter/setter for
OMP_DISPLAY_ENV. AcceptsTRUE,FALSE, orVERBOSE, case-insensitively. unset_omp_display_env-
Deletes
OMP_DISPLAY_ENV. omp_default_device([$value])-
Getter/setter for
OMP_DEFAULT_DEVICE. Validated as a non-negative integer. unset_omp_default_device-
Deletes
OMP_DEFAULT_DEVICE. omp_dynamic([$value])-
Getter/setter for
OMP_DYNAMIC. Existing compatibility behavior is retained: a false value (0,false, orFALSE) unsetsOMP_DYNAMICrather than storing a false string. Calling the method with no value is a normal, non-destructive getter. unset_omp_dynamic-
Deletes
OMP_DYNAMIC. omp_max_active_levels([$value])-
Getter/setter for
OMP_MAX_ACTIVE_LEVELS. GCC/libgomp documents a positive integer and this module preserves that GNU/legacy rule. OpenMP 5.2 itself permits a non-negative integer, so zero is OpenMP-valid but is rejected by this GCC/libgomp-oriented validation profile. unset_omp_max_active_levels-
Deletes
OMP_MAX_ACTIVE_LEVELS. omp_max_task_priority([$value])-
Getter/setter for
OMP_MAX_TASK_PRIORITY. Validated as a non-negative integer. unset_omp_max_task_priority-
Deletes
OMP_MAX_TASK_PRIORITY. omp_nested([$value])-
Getter/setter for the deprecated-but-still-supported
OMP_NESTEDvariable. Existing compatibility behavior is retained: a false value unsets the variable. Calling the method with no value is a normal, non-destructive getter. For new code,OMP_MAX_ACTIVE_LEVELSis generally preferable. unset_omp_nested-
Deletes
OMP_NESTED. omp_num_teams([$value])-
Getter/setter for
OMP_NUM_TEAMS. Validated as a positive integer. unset_omp_num_teams-
Deletes
OMP_NUM_TEAMS. omp_num_threads([$value])-
Getter/setter for
OMP_NUM_THREADS. Accepts either one positive integer or a comma-separated list of positive integers such as8,4,2. unset_omp_num_threads-
Deletes
OMP_NUM_THREADS. omp_proc_bind([$value])-
Getter/setter for
OMP_PROC_BIND. Assignment remains pass-through for backward compatibility; strictassertvalidates OpenMP policies plus libgomp's deprecatedMASTERcompatibility spelling. unset_omp_proc_bind-
Deletes
OMP_PROC_BIND. omp_places([$value])-
Getter/setter for
OMP_PLACES. Assignment remains pass-through for backward compatibility; strictassertvalidates grammar without probing processor topology. unset_omp_places-
Deletes
OMP_PLACES. omp_stacksize([$value])-
Getter/setter for
OMP_STACKSIZE. Assignment remains pass-through for backward compatibility; strictassertvalidates positive size/unit syntax without checking memory availability. unset_omp_stacksize-
Deletes
OMP_STACKSIZE. omp_schedule([$value])-
Getter/setter for
OMP_SCHEDULE. Assignment remains pass-through for backward compatibility; strictassertvalidates the OpenMP 5.2[modifier:]kind[,chunk]grammar. unset_omp_schedule-
Deletes
OMP_SCHEDULE. omp_target_offload([$value])-
Getter/setter for
OMP_TARGET_OFFLOAD. AcceptsMANDATORY,DISABLED, orDEFAULT, case-insensitively. unset_omp_target_offload-
Deletes
OMP_TARGET_OFFLOAD. omp_teams_thread_limit([$value])-
Getter/setter for
OMP_TEAMS_THREAD_LIMIT. Validated as a positive integer. unset_omp_teams_thread_limit-
Deletes
OMP_TEAMS_THREAD_LIMIT. omp_thread_limit([$value])-
Getter/setter for
OMP_THREAD_LIMIT. Validated as a positive integer. unset_omp_thread_limit-
Deletes
OMP_THREAD_LIMIT. omp_wait_policy([$value])-
Getter/setter for
OMP_WAIT_POLICY. AcceptsACTIVEorPASSIVE, case-insensitively. unset_omp_wait_policy-
Deletes
OMP_WAIT_POLICY. gomp_cpu_affinity([$value])-
Getter/setter for GNU
GOMP_CPU_AFFINITY. Assignment remains pass-through for backward compatibility; strictassertvalidates GNU CPU/range/stride syntax without checking host CPUs. unset_gomp_cpu_affinity-
Deletes
GOMP_CPU_AFFINITY. gomp_debug([$value])-
Getter/setter for GNU
GOMP_DEBUG. Accepts0or1. unset_gomp_debug-
Deletes
GOMP_DEBUG. gomp_stacksize([$value])-
Getter/setter for GNU
GOMP_STACKSIZE, which controls the default worker thread stack size in kilobytes. Assignment remains pass-through; strictassertvalidates GNU numeric syntax plus the historical unit-suffix compatibility accepted by this module. unset_gomp_stacksize-
Deletes
GOMP_STACKSIZE. gomp_spincount([$value])-
Getter/setter for GNU
GOMP_SPINCOUNT, which controls active busy-waiting before passive waiting. Assignment remains pass-through for backward compatibility; strictassertaccepts an integer with documented magnitude suffixes orINFINITE/INFINITY. unset_gomp_spincount-
Deletes
GOMP_SPINCOUNT. gomp_rtems_thread_pools([$value])-
Getter/setter for GNU
GOMP_RTEMS_THREAD_POOLS, used only on RTEMS. Assignment remains pass-through for backward compatibility; strictassertvalidates the GNUcount[$priority]@schedulerlist grammar without probing RTEMS. unset_gomp_rtems_thread_pools-
Deletes
GOMP_RTEMS_THREAD_POOLS.
SUPPORTED ENVIRONMENT VARIABLES
The canonical list in GCC 16.2 libgomp is:
OMP_ALLOCATOR
OMP_AFFINITY_FORMAT
OMP_CANCELLATION
OMP_DISPLAY_AFFINITY
OMP_DISPLAY_ENV
OMP_DEFAULT_DEVICE
OMP_DYNAMIC
OMP_MAX_ACTIVE_LEVELS
OMP_MAX_TASK_PRIORITY
OMP_NESTED
OMP_NUM_TEAMS
OMP_NUM_THREADS
OMP_PROC_BIND
OMP_PLACES
OMP_STACKSIZE
OMP_SCHEDULE
OMP_TARGET_OFFLOAD
OMP_TEAMS_THREAD_LIMIT
OMP_THREAD_LIMIT
OMP_WAIT_POLICY
GOMP_CPU_AFFINITY
GOMP_DEBUG
GOMP_STACKSIZE
GOMP_SPINCOUNT
GOMP_RTEMS_THREAD_POOLS
For authoritative grammar, defaults, ICV scope, and implementation notes, see the GCC 16.2 libgomp environment-variable chapter:
https://gcc.gnu.org/onlinedocs/gcc-16.2.0/libgomp/Environment-Variables.html
EXTERNAL EXECUTABLES VS. IN-PROCESS OPENMP
For an external OpenMP executable, environment changes made immediately before system or exec naturally affect the new process. This is the simplest and most general usage of the module.
For OpenMP-enabled C code loaded into the current Perl process through XS, Inline::C, or another FFI mechanism, the OpenMP runtime may already have read its initialization environment. OpenMP::Simple addresses the useful subset of settings that can be refreshed through OpenMP runtime setter APIs.
This means the two modules complement each other:
OpenMP::Environment -> manages and validates %ENV
OpenMP::Simple -> applies selected %ENV values to an active runtime
EXAMPLES IN THE DISTRIBUTION
The examples/ directory contains launcher, environment-summary, validation, and Inline::C/OpenMP examples. The launcher example is particularly relevant when wrapping existing OpenMP-enabled applications.
BACKWARD COMPATIBILITY
Version 1.5.0 remains an additive update. Existing accessor names remain unchanged. Existing false/unset behavior for OMP_DYNAMIC and OMP_NESTED is preserved. Their no-argument calls now behave as non-destructive getters, consistent with every other accessor. Existing canonical variable ordering returned by vars is preserved, with the three newly supported GCC 16.2 variables appended.
Every assignment accepted by previous releases remains accepted. The strict 1.5.0 validation rules for historically pass-through variables are opt-in via assert, assert_omp_environment, or OpenMP::Environment::Validation. Thus validation can be substantially more informative without changing setter or lvalue compatibility.
SEE ALSO
OpenMP::Environment::Constants, OpenMP::Environment::Validation, Dispatch::Fu, OpenMP::Simple, Inline::C, and the GCC libgomp manual:
https://gcc.gnu.org/onlinedocs/gcc-16.2.0/libgomp/
The OpenMP specification is available from https://www.openmp.org/.
AUTHOR
Brett Estrade <oodler@cpan.org>
ACKNOWLEDGEMENTS
Thanks to the Perl and OpenMP communities, including contributors and participants in the Perl #pdl and #native channels who helped with Inline::C, shared-library load-time, and OpenMP-runtime behavior discussions.
COPYRIGHT AND LICENSE
Same as Perl.