jitclass 属性中的空集

Empty set in a jitclass attribute

我需要创建一个 set 作为 jitclass 属性,它必须以空开头:

import numba as nb

@nb.jitclass([('foo', nb.types.Set(nb.f8))])
class Bar:
    def __init__(self):
        self.foo = set()

b = Bar()

但它失败了,因为 numba 不知道临时 set 变量包含的对象的类型:

Failed in nopython mode pipeline (step: nopython frontend)
Cannot infer the type of variable '[=11=].2' (temporary variable),
have imprecise type: set(undefined).

这虽然有效:

import numba as nb

@nb.jitclass([('foo', nb.types.Set(nb.f8))])
class Bar:
    def __init__(self):
        self.foo = {0.}
        self.foo.clear()

b = Bar()

但是解决方案真的很难看。有没有更好的方法来初始化空set?

我正在使用 Python 3.6 和 Numba 0.45.1

您不能在 jitclass__init__ 中实例化空的 "Python classes"。 lists:

也会发生同样的问题(从 numba 0.45.1 开始)
@nb.jitclass([('foo', nb.types.List(nb.f8))])
class Bar:
    def __init__(self):
        self.foo = []
TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Failed in nopython mode pipeline (step: nopython frontend)
Cannot infer the type of variable '[=11=].1' (temporary variable), have imprecise type: list(undefined).

这里的问题是 numba 通过分析函数体来推断类型。它没有考虑 class 的规范。


我个人会创建一个函数包装器来创建空集,这样如果(或何时)numba 决定基于 signature/specification 创建空集,更改代码会更容易:

import numba as nb

@nb.njit
def create_empty_set_float64():
    aset = {1.}
    aset.clear()
    return aset

@nb.jitclass([('foo', nb.types.Set(nb.f8))])
class Bar:
    def __init__(self):
        self.foo = create_empty_set_float64()

b = Bar()