Python 多维数组循环的Numba并行化

Python 多维数组循环的Numba并行化,python,for-loop,parallel-processing,numba,parfor,Python,For Loop,Parallel Processing,Numba,Parfor,我正在尝试将for循环与numba并行。我是这个库的新手,但经过一些研究后,我编写了这段代码,与我研究的示例相比,这段代码看起来是正确的: @njit(nopython=True, parallel=True) def tempFtemp(ftemp_pte, func_F, numPointsEval, pointsToEval): for i in prange(0, numPointsEval): ftemp_pte[:,i] = np.hstack(func_F(np.vstac

我正在尝试将for循环与numba并行。我是这个库的新手,但经过一些研究后,我编写了这段代码,与我研究的示例相比,这段代码看起来是正确的:

@njit(nopython=True, parallel=True)
def tempFtemp(ftemp_pte, func_F, numPointsEval, pointsToEval):
for i in prange(0, numPointsEval):
    ftemp_pte[:,i] = np.hstack(func_F(np.vstack(pointsToEval[:,i])))
return ftemp_pte

ftemp_pte= tempFtemp(ftemp_pte, func_F, numPointsEval, pointsToEval)
当我在程序Think中编译它时,我在prange(0,numPointsEval)中i的
行中得到错误“non-precise type pyobject”:
ftemp_pte
pointsToEval
都是二维数组,
numPointsEval
是一个整数,
func_F
是一个随机函数,它将生成要存储在
ftemp_pte[:,i]
中的一维数组

如果您能帮助我们找出导致此错误的原因,我们将不胜感激

[编辑]

我最初使用的顺序代码(有效)如下:

def func_F(x):
    f= np.zeros((1,2))
    f[0,0]= x[0,0]
    n= max(np.size(x,0), np.size(x,1))    
    g    = 1 + 9* np.sum(x[1:n])/(n-1)
    h    = 1 - np.sqrt(f[0,0]/g)
    f[0,1] = g * h
    F= np.transpose(f)
    return F

for i in range(0, numPointsEval):
   ftemp_pte[:,i] = np.hstack(func_F(np.vstack(pointsToEval[:,i])))
我还应该提到,需要使用
hstack
vstack
,以便创建的数组的格式能够匹配
ftemp_pte
数组。删除这些说明将导致尺寸不匹配

变量
ftemp_pte
始终有2行和x行。正确值的一个示例是
[[0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875 0.21875][0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.530.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.5397286 0.53970.5397286 0.53970.53970.5397286 0.53970.5397

我的代码的最初目的是将以下Matlab的parfor指令翻译成Python

parfor i=1:numPointsEval
     ftemp_pte(:,i) = feval(func_F,pointsToEval(:,i));
任何帮助都将不胜感激

假设一级函数对象可以是Numba cfunc编译函数、JIT编译函数和实现包装器地址协议的对象

您可以传递JITted函数,如以下简化示例所示:

@nb.njit
def cos(a):
    return np.cos(a)

@nb.njit(parallel=True)
def tempFtemp(ftemp_pte, func_F, numPointsEval, pointsToEval):
    for i in nb.prange(numPointsEval):
        ftemp_pte[:, i] = func_F(pointsToEval[:, i])
    return ftemp_pte

ftemp_pte = tempFtemp(ftemp_pte, np.cos, numPointsEval, pointsToEval)  # Error
ftemp_pte = tempFtemp(ftemp_pte, cos, numPointsEval, pointsToEval)     # Works
这解决了“非精确类型pyobject”问题,但我已从示例中删除了
hstack
vstack
操作,因为它们会产生问题的答案2

只要你不是在堆叠数组,而是对它们进行修改,你就应该避免<代码> HSTACKE()/<代码>和<代码> VSTACK()>代码>,并考虑使用<代码> RESHAPE()/<代码>或<代码> RAVEL()>代码>。

ftemp_pte[:, i] = func_F(pointsToEval[:, i].reshape(1, -1)).ravel()
但是,numba不支持非连续数组上的
reformate()

因此,我已设法使您的代码使用numba运行,方法是转置所有内容以避免重新塑造数组。以下代码确实有效,可能会给您一些想法:

@nb.njit
def func_F(x):
    f = np.zeros(2)    # Simple 1d array
    f[0] = x[0]
    n = max(x.shape)
    g = 1 + 9 * np.sum(x[1:n]) / (n - 1)
    h = 1 - np.sqrt(f[0] / g)
    f[1] = g * h
    return f

@nb.njit(parallel=True)
def tempFtemp(ftemp_pte, func_F, numPointsEval, pointsToEval):
    for i in nb.prange(numPointsEval):
        ftemp_pte[i] = func_F(pointsToEval[i])
    return ftemp_pte

ftemp_pte = np.zeros((2, 5)).T
pointsToEval = np.zeros((2, 5)).T
numPointsEval = 5
ftemp_pte = tempFtemp(ftemp_pte, func_F, numPointsEval, pointsToEval)
print(ftemp_pte.T)

感谢您的帮助,遗憾的是它仍然不起作用。在尝试您的建议后,Imma用以下问题编辑了我的帖子根据新的错误消息,在
tempFunc\u()中调用
func\u F()
时会出现问题
。这可能是因为函数本身或传递给它的参数。您应该发布最简单版本的
func\u F()
并将数据传递给it部门,使问题得以重现。好的,非常感谢。我将编辑帖子,以便提供所有必要的信息。非常感谢您的帮助我更新了问题并提供了我认为需要的所有详细信息。我非常感谢您的帮助,我已经就这个问题讨论了很多天了。能否给我一些反馈轻松?非常感谢您的帮助。代码不起作用,但我将尝试找到另一种替代方法,我将为您建议的操作更改
vstack
hstack
操作