并行选项的用法麻木.jitdecorator使函数给出错误的结果

2024-04-24 14:46:36 发布

您现在位置:Python中文网/ 问答频道 /正文

给定一个矩形(x1, y1)(x2, y2)的两个对角点和两个半径r1r2所定义的圆之间的点与矩形中点总数的比率。在

简单的NumPy方法:

def func_1(x1,y1,x2,y2,r1,r2,n):
     x11,y11 = np.meshgrid(np.linspace(x1,x2,n),np.linspace(y1,y2,n))
     z1 = np.sqrt(x11**2+y11**2)
     a = np.where((z1>(r1)) & (z1<(r2)))
     fill_factor = len(a[0])/(n*n)
     return fill_factor

接下来,我试图用numba的jit装饰器优化这个函数。当我使用:

^{pr2}$

该函数速度更快,输出正确。但我同时补充:

parallel = True

但结果是错误的。 我知道这与我的z矩阵有关,因为它没有被正确更新。在

@jit(nopython=True,parallel=True)
def func_2(x1,y1,x2,y2,r1,r2,n):
    x_ = np.linspace(x1,x2,n)
    y_ = np.linspace(y1,y2,n)
    z1 = np.zeros((n,n))
    for i in range(n):
        for j in range(n):
            z1[i][j] = np.sqrt((x_[i]*x_[i]+y_[j]*y_[j]))
    a = np.where((z1>(r1)) & (z1<(r2)))
    fill_factor = len(a[0])/(n*n)
    return fill_factor

测试值:

x1 = 1.0
x2 = -1.0
y1 = 1.0
y2 = -1.0
r1 = 0.5
r2 = 0.75
n = 25000

附加信息:Python版本:3.6.1,Numba版本:0.34.0+5.g1762237,NumPy版本:1.13.1


Tags: 版本numpytruenpfillr2x1x2
1条回答
网友
1楼 · 发布于 2024-04-24 14:46:36

parallel=True的问题是它是一个黑匣子。Numba甚至不能保证它会并行化任何东西。它使用启发式来确定它是否可并行化,以及哪些可以并行完成。它们可能会失败,在您的示例中,它们确实会失败,就像my experiments with ^{} and numba中一样。这使得parallel不可信,我建议不要使用它!在

在较新的版本(0.34)中添加了prange,这样你会有更多的运气。它不能在这种情况下应用,因为prange的工作方式与range相似,这与{}不同。。。在

请注意:您可以完全避免在函数中生成z和执行np.where,只需显式地执行检查:

import numpy as np
import numba as nb

@nb.njit   # equivalent to "jit(nopython=True)".
def func_2(x1,y1,x2,y2,r1,r2,n):
    x_ = np.linspace(x1,x2,n)
    y_ = np.linspace(y1,y2,n)
    cnts = 0
    for i in range(n):
        for j in range(n):
            z = np.sqrt(x_[i] * x_[i] + y_[j] * y_[j])
            if r1 < z < r2:
                cnts += 1
    fill_factor = cnts/(n*n)
    return fill_factor

与您的函数相比,这还可以提供一些加速,甚至比使用parallel=True(如果它能正常工作的话)还要快。在

相关问题 更多 >