用qumbxswpoi的别名numba njit
装饰的函数产生jit(nopython=True)
对就地操作的不同结果(简单的numpy
也给出了@jit(nopython=False)
的不同结果):
numpy
它看起来像In [1]: import numpy as np
from numba import njit
def npfun(arr):
arr -= arr[3]
@njit
def jitfun(arr):
arr -= arr[3]
arr1 = np.ones((6,2))
arr2 = arr1.copy()
npfun(arr1)
jitfun(arr2)
arr1 == arr2
Out[1]: array([[ True, True],
[ True, True],
[ True, True],
[ True, True],
[False, False],
[False, False]], dtype=bool)
评估rhs并将其作为副本传递,而numpy
将rhs视为视图。有没有技术理由这样做?
numba
numpy 1.13.3
你正在做的操作:
numba 0.35
曾经是NumPy中未定义的行为。它最近才被定义,在arr -= arr[3]
,释放NumPy 1.13.0。新的,定义的行为总是表现为它复制了所有输入,尽管它试图避免在检测到它不需要时实际制作副本。
看起来Numba目前没有尝试模仿新行为,无论是因为它有多新,还是因为Numba特有的担忧。
如果你使用June 7th this year参数的显式就地操作,而不是增强赋值,它将帮助Numba:replace
out
同
arr -= arr[3]
这使得jitted版本(虽然使用@jit,而不是@njit)与NumPy版本完全相同。值得注意的是,尝试@njit这个函数现在会失败,告诉你比njit无法处理np.subtract(arr, arr[3], out=arr)
参数。
我已经看到你已经out
,所以有可能改变增强作业的处理以匹配NumPy。
正如hpaulj所说,Numba输出相当于循环遍历数组的行。 Python JITter无法对NumPy底层的C代码做任何事情;它需要Python才能使用。支持NumPy方法(在某种程度上)的原因是Numba开发人员遇到了将NumPy数组操作解码为标量对象的显式Python迭代的麻烦,然后可以将其传递给LLVM。来自opened an issue on this:
- 合成一个实现数组表达式的Python函数:这个新的Python函数本质上就像一个Numpy ufunc,它在广播数组参数中的标量值上返回表达式的结果。降低功能通过从数组表达式树转换为Python AST来实现这一点。
- 将合成Python函数编译到内核中:此时,降低函数依赖于现有代码来降低ufunc和DUFunc内核,在定义如何降低对合成函数的调用之后调用documentation。
最终结果类似于Numba对象模式中的循环提升。
上述numba.targets.numpyimpl.numpy_ufunc_kernel()
收集索引并迭代它们。如果被迭代的对象在迭代过程中发生变异,则会使事情发生变化。