IEEE 浮点运算是确定性的,但请参阅 How can floating point calculations be made deterministic?对于整体浮点计算可能具有不确定性的一种方式:
... parallel computations are non-deterministic in terms of the order in which floating-point computations are performed, which can result in non-bit-exact results across runs.
两部分问题:
scipy.optimize.fsolve()
, 进而调用像 MINPACK 和 GLPK 这样的原生库以及像 BLAS、ATLAS 和 MKL 这样优化的线性代数子程序。 “If your numpy/scipy is compiled using one of these, then dot() will be computed in parallel (if this is faster) without you doing anything. ”这些本地库是否曾经以引入非确定性结果的方式进行并行化?
假设:
numpy.empty()
返回一个不初始化条目的新数组。目前还不清楚它在实践中要快得多。所以要小心!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)
需要 1.3 倍的时间(在我的 MBP 上)。令人费解。 另见:
Hash values are salted in Python 3 and each dict preserves insertion order .这可能会改变每次运行的操作顺序。 [我正在 Python 2.7.15 中解决这个问题。]
最佳答案
我发现我遇到的大多数(不是全部)非确定性问题似乎在 OpenBLAS 0.3.5 的代码中得到了修复。
早期版本的 OpenBLAS 中的一堆线程问题是 fixed in release 0.3.4 ,但该版本有一个 macOS 兼容性错误,该错误已在 0.3.5 版的代码中修复。这些错误也发生在 Apple 的 Accelerate 框架版本 1.1 和英特尔的 MKL mkl==2019.0
.
见 how to install OpenBLAS and compile NumPy and SciPy on it .
也许我遇到的其余问题是由于与 Accelerate 相关联的其他库?
注:我仍然愿意接受这个问题的更多答案。
关于numpy - 浮点非确定性的原因?包括 NumPy?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53626778/