python - Passing and returning numpy arrays to C++ methods via Cython -


there lots of questions using numpy in cython on site, particularly useful 1 being simple wrapping of c code cython.

however, cython/numpy interface api seems have changed bit, in particular ensuring passing of memory-contiguous arrays.

what best way write wrapper function in cython that:

  • takes numpy array not contiguous
  • calls c++ class method signature double* data_in, double* data_out
  • returns numpy array of double* method wrote to?

my try below:

cimport numpy np import numpy np # suggested jorgeca  cdef extern "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 not optimal. have suggestions on improving snippet above?

and (2) throws , "np not defined on line x_c = ...") when calling @ runtime. exact testing code , error message following:

import numpy np import mywrapper mywrapper.run(np.array([[1,2],[3,4]], dtype=np.double))  # nameerror: name 'np' not defined [at mywrapper.pyx":x_c = ...] # fixed! 

you've got right. first, optimization shouldn't big deal. ideally, of time spent inside c++ kernel, not in cythnon wrapper code.

there few stylistic changes can make simplify code. (1) reshaping between 1d , 2d arrays not necessary. when know memory layout of data (c-order vs. fortran order, striding, etc), can see array chunk of memory you're going index in c++, numpy's ndim doesn't matter on c++ side -- it's seeing pointer. (2) using cython's address-of operator &, can pointer start of array in little cleaner way -- no explicit cast necessary -- using &x[0,0].

so edited version of original snippet:

cimport numpy np import numpy np  cdef extern "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):     x = np.ascontiguousarray(x)     cdef np.ndarray[np.double_t, ndim=2, mode="c"] y = np.zeros_like(x)      cdef myclass myclass     myclass = myclass()     myclass.run(&x[0,0], x.shape[0], x.shape[1], &y[0,0])      return y 

Comments

Popular posts from this blog

php - get table cell data from and place a copy in another table -

javascript - Mootools wait with Fx.Morph start -

php - Navigate throught databse rows -