2014-07-21 69 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