使用cython和多线程提高python循环效率

时间:2016-11-30 15:20:41

标签: python multithreading numpy

我使用python和numpy用显式有限差分法(FDM)求解扩散方程。效率问题发生在for循环期间解决方程式,我找不到用numpy进行矢量化的方法。我用Google搜索,发现cython是其中一个解决方案。以下问题与cython和cython并行有关。

如果我希望代码更高效,我该怎么办?我尝试了cython并行,但是因为for循环中的代码不是纯粹的c类型,可能会出现gil问题。

我的代码看起来像吼叫:

import numpy as np
cimport numpy as np
cimport cython
import cython
from cython.parallel import prange, parallel


DTYPEFLOAT = np.float32
DTYPEINT8 = np.int8
DTYPEDOUBLE = np.double
ctypedef np.float32_t DTYPE_t
ctypedef np.double_t DTYPEDOUBLE_t
ctypedef np.int8_t DTYPEINT8_t

@cython.boundscheck(False)
@cython.wraparound(False)

cdef int[:, :] _MooreNeighborhood(int iN, int jN, int i0, int j0):
    cdef int[:,:] mOutput
    cdef unsigned int iU, iD, jL, jR

    mOutput = np.empty((8,2), dtype=np.int32)

    if i0 == 0:
        iD = iN-1
    else:
        iD = i0-1

    if i0 == iN-1:
        iU = 0
    else:
        iU = i0+1

    if j0 == 0:
        jL = jN-1
    else:
        jL = j0-1

    if j0 == jN-1:
        jR = 0
    else:
        jR = j0+1

    mOutput[0,0] = iD
    mOutput[0,1] = j0
    mOutput[1,0] = i0
    mOutput[1,1] = jR
    mOutput[2,0] = iU
    mOutput[2,1] = j0
    mOutput[3,0] = i0
    mOutput[3,1] = jL

    mOutput[4,0] = iD
    mOutput[4,1] = jR
    mOutput[5,0] = iU
    mOutput[5,1] = jR
    mOutput[6,0] = iU
    mOutput[6,1] = jL
    mOutput[7,0] = iD
    mOutput[7,1] = jL

    return mOutput

cpdef np.ndarray[DTYPEDOUBLE_t, ndim=2] _diffusionFD2(np.ndarray[DTYPEDOUBLE_t, ndim=2]  mInput, np.ndarray[DTYPEINT8_t, ndim=2]  mRegion,
                          double coeff_D, double delta_i, double delta_j, double delta_t):

cdef unsigned int iN, jN, i, j, iR, jR, iL, jL, iU, jU, iD, jD
cdef double cR, cL, cU, cD, cC

cdef np.ndarray[DTYPEDOUBLE_t, ndim=2] mOutput
cdef int[:, :] neighborhood

if not np.any(mRegion):
    return mInput

iN = mInput.shape[0]
jN = mInput.shape[1]

mOutput = np.copy(mInput)

for i in range(iN):
    for j in range(jN):
        if mRegion[i][j]:
            neighborhood = _MooreNeighborhood(iN, jN, i, j)
            cC = mInput[i,j]

            iR = neighborhood[1,0]
            jR = neighborhood[1,1]

            iL = neighborhood[3,0]
            jL = neighborhood[3,1]

            iD = neighborhood[0,0]
            jD = neighborhood[0,1]

            iU = neighborhood[2,0]
            jU = neighborhood[2,1]

            if not mRegion[iR,jR]:
                cR = cC
            else:
                cR = mInput[iR,jR]
            if not mRegion[iL,jL]:
                cL = cC
            else:
                cL = mInput[iL,jL]
            if not mRegion[iU,jU]:
                cU = cC
            else:
                cU = mInput[iU,jU]
            if not mRegion[iD,jD]:
                cD = cC
            else:
                cD = mInput[iD,jD]

            mOutput[i,j] = cC+coeff_D*delta_t*((cU + cD - 2*cC)/(delta_i**2) + (cR + cL - 2*cC)/(delta_j**2))

return mOutput

0 个答案:

没有答案
相关问题