我不確定這是否已被解決以前,我試過搜索,但沒有找到我正在尋找什麼。我想獲得下面的代碼工作(文件是some_CD.pyx名)與Openmp的Cython numpy陣列(沒有GIL)
import numpy as np
cimport numpy as np
cimport cython
from cython.parallel import *
ctypedef np.float64_t DTYPE
cdef DTYPE evaluate_objective(np.ndarray[DTYPE, ndim=2] A,np.ndarray[DTYPE, ndim=1] b,np.ndarray[DTYPE, ndim=1] x):
return x.dot(A.dot(x) - b.dot(x))
cpdef DTYPE coordinate_descent(np.ndarray[DTYPE, ndim=2] A,np.ndarray[DTYPE, ndim=1] b,int nDim, int nIter):
cdef int i, iter
cdef np.ndarray[DTYPE,
ndim=1] x = \
np.zeros(nDim,)
cdef DTYPE temp
for iter in prange(nIter,nogil=True):
i = (iter%nDim)
temp = (b[i]-(A[:,i].dot(x)*x[i]) + (A[i,i]*x[i]*x[i]))/A[i,i]
x[i] = np.max([0,np.min([temp,1])])
return evaluate_objective(A,b,x)
我setup.py看起來如下
from distutils.core import setup, Extension
from Cython.Build import cythonize
import numpy
ext_modules = [
Extension(
"some_CD",
["some_CD.pyx"],
extra_compile_args=['-fopenmp'],
extra_link_args=['-fopenmp'],
)
]
setup(
name='some_parallel',
ext_modules=cythonize(ext_modules),
include_dirs=[numpy.get_include()]
)
有很多事情我不知道這個代碼。首先,我是否以正確的方式使用numpy數組?是否在prange中使用float64,np.int類型的變量?
不幸的是,你不能在nogil上下文中使用numpy數組,因爲它們本身就是python對象。這個問題也困擾了我一段時間,雖然我沒有寫出自己解決問題的東西,但是我正在瀏覽sklearn的sourcode,看起來他們在進入nogil環境之前會將其數據記錄到他們的ndarrays中。這應該讓你進入一個純粹的C語境,你可以用prange來使用nogil。 – Erotemic
複製整個陣列特別是在大尺寸時是不是很費時間?有沒有什麼有效的方法?如果可能,你可以修改代碼作爲答案嗎?花費相當長的時間才能瞭解正確的語法和所有! – user52705