1.9。提前编译代码

原文: http://numba.pydata.org/numba-doc/latest/user/pycc.html

虽然 Numba 的主要用例是即时编译,但它也为提前编译(AOT)提供了便利。

1.9.1。概述

1.9.1.1。好处

  1. AOT 编译生成一个编译的扩展模块,它不依赖于 Numba:您可以在没有安装 Numba 的机器上分发模块(但需要 Numpy)。
  2. 运行时没有编译开销(但请参阅@jit 缓存选项),也没有导入 Numba 的任何开销。

也可以看看

编译的扩展模块在 Python 打包用户指南中讨论。

1.9.1.2。限制

  1. AOT 编译只允许常规功能,而不是 ufuncs
  2. 您必须明确指定功能签名。
  3. 每个导出的函数只能有一个签名(但您可以使用不同的名称导出多个不同的签名)。
  4. AOT 编译为您的 CPU 架构系列生成通用代码(例如“x86-64”),而 JIT 编译生成针对您的特定 CPU 模型优化的代码。

1.9.2。用法

1.9.2.1。独立示例

  1. from numba.pycc import CC
  2. cc = CC('my_module')
  3. # Uncomment the following line to print out the compilation steps
  4. #cc.verbose = True
  5. @cc.export('multf', 'f8(f8, f8)')
  6. @cc.export('multi', 'i4(i4, i4)')
  7. def mult(a, b):
  8. return a * b
  9. @cc.export('square', 'f8(f8)')
  10. def square(a):
  11. return a ** 2
  12. if __name__ == "__main__":
  13. cc.compile()

如果您运行此 Python 脚本,它将生成名为my_module的扩展模块。根据您的平台,实际文件名可能是my_module.somy_module.pydmy_module.cpython-34m.so等。

生成的模块有三个功能:multfmultisquaremulti以 32 位整数(i4)运行,而multfsquare以双精度浮点运算(f8):

  1. >>> import my_module
  2. >>> my_module.multi(3, 4)
  3. 12
  4. >>> my_module.square(1.414)
  5. 1.9993959999999997

1.9.2.2。 Distutils 整合

您还可以使用 distutils 或 setuptools 在setup.py脚本中集成扩展模块的编译步骤:

  1. from distutils.core import setup
  2. from source_module import cc
  3. setup(...,
  4. ext_modules=[cc.distutils_extension()])

上面的source_module是定义cc对象的模块。像这样编译的扩展会自动包含在 Python 项目的构建文件中,因此您可以将它们分发到二进制包(如 wheel 或 Conda 包)中。请注意,在使用 conda 的情况下,用于 AOT 的编译器需要是 Anaconda 发行版中可用的编译器。

1.9.2.3。签名语法

导出签名的语法与@jit装饰器中的语法相同。您可以在类型参考中阅读更多相关信息。

以下是在 1d 数组上导出二阶中心差异的实现的示例:

  1. @cc.export('centdiff_1d', 'f8[:](f8[:], f8)')
  2. def centdiff_1d(u, dx):
  3. D = np.empty_like(u)
  4. D[0] = 0
  5. D[-1] = 0
  6. for i in range(1, len(D) - 1):
  7. D[i] = (u[i+1] - 2 * u[i] + u[i-1]) / dx**2
  8. return D

您也可以省略返回类型,然后由 Numba 推断:

  1. @cc.export('centdiff_1d', '(f8[:], f8)')
  2. def centdiff_1d(u, dx):
  3. # Same code as above
  4. ...