DEV Community

Yuki Kimoto
Yuki Kimoto

Posted on

How to use OpenMP from Perl with SPVM.

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];
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

openmp.pl

use strict;
use warnings;

use FindBin;
use lib "$FindBin::Bin/lib";

use SPVM 'MyOpenMP';

SPVM::MyOpenMP->test;
Enter fullscreen mode Exit fullscreen mode

This program outputs values calculated by OpenMP.

6
8
10
Enter fullscreen mode Exit fullscreen mode

Top comments (0)