while 在 jitted 函数中循环奇怪且不稳定的行为

while loop strange and unstable behavior in a jitted function

我发现当 numpy 数组的索引在 njit 装饰函数的 while 循环内越界时,函数处理 while 循环的方式可能会很奇怪,我不确定为什么会这样。

from numba import njit
import numpy as np


def func1(v):
    i= 0
    K= v[-1]+1
    while v[i] < K:
        i+=1
    return i

@njit        
def func2(v):
    i= 0
    K= v[-1]+1
    while v[i] < K:
        i+=1
    return i

x= np.arange(2)
result2 = func2(x)
result1 = func1(x)

以下是结果的简短摘要:

1) func2 不会加注 IndexError

2) func2 returns 不同的结果(比如有时是 4;有时是 5912 等, 基本上不稳定的输出)每次我们 运行 控制台中的文件(我使用的是 ipython 版本 7.8.0

我不确定为什么以及如何发生这种情况(可能是由于 numbaspyderipython 问题,也可能是我的 cpu 坏了无法修复)这就是我在这里寻求帮助的原因。


注意:我正在使用:

我以前听说过 Numba,但我自己从未使用过。

这里是刚刚对它(版本 0.45.1)进行一些修改的结果。

from numba import njit
import numpy as np

x = np.arange(2)

@njit        
def func2(v):
    i = 0
    k = v[-1]+1
    while v[i] < k:
        i += 1
    return i

@njit
def func3(x):
    return x[2]



func2(x)  # returns 2, but no error raised

func3(x)  # returns 32, no error raised 
func3(np.array([0]))   # returns 32, no error raised

func2([0, 1])  # IndexError raised
func3([0, 1])  # IndexError raised

所以对我来说,这个错误看起来是 Numba 的 jit 和 Numpy 数组之间某种交互的结果,因为正常的 Python 列表的行为符合预期。

出于性能原因,Numba 不会对 Numpy 数组进行边界检查。目前有选择性地打开它的工作(https://github.com/numba/numba/pull/4432)。当您超出数组的边界时,您将获得该位置内存中的任何内容或可能出现段错误。