Numba:在原地对数组进行排序

6
Numba具有使用JIT编译加速循环的惊人能力。然而,当使用numpy时,不允许创建任何新数组。幸运的是,大多数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数组进行排序?


4
似乎arr.sort是C代码,而不是Python循环。而np.sort(a)只是复制了a,并对其进行排序。那么有什么可以加速的地方呢? - hpaulj
对于将向量有效地投影到1-范数球上,排序向量是必要的子程序。请参见http://machinelearning.org/archive/icml2008/papers/361.pdf。 - duckworthd
3
我并没有质疑您需要排序,而是想知道numba是否可以加速这种操作。如果已经编译过了,它已经达到了最快的速度。您可以尝试使用不同的“kind”参数值进行实验。 - hpaulj
1个回答

6
Numba应该能够在“nopython”模式下编译此代码,但不幸的是我们尚未添加对ndarray.sort()的支持。它可以在“python”模式下编译,但速度较慢,因为它必须通过Python对象层,但由于看起来ndarray.sort()是用C实现的,所以可能没有太大区别。我已经在numba的github问题跟踪器中添加了一个错误报告
另一件需要注意的事情是,如果可能的话,numba将在nopython模式下编译循环,而函数的其余部分则在python模式下编译。这允许您使用不受支持的函数,如ndarray.sort()和numpy.arange()之类创建和返回新数组的函数,同时仍然具有快速编译的循环(只要您不在循环内调用ndarray.sort()或numpy.arange(),但如果性能是一个重要问题,您可能不想这样做)。
因此,总结一下:在numba正确支持在nopython模式下调用ndarray.sort()之前,您可以使用jit装饰器而不是njit装饰器,只要您不在循环内排序数组。

感谢@jayvius!我的np.sort所需的调用嵌套在“nopython”模式循环中,因此我继续实现了冒泡排序来推进工作。如果我使用“python”模式,性能实际上比纯Python基线更差,但是使用“nopython”模式,我获得了200倍的速度增益!请参见相关代码:https://github.com/duckworthd/cvxcluster/blob/numba/cvxcluster/_coordinate_ascent.py#L75 - duckworthd
1
更新:现在Numba支持np.sort - user16836078

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接