NAME
OpenMP::Simple - Inline::C support for using OpenMP from Perl
SYNOPSIS
Using OpenMP::Environment
use strict;
use warnings;
use OpenMP::Simple;
use OpenMP::Environment;
use Inline (
C => 'DATA',
with => qw/OpenMP::Simple/,
);
my $env = OpenMP::Environment->new;
$env->omp_num_threads(4);
$env->omp_schedule('dynamic,4');
# Optional: validate the OpenMP environment before entering C.
$env->assert_omp_environment;
print "threads = ", _openmp_threads(), "\n";
__DATA__
__C__
int _openmp_threads() {
PerlOMP_GETENV_BASIC
int threads = 0;
#pragma omp parallel
{
#pragma omp single
threads = omp_get_num_threads();
}
return threads;
}
Using %ENV directly
OpenMP::Environment is convenient, but it is not required in order to use OpenMP::Simple. The macros read the normal OpenMP environment variables from %ENV.
use strict;
use warnings;
BEGIN {
$ENV{OMP_NUM_THREADS} = 4;
$ENV{OMP_SCHEDULE} = 'guided,8';
}
use OpenMP::Simple;
use Inline (
C => 'DATA',
with => qw/OpenMP::Simple/,
);
print "threads = ", _openmp_threads(), "\n";
__DATA__
__C__
int _openmp_threads() {
PerlOMP_GETENV_BASIC
int threads = 0;
#pragma omp parallel
{
#pragma omp single
threads = omp_get_num_threads();
}
return threads;
}
Using OpenMP without the environment macros
OpenMP::Simple can also be used simply to obtain the OpenMP build and link configuration through Alien::OpenMP. There is no requirement that a PerlOMP_* environment macro be used.
use strict;
use warnings;
use OpenMP::Simple;
use Inline (
C => 'DATA',
with => qw/OpenMP::Simple/,
);
print "maximum threads = ", _openmp_max_threads(), "\n";
__DATA__
__C__
int _openmp_max_threads() {
return omp_get_max_threads();
}
DESCRIPTION
OpenMP::Simple is a small Inline::C configuration wrapper around Alien::OpenMP. It supplies the compiler and linker configuration discovered by Alien::OpenMP and automatically includes the openmp-simple.h header shipped with this distribution.
The header provides convenience macros and helper functions for common Perl/OpenMP tasks. The most commonly used macros read standard OpenMP variables from %ENV and apply those values to the current OpenMP runtime by calling the corresponding OpenMP runtime functions.
OpenMP::Environment is the recommended interface for managing OpenMP environment variables from Perl because it provides a consistent API and can validate values. It is not, however, required by OpenMP::Simple. Setting %ENV directly is supported, and OpenMP::Simple may also be used without any environment-update macros at all.
Runtime environment and process startup
Not every OpenMP environment variable has a corresponding runtime setter. Variables such as OMP_NUM_THREADS and OMP_SCHEDULE can be read by OpenMP::Simple and applied with OpenMP runtime functions. Other variables, such as OMP_CANCELLATION, may be consumed by the OpenMP runtime when the runtime is initialized and therefore may need to be present in the environment before the Inline::C shared library is loaded.
When an OpenMP setting must exist before runtime initialization, set it in a BEGIN block or otherwise arrange for it to be present in the process environment before OpenMP code is loaded.
Experimental data conversion helpers
The array conversion and verification helpers are intended to make common Perl-to-C data handling less repetitive. They remain more experimental than the environment-update macros.
Perl API access from arbitrary OpenMP worker threads should not be assumed to be safe. Where practical, stage Perl data on the Perl/caller thread and do only native C work inside OpenMP worker threads. The string conversion helpers have been hardened in this direction. The _r numeric conversion helpers should still be regarded as experimental when portability across Perl builds and threading models is important.
OpenMP::Environment
OpenMP::Environment and OpenMP::Simple are designed to work together, but they have separate responsibilities.
OpenMP::Environment manages and validates the Perl process environment. OpenMP::Simple makes those environment values useful inside Inline::C code by applying them to the active OpenMP runtime.
For example:
my $env = OpenMP::Environment->new;
$env->omp_num_threads(8);
$env->omp_dynamic('FALSE');
$env->omp_schedule('static,16');
$env->assert_omp_environment;
and then in C:
void apply_openmp_environment() {
PerlOMP_UPDATE_WITH_ENV__NUM_THREADS
PerlOMP_UPDATE_WITH_ENV__DYNAMIC
PerlOMP_UPDATE_WITH_ENV__SCHEDULE
}
The equivalent can be done without OpenMP::Environment:
$ENV{OMP_NUM_THREADS} = 8;
$ENV{OMP_DYNAMIC} = 'FALSE';
$ENV{OMP_SCHEDULE} = 'static,16';
The C code is unchanged because the macros read the process environment, not the Perl object that was used to create it.
PORTABILITY AND TESTED PLATFORMS
Tested configurations
The continuous-integration matrix documents configurations that are actively tested. It is not intended to define the complete set of platforms on which OpenMP::Simple can run.
Current testing includes:
Perl 5.10 through Perl 5.44 on Ubuntu 22.04 and Ubuntu 24.04.
Perl 5.44.0 built specifically with GCC 12.5.0, 13.4.0, 14.4.0, 15.3.0, and 16.2.0.
macOS with Perl 5.42.2, Apple Clang 21.0.0, and libomp 22.1.8.
Windows with Strawberry Perl 5.42.2.1 and GCC 13.2.0.
The dedicated GCC matrix builds Perl with each compiler being tested so that the compiler recorded in Perl's Config is the same compiler used by Alien::OpenMP and OpenMP::Simple.
Portability beyond the tested matrix
OpenMP::Simple itself contains very little platform-specific code. It relies on Alien::OpenMP to provide the compiler and OpenMP runtime configuration required by Inline::C. As a result, systems outside the tested matrix should generally work when the Perl installation, C compiler, and OpenMP runtime form a compatible toolchain.
Older Linux distributions are expected to remain usable provided their Perl, compiler, C library, and OpenMP runtime satisfy the requirements of Alien::OpenMP and the particular OpenMP runtime functions being used. The tested Ubuntu 22.04 and Ubuntu 24.04 systems should therefore be regarded as reference platforms rather than minimum supported operating-system versions.
Likewise, GCC versions older than those in the dedicated GCC matrix may work. Most basic OpenMP::Simple functionality uses long-established OpenMP runtime interfaces such as omp_set_num_threads, omp_set_schedule, omp_set_dynamic, omp_set_nested, omp_set_max_active_levels, and omp_set_default_device.
Individual newer features may require a newer OpenMP implementation. In particular, omp_set_num_teams and omp_set_teams_thread_limit require the corresponding runtime support and should not be assumed to exist on older OpenMP runtimes.
Other Unix-like systems, other Clang/libomp combinations, and other compatible OpenMP implementations may also work but are not currently part of the continuous-integration matrix. A platform should not be considered unsupported merely because its exact operating-system or compiler version does not appear in CI.
The important portability constraint is the toolchain as a whole: the compiler and OpenMP runtime used by OpenMP::Simple should be compatible with the compiler configuration of the Perl being used. Alien::OpenMP is responsible for discovering and supplying that configuration.
Accordingly:
Configurations in the CI matrix are actively tested.
Older operating systems are supported where the Perl, compiler, and OpenMP toolchain remains compatible.
Older compiler and OpenMP combinations may support the core API even when newer optional OpenMP runtime functions are unavailable.
Untested platforms using compatible Perl, C compiler, and OpenMP runtime combinations are expected to work, but should be regarded as unverified until exercised by CI or CPAN Testers.
PROVIDED C MACROS
Updating the OpenMP runtime from %ENV
The PerlOMP_UPDATE_WITH_ENV__* macros read standard OpenMP environment variables and, where an OpenMP runtime setter exists, apply the value to the current runtime.
The variables can be set through OpenMP::Environment or directly through %ENV.
PerlOMP_GETENV_BASIC
A convenience bundle equivalent to:
PerlOMP_UPDATE_WITH_ENV__NUM_THREADS
PerlOMP_UPDATE_WITH_ENV__SCHEDULE
This is useful when a routine should honor the two most common per-call settings without spelling out both macros.
PerlOMP_UPDATE_WITH_ENV__NUM_THREADS
Reads $ENV{OMP_NUM_THREADS} and applies it with omp_set_num_threads.
With OpenMP::Environment:
my $env = OpenMP::Environment->new;
$env->omp_num_threads(8);
Without OpenMP::Environment:
$ENV{OMP_NUM_THREADS} = 8;
In either case:
int threads_in_team() {
PerlOMP_UPDATE_WITH_ENV__NUM_THREADS
int threads = 0;
#pragma omp parallel
{
#pragma omp single
threads = omp_get_num_threads();
}
return threads;
}
PerlOMP_UPDATE_WITH_ENV__SCHEDULE
Reads $ENV{OMP_SCHEDULE} and applies it with omp_set_schedule.
The current helper recognizes static, dynamic, guided, and auto, with an optional comma-separated chunk size where meaningful, for example:
$ENV{OMP_SCHEDULE} = 'dynamic,4';
or:
my $env = OpenMP::Environment->new;
$env->omp_schedule('dynamic,4');
A simple runtime check is:
int current_schedule_chunk() {
PerlOMP_UPDATE_WITH_ENV__SCHEDULE
omp_sched_t kind;
int chunk = 0;
omp_get_schedule(&kind, &chunk);
return chunk;
}
The OpenMP runtime may normalize schedule details, especially for auto, so code should not assume that every implementation reports an identical chunk value for every scheduling mode.
PerlOMP_UPDATE_WITH_ENV__DYNAMIC
Reads $ENV{OMP_DYNAMIC} and applies it with omp_set_dynamic. True values accepted by the helper include TRUE, true, and 1; other values disable dynamic adjustment.
PerlOMP_UPDATE_WITH_ENV__NESTED
Reads $ENV{OMP_NESTED} and applies it with omp_set_nested.
omp_set_nested is retained for compatibility with the existing OpenMP::Simple API, although newer OpenMP specifications prefer controlling nested parallelism with active-level settings such as OMP_MAX_ACTIVE_LEVELS and omp_set_max_active_levels.
PerlOMP_UPDATE_WITH_ENV__MAX_ACTIVE_LEVELS
Reads $ENV{OMP_MAX_ACTIVE_LEVELS} and applies it with omp_set_max_active_levels.
PerlOMP_UPDATE_WITH_ENV__DEFAULT_DEVICE
Reads $ENV{OMP_DEFAULT_DEVICE} and applies it with omp_set_default_device.
Device numbers are runtime-dependent. A host-only OpenMP implementation may report zero target devices, so portable code should query omp_get_num_devices before assuming that a particular target device number is valid.
PerlOMP_UPDATE_WITH_ENV__NUM_TEAMS
Reads $ENV{OMP_NUM_TEAMS} and applies it with omp_set_num_teams when the OpenMP runtime provides that function.
This is a newer OpenMP runtime interface than the core thread-management functions. Availability therefore depends on the compiler and OpenMP runtime being used.
PerlOMP_UPDATE_WITH_ENV__TEAMS_THREAD_LIMIT
Reads $ENV{OMP_TEAMS_THREAD_LIMIT} and applies it with omp_set_teams_thread_limit when the OpenMP runtime provides that function.
As with omp_set_num_teams, availability depends on the OpenMP implementation and version.
PerlOMP_RET_ARRAY_REF_ret
Creates a mortal Perl AV * named ret. It is a convenience helper for Inline::C routines that build and return an array reference.
For example:
AV *values() {
PerlOMP_RET_ARRAY_REF_ret
av_push(ret, newSViv(10));
av_push(ret, newSViv(20));
av_push(ret, newSViv(30));
return ret;
}
PROVIDED C FUNCTIONS FOR COUNTING PERL ARRAYS
PerlOMP_1D_Array_NUM_ELEMENTS
int PerlOMP_1D_Array_NUM_ELEMENTS(SV *AVref);
Returns the number of elements in a one-dimensional Perl array reference.
PerlOMP_2D_AoA_NUM_ROWS
int PerlOMP_2D_AoA_NUM_ROWS(SV *AoAref);
Returns the number of rows in a two-dimensional Perl array-of-arrays.
PerlOMP_2D_AoA_NUM_COLS
int PerlOMP_2D_AoA_NUM_COLS(SV *AoAref);
Returns the number of elements in the first row of a two-dimensional Perl array-of-arrays. It assumes that the caller intends the rows to have a common shape; it does not verify every row length.
Example
These helpers do not require OpenMP::Environment:
use strict;
use warnings;
use OpenMP::Simple;
use Inline (
C => 'DATA',
with => qw/OpenMP::Simple/,
);
my $matrix = [
[ 1, 2, 3 ],
[ 4, 5, 6 ],
];
print rows($matrix), " x ", cols($matrix), "\n";
__DATA__
__C__
int rows(SV *matrix) {
return PerlOMP_2D_AoA_NUM_ROWS(matrix);
}
int cols(SV *matrix) {
return PerlOMP_2D_AoA_NUM_COLS(matrix);
}
PROVIDED C FUNCTIONS FOR CONVERTING 1D PERL ARRAYS TO C ARRAYS
PerlOMP_1D_Array_TO_1D_FLOAT_ARRAY
void PerlOMP_1D_Array_TO_1D_FLOAT_ARRAY(
SV *AVref,
int numElements,
float retArray[numElements]
);
Converts a one-dimensional Perl array reference to a C array of float.
PerlOMP_1D_Array_TO_1D_FLOAT_ARRAY_r
void PerlOMP_1D_Array_TO_1D_FLOAT_ARRAY_r(
SV *AVref,
int numElements,
float retArray[numElements]
);
OpenMP-parallelized variant of PerlOMP_1D_Array_TO_1D_FLOAT_ARRAY. See "Experimental data conversion helpers" before relying on the _r conversion helpers across different Perl threading models.
PerlOMP_1D_Array_TO_1D_INT_ARRAY
void PerlOMP_1D_Array_TO_1D_INT_ARRAY(
SV *AVref,
int numElements,
int retArray[numElements]
);
Converts a one-dimensional Perl array reference to a C array of int.
PerlOMP_1D_Array_TO_1D_INT_ARRAY_r
void PerlOMP_1D_Array_TO_1D_INT_ARRAY_r(
SV *AVref,
int numElements,
int retArray[numElements]
);
OpenMP-parallelized variant of PerlOMP_1D_Array_TO_1D_INT_ARRAY. See "Experimental data conversion helpers" for the portability caveat applying to _r conversion helpers.
PerlOMP_1D_Array_TO_1D_STRING_ARRAY
void PerlOMP_1D_Array_TO_1D_STRING_ARRAY(
SV *AVref,
int numElements,
char *retArray[numElements]
);
Converts a one-dimensional Perl array reference to separately allocated native C strings.
The caller owns the resulting C strings and should free each element when it is no longer needed.
PerlOMP_1D_Array_TO_1D_STRING_ARRAY_r
void PerlOMP_1D_Array_TO_1D_STRING_ARRAY_r(
SV *AVref,
int numElements,
char *retArray[numElements]
);
Parallelized string-copy variant. Perl scalar access and native-buffer setup are staged on the caller thread; OpenMP workers copy native string data rather than manipulating Perl scalar storage directly.
As with the non-_r form, the caller owns the resulting C strings and should free them.
PROVIDED C FUNCTIONS FOR CONVERTING 2D PERL ARRAYS TO C ARRAYS
PerlOMP_2D_AoA_TO_2D_FLOAT_ARRAY
void PerlOMP_2D_AoA_TO_2D_FLOAT_ARRAY(
SV *AoA,
int numRows,
int rowSize,
float retArray[numRows][rowSize]
);
Converts a two-dimensional Perl array-of-arrays to a two-dimensional C array of float.
PerlOMP_2D_AoA_TO_2D_FLOAT_ARRAY_r
OpenMP-parallelized variant of PerlOMP_2D_AoA_TO_2D_FLOAT_ARRAY. See "Experimental data conversion helpers" for the portability caveat applying to _r conversion helpers.
PerlOMP_2D_AoA_TO_2D_INT_ARRAY
void PerlOMP_2D_AoA_TO_2D_INT_ARRAY(
SV *AoA,
int numRows,
int rowSize,
int retArray[numRows][rowSize]
);
Converts a two-dimensional Perl array-of-arrays to a two-dimensional C array of int.
PerlOMP_2D_AoA_TO_2D_INT_ARRAY_r
OpenMP-parallelized variant of PerlOMP_2D_AoA_TO_2D_INT_ARRAY. See "Experimental data conversion helpers" for the portability caveat applying to _r conversion helpers.
PerlOMP_2D_AoA_TO_2D_STRING_ARRAY
void PerlOMP_2D_AoA_TO_2D_STRING_ARRAY(
SV *AoA,
int numRows,
int rowSize,
char *retArray[numRows][rowSize]
);
Converts a two-dimensional Perl array-of-arrays to separately allocated native C strings.
The caller owns the resulting strings and should free every element.
PerlOMP_2D_AoA_TO_2D_STRING_ARRAY_r
void PerlOMP_2D_AoA_TO_2D_STRING_ARRAY_r(
SV *AoA,
int numRows,
int rowSize,
char *retArray[numRows][rowSize]
);
Parallelized string-copy variant. Perl scalar access and native-buffer setup are staged on the caller thread; OpenMP workers copy native string data rather than manipulating Perl scalar storage directly.
The caller owns the resulting strings and should free every element.
PROVIDED ARRAY VERIFICATION FUNCTIONS
PerlOMP_VERIFY_1D_Array
void PerlOMP_VERIFY_1D_Array(SV *array);
Verifies that the supplied Perl value is a one-dimensional array reference.
PerlOMP_VERIFY_1D_INT_ARRAY
void PerlOMP_VERIFY_1D_INT_ARRAY(SV *array);
Verifies that a one-dimensional Perl array contains integer values.
PerlOMP_VERIFY_1D_FLOAT_ARRAY
void PerlOMP_VERIFY_1D_FLOAT_ARRAY(SV *array);
Verifies that a one-dimensional Perl array contains floating-point values.
PerlOMP_VERIFY_1D_STRING_ARRAY
void PerlOMP_VERIFY_1D_STRING_ARRAY(SV *array);
Verifies that a one-dimensional Perl array contains string values.
PerlOMP_VERIFY_2D_AoA
void PerlOMP_VERIFY_2D_AoA(SV *array);
Verifies that the supplied Perl value is a two-dimensional array-of-arrays.
PerlOMP_VERIFY_2D_INT_ARRAY
void PerlOMP_VERIFY_2D_INT_ARRAY(SV *array);
Verifies that a two-dimensional Perl array contains integer values.
PerlOMP_VERIFY_2D_FLOAT_ARRAY
void PerlOMP_VERIFY_2D_FLOAT_ARRAY(SV *array);
Verifies that a two-dimensional Perl array contains floating-point values.
PerlOMP_VERIFY_2D_STRING_ARRAY
void PerlOMP_VERIFY_2D_STRING_ARRAY(SV *array);
Verifies that a two-dimensional Perl array contains string values.
TESTS AND EXAMPLES
The distribution's t directory contains focused examples for the macros and helper functions. The test suite is also used to exercise Perl, compiler, OpenMP runtime, and operating-system combinations that are difficult to represent accurately in a single documentation example.
Examples in the test suite may use Test::More or other testing modules for verification. Those testing modules are not required merely to use OpenMP::Simple in an application.
SEE ALSO
Alien::OpenMP provides the OpenMP compiler and linker configuration used by this module.
OpenMP::Environment provides a Perl interface for managing and validating OpenMP environment variables and is the recommended companion module when an application needs runtime configuration through %ENV.
The GNU libgomp documentation is useful when using GCC's OpenMP runtime:
https://gcc.gnu.org/onlinedocs/libgomp/
The OpenMP specification and implementation documentation for the compiler and runtime in use remain authoritative for implementation-specific behavior.
https://www.openmp.org/specifications/
See also the RPerl project for related work involving Perl and compiled parallel code:
AUTHOR
Brett Estrade <oodler@cpan.org>
AI GENERATED CODE DISCLAIMER
For transparency, portions of the conversion functions, verification functions, their documentation, and associated tests were developed with substantial assistance from generative AI tools. These portions are maintained and tested as part of OpenMP::Simple like the rest of the distribution.
LICENSE AND COPYRIGHT
This software is licensed under the same terms as Perl itself.