在单独的文件中使用 numba 编译 class 的问题

Issue with compiling a class with numba in a seperate file

我在使用带有 numba 的 jitclass 装饰器来“编译”我的 python 代码时遇到问题。在有人告诉我阅读文档之前,我不知道在何处查看文档,所以如果您要告诉我,请将我指向 numba 文档中的特定点:)

我现在拥有的示例(如果您尝试 运行 它,您需要使用 -O 标志使其退出调试模式):

# class in separate file
print(f"debug state = {__debug__}\n")
if not __debug__:
    from numba import int64, float64    # import types
    from numba import njit
    from numba.experimental import jitclass
    spec = [
        ('init_val', int64),
        ('spacing', float64),
    ]
def blank_dec(*args, **kwargs):
    return args[0]
dec = blank_dec if __debug__ else jitclass(spec)
@dec
class foo:
    def __init__(self, init_val, spacing):
        self.property = init_val
        self.spacing  = spacing
    def foobar(self):
        try:
            # method here, just adding numbers
        except Exception as e:
            if __debug__:
                print(e) # this line appears to give trouble, error below
            else:
                sys.stderr.write(e) # this also causes issues
        

#main file
if __name__ == "__main__":
    foobar = foo(16, 1E-05)

这代表了我的设置并重现了我得到的错误。这是错误(文件路径用“#######”编辑):

Traceback (most recent call last):

  File "main.py", line 4, in <module>

    foobar = tc.foo(16, 1E-05)

  File "#######/anaconda3/envs/PHYS/lib/python3.8/site-packages/numba/experimental/jitclass/base.py", line 124, in __call__

    return cls._ctor(*bind.args[1:], **bind.kwargs)

  File "#######/anaconda3/envs/PHYS/lib/python3.8/site-packages/numba/core/dispatcher.py", line 482, in _compile_for_args

    error_rewrite(e, 'typing')

  File ""#######/anaconda3/envs/PHYS/lib/python3.8/site-packages/numba/core/dispatcher.py", line 423, in error_rewrite

    raise e.with_traceback(None)

numba.core.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)

Failed in nopython mode pipeline (step: nopython frontend)

Cannot resolve setattr (instance.jitclass.foo#7f433450f1f0<init_val:int64,spacing:float64>).property = int64

File "testclass.py", line 20:
    def __init__(self, init_val, spacing):
        self.property = init_val
        ^

During: typing of set attribute 'property' at "#######/testing/testclass.py (20)

File "testclass.py", line 20:
    def __init__(self, init_val, spacing):
        self.property = init_val
        ^

During: resolving callee type: jitclass.foo#7f433450f1f0<init_val:int64,spacing:float64> During: typing of call at <string> (3)

During: resolving callee type: jitclass.foo#7f433450f1f0<init_val:int64,spacing:float64> During: typing of call at <string> (3)


File "<string>", line 3: <source missing, REPL/exec in use?> 

它似乎在抱怨字符串,但我不明白为什么。我看到另一个 post 说我需要使用编码来格式化字符串,但这似乎不是我的问题。

我也尝试删除 try-except 块和初始打印语句——因为我认为问题可能与打印语句有关,但这似乎无法解决问题。

非常感谢任何帮助!

如果您按照建议创建一个 minimal reproducible example,那么对于您和可以帮助您的人来说,一切都会变得更容易。

例如,您可以快速将问题“提炼”为:

spec = [
    ('init_val', nb.int64),
    ('spacing', nb.float64),
    ]

@nb.experimental.jitclass(spec)
class Foo:

    def __init__(self, init_val, spacing):
        self.property = init_val
        self.spacing = spacing

c = Foo(16, 1E-05)

同时出现同样的错误:

numba.core.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Failed in nopython mode pipeline (step: nopython frontend)
Cannot resolve setattr: (instance.jitclass.Foo#7f29d72ae850<init_val:int64,spacing:float64>).property = int64

File "test_numba.py", line 2569:
        def __init__(self, init_val, spacing):
            self.property = init_val
            ^

During: typing of set attribute 'property' at /home/jotaele/Devel/codetest/tests/test_numba.py (2569)

File "test_numba.py", line 2569:
        def __init__(self, init_val, spacing):
            self.property = init_val
            ^

Numba 恰恰指出了问题所在:您没有声明属性 property

如果您将规范更改为:

,它会编译
spec = [
    ('property', nb.int64),
    ('spacing', nb.float64),
    ]

更好的是,您可以使用类型注释代替经典规范:

@nb.experimental.jitclass
class Foo:
        
    property: nb.int64
    spacing: nb.float64

    def __init__(self, init_val, spacing):
        self.property = init_val
        self.spacing = spacing