为什么 numba 适用于 numpy 字符串向量而不适用于 numpy 字符串?

Why does numba work on numpy string vectors but not on numpy strings?

考虑最简单的函数

@numba.jit
def foo(s1):
    return s1

现在正在构造 np.bytes_ 个对象的数组

> a = np.array(['abc']*5, dtype='S5')
> a
array([b'abc', b'abc', b'abc', b'abc', b'abc'], dtype='|S5')

为什么用矢量调用 foo 有效:

> foo(a)
array([b'abc', b'abc', b'abc', b'abc', b'abc'], dtype='|S5')

但是用单个元素调用 foo 会引发异常

> foo(a[0])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_8124/2559272744.py in <module>
----> 1 foo(a[0])

TypeError: bad argument type for built-in operation

(这是来自 Windows 上的 conda-forge 的 运行 numba 0.54.1 以及 Python 3.9.7 和 numpy 1.20.3)

bytesnp.bytes_ 类型都未在最新版本的 the set of types supported by numba 中列出。它支持的最接近的东西是:

  1. 字符序列(读作:str)(尽管它明确表示“对它们没有可用的操作”,所以这很没用);如果您调用 foo(a[0].decode()) 使其成为文本,您的函数将起作用(但只是因为它是一个非常无用的函数)
  2. 实际 numpy 个数组;将 bytes/np.bytes_ 视为 np.array 的成本非常低,因此您可以这样做: foo(np.frombuffer(a[0], np.uint8)) 并生成在编程上更有用且代表相同的东西数据。

bytes 类型与 str 类型一样,几乎不支持。他们的支持非常低效,而且支持极简。此外,还有一些已打开的相关错误(如 this one。此外,据我所知,短期内没有计划解决此问题。

根据我的理解,a[0] returns 是 numpy.bytes_ 类型的对象,它与 bytes 不完全兼容(至少对于 Numba 而言)。使用 numpy.bytes_ 编译函数似乎会导致一个错误,使 Numba 在 numpy.bytes_bytes 之间混淆(Numba 尝试使用错误类型的编译函数)。

确实,以下代码有效:

@numba.jit
def foo(s1):
    return s1

foo(b'test')      # Works
foo(bytes(a[0]))  # Works

以下代码失败:

@numba.jit
def foo(s1):
    return s1

foo(a[0])         # Fail and cause a bug
foo(bytes(a[0]))  # Now fail (do not recompile the function properly)
foo(b'test')      # Also fail (do not recompile the function properly)

请注意,bytes 类型仅在 read-only 模式下受支持。