Return A 2d Cython Pointer To Python Array
Solution 1:
As soon as you use int**
(or similar) your data is in so-called indirect memory layout. Cython's typed memory views support indirect memory layout (see for example Cython: understanding a typed memoryview with a indirect_contignuous memory layout), however there are not so many classes implementing this interface.
Numpy's ndarrays do not implement indirect memory layout - they only support direct memory layouts (e.g. pointer of type int*
and not int**
), so passing an int**
to a numpy array will do no good.
The good thing is, that because you share the memory with a_cython
, the values were already updated in-place. You can get the underlying numpy array by returning the base
-object of the typed memory view, i.e.
return a_cython.base# returns 2d-numpy array.
there is no need to copy memory at all!
There are however some issues with memory management (e.g. you need to free point_to_a
).
This is maybe an overkill in your case, but I use the opportunity to shamelessly plug-in a library of mine indirect_buffer
: Because alternatives for indirect memory layout buffers are scarce and from time to time one needs one, I've create one to avoid writing always the same code.
With indirect_buffer
your function could look like following:
%%cython
#just an example for a c-function
cdefexternfrom *:
"""
void fillit(int** ptr, int N, int M){
int cnt=0;
for(int i=0;i<N;i++){
for(int j=0;j<M;j++){
ptr[i][j]=cnt++;
}
}
}
"""
void fillit(int** ptr, int N, int M)
from indirect_buffer.buffer_impl cimport IndirectMemory2D
defpy_fillit(a):
#create collection, it is a view of a
indirect_view=IndirectMemory2D.cy_view_from_rows(a, readonly=False)
fillit(<int**>indirect_view.ptr, indirect_view.shape[0], indirect_view.shape[1])
# values are updated directly in a
which now can be used, for example:
import numpy as np
a=np.zeros((3,4), dtype=np.int32)
py_fillit(a)
print(a)
# prints as expected:# array([[ 0, 1, 2, 3],# [ 4, 5, 6, 7],# [ 8, 9, 10, 11]])
The above version does a lot of things right: memory management, locking of buffers and so on.
Post a Comment for "Return A 2d Cython Pointer To Python Array"