The code presented here is simple to illustrate a use case. I want to know the efficient ways of passing an array of num to C from Raku.
#include <stdio.h>
#include <omp.h>
void c_sum_two(double *first, double *second, double *third, int num)
{
    #pragma omp parallel for
    for (int i = 0; i < num; i++)
    {
        third[i] = first[i] + second[i];
    }
}
What this does is: passes first and second array from Raku to C, performs some calculation, in this case (addition using openmp) and returns a num array to raku.
use NativeCall;
constant MYDYN = "./testsum.dll";
sub c_sum_two(CArray[num64], CArray[num64],CArray[num64], int32) 
    is native( MYDYN) { * };
sub native_sum_two(@arr_one is copy, @arr_two is copy) {
    my $elems = @arr_one.elems;
    ##======================================================##
    # check if two array have same elems
    ##======================================================##
    # Prepare arrays for passing to C
    ##======================================================##
    @arr_one = @arr_one.map: {$_.Num};
    @arr_two = @arr_two.map: {$_.Num};
    # handling first array
    my $first = CArray[num64].new(@arr_one);
    # handling second array
    my $second = CArray[num64].new(@arr_two);
    ##======================================================##
    # Prepare for return array
    my $return = CArray[num64].allocate($elems);
    ##======================================================##
    # Call the C function
    c_sum_two($first, $second, $return, $elems);
    ##======================================================##
    # Get the output back
    $return.list
}
my @a = <1.2 2 3.2 10 0.33>;
my @b = <2 12 18 10 8>;
say native_sum_two(@a, @b) # (3.2 14 21.2 20 8.33)
While preparing for passing arrays to C, I am converting each value of two arrays to Num (O(n) + O(n) time).
May be due to the overhead, I am not getting the speedup compared to the same thing in raku:
my @c;
for [email protected] {
    @c[$_] = @a[$_] + @b[$_];
}
say @c
                you can avoid creating the intermediate Num arrays and use the NativeCall CArray constructor with your original arrays directly.
sub native_sum_two(@arr_one is copy, @arr_two is copy) {
    my $elems = @arr_one.elems;
    # Create CArray directly from Raku arrays
    my $first = CArray[num64].new(@arr_one».Num);
    my $second = CArray[num64].new(@arr_two».Num);
    # Prepare for the return array
    my $return = CArray[num64].allocate($elems);
    # Call the C function
    c_sum_two($first, $second, $return, $elems);
    # Get the output back
    $return.list
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With