我有下面的代码,我正在尝试并行化。描述如下:
# 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根据stat_func的值切换到sma_vec或wma_vec,而void_vec是一个什么都不做的虚拟函数。stat_vec在一维向量上返回sma_vec或wma_vec的输出。stat_mat通过遍历二维向量(C型行)的行返回sma_vec或wma_vec的输出。stat_choose检查它是一维np.ndarray还是二维np.ndarray,并相应地将结果重定向到stat_vec或stat_mat。sma和wma打算成为stat_choose的python。安装文件如下:
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_modulesextra_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我如何转换这段代码来编译它,使stat_mat被并行化?
发布于 2015-05-23 22:59:31
试着改变
ctypedef void (*vector_ptr)(double[:], double, double[:])至
ctypedef void (*vector_ptr)(double[:], double, double[:]) nogil至少我明天才能测试这个。
发布于 2015-05-31 03:01:40
ctypedef void (*vector_ptr)(double[:], double, double[:]) nogil对于Baum mit Augen:当使用函数指针到nogil函数时,nogil限定符必须是函数指针类型的一部分。只有nogil函数可以在prange块中调用。但是,当函数指针类型不包含nogil限定符时,在橙色或nogil块中调用是非法的。
https://stackoverflow.com/questions/30418238
复制相似问题