0

I have noticed that it is possible to create a borrowed/stolen reference to a (3D) numpy array of floats using PyArray_AsCArray as following:

...
float ***matrix_c;
npy_intp dims[3] = {X, Y, Z};
PyArray_Descr *descriptor = PyArray_DescrFromType(NPY_FLOAT32);
PyArray_AsCArray(&matrix_pyobject, (void **)&matrix_c, dims, 3, descriptor);
...

However, when doing this from different parts in the code with the intention of transferring the same array, this will not work for my case. I needed each of the transfers to give me a reference to the inner array, so I could work with the same addresses.

For this purpose I found out I could access the internal array without worrying about references using PyArray_DATA, nonetheless this gives a 1D flat view of the matrix as a void * referencing the first element of the matrix.

Is there any way in which I can get a reference to the internal array using this last call and still be able to work with the array as a 3D C array?

Pyramid
  • 31
  • 8
  • Is there a reason why you aren't using a 3D array in C, if that's what you actually need? – Lundin Jun 14 '19 at 11:24
  • The array I obtain comes from the Python-side of an application. I transfer a 3D Numpy array for heavy computation phases to C, access and modify it in C, and then continue the Python-part with the now-modified Numpy array. All this, without transferring data or making copies (thus why I need direct references) – Pyramid Jun 14 '19 at 12:31
  • https://stackoverflow.com/questions/15576136/passing-3-dimensional-numpy-array-to-c – Joe Jun 14 '19 at 13:11
  • https://stackoverflow.com/questions/51036850/get-pointer-from-numpy-array-to-send-image-to-c – Joe Jun 14 '19 at 13:11
  • https://stackoverflow.com/questions/14341549/passing-a-set-of-numpy-arrays-into-c-function-for-input-and-output – Joe Jun 14 '19 at 13:12
  • The first link uses borrowed references, which I want to avoid as I specified above. The third one uses ctypes, which I also want to avoid as I believe it should be possible to have python-floats + C-floats interactions without the need for an extra package from the python-side (I already use numpy for other things in the python-side). As for the second URL I believe this is what NumPy inherently uses, so this should be exposed somehow within the calls I mentioned above (correct me if I'm wrong, as I'm no expert in the internals of the NumPy-C API). – Pyramid Jun 14 '19 at 13:37
  • Wow... Python actually uses 3 star programming as back end, or is this numpy thing just yet another horrid open source lib? And then people wonder why Python is slow... – Lundin Jun 14 '19 at 14:06

1 Answers1

1

Found out quite an easy way to solve this, so I will post it just in case anyone else struggles with this.

I tried solving it through a pointer of 2D structures, but in the end, all which I needed was a cast to a pointer to 3D structures:

PyObject *matrix_object;
PyArg_ParseTuple(args, "O", &matrix_object);
float *matrix_c = (float *)PyArray_DATA((PyArrayObject *)matrix_object);
npy_intp *shape = PyArray_DIMS((PyArrayObject *)matrix_object);

// More code...
int numblocks = shape[0];
int blocksize = shape[1];
int elemsize  = shape[2];

float (*structured_matrix)[numblocks][blocksize][elemsize] = (float (*)[numblocks][blocksize][elemsize])matrix_c;

// Access structured_matrix as: structured_matrix[X][Y][Z]
Pyramid
  • 31
  • 8