我有以下代码,我正在尝试并行化。描述如下:
# cython: boundscheck=False
# cython: wraparound=False
# cython: cdivision=True
cimport cython
import numpy as np
cimport numpy as cnp
from numpy cimport ndarray as ar
# define a function pointer
ctypedef void (*vector_ptr)(double[:], double, double[:])
cdef void sma_vec(double[:] x, double m, double[:] y) nogil:
cdef:
int n
int mi = int(m)
Py_ssize_t i, j
n = x.shape[0]
for i in range(mi-1, n):
for j in range(i-mi+1, i+1):
if j == i-mi+1:
y[i] = x[j]
else:
y[i] += x[j]
y[i] /= m
cdef void wma_vec(double[:] x, double m, double[:] y) nogil:
cdef:
int n
int mi = int(m)
Py_ssize_t i, j
n = x.shape[0]
for i in range(mi-1, n):
for j in range(i-mi+1, i+1):
if j == i-mi+1:
y[i] = x[j]
else:
y[i] += x[j]*float(j-i+m)
y[i] /= float(m*(m+1))/2.0
cdef void void_vec(double[:] x, double m, double[:] y) nogil:
pass
cdef vector_ptr stat_switch(stat_func):
if stat_func == 'sma':
return &sma_vec
elif stat_func == 'wma':
return &wma_vec
else:
return &void_vec
cdef double[:] stat_vec(double[:] x, double m, stat_func):
cdef:
vector_ptr stat_func_ptr = stat_switch(stat_func)
double[:] y = x.copy()
y[:] = np.nan
stat_func_ptr(x, m, y)
return y
cdef double[:, ::1] stat_mat(double[:, ::1] x, double m, stat_func):
cdef:
vector_ptr stat_func_ptr = stat_switch(stat_func)
int n
Py_ssize_t i
double[:, ::1] y = x.copy()
double[:] yi
double[:] xi
y[:, :] = np.nan
n = x.shape[1]
if n > int(m):
for i in range(0, x.shape[0]):
yi = y[i, :]
xi = x[i, :]
stat_func_ptr(xi, m, yi)
return y
cdef ar stat_choose(ar x, double m, stat_func):
if x.ndim == 1:
return np.asarray(stat_vec(x, m, stat_func))
elif x.ndim == 2:
return np.asarray(stat_mat(x, m, stat_func))
else:
raise ValueError('Cannot handle more than two dimensions')
cpdef ar sma(ar x, double m):
return stat_choose(x, m, 'sma')
cpdef ar wma(ar x, double m):
return stat_choose(x, m, 'wma')
上述代码说明:
函数sma_vec
,wma_vec
,计算x
上的一些指标并返回y
中的输出(在此示例中,滚动移动平均线和滚动加权移动平均线)。
函数stat_switch
切换为sma_vec
或wma_vec
,具体取决于stat_func
的值,而void_vec
是一个无效的虚函数。
函数stat_vec
在一维向量上返回sma_vec
或wma_vec
的输出
函数stat_mat
通过循环遍历二维向量(C类行)的行来返回sma_vec
或wma_vec
的输出
函数stat_choose
检查它是1维np.ndarray
还是2维np.ndarray
,并相应地将结果重定向到stat_vec
或{{1} }
函数stat_mat
和sma
旨在成为wma
的python包装器。
设置文件如下:
stat_choose
为了并行化from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy as np
ext_modules = [Extension('movavg1', ['stat/movavg1.pyx'], include_dirs=[np.get_include()],
define_macros=[('NPY_NO_DEPRECATED_API', None)],
extra_compile_args=['-O3', '-march=native', '-ffast-math']
)]
setup(
name="Moving Average Functions",
cmdclass={'build_ext': build_ext},
ext_modules=ext_modules
)
函数,我有一个循环,我执行以下操作:
stat_mat
将from cython.parallel import prange
代码更改为(已更改stat_mat
至range
):
而不是prange
,我正在使用range(0, x.shape[0])
在设置文件中,我向prange(x.shape[0], nogil=True)
添加了-fopenmp
:
ext_modules
extra_compile_args=['-O3', '-march=native', '-ffast-math', '-fopenmp'],
当我尝试编译时,我收到一个错误:
extra_link_args=['-fopenmp']
如何将此代码转换为编译它以便Error compiling Cython file:
------------------------------------------------------------
...
n = x.shape[1]
if n > int(m):
for i in prange(x.shape[0], nogil=True):
yi = y[i, :]
xi = x[i, :]
stat_func_ptr(xi, m, yi)
^
------------------------------------------------------------
stat\movavg1.pyx:73:25: Calling gil-requiring function not allowed
without gil
并行化?
答案 0 :(得分:0)
尝试更改
ctypedef void (*vector_ptr)(double[:], double, double[:])
要
ctypedef void (*vector_ptr)(double[:], double, double[:]) nogil
不幸的是,直到明天我才能测试这个。
答案 1 :(得分:0)
ctypedef void (*vector_ptr)(double[:], double, double[:]) nogil
对于Baum mit Augen:当使用函数指针指向nogil函数时,nogil限定符必须是函数指针类型的一部分。只有nogil函数可以在prange块中调用。但是当函数指针类型不包含nogil限定符时,在橙色或nogil块内调用是违法的。