【问题标题】:Why does this code fail to compile with Numba?为什么这段代码无法用 Numba 编译?
【发布时间】:2021-09-26 04:16:57
【问题描述】:

我有一个示例代码来说明我的问题。如果你运行:

import numpy as np
from numba import jit


@jit(nopython=True)
def test():
    arr = np.array([[[11, 12, 13], [11, 12, 13]], [[21, 22, 23], [21, 22, 23]]])

    arr2 = arr[:, 0, :]

    arr3 = arr2.argsort()

    print(arr3)

test()

它会失败:

numba.core.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Invalid use of BoundFunction(array.argsort for array(int64, 2d, A)) with parameters ()
During: resolving callee type: BoundFunction(array.argsort for array(int64, 2d, A))
During: typing of call at /home/stark/Work/mmr6/test.py (41)


File "test.py", line 41:
def test():
    <source elided>

    arr3 = arr2.argsort()
    ^

argsort 应该在最后一个轴上进行 argsort。本质上它应该给我:

>>>
[[0 1 2]
 [0 1 2]]

我认为复制arr2 数组(使用copy())可以解决问题,因为它会使数组在内存中连续(而不是视图),但是除了arr2 的类型之外,它会失败并显示相同的消息现在消息中的 array(int64, 2d, C) 符合预期。

为什么会失败,我该如何解决?

【问题讨论】:

  • numba 真的很糟糕,我过去用过它,有一半的时间它会抛出错误,无法将代码编译成 C。它在@987654328 行失败的原因@是因为它不理解如何将numpy编译成C代码。
  • 我的建议是根本不要使用 numba,numpy 已经是一个非常优化的库,所以无论如何都不需要它。
  • numba 不完全支持多维数组。使用 nd-arrays 时有些事情会起作用,但很多事情不会并且会抱怨“非连续数组”
  • @Vinzent 它不...?我记得过去用@njit 使用它们。
  • @MateenUlhaq 一些(一些)事情有效,但很多其他事情却没有。

标签: python jit numba


【解决方案1】:

遗憾的是,这是当前已知的 Numba 限制。见this issue。目前只支持一维数组。但是,您的情况有一个简单的解决方法:

import numpy as np
from numba import jit


@jit(nopython=True)
def test():
    arr = np.array([[[11, 12, 13], [11, 12, 13]], [[21, 22, 23], [21, 22, 23]]])

    arr2 = arr[:, 0, :]

    arr3 = np.empty(arr2.shape, dtype=arr2.dtype)
    for i in range(arr2.shape[0]):
        arr3[i] = arr2[i, :].argsort()

    print(arr3)

test()

请注意,即使实现了,也不会更快。见this issue。实际上,对于任何给定的 Numpy 原语,Numba 没有理由更快。但是,您可以使用 Numba 手动编写自己的 Numpy 原语版本,并且有时由于算法专业化、并行性或数学优化(例如快速数学)而得到加速。当您想要执行 Numpy 中尚未/直接可用的高效操作时,Numba 通常很棒,并且可以使用循环轻松实现此操作。

实际上,您可以使用 Numba 的 prange 和 JIT 参数 parallel=True 来加快计算速度,假设 argsort 尚未并行运行(AFAIK 它应该是顺序的)。这应该比大数组上的 Numpy 实现(也不应该顺序运行)快一点(在小数组上,产生多个线程的成本可能比实际计算大)。

【讨论】:

  • 是的,没错——这只是这个问题的一个典型例子。在我的真实代码中,我主要使用 numba 来利用 prange。非常感谢,那我就那样做吧。
猜你喜欢
  • 1970-01-01
  • 2012-07-06
  • 2013-08-08
  • 1970-01-01
  • 1970-01-01
  • 2012-12-28
  • 1970-01-01
  • 2010-10-24
相关资源
最近更新 更多