我已经开始处理并行编程和cython/openmp,我有一个简单的程序,可以使用prange在数组上求和:
import numpy as np
from cython.parallel import prange
from cython import boundscheck, wraparound
@boundscheck(False)
@wraparound(False)
def parallel_summation(double[:] vec):
cdef int n = vec.shape[0]
cdef double total
cdef int i
for i in prange(n, nogil=True):
total += vec[i]
return total
使用setup.py文件似乎可以正常工作。但是,我想知道是否可以调整这个函数,并对处理器的工作有更多的控制。
假设我有4个处理器:我想将向量分成4个部分,然后让每个处理器在本地添加元素。然后在最后,我可以把每个处理器的结果组合起来得到总数从cython文档中,我无法收集是否有可能发生这样的事情(文档有点稀疏)。
如果有人能解释一下使用cython/openmp是否/如何完成这样的工作,或者帮助查找一些相关的示例(在网上很难找到简单的示例),我将不胜感激。
最佳答案
我想把向量分成4个部分,然后让每个处理器在内部局部添加元素然后在最后,我可以把每个处理器的结果组合起来得到总数。
这正是这里正在发生的事情cython从你的就地操作推断你想做一个减量。openmp将实现一个带有total
变量的私有(零初始化)副本的并行循环,并将它们全部添加到循环末尾的total
中。
在生成的c中,如下所示:
#pragma omp parallel
{
#pragma omp for firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) reduction(+:__pyx_v_total)
for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_3; __pyx_t_2++){
{
__pyx_v_i = (int)(0 + 1 * __pyx_t_2);
__pyx_t_4 = __pyx_v_i;
__pyx_v_total = (__pyx_v_total + (*((double *) ( /* dim=0 */ (__pyx_v_vec.data + __pyx_t_4 * __pyx_v_vec.strides[0]) ))));
}
}
}
您只需要启用openmpas described here。
您应该在代码中更改的一件事是初始化
total = 0
,否则它只是一个包含垃圾的单元化C变量。关于python - 求和操作的本地并行计算,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42335427/