Rust returning SISGEV on large operation (C++ static lib)

I tried to summarize the whole situation in the title but the thing is that I need rust as lib to perform an array multiplication calling it from C++, and it works fine, but if I increase the size up to 1024 x 1024 (i64) rust crashes immediately.

The matrices are harcoded in a C file, there are A, B and Result matrices (to check the result).
I'm using flat matrices with an inline "index" function to access them like index(i,j).
The matrices are inside the "InputVectorType" as a struct, and all structs are inside an array (defined in C headers).
The code doesn't fail if I comment line 53 (Res[ii * SIZE + jj] += aux; //FAILS) or if the size is smaller.

Here is my

pub const SIZE:usize = 1024;
pub const BLOCK_SIZE:usize = SIZE;//8-128

fn index(i: usize, j: usize) -> usize {
    i * SIZE + j

pub struct InputVectorType {
    pub AMatrix: [i64;SIZE*SIZE],
    pub BMatrix: [i64;SIZE*SIZE],
    pub RMatrix: [i64;SIZE*SIZE],
pub struct OutputVectorType {
    pub errors: i64,

pub extern "C" fn rust_function(
    input_vector: *const InputVectorType,
    output_vector: *mut OutputVectorType,
) {
    if input_vector.is_null() || output_vector.is_null() {

    let A:[i64; SIZE*SIZE];
    let B:[i64; SIZE*SIZE];
    let GOLD:[i64; SIZE*SIZE];
    let mut Res:[i64; SIZE*SIZE] = [0;SIZE*SIZE];

        A = (*input_vector).AMatrix;
        B = (*input_vector).BMatrix;
        GOLD = (*input_vector).RMatrix;
    Res.iter_mut().for_each(|e| *e = 0);

    for i in (0..SIZE).step_by(BLOCK_SIZE) {
        for j in (0..SIZE).step_by(BLOCK_SIZE) {
            for k in (0..SIZE).step_by(BLOCK_SIZE) {
                // Multiply blocks
                for ii in i..(i+BLOCK_SIZE) {
                    for jj in j..(j+BLOCK_SIZE) {
                        let mut aux = 0;
                        for kk in k..(k+BLOCK_SIZE) {
                            aux += A[index(ii, kk)] * B[index(kk, jj)];
                        //println!("{}",ii*SIZE+jj); //Good
                        Res[ii * SIZE + jj] += aux; //FAILS
    let res = Res[4];
    unsafe {
        (*output_vector).errors = res;

Thank you in advance.

My best guess is that you’re getting something like a stack overflow: If you never write into Res, the optimizer can spot that and skip the allocation.


You are storing 8MB of arrays on the stack, are you sure it's big enough for them?


In any case, it’s probably better to read from the input vectors directly instead of copying them onto the stack first:

-    let A:[i64; SIZE*SIZE];
-    let B:[i64; SIZE*SIZE];
-    let GOLD:[i64; SIZE*SIZE];
+    let A:&[i64; SIZE*SIZE];
+    let B:&[i64; SIZE*SIZE];
+    let GOLD:&[i64; SIZE*SIZE];
     let mut Res:[i64; SIZE*SIZE] = [0;SIZE*SIZE];

-        A = (*input_vector).AMatrix;
-        B = (*input_vector).BMatrix;
-        GOLD = (*input_vector).RMatrix;
+        A = &(*input_vector).AMatrix;
+        B = &(*input_vector).BMatrix;
+        GOLD = &(*input_vector).RMatrix;
1 Like

This explains the strange behavior. Thank you :slight_smile:

That's true, I like the idea but I did the changes to the and it didn't fix it. Maybe I need to change anything more?

Should I dereference the A and B pointers in the multiplication? (Althoug rust should do it automatically)

Or I'll have to box the slice maybe

As everybody guessed it was a stack overflow, I fixed it using Box on the Res array and adding the changes from 2e71828.

Thank you fr your help :3

1 Like