提前编译代码
虽然 Numba 的主要用例是即时编译,但它也提供了提前编译(AOT)的功能。
注意
要使用此功能,在编译时需要 setuptools
包,但它不是生成扩展模块的运行时依赖项。
注意
此模块正在等待弃用。有关更多信息,请参阅numba.pycc 模块的弃用。
概述
优点
AOT 编译生成一个不依赖于 Numba 的已编译扩展模块:您可以在未安装 Numba 的机器上分发该模块(但需要 NumPy)。
运行时没有编译开销(但请参阅
@jit
缓存 选项),也没有导入 Numba 的开销。
另请参阅
Python 打包用户指南中讨论了已编译的扩展模块。
用法
独立示例
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 集成
您还可以使用 distutils 或 setuptools 将扩展模块的编译步骤集成到您的 setup.py
脚本中。
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
装饰器中相同。您可以在类型参考中阅读更多相关信息。
这是一个导出 1d 数组上二阶中心差分实现的示例
@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
...