2016-06-07 154 views
0

我真的很想用使用Cython的openmp來運行scipy.interpolation.RectBivariateSpline.ev函數。樣條函數的評估函數現在是我的代碼中待優化的最後一個瓶頸。作爲一個權宜之計,我正在使用Python的multiprocessing包來對大型座標數組進行評估......但出於以下原因,我們需要從multiprocessing包中移開。在Cython中使用openmp調用Scipy的RectBivariateSpline評估函數

我將Fortran bisplev函數重構爲C之前的最後一站,然後使用Cython進行打包,嘗試使用openmp和Cython來包裝Scipy scipy.interpolate._fitpack._bisplev函數。

正如我所料(但希望情況並非如此),_bisplev是一個Python對象,而不是cdef d,在Cython中不能用nogil調用。我看過但找不到_bisplev的源代碼,但我現在想象它是某種Fortran-C-Python界面。 (對於我來說,這是一個令人髮指的聲明,因爲我不知道它是什麼)。

如果有人對我可以從哪裏出發有什麼建議......特別是在不使用Python multiprocessing的情況下並行調用scipy.interpolation.RectBivariateSpline.ev的最佳方式,我將不勝感激。任何其他提示或推動正確的方向也將不勝感激。

我在做(幼稚)用Cython包裝爲bispev的意圖使用OpenMP ::

interp2_fastev.pyx

import numpy as np 
cimport numpy as np 
from scipy.interpolate._fitpack import _bispev 

def ev(double[:] x, double[:] y, double[:] ty, int kx, int ky, double[:] tx, double[:] c): 
    cdef int ckx 
    cdef int cky 
    ckx = kx 
    cky = ky 

    with nogil: 
     _bispev(tx, ty, c, kx, ky, x, y, 0, 0) 

我打算最終使用prange環路並行首次嘗試,但如果我甚至不能撥打_bispevnogil,那不是一個選項。

回答

1

_fitpack是經過編譯的文件(的.so):/scipy/interpolate/_fitpack.cpython-35m-i386-linux-gnu.so

搜索上github我發現

scipy/scipy/interpolate/src/_fitpackmodule.c 
scipy/scipy/interpolate/src/__fitpack.h 

第二屆有這似乎照顧的的

static char doc_bispev[] = " [z,ier] = _bispev(tx,ty,c,kx,ky,x,y,nux,nuy)"; 
fitpack_bispev(PyObject *dummy, PyObject *args) 

定義內存分配和調用Fortran:

BISPEV(tx, &nx, ty, &ny, c, &kx, &ky, x, &mx, y, &my, z, wrk, &lwrk, 
      iwrk, &kwrk, &ier); 

與Fortran代碼:

scipy/scipy/interpolate/src/fitpack.pyf 
+0

實際上有兩個獨立的擴展,'_fitpack'和'dftitpack'。 'fitpackmodule.c'和'__fitpack.h'是第一個,'dftipack'是從'pyf'包裝器創建的https://github.com/scipy/scipy/blob/master/scipy/interpolate/setup .py#L25 –

+0

'bispev'似乎來自'dfitpack',所以'__fitpack.h'和'fitpackmodule.c'對於這個特定的問題是無關緊要的。 (是的,這是一團糟) –

+0

此外,要釋放GIL,您可能需要一個最近足夠的scipy:pyf包裝僅被標記爲scipy 0.17 IIRC的線程安全。 –