There are lots of questions about using numpy in cython on this site, a particularly useful one being Simple wrapping of C code with cython.
However, the cython/numpy interface api seems to have changed a bit, in particular with ensuring the passing of memory-contiguous arrays.
What is the best way to write a wrapper function in cython that:
- takes a numpy array that is likely but not necessarily contiguous
- calls a C++ class method with the signature
double* data_in, double* data_out
- returns a numpy array of the
double*
that the method wrote to?
My try is below:
cimport numpy as np
import numpy as np # as suggested by jorgeca
cdef extern from "myclass.h":
cdef cppclass MyClass:
MyClass() except +
void run(double* X, int N, int D, double* Y)
def run(np.ndarray[np.double_t, ndim=2] X):
cdef int N, D
N = X.shape[0]
D = X.shape[1]
cdef np.ndarray[np.double_t, ndim=1, mode="c"] X_c
X_c = np.ascontiguousarray(X, dtype=np.double)
cdef np.ndarray[np.double_t, ndim=1, mode="c"] Y_c
Y_c = np.ascontiguousarray(np.zeros((N*D,)), dtype=np.double)
cdef MyClass myclass
myclass = MyClass()
myclass.run(<double*> X_c.data, N, D, <double*> Y_c.data)
return Y_c.reshape(N, 2)
This code compiles but is not necessarily optimal. Do you have any suggestions on improving the snippet above?
and (2) throws and "np is not defined on line X_c = ...
") when calling it at runtime.
The exact testing code and error message are the following:
import numpy as np
import mywrapper
mywrapper.run(np.array([[1,2],[3,4]], dtype=np.double))
# NameError: name 'np' is not defined [at mywrapper.pyx":X_c = ...]
# fixed!