我已经开始处理并行编程和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/

10-13 08:30