低级扩展API

此扩展API可通过 numba.extending 模块获得。它允许您直接挂钩到 Numba 编译链中。因此,它区分了几个编译阶段

  • 通过查看执行的操作,类型推断(typing)阶段推导出编译函数中变量的类型。

  • 降级(lowering)阶段将高级 Python 操作转换为低级 LLVM 代码。此阶段利用类型推断阶段导出的类型信息。

  • 装箱(Boxing)拆箱(unboxing)将 Python 对象转换为原生值,反之亦然。它们发生在从 Python 解释器调用 Numba 函数的边界处。

类型推断(Typing)

类型推断——或简称为类型推断(typing)——是将 Numba 类型分配给函数中所有相关值的过程,以实现高效的代码生成。广义上讲,类型推断有两种形式:对普通 Python (例如函数参数或全局变量)进行类型推断,以及对已知值类型上的操作(或函数)进行类型推断。

@typeof_impl.register(cls)

将装饰的函数注册为对 cls 类的 Python 值进行类型推断。被装饰的函数将以签名 (val, c) 调用,其中 val 是正在进行类型推断的 Python 值,c 是一个上下文对象。

@type_callable(func)

将装饰的函数注册为对可调用对象 func 进行类型推断。func 可以是实际的 Python 可调用对象,也可以是表示 Numba 内部已知操作的字符串(例如 'getitem')。被装饰的函数会带一个 context 参数调用,并且必须返回一个类型推断函数。该类型推断函数应与正在推断类型的函数具有相同的签名,并以函数参数的 Numba 类型调用;它应该返回函数返回值的 Numba 类型,如果推断失败则返回 None

as_numba_type.register(py_type, numba_type)

注册 Python 类型 py_type 与 Numba 类型 numba_type 对应。这可用于注册新类型或覆盖现有默认值(例如,将 float 视为 numba.float32 而不是 numba.float64)。

此函数也可以用作装饰器。它将装饰函数注册为 as_numba_type 在尝试推断 Python 类型的 Numba 类型时使用的类型推断函数。被装饰的函数会带一个 py_type 参数调用,并返回相应的 Numba 类型,如果无法推断该 py_type 则返回 None

降级(Lowering)

以下所有装饰器都接受某种类型规范。类型规范通常是类型类(例如 types.Float)或特定类型实例(例如 types.float64)。某些值具有特殊含义

  • types.Any 匹配任何类型;这允许您在实现内部进行自己的调度

  • types.VarArg(<some type>) 匹配给定类型的任意数量的参数;它只能在描述函数参数时作为最后一个类型规范出现。

以下 API 中的 context 参数是一个目标上下文,提供各种用于代码生成的实用方法(例如创建常量、从一种类型转换为另一种类型、查找特定函数的实现等)。builder 参数是正在生成的 LLVM 代码的 llvmlite.ir.IRBuilder 实例。

signature 是一个指定操作具体类型的对象。签名的 args 属性是参数类型的元组。签名的 return_type 属性是操作应返回的类型。

注意

Numba 总是基于 Numba 类型进行推断,但在降级过程中传递的值是 LLVM 值:它们不包含所需的类型信息,这就是为什么 Numba 类型也需要显式传递的原因。

LLVM 有自己非常低级的类型系统:您可以通过查找其 .type 属性来访问值的 LLVM 类型。

原生操作

@lower_builtin(func, typespec, ...)

将装饰的函数注册为实现给定 Numba typespecs 所描述参数的可调用对象 func。与 type_callable() 一样,func 可以是实际的 Python 可调用对象,也可以是表示 Numba 内部已知操作的字符串(例如 'getitem')。

被装饰的函数会以四个参数 (context, builder, sig, args) 调用。sig 是调用可调用对象时所用的具体签名。args 是调用可调用对象时所用参数值的元组;args 中的每个值都对应于 sig.args 中的一个类型。函数必须返回与类型 sig.return_type 兼容的值。

@lower_getattr(typespec, name)

将装饰的函数注册为实现给定 typespec 的属性 name。被装饰的函数会以四个参数 (context, builder, typ, value) 调用。typ 是正在查找属性的具体类型。value 是正在查找属性的值。

@lower_getattr_generic(typespec)

将装饰的函数注册为给定 typespec 上属性查找的备用方案。任何没有相应 lower_getattr() 声明的属性都将通过 lower_getattr_generic() 处理。被装饰的函数会以五个参数 (context, builder, typ, value, name) 调用。typvaluelower_getattr() 中的含义相同。name 是正在查找的属性名称。

@lower_cast(fromspec, tospec)

将装饰的函数注册为将 fromspec 描述的类型转换为 tospec 描述的类型。被装饰的函数会以五个参数 (context, builder, fromty, toty, value) 调用。fromtytoty 分别是正在转换的源类型和目标类型。value 是正在转换的值。函数必须返回与类型 toty 兼容的值。

常量

@lower_constant(typespec)

将装饰的函数注册为为 Numba typespec 实现常量创建。被装饰的函数会以四个参数 (context, builder, ty, pyval) 调用。ty 是要创建常量的具体类型。pyval 是要转换为 LLVM 常量的 Python 值。函数必须返回与类型 ty 兼容的值。

装箱和拆箱

在这些函数中,c 是一个包含多个属性的便利对象

一个对象,与原生值相对,是一个 PyObject * 指针。此类指针可以通过 pyapi 对象中的方法生成或处理。

@box(typespec)

将装饰的函数注册为对与 typespec 匹配的值进行装箱。被装饰的函数会以三个参数 (typ, val, c) 调用。typ 是正在装箱的具体类型。val 是正在装箱的值。函数应返回一个 Python 对象,或返回 NULL 以表示错误。

@unbox(typespec)

将装饰的函数注册为对与 typespec 匹配的值进行拆箱。被装饰的函数会以三个参数 (typ, obj, c) 调用。typ 是正在拆箱的具体类型。obj 是正在拆箱的 Python 对象(在 C 语言中是一个 PyObject * 指针)。函数应返回一个 NativeValue 对象,该对象提供拆箱结果值和一个可选的错误位。