Reputation: 7581
Below is a Minimum(?) Reproducible Example of my code. It is a first pass at stress testing / benchmarking the WIP Raku Module Dan::Polars.
In Rust, I make a libmre.so with this code
1 use libc::c_char;
2 use libc::size_t;
3 use std::slice;
4 use std::ffi::*; //{CStr, CString,}
5
6 // Container
7
8 pub struct VecC {
9 ve: Vec::<String>,
10 }
11
12 impl VecC {
13 fn new(data: Vec::<String>) -> VecC
14 {
15 VecC {
16 ve: data,
17 }
18 }
19
20 fn show(&self) {
21 println!{"{:?}", self.ve};
22 }
23 }
24
25 #[no_mangle]
26 pub extern "C" fn ve_new_str(ptr: *const *const c_char, len: size_t)
27 -> *mut VecC {
28
29 let mut ve_data = Vec::<String>::new();
30 unsafe {
31 assert!(!ptr.is_null());
32
33 for item in slice::from_raw_parts(ptr, len as usize) {
34 ve_data.push(CStr::from_ptr(*item).to_string_lossy().into_owned());
35 };
36 };
37
38 Box::into_raw(Box::new(VecC::new(ve_data)))
39 }
40
41 #[no_mangle]
42 pub extern "C" fn ve_show(ptr: *mut VecC) {
43 let ve_c = unsafe {
44 assert!(!ptr.is_null());
45 &mut *ptr
46 };
47
48 ve_c.show();
49 }
and this Cargo.toml
1 [package]
2 name = "mre"
3 version = "0.1.0"
4 edition = "2021"
5
6 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7
8 [dependencies]
9 libc = "0.2.126"
10
11 [lib]
12 name = "mre"
13 path = "src/lib.rs"
14 crate-type = ["cdylib"]
In Raku, I consume libmre.so like this
1 #!/usr/bin/env raku
2 use lib '../lib';
3
4 use NativeCall;
5
6 #my $output; #mre tried to move decl to here to avoid going out of scope
7 sub carray( $dtype, @items ) {
8 my $output := CArray[$dtype].new();
9 loop ( my $i = 0; $i < @items; $i++ ) {
10 $output[$i] = @items[$i]
11 }
12 say $output;
13 $output
14 }
15
16 ### Container Classes that interface to Rust lib.rs ###
17
18 constant $n-path = '../mre/target/debug/mre';
19
20 class VecC is repr('CPointer') is export {
21 sub ve_new_str(CArray[Str],size_t) returns VecC is native($n-path) { * }
22 sub ve_show(VecC) is native($n-path) { * }
23
24 method new(@data) {
25 ve_new_str(carray(Str, @data), @data.elems );
26 }
27
28 method show {
29 ve_show(self)
30 }
31 }
32
33 my \N = 100; #should be 2e9 #fails between 30 and 100
34 my \K = 100;
35
36 sub randChar(\f, \numGrp, \N) {
37 my @things = [sprintf(f, $_) for 1..numGrp];
38 @things[[1..numGrp].roll(N)];
39 }
40
41 my @data = [randChar("id%03d", K, N)];
42
43 my $vec = VecC.new( @data );
44 $vec.show;
When \N is <30 this runs fine with output like this:
NativeCall::Types::CArray[Str].new
["id098", "id035", "id024", "id067", "id051", "id025", "id024", "id092", "id044", "id042", "id033", "id004", "id100", "id091", "id087", "id059", "id031", "id063", "id019", "id035"]
When \N is > 50 however, I get:
NativeCall::Types::CArray[Str].new
Segmentation fault (core dumped)
This is:
Welcome to Rakudo™ v2022.04.
Implementing the Raku® Programming Language v6.d.
Built on MoarVM version 2022.04.
on ubuntu
Since the benchmark calls for \N to be 2e9, I could use some help to try and resolve this.
You are welcome to use p6steve/raku-dan:polars-2022.02-arm64 (or -amd64) on Docker Hub if you would like to try this at home. Don't forget to go cargo build
first time. This includes RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | bash -s -- -y
Upvotes: 6
Views: 164
Reputation: 1135
There's a off by one bug in randChar
function
sub randChar(\f, \numGrp, \N) {
my @things = [sprintf(f, $_) for 1..numGrp];
@things[[1..numGrp].roll(N)];
}
You're indexing the @things
array with indexes from 1
to numGrp
, but the biggest index of @things
is numGrp - 1
. So sometimes there's a (Any)
instead of a string in one (or more) of the elements of the returned array.
What you want is this:
sub randChar(\f, \numGrp, \N) {
my @things = [sprintf(f, $_) for 1..numGrp];
@things.roll(N); # call roll directly on @things
}
Upvotes: 7