“numba nopython模式”;未定义变量'$313.3'&引用;

“numba nopython模式”;未定义变量'$313.3'&引用;,python,numpy,numba,Python,Numpy,Numba,这是我从图像构造最小树的代码(f是scipy提供的图像) 这是我正在编写的一个接缝雕刻程序的基础。 此代码段在普通python中正常工作。当我使用@numba.jit而不使用nopython=True时,它也可以工作(性能提高了约200%),但这是在对象模式下 当我尝试使用nopython=True模式时,它不会编译,我得到错误: Failed at nopython (nopython frontend) Undefined variable '$313.3' 我不明白为什么它不能编译,因为

这是我从图像构造最小树的代码(
f
是scipy提供的图像)

这是我正在编写的一个接缝雕刻程序的基础。

此代码段在普通python中正常工作。当我使用
@numba.jit
而不使用
nopython=True
时,它也可以工作(性能提高了约200%),但这是在对象模式下

当我尝试使用
nopython=True
模式时,它不会编译,我得到错误:

Failed at nopython (nopython frontend)
Undefined variable '$313.3'
我不明白为什么它不能编译,因为我看不到任何可能未定义的内容

from numba import jit
from scipy import misc
import numba

f = misc.face()
@jit(nopython=True)
def explorethisx(inar, x):
    places = []
    places.append((x,0))
    x1,y1 = x,0
    s = numba.int64(0)
    co = 0
    #for _ in range( 799):

    while co != numba.int16(799):
        co += 1
        a1,a2,a3 = 999,999,999
        a1 = inar[y1 + 1][x1-1][1]
        a2 = inar[y1 + 1][x1][1]
        a3 = inar[y1 + 1][x1 + 1][1]
        m = a1
        ch = -1
        if m > a2:
            m = a2
            ch = 0
        if m > a3:
            m = a3
            ch = 1
        x1 = x1 + ch
        y1 = y1 + 1
        s += inar[y1][x1][1]
        places.append((x1,y1))
    return([s, places])
explorethisx(f,3)
explorethisx.inspect_types()

Numba是一个非常酷的项目,即使是在python对象模式下,性能的提高也给我留下了深刻的印象。

异常消息具有误导性。只是它只支持同构列表,所以当您尝试返回
[s,places]
时,您将返回一个包含一个“整数”和一个“整数元组列表”的列表,这两个列表不再是同构的

请注意,这个最小的示例已经演示了该异常:

from numba import jit

@jit(nopython=True)
def test():
    places = []
    places.append((1, 2))
    places.append((2, 3))
    return [10, places]

>>> test()
...
TypingError: Failed at nopython (nopython frontend)
Undefined variable '$0.12'
您只需返回一个元组:

return (s, places)
而不是旧的

return([s, places])

即使这样编译-调用函数时函数包含越界内存访问(我有一个segfault),因此您肯定也需要检查内存访问。

这太疯狂了,为什么它会给出
$
的错误?我一直在尝试调试
f
以查找字符串。换句话说,我不怀疑您已查明问题所在,但错误消息对我来说确实有误导性。我正在努力学习麻木,这无疑让我省去了一个巨大的头痛。这样一种报告混合类型的奇怪方式。漏洞百出的抽象。可能这是numba代码中的一个占位符。我不知道他们为什么选择那个异常消息,但这并不是真正的误导——我宁愿说这根本没有帮助。尽管如此,上周我还是遇到了一个例外,所以我记得是什么导致了它,以及如何修复它。(请注意,他们已经提交了一份错误报告以改进错误消息:)。对于我来说,异常是误导性的,因为我在查找字符串,我忽略了嵌套列表。作为一般提示,使用
x[I,j,k]
而不是
x[I][j][k]
访问数组元素要快得多。例如,使用
inar[y1+1,x1-1,1]
和类似的方法。这使我的代码基准测试速度提高了近1.6倍。这适用于Ndarray上的所有numpy/numba操作。@JoshAdel我可以问一下您是如何运行基准测试的吗?我知道的唯一方法是使用cProfile。我倾向于使用
%timeit
魔术在Jupyter笔记本中进行配置。特别是在分析代码时,您需要抛出jitted函数的第一次执行,因为这将包括编译时间,您只需支付一次。