从JIT编译代码中回调到Python解释器
少数情况下,nopython模式函数需要回调到Python解释器以调用Numba无法编译的代码。这些情况包括:
为长时间运行的JIT编译函数记录进度;
使用Numba当前不支持的数据结构;
使用Python调试器调试JIT编译的代码。
当Numba回调到Python解释器时,需要执行以下操作:
获取GIL;
将本地表示形式的值转换回Python对象;
回调到Python解释器;
将Python代码返回的值转换成本地表示形式;
释放GIL。
这些步骤可能开销很大。用户**不应**在性能关键路径上依赖此处描述的功能。
objmode
上下文管理器
警告
此功能容易被误用。用户在使用此功能之前,应首先考虑其他方法来实现其预期目标。
- numba.objmode(*args, **kwargs)
创建一个上下文管理器,用于JIT编译函数内部,以进入*对象模式*来使用解释器功能。with上下文的主体被提升到一个以*对象模式*编译的函数中。此转换过程是有限的,不能处理所有可能的Python代码。但是,用户可以将复杂逻辑封装在另一个Python函数中,然后由解释器执行。
将其用作只接受关键字参数的函数。参数名必须与with块中的输出变量对应。它们各自的值可以是:
表示预期类型的字符串;即,
"float32"
。编译时绑定的全局或非局部变量,引用预期类型。这些变量在编译时读取。
退出with上下文时,输出变量将根据注解转换为预期的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块不能使用传入的列表对象。
with块不能使用传入的函数对象。
with块不能
yield
,break
,return
或raise
,从而立即离开with块执行。with块不能包含 with 语句。
随机数生成器状态不同步;即,nopython模式和对象模式使用不同的RNG状态。
注意
在非nopython模式下使用时,此上下文管理器无效。
警告
此功能是实验性的。支持的功能可能会在不通知的情况下更改。