【发布时间】:2020-04-22 18:54:46
【问题描述】:
这是一个玩具njit 函数,它接收一个距离矩阵,循环遍历矩阵的每一行,并记录每列中的最小值以及最小值来自哪一行。但是,IIUC 使用 prange 可能会导致竞争条件(尤其是对于较大的输入数组):
from numba import njit, prange
import numpy as np
@njit
def some_transformation_func(D, row_i):
"""
This function applies some transformation to the ith row (`row_i`) in the `D` matrix in place.
However, the transformation time is random (but all less than a second), which means
that the rows can take
"""
# Apply some inplace transformation on the ith row of D
@njit(parallel=True)
def some_func(D):
P = np.empty((D.shape[1]))
I = np.empty((D.shape[1]), np.int64)
P[:] = np.inf
I[:] = -1
for row in prange(D.shape[0]):
some_transformation_func(D, row)
for col in range(D.shape[1]):
if P[col] > D[row, col]:
P[col] = D[row, col]
I[col] = row
return P, I
if __name__ == "__main__":
D = np.array([[4,1,6,9,9],
[1,3,8,2,7],
[2,8,0,0,1],
[3,7,4,6,5]
])
P, I = some_func(D)
print(P)
print(I)
# [1. 1. 0. 0. 1.]
# [1 0 2 2 2]
我如何确认是否存在竞争条件(特别是如果 D 非常大且包含更多行和列)?而且,更重要的是,如果存在竞态条件,我该如何避免呢?
【问题讨论】:
-
不写答案,因为我不是 Numba 专家,阅读 stackoverflow.com/questions/59596794/… 让我相信你的行
P[col] > D[row, col]: P[col] = D[row, col]是一场比赛,因为它们是两条独立的行,没有锁定,读取和写入相同的记忆。 -
至于测试,就像你说的,随着数组变大,不达到竞争条件不一致的概率会降低。我建议一个简单的连续实现,并在非常大的数组上比较使用
numpy.testing.assert_almost_equal。如果相等,那么比赛的概率非常低。 -
还有一点,在python中,与Matlab不同,在局部变量名中使用大写字母被认为是非常规的。
-
如果有任何帮助,请告诉我
-
感谢您的回复。但是我真正需要帮助我们如何避免竞争条件(不损失并行性能)
标签: python race-condition numba