NAME

OpenMP::Environment - manage OpenMP and GNU libgomp environment variables from Perl

SYNOPSIS

OpenMP::Environment is intended for two closely related jobs:

  • Preparing %ENV before 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_ALLOCATOR

  • OMP_AFFINITY_FORMAT

  • OMP_DISPLAY_AFFINITY

  • comma-separated positive-integer lists for OMP_NUM_THREADS

  • lvalue assignment for all omp_* and gomp_* 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_* and GOMP_* 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.

Prints all supported canonical variables and their current values or unset status.

Prints supported canonical variables currently set.

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 delete semantics. 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; strict assert validates 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; strict assert validates affinity-format field syntax.

unset_omp_affinity_format

Deletes OMP_AFFINITY_FORMAT.

omp_cancellation([$value])

Getter/setter for OMP_CANCELLATION. Accepts TRUE or FALSE, case-insensitively.

unset_omp_cancellation

Deletes OMP_CANCELLATION.

omp_display_affinity([$value])

Getter/setter for OMP_DISPLAY_AFFINITY. Accepts TRUE or FALSE, case-insensitively.

unset_omp_display_affinity

Deletes OMP_DISPLAY_AFFINITY.

omp_display_env([$value])

Getter/setter for OMP_DISPLAY_ENV. Accepts TRUE, FALSE, or VERBOSE, 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, or FALSE) unsets OMP_DYNAMIC rather 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_NESTED variable. 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_LEVELS is 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 as 8,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; strict assert validates OpenMP policies plus libgomp's deprecated MASTER compatibility spelling.

unset_omp_proc_bind

Deletes OMP_PROC_BIND.

omp_places([$value])

Getter/setter for OMP_PLACES. Assignment remains pass-through for backward compatibility; strict assert validates 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; strict assert validates 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; strict assert validates the OpenMP 5.2 [modifier:]kind[,chunk] grammar.

unset_omp_schedule

Deletes OMP_SCHEDULE.

omp_target_offload([$value])

Getter/setter for OMP_TARGET_OFFLOAD. Accepts MANDATORY, DISABLED, or DEFAULT, 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. Accepts ACTIVE or PASSIVE, 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; strict assert validates 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. Accepts 0 or 1.

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; strict assert validates 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; strict assert accepts an integer with documented magnitude suffixes or INFINITE/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; strict assert validates the GNU count[$priority]@scheduler list 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.