未执行的行执行 - 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)
如果我们在 f1
或 f2
中取消注释,则会抛出以下错误。请注意,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.jit
和 nonpython=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):
...
@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)
如果我们在 f1
或 f2
中取消注释,则会抛出以下错误。请注意,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.jit
和 nonpython=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):
...