Numba具有使用JIT编译加速循环的惊人能力。然而,关键的转折是使用numpy时one isn't allowed to create any new arrays。幸运的是,大多数numpy函数都包含一个可选的out
参数,用于将输出写入 - numpy.sort
除外。最明显的替代方案是numpy.ndarray.sort
,它已经到位,
@njit("void(f8[:])")
def sort_inplace(arr):
arr.sort()
但是无法编译,
...
...
...
/Users/duckworthd/anaconda/lib/python2.7/site-packages/numba/typeinfer.pyc in propagate(self)
293 print("propagate".center(80, '-'))
294 oldtoken = newtoken
--> 295 self.constrains.propagate(self.context, self.typevars)
296 newtoken = self.get_state_token()
297 if config.DEBUG:
/Users/duckworthd/anaconda/lib/python2.7/site-packages/numba/typeinfer.pyc in propagate(self, context, typevars)
112 raise
113 except Exception as e:
--> 114 raise TypingError("Internal error:\n%s" % e, constrain.loc)
115
116
TypingError: Internal error:
Attribute 'sort' of array(float64, 1d, A) is not typed
如果没有重新实现排序算法,有没有办法在JIT编译的numba循环中对numpy数组进行排序?
答案 0 :(得分:4)
Numba应该能够在" nopython"模式,但不幸的是我们尚未增加对ndarray.sort()的支持。它汇编在" python"虽然模式虽然必须通过python对象层,但速度较慢,但由于看起来ndarray.sort()在C中实现,因此它可能没什么区别。我继续在numba的github问题跟踪器中添加bug report。
另外需要注意的是,如果可能的话,numba将在nopython模式下编译循环,而其余的函数是在python模式下编译的。这允许您使用不受支持的函数,如ndarray.sort(),以及像numpy.arange()这样的函数创建并返回一个新数组,同时仍然具有快速编译的循环(只要您不调用ndarray.sort) ()或循环中的numpy.arange(),但如果性能是一个大问题,你可能不想这样做。)
总而言之:你可以使用jit装饰器代替njit装饰器,直到numba正确支持在nopython模式下调用ndarray.sort(),只要你不排序数组在一个循环中。