python - python/numpy 中的 float 学不能跨机器重现

标签 python numpy floating-point blas

比较几台不同机器的浮点计算结果,它们始终产生不同的结果。这是一个重现该行为的精简示例:

import numpy as np
from numpy.random import randn as rand

M = 1024
N = 2048
np.random.seed(0)

a = rand(M,N).astype(dtype=np.float32)
w = rand(N,M).astype(dtype=np.float32)

b = np.dot(a, w)
for i in range(10):
    b = b + np.dot(b, a)[:, :1024]
    np.divide(b, 100., out=b)

print b[0,:3]

不同的机器产生不同的结果,比如

  • [-2.85753540e-05 -5.94204867e-05 -2.62337649e-04]
  • [-2.85751412e-05 -5.94208468e-05 -2.62336689e-04]
  • [ -2.85754559e-05 -5.94202756e-05 -2.62337562e-04]

但我也可以获得相同的结果,例如通过在同一年份的两台 MacBook 上运行。这发生在具有相同版本的 Python 和 numpy 的机器上,但不一定链接到相同的 BLAS 库(例如,Mac 上的加速框架,Ubuntu 上的 OpenBLAS)。然而,不同的数值库不应该都符合相同的 IEEE 浮点标准并给出完全相同的结果吗?

最佳答案

浮点计算并不总是可重现的。

如果您使用相同的可执行镜像、输入、使用相同的编译器和相同的编译器设置(开关)构建的库,您可能在不同机器上获得可重现的 float 计算结果。

但是,如果您使用动态链接库,您可能会得到不同的结果,原因有很多。首先,作为 Veedrac pointed in comments它可能在不同的体系结构上对其例程使用不同的算法。其次,编译器可能会根据开关(各种优化、控制设置)生成不同的代码。即使是 a+b+c 也会在机器和编译器之间产生不确定的结果,因为我们无法确定求值顺序和中间计算的精度。

阅读here为什么不能保证在不同的 IEEE 754-1985 实现上获得相同的结果。新标准 (IEEE 754-2008) 试图走得更远,但它仍然不能保证不同实现之间的结果相同,因为例如它允许实现者选择何时检测到微小(下溢异常)

有关浮点确定性的更多信息可以在 this article 中找到.

关于python - python/numpy 中的 float 学不能跨机器重现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30065437/

相关文章:

python - 在这种情况下,内存分配在 python 中是如何工作的?

C - 将 float 存储到 char 数组并反转

C float 初始化结果意外

C程序没有正确添加 float

python - os.walk 函数的问题

python - OpenCV 读取具有多个流/轨道的视频文件

python - 如何对 Numpy datetime64 数组进行切片

python - 如何创建行间等差的 Numpy 二维数组?

Python Gmail Api Base64 解码电子邮件正文中的奇怪字符

python - 使用Pandas导出csv时如何指定数据类型和格式?