未执行的行执行 - Numba

Unexecuted line executes - Numba

@jit(nopython=True)
def f1(x, y):
    #if y is None:
    #    y = x
    y[0] = 0
    x[0] = 0
    return x

@jit(nopython=True)
def f2(x, y):
    if y is None:
        y = x
    #y[0] = 0
    x[0] = 0
    return x

x = np.zeros(5, dtype='complex128')
f1(x, x.real)
f2(x, x.real)

如果我们在 f1f2 中取消注释,则会抛出以下错误。请注意,y 永远不会是 None,因此 y = x 永远不会执行。此外,无论是否未注释,下面都不会失败:

f1(x, x)
f2(x, x)
f1(x.real, x.real)
f2(x.real, x.real)

我是不是遗漏了什么,还是 Numba 错误?


  File "<ipython-input-117-a1d860b39413>", line 1, in <module>
    f2(x, x.real)
  File "D:\Anaconda\lib\site-packages\numba\core\dispatcher.py", line 415, in _compile_for_args
    error_rewrite(e, 'typing')
  File "D:\Anaconda\lib\site-packages\numba\core\dispatcher.py", line 358, in error_rewrite
    reraise(type(e), e, None)
  File "D:\Anaconda\lib\site-packages\numba\core\utils.py", line 80, in reraise
    raise value.with_traceback(tb)

TypingError: Cannot unify array(float64, 1d, A) and array(complex128, 1d, C) for 'y.2', 
defined at <ipython-input-115-c97d2a6dc56c> (13)

File "<ipython-input-115-c97d2a6dc56c>", line 13:
def f2(x, y):
    <source elided>
        y = x
    y[0] = 0
    ^
During: typing of assignment at <ipython-input-115-c97d2a6dc56c> (13)

你不能在 numba.jitnonpython=True 中这样做,因为 python 程序将被编译(就像 c 代码),并且必须可运行。与在运行时计算的 python 代码不同,编译后的代码必须提前计算,编译器无法猜测 y 是否为 None

要解决此问题,您可以删除 nonpython=True(或将其设置为 False

@jit(nopython=False)
def f1(x, y):
    #if y is None:
    #    y = x
    y[0] = 0
    x[0] = 0
    return x

@jit(nopython=False)
def f2(x, y):
    if y is None:
        y = x
    #y[0] = 0
    x[0] = 0
    return x

x = np.zeros(5, dtype='complex128')
f1(x, x.real)
f2(x, x.real)

但是使用 @jit 有什么意义,因为它会退回到 non-compiled 版本的代码,没有速度增益?因此,您应该重新考虑代码的设计,或者在没有 @jit 装饰器的情况下使用它,因为在这种情况下它是无用的。

简单的解决方法是用 Python 函数包装 Numba 函数:

def f1(x, y=None):
    if y is None:
        y = x
    assert isinstance(x, np.ndarray) and isinstance(y, np.ndarray)
    return _f1(x, y)

@njit
def _f1(x, y):
    ...