Numpy: Las pruebas de regresión polyfit y eig fallan después de la actualización de Windows 10 a 2004

Creado en 3 jul. 2020  ·  171Comentarios  ·  Fuente: numpy/numpy

Las pruebas fallan:
FAILED .... \ lib \ tests \ test_regression.py :: TestRegression :: test_polyfit_build - numpy.linalg.LinAlgError: SVD no ...
FAILED .... \ linalg \ tests \ test_regression.py :: TestRegression :: test_eig_build - numpy.linalg.LinAlgError: Eigenvalues ​​...
FAILED .... \ ma \ tests \ test_extras.py :: TestPolynomial :: test_polyfit - numpy.linalg.LinAlgError: SVD no convergió i ...

con excepciones:

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

y

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

Pasos tomados:

  • Crea una VM
  • Instale la última versión de Windows 10 y actualice a la última versión 2004 (10.0.19041)
  • Instalar Python 3.8.3
  • pip install pytest
  • pip install numpy
  • pip install hypothesis
  • ejecutar pruebas en el paquete

Lo mismo ocurre cuando se ejecutan pruebas en el repositorio.

Versión 1.19.0 de numpy

¿Me faltan dependencias? ¿O es que Windows se está volviendo loco?

00 - Bug 32 - Installation

Comentario más útil

Hemos fusionado una actualización de OpenBLAS v0.3.12 y una compilación local que usa esa versión + la actualización de Windows 2004 pasa el conjunto de pruebas.

Todos 171 comentarios

Editar: Obviamente estás usando pip.También he tenido un resultado extraño en Windows AMD64 en el pasado reciente con bibliotecas de álgebra lineal y descomposiciones de valores propios (en el contexto de la ejecución de pruebas para modelos de estadísticas).

Si tiene tiempo, intente usar Python y pip de 32 bits y vea si tiene los mismos problemas. No pude verlos en ventanas de 32 bits, pero eran repetibles en ventanas de 64 bits.

Si uso conda, que envía MKL, no tengo los errores.

Editar: también los veo cuando uso NumPy 1.18.5 en Windows AMD64.

las pruebas fallan después de la última actualización de Windows 10

¿Las pruebas fallaron antes de la actualización?

No @charris , antes de la actualización, el conjunto de pruebas simplemente pasa.

@speixoto ¿Sabes qué actualización fue específicamente? Me interesaría ver si resuelve mi problema con las ruedas instaladas en pip.

La actualización 1809 (10.0.17763) no estaba causando ninguna prueba fallida @bashtage

1909 tampoco estaba causando nada. Solo comenzó a suceder en 2004.

No estoy 100% convencido de que sea 2004 o algo después. Creo que 2004 funcionó.

FWIW No puedo reproducir estos fallos en CI (Azure o appveyor) pero lo hago localmente en 2 máquinas que son AMD64 y se actualizan en 2004.

¿Alguno de ustedes ha intentado ver si los obtiene en Python de 32 bits?

Parece que se han informado varios problemas con la actualización de 2004. ¿Quizás esto debería informarse también?

Acabo de ejecutar lo siguiente en una instalación nueva de 1909 y 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

En 1909 sin fracasos. En 2004, 30 fallas relacionadas con funciones de álgebra lineal.

Cuando ejecuto pruebas en 2004 en un depurador, noto que la primera llamada a una función a menudo devuelve un resultado incorrecto, pero llamar de nuevo produce el resultado correcto (que permanece correcto si se llama repetidamente). No estoy seguro si esta es información útil para adivinar una causa.

¿Las versiones anteriores de NumPy también tienen problemas? Supongo que está ejecutando 1.19.0.

Usando pip + 1.18.4 y scipy 1.4.1, obtengo el mismo conjunto de errores.

Estos son realmente comunes:

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

Cuando ejecuto usando 1.18.5 + MKL, no obtengo errores. Es difícil decir si es probable que se trate de un error de OpenBLAS o de Windows. Probablemente esto último, pero será muy difícil de encontrar y el diagnóstico está más allá de mis capacidades para la depuración de bajo nivel.

En la misma máquina física, cuando ejecuto Ubuntu usando paquetes pip, no veo ningún error.

Este es el comportamiento más extraño. Falla en la primera llamada, funciona en la segunda y posteriores. Otro comportamiento difícil de entender es que si ejecuto la prueba fallida de forma aislada, no veo el error.

svd

Una actualización final: si pruebo usando una compilación de código fuente de NumPy sin BLAS optimizado, todavía veo errores, aunque no son un conjunto idéntico.

Quizás valga la pena hacer ping a los desarrolladores de OpenBLAS. ¿Ocurre con float32 con tanta frecuencia como con float64?

Cuando ejecuto una prueba completa de NumPy 1.19.0, python -c "import numpy;numpy.test('full')" veo los mismos errores que el anterior:

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...

Creo que si solo ejecuta la prueba exclusivamente, debería pasar si recuerdo correctamente haber hecho ping a las cosas, por lo que eso significa un comportamiento aún más extraño.

He presentado una solicitud ante Microsoft de la única manera que sé:

https://aka.ms/AA8xe7q

Publicar en caso de que otros encuentren esto a través de la búsqueda:

Los usuarios de Windows deben usar Conda / MKL si están en 2004 hasta que esto se resuelva

Aquí hay un pequeño ejemplo de reproducción:

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)

Produce

 ** 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

¿LAPACK cuenta desde 0 o 1? Todos los valores ilegales parecen ser números enteros:
DGEBAL
DGEHRD
DORGHR
DHSEQR

Parece más un problema de OpenBlas (o algo entre 2004 y OpenBLAS). Aquí está mi resumen:

NumPy solamente python -c "import numpy;numpy.test('full')"

  • Sin BLAS optimizado: pase completo
  • OpenBLAS: falla completa
  • MKL: Pase completo

pruebas de statsmodels pytest statsmodels

  • Pip NumPy y SciPy: falla relacionada con SVD y código relacionado con QR
  • MKL NumPy y SciPy: Pass
  • Sin BLAS optimizado: falla , pero menos que todos involucren rutinas scipy.linalg , que usan OpenBLAS.
  • Sin BLAS optimizado, sin SciPY linalg: Pass

Sería bueno saber qué cambió en 2004. ¿Quizás necesitemos un indicador diferente al compilar / vincular la biblioteca?

_Si_ es un error de OpenBLAS, es poco probable que lo hayan visto ya que ninguno de los CI basados ​​en Windows está usando la compilación 19041 (también conocida como Windows 10 2004) o posterior.

Para que quede claro, ¿es cierto que ninguno de estos informes involucra WSL?

No. Todo con python.exe proporcionado por conda o proporcionado por python.org python.exe

¿La prueba falla si la variable de entorno OPENBLAS_CORETYPE=Haswell o OPENBLAS_CORETYPE=NEHALEM se establece explícitamente?

Probé Atom, SandyBridge, Haswell, Prescott y Nehalem, todos con resultados idénticos.

Lo mas extraño es que si corres

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)

la segunda (y cualquier otra) llamada a eig tiene éxito.

SciPy tiene un error similar en

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) 

que sube

 ** 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)

Nota final, la conversión a np.complex128 también aumenta, mientras que la conversión a np.float32 o np.complex64 ambos funcionan sin problemas.

Python partes del código compiladas con enteros largos pero OpenBLAS construido sin INTERFACE64 = 1 en las partes de fortran (LAPACK)?
(Esto todavía no explicaría por qué falla la primera llamada, pero cualquier posterior tiene éxito, ni por qué funcionó antes de la actualización 19041)

Los usuarios de Windows 10 pueden votar a favor de este problema en el Centro de comentarios de Microsoft.

https://aka.ms/AA8xe7q

A petición de profundicé un poco en el código, y supongo que algún aspecto del estado de punto flotante ahora es diferente en la entrada. Eso parecería estar confirmado por esto:

la conversión a np.complex128 también aumenta, mientras que la conversión a np.float32 o np.complex64 funcionan sin problemas.

El primer mensaje de advertencia (que no parece aparecer cuando tiene éxito) "En la entrada al parámetro DGEBAL número 3 tenía un valor ilegal" es causado por esta condición https://github.com/xianyi/OpenBLAS/blob/ce3651516f12079f3ca2418aa85b9ad571c3a391/lapack -netlib / SRC / dgebal.f # L336 que podría ser causado por cualquier número de cálculos previos

Jugando con los pasos de reproducción, descubrí que hacer el mod como float32 lo "arregla":

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)

Entonces, supongo que hay algo en esa ruta de código que está restableciendo correctamente el estado, aunque no estoy seguro de qué es. Con suerte, alguien más familiarizado con las partes internas de numpy podría saber dónde podría estar sucediendo eso.

Me recuerda un poco a un viejo error que vimos con mingw en Windows, donde la configuración del registro de punto flotante no fue heredada por los subprocesos de trabajo, lo que provoca que los desnormales no se vuelvan a cero y a veces estropeen los cálculos posteriores.
No estoy seguro de si esto es de alguna manera relevante para Windows actual en el hardware actual, pero podría ser interesante saber si su
La compilación de OpenBLAS se realizó con CONSISTENT_FPCSR = 1 (o si agregar esa opción de compilación ayuda).

@mattip ¿Sabe si CONSISTENT_FPCSR = 1 en la compilación de OpenBLAS?

Bueno, al menos esto está fuera del camino entonces. la conexión parecía bastante remota de todos modos.

¡Hola! He estado experimentando un problema similar durante algún tiempo y todas mis pruebas apuntan a algo sospechoso entre Windows 10 (2004) y OpenBlas. Normalmente ejecuto mis programas en 3 PC (2 estaciones de trabajo con Windows 10 y una computadora portátil con Windows 7 más antigua). Mis scripts de Python comenzaron a comportarse mal con errores relacionados con la convergencia de linalg y svd () en el momento en que actualicé mis 2 estaciones de trabajo a la versión 2004 de Windows 10. También experimenté fallas la primera vez que ejecuté el script, pero la mayoría de las veces funcionó en un segundo intento (ejecutando cuadernos de Jupyter). ¡La vieja computadora portátil seguía ejecutando los mismos programas sin errores! Tengo miniconda, python 3.6 y todos los paquetes se instalan usando pip (el env es exactamente el mismo en las 3 máquinas).
Hoy eliminé la instalación predeterminada de pip numpy (1.19.0) e instalé la versión numpy + mkl (numpy-1.19.1 + mkl-cp36-cp36m-win_amd64.whl) de https://www.lfd.uci.edu/ ~ gohlke / pythonlibs /. Hasta ahora, los errores relacionados con la convergencia de linalg y svd () desaparecieron. Si encuentro algo más, volveré aquí y lo reportaré.

Dário

¿Es extraño que la dll de OpenBLAS esté siendo creada por la versión VC9 de lib.exe? Esta es la versión que se utilizó con Python 2.7. Puede que no importe, pero se siente extraño dado que VC9 no se usa en ninguna parte.

El siguiente paso para alguien (quizás yo) sería construir NumPy master con un OpenBLAS de un solo subproceso ( USE_THREAD=0 ) para ver si esto soluciona los problemas.

He intentado algunos experimentos sin éxito:

  • Desactivar hilos USE_THREADS=0
  • ILP64 INTERFACE64=1 <- Segfault en la prueba de NumPy con violación de acceso

¿Puede ejecutar el conjunto de pruebas LAPACK con esa configuración de Win10? Recientemente había arreglado la compilación de cmake para producirlo, tal vez proporcione alguna pista sin ningún numpy involucrado.

                        -->   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%)

Aunque veo muchas líneas como

-->  Testing DOUBLE PRECISION Nonsymmetric Eigenvalue Problem [ xeigtstd < nep.in > dnep.out ]
---- TESTING ./xeigtstd... FAILED(./xeigtstd < nep.in > dnep.out did not work) !

así que no estoy seguro de si son confiables.

Parece que la mayoría de las pruebas son segmentadas, pero las supervivientes son perfectas ... esto es un poco más extremo de lo que esperaba.
(El COMPLEX y COMPLEX16 son un poco exigentes en términos de tamaño de pila, por lo que es mucho más probable que haya fallas con la configuración predeterminada del sistema operativo, pero REAL y DOUBLE normalmente mostrarían alrededor de 1200000 pruebas ejecutadas. Esto me hace preguntarme si MS cambió algo con la pila predeterminada aunque límite o diseño)

Algunos antecedentes. Todo se está construyendo con gcc.exe / gfortran.exe. Estos se utilizan para producir un archivo .a, que luego se empaqueta en una DLL. Específicamente:

$ 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)

Realmente creo que el problema está en la transferencia entre NumPy y OpenBLAS. No puedo imaginar cómo podría ocurrir este comportamiento cuando la primera llamada es un error, pero la segunda y las siguientes están bien. ¿Cómo resolverlo (o TBH incluso diagnosticar con precisión el problema profundo) aunque ...?

¿Abolir la plataforma MS y vivir felices para siempre? Si falla las pruebas de lapack, el problema de transferencia se encuentra entre Fortran (= parte LAPACK de OpenBLAS) y C, o Fortran y "cualquier otra cosa".

Me gustaría saber si es posible construir Numpy con OpenBLAS usando icc
e ifort para ver si el problema persiste. Sin embargo, esa es una gran pregunta.

El miércoles 12 de agosto de 2020 a las 19:04, Martin Kroeker [email protected] escribió:

¿Abolir la plataforma MS y vivir felices para siempre? Si falla el
lapack prueba el problema de transferencia se encuentra entre Fortran (= LAPACK parte de
OpenBLAS) y C, o Fortran y "cualquier otra cosa".

-
Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/numpy/numpy/issues/16744#issuecomment-673026759 , o
darse de baja
https://github.com/notifications/unsubscribe-auth/ABKTSRLSHZ2XWF4OE7J3QO3SALKSJANCNFSM4OP5IXNQ
.

Probablemente sería suficiente simplemente construir OpenBLAS con los compiladores de Intel (aunque eso parece ser suficientemente problemático al menos con VS de lo que surgió recientemente, y no tengo una licencia válida para ifc / ifort en este momento.

Los usuarios de Windows deben usar Conda / MKL si están en 2004 hasta que esto se resuelva

@bashtage Gracias por tu sugerencia.
En mi caso, tengo un error cuando uso sqlite usando por pandasql después de aplicar la versión Conda de numpy.

pero no tengo ningún problema cuando uso esta versión de numpy + mkl .

@bashtage parece que hay una nueva presentación de MSVC con una solución para ese problema de enlace de óxido, ¿quizás vale la pena intentarlo?

FYI: problema relacionado con SciPy: https://github.com/scipy/scipy/issues/12747

Hay un informe de que la compilación 17763.1397 de Windows (11 de agosto) soluciona el problema, consulte el número 17082.

Hay un informe de que la compilación 17763.1397 de Windows (11 de agosto) soluciona el problema, consulte el número 17082.

https://support.microsoft.com/en-us/help/4565349/windows-10-update-kb4565349

La compilación 17763.1397 es solo para Windows 10, versión 1809 (se aplica a: Windows 10, versión 1809, todas las ediciones, Windows Server, versión 1809, Windows Server 2019, todas las ediciones).
En este caso, no hay problemas para Windows 10, versión 1809.

Esta es la versión actualizada recientemente de Windows 10, versión 2004.
https://support.microsoft.com/en-us/help/4566782
11 de agosto de 2020: KB4566782 (compilación del SO 19041.450).

Todavía tengo el mismo problema en Windows 10, versión 2004

image

Mismos fallas en 19042.487 (esta es la rama 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)

Puedo reproducir las fallas (parciales) en la prueba lapack de OpenBLAS, que solo afectan a las pruebas EIG (valor propio), que se sabe que tienen algunos requisitos de tamaño de pila inusualmente altos. Allí, el SIGSEGV ocurre en __chkstk_ms_ que se ingresa incluso antes de main (). Duplicar los valores predeterminados de "tamaño reservado de pila" y "tamaño de confirmación de pila" del ejecutable respectivo con la utilidad peflags (por ejemplo, peflags -x4194304 -X4194304 EIG/xeigtsts.exe ) hace que los programas funcionen normalmente, lo que sugiere que la interacción de C / Fortran y el paso de argumentos como tal no problemático. Todavía no he intentado aplicar esto al caso numpy (ni siquiera estoy seguro de qué configuración de peflag ajustar allí, ¿python.exe?), Pero OpenBLAS parece funcionar normalmente cuando se construye con la versión msys2 mingw64 de gcc 9.1.0 en 19041.450 también conocido como 2004

@ martin-frbg Eso parece un progreso.

Fui por un agujero de conejo tratando de instalar todas las dependencias para construir numpy en Windows / MSYS2, por lo que no hay más progreso.

@ martin-frbg, el paquete numpy basado en Msys2 se puede instalar con pacman. Los scripts y parches de compilación de Msys2 están disponibles aquí: https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-python-numpy y https://github.com/msys2/MINGW-packages/tree / master / mingw-w64-openblas.

En una última reunión de triaje, esto surgió como una prioridad relativamente alta, y @hameerabbasi y yo estamos dispuestos a ayudar. ¿Qué podemos hacer?

@bashtage ¿ podrías intentar hacer la pila más grande con editbin /STACK:3145728 python.exe

¿Hay alguna forma de intentar construir NumPy con las versiones de las bibliotecas de OpenBLAS en lugar de las que construimos? Quizás nuestras construcciones estén un poco desviadas.

Probablemente sería posible reemplazar el libopenblas.dll en su compilación con uno creado a partir de la rama actual develop o una versión anterior como 0.3.8 o 0.3.9 para ver si eso tiene algún efecto. (No es que tenga en mente ningún compromiso específico en este momento que pueda haber tenido algo que ver con esto). Desafortunadamente, sigo experimentando errores de instalación incluso con los paquetes msys2, actualmente no puedo ejecutar las pruebas aparentemente debido a que self.ld_version no devuelve nada en una verificación de versión.

Gracias. Estoy intentando actualizar mis ventanas para construir 2004, veamos si termino antes del fin de semana

Además, el "pequeño ejemplo de reproducción" de bashtage de https://github.com/numpy/numpy/issues/16744#issuecomment -655430682 no genera ningún error en mi configuración de msys2. (Por lo que puedo decir, su libopenblas en mingw64 / usr / lib es un 0.3.10 de un solo subproceso construido para Haswell)

@ martin-frbg ¿Es posible construir OpenBLAS usando MSVC?

¿MSVC simple? Es factible, pero ofrece una biblioteca poco optimizada ya que MSVC no admite los núcleos de ensamblaje, prácticamente lo mismo que si construyera OpenBLAS para TARGET = GENERIC.

Además, el "pequeño ejemplo de reproducción" de bashtage de # 16744 (comentario) no genera ningún error en mi configuración de msys2. (Por lo que puedo decir, su libopenblas en mingw64 / usr / lib es un 0.3.10 de un solo subproceso construido para Haswell)

Estoy bastante seguro de que tiene algo que ver con la interfaz entre NumPy y OpenBLAS. La compilación de 32 bits de NumPy tampoco tiene este problema. Las ideas de la gente de Microsoft con la que hablé de que probablemente se trata de un problema de sincronización de subprocesos parecen ser las más plausibles. Podría explicar cómo el valor incorrecto está presente en la primera llamada y luego se corrige en llamadas posteriores.

Fui por un agujero de conejo tratando de instalar todas las dependencias para construir numpy en Windows / MSYS2, por lo que no hay más progreso.

Es un dolor Lo hice, pero automatizarlo para probar algunos experimentos me llevó mucho tiempo. Básicamente, requiere copiar los pasos de https://github.com/MacPython/openblas-libs para obtener los archivos .a y luego copiar los pasos de https://github.com/numpy/numpy/blob/master/ azure-steps-windows.yml para compilar NumPy. Es particularmente difícil ya que algunas partes quieren MSYS2 estándar y otras necesitan que desaparezcan, por lo que terminas instalando y desinstalando la mayor parte de gcc cada vez que quieres hacer un experimento.

La forma más fácil de obtener una compilación de DLL es abrir una cuenta de appveyor y luego clonar https://github.com/MacPython/openblas-libs. Al final de su compilación, hay un artefacto que puede encontrar en el sitio web para descargar y que tiene el archivo dll (y .a). Sin embargo, esto es lento, tardando 3 horas en construir las 3 versiones.

Mirando https://github.com/MacPython/openblas-libs , OpenBLAS parece estar construido con INTERFACE64=1 . Este no es el caso de Msys2 build OpenBLAS y numpy.

@carlkl Este problema no se trata de la compilación Msys2 de NumPy u OpenBLAS. Se trata de la compilación Win32 / AMD64 que hace uso de gfortran proporcionado por Msys2 para compilar fuentes de fortran, pero luego construye una DLL de Win32 a partir de la biblioteca compilada usando lib.exe de MS.

@bashtage Mencioné esto, porque se informó https://github.com/numpy/numpy/issues/16744#issuecomment -689785607, que el segfault no se pudo reproducir dentro de msys2. Y supongo que el entorno msys2 mencionado contiene los paquetes binarios openblas y numpy proporcionados por msys2.

No tengo idea, si el número de Windows de 64 bits está compilado con una bandera similar con MSVC o no.

Por cierto: no puedo encontrar la bandera -fdefault-integer-8 en el repositorio scipy.
No estoy seguro de si el código compilado con -fdefault-integer-8 es compatible con ABI con el código compilado sin esta marca.

Otro aspecto viene a mi mente: tal vez -fdefault-integer-8 debería combinarse con -mcmodel=large .

EDITAR: Recuerde: Windows64 tiene un modelo de memoria LLP64, no ILP64.
LLP64 significa: largo: 32 bits, puntero: 64 bits

Entonces, ¿qué tamaño de números enteros utiliza la compilación numpy que experimenta el problema Win10-2004? Es mejor que coincida con lo que se creó OpenBLAS, pero IIRC este tema ya surgió anteriormente en este hilo (y una falta de coincidencia probablemente conduciría a una rotura más pronunciada independientemente del nivel de parche de Windows)

Al menos Openblas se puede construir en tres variantes con https://github.com/MacPython/openblas-libs (ver appveyor.yml):

  • 32 bits
  • 64 bits
  • 64 bits con INTEGER64

pero si no tengo idea de lo que se usa para las numerosas versiones de 64 bits en Windows.

_y una falta de coincidencia probablemente conduciría a una rotura más pronunciada independientemente del nivel de parche de Windows_

-fdefault-integer-8 solo se aplica a la parte fortran de Lapack. No cambia el modelo de memoria subyacente (LLP64), por lo que no estoy seguro de si deberíamos esperar problemas fuera de las partes de Fortran Lapack.

hmm,

https://github.com/numpy/numpy/blob/60a21a35210725520077f13200498e2bf3198029/azure-pipelines.yml dice

- 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_'
todas las demás versiones ( Python36-64bit-full , Python37-64bit-full ) se compilan sin NPY_USE_BLAS_ILP64.

Los binarios de Numpy en pypi.org están todos construidos con openblas enteros de 32 bits. https://github.com/MacPython/numpy-wheels/blob/v1.19.x/azure/windows.yml

Para obtener detalles sobre el proceso de compilación de gfortran frente a MSVC, consulte aquí . Microsoft lib.exe no está involucrado en la producción de la DLL de openblas, es todo mingw toolchain. Numpy usa el archivo openblas.a y genera la DLL usando gfortran. https://github.com/numpy/numpy/blob/74712a53df240f1661fbced15ae984888fd9afa6/numpy/distutils/fcompiler/gnu.py#L442 Las herramientas MSVC se utilizan para producir el archivo .lib a partir del archivo .def y el código Numpy C compilado con MSVC está vinculado usando ese archivo .lib a la DLL producida por gfortran.

Una posibilidad teórica que podría salir mal es si hay algún tipo de desajuste de la versión mingw entre mingw que produjo el artefacto openblas.a estático y la versión mingw utilizada cuando se compila numpy. Sin embargo, no estoy seguro si esto es posible que pueda causar problemas.

choco install -y mingw --forcex86 --force --version=5.3.0 usados ​​en windows.yml parecen estar desactualizados. ¿Por qué no usar 7.3.0 o 8.1.0 ? Puedo recordar problemas que tuve con gcc-5.x hace dos o tres años.

choco install -y mingw --forcex86 --force --version = 5.3.0 usado en windows.yml parece estar desactualizado

Eso es solo para la compilación de Windows de 32 bits, por lo que probablemente no esté relacionado con este problema.

todas las demás versiones ( Python36-64bit-full , Python37-64bit-full ) se compilan sin NPY_USE_BLAS_ILP64.

Mismos errores en Python 3.6 y 3.8.

Queda una idea (estoy cavando en la oscuridad):

OpenBLAS ahora está compilado con -fno-optimize-sibling-calls , consulte https://github.com/xianyi/OpenBLAS/issues/2154 , https://github.com/xianyi/OpenBLAS/pull/2157 y https: // gcc .gnu.org / bugzilla / show_bug.cgi? id = 90329.
Editar: ver también: https://gcc.gnu.org/legacy-ml/fortran/2019-05/msg00181.html

Numpy no aplicó esta bandera en su parte gfortran de distutils. Sé que numpy está compilado con MSVC. Por lo tanto, esperaría problemas con scipy en lugar de numpy, por lo que esto podría ser nuevamente un viaje equivocado.

Los binarios de Numpy en pypi.org están todos construidos con openblas enteros de 32 bits. https://github.com/MacPython/numpy-wheels/blob/v1.19.x/azure/windows.yml

¿Por qué las configuraciones de compilación que se usan en las pruebas son diferentes de las que se usan en la versión? Parece un riesgo.

¿Podríamos agregar artefactos a las compilaciones de Azure? Esto facilitaría mucho la obtención de ruedas para realizar pruebas. Mi única preocupación aquí es que el límite de artefactos libres es bastante pequeño IIRC, 1GB, y no sé qué sucede cuando lo golpeas (FIFO sería bueno, pero puede hacer otras cosas, incluido el error).

¿Por qué las configuraciones de compilación que se usan en las pruebas son diferentes de las que se usan en la versión?

Probamos todas las versiones de Python compatibles en Windows sin NPY_USE_BLAS_ILP64 , y también probamos Python 3.8 con NPY_USE_BLAS_ILP64 , consulte https://github.com/numpy/numpy/blob/v1.19.2/azure -pipelines.yml # L195. Entonces, las compilaciones semanales son correctas al usar openblas enteros de 32 bits.

¿Podríamos agregar artefactos a las compilaciones de Azure?

Probablemente sea fácil probarlo y averiguar los límites si se produce un error. Sin embargo, las ruedas semanales están destinadas a recrear fielmente las versiones de prueba. Cualquier discrepancia debe tratarse como error y corregirse.

Probablemente sea fácil probarlo y averiguar los límites si se produce un error. Sin embargo, las ruedas semanales están destinadas a recrear fielmente las versiones de prueba. Cualquier discrepancia debe tratarse como error y corregirse.

Estaba pensando que sería más fácil experimentar en un PR en el repositorio principal y tomar el artefacto para probarlo en 2004.

Tiene sentido.

Puede activar las canalizaciones de Azure en su repositorio bashtage / numpy

Un poco más de información: la primera llamada que falla es porque DNRM2 dentro de OpenBLAS devuelve una NAN. Para mí, esto es repetible: cada llamada a

a = np.arange(13 * 13, dtype=np.float64).reshape(13, 13)
a = a % 17
np.linalg.eig(a)

imprime ** On entry to DGEBAL parameter number 3 had an illegal value , que es otra forma de decir " DNRM2 devuelto NAN". La operación mod es crítica, sin ella la llamada a eig no imprime este error.

¿Cómo podría haber interacción entre mod ufunc y la llamada a OpenBLAS?

La operación mod es crítica, sin ella la llamada a eig no imprime este error.

¿La construcción de esta misma matriz exacta desencadena manualmente el error de forma repetida?

Este código no desencadena la falla:

a = np.array([x % 17 for x in range(13 * 13)], dtype=np.float64)
a.shape = (13, 13)
np.linalg.eig(a)

¿Podría el mod dejar un registro en un estado indefinido? No he vuelto a comprobar el nrm2.S, pero creo que hace algunos años tuvimos algunos problemas al ensamblar XORing un registro consigo mismo para borrarlo, lo que fallaría en NaN.

Para los que siguen, float64 % termina llamando npy_divmod por cada valor.

... que, en la primera línea llama a npy_fmod() , que es fmod () . Aquí hay algunos cambios que probé. "Error" significa que obtengo el mensaje "valor ilegal" de OpenBLAS cuando ejecuto el código que llama a a % 17; np.linalg.eig(a)
codigo | Salir
--- | ---
mod = npy_fmod@c@(a, b); (código original) | Error
mod = 100; //npy_fmod@c@(a, b); | No hay error
mod = npy_fmod@c@(a, b); mod = 100.0; | Error

Entonces parece que fmod de MSVC está haciendo algo que confunde a OpenBLAS.

Eso es interesante y extraño.

¿Puede usar una versión ingenua (no proporcionada por la plataforma) de fmod para ver si eso lo solucionó?

O simplemente fuerce HAVE_MODF a 0 .

No creo que tengamos una versión ingenua de fmod, ¿verdad?

Veo que hay una macro HAVE_MODF, pero ¿a dónde conduce esta ruta ?

Parece que vuelve a la versión doble si faltan el flotador y el doble largo. La versión doble es obligatoria para construir numpy. El undef es probablemente para evitar las funciones en línea del compilador, ISTR que eso fue un problema en Windows hace mucho tiempo.

Quería "probar" que el problema es la implementación fmod , que proviene de ucrtbase.dll . Así que escribí una pequeña solución que usa ctypes para sacar la función de la dll y usarla en lugar de llamar directamente fmod . Las pruebas aún fallan. Luego cambié a una versión anterior de ucrtbase.dll (solo para la función fmod ). Las pruebas pasan. Abrí un hilo en el foro de Visual Studio . Si alguien conoce una forma mejor de comunicarse con Microsoft, sería genial.

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)
 {

¿Qué pasa si agrega algún código después de la llamada fmod, de modo que ST(0) no contenga nan? ¿O configurarlo en nan sintéticamente?
¿Las convenciones de llamadas imponen algunas restricciones sobre cómo se supone que se comportan estos registros?

Quería "probar" que el problema es la implementación fmod , que proviene de ucrtbase.dll . Así que escribí una pequeña solución que usa ctypes para sacar la función de la dll y usarla en lugar de llamar directamente fmod . Las pruebas aún fallan. Luego cambié a una versión anterior de ucrtbase.dll (solo para la función fmod ). Las pruebas pasan. Abrí un hilo en el foro de Visual Studio . Si alguien conoce una forma mejor de comunicarse con Microsoft, sería genial.

Como mínimo, cualquier persona con una cuenta azul, que probablemente sea mucha gente aquí, puede votarla. Me pondré en contacto con algunos de los contactos que hice cuando apareció este problema y que trabajan en Azure ML para ver si pueden hacer algo.

Como mínimo, cualquier persona con una cuenta azul, que probablemente sea mucha gente aquí, puede votarla.

Gracias por el consejo, ¡votó a favor!

No creo que tengamos una versión ingenua de fmod, ¿verdad?

No. Es una función complicada que la especificación IEEE-754 requiere para tener cierto comportamiento. También es muy lento, lo que probablemente esté relacionado con la especificación.

El arduo trabajo de fmod lo realiza la instrucción fprem x87, incluso en la variante VS2019; consulte la esencia de @mattip (última línea) https://gist.github.com/mattip / d9e1f3f88ce77b9fde6a285d585c738e. ( fprem1 es la variante remainder cierto.)

Se debe tener cuidado cuando se usa junto con registros MMX o SSE, como se describe aquí: https://stackoverflow.com/questions/48332763/where-does-the-xmm-instruction-divsd-store-the-remainder.

Hay algunas implementaciones alternativas disponibles como se describe en https://github.com/xianyi/OpenBLAS/issues/2709#issuecomment -702634696. Sin embargo: todos estos necesitan gcc (mingw-w64) para su compilación. OpenLIBM no se compila con MSVC AFAIK. Y el código ensamblador en línea no está permitido con MSVC. En principio, se podría construir (mingw-w64) y usar (MSVC) una biblioteca auxiliar fmod durante la compilación numpy.

¿Qué pasa si agrega algún código después de la llamada fmod, de modo que ST (0) no contenga nan? ¿O configurarlo en nan sintéticamente? ¿Las convenciones de llamadas imponen algunas restricciones sobre cómo se supone que se comportan estos registros?

Supongo que podríamos agregar un pequeño ensamblaje para borrar los registros antes de llamar a OpenBLAS en Windows. Intenté hacer esto en una pequeña configuración de prueba, pero mi ensamblaje masm foo es débil. Intenté escribir un procedimiento que solo llame a fldz varias veces, cuando lo uso obtengo una excepción. ¿Ayuda?

En lots_of_fldz.asm :

.code
lots_of_fldz proc
    fldz
    fldz
    fldz
    fldz
    fldz
    fldz

lots_of_fldz endp
end

En otro archivo:

#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;
}

Colóquelos en un proyecto de VisualStudio y siga esta guía para activar la compilación masm

@mattip , creé un archivo ensamblador para la función fmod de 64 bits que crea un segmento text: idéntico al que se encuentra en la función fmod de mingw-w64 (64 bits). No tengo idea si esto funciona como un reemplazo para la función fmod con errores, pero al menos uno debería intentarlo. El archivo obj resultante podría agregarse a npymath.lib.

fmod.asm: (64 bits)

.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

comando masm: ml64.exe /c fmod.asm crea fmod.obj (use la variante de 64 bits de ml64.exe)

''

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

@carlkl gracias. Sería más feliz con una pieza de ensamblador que restablezca los registros ST (N) que podríamos usar en x86_64 antes de llamar a las funciones de OpenBLAS. Hoy este problema surgió debido a un cambio en fmod , mañana puede ser una función diferente. No estoy seguro de que se requieran funciones para restablecer los registros ST(N) al regresar. Si no existe tal requisito, fmod no tiene errores y el cambio en Windows expuso una falla en OpenBLAS para restablecer los registros antes de usarlos, que deberíamos ayudarlos a solucionarlo o solucionarlo.

Intenté restablecer los registros usando fldz en el comentario anterior, pero mi programa de prueba no funciona.

@mattip , mi conocimiento de ensamblador también es más o menos básico. Sin embargo, puede encontrar una posible respuesta en este hilo SO: https://stackoverflow.com/questions/19892215/free-the-x87-fpu-stack-ia32/33575875

De 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.

Supongo que también podríamos llamar a fninit al comienzo de OpenBLAS nrm2.S (después de la macro PROFCODE) para verificar esa teoría

Interesante parte del
Interfaz binaria de la aplicación System VSuplemento de procesador de arquitectura AMD64Versión borrador 0.99.6

_Los bits de control del registro MXCSR se guardan (se conservan entre llamadas), mientras que los bits de estado se guardan (no se conservan) de la persona que llama ._

_El registro de la palabra de estado x87 se guarda para la persona que llama, mientras que la palabra de control x87 se guarda para la persona que llama.

_Todos los registros x87 están guardados por el llamante, por lo que los llamados que hacen uso de los registros MMX pueden utilizar la instrucción femms más rápida.

Bastante diferente en comparación con la convención de llamadas de Windows de 64 bits.

@ martin-frbg, fninit es peligroso: The FPU control word is set to 037FH (round to nearest, all exceptions masked, 64-bit precision). X87 La precisión extendida no es la deseada en todos los casos, especialmente en Windows.

No quisiera esto para una versión de lanzamiento, solo para una prueba rápida. Todavía no estoy del todo convencido de que OpenBLAS debería de alguna manera limpiar "antes" de sí mismo, pero no puedo encontrar ninguna documentación clara sobre el comportamiento de Windows con la fpu x87 heredada. Me di cuenta de que Agner Fog tiene un documento sobre convenciones de llamadas en http://www.agner.org/optimize/calling_conventions.pdf (la discusión sobre el manejo de Win64 de los registros FP comienza en la página 13, pero se concentra en la disponibilidad básica y el comportamiento en los cambios de contexto).

Consulte 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.

Supongo que esto significa: no use instrucciones x87 (Win64). Si es así, buena suerte. O en otras palabras: el destinatario es responsable de no sufrir daños.

¿Eso parece describir el comportamiento del compilador de MSVC específicamente, mientras que creo que estamos en un ecosistema mingw?

No, Numpy (Pypi) está compilado con MSVC (Visual Studio 2019) en Windows. Para OpenBLAS se usa mingw-w64 (debido a las partes de Fortran). Además, las partes de Scipy Fortran se compilan con mingw-w64. Sin embargo, CPython y sus extensiones binarias se basan en gran medida en los estándares establecidos por MSVC.

Por cierto: esta fue la razón del desarrollo de https://github.com/mingwpy, que actualmente está volviendo a cobrar vida. (enchufe desvergonzado)

Otro poco:

mingw-w64 usa (casi) las mismas convenciones de llamada que MSVC. Las únicas diferencias notables son la alineación de pila diferente en x86 (32 bits), relevante para SIMD y el vectorcall no compatible.

Interesante. x86 no se ve afectado. Solo AMD64.

El domingo 4 de octubre de 2020 a las 22:19, carlkl [email protected] escribió:

Otro poco:

mingw-w64 usa (casi) las mismas convenciones de llamada que MSVC. Lo único
Las diferencias notables son la alineación de pila diferente en x86 (32 bits) -
relevante para SIMD y el vectorcall no compatible.

-
Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/numpy/numpy/issues/16744#issuecomment-703317784 , o
darse de baja
https://github.com/notifications/unsubscribe-auth/ABKTSRMFHWZVLDYDFGBM6YDSJDRGTANCNFSM4OP5IXNQ
.

¿MSVC 32bit no ha repudiado la fpu tal vez? Simplemente haré un reemplazo provisional del nrm2.S que usa fpu por nrm2_see2.S (si es viable, desafortunadamente hay una serie de rutinas de ensamblaje no utilizadas pero mortales flotando en la base de código) o la versión C simple para el sistema operativo == Windows entonces. (Sin embargo, el otro problema discutido aquí tiene que ser algo más, ya que creo que todas las demás rutinas de ensamblaje anteriores para x86_64 son SSE2 al menos)

@mattip , ¿quizás una llamada a _fpreset después de divmod es suficiente para restablecer desde un estado de FPU en mal estado?

tal vez una llamada a _fpreset

No, no restablece los registros ST(N) , ni corrige las pruebas fallidas.

¿Le diste una oportunidad a _fninit ? Esto debería restablecer la pila de FPU. O ffree o fstp lugar de fldz como se menciona en https://stackoverflow.com/questions/19892215/free-the-x87-fpu-stack-ia32/33575875 ?

Con mucho gusto probaría los comandos del ensamblador, pero el proyecto de prueba en el comentario anterior falla. Alguien necesita corregir mi código para que funcione (de hecho, fninit parece un buen candidato), luego puedo emitir instrucciones de ensamblador para restablecer los registros en NumPy antes de llamar a OpenBLAS.

¿Algo como esto?

.code
reset_fpu proc
    finit
    fldz
reset_fpu endp
end

finit ist wait más fninit . No estoy seguro de que se necesite fldz después de fninit .

Como dije en el comentario, falta algo para que la llamada al código ensamblador compilado funcione correctamente. Esto es más o menos lo que tenía en ese comentario. El código falla con exited with code -2147483645 . Eche un vistazo al código completo y vea si puede hacerlo funcionar.

Puedo probarlo (mañana). Sin embargo, estos fragmentos pueden resultar útiles:

https://www.website.masmforum.com/tutorials/fptute/fpuchap4.htm
(uno de los sitios más legibles sobre estos temas que encontré)

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. 

Según tengo entendido, fldz puede segregarse si st (7) está en uso, por lo tanto:

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. 

puede intentar:

.code
reset_fpu proc
    ffree st(7)
    fldz
reset_fpu endp
end

Lo siento, no me estoy aclarando. El problema inmediato no es qué llamadas de ensamblador realizar. El problema inmediato es cómo crear correctamente un procedimiento invocable de manera que podamos usarlo y demostrarlo en un archivo de dos ( *.asm y main.c / main.cpp ) proyecto que se compila y se ejecuta. Una vez que tengamos eso, puedo continuar explorando diferentes llamadas y cómo influyen en OpenBLAS.

@mattip , lo entiendo. Definitivamente lo intentaré, pero esto puede llevar su tiempo.

Tengo la impresión de que el mal comportamiento _tempory_ de fmod en UCRT debería ser _healed_ por OpenBLAS: https://github.com/xianyi/OpenBLAS/pull/2882 y no por numpy ya que numpy no usa la FPU en WIN64. Y, por supuesto, MS debería solucionar este problema con un parche de Windows.
El parche número uno en este caso sería garantizar el uso de una versión de OpenBLAS durante la compilación no anterior a la próxima versión de OpenBLAS.

@matti Hay un control de cordura en numpy/__init__.py . ¿Existe una prueba simple y confiable que podamos agregar para detectar este problema?

a = np.arange(13 * 13, dtype=np.float64).reshape(13, 13)
a = a % 17
va, ve = np.linalg.eig(a)

@mattip , gracias por el fragmento. Pero necesitaré algo de tiempo para tener acceso a un escritorio donde podré hacer este tipo de pruebas. En este momento estoy trabajando la mayor parte del tiempo con una computadora portátil con un entorno de programación mínimo donde no puedo instalar casi nada.

Hemos fusionado una actualización de OpenBLAS v0.3.12 y una compilación local que usa esa versión + la actualización de Windows 2004 pasa el conjunto de pruebas.

Dejando esto abierto hasta que Windows se actualice.

¿Se han construido las ruedas de prelanzamiento con el nuevo OpenBLAS? Feliz de hacer algunas pruebas adicionales con proyectos posteriores que estaban experimentando este error.

Las ruedas de prelanzamiento de Windows 3.9 faltan actualmente porque hubo errores de prueba (ahora corregidos). La biblioteca fija se utilizará en 1.19.3 que saldrá hoy o mañana.

La opción /MT habilita la vinculación estática en Windows. Es posible vincular estáticamente con libucrt.lib utilizando la versión 1909 del SDK de Microsoft. Esto podría actuar como una solución para el error ucrtbase.dll en 2004 y 20H2. Haría las ruedas más grandes, lo cual es una desventaja.

No tengo idea de si este problema / MT sigue siendo válido, pero debería considerarlo.

Creo que si NumPy es el único módulo que se compila con MT, entonces podría ser
OKAY. Por supuesto, podría darse el caso de que si NumPy es MT, entonces cualquier
aguas abajo también necesitaría ser MT, por lo que esto sería un problema.

El lunes 2 de noviembre de 2020 a las 19:37, carlkl [email protected] escribió:

No tengo idea si este problema / MT
https://stevedower.id.au/blog/building-for-python-3-5-part-two sigue siendo
válido, pero debe considerarse.

-
Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/numpy/numpy/issues/16744#issuecomment-720682011 , o
darse de baja
https://github.com/notifications/unsubscribe-auth/ABKTSRJIVAQLECK4E2EVSSDSN4C65ANCNFSM4OP5IXNQ
.

¿Alguna solución alternativa recomendada para este problema? Mi situación es que estoy en una máquina actualizada a la actualización de 2004 y tengo un software de escritorio que usa pip para instalar numpy / scipy / pandas, etc. Todo este software se ve afectado por este problema causado por la actualización de Microsoft.

Se agradecería cualquier recomendación, porque usar conda para instalar numpy no es una opción para el software en el que estoy trabajando.

Si no necesita la ventana acoplable, puede anclar 1.19.3. Pasa todas las pruebas en mis sistemas Windows.

Gracias. 1.19.3 trabaja con pip en el tema.

El enlace en la detección de BLAS incorrecta genera muchas publicaciones ruidosas en el sitio de MS. Espero que esto no termine explotando.

Supongo que otra alternativa es usar un fmod de terceros en Win64.

Me pregunto cuál sería la respuesta si NumPy tuviera un error sin corregir tan grave durante cuatro meses después del lanzamiento, especialmente si no proporcionáramos instrucciones claras para que los usuarios cambiaran a la versión anterior. Los usuarios pueden anclar fácilmente a 1.19.3, pero eso no resolverá el problema, solo lo moverá a otro paquete que use los registros después de que se hayan estropeado: tal vez scipy, tal vez tensorflow.

Otra idea para una solución alternativa: vea si hay alguna otra función en ucrt que use la FPU y deje su estado en buenas condiciones. Si hay uno, podríamos llamarlo después de fmod. Esto tendría la ventaja sobre la solución de ensamblaje que @mattip escribió, ya que no necesitaría ningún archivo especial o proceso de compilación.

No creo que debamos invertir más esfuerzo en solucionar este problema. Cualquier trabajo adicional que hagamos para mitigar el problema requerirá un valioso tiempo para los desarrolladores y reducirá la presión sobre Microsoft para solucionarlo. Además, como se mencionó anteriormente, cualquier código en otros proyectos que llame a fmod y / o use los registros puede tener este problema sin conexión a NumPy.

No creo que debamos invertir más esfuerzo en solucionar este problema. Cualquier trabajo adicional que hagamos para mitigar el problema requerirá un valioso tiempo para los desarrolladores y reducirá la presión sobre Microsoft para solucionarlo. Además, como se mencionó anteriormente, cualquier código en otros proyectos que llame a fmod y / o use los registros puede tener este problema sin conexión a NumPy.

Habiendo visto la reacción al mensaje de error, claramente no es muy útil. Por ejemplo, debería sugerir que los usuarios de Windows que quieran utilizar las últimas funciones de NumPy deberían utilizar una distribución que se envíe con MKL en lugar de la rueda de pip. También debe incluir un enlace a este hilo.

Si bien esto es claramente responsabilidad de MS de arreglar, causar dolor a los usuarios al señalar la culpa de otra persona rara vez es una buena manera de que cualquier proyecto mantenga la buena voluntad.

@bashtage No estoy muy seguro de a qué te refieres con causar dolor. Podríamos eliminar el enlace y hacer que los usuarios aterricen aquí, pero debemos advertir a los usuarios que cuando se ejecutan en 2004 no se puede confiar en los resultados, y si no puede confiar en los resultados de un cálculo, debe evitar el cálculo en esa plataforma.

No estoy muy seguro de lo que quiere decir con causar dolor.

La importación de NumPy falla espectacularmente y no se proporciona ninguna solución. Sería muy útil para la mayoría de los usuarios si la lista de soluciones alternativas conocidas fuera claramente visible:

(a) Usar una distribución basada en MKL como conda o Enthought Deployment Manager que evita esto pero en código de álgebra lineal
(b) Vuelva a NumPy 1.19.3 que se envía con una versión de OpenBLAS que está protegida contra el error. Es posible que esta opción no sea adecuada para usuarios que ejecutan en contenedores.
(c) Construir desde la fuente. Esta opción tendrá BLAS de bajo rendimiento, pero puede ser adecuada en entornos donde no se permite la distribución de terceros y se utilizan contenedores o se requiere una función reciente o una corrección de errores en NumPy.

No creo que esté mal llamar la atención sobre el error fmod, pero luego envía a los usuarios a ese foro como si hubiera alguna solución esperándolos.

Podríamos eliminar el enlace y hacer que los usuarios aterricen aquí, pero debemos advertir a los usuarios que cuando se ejecutan en 2004 no se puede confiar en los resultados, y si no puede confiar en los resultados de un cálculo, debe evitar el cálculo en esa plataforma.

Ésta no es una opción. Los usuarios solo deben evitar NumPy + OpenBLAS (ex 0.3.12). No necesitan evitar NumPy + Windows (2004 / 20H2 (ahora hay 2 versiones publicadas afectadas)).

Distribución basada en MKL

También hubo un informe de problemas con MKL.

Volver a NumPy 1.19.3

Pero eso no solucionará otros problemas potenciales resultantes del uso de fmod. El problema es que no hay forma de asegurarse de que los resultados sean correctos.

La gente no debería usar Python en 2004, ¿tal vez usar WSL en su lugar? También estaría de acuerdo con incluir un ucrt más antiguo con las ruedas de Windows si eso fuera posible, pero ¿qué pasa con otros proyectos? ¿Existe una manera fácil de volver a versiones anteriores de Windows?

También hubo un informe de problemas con MKL.

NumPy no tiene una prueba que falle en MKL. Parece difícil suponer que existe un problema cuando no se informa de fallas. El error fmod no se manifiesta en el BLAS de MKL (presumiblemente porque no usa FPU).

Pero eso no solucionará otros problemas potenciales resultantes del uso de fmod. El problema es que no hay forma de asegurarse de que los resultados sean correctos.

No, pero tampoco solucionará los problemas de seguridad de Windows ni muchos otros errores. El problema aquí es muy particular.

  1. fmod está bien porque produce resultados correctos
  2. Necesita tener código escrito en ensamblador para encontrar este problema ya que el compilador del sistema no producirá código x87.

Estos dos me sugieren que el problema es muy difícil de alcanzar para casi todo el código. Solo el código de mayor rendimiento como OpenBLAS, las bibliotecas FFT que contienen kernels escritos a mano o MKL probablemente activen el número 2.

También creo que es razonable publicar la solución, ya que si OpenBLAS 0.3.12 funcionó como se esperaba, NumPy se habría lanzado y este problema nunca se habría planteado a los usuarios.

La gente no debería usar Python en 2004, ¿tal vez usar WSL en su lugar? También estaría de acuerdo con incluir un ucrt más antiguo con las ruedas de Windows si eso fuera posible, pero ¿qué pasa con otros proyectos? ¿Existe una manera fácil de volver a versiones anteriores de Windows?

Sospecho que para muchos usuarios esto no es realmente una opción para muchos usuarios: usuarios corporativos en el escritorio empresarial, estudiantes novatos (que deberían usar conda) o cualquiera que haya comprado una computadora portátil con 2004 o 20H2 que no pueda degradar.

Tenga en cuenta que Condas no solo está empaquetado numpy vinculado contra MLK, sino que también envía su propia versión de ucrtbase.dll que parece ser una versión anterior (10.0.17134.12)

En gran parte de acuerdo con @bashtage aquí, una importación fallida sin una recomendación razonable para solucionarlo es un poco hostil para los usuarios (a pesar de que la falla principal es de microsoft).

@jenshnielsen : Tenga en cuenta que no solo el paquete de Condas está vinculado con MLK [...]

Las compilaciones empaquetadas por conda-forge permiten cambiar la implementación de blas / lapack (fuera de openblas / mkl / blis / netlib), no tiene que ser MKL.

La gente no debería usar Python en 2004, ¿tal vez usar WSL en su lugar?

Ese no es el modo de operaciones predeterminado para la mayoría de los usuarios.

También estaría de acuerdo con incluir un ucrt más antiguo con las ruedas de Windows si eso fuera posible, pero ¿qué pasa con otros proyectos?

Otros proyectos no son nuestra responsabilidad.

¿Existe una manera fácil de volver a versiones anteriores de Windows?

Si realizó una nueva instalación o limpió su espacio en disco, será casi imposible hacerlo.

En gran parte de acuerdo con @bashtage aquí, una importación fallida sin una recomendación razonable para solucionarlo es un poco hostil para los usuarios (a pesar de que la falla principal es de microsoft).

Estoy de acuerdo. Podríamos terminar perdiendo muchos usuarios si no solucionamos esto.

También estaría de acuerdo con incluir un ucrt más antiguo con las ruedas de Windows si eso fuera posible, pero ¿qué pasa con otros proyectos?

@charris , esto no ayudará en Windows 10. Si implementa un ucrt diferente junto con python o numpy, nunca se cargará en Windows 10. Este método solo se aplica a versiones anteriores de Windows (Windows 7, 8, 8.1).

@carlkl
El python empaquetado conda en realidad se interpone en la resolución de la ruta de búsqueda de DLL (que, sin cambios, presumiblemente sería la razón por la que dice que nunca puede funcionar en Windows 10), y esta es AFAICT también la razón por la que conda _does_ proporciona un ucrtbase.dll , como escribe @jenshnielsen .

@ h-vetinari, la implementación de Universal CRT establece claramente:

_Existen dos restricciones en la implementación local que debe tener en cuenta:
En Windows 10, siempre se usa Universal CRT en el directorio del sistema, incluso si una aplicación incluye una copia local de la aplicación de Universal CRT. Es cierto incluso cuando la copia local es más nueva, porque Universal CRT es un componente central del sistema operativo en Windows 10._

Por cierto: lo probé yo mismo. No hay forma de cargar otro UCRT que el UCRT disponible implementado con Windows 10.

También creo que es razonable publicar la solución.

con esto creo que te refieres a agregar PR gh-17547?

Prueba del punto de

image

Este error, causado por la propia MS, debería llamarse Heisenbug . Fue costoso y difícil encontrar la causa: Windows 2004 UCRT fmod deja los registros FPU en un estado fallido bajo ciertas circunstancias. Esto puede dar lugar a errores de cálculo numérico mucho más tarde cuando vuelva a utilizar la FPU. Los errores de cálculo no suelen aparecer en los códigos de usuario si no se prueban rigurosamente. Esto puede significar que los errores numéricos importantes no se detectan durante mucho tiempo. Difícilmente podría ser peor.

con esto creo que te refieres a agregar PR gh-17547 ?

Lo siento, escribí algo incorrecto.

El único cambio que sugiero es que NumPy proporciona más información en la excepción planteada en la importación que sugiere formas en las que un usuario podría obtener un entorno en Windows 2004 / H2 que le permitiría continuar con su trabajo / escuela / pasatiempo.

  1. WSL
  2. conda / entusiasmado
  3. 1.19.3
  4. Construir desde la fuente

[Este pedido es mi preferencia en cuanto a la calidad de la solución]

Creo que también tendría sentido vincularlo a este problema, o a un problema que sea un poco más claro que proporcione una explicación más profunda. Este segundo enlace también podría ser a algunas notas de la versión en los documentos, en lugar de un problema de github.

Las compilaciones empaquetadas por conda-forge permiten cambiar la implementación de blas / lapack (fuera de openblas / mkl / blis / netlib), no tiene que ser MKL.

@ h-vetinari ¿Las compilaciones de conda-forge + OpenBLAS pasan las pruebas en 2004 / H2?

Acabo de comprobar y coda-forge envía OpenBlas 0.3.12. ¿Entonces esto choca los contenedores?

Usar el método de curación del estado de FPU con la instrucción EMMS en OpenBLAS-0.3.12 debería ayudar, por supuesto, a limpiar las pruebas numpy y scipy, pero como @charris declaró llamar a fmod(0,x) en Las instrucciones CPython y luego FPU llamadas más tarde (en un paquete diferente al de OpenBLAS) también podrían ocurrir. En este caso, el problema solo se traslada a otra parte.

De hecho, la mejor apuesta es obligar a MS a corregir este comportamiento defectuoso. ¿Quizás Steve Dower pueda ayudar?

Esta también podría ser una historia interesante para Agner Fog o tal vez Bruce Dawson: vea esta historia relacionada en su blog:
Todo lo viejo es nuevo de nuevo y un error del compilador

Probablemente el error en OpenBlas 0.3.12. Tenga en cuenta la columna de bytes privados:

image

Esto probablemente tiene como valor predeterminado 24 subprocesos BLAS ya que tengo 24 CPU lógicas.

Esto es OpenBLAS 0.3.12 con NumPy 1.19.2 de conda-forge.

Establecer $env:OPENBLAS_NUM_THREADS=1 produce una reducción dramática

image

Y con $env:OPENBLAS_NUM_THREADS=4 hilos:

image

@bashtage : ¿podría seguir hablando de OpenBLAS 0.3.12 en OpenBLAS xianyi / OpenBLAS # 2970?

@mattip Estaba tratando de determinar si conda + OpenBLAS era una alternativa creíble. No creo que resuelva nada de lo que resuelve 1.19.3 habiendo visto estos resultados.

@bashtage : Prueba del punto de

Dado que Python empaquetado con conda elude activamente la resolución DLL estándar de Windows, no estoy seguro de qué tan buena será una herramienta de Windows. Me he encontrado con este problema, por ejemplo, con libcrypto.dll desactualizados en C:\Windows\System32 , consulte, por ejemplo, https://github.com/conda-forge/staged-recipes/pull/11452. En pocas palabras, la biblioteca del sistema obsoleta solo fue detectada por una falla de prueba en el conjunto de pruebas cryptography y luego, usando CONDA_DLL_SEARCH_MODIFICATION_ENABLE , el uso del openssl proporcionado por conda podría forzarse.

@bashtage : @ h-vetinari ¿Las compilaciones conda-forge + OpenBLAS superan las pruebas en 2004 / H2?

El CI que está construyendo los paquetes probablemente no está en una versión tan actual, y me tomó un poco construirlo yo mismo. Actualmente estoy usando una máquina de 2004 y este es el resultado, muy positivo **:

= 10487 passed, 492 skipped, 19 xfailed, 1 xpassed, 227 warnings in 529.08s (0:08:49) =

@bashtage : Acabo de comprobar y conda-forge envía OpenBlas 0.3.12. ¿Entonces esto choca los contenedores?

conda-forge no se envía con ninguna versión fija de openblas; la versión de blas puede incluso ser "intercambiada en caliente" (por ejemplo, entre openblas, mkl, blis), por lo que la versión no es un gran problema. Sin embargo, generalmente utilizará la versión empaquetada más reciente. No puedo verificar si el accidente se reproduce o no dentro de los contenedores.

@bashtage :: @mattip Estaba tratando de determinar si conda + OpenBLAS era una alternativa creíble. No creo que resuelva nada de lo que resuelve 1.19.3 habiendo visto estos resultados.

El aumento de memoria se debió a un cambio en openblas 0.3.12, como se explica más adelante en xianyi / OpenBLAS # 2970. Hasta ahora, conda-forge me parece una alternativa creíble, al menos no se ve afectado directamente por el error.

** Usé el maestro actual de https://github.com/conda-forge/numpy-feedstock , que todavía está en 1.19.2, junto con openblas 0.3.12. También podría probar https://github.com/conda-forge/numpy-feedstock/pull/210 + openblas 0.3.12, si la gente está interesada.

En buenas noticias, MS volvió al foro de VS y sugirió que una solución podría estar disponible para fines de enero de 2021. Dada esta actualización, creo que la única pregunta es si hay algún valor en actualizar el mensaje de error que se genera cuando el Se detecta la función de buggy.

Dado que Python empaquetado con conda elude activamente la resolución DLL estándar de Windows, no estoy seguro de qué tan buena será una herramienta de Windows. He encontrado este problema, por ejemplo, con libcrypto.dll obsoletos en C:\Windows\System32 , consulte, por ejemplo, conda-forge / staged-recipes # 11452 . En pocas palabras, la biblioteca del sistema obsoleta solo fue detectada por una falla de prueba en el conjunto de pruebas cryptography y luego, usando CONDA_DLL_SEARCH_MODIFICATION_ENABLE , el uso del openssl proporcionado por conda podría forzarse.

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')"

salidas

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

Esto muestra que cuando se utiliza el antiguo OpenBLAS, se está utilizando la función defectuosa de la DLL ucrt actual.

Solo openblas = 0.3.12 de conda forge pasará las pruebas, pero es el mismo que se envió en NumPy 1.19.3.

¿Qué habla en contra de una nueva versión compilada con un OpenBLAS-0.3.12 desarmado? Se redujo el tamaño de búfer y tal vez se redujo el número de subprocesos en tiempo de compilación de OpenBLAS utilizado para numpy. Esto debería reducir el consumo de memoria de OpenBLAS y debería ayudar no solo en el caso de prueba de Docker, sino también a los usuarios con menos equipos
cajas de ventanas.

Aquí del https://tinyurl.com/y3dm3h86 informe de error desde dentro de Python. Primero, gracias por proporcionar una versión que funciona en Windows por ahora (1.19.3).

Entiendo que 1.19.3 no funciona en Linux y 1.19.4 no funciona en Windows (aunque tiene el error).

¿Sería posible crear la última versión en pypi 1.19.3 para Windows y 1.19.4 para todas las demás plataformas? En otras palabras, simplemente elimine https://files.pythonhosted.org/packages/33/26/c448c5203823d744b7e71b81c2b6dcbcd4bff972897ce989b437ee836b2b/numpy-1.19.4-cp36-cp36m-win_amd64.whl por completo (y las correspondientes versiones 3.9 ¿por ahora?

@luciansmith Siempre que la fuente esté disponible para 1.19.4 pip, intentaremos usar esta versión a menos que se pasen banderas adicionales. Creo que la mayoría de los usuarios solo pasarían indicadores adicionales si conocieran el problema, pero luego podrían simplemente anclar 1.19.3.

Mi preferencia sería tener un 1.19.5 que use OpenBLAS 0.3.9 en Linux y 0.3.12 en Windows, pero no sé si esto es posible.

¿Fue útil esta página
0 / 5 - 0 calificaciones