低级扩展API
此扩展API通过 numba.extending
模块提供。它允许你直接接入Numba的编译链。因此,它在几个编译阶段之间进行了区分:
在 类型 推导阶段,通过查看执行的操作来推导编译函数中变量的类型。
在 降低 阶段,将高级Python操作转换为低级LLVM代码。此阶段利用了类型推导阶段得出的类型信息。
装箱 和 拆箱 将 Python 对象转换为原生值,反之亦然。它们发生在从 Python 解释器调用 Numba 函数时的边界处。
打字
类型推断 – 或者简单地称为 类型化 – 是为函数中涉及的所有值分配 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
)。此函数也可以用作装饰器。它将装饰的函数注册为类型推断函数,当尝试推断 Python 类型的 Numba 类型时,由
as_numba_type
使用。装饰的函数以单个 py_type 参数调用,并返回相应的 Numba 类型,或者如果无法推断该 py_type,则返回None
。
降低
以下装饰器都接受某种类型的规范。类型规范通常是一个类型类(如 types.Float
)或一个特定的类型实例(如 types.float64
)。某些值具有特殊含义:
types.Any
匹配任何类型;这允许在实现内部进行自己的调度。types.VarArg(<某种类型>)
匹配任意数量的给定类型的参数;它只能在描述函数参数时作为最后一个类型规范出现。
以下API中的 context 参数是一个目标上下文,提供了各种用于代码生成的实用方法(例如创建常量、类型转换、查找特定函数的实现等)。 builder 参数是一个用于生成LLVM代码的 llvmlite.ir.IRBuilder
实例。
一个 签名 是一个指定操作具体类型的对象。签名的 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)
调用。typ 和 value 与lower_getattr()
中的相同。name 是正在查找的属性的名称。
- @lower_cast(fromspec, tospec)
将装饰的函数注册为从 fromspec 描述的类型转换为 tospec 描述的类型。装饰的函数以五个参数
(context, builder, fromty, toty, value)
调用。fromty 和 toty 分别是正在转换的源类型和目标类型。value 是正在转换的值。该函数必须返回与类型toty
兼容的值。
常量
- @lower_constant(typespec)
将装饰的函数注册为实现 Numba typespec 的常量创建。装饰的函数以四个参数
(context, builder, ty, pyval)
调用。ty 是为其创建常量的具体类型。pyval 是要转换为 LLVM 常量的 Python 值。该函数必须返回与类型ty
兼容的值。
装箱和拆箱
在这些函数中,c 是一个方便的对象,具有多个属性:
其
context
属性是一个如上所述的目标上下文它的
builder
属性是一个llvmlite.ir.IRBuilder
,如上所述。它的
pyapi
属性是一个对象,提供了对 Python 解释器的 C API 子集的访问。
对象,与原生值相对,是一个 PyObject *
指针。这样的指针可以通过 pyapi
对象中的方法生成或处理。
- @box(typespec)
将装饰的函数注册为匹配 typespec 的装箱值。装饰的函数以三个参数
(typ, val, c)
调用。typ 是正在装箱的具体类型。val 是正在装箱的值。该函数应返回一个 Python 对象,或返回 NULL 以表示错误。
- @unbox(typespec)
将装饰的函数注册为解包与 typespec 匹配的值。装饰的函数以三个参数
(typ, obj, c)
调用。typ 是正在解包的具体类型。obj 是正在解包的 Python 对象(在 C 术语中是PyObject *
指针)。该函数应返回一个NativeValue
对象,给出解包结果值和一个可选的错误位。