私はcythonで単純な補間関数を書いて、他のcythonコードから(たくさんの)呼び出されます。パラメータの1つがnumpyの配列です:numpy配列のCythonオーバヘッド
@cython.boundscheck(False)
@cython.cdivision(True)
@cython.wraparound(False)
cdef double interpU_cython(double kX,double kY,int iX,int iY, int iTheta,int nbX,int nbY,np.ndarray[double, ndim=3] u, double outVal):
cdef double uPt, u0, u1
if (iX >= 0 and iY >= 0 and iX < nbX-1 and iY < nbY-1):
u0 = u[iX,iY,iTheta] + (u[iX+1,iY,iTheta]-u[iX,iY,iTheta]) * kX
u1 = u[iX,iY+1,iTheta] + (u[iX+1,iY+1,iTheta]-u[iX,iY+1,iTheta]) * kX
uPt = u0 + (u1-u0) * kY
else:
uPt = outVal
return uPt
私は-a cython とPythonの呼び出しをチェックし、関数呼び出しがいくつかのPythonの呼び出しに依存しているように見えます:
+01: cimport cython
02: cimport numpy as np
+03: import numpy as np
04:
05: @cython.boundscheck(False)
06: @cython.cdivision(True)
07: @cython.wraparound(False)
+08: cdef double interpU_cython(double kX,double kY,int iX,int iY, int iTheta,int nbX,int nbY,np.ndarray[double, ndim=3] u, double outVal):
static double __pyx_f_10FSM_cython_interpU_cython(double __pyx_v_kX, double __pyx_v_kY, int __pyx_v_iX, int __pyx_v_iY, int __pyx_v_iTheta, int __pyx_v_nbX, int __pyx_v_nbY, PyArrayObject *__pyx_v_u, double __pyx_v_outVal) {
double __pyx_v_uPt;
double __pyx_v_u0;
double __pyx_v_u1;
__Pyx_LocalBuf_ND __pyx_pybuffernd_u;
__Pyx_Buffer __pyx_pybuffer_u;
double __pyx_r;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("interpU_cython", 0);
__pyx_pybuffer_u.pybuffer.buf = NULL;
__pyx_pybuffer_u.refcount = 0;
__pyx_pybuffernd_u.data = NULL;
__pyx_pybuffernd_u.rcbuffer = &__pyx_pybuffer_u;
{
__Pyx_BufFmt_StackElem __pyx_stack[1];
if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_u.rcbuffer->pybuffer, (PyObject*)__pyx_v_u, &__Pyx_TypeInfo_double, PyBUF_FORMAT| PyBUF_STRIDES, 3, 0, __pyx_stack) == -1)) __PYX_ERR(0, 8, __pyx_L1_error)
}
__pyx_pybuffernd_u.diminfo[0].strides = __pyx_pybuffernd_u.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_u.diminfo[0].shape = __pyx_pybuffernd_u.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_u.diminfo[1].strides = __pyx_pybuffernd_u.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_u.diminfo[1].shape = __pyx_pybuffernd_u.rcbuffer->pybuffer.shape[1]; __pyx_pybuffernd_u.diminfo[2].strides = __pyx_pybuffernd_u.rcbuffer->pybuffer.strides[2]; __pyx_pybuffernd_u.diminfo[2].shape = __pyx_pybuffernd_u.rcbuffer->pybuffer.shape[2];
/* … */
/* function exit code */
__pyx_L1_error:;
{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
__Pyx_PyThreadState_declare
__Pyx_PyThreadState_assign
__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_u.rcbuffer->pybuffer);
__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
__Pyx_WriteUnraisable("FSM_cython.interpU_cython", __pyx_clineno, __pyx_lineno, __pyx_filename, 0, 0);
__pyx_r = 0;
goto __pyx_L2;
__pyx_L0:;
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_u.rcbuffer->pybuffer);
__pyx_L2:;
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
09: cdef double uPt, u0, u1
+10: if (iX >= 0 and iY >= 0 and iX < nbX-1 and iY < nbY-1):
+11: u0 = u[iX,iY,iTheta] + (u[iX+1,iY,iTheta]-u[iX,iY,iTheta]) * kX
+12: u1 = u[iX,iY+1,iTheta] + (u[iX+1,iY+1,iTheta]-u[iX,iY+1,iTheta]) * kX
+13: uPt = u0 + (u1-u0) * kY
14: else:
+15: uPt = outVal
+16: return uPt
がありますかなりのオーバーヘッドなしでnumpy配列を渡して使用するための効率的な方法、またはコードのコンパイルされた部分にあるすべてのものに対してc配列を使うだけですか?
numpy配列の最初の要素へのポインタを使用し、配列サイズをパラメータに追加して1次元配列として使用するのは安全ですか?
おかげ