how to pass numpy array to Cython function correctly?

匿名 (未验证) 提交于 2019-12-03 02:06:01

问题:

This is described in many places but i simply cannot get it to work. I am calling a C++ function from Cython:

cimport numpy as np cdef extern from "test.h" namespace "mytest":    void test(double *A, int m)  cdef int foo():   cdef np.ndarray[double,mode="c"] a = np.array([1,2,3,4,5],dtype=float)   # pass ptr to first element of 'a'   test(&a[0], len(a))   return 0  foo()

test.cpp is just:

#include  namespace mytest {     void test(double *A, int m)     {     for (int i = 0; i 

test.h just has:

namespace mytest {   void test(double *A, int m); }

This seems to work but when is np.ascontiguousarray needed? Is it sufficient to do:

cdef np.ndarray[double,mode="c"] a = np.array([1,2,3,4,5],dtype=float)

or do you need:

cdef np.ndarray[double,mode="c"] a = np.ascontiguousarray(np.array([1,2,3,4,5],dtype=float))

second and more importantly, how can this generalize to 2d arrays?

Handling 2d arrays

Here is my attempt at passing 2d numpy arrays to C++ which does not work:

cdef np.ndarray[double,mode="c",ndim=2] a = np.array([[1,2],[3,4]],dtype=float)

which is called as:

test(&a[0,0], a.shape[0], a.shape[1])

in the cpp code:

void test(double *A, int m, int n)  {    printf("reference 0,0 element\n");   printf("%f\n", A[0][0]); }

UPDATE: The correct answer

The correct answer is to use linear indexing for the array and not the [][] syntax. The correct way to print the 2d array is:

for (int i = 0; i 

回答1:

For 2D arrays, you just need the ndim keyword:

cdef np.ndarray[double, mode="c", ndim=2]

The result may or may not share memory with the original. If it shares memory with the original, then the array may not be contiguous, or may have an unusual striding configuration. In this case, passing the buffer to C/C++ directly will be disastrous.

You should always use ascontiguousarray unless your C/C++ code is prepared to deal with non-contiguous data (in which case you will need to pass in all relevant stride data from Cython into the C function). If the input array is already contiguous, no copy will be made. Make sure to pass a compatible dtype to ascontiguousarray so that you don't risk a second copy (e.g. having to convert from a contiguous float array to a contiguous double array).



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!