How to use OpenMP from Perl with SPVM.
See an example to bind OpenMP to SPVM
SPVM provides a way to bind C language libraries and call them from Perl.
When binding C libraries to Perl, you typically write XS, but SPVM offers an alternative approach.
MyOpenMP.spvm
class MyOpenMP {
native static method sum_vec_int : int[] ($nums1 : int[], $nums2 : int[]);
static method test : void () {
my $nums1 = [1, 2, 3];
my $nums2 = [5, 6, 7];
my $nums3 = &sum_vec_int($nums1, $nums2);
for (my $i = 0; $i < @$nums3; $i++) {
say $nums3->[$i];
}
}
}
MyOpenMP.c
#include "spvm_native.h"
#include <string.h>
static const char* FILE_NAME = "SPVM/MyOpenMP.c";
int32_t SPVM__MyOpenMP__sum_vec_int(SPVM_ENV* env, SPVM_VALUE* stack) {
void* obj_nums1 = stack[0].oval;
if (obj_nums1 == NULL) {
return env->die(env, stack, "$nums1 must be defined.", __func__, FILE_NAME, __LINE__);
}
int32_t* nums1 = env->get_elems_int(env, stack, obj_nums1);
void* obj_nums2 = stack[1].oval;
if(obj_nums2 == NULL) {
return env->die(env, stack, "$nums2 must be defined.", __func__, FILE_NAME, __LINE__);
}
int32_t* nums2 = env->get_elems_int(env, stack, obj_nums2);
int32_t length = env->length(env, stack, obj_nums1);
void* obj_nums3 = env->new_int_array(env, stack, length);
int32_t* nums3 = env->get_elems_int(env, stack, obj_nums3);
int32_t i;
#pragma omp parallel for
for (i = 0; i < length; i++) {
nums3[i] = nums1[i] + nums2[i];
}
stack[0].oval = obj_nums3;
return 0;
}
MyOpenMP.config
use strict;
use warnings;
use SPVM::Builder::Config;
my $config = SPVM::Builder::Config->new_gnu99(file => __FILE__);
# Compiler options
$config->add_ccflag('-fopenmp');
# Linker option
$config->add_ldflag('-fopenmp');
$config->add_lib('gomp');
$config;
openmp.pl
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/lib";
use SPVM 'MyOpenMP';
SPVM::MyOpenMP->test;
This program outputs values calculated by OpenMP.
6
8
10
Top comments (0)