如何解决Numba AOT编译含函数依赖的代码时出现的类型识别错误
Numba AOT编译内部函数调用报错解决方案
该报错并非因为Numba不支持AOT编译存在内部依赖调用的函数,核心原因是:仅通过
@cc.export装饰的函数不会自动暴露Numba可识别的类型签名,编译上层函数calc2时,解释器会把calc识别为普通Python函数,无法匹配对应的类型。
解决方案1:给被调用函数添加明确签名的@njit装饰器
这是最通用的解决方案,无论你是否需要将被调用函数暴露为导出接口都可以使用:
- 如果
calc不需要对外暴露,只做内部调用,可以省略@cc.export装饰,仅保留带签名的@njit即可 - 如果
calc需要对外导出,按@cc.export在上、@njit在下的顺序装饰即可
注意装饰器中填写的函数签名需要和@cc.export中声明的签名保持一致,避免类型不匹配报错
修正后的代码示例:
from numba.pycc import CC from numba import njit cc = CC('test') cc.verbose = True # 需对外导出calc的写法 @cc.export('calc', 'f8(f8, f8)') @njit('f8(f8, f8)') def calc(a, b): return a + b @cc.export('calc2', 'f8(f8, f8)') @njit('f8(f8, f8)') def calc2(a, b): return a * calc(a, b) if __name__ == "__main__": cc.compile()
解决方案2:仅编译导出入口函数,内部函数自动推导
如果你的依赖调用层级简单,内部函数逻辑没有Numba不支持的语法,也可以仅给最上层的导出函数加@njit装饰,Numba会自动推导内部调用的函数类型,不需要给内部函数加任何装饰:
from numba.pycc import CC from numba import njit cc = CC('test') cc.verbose = True # 内部调用函数不需要额外装饰,编译时会自动推导类型 def calc(a, b): return a + b @cc.export('calc2', 'f8(f8, f8)') @njit('f8(f8, f8)') def calc2(a, b): return a * calc(a, b) if __name__ == "__main__": cc.compile()
内容的提问来源于stack exchange,提问作者basil_man
相关产品推荐
相关产品推荐

