2014-07-21 48 views
1

通过numpy的阵列我想了解这是访问与NumPy阵列通过用Cython传递给C代码最快最安全的方式。 我有以下文件:如何访问通过用Cython

func.c:

typedef struct { 
    int nr;     
    double *my_array;  
} my_struct; 

my_struct grid; 

void allocate(int n) { 
    grid.nr = n; 
    grid.my_array = (double*)malloc(grid.nr*sizeof(double)); 
} 

void Cfunc1(double *array) { 
    my_array = array; 

    //e.g. operation on my_array.. 
    for (int i=0; i<n; i++) my_array[i] *= 0.1; 
} 

void Cfunc2(int n, double *array) { 
    for (int i=0; i<n; i++) { 
     my_array[i] = array[i]; 

    //e.g. operation on my_array.. 
    for (int i=0; i<n; i++) my_array[i] *= 0.1; 

} 

func_wrap.pyx:

cdef extern from "func.h": 
    void myfunc1(double *) 
    void myfunc2(int, double *) 
    void allocate(int) 

def pyfunc1(int n, double[:] array): 
    allocate(n) 
    Cfunc1(&array[0]) 

def pyfunc2(int n, double[:] array): 
    allocate(n) 
    Cfunc2(n, &array[0]) 

setup.py:

from distutils.core import setup 
from distutils.extension import Extension 
from Cython.Distutils import build_ext 
import distutils 
setup(cmdclass = {'build_ext': build_ext}, ext_modules = [Extension("func", ["func.c"])]) 

func.so生产用:

python setup.py build_ext --inplace 

py_func.py:

import numpy 
import func 

arr = numpy.random.randn(10) 
func.pyfunc1(arr) # or func.pyfunc2(len(arr), arr) 

一些问题:

  1. 它是更快地使用Cfunc1()Cfunc2()

  2. 使用Cfunc2意味着数据被复制?你会用哪一个?

  3. 从理论上说,我会说,Cfunc1不需要的my_array以前malloc,而Cfunc2应该需要它。相反,这两个功能似乎没有malloc,你能告诉我为什么吗?

非常感谢!

+1

1)你告诉我! 'timeit'是你的朋友...... 2)这取决于'pyfunc'的作用(你需要修改'array'吗?你想修改它吗?)3)你能告诉我们你声明'my_array'的位置吗? –

回答

0

你的问题归结为“当我将数组传递给C代码时,是否需要复制数组的内容”。答案是否定的,但在某些情况下你可能会想。主要是当你想修改内容时不会中断原始数组。在某些情况下,在对数据运行计算密集型算法之前,将非连续阵列复制到连续阵列可能会很有用。这就是说,你当前的代码假设数据已经是连续的,所以在非连续的情况下,它只会给出错误的结果,复制或不复制。

如果你要使用指针访问numpy数组,你几乎总是想使用double[::1]而不是double[:],这样cython就会插入一个错误检查步骤来确保数组是连续的。

此外,如果您要将numpy数组的内容复制到其他数据结构(即c数组或malloc内存块),您需要声明/分配足够的内存才能完成此操作。没有看到my_array是如何声明和分配的,没有办法知道你的代码是如何工作的,但是内存必须被分配到某个地方。

+0

我以前用my_array =(double *)malloc((n)* sizeof(double))分配my_array。 my_array属于全局定义的结构,但我不想添加此详细信息以使问题更一般化。假设我有许多my_array,其中一些将在C中以只读方式使用,而另一些将用于将值返回给Python脚本。我应该为他们采取不同的行为吗? – mtazzari

+0

@mtazzari,你需要更具体。不知道你想要达到什么目标,很难提出任何建议。 –

+0

我编辑我的原始问题是更具体。 – mtazzari