浮点不确定性的原因?包括NumPy?

时间:2018-12-05 06:55:53

标签: numpy blas intel-mkl atlas non-deterministic

IEEE浮点运算是确定性的,但请参见How can floating point calculations be made deterministic?,以了解整体浮点计算可以是不确定性的一种方式:

  

...就执行浮点计算的顺序而言,并行计算是不确定的,这可能会导致各次运行的结果不精确。

两部分问题:

假设:

  • 相同的软件,相同的输入,相同的硬件。多次运行的输出应相等。
    • 如果这行得通,那么在进行代码重构后测试输出是否相等是非常必要的。 (是的,操作顺序的某些更改会使某些输出不相等。)
  • 程序中的所有随机数都是伪随机数,在所有运行中均以相同种子的相同方式使用。
  • 没有未初始化的值。 Python通常以这种方式是安全的,但是numpy.empty()返回一个新数组而不初始化条目。尚不清楚它在实践中会快得多。所以要当心!

    • @PaulPanzer的测试表明numpy.empty()确实返回了未初始化的数组,并且可以轻松快速地回收最近使用的数组:

      import numpy as np np.arange(100); np.empty(100, int); np.empty(100, int) np.arange(100, 200.0); np.empty(100, float); np.empty(100, float)

    • 为这些例程获取有用的时序测量非常棘手!在timeit循环中,numpy.empty()可以保持重新分配相同的一个或两个存储节点。时间与阵列大小无关。为防止回收:

      from timeit import timeit timeit('l.append(numpy.empty(100000))', 'import numpy; l = []') timeit('l.append(numpy.zeros(100000))', 'import numpy; l = []')

      但是将数组大小减小为numpy.zeros(10000)所需的时间是原来的15倍;将其减小到numpy.zeros(1000)所需的时间是我的MBP的1.3倍。令人困惑。

另请参见: Hash values are salted in Python 3 and each dict preserves insertion order。这可能会因运行而异。 [我正在Python 2.7.15中解决这个问题。]

1 个答案:

答案 0 :(得分:0)

我发现我遇到的大多数(不是全部)不确定性问题似乎已在OpenBLAS 0.3.5的代码中修复。

早期版本的OpenBLAS中有许多线程问题是fixed in release 0.3.4,但该版本具有macOS兼容性错误,该错误已在0.3.5版本的代码中修复。苹果的Accelerate Framework 1.1版和英特尔的MKL mkl==2019.0也会发生这些错误。

请参见how to install OpenBLAS and compile NumPy and SciPy on it

也许我遇到的其余问题是由于链接到Accelerate的其他库引起的?

注意:我仍然愿意回答这个问题。