5

Numba 具有通过 JIT 编译加速循环的惊人能力。然而,关键的转折是,当使用 numpy 时,不允许创建任何新数组。幸运的是,大多数 numpy 函数都包含一个可选out参数,用于将输出写入 -- except 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 数组进行排序?

4

1 回答 1

5

Numba 应该能够在“nopython”模式下编译它,但不幸的是我们还没有添加对 ndarray.sort() 的支持。它在“python”模式下编译虽然速度较慢,因为它必须通过 python 对象层,但因为看起来 ndarray.sort() 是用 C 实现的,所以可能没有太大区别。我继续在 numba 的 github 问题跟踪器中添加了一个错误报告。

另一件需要注意的事情是,如果可能,numba 将在 nopython 模式下编译循环,而函数的其余部分在 python 模式下编译。这允许您使用不受支持的函数,如 ndarray.sort(),以及创建和返回新数组的函数,如 numpy.arange(),同时仍然具有快速编译循环(只要您不调用 ndarray.sort()或循环中的 numpy.arange() ,但如果性能是一个大问题,你可能不想这样做)。

总结一下:只要您不在循环内对数组进行排序,您就可以使用 jit 装饰器而不是 njit 装饰器,直到 numba 正确支持在 nopython 模式下调用 ndarray.sort() 。

于 2014-05-29T21:42:50.387 回答