2.9。浮点陷阱
原文: http://numba.pydata.org/numba-doc/latest/reference/fpsemantics.html
2.9.1。精度和准确度
对于某些操作,Numba 可能使用与 Python 或 Numpy 不同的算法。结果可能不是逐位兼容的。差异通常应该很小并且在合理的期望范围内。但是,小的累积差异最终可能会产生很大的差异,特别是如果涉及不同的功能。
2.9.1.1。数学库实现
Numba 支持各种平台和操作系统,每个平台和操作系统都有自己的数学库实现(此处称为libm
)。 libm
中包含的大多数数学函数都有 IEEE 754 标准规定的特定要求(如sin()
,exp()
等),但每个实现都可能有错误。因此,在某些平台上,Numba 必须特别注意以解决已知的libm
问题。
另一个典型问题是操作系统的libm
功能集不完整,需要通过附加功能进行补充。这些参考 IEEE 754 和 C99 标准提供,并且通常以类似于等效 CPython 功能的方式在 Numba 中实现。
特别是,已知数学库问题会影响 Windows 上的 Python 2.7 构建,因为 Python 2.7 需要使用过时版本的 Microsoft Visual Studio 编译器。
2.9.1.2。线性代数
即使给出float32
输入,Numpy 也会强制某些线性代数运算以双精度模式运行。当所有输入都是float32
或complex64
时,Numba 将始终观察输入的精度,并调用单精度线性代数例程。
Numba 中numpy.linalg
例程的实现仅支持在提供底层核心功能的 LAPACK 函数中使用的浮点类型。因此,仅支持float32
,float64
,complex64
和complex128
类型。如果用户有例如在int32
类型中,在用于这些例程之前,必须对浮点类型执行适当的类型转换。这个决定的原因是基本上避免必须复制在 Numpy 中做出的类型转换选择,并且还鼓励用户为他们正在进行的操作选择最佳浮点类型。
2.9.1.3。混合型操作
Numpy 最常返回float64
作为使用混合整数和浮点操作数的计算结果(典型示例是幂运算符**
)。相比之下,Numba 将在浮点操作数中选择最高精度,因此例如float32 ** int32
将返回float32
,而不管输入值如何。这使得性能特征更容易预测,但如果需要额外的精度,则应明确地将输入转换为float64
。
2.9.2。警告和错误
当调用 vectorize()
创建的 ufunc 时,Numpy 将通过检查 FPU 错误字来确定是否发生错误。然后它可能会打印出警告或引发异常(例如RuntimeWarning: divide by zero encountered
),具体取决于当前的错误处理设置。
但是,根据 LLVM 如何优化 ufunc 代码,可能会出现一些虚假警告或错误。如果您遇到此问题,我们建议您调用 numpy.seterr()
来更改 Numpy 的错误处理设置,或者 numpy.errstate
上下文管理器暂时切换它们:
with np.errstate(all='ignore'):
x = my_ufunc(y)