Numba 的 prange 给出了错误的结果
Numba's prange gives wrong result
在使用 prange 与 range 相比时,在 prange 循环中更新列表会给出错误的结果。
from numba import jit, prange
import numpy as np
@jit(parallel=True)
def prange_test(A):
s = [0,0,0,0]
b = 0.
for i in prange(A.shape[0]):
s[i%4] += A[i]
b += A[i]
return s,b
def range_test(A):
s = [0,0,0,0]
b = 0.
for i in range(A.shape[0]):
s[i%4] += A[i]
b += A[i]
return s,b
A = np.random.random(100000)
print(prange_test(A))
print(range_test(A))
和b是一样的,但是s中的部分和是错误的:
(array([7013.98962611, 6550.90312863, 7232.49698366, 7246.53627734]), 49955.32870429267)
([12444.683249345742, 12432.449908902432, 12596.461028432543, 12481.734517611982], 49955.32870429247)
虽然在文档中有点不清楚,但当您从 prange
并行循环的不同迭代写入相同的数据元素时,您不能安全地累积到 array-like 对象中。我今年早些时候实际提交的 github issue 询问了这个特定问题。
再次提出这个问题提醒我,我想向 numba 文档提交 PR 来澄清这一点。
在使用 prange 与 range 相比时,在 prange 循环中更新列表会给出错误的结果。
from numba import jit, prange
import numpy as np
@jit(parallel=True)
def prange_test(A):
s = [0,0,0,0]
b = 0.
for i in prange(A.shape[0]):
s[i%4] += A[i]
b += A[i]
return s,b
def range_test(A):
s = [0,0,0,0]
b = 0.
for i in range(A.shape[0]):
s[i%4] += A[i]
b += A[i]
return s,b
A = np.random.random(100000)
print(prange_test(A))
print(range_test(A))
和b是一样的,但是s中的部分和是错误的:
(array([7013.98962611, 6550.90312863, 7232.49698366, 7246.53627734]), 49955.32870429267)
([12444.683249345742, 12432.449908902432, 12596.461028432543, 12481.734517611982], 49955.32870429247)
虽然在文档中有点不清楚,但当您从 prange
并行循环的不同迭代写入相同的数据元素时,您不能安全地累积到 array-like 对象中。我今年早些时候实际提交的 github issue 询问了这个特定问题。
再次提出这个问题提醒我,我想向 numba 文档提交 PR 来澄清这一点。