Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing Numpy arrays to C code wrapped with Cython

I have a small bit of existing C code that I want to wrap using Cython. I want to be able to set up a number of numpy arrays, and then pass those arrays as arguments to the C code whose functions take standard c arrays (1d and 2d). I'm a little stuck in terms of figuring out how to write the proper .pyx code to properly handle things.

There are a handful of functions, but a typical function in the file funcs.h looks something like:

double InnerProduct(double *A, double **coords1, double **coords2, const int len)

I then have a .pyx file that has a corresponding line:

cdef extern from "funcs.h":
    double InnerProduct(double *A, double **coords1, double **coords2, int len)

where I got rid of the const because cython doesn't support it. Where I'm stuck is what the wrapper code should then look like to pass a MxN numpy array to the **coords1 and **coords2 arguments.

I've struggled to find the correct documentation or tutorials for this type of problem. Any suggestions would be most appreciated.

like image 944
JoshAdel Avatar asked Dec 21 '10 00:12

JoshAdel


1 Answers

You probably want Cython's "typed memoryviews" feature, which you can read about in full gory detail here. This is basically the newer, more unified way to work with numpy or other arrays. These can be exposed in Python-land as numpy arrays, or you can export them to Python (for example, here). You have to pay attention to how the striding works and make sure you're consistent about e.g. C-contiguous vs. FORTRAN-like arrays, but the docs are pretty clear on how to do that.

Without knowing a bit more about your function it's hard to be more concrete on exactly the best way to do this - i.e., is the C function read-only for the arrays? (I think yes based on the signature you gave, but am not 100% sure.) If so you don't need to worry about making copies if needed to get C-contiguous states, because the C function doesn't need to talk back to the Python-level numpy array. But typed memoryviews will let you do any of this with a minimum of fuss.

like image 146
eteq Avatar answered Oct 23 '22 18:10

eteq