Numba Nopython模式:“未定义变量'$ 313.3'”。

4
这是我构建图像最小树的代码(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对象模式下也能提供出色的性能改进。


1
作为一般提示,使用x[i,j,k]访问数组元素比使用x[i][j][k]更快。因此,例如在整个代码中都使用inar[y1 + 1,x1-1,1]等方式。这使得我对您的代码进行基准测试时加速了近1.6倍。这对于所有numpy/numba操作ndarrays都是正确的。 - JoshAdel
@JoshAdel,我可以问一下你是如何运行基准测试的吗?我知道的唯一方法是使用cProfile。 - George John
我倾向于在Jupyter笔记本中使用%timeit魔法进行分析。特别是在分析Numba代码时,您需要丢弃已编译函数的第一次执行,因为它将包括编译时间,而这只需要支付一次。 - JoshAdel
1个回答

6
异常信息有误导性。实际上,仅支持同构列表,因此当您尝试返回[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])

即使这个代码可以编译通过,但是函数中存在越界内存访问的问题(我遇到了段错误),因此您一定需要检查您的内存访问。

这太疯狂了,为什么它会在 $ 处出现错误?我一直在调试 f,寻找一个字符串。 - roganjosh
换句话说,我不怀疑你已经找到了问题所在,但是这个错误信息对我来说确实非常误导。我正在尝试学习numba,这无疑为我节省了很大的麻烦。报告混合类型的方式真是奇怪。 - roganjosh
漏洞抽象。可能这是numba代码中的占位符。 - Mark Reed
1
我不知道为什么他们选择了那个异常消息,虽然它并不是真正的误导性 - 我宁愿说它根本没有帮助。尽管如此,上周我遇到了这个异常,所以我记得是什么原因引起的以及如何修复它。(请注意,他们已经提交了错误报告以改进错误消息:https://github.com/numba/numba/issues/2237)。 - MSeifert
对我来说,这个异常是误导性的,因为我一直在寻找字符串,却忽略了嵌套列表。 - roganjosh
非常感谢!我现在感觉有点傻,我记得在指南中读到了关于同类列表的内容,我应该意识到的。 - George John

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接