版本 0.59.0 (2024年1月31日)
这是一个主要的 Numba 版本发布。Numba 现在支持 Python 3.12,请在下方找到所有值得注意项目的摘要。
亮点
Python 3.12 支持
此版本的突出特点是 Numba 正式支持 Python 3.12。
请注意,此版本中(针对 Python 3.12)暂时禁用了性能分析支持,并且在开发过程中已发现若干已知问题。Numba 团队正在积极解决这些问题。请参阅相关问题页面(Numba #9289 和 Numba #9291)以获取正在进行的修复列表和进度更新。
(PR-#9246)
将最低支持的 Python 版本移至 3.9。
已移除对 Python 3.8 的支持,Numba 的最低支持 Python 版本现在是 Python 3.9。
(PR-#9310)
新功能
添加对 ufunc 属性和 reduce 的支持
增加了对 ufunc.reduce
和大多数 ufunc 属性的支持。
(PR-#9123)
添加一个配置变量以启用/禁用 llvmlite 内存管理器
添加了一个配置变量,用于强制启用或禁用 llvmlite 内存管理器。
(PR-#9341)
改进
将 TargetLibraryInfo
传递添加到 CPU LLVM 管道。
TargetLibraryInfo
过程确保在调用简化期间进行的优化适合目标平台,如果没有这个过程,目标平台将被假定为Linux,代码将被优化以生成例如在Windows上不存在的数学符号。历史上,这个问题通过使用Numba内部库携带包装符号来避免,但这样做可能会损害性能。由于这一变化,Numba内部库变得更小,并且在使用``exp2``和``log2``函数的代码中增加了优化机会。
(PR-#9336)
Numba 弃用警告类现在是内置警告类的子类
为了帮助用户管理和抑制来自 Numba 的弃用警告,NumbaDeprecationWarning
和 NumbaPendingDeprecationWarning
类现在分别是内置 DeprecationWarning
和 PendingDeprecationWarning
的子类。因此,DeprecationWarning
和 PendingDeprecationWarning
上的警告过滤器将适用于 Numba 的弃用警告。
(PR-#9347)
NumPy 支持
添加了对 np.indices() 函数的支持。
添加了对 numpy.indices()
的支持。
(PR-#9126)
添加了对 np.polynomial.polynomial.Polynomial
类的支持。
为包 np.polynomial.polynomial
中的 Polynomial 类添加了支持。
(PR-#9140)
增加了对函数 np.polynomial.polyutils.as_series()
的支持,以及来自 np.polynomial.polynomial
的函数 polydiv()
、polyint()
、polyval()
。
增加了对 np.polynomial.polyutils.as_series()
、np.polynomial.polynomial.polydiv()
、``np.polynomial.polynomial.polyint()``(仅前两个参数)、``np.polynomial.polynomial.polyval()``(仅前两个参数)的支持。
(PR-#9141)
添加了对 np.unwrap() 函数的支持。
为 numpy.unwrap()
添加了支持。仅当 axis
参数的值等于 -1 时才支持该参数。
(PR-#9154)
添加了对检查数据类型是否相等的功能支持。
增加了对检查两个 dtype 对象是否相等的支持,例如 assert X.dtype == np.dtype(np.float64)
。
(PR-#9249)
CUDA API 变更
增加了对使用C ABI编译设备函数的支持
通过 compile_ptx()
API 支持使用 C ABI 编译设备函数,以便更容易与 CUDA C/C++ 和其他语言进行互操作。
(PR-#9223)
使 grid() 和 gridsize() 使用 64 位整数
cuda.grid()
和 cuda.gridsize()
现在使用64位整数,因此当网格包含超过 2 ** 31
个线程时,它们不再溢出。
(PR-#9235)
通过实现使用列表来防止内核被丢弃
使用 nvJitLink 编译和链接时,内核不再被丢弃,因为它们被添加到 @"llvm.used"
列表中。
(PR-#9267)
支持 Windows CUDA 12.0 工具包 conda 包
在Windows上,CUDA工具包12.0的conda包中使用的库路径被添加到检测CUDA库时使用的搜索路径中。
(PR-#9279)
性能提升与变更
改进IR复制速度
对 FunctionIR
的深度复制进行了改进。在一种情况下,InlineInlineables
过程的速度提高了3倍。
(PR-#9245)
Bug 修复
动态分配 Parfor 调度
此PR修复了一个问题,即并行区域在循环中多次执行。之前的代码使用alloca在栈上分配parfor调度,但如果循环中有许多这样的parfor,则会导致栈溢出。新代码在并行区域前后分别调用Numba并行运行时的分配/释放对。目前,这些调用重定向到malloc/free,尽管其他机制如池化也是可能的,并且可能会在以后实现。此PR还增加了在prange循环未转换为parfor的情况下发出警告。如果循环中有异常控制流,可能会发生这种情况。这些是相关的,因为原始问题中有一个prange循环未转换为parfor,因此prange主体内的所有parfor都在并行运行,每次都增加栈的使用。
(PR-#9048)
在 @guvectorize
函数中支持多种输出
此PR修复了 Numba #9058 ,现在可以调用具有多个输出的guvectorize。
(PR-#9049)
在 PythonAPI.call
中修复了对 None
参数的处理。
修复了当 args=None
传递给 PythonAPI.call
时发生的段错误。
(PR-#9089)
修复PHI节点中字面值的传播。
修复了字面量传播过程中一个错误,其中PHI节点可能被错误地替换为常量。
(PR-#9144)
numpy.digitize
实现行为与 numpy 一致
numpy.digitize
的实现已更新,以在更广泛的情况下按照 numpy 的行为方式进行操作,包括在提供的 bins 实际上不是单调的情况下。
(PR-#9169)
numpy.searchsorted
和 numpy.sort
行为更新
numpy.searchsorted
的实现已更新,以在更广泛的使用场景中产生与 numpy 相同的输出,包括提供的数组 a 实际上未正确排序的情况。numpy.searchsorted
实现了一个修复,针对 side=’right’ 且提供的数组 a 包含 NaN 的情况。numpy.searchsorted
实现扩展以支持复杂输入。numpy.sort
(以及array.sort
) 的实现扩展以支持复杂数据的排序。
(PR-#9189)
修复SSA以考虑变量,其中使用不受定义支配
SSA 问题被修复,使得条件定义的变量将接收一个 phi 节点,表明存在一条路径,其中该变量是未定义的。这会影响依赖 SSA 行为的扩展代码。
(PR-#9242)
修复了 prange
中的 RecursionError
使用 prange
的某些循环模式导致编译器出现 RecursionError
的问题已修复。以下展示了此类循环的一个示例。该问题会导致编译器陷入无限递归循环,试图确定 var1
和 var2
的定义。该模式涉及在 if-else 树中定义变量,但并非所有分支都定义了这些变量。
for i in prange(N):
for j in inner:
if cond1:
var1 = ...
elif cond2:
var1, var2 = ...
elif cond3:
pass
if cond4:
use(var1)
use(var2)
(PR-#9244)
在 ufunc.reduce 中支持负轴。
修复了 ufunc.reduce 中的一个错误,以正确处理负轴值。
(PR-#9296)
修复 parfor 归约与 Python 3.12 的问题。
parfor 归约代码对它发现的语句顺序有一定的期望,这些期望基于 Numba 先前版本生成的代码。在 Python 3.12 中,过去紧随归约操作符语句(如二元操作)的赋值语句,现在被移到了自己的基本块中。这一变化重新排序了发现的归约节点集合,使得该赋值语句紧随归约操作符之后,就像在之前的 Numba 版本中一样。这仅影响内部的 parfor 归约代码,实际上并不改变 Numba IR。
(PR-#9334)
更改
使测试列表不调用CPU编译。
Numba 的测试列表命令 python -m numba.runtests -l
由于测试套件中某些测试函数的声明方式,历史上会触发 CPU 目标编译。现在已调整为在测试列表时不调用 CPU 目标编译器,并添加了一个测试以确保这种情况保持不变。
(PR-#9309)
由于 Python 3.12 在推导式中的变量遮蔽导致的语义差异
Python 3.12 引入了一个新的字节码 LOAD_FAST_AND_CLEAR
,它仅在推导式中使用。它具有 Numba 无法建模的动态语义。
例如,
def foo():
if False:
x = 1
[x for x in (1,)]
return x # This return uses undefined variable
变量 x 在返回语句中未定义。Numba 不会引发 UnboundLocalError
,而是在编译时如果使用了未定义的变量,会引发 TypingError
。
然而,Numba 并不能总是检测到未定义的变量。
例如,
def foo(a):
[x for x in (0,)]
if a:
x = 3 + a
x += 10
return x
调用 foo(0)
返回 10
而不是引发 UnboundLocalError
。这是因为 Numba 在运行时不跟踪变量的生命周期。返回值是 0 + 10
,因为 Numba 会将未定义的变量零初始化。
(PR-#9315)
重构并移除遗留的API/测试内部组件。
为了便于一般维护,减少调用编译的可能方式,已移除了一些内部使用的函数,具体包括:
numba.core.compiler.compile_isolated
已被移除。numba.tests.support.TestCase::run_nullary_func
已被移除。numba.tests.support.CompilationCache
已被移除。
此外,”嵌套上下文” 的概念已从 numba.core.registry.CPUTarget
中移除,连同其实现细节。目标扩展的维护者(那些使用 numba.core.target_extension
中的 API 来扩展 Numba 对自定义/合成硬件支持的人)应注意,如果存在,同样可以从 numba.core.descriptor.TargetDescriptor
的目标扩展实现中删除。也就是说,nested_context
方法及其相关实现细节可以从自定义目标的 TargetDescriptor
中直接移除。
此外,在重构过程中发现了一个关于记录数组类型的错误。事实证明,仅在可变性上有所不同的两种记录类型可能会混淆,这一问题现已修复。
(PR-#9330)
弃用
显式设置 NUMBA_CAPTURED_ERRORS=old_style
将引发弃用警告
根据旧样式错误捕获的弃用计划,显式设置 NUMBA_CAPTURED_ERRORS=old_style
将引发弃用警告。此版本是最后一个使用“旧样式”作为默认值的版本。详细信息记录在 https://numba.readthedocs.io/en/0.58.1/reference/deprecation.html#deprecation-of-old-style-numba-captured-errors
(PR-#9346)
已过时的弃用
对象模式 回退 支持已被移除。
根据 Numba 0.59.0 的弃用计划,所有 Numba jit
系列装饰器中已移除对“对象模式回退”的支持。此外,nopython
关键字参数的默认值已更改为 True
,这意味着所有 Numba jit
系列装饰的函数现在默认将以 nopython
模式编译。
(PR-#9352)
移除已弃用的API @numba.generated_jit
。
根据 0.59.0 的弃用计划,@numba.generated_jit
的支持已被移除。建议使用 @numba.extending.overload
和高级扩展 API 作为替代。
(PR-#9353)
拉取请求:
PR #9058: 修复具有多个输出的gufunc (guilhermeleobas)
PR #9089: 修复在 PythonAPI.call 中为 args 传递 None 时的段错误 (hellozee)
PR #9123: 实现大多数ufunc属性和ufunc.reduce (guilhermeleobas)
PR #9126: 添加对 np.indices() 的支持 (KrisMinchev)
PR #9140: 添加对 Polynomial 类的支持 (KrisMinchev)
PR #9141: 添加对 np.polynomial.polyutils 中的 as_series() 以及 np.polynomial.polynomial 中的 polydiv()、polyint()、polyval() 的支持 (KrisMinchev)
PR #9144: 修复在PHI节点中错误传播字面量时的错误 (guilhermeleobas)
PR #9154: 添加对 np.unwrap() 的支持 (KrisMinchev)
PR #9168: 修复 overload_method 模板中的 get_template_info 方法 (dlee992 sklam)
PR #9191: 添加一个 Numba 自检脚本并在 CI 中使用。(stuartarchibald)
PR #9246: 支持 Python 3.12 (stuartarchibald kc611 esc)
PR #9249: 添加对检查dtypes相等的支持 (saulshanabrook)
PR #9296: 修复当轴为负数时的错误,并检查轴是否无效 (guilhermeleobas)
PR #9309: 继续 #9044,在列出测试时防止在 CPU 目标上进行编译。(stuartarchibald apmasell)
PR #9310: 移除对 Python 3.8 的支持。(stuartarchibald)
PR #9330: 重构并移除遗留的API/测试内部实现。(stuartarchibald)
PR #9331: 修复来自3.12的语法和弃用警告。(stuartarchibald)
PR #9336: 添加 TargetLibraryInfo 传递到 CPU LLVM 管道。(stuartarchibald)
PR #9346: 设置
NUMBA_CAPTURED_ERRORS=old_style
现在会引发警告。(sklam)PR #9352: 从 @jit 中移除对象模式回退。(stuartarchibald)
PR #9353: 移除 numba.generated_jit (stuartarchibald)
PR #9356: 重构打印测试以避免NRT泄漏问题。(stuartarchibald)
PR #9357: 修复 _set_init_process_lock 警告中的一个拼写错误。(stuartarchibald)
PR #9358: 移除关于轮子中OpenMP限制的说明。(stuartarchibald)
PR #9359: 修复针对objmode回退的test_jit_module测试。(stuartarchibald)
PR #9402: 0.59 最终版本的文档更新 (sklam stuartarchibald)
PR #9403: 修复测试套件中有状态配置的测试隔离 (sklam stuartarchibald)
PR #9404: 修复 Python 3.12.1 的跳过测试 stderr 更改。(stuartarchibald)