所以我有一个似乎完全可以接受的循环来进行并行.但当我把它传递给Numba parallel时,它总是给出错误的结果.循环中发生的所有事情是,输入矩阵的一个元素被设置为0,矩阵乘法发生并填充一个新矩阵,然后被设置为0的元素被设置回其原始值.似乎数组a在每次发送Numba时都会被修改,所以我try 将a复制到循环中的另一个变量,只修改副本,但却得到了相同的错误结果(未显示).下面是一个简单的例子.我只是不知道问题是什么,也不知道如何解决:

import numpy as np
from scipy.stats import random_correlation
import numba as nb

def myfunc(a, corr):
    b = np.zeros(a.shape[0])

    for i in range(b.shape[0]):
        temp = a[i]
        a[i] = 0
        b[i] = a@corr@a.T
        a[i] = temp

    return b

@nb.njit(parallel=True)
def numbafunc(a, corr):
    b = np.zeros(a.shape[0])

    for i in nb.prange(b.shape[0]):
        temp = a[i]
        a[i] = 0
        b[i] = a@corr@a.T
        a[i] = temp

    return b

if __name__ == '__main__':
    a = np.random.rand(10)
    corr = random_correlation.rvs(eigs=[2,2,1,1,1,1,0.5,0.5,0.5,0.5])

    b_1 = myfunc(a, corr)
    b_2 = numbafunc(a, corr)

    # check if serial and Numba results match off the same inputs
    print(np.isclose(b_1,b_2))

    # double check the original function returns the same results again..
    b_1_check = myfunc(a, corr)
    print(np.isclose(b_1, b_1_check))

返回所有假值,或至少9/10为假...有人能指出代码的哪一部分对并行化有问题吗?我觉得不错.非常感谢!

推荐答案

百分之一百零七.实际上,a[i] = 0 modifies the array 102 shared between multiple threads为不同的i值读/写a.将该值存储在temp中以在以后恢复它只能按顺序工作,但不能并行工作,因为线程可以随时读取a.

为了解决这个问题,每个线程都应该在自己的a:

@nb.njit(parallel=True)
def numbafunc(a, corr):
    b = np.zeros(a.shape[0])

    for i in nb.prange(b.shape[0]):
        c = a.copy()
        c[i] = 0.0
        b[i] = c @ corr @ c.T

    return b

Python相关问答推荐

仿制药的类型铸造

韦尔福德方差与Numpy方差不同

如何使用html从excel中提取条件格式规则列表?

发生异常:TclMessage命令名称无效.!listbox"

更改键盘按钮进入'

如何在给定的条件下使numpy数组的计算速度最快?

形状弃用警告与组合多边形和多边形如何解决

如何并行化/加速并行numba代码?

dask无groupby(ddf. agg([min,max])?''''

基于形状而非距离的两个numpy数组相似性

如何在两列上groupBy,并使用pyspark计算每个分组列的平均总价值

找到相对于列表索引的当前最大值列表""

pandas fill和bfill基于另一列中的条件

如何在一组行中找到循环?

如何从比较函数生成ngroup?

如何将列表从a迭代到z-以抓取数据并将其转换为DataFrame?

Django更新视图未更新

在聚合中使用python-polars时如何计算模式

如何删除剪裁圆的对角线的外部部分

如何定义一个将类型与接收该类型的参数的可调用进行映射的字典?