Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrapping C function in Cython and NumPy

I'd like to call my C function from Python, in order to manipulate some NumPy arrays. The function is like this:

void c_func(int *in_array, int n, int *out_array);

where the results are supplied in out_array, whose size I know in advance (not my function, actually). I try to do in the corresponding .pyx file the following, in order to able to pass the input to the function from a NumPy array, and store the result in a NumPy array:

def pyfunc(np.ndarray[np.int32_t, ndim=1] in_array):    
    n = len(in_array)
    out_array = np.zeros((512,), dtype = np.int32)
    mymodule.c_func(<int *> in_array.data, n, <int *> out_array.data)
    return out_array

But I get "Python objects cannot be cast to pointers of primitive types" error for the output assignment. How do I accomplish this?

(If I require that the Python caller allocates the proper output array, then I can do

def pyfunc(np.ndarray[np.int32_t, ndim=1] in_array, np.ndarray[np.int32_t, ndim=1] out_array):  
    n = len(in_array)
    mymodule.cfunc(<int *> in_array.data, n, <int*> out_array.data)

But can I do this in a way that the caller doesn't have to pre-allocate the appropriately sized output array?

like image 287
Peter Avatar asked Apr 08 '12 03:04

Peter


People also ask

Is Cython compatible with NumPy?

You can use NumPy from Cython exactly the same as in regular Python, but by doing so you are losing potentially high speedups because Cython has support for fast access to NumPy arrays.

Does Cython generate C code?

You need to add this path only if you use cimport numpy . With older Cython releases, setting this macro will fail the C compilation, because Cython generates code that uses this deprecated C-API.

Does Cython use C or C++?

Cython can call into both C and C++ code, and even subclass C++ classes.


1 Answers

You should add cdef np.ndarray before the out_array assignement:

def pyfunc(np.ndarray[np.int32_t, ndim=1] in_array):    
    cdef np.ndarray out_array = np.zeros((512,), dtype = np.int32)
    n = len(in_array)
    mymodule.c_func(<int *> in_array.data, n, <int *> out_array.data)
    return out_array
like image 149
Simon Bergot Avatar answered Sep 28 '22 03:09

Simon Bergot