测试失败:
失败.....
失败.... \ linalg \ tests \ test_regression.py :: TestRegression :: test_eig_build-numpy.linalg.LinAlgError:特征值...
失败.... \ ma \ tests \ test_extras.py :: TestPolynomial :: test_polyfit-numpy.linalg.LinAlgError:SVD未收敛...
例外:
err = 'invalid value', flag = 8
def _raise_linalgerror_lstsq(err, flag):
> raise LinAlgError("SVD did not converge in Linear Least Squares")
E numpy.linalg.LinAlgError: SVD did not converge in Linear Least Squares
err = 'invalid value'
flag = 8
和
err = 'invalid value', flag = 8
def _raise_linalgerror_eigenvalues_nonconvergence(err, flag):
> raise LinAlgError("Eigenvalues did not converge")
E numpy.linalg.LinAlgError: Eigenvalues did not converge
err = 'invalid value'
flag = 8
采取的步骤:
pip install pytest
pip install numpy
pip install hypothesis
在存储库中的测试上运行时,也会发生同样的问题。
numpy版本1.19.0
我是否缺少任何依赖关系? 还是只是Windows变得疯狂?
编辑:您显然正在使用pip。最近在Windows AMD64上我也得到了一个奇怪的结果,它具有线性代数库和特征值分解(在对statsmodels进行测试的情况下)。
如果有时间,请尝试使用32位Python和pip,看看是否遇到相同的问题? 我在32位窗口上看不到它们,但在64位窗口上却可以重复。
如果我使用MKL附带的conda,则没有错误。
编辑:在Windows AMD64上使用NumPy 1.18.5时,我也会看到它们。
最新Windows 10更新后测试失败
测试在更新之前是否失败?
否@charris ,在更新测试套件通过之前。
@speixoto您知道它具体是哪个更新吗? 我很想知道它是否可以解决点子安装车轮的问题。
更新1809(10.0.17763)并未导致任何失败的测试@bashtage
1909年也没有造成任何事情。 它始于2004年。
我不是100%确信是2004年或之后。 我认为2004年运作良好。
FWIW我无法在CI(Azure或appveyor)上重现这些崩溃,但是我在两台同时都是AMD64并在2004年更新的机器上进行本地处理。
你们中的任何一个都试图查看是否在32位Python上获得它们吗?
似乎针对2004年更新报告了许多问题。 也许这也应该报告?
我只是在1909和2004的全新安装上运行了以下命令:
pip install numpy scipy pandas pytest cython
git clone https://github.com/statsmodels/statsmodels.git
cd statsmodels
pip install -e . --no-bulid-isolation
pytest statsmodels
1909年没有失败。 在2004年,有30个失败都与线性代数函数有关。
当我在调试器中于2004年运行测试时,我注意到对函数的第一次调用通常会返回错误的结果,但是再次调用会产生正确的结果(如果反复调用,则仍然正确)。 不确定这是否对猜测原因有用。
NumPy的早期版本也有问题吗? 我假设您正在运行1.19.0。
使用pip + 1.18.4和scipy 1.4.1,我得到了相同的错误集。
这些确实很常见:
ERROR statsmodels/graphics/tests/test_gofplots.py::TestProbPlotLongely::test_ppplot - numpy.linalg.LinAlgError: SVD did not converge
ERROR statsmodels/graphics/tests/test_gofplots.py::TestProbPlotLongely::test_qqplot_other_array - numpy.linalg.LinAlgError: SVD did not converge
ERROR statsmodels/graphics/tests/test_gofplots.py::TestProbPlotLongely::test_probplot - numpy.linalg.LinAlgError: SVD did not converge
ERROR statsmodels/graphics/tests/test_regressionplots.py::TestPlot::test_plot_leverage_resid2 - numpy.linalg.LinAlgError: SVD did not converge
ERROR statsmodels/regression/tests/test_regression.py::TestOLS::test_params - numpy.linalg.LinAlgError: SVD did not converge
ERROR statsmodels/regression/tests/test_regression.py::TestOLS::test_scale - numpy.linalg.LinAlgError: SVD did not converge
ERROR statsmodels/regression/tests/test_regression.py::TestOLS::test_ess - numpy.linalg.LinAlgError: SVD did not converge
ERROR statsmodels/regression/tests/test_regression.py::TestOLS::test_mse_total - numpy.linalg.LinAlgError: SVD did not converge
ERROR statsmodels/regression/tests/test_regression.py::TestOLS::test_bic - numpy.linalg.LinAlgError: SVD did not converge
ERROR statsmodels/regression/tests/test_regression.py::TestOLS::test_norm_resids - numpy.linalg.LinAlgError: SVD did not converge
ERROR statsmodels/regression/tests/test_regression.py::TestOLS::test_HC2_errors - numpy.linalg.LinAlgError: SVD did not converge
ERROR statsmodels/regression/tests/test_regression.py::TestOLS::test_missing - numpy.linalg.LinAlgError: SVD did not converge
ERROR statsmodels/regression/tests/test_regression.py::TestOLS::test_norm_resid_zero_variance - numpy.linalg.LinAlgError: SVD did not converge
ERROR statsmodels/tsa/tests/test_stattools.py::TestADFConstant::test_teststat - numpy.linalg.LinAlgError: SVD did not converge
ERROR statsmodels/tsa/tests/test_stattools.py::TestADFConstant::test_pvalue - numpy.linalg.LinAlgError: SVD did not converge
ERROR statsmodels/tsa/tests/test_stattools.py::TestADFConstant::test_critvalues - numpy.linalg.LinAlgError: SVD did not converge
当我使用1.18.5 + MKL运行时,没有任何错误。 很难说这可能是OpenBLAS错误还是Windows错误。 可能是后者,但要实现它确实非常困难,并且诊断超出了我的底层调试能力。
在同一台物理计算机上,当我使用pip软件包在Ubuntu中运行时,没有看到任何错误。
这是最奇怪的行为。 第一次通话失败,第二次及以后都无法使用。 另一个难以理解的行为是,如果我单独运行失败的测试,则看不到错误。
最终更新:如果我使用不优化BLAS的NumPy源版本进行测试,尽管它们不是同一套,但仍然会看到错误。
也许值得对OpenBLAS开发人员执行ping操作。 它与float64一样频繁发生吗?
当我对NumPy 1.19.0, python -c "import numpy;numpy.test('full')"
进行全面测试时,我看到与上面相同的错误:
FAILED Python/Python38/Lib/site-packages/numpy/lib/tests/test_regression.py::TestRegression::test_polyfit_build - numpy.linalg.LinAlgError: SVD did not conv...
FAILED Python/Python38/Lib/site-packages/numpy/linalg/tests/test_regression.py::TestRegression::test_eig_build - numpy.linalg.LinAlgError: Eigenvalues did n...
FAILED Python/Python38/Lib/site-packages/numpy/ma/tests/test_extras.py::TestPolynomial::test_polyfit - numpy.linalg.LinAlgError: SVD did not converge in Lin...
我认为,如果您只运行测试,那么如果我没记错,应该可以通过测试,这意味着更奇怪的行为。
我已经以唯一的方式向Microsoft提出了申请:
张贴以防其他人通过搜索找到它:
Windows用户应在2004年使用Conda / MKL,直到此问题得到解决
这是一个小的复制示例:
import numpy as np
a = np.arange(13 * 13, dtype=np.float64)
a.shape = (13, 13)
a = a % 17
va, ve = np.linalg.eig(a)
产生
** On entry to DGEBAL parameter number 3 had an illegal value
** On entry to DGEHRD parameter number 2 had an illegal value
** On entry to DORGHR DORGQR parameter number 2 had an illegal value
** On entry to DHSEQR parameter number 4 had an illegal value
---------------------------------------------------------------------------
LinAlgError Traceback (most recent call last)
<ipython-input-11-bad305f0dfc7> in <module>
3 a.shape = (13, 13)
4 a = a % 17
----> 5 va, ve = np.linalg.eig(a)
<__array_function__ internals> in eig(*args, **kwargs)
c:\anaconda\envs\py-pip\lib\site-packages\numpy\linalg\linalg.py in eig(a)
1322 _raise_linalgerror_eigenvalues_nonconvergence)
1323 signature = 'D->DD' if isComplexType(t) else 'd->DD'
-> 1324 w, vt = _umath_linalg.eig(a, signature=signature, extobj=extobj)
1325
1326 if not isComplexType(t) and all(w.imag == 0.0):
c:\anaconda\envs\py-pip\lib\site-packages\numpy\linalg\linalg.py in _raise_linalgerror_eigenvalues_nonconvergence(err, flag)
92
93 def _raise_linalgerror_eigenvalues_nonconvergence(err, flag):
---> 94 raise LinAlgError("Eigenvalues did not converge")
95
96 def _raise_linalgerror_svd_nonconvergence(err, flag):
LinAlgError: Eigenvalues did not converge
这似乎更像是OpenBlas问题(或2004年到OpenBLAS之间的某个问题)。 这是我的摘要:
仅NumPy python -c "import numpy;numpy.test('full')"
statsmodels测试pytest statsmodels
scipy.linalg
例程,这些例程使用OpenBLAS。很高兴了解2004年的变化。也许在编译/链接库时我们需要一个不同的标志?
_If_这是一个OpenBLAS错误,他们不太可能会看到它,因为所有基于Windows的CI都没有使用版本19041(即Windows 10 2004)或更高版本。
明确地说,这些报告中是否都没有涉及WSL?
否。所有由conda提供的python.exe
或python.org提供的python.exe
如果明确设置了环境变量OPENBLAS_CORETYPE=Haswell
或OPENBLAS_CORETYPE=NEHALEM
,测试是否会失败?
我尝试了Atom,SandyBridge,Haswell,Prescott和Nehalem,所有结果均相同。
最奇怪的是,如果您跑步
import numpy as np
a = np.arange(13 * 13, dtype=np.float64)
a.shape = (13, 13)
a = a % 17
va, ve = np.linalg.eig(a) # This will raise, so manually run the next line
va, ve = np.linalg.eig(a)
第二次(以及以后)对eig
调用成功。
SciPy在
import numpy as np
import scipy.linalg
a = np.arange(13 * 13, dtype=np.float64)
a.shape = (13, 13)
a = a % 17
va, ve = scipy.linalg.eig(a)
这引起了
** On entry to DGEBAL parameter number 3 had an illegal value
** On entry to DGEHRD parameter number 2 had an illegal value
** On entry to DORGHR DORGQR parameter number 2 had an illegal value
** On entry to DHSEQR parameter number 4 had an illegal value
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-58-8dfe8125dfe3> in <module>
4 a.shape = (13, 13)
5 a = a % 17
----> 6 va, ve = scipy.linalg.eig(a)
c:\anaconda\envs\py-pip\lib\site-packages\scipy\linalg\decomp.py in eig(a, b, left, right, overwrite_a, overwrite_b, check_finite, homogeneous_eigvals)
245 w = _make_eigvals(w, None, homogeneous_eigvals)
246
--> 247 _check_info(info, 'eig algorithm (geev)',
248 positive='did not converge (only eigenvalues '
249 'with order >= %d have converged)')
c:\anaconda\envs\py-pip\lib\site-packages\scipy\linalg\decomp.py in _check_info(info, driver, positive)
1348 """Check info return value."""
1349 if info < 0:
-> 1350 raise ValueError('illegal value in argument %d of internal %s'
1351 % (-info, driver))
1352 if info > 0 and positive:
ValueError: illegal value in argument 4 of internal eig algorithm (geev)
最后的提示,转换为np.complex128
也会提高,而转换为np.float32
或np.complex64
都可以正常工作。
使用长整数编译的代码的Python部分,但是在fortran(LAPACK)部分中没有INTERFACE64 = 1的情况下构建的OpenBLAS?
(这仍不能解释为什么第一次调用失败但随后的调用成功,也不能解释为什么它在更新19041之前起作用)
Windows 10用户可以在Microsoft的反馈中心中解决此问题。
在@bashtage的请求下,我稍微深入了一下代码,我的猜测是浮点状态的某些方面现在在输入时有所不同。 这似乎可以证实这一点:
转换为np.complex128也会增加,而转换为np.float32或np.complex64都可以正常工作。
第一条警告消息(成功时似乎未出现)“在输入DGEBAL参数3时具有非法值”是由这种情况引起的https://github.com/xianyi/OpenBLAS/blob/ce3651516f12079f3ca2418aa85b9ad571c3a391/lapack -netlib / SRC / dgebal.f#L336 ,这可能是由前往NaN的许多先前计算引起的。
玩了repro步骤之后,我发现将mod作为float32可以“修复”它:
import numpy as np
a = np.arange(13 * 13, dtype=np.float64)
a.shape = (13, 13)
a = (a.astype(np.float32) % 17).astype(np.float64) # <-- only line changed
va, ve = np.linalg.eig(a)
因此,我猜测该代码路径中是否有某些内容可以正确重置状态,尽管我不确定它是什么。 希望更熟悉numpy内部的人可能知道这可能发生在哪里。
有点让我想起了我们在WINDOWS上的mingw上看到的一个旧错误,在该错误中浮点寄存器配置不是由工作线程继承的,从而导致异常值不会刷新为零,有时会弄乱后续的计算。
不知道这与当前硬件上的当前Windows是否有任何关系,但是了解您的计算机是否可能很有趣
OpenBLAS构建是在CONSISTENT_FPCSR = 1的情况下完成的(或者添加该构建选项会有所帮助)。
@mattip您知道OpenBLAS构建中的CONSISTENT_FPCSR = 1吗?
好吧,至少到那时为止。 无论如何,连接似乎很遥远。
嗨! 我已经遇到了类似的问题已有一段时间了,我的所有测试都表明Windows 10(2004)和OpenBlas之间有些混乱。 我通常在3台PC(2台Windows 10工作站和一台较旧的Windows 7笔记本电脑)上运行程序。 在将2个工作站升级到Windows 10的2004版前后,我的python脚本开始出现与linalg和svd()收敛有关的错误,我第一次运行该脚本时也遇到了崩溃,但大多数情况下第二次尝试工作(运行Jupyter笔记本)。 旧的笔记本电脑装备一直在运行相同程序,没有错误! 我有miniconda,python 3.6,并且所有软件包都使用pip安装(env在3台计算机上完全相同)。
今天,我从https://www.lfd.uci.edu/删除了默认的numpy(1.19.0)安装并安装了numpy + mkl(numpy-1.19.1 + mkl-cp36-cp36m-win_amd64.whl)版本。
达里奥
奇怪的是,OpenBLAS dll是由lib.exe的VC9版本创建的吗? 这是Python 2.7所使用的版本。 可能并不重要,但是由于VC9并未在任何地方使用,因此感到很奇怪。
对于某人(也许对我来说)的下一步是使用单线程OpenBLAS( USE_THREAD=0
)构建NumPy master,以查看是否可以解决问题。
我尝试了一些实验,但均未成功:
USE_THREADS=0
INTERFACE64=1
<-NumPy测试中的段错误与访问冲突您可以使用Win10安装程序运行LAPACK测试套件吗? 我最近修复了cmake构建以生成它,也许它提供了一些线索,而没有涉及到任何numpy。
--> LAPACK TESTING SUMMARY <--
SUMMARY nb test run numerical error other error
================ =========== ================= ================
REAL 409288 0 (0.000%) 0 (0.000%)
DOUBLE PRECISION 410100 0 (0.000%) 0 (0.000%)
COMPLEX 420495 0 (0.000%) 0 (0.000%)
COMPLEX16 13940 0 (0.000%) 0 (0.000%)
--> ALL PRECISIONS 1253823 0 (0.000%) 0 (0.000%)
虽然我确实看到很多线条
--> Testing DOUBLE PRECISION Nonsymmetric Eigenvalue Problem [ xeigtstd < nep.in > dnep.out ]
---- TESTING ./xeigtstd... FAILED(./xeigtstd < nep.in > dnep.out did not work) !
所以我不确定这些是否值得信赖。
看起来大多数测试都是分段测试,但是尚存的测试是完美无瑕的……这比我预期的还要极端。
(在堆栈大小方面,COMPLEX和COMPLEX16要求很高,因此默认操作系统设置下失败的可能性更大,但是REAL和DOUBLE通常会显示大约1200000个测试运行。这让我想知道MS是否更改了默认堆栈限制或布局)
一些背景。 一切都使用gcc.exe / gfortran.exe构建。 这些文件用于生成.a文件,然后将其打包到DLL中。 特别:
$ gcc -v
Using built-in specs.
COLLECT_GCC=C:\git\numpy-openblas-windows\openblas-libs\mingw64\bin\gcc.exe
COLLECT_LTO_WRAPPER=C:/git/numpy-openblas-windows/openblas-libs/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/7.1.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../../../src/gcc-7.1.0/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/c/mingw710/x86_64-710-posix-seh-rt_v5-rev0/mingw64 --enable-shared --enable-static --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --enable-libstdcxx-filesystem-ts=yes --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw710/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/c/mingw710/prerequisites/x86_64-w64-mingw32-static --with-mpc=/c/mingw710/prerequisites/x86_64-w64-mingw32-static --with-isl=/c/mingw710/prerequisites/x86_64-w64-mingw32-static --with-pkgversion='x86_64-posix-seh-rev0, Built by MinGW-W64 project' --with-bugurl=http://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -fno-ident -I/c/mingw710/x86_64-710-posix-seh-rt_v5-rev0/mingw64/opt/include -I/c/mingw710/prerequisites/x86_64-zlib-static/include -I/c/mingw710/prerequisites/x86_64-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -fno-ident -I/c/mingw710/x86_64-710-posix-seh-rt_v5-rev0/mingw64/opt/include -I/c/mingw710/prerequisites/x86_64-zlib-static/include -I/c/mingw710/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS=' -I/c/mingw710/x86_64-710-posix-seh-rt_v5-rev0/mingw64/opt/include -I/c/mingw710/prerequisites/x86_64-zlib-static/include -I/c/mingw710/prerequisites/x86_64-w64-mingw32-static/include' LDFLAGS='-pipe -fno-ident -L/c/mingw710/x86_64-710-posix-seh-rt_v5-rev0/mingw64/opt/lib -L/c/mingw710/prerequisites/x86_64-zlib-static/lib -L/c/mingw710/prerequisites/x86_64-w64-mingw32-static/lib '
Thread model: posix
gcc version 7.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)
$ gfortran -v
Using built-in specs.
COLLECT_GCC=C:\git\numpy-openblas-windows\openblas-libs\mingw64\bin\gfortran.exe
COLLECT_LTO_WRAPPER=C:/git/numpy-openblas-windows/openblas-libs/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/7.1.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../../../src/gcc-7.1.0/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/c/mingw710/x86_64-710-posix-seh-rt_v5-rev0/mingw64 --enable-shared --enable-static --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --enable-libstdcxx-filesystem-ts=yes --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw710/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/c/mingw710/prerequisites/x86_64-w64-mingw32-static --with-mpc=/c/mingw710/prerequisites/x86_64-w64-mingw32-static --with-isl=/c/mingw710/prerequisites/x86_64-w64-mingw32-static --with-pkgversion='x86_64-posix-seh-rev0, Built by MinGW-W64 project' --with-bugurl=http://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -fno-ident -I/c/mingw710/x86_64-710-posix-seh-rt_v5-rev0/mingw64/opt/include -I/c/mingw710/prerequisites/x86_64-zlib-static/include -I/c/mingw710/prerequisites/x86_64-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -fno-ident -I/c/mingw710/x86_64-710-posix-seh-rt_v5-rev0/mingw64/opt/include -I/c/mingw710/prerequisites/x86_64-zlib-static/include -I/c/mingw710/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS=' -I/c/mingw710/x86_64-710-posix-seh-rt_v5-rev0/mingw64/opt/include -I/c/mingw710/prerequisites/x86_64-zlib-static/include -I/c/mingw710/prerequisites/x86_64-w64-mingw32-static/include' LDFLAGS='-pipe -fno-ident -L/c/mingw710/x86_64-710-posix-seh-rt_v5-rev0/mingw64/opt/lib -L/c/mingw710/prerequisites/x86_64-zlib-static/lib -L/c/mingw710/prerequisites/x86_64-w64-mingw32-static/lib '
Thread model: posix
gcc version 7.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)
我确实认为问题出在NumPy和OpenBLAS之间。 我无法想象在第一次调用是错误的情况下还会发生这种行为,但是第二次和后续调用都很好。 但是,如何解决(或TBH甚至可以准确诊断出深层问题)?
废除MS平台并从此过上幸福的生活? 如果lapack测试失败,则切换问题将在Fortran(= OpenBLAS的LAPACK部分)和C或Fortran与“其他”之间。
我很好奇是否有可能使用icc用OpenBLAS构建Numpy
和ifort,以便查看问题是否仍然存在。 不过,这是一个很大的问题。
2020年8月12日,星期三,19:04 Martin Kroeker [email protected]写道:
废除MS平台并从此过上幸福的生活? 如果失败
lapack测试切换问题位于Fortran(=
OpenBLAS)和C,或者Fortran和“其他”。-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看
https://github.com/numpy/numpy/issues/16744#issuecomment-673026759 ,或者
退订
https://github.com/notifications/unsubscribe-auth/ABKTSRLSHZ2XWF4OE7J3QO3SALKSJANCNFSM4OP5IXNQ
。
仅使用Intel编译器构建OpenBLAS可能就足够了(尽管至少对于最近发布的VS来说这似乎已经足够麻烦了,目前我还没有有效的ifc / ifort许可证。
Windows用户应在2004年使用Conda / MKL,直到此问题得到解决
@bashtage感谢您的建议。
就我而言,在应用Conda版本的numpy后,使用pandasql使用sqlite时遇到一些错误。
但是使用此版本的numpy + mkl时我没有任何问题。
@bashtage似乎有一个新的MSVC预发行版,带有针对该锈链接问题的修复程序,也许值得一试?
仅供参考:相关的SciPy问题: https :
有报告指出Windows内部版本17763.1397(8月11日)已解决此问题,请参阅#17082。
有报告指出Windows内部版本17763.1397(8月11日)已解决此问题,请参阅#17082。
https://support.microsoft.com/zh-CN/help/4565349/windows-10-update-kb4565349
内部版本17763.1397仅适用于Windows 10版本1809(适用于:Windows 10版本1809,所有版本Windows Server版本1809 Windows Server 2019,所有版本)。
对于Windows 10版本1809,在这种情况下没有问题。
这是Windows 10 2004版的最新更新版本。
https://support.microsoft.com/zh-CN/help/4566782
2020年8月11日-KB4566782(操作系统内部版本19041.450)。
我在Windows 10版本2004上仍然存在相同的问题
在19042.487(这是20H2分支)上发生相同的故障:
-- Docs: https://docs.pytest.org/en/stable/warnings.html
=============================================== short test summary info ===============================================
FAILED lib/tests/test_regression.py::TestRegression::test_polyfit_build - numpy.linalg.LinAlgError: SVD did not conve...
FAILED linalg/tests/test_regression.py::TestRegression::test_eig_build - numpy.linalg.LinAlgError: Eigenvalues did no...
FAILED ma/tests/test_extras.py::TestPolynomial::test_polyfit - numpy.linalg.LinAlgError: SVD did not converge in Line...
3 failed, 11275 passed, 559 skipped, 20 xfailed, 1 xpassed, 1 warning in 398.16s (0:06:38)
我可以在OpenBLAS的lapack测试中重现(部分)失败-仅影响EIG(特征值)测试,众所周知,这些测试对堆栈大小的要求异常高。 SIGSEGV出现在__chkstk_ms_中,甚至在main()之前输入。 使用peflags实用程序将相应可执行文件的默认“堆栈保留大小”和“堆栈提交大小”的默认值加倍(例如peflags -x4194304 -X4194304 EIG/xeigtsts.exe
),可使程序正常工作,这表明C / Fortran交互和参数传递本身是没问题。 我尚未尝试将其应用于numpy情况(甚至不确定其peflag设置是否在那里进行调整-python.exe吗?),但在19041.450 aka上使用gcc 9.1.0的msys2 mingw64版本构建时,OpenBLAS本身似乎正常运行2004年
@ martin-frbg看起来像进度。
走了一个兔子洞,尝试在Windows / MSYS2上安装所有用于构建numpy的依赖项,因此没有任何进一步的进展。
@ martin-frbg,可以与pacman一起安装基于Msys2的numpy软件包。 Msys2构建脚本和补丁可在此处获得: https : https://github.com/msys2/MINGW-packages/tree / master / mingw-w64-openblas。
在最近的分类会议中,这是一个相对较高的优先级, @ hameerabbasi和我愿意提供帮助。 我们能做些什么?
@bashtage您可以尝试使用editbin /STACK:3145728 python.exe
使堆栈变大吗
有没有一种方法可以尝试使用OpenBLAS版本的库而不是我们构建的库来构建NumPy? 也许我们的构建有些偏离。
可能可以用从当前develop
分支或较旧的发行版(如0.3.8或0.3.9)创建的版本替换构建中的libopenblas.dll,以查看是否具有任何效果? (并不是说我现在有任何具体的承诺可能与此有任何关系)。 不幸的是,即使使用msys2软件包,我仍然遇到安装错误,目前显然由于self.ld_version在版本检查中未返回任何内容而无法运行测试。
谢谢。 我正在尝试更新Windows以构建2004,让我们看看我是否在周末之前完成
另外,来自https://github.com/numpy/numpy/issues/16744#issuecomment -655430682的bashtage的“小型复制示例”不会在我的msys2设置中引发任何错误。 (据我所知,它们在mingw64 / usr / lib中的libopenblas是为Haswell构建的单线程0.3.10)
@ martin-frbg是否可以使用MSVC构建OpenBLAS?
普通的MSVC? 可行,但提供的库优化较差,因为MSVC不支持程序集内核-几乎与为TARGET = GENERIC构建OpenBLAS一样。
另外,来自#16744的bashtage的“小型复制示例”
我很确定这与NumPy和OpenBLAS之间的接口有关。 NumPy的32位版本也没有此问题。 与我交谈过的Microsoft员工的想法是,这很可能是线程同步问题,这似乎是最合理的。 它可以解释在第一次调用中如何出现错误的值,然后在后续调用中进行纠正。
走了一个兔子洞,尝试在Windows / MSYS2上安装所有用于构建numpy的依赖项,因此没有任何进一步的进展。
真痛苦我已经完成了,但是将其自动化以进行一些实验需要很长时间。 基本上,它需要从https://github.com/MacPython/openblas-libs复制步骤以获取.a文件,然后从https://github.com/numpy/numpy/blob/master/复制步骤
获取DLL构建的最简单方法是打开一个appveyor帐户,然后克隆https://github.com/MacPython/openblas-libs。 在构建结束时,您可以从网站上找到包含dll(和.a文件)的工件。 但是,这很慢,需要花费3个小时来构建所有3个版本。
查看https://github.com/MacPython/openblas-libs ,似乎使用INTERFACE64=1
构建OpenBLAS。 Msys2构建OpenBLAS和numpy并非如此。
@carlkl此问题与NumPy或OpenBLAS的Msys2版本无关。 这是关于Win32 / AMD64构建的,该构建利用Msys2提供的gfortran编译fortran源,然后使用MS的lib.exe从编译的库中构建Win32 DLL。
@bashtage我提到了这一点,因为据报道它是https://github.com/numpy/numpy/issues/16744#issuecomment -689785607,该段错误无法在msys2中复制。 而且我猜想提到的msys2环境包含msys2提供的openblas和numpy二进制包。
我不知道,如果Windows 64bit numpy是用MSVC的类似标志编译的,还是没有。
顺便说一句:我在scipy存储库中找不到标志-fdefault-integer-8
。
我不确定使用-fdefault-integer-8
编译的代码是否与不带此标志的编译代码兼容。
我想到了另一个方面:也许-fdefault-integer-8
应该与-mcmodel=large
结合使用。
编辑:记住:Windows64具有LLP64内存模型,而不是ILP64。
LLP64的意思是:long:32bit,指针:64bit
那么,遇到Win10-2004问题的numpy构建使用什么大小的整数? 它最好与OpenBLAS构建的目的相匹配,但是IIRC这个话题早已在该线程中出现了(不匹配可能会导致更明显的损坏,而与Windows补丁程序级别无关)
至少可以使用https://github.com/MacPython/openblas-libs (请参阅appveyor.yml)在三个变体中构建Openblas:
但是如果不知道在Windows上用于numpy 64位版本的是什么。
_无论Windows补丁程序级别如何,不匹配都可能导致更明显的损坏_
-fdefault-integer-8
仅适用于Lapack的fortran部分。 它不会更改基础内存模型(LLP64),所以我不确定是否应该在Fortran Lapack部件之外遇到问题。
嗯,
https://github.com/numpy/numpy/blob/60a21a35210725520077f13200498e2bf3198029/azure-pipelines.yml说
- job: Windows
pool:
vmImage: 'VS2017-Win2016'
...
Python38-64bit-full:
PYTHON_VERSION: '3.8'
PYTHON_ARCH: 'x64'
TEST_MODE: full
BITS: 64
NPY_USE_BLAS_ILP64: '1'
OPENBLAS_SUFFIX: '64_'
其他所有版本( Python36-64bit-full
, Python37-64bit-full
)都没有NPY_USE_BLAS_ILP64。
pypi.org上的Numpy二进制文件都是使用32位整数openblas构建的。 https://github.com/MacPython/numpy-wheels/blob/v1.19.x/azure/windows.yml
有关构建过程gfortran与MSVC的详细信息,请参见此处。 Microsoft lib.exe不参与生产openblas DLL,所有这些都是mingw工具链。 Numpy使用openblas.a
文件,并使用gfortran生成DLL。 https://github.com/numpy/numpy/blob/74712a53df240f1661fbced15ae984888fd9afa6/numpy/distutils/fcompiler/gnu.py#L442 MSVC工具用于从.def文件生成.lib文件,以及使用MSVC编译的Numpy C代码使用该.lib文件链接到gfortran生成的DLL。
一个可能出错的理论可能性是,产生静态openblas.a工件的mingw与构建numpy时使用的mingw版本之间是否存在某种mingw版本不匹配。 但是,不确定是否有可能引起问题。
choco install -y mingw --forcex86 --force --version=5.3.0
使用的windows.yml
似乎已过时。 为什么不使用7.3.0
或8.1.0
? 我记得两三年前我在gcc-5.x上遇到的问题。
在Windows.yml中使用的choco install -y mingw --forcex86 --force --version = 5.3.0似乎已过时
这仅适用于32位Windows构建,因此可能与此问题无关。
所有其他版本(
Python36-64bit-full
,Python37-64bit-full
)都没有NPY_USE_BLAS_ILP64构建。
在Python 3.6和3.8上出现相同的错误。
还有一个想法(我在黑暗中挖掘):
OpenBLAS现编译-fno-optimize-sibling-calls
,看到https://github.com/xianyi/OpenBLAS/issues/2154 , https://github.com/xianyi/OpenBLAS/pull/2157和https://开头的gcc .gnu.org / bugzilla / show_bug.cgi?id = 90329。
编辑:另请参阅: https :
Numpy没有将此标志应用于distutils的gfortran部分。 我知道numpy是使用MSVC编译的。 因此,我期望scipy而不是numpy出现问题,因此这可能又是一次错误的旅行。
pypi.org上的Numpy二进制文件都是使用32位整数openblas构建的。 https://github.com/MacPython/numpy-wheels/blob/v1.19.x/azure/windows.yml
为什么测试中使用的构建配置与发行版中使用的不同? 这听起来像是一种风险。
我们可以向Azure版本添加工件吗? 这将使车轮的测试变得更加简单。 我在这里唯一关心的是,免费工件限制是很小的IIRC,1GB,而且我不知道当您按下它时会发生什么(FIFO会很好,但可能会做其他事情,包括错误)。
为什么测试中使用的构建配置与发行版中使用的不同?
我们在没有NPY_USE_BLAS_ILP64
Windows中测试了所有受支持的python版本,并且也在NPY_USE_BLAS_ILP64
测试了python 3.8,请参见https://github.com/numpy/numpy/blob/v1.19.2/azure -pipelines.yml#L195。 因此,每周构建使用32位整数openblas是正确的。
我们可以向Azure版本添加工件吗?
可能很容易尝试一下,并找出有关错误的限制。 但是,每周一次的转轮旨在忠实地重建测试版本。 任何差异均应视为错误并已解决。
可能很容易尝试一下,并找出有关错误的限制。 但是,每周一次的转轮旨在忠实地重建测试版本。 任何差异均应视为错误并已解决。
我当时认为,对主仓库进行PR并尝试在2004年进行测试会比较容易。
说得通。
您可以在回购bashtage / numpy中打开Azure管道
更多信息:失败的第一个调用是因为OpenBLAS中的DNRM2
返回NAN。 对我来说,这是可重复的:每次致电
a = np.arange(13 * 13, dtype=np.float64).reshape(13, 13)
a = a % 17
np.linalg.eig(a)
打印** On entry to DGEBAL parameter number 3 had an illegal value
,这是另一种说法“ DNRM2
返回NAN”。 mod
操作很关键,没有它,对eig
的调用不会显示此错误。
mod
ufunc和对OpenBLAS的调用之间如何进行交互?
mod
操作很关键,没有它,对eig
的调用不会显示此错误。
手动构造此完全相同的数组是否会重复触发该错误?
此代码不会触发失败:
a = np.array([x % 17 for x in range(13 * 13)], dtype=np.float64)
a.shape = (13, 13)
np.linalg.eig(a)
前面的mod
使寄存器处于未定义状态? 我没有再次检查nrm2.S,但是我认为几年前汇编对文件进行异或以清除它有一些问题,这在NaN上会失败。
对于后续的代码,float64 %
最终会为每个值调用npy_divmod
。
...在第一行中调用npy_fmod()
,即fmod() 。 这是我尝试的一些更改。 “错误”表示我在运行调用a % 17; np.linalg.eig(a)
的代码时从OpenBLAS收到“非法值”消息
代码结果
--- | ---
mod = npy_fmod@c@(a, b);
(原始代码)| 错误
mod = 100; //npy_fmod@c@(a, b);
| 没错
mod = npy_fmod@c@(a, b); mod = 100.0;
| 错误
因此,似乎MSVC中的fmod
所做的事情使OpenBLAS感到困惑。
那很有趣,而且很奇怪。
您可以使用fmod的原始版本(非平台提供)来查看该版本是否已解决吗?
或者只是将HAVE_MODF
强制0
。
我认为我们没有fmod的天真的版本,对吗?
我看到有一个HAVE_MODF宏,但是该路径指向何处?
看起来像Iike,如果缺少float和long double,则会退回到double版本。 双重版本是构建numpy所必需的。 undef可能是为了避免编译器内联函数(ISTR),这早在Windows上就是一个问题。
我想“证明”问题是来自ucrtbase.dll
的fmod
实现。 因此,我写了一些解决方法,使用ctypes将函数拉出dll并使用它来直接调用fmod
。 测试仍然失败。 然后我切换到ucrtbase.dll
的旧版本(仅用于fmod
函数)。 测试通过。 我在视觉工作室论坛上打开了一个
diff --git a/numpy/core/src/npymath/npy_math.c b/numpy/core/src/npymath/npy_math.c
index 404cf67b2..675905f73 100644
--- a/numpy/core/src/npymath/npy_math.c
+++ b/numpy/core/src/npymath/npy_math.c
@@ -7,3 +7,27 @@
#define NPY_INLINE_MATH 0
#include "npy_math_internal.h"
+#include <Windows.h>
+
+typedef double(*dbldbldbl)(double, double);typedef double(*dbldbldbl)(double, double);
+
+dbldbldbl myfmod = NULL;
+
+typedef double(*dbldbldbl)(double, double);
+extern dbldbldbl myfmod;
+
+
+double __fmod(double x, double y)
+{
+ if (myfmod == NULL) {
+ HMODULE dll = LoadLibraryA("ucrtbase_old.dll");
+ //HMODULE dll = LoadLibraryA("c:\\windows\\system32\\ucrtbase.DLL");
+ myfmod = (dbldbldbl)GetProcAddress(dll, "fmod");
+ }
+ return myfmod(x, y);
+}
+
+long double __fmodl(long double x, long double y) { return fmodl(x, y); }
+float __fmodf(float x, float y) { return fmodf(x, y); }
+
+
diff --git a/numpy/core/src/npymath/npy_math_internal.h.src b/numpy/core/src/npymath/npy_math_internal.h.src
index 18b6d1434..9b0600a34 100644
--- a/numpy/core/src/npymath/npy_math_internal.h.src
+++ b/numpy/core/src/npymath/npy_math_internal.h.src
@@ -55,6 +55,11 @@
*/
#include "npy_math_private.h"
+double __fmod(double x, double y);
+long double __fmodl(long double x, long double y);
+float __fmodf(float x, float y);
+
+
/*
*****************************************************************************
** BASIC MATH FUNCTIONS **
@@ -473,8 +478,8 @@ NPY_INPLACE @type@ npy_@kind@@c@(@type@ x)
/**end repeat1**/
/**begin repeat1
- * #kind = atan2,hypot,pow,fmod,copysign#
- * #KIND = ATAN2,HYPOT,POW,FMOD,COPYSIGN#
+ * #kind = atan2,hypot,pow,copysign#
+ * #KIND = ATAN2,HYPOT,POW,COPYSIGN#
*/
#ifdef HAVE_@KIND@@C@
NPY_INPLACE @type@ npy_@kind@@c@(@type@ x, @type@ y)
@@ -484,6 +489,13 @@ NPY_INPLACE @type@ npy_@kind@@c@(@type@ x, @type@ y)
#endif
/**end repeat1**/
+#ifdef HAVE_FMOD@C@
+NPY_INPLACE @type@ npy_fmod@c@(@type@ x, @type@ y)
+{
+ return __fmod@c@(x, y);
+}
+#endif
+
#ifdef HAVE_MODF@C@
NPY_INPLACE @type@ npy_modf@c@(@type@ x, @type@ *iptr)
{
如果在fmod调用之后添加一些代码,以使ST(0)
不包含nan,该怎么办? 或将其设置为nan?
调用约定是否对这些寄存器的行为方式施加了一些限制?
我想“证明”问题是来自
ucrtbase.dll
的fmod
实现。 因此,我写了一些解决方法,使用ctypes将函数拉出dll并使用它来直接调用fmod
。 测试仍然失败。 然后我切换到ucrtbase.dll
的旧版本(仅用于fmod
函数)。 测试通过。 我在视觉工作室论坛上打开了一个
至少有天蓝色帐户的人(可能是这里的很多人)都可以投票。 我将联系最初出现此问题时与我联系的一些联系人,这些联系人在Azure ML中工作,以查看他们是否可以执行任何操作。
至少有天蓝色帐户的人(可能是这里的很多人)都可以投票。
感谢您的提示,推荐!
我认为我们没有fmod的天真的版本,对吗?
不能。这是IEEE-754规范要求的具有某些行为的棘手功能。 它也非常慢,这可能与规格有关。
fmod
的艰苦工作由fprem
x87指令执行,即使在VS2019变体中也是如此-参见@mattip的要旨(最后一行) https://gist.github.com/mattip / d9e1f3f88ce77b9fde6a285d585c738e。 ( fprem1
是remainder
变体。)
与MMX或SSE寄存器结合使用时必须小心-如此处所述: https :
如https://github.com/xianyi/OpenBLAS/issues/2709#issuecomment -702634696中所述,还有一些可用的替代实现。 但是:所有这些都需要gcc(mingw-w64)进行编译。 OpenLIBM不使用MSVC AFAIK进行编译。 而且MSVC不允许内联汇编代码。 原则上,可以在numpy构建期间构建(mingw-w64)并使用(MSVC)fmod帮助程序库。
如果在fmod调用之后添加一些代码,以便ST(0)不包含nan怎么办? 或将其设置为nan? 调用约定是否对这些寄存器的行为方式施加了一些限制?
我想我们可以在Windows上调用OpenBLAS之前添加一些汇编程序来清除寄存器。 我尝试在一些测试设置中执行此操作,但我的masm程序集foo较弱。 我尝试编写一个仅多次调用fldz
,使用它时出现异常。 救命?
在lots_of_fldz.asm
:
.code
lots_of_fldz proc
fldz
fldz
fldz
fldz
fldz
fldz
lots_of_fldz endp
end
在另一个文件中:
#include <iostream>
#include <Windows.h>
extern "C" {
int lots_of_fldz(void);
}
int main()
{
typedef double(*dbldbldbl)(double, double);
//HMODULE dll = LoadLibraryA("D:\\CPython38\\ucrtbase_old.dll");
HMODULE dll = LoadLibraryA("c:\\windows\\system32\\ucrtbase.DLL");
if (dll == NULL) {
return -1;
}
dbldbldbl myfmod;
myfmod = (dbldbldbl)GetProcAddress(dll, "fmod");
double x = 0.0, y = 17.0;
double z = x + y;
z = myfmod(x, y);
lots_of_fldz();
/* CRASH */
std::cout << "Hello World!\n";
return 0;
}
将它们放入VisualStudio项目中,然后按照本指南打开masm编译
@mattip ,我为64位fmod函数创建了一个汇编文件,该文件创建了与mingw-w64(64位)相应的fmod
函数中相同的text:
段。 不知道这是否可以代替越野车的fmod函数,但至少应该尝试一下。 可以将生成的obj文件添加到npymath.lib。
fmod.asm:(64位)
.code
fmod PROC
sub rsp , 18h
movsd QWORD PTR [rsp+8h] , xmm0
fld QWORD PTR [rsp+8h]
movsd QWORD PTR [rsp+8h] , xmm1
fld QWORD PTR [rsp+8h]
fxch st(1)
L1:
fprem
fstsw ax
sahf
jp L1
fstp st(1)
fstp QWORD PTR [rsp+8h]
movsd xmm0 , QWORD PTR [rsp+8h]
add rsp,18h
ret
fmod endp
end
masm命令: ml64.exe /c fmod.asm
创建fmod.obj
(使用ml64.exe的64位变体)
``
objdump -D fmod.obj
....
Disassembly of section .text$mn:
0000000000000000 <fmod>:
0: 48 83 ec 18 sub $0x18,%rsp
4: f2 0f 11 44 24 08 movsd %xmm0,0x8(%rsp)
a: dd 44 24 08 fldl 0x8(%rsp)
e: f2 0f 11 4c 24 08 movsd %xmm1,0x8(%rsp)
14: dd 44 24 08 fldl 0x8(%rsp)
18: d9 c9 fxch %st(1)
1a: d9 f8 fprem
1c: 9b df e0 fstsw %ax
1f: 9e sahf
20: 7a f8 jp 1a <fmod+0x1a>
22: dd d9 fstp %st(1)
24: dd 5c 24 08 fstpl 0x8(%rsp)
28: f2 0f 10 44 24 08 movsd 0x8(%rsp),%xmm0
2e: 48 83 c4 18 add $0x18,%rsp
32: c3 retq
@mattip ,我的汇编程序https :
从https://docs.microsoft.com/de-de/cpp/build/x64-calling-convention?view=vs-2019 :
The x87 register stack is unused. It may be used by the callee, but consider it volatile across function calls.
猜猜我们也可以在OpenBLAS nrm2.S的开头(在PROFCODE宏之后)调用fninit
来检查该理论
有趣的一点
System V应用程序二进制接口AMD64体系结构处理器补充草案版本0.99.6
_MXCSR寄存器的控制位是被调用者保存的(在调用之间保留),而状态位是被调用者保存的(不保留)。
_x87状态字寄存器已保存呼叫者,而x87控制字已保存了被呼叫者。
_所有x87寄存器都保存有呼叫者,因此使用MMX寄存器的被调用者可能会使用更快的femms指令。
与Windows 64位调用约定相比有很大不同。
@ martin-frbg, fninit
是危险的: The FPU control word is set to 037FH (round to nearest, all exceptions masked, 64-bit precision).
不是在所有情况下都需要X87扩展精度,尤其是在Windows上。
我不希望将其用于发行版,而只是为了进行快速测试。 仍然不太确信OpenBLAS应该以某种方式在“本身”之前进行清理,但是我找不到关于旧版x87 fpu的Windows行为的任何清晰文档。 我注意到Agner Fog在http://www.agner.org/optimize/calling_conventions.pdf上有一个有关调用约定的文档(有关FP寄存器的Win64处理的讨论从第13页开始,但着重于上下文切换的基本可用性和行为)。
参见https://github.com/numpy/numpy/issues/16744#issuecomment -703305582:
The x87 register stack is unused. It may be used by the callee, but consider it volatile across function calls.
我想这意味着:不要使用x87指令(Win64)。 如果这样做,祝您好运。 换句话说:被叫方有责任不伤害他人。
嗯,这似乎专门描述了MSVC编译器的行为,而我认为我们处于mingw生态系统中?
不,Numpy(Pypi)是在Windows上使用MSVC(Visual Studio 2019)编译的。 对于OpenBLAS,使用mingw-w64(由于Fortran部件)。 Scipy Fortran部件也使用mingw-w64进行编译。 但是,CPython及其二进制扩展在很大程度上基于MSVC设置的标准。
顺便说一句:这就是开发https://github.com/mingwpy的原因,
还有一点:
mingw-w64使用(几乎)与MSVC相同的调用约定。 唯一值得注意的区别是x86(32位)上的堆栈对齐方式不同-与SIMD和不受支持的vectorcall
。
有趣。 x86不受影响。 仅AMD64。
2020年10月4日,星期日,22:19 carlkl [email protected]写道:
还有一点:
mingw-w64使用(几乎)与MSVC相同的调用约定。 唯一的
显着的不同是x86(32位)上的堆栈对齐方式不同-
与SIMD和不受支持的引导程序有关。-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看
https://github.com/numpy/numpy/issues/16744#issuecomment-703317784 ,或者
退订
https://github.com/notifications/unsubscribe-auth/ABKTSRMFHWZVLDYDFGBM6YDSJDRGTANCNFSM4OP5IXNQ
。
MSVC 32bit也许还没有放弃fpu? 我将使用nrm2_see2.S(如果可行,不幸的是,在代码库中有许多未使用但致命的汇编例程)替换使用fpu的nrm2.S(如果可行,很不幸)在代码库中或纯C版本的OS中进行临时替换。 ==然后是Windows。 (但是,这里讨论的另一个问题必须是其他问题,因为我认为x86_64的所有其他较旧的汇编例程至少是SSE2)
@mattip ,也许在divmod
之后调用_fpreset
足以从混乱的FPU状态复位?
也许致电
_fpreset
不会,它不会重置ST(N)
寄存器,也不会修复失败的测试。
您是否尝试了_fninit
? 这应该重置FPU堆栈。 或ffree
或fstp
代替fldz
如https://stackoverflow.com/questions/19892215/free-the-x87-fpu-stack-ia32/33575875 ?
我很乐意尝试汇编程序命令,但是上面注释中的测试项目崩溃了。 有人需要更正我的代码以使其工作(实际上, fninit
似乎是一个不错的选择),然后我可以发出汇编指令以在调用OpenBLAS之前重置NumPy中的寄存器。
像这样吗
.code
reset_fpu proc
finit
fldz
reset_fpu endp
end
finit
ist wait
加上fninit
。 我不确定fldz
是否需要fninit
。
正如我在评论中所说,要使对已编译汇编代码的调用正常工作,缺少了一些东西。 这几乎就是我在那条评论中所说的。 代码因exited with code -2147483645
而崩溃。 请查看完整的代码,看看是否可以使其正常工作。
我可以尝试(明天)。 但是,也许这些片段是有帮助的:
https://www.website.masmforum.com/tutorials/fptute/fpuchap4.htm
(我找到的有关此主题的最易读的网站之一)
FLDZ (Load the value of Zero)
Syntax: fldz (no operand)
Exception flags: Stack Fault, Invalid operation
This instruction decrements the TOP register pointer in the Status Word
and loads the value of +0.0 into the new TOP data register.
If the ST(7) data register which would become the new ST(0) is not empty, both
a Stack Fault and an Invalid operation exceptions are detected, setting both flags
in the Status Word. The TOP register pointer in the Status Word would still
be decremented and the new value in ST(0) would be the INDEFINITE NAN.
A typical use of this instruction would be to "initialize" a data register intended
to be used as an accumulator. Even though a value of zero could also be easily
loaded from memory, this instruction is faster and does not need the use of memory.
据我了解,如果使用st(7),则fldz可能会出现段错误,因此:
FFREE (Free a data register)
Syntax: free st(x)
This instruction modifies the Tag Word to indicate that the specified 80-bit data register
is now considered as empty. Any data previously in that register becomes unusable.
Any attempt to use that data will result in an Invalid exception being detected and an
INDEFINITE value possibly being generated.
Although any of the 8 data registers can be tagged as free with this instruction,
the only one which can be of any immediate value is the ST(7) register when
all registers are in use and another value must be loaded to the FPU.
If the data in that ST(7) is still valuable, other instructions should be used
to save it before emptying that register.
您可以尝试:
.code
reset_fpu proc
ffree st(7)
fldz
reset_fpu endp
end
对不起,我没有说清楚。 眼前的问题不是汇编程序要调用哪个。 紧迫的问题是如何以一种我们可以使用的方式正确地创建一个可调用过程,并以两个文件( *.asm
和main.c
/ main.cpp
)编译并运行的项目。 一旦有了这些内容,我就可以继续探讨不同的调用以及它们如何影响OpenBLAS。
@mattip ,我了解。 我一定会尝试的,但这可能需要一些时间。
我给人的印象是UCRT中fmod的_tempory_不良行为应该由OpenBLAS _healed_处理: https :
在这种情况下,numpy修补程序将确保在构建期间使用OpenBLAS版本,且版本不早于即将发布的OpenBLAS版本。
@matti numpy/__init__.py
有一个健全性检查。 我们可以添加一个简单可靠的测试来检测此问题吗?
a = np.arange(13 * 13, dtype=np.float64).reshape(13, 13)
a = a % 17
va, ve = np.linalg.eig(a)
@mattip ,谢谢您的摘录。 但是我将需要一些时间来访问台式机,在那里我可以进行此类测试。 现在,我大部分时间都在笔记本电脑上使用最小的编程环境,几乎无法安装任何东西。
我们已经合并了对OpenBLAS v0.3.12的更新,并且使用该版本+ Windows Update 2004的本地版本通过了测试套件。
在Windows更新之前,请保持打开状态。
新版OpenBLAS是否装有预释放轮? 很高兴对遇到此错误的下游项目进行一些进一步的测试。
由于存在测试错误(现已修复),当前缺少Windows 3.9预发布轮。 固定库将在今天或明天发布的1.19.3中使用。
/MT
选项启用Windows上的静态链接。 使用Microsoft SDK的1909版本可以静态链接libucrt.lib。 这可以作为2004和20H2年ucrtbase.dll错误的解决方法。 这会使车轮更大,这是不利的一面。
我不知道这个/ MT问题是否仍然有效,但是应该考虑。
我认为,如果NumPy是唯一使用MT构建的模块,则可能是
好。 当然,如果NumPy是MT,则可能是这样
下游也需要MT,因此这将是一个问题。
2020年11月2日星期一,19:37 carlkl [email protected]写道:
我不知道这个/ MT问题
https://stevedower.id.au/blog/building-for-python-3-5-part-two仍然是
有效,但是应该考虑。-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看
https://github.com/numpy/numpy/issues/16744#issuecomment-720682011 ,或
退订
https://github.com/notifications/unsubscribe-auth/ABKTSRJIVAQLECK4E2EVSSDSN4C65ANCNFSM4OP5IXNQ
。
有关此问题的任何建议的解决方法? 我的情况是我正在更新到2004更新的计算机上,并且拥有使用pip安装numpy / scipy / pandas等的桌面软件。所有此软件都受Microsoft更新引起的此问题的影响。
任何建议将不胜感激,因为使用conda安装numpy并不是我正在开发的软件的选项。
如果您不需要docker,则可以固定1.19.3。 它通过了Windows系统上的所有测试。
谢谢。 1.19.3在此问题上与pip配合使用。
BLAS错误检测中的链接在MS网站上引发了很多嘈杂的帖子。 我希望这不会最终爆炸。
我想另一种选择是在Win64上使用第三方fmod。
我不知道如果NumPy在发布后四个月内有如此严重的未修复错误,将会带来怎样的反应,特别是如果我们没有为用户提供降级到先前版本的明确说明的话。 用户可以轻松固定到1.19.3,但这并不能解决问题,它只会在混乱之后将其移动到另一个使用寄存器的包中:可能是scipy,也许是tensorflow。
解决方法的另一种思路:查看ucrt中是否有使用FPU并将其状态保持在良好状态的其他功能。 如果有一个,我们可以在fmod之后调用它。 这将优于@mattip编写的程序集解决方法,因为它不需要任何特殊的文件或生成过程。
我认为我们不应该投入更多的精力来解决这个问题。 我们为减轻该问题所做的任何其他工作将占用开发人员宝贵的时间,并减轻Microsoft解决此问题的压力。 另外,如上所述,其他项目中调用fmod
和/或使用寄存器的任何代码都可能会遇到此问题,而与NumPy无关。
我认为我们不应该投入更多的精力来解决这个问题。 我们为减轻该问题所做的任何其他工作将占用开发人员宝贵的时间,并减轻Microsoft解决此问题的压力。 另外,如上所述,其他项目中调用
fmod
和/或使用寄存器的任何代码都可能会遇到此问题,而与NumPy无关。
看到对错误消息的反应后,显然不是很有帮助。 例如,它应该建议想要使用最新NumPy功能的Windows用户使用MKL附带的发行版,而不是pip wheel。 它还应包含到该线程的链接。
虽然这显然是MS的修复责任,但要让用户指出别人的过错让他们感到痛苦,这对保持项目良好信誉的任何项目来说都是很少的好方法。
@bashtage不太确定引起痛苦的意思。 我们可以删除链接,让用户进入此处,但我们应该警告用户,当他们在2004年运行时,结果将不可信任;如果您不信任计算结果,则应避免在该平台上进行计算。
不太确定引起痛苦的意思。
NumPy的导入失败很明显,并且没有提供解决方法。 如果已知解决方法的列表清晰可见,这对大多数用户将是最有用的:
(a)使用基于MKL的发行版(例如conda或Enthought Deployment Manager)来避免这种情况,但使用线性代数代码
(b)恢复为NumPy 1.19.3,该版本随附受该错误保护的OpenBLAS版本。 此选项可能不适用于在容器中运行的用户。
(c)从源代码构建。 此选项的BLAS性能不佳,但可能适用于不允许第三方分发且使用容器或需要NumPy中的最新功能或错误修复的环境。
我认为唤起人们对fmod错误的关注并没有错,但是随后它将用户发送到该论坛,就好像有某种解决方案正在等待他们。
我们可以删除链接,让用户进入此处,但我们应该警告用户,当他们在2004年运行时,结果将不可信任;如果您不信任计算结果,则应避免在该平台上进行计算。
这不是一个选择。 用户只需要避免使用NumPy + OpenBLAS(例如0.3.12)。 他们不需要避免使用NumPy + Windows(2004 / 20H2(现在有2个发行版本受到影响))。
基于MKL的发行
也有关于MKL问题的报告。
恢复为NumPy 1.19.3
但这无法解决由于使用fmod而导致的其他潜在问题。 问题在于无法确保结果正确。
人们在2004年不应该使用Python,或者使用WSL? 如果可能的话,我还可以在车窗轮子上安装一个旧的ucrt,但是其他项目呢? 有一种简单的方法可以返回到较早的Windows版本吗?
也有关于MKL问题的报告。
NumPy没有在MKL上失败的测试。 当没有故障报告时,似乎很难假定存在问题。 fmod错误不会在MKL的BLAS中显示出来(大概是因为它不使用FPU)。
但这无法解决由于使用fmod而导致的其他潜在问题。 问题在于无法确保结果正确。
不,但是它也不能解决Windows安全问题或许多其他错误。 这里的问题非常特殊。
这两个向我暗示,几乎所有代码都很难解决这个问题。 只有性能最高的代码(如OpenBLAS,包含手写内核的FFT库或MKL)才可能触发#2。
我还认为发布此修复程序是合理的,因为如果OpenBLAS 0.3.12能够按预期工作,则NumPy将会发布,并且永远不会向用户提出此问题。
人们在2004年不应该使用Python,或者使用WSL? 如果可能的话,我还可以在车窗轮子上安装一个旧的ucrt,但是其他项目呢? 有一种简单的方法可以返回到较早的Windows版本吗?
我怀疑对于许多用户而言,这实际上不是许多用户的选择:企业台式机上的企业用户,新手学生(应使用conda)或购买无法降级的2004或20H2笔记本电脑的任何人。
请注意,不仅Condas numpy与MLK链接在一起,它还已经发布了自己的ucrtbase.dll
版本,该版本似乎是较旧的版本(10.0.17134.12)
在这里与@bashtage大致相同,导入失败,没有合理的建议对其进行修复,这对用户来说有点敌意(尽管主要故障是与Microsoft有关)。
@jenshnielsen :请注意,不仅Condas numpy打包了与MLK链接[...]
conda-forge打包的构建允许切换blas / lapack实现(从openblas / mkl / blis / netlib中退出),它不一定是MKL。
人们在2004年不应该使用Python,或者使用WSL?
对于大多数用户而言,这不是默认的操作模式。
如果可能的话,我还可以在车窗轮子上安装一个旧的ucrt,但是其他项目呢?
其他项目不是我们的责任。
有一种简单的方法可以返回到较早的Windows版本吗?
如果您进行全新安装或清理磁盘空间,则几乎不可能这样做。
在这里与@bashtage大致相同,导入失败,没有合理的建议对其进行修复,这对用户来说有点敌意(尽管主要故障是与Microsoft有关)。
我同意。 如果不解决这个问题,我们可能最终会失去很多用户。
如果可能的话,我还可以在车窗轮子上安装一个旧的ucrt,但是其他项目呢?
@charris ,这在Windows 10上无济于事。如果将其他ucrt与python或numpy一起部署,则它将永远不会在Windows 10上加载。此方法仅适用于较旧的Windows版本(Windows 7、8、8.1)。
@carlkl
conda打包的python实际上将自身插入DLL搜索路径解析度(该解析度-不变-可能是您说它永远无法在Windows 10上运行的原因),这也是AFAICT也是conda _does_提供ucrtbase.dll
,如@jenshnielsen所写。
@ h-vetinari,通用CRT部署明确指出:
_要注意的本地部署有两个限制:
在Windows 10上,即使应用程序包含通用CRT的应用程序本地副本,也始终使用系统目录中的通用CRT。 即使本地副本是较新的,也是如此,因为Universal CRT是Windows 10上的核心操作系统组件。
顺便说一句:我自己测试了它。 除了与Windows 10一起部署的可用UCRT之外,无法加载其他UCRT。
我也认为发布修复程序是合理的
我想您是说添加PR gh-17547吗?
@carlkl观点的证明:
此错误由MS本身引起,应称为Heisenbug 。 这是昂贵且困难的原因:Windows 2004 UCRT fmod在某些情况下会使FPU寄存器处于错误状态。 当再次使用FPU时,这会导致数值计算错误。 如果未经严格测试,通常不会在用户代码中弹出计算错误。 这可能意味着很长一段时间都不会发现重大的数值错误。 几乎不会更糟。
我想您是说添加PR gh-17547吗?
抱歉,我写错了。
我建议的唯一更改是NumPy提供了更多有关导入异常的信息,该异常建议用户在Windows 2004 / H2上获得可以使他们继续工作/学习/业余爱好的环境的方式。
[此顺序是我对解决方案质量的偏好]
我认为,链接到此问题,或者链接到更干净的问题,可以提供更深层次的解释,也很有意义。 第二个链接也可能是指向文档中的一些发行说明,而不是github问题。
conda-forge打包的构建允许切换blas / lapack实现(从openblas / mkl / blis / netlib中退出),它不一定是MKL。
@ h-vetinari conda-forge + OpenBLAS是否在2004 / H2上建立通过测试?
我刚刚检查了一下,然后用Coda-forge发行了OpenBlas 0.3.12。 难道这会崩溃吗?
使用OpenBLAS-0.3.12中的EMMS
指令使用恢复FPU状态的方法当然应该有助于使numpy和scipy测试变得干净,但正如@charris所说,在fmod(0,x)
也可能发生CPython和后来的FPU指令(在不同于OpenBLAS的程序包中)被调用。 在这种情况下,问题只会转移到其他地方。
最好的选择确实是迫使MS修补越野车的行为。 也许史蒂夫·道尔能帮上忙吗?
对于Agner Fog或Bruce Dawson来说,这可能也是一个有趣的故事:请参见在他的博客中的以下相关故事:
旧事物又是新事物,还有编译器错误
可能是OpenBlas 0.3.12中的错误。 请注意“专用字节数”列:
这可能默认为24个BLAS线程,因为我有24个逻辑CPU。
这是来自conda-forge的带有NumPy 1.19.2的OpenBLAS 0.3.12。
设置$env:OPENBLAS_NUM_THREADS=1
可以大大减少
并使用$env:OPENBLAS_NUM_THREADS=4
线程:
@bashtage :您能否继续在OpenBLAS xianyi / OpenBLAS#2970中讨论OpenBLAS 0.3.12?
@mattip我正在尝试确定conda + OpenBLAS是否是可靠的替代方案。 我看不到1.19.3解决了这些结果后所解决的任何问题。
@bashtage : @carlkl观点的证明:
由于conda打包的python主动规避了Windows标准的DLL分辨率,因此我不确定Windows工具将提供多少证据。 我遇到过这个问题,例如C:\Windows\System32
libcrypto.dll
过期,请参见例如https://github.com/conda-forge/staged-recipes/pull/11452。 长话短说,过时的系统库仅由cryptography
测试套件中的测试失败引起,然后-使用CONDA_DLL_SEARCH_MODIFICATION_ENABLE
-可以强制使用conda提供的openssl。
@bashtage :@ h-vetinari conda-forge + OpenBLAS是否在2004 / H2上建立通过测试?
构建软件包的CI可能不是在当前版本上,因此我自己花了一些时间来构建它。 我目前在2004年的计算机上运行,这是-非常肯定的-结果**:
= 10487 passed, 492 skipped, 19 xfailed, 1 xpassed, 227 warnings in 529.08s (0:08:49) =
@bashtage :我刚刚检查了一下,conda-forge发布了OpenBlas 0.3.12。 难道这会崩溃吗?
conda-forge不附带任何固定的openblas版本-blas版本甚至可以被“热交换”(例如,在openblas,mkl,blis之间),因此该版本并不是一个大问题。 通常,它将使用最新的打包版本。 我无法验证崩溃是否在容器内复制。
@bashtage :: @mattip我试图确定conda + OpenBLAS是否是可靠的选择。 我看不到1.19.3解决了这些结果后所解决的任何问题。
内存增加是由于openblas 0.3.12中的更改所致,如xianyi / OpenBLAS#2970中进一步讨论的。 到目前为止,conda-forge对我来说似乎是一种可靠的选择-至少它不受该错误的直接影响。
**我使用了https://github.com/conda-forge/numpy-feedstock的当前母版(仍为1.19.2)以及openblas 0.3.12。 如果人们感兴趣,我也可以尝试https://github.com/conda-forge/numpy-feedstock/pull/210 + openblas 0.3.12。
好消息是,MS回到了VS论坛,并建议可能在2021年1月底前修复此问题。鉴于此更新,我认为唯一的问题是,更新在检测到越野车功能。
由于conda打包的python主动规避了Windows标准的DLL分辨率,因此我不确定Windows工具将提供多少证据。 我遇到过这个问题,例如
C:\Windows\System32
libcrypto.dll
已经过时,请参阅例如conda-forge / staged-recipes#11452 。 长话短说,过时的系统库仅由cryptography
测试套件中的测试失败引起,然后-使用CONDA_DLL_SEARCH_MODIFICATION_ENABLE
-可以强制使用conda提供的openssl。
conda create -n cf -c conda-forge python numpy pytest hypothesis blas=*=openblas openblas=0.3.9 -y
conda activate cf
python -c "import numpy as np;np.test('full')"
输出
C:\Anaconda\envs\cf\lib\site-packages\numpy\linalg\linalg.py:94: LinAlgError
---------------------------------------------------------------------- Captured stdout call ----------------------------------------------------------------------
** On entry to DGEBAL parameter number 3 had an illegal value
** On entry to DGEHRD parameter number 2 had an illegal value
** On entry to DORGHR DORGQR parameter number 2 had an illegal value
** On entry to DHSEQR parameter number 4 had an illegal value
这表明当使用旧的OpenBLAS时,将使用当前ucrt DLL中的越野车功能。
仅conda forge的openblas = 0.3.12会通过测试,但这与NumPy 1.19.3中提供的相同。
对于使用解除武装的OpenBLAS-0.3.12编译的新的numpy版本,该怎么说呢? 在用于numpy的OpenBLAS编译时,减小了缓冲区大小,并可能减少了线程数。 这将减少OpenBLAS的内存消耗,不仅在Docker测试用例中,而且在设备欠佳的用户中也应有所帮助
窗户盒。
这是来自Python内部的https://tinyurl.com/y3dm3h86错误报告。 首先,感谢您提供了目前可在Windows上运行的版本(1.19.3)。
我知道1.19.3在Linux上不起作用,而1.19.4在Windows上不起作用(尽管有错误)。
是否有可能在Windows的pypi 1.19.3上为所有其他平台制作1.19.4的最新版本? 换句话说,只需删除https://files.pythonhosted.org/packages/33/26/c448c5203823d744b7e71b81c2b6dcbcd4bff972897ce989b437ee836b2b/numpy-1.19.4-cp36-cp36m-win_amd64.whl (以及相应的3.7 / 3.8 / 3.9 amd64版本)即可。目前?
@luciansmith,只要提供的源代码为1.19.4,pip将尝试使用此版本,除非传递了其他标志。 我认为大多数用户只有在知道了问题的情况下才会传递其他标志,但是他们只能固定1.19.3。
我的首选是拥有一个1.19.5,该版本在Linux上使用OpenBLAS 0.3.9,在Windows上使用0.3.12,但是我不知道这是否可行。
最有用的评论
我们已经合并了对OpenBLAS v0.3.12的更新,并且使用该版本+ Windows Update 2004的本地版本通过了测试套件。