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.3.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};

OMP_ALLOCATOR and OMP_AFFINITY_FORMAT are intentionally not validated by this module because their accepted grammars are substantially more complex than the scalar checks performed here.

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. Its libgomp documentation contains 25 canonical OpenMP/GOMP environment-variable names, and this release exposes all 25 while retaining the accessors and semantics from earlier OpenMP::Environment releases.

Version 1.3.0 adds support for:

  • OMP_ALLOCATOR

  • OMP_AFFINITY_FORMAT

  • OMP_DISPLAY_AFFINITY

  • comma-separated positive-integer lists for OMP_NUM_THREADS

  • validated lvalue assignment for all omp_* and gomp_* accessors

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

Validation is intentionally conservative. Values are validated when the accepted grammar is simple and stable; complex OpenMP/libgomp syntaxes are passed through unchanged.

The following variables are validated:

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_TARGET_OFFLOAD
OMP_TEAMS_THREAD_LIMIT
OMP_THREAD_LIMIT
OMP_WAIT_POLICY
GOMP_DEBUG

The following are supported but not currently validated:

OMP_ALLOCATOR
OMP_AFFINITY_FORMAT
OMP_PROC_BIND
OMP_PLACES
OMP_STACKSIZE
OMP_SCHEDULE
GOMP_CPU_AFFINITY
GOMP_STACKSIZE
GOMP_SPINCOUNT
GOMP_RTEMS_THREAD_POOLS

assert_omp_environment validates canonical supported variables already present in %ENV. An environment with none of those variables set is valid.

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

Validates supported canonical variables already set in %ENV. Dies on the first validation failure encountered 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.

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.3.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. Not validated.

unset_omp_allocator

Deletes OMP_ALLOCATOR.

omp_affinity_format([$value])

Getter/setter for OMP_AFFINITY_FORMAT. Not validated.

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. Validated as a positive integer.

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. Not validated.

unset_omp_proc_bind

Deletes OMP_PROC_BIND.

omp_places([$value])

Getter/setter for OMP_PLACES. Not validated.

unset_omp_places

Deletes OMP_PLACES.

omp_stacksize([$value])

Getter/setter for OMP_STACKSIZE. Not validated.

unset_omp_stacksize

Deletes OMP_STACKSIZE.

omp_schedule([$value])

Getter/setter for OMP_SCHEDULE. Not validated. libgomp accepts schedule specifications such as static, dynamic,8, guided,4, and auto.

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. Not validated.

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. Not validated.

unset_gomp_stacksize

Deletes GOMP_STACKSIZE.

gomp_spincount([$value])

Getter/setter for GNU GOMP_SPINCOUNT, which controls active busy-waiting before passive waiting. libgomp accepts an integer, optionally with magnitude suffixes, or INFINITE/INFINITY. Not validated.

unset_gomp_spincount

Deletes GOMP_SPINCOUNT.

gomp_rtems_thread_pools([$value])

Getter/setter for GNU GOMP_RTEMS_THREAD_POOLS, used only on RTEMS. Not validated.

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.3.0 is intended as 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.

The only validation broadening is for OMP_NUM_THREADS: every value accepted by previous releases remains accepted, while standard comma-separated nested thread-count lists are now accepted as well.

SEE ALSO

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.