Skip to content Skip to sidebar Skip to footer

Segfault When Trying To Write To A Numpy Array Created Within A C Extension

I have an if clause within a for loop in which I have defined state_out beforehand with: state_out = (PyArrayObject *) PyArray_FromDims(1,dims_new,NPY_BOOL); And the if conditions

Solution 1:

if (conn_ctr<sum*2){
        *(state_out->data + i*state_out->strides[0]) =  true;
    }
    else {
        *(state_out->data + i*state_out->strides[0]) =  false;
    }

Here, I naively make a pointer arithmetic, state_out->data is a pointer to the beginning of data, it is defined to be a pointer of char:SciPy Doc - Python Types and C-Structures

typedefstructPyArrayObject {
    PyObject_HEAD
    char *data;
    int nd;
    npy_intp *dimensions;
    npy_intp *strides;
    ...
} PyArrayObject;

Which a portion of I copied here. state_out->strides is a pointer to an array of length of the dimension of the array we have. This is a 1d array in this case. So when I make the pointer arithmetic (state_out->data + i*state_out->strides[0]) I certainly aim to calculate the pointer that points the ith value of the array, but I failed to give the type of the pointer, so the

I had tried :

NPY_BOOL *adj_value_ptr, *mask_value_ptr, *state_value_ptr, *state_out_ptr;

which the variables are pointing towards the values that I am interested in my for loop, and state_out_ptr is the one that I am writing to. I had thought that since I state that the constituents of these arrays are of type NPY_BOOL, the pointers that point to the data within the array would be of type NPY_BOOL also. This fails with a SegFault when one is working with data directly manipulating the memory. This is from the fact that NPY_BOOL is an enum for an integer (as pv kindly stated in the comments.) for NumPy to use internally,.There is a C typedefnpy_bool in order to use within the code for boolean values.Scipy Docs. When I introduced my pointers with the type

npy_bool *adj_value_ptr, *mask_value_ptr, *state_value_ptr, *state_out_ptr;

Segmentation fault disappeared, and I succeeded in manipulating and returning a Numpy Array.

I'm not an expert, but this solved my issue, point out if I'm wrong.

The part that has changed in the source code is:

state_out = (PyArrayObject *) PyArray_FromDims(1,dims_new,NPY_BOOL);

npy_bool *adj_value_ptr, *mask_value_ptr, *state_value_ptr, *state_out_ptr;
npy_intp i,j;

for(i=0;i<dims[0];i++){
    npy_int sum = 0;
    npy_int conn_ctr = 0;

        for(j=0;j<dims[1];j++){

            adj_value_ptr = (adjacency_arr->data + i*adjacency_arr->strides[0]
                     +j*adjacency_arr->strides[1]);

            if (*adj_value_ptr == true){

                mask_value_ptr = (mask_arr->data + i*mask_arr->strides[0]
                +j*mask_arr->strides[1]);

                state_value_ptr = (state_arr->data + j*state_arr->strides[0]);

                if ( (*(bool *) mask_value_ptr ^ *(bool *)state_value_ptr) ==  true){
                    sum++;
                }
                conn_ctr++;
            }
        }
        state_out_ptr = (state_out->data + i*state_out->strides[0]);
        if (conn_ctr < sum*2){
            *state_out_ptr =  true;
        }
        else {
            *state_out_ptr =  false;
        }
}

Post a Comment for "Segfault When Trying To Write To A Numpy Array Created Within A C Extension"