提前编译代码
虽然 Numba 的主要用途是 即时编译,但它也提供了一个用于 提前编译 (AOT) 的功能。
备注
要使用此功能,编译时需要 setuptools
包,但它不是生成的扩展模块的运行时依赖项。
备注
此模块即将弃用。更多信息请参见 弃用 numba.pycc 模块。
概述
好处
AOT 编译生成一个不依赖于 Numba 的编译扩展模块:你可以在没有安装 Numba 的机器上分发该模块(但需要 NumPy)。
在运行时没有编译开销(但请参见
@jit
缓存 选项),也没有导入 Numba 的开销。
参见
编译后的扩展模块在 Python 打包用户指南 中进行了讨论。
限制
AOT 编译仅允许常规函数,不允许 ufuncs。
你必须明确指定函数签名。
每个导出的函数只能有一个签名(但你可以用不同的名称导出几个不同的签名)。
导出的函数不会检查传递给它们的参数类型;调用者应提供正确类型的参数。
AOT 编译为您的 CPU 架构系列(例如“x86-64”)生成通用代码,而 JIT 编译则为您的特定 CPU 型号生成优化的代码。
用法
独立示例
from numba.pycc import CC
cc = CC('my_module')
# Uncomment the following line to print out the compilation steps
#cc.verbose = True
@cc.export('multf', 'f8(f8, f8)')
@cc.export('multi', 'i4(i4, i4)')
def mult(a, b):
return a * b
@cc.export('square', 'f8(f8)')
def square(a):
return a ** 2
if __name__ == "__main__":
cc.compile()
如果你运行这个Python脚本,它将生成一个名为 my_module
的扩展模块。根据你的平台,实际的文件名可能是 my_module.so
、 my_module.pyd
、 my_module.cpython-34m.so
等。
生成的模块有三个函数:multf
、multi
和 square
。multi
操作 32 位整数 (i4
),而 multf
和 square
操作双精度浮点数 (f8
):
>>> import my_module
>>> my_module.multi(3, 4)
12
>>> my_module.square(1.414)
1.9993959999999997
Distutils 集成
你也可以在你的 setup.py
脚本中集成扩展模块的编译步骤,使用 distutils 或 setuptools:
from distutils.core import setup
from source_module import cc
setup(...,
ext_modules=[cc.distutils_extension()])
上面的 source_module
是定义 cc
对象的模块。像这样编译的扩展将自动包含在您的 Python 项目的构建文件中,因此您可以将它们分发在二进制包中,例如 wheels 或 Conda 包。请注意,在使用 conda 的情况下,用于 AOT 的编译器需要是 Anaconda 发行版中可用的那些。
签名语法
导出签名的语法与 @jit
装饰器中的相同。你可以在 类型 参考中阅读更多相关内容。
以下是一个在一维数组上实现二阶中心差分的导出示例:
@cc.export('centdiff_1d', 'f8[:](f8[:], f8)')
def centdiff_1d(u, dx):
D = np.empty_like(u)
D[0] = 0
D[-1] = 0
for i in range(1, len(D) - 1):
D[i] = (u[i+1] - 2 * u[i] + u[i-1]) / dx**2
return D
你也可以省略返回类型,Numba 将会自动推断:
@cc.export('centdiff_1d', '(f8[:], f8)')
def centdiff_1d(u, dx):
# Same code as above
...