从JIT编译的代码中回调Python解释器
在极少数但确实存在的情况下,一个 nopython 模式的函数需要回调到 Python 解释器以调用无法被 Numba 编译的代码。这种情况包括:
记录长时间运行的JIT函数的进度;
使用当前Numba不支持的数据结构;
在JIT编译的代码中使用Python调试器进行调试。
当 Numba 回调 Python 解释器时,以下情况必须发生:
获取 GIL;
将本机表示中的值转换回 Python 对象;
回调到 Python 解释器;
将Python代码返回的值转换为本地表示;
释放 GIL。
这些步骤可能会很耗费资源。用户**不应**在性能关键的路径上依赖此处描述的功能。
objmode
上下文管理器
警告
此功能容易被误用。用户在使用此功能之前应首先考虑其他方法来实现其预期目标。
- numba.objmode(*args, **kwargs)
创建一个上下文管理器,用于在 jitted 函数内部进入 对象模式 以使用解释器功能。with-context 的主体被提升为一个在 对象模式 下编译的函数。这个转换过程是有限的,不能处理所有可能的 Python 代码。然而,用户可以将复杂的逻辑包装在另一个 Python 函数中,该函数将由解释器执行。
将其用作仅接受关键字参数的函数。参数名称必须对应于with-block的输出变量。它们的相应值可以是:
表示预期类型的字符串;例如
"float32"
。编译时绑定的全局或非局部变量,引用预期的类型。这些变量在编译时读取。
当退出 with-context 时,输出变量根据注释转换为预期的 nopython 类型。此过程与将 Python 对象传递给 nopython 函数的参数相同。
示例:
import numpy as np from numba import njit, objmode, types def bar(x): # This code is executed by the interpreter. return np.asarray(list(reversed(x.tolist()))) # Output type as global variable out_ty = types.intp[:] @njit def foo(): x = np.arange(5) y = np.zeros_like(x) with objmode(y='intp[:]', z=out_ty): # annotate return type # this region is executed by object-mode. y += bar(x) z = y return y, z
备注
已知限制:
with-block 不能使用传入的列表对象。
with-block 不能使用传入的函数对象。
with-block 不能
yield
、break
、return
或raise
,以使执行将立即离开 with-block。with-block 不能包含 with 语句。
随机数生成器状态不会同步;即 nopython 模式和对象模式使用不同的 RNG 状态。
备注
在非Python模式外使用时,上下文管理器无效。
警告
此功能是实验性的。支持的功能可能会在没有通知的情况下更改。