Numpy: Les tests de régression polyfit et eig échouent après la mise à jour de Windows 10 vers 2004

Créé le 3 juil. 2020  ·  171Commentaires  ·  Source: numpy/numpy

Les tests échouent:
FAILED .... \ lib \ tests \ test_regression.py :: TestRegression :: test_polyfit_build - numpy.linalg.LinAlgError: SVD n'a pas ...
ECHEC .... \ linalg \ tests \ test_regression.py :: TestRegression :: test_eig_build - numpy.linalg.LinAlgError: valeurs propres ...
FAILED .... \ ma \ tests \ test_extras.py :: TestPolynomial :: test_polyfit - numpy.linalg.LinAlgError: SVD n'a pas convergé i ...

avec des exceptions:

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

et

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

Mesures prises:

  • Créer une VM
  • Installez la dernière version de Windows 10 et mettez à jour vers la dernière version 2004 (10.0.19041)
  • Installez Python 3.8.3
  • pip install pytest
  • pip install numpy
  • pip install hypothesis
  • exécuter des tests dans le package

Le même problème se produit lors de l'exécution de tests dans le référentiel.

Version 1.19.0 de numpy

Est-ce que je manque des dépendances? Ou est-ce que Windows devient dingue?

00 - Bug 32 - Installation

Commentaire le plus utile

Nous avons fusionné une mise à jour vers OpenBLAS v0.3.12 et une version locale utilisant cette version + la mise à jour de Windows 2004 passe la suite de tests.

Tous les 171 commentaires

Edit: Vous utilisez évidemment pip.J'ai également eu un résultat étrange sur Windows AMD64 dans un passé récent avec des bibliothèques d'algèbre linéaire et des décompositions de valeurs propres (dans le contexte de l'exécution de test pour statsmodels).

Si vous avez le temps, essayez d'utiliser Python 32 bits et pip et voyez si vous rencontrez les mêmes problèmes? Je ne pouvais pas les voir sur les fenêtres 32 bits, mais ils étaient reproductibles sur les fenêtres 64 bits.

Si j'utilise conda, qui fournit MKL, je n'ai pas les erreurs.

Edit: Je les vois également lors de l'utilisation de NumPy 1.18.5 sur Windows AMD64.

les tests échouent après la dernière mise à jour de Windows 10

Les tests ont-ils échoué avant la mise à jour?

Non @charris , avant la mise à jour, la suite de tests passe juste.

@speixoto Savez-vous de quelle mise à jour il s'agissait précisément? Je serais intéressé de voir si cela résout mon problème avec les roues installées par pip.

La mise à jour 1809 (10.0.17763) n'a provoqué aucun échec du test @bashtage

1909 ne causait rien non plus. Cela n'a commencé qu'à partir de 2004.

Je ne suis pas convaincu à 100% que ce soit 2004 ou quelque chose après. Je pense que 2004 a fonctionné.

FWIW Je ne peux pas reproduire ces plantages sur CI (Azure ou appveyor) mais je le fais localement sur 2 machines qui sont à la fois AMD64 et mises à jour en 2004.

L'un de vous a-t-il essayé de voir si vous les obteniez sur Python 32 bits?

Il semble qu'un certain nombre de problèmes aient été signalés par rapport à la mise à jour de 2004. Peut-être que cela devrait également être signalé?

J'ai juste exécuté ce qui suit sur une nouvelle installation de 1909 et 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, aucun échec. En 2004, 30 échecs étaient tous liés aux fonctions d'algèbre linéaire.

Lorsque j'exécute des tests sur 2004 dans un débogueur, je remarque que le premier appel à une fonction renvoie souvent un résultat incorrect, mais un nouvel appel produit le résultat correct (qui reste correct s'il est appelé à plusieurs reprises). Je ne sais pas si ce sont des informations utiles pour deviner une cause.

Les versions antérieures de NumPy ont-elles également des problèmes? Je suppose que vous exécutez 1.19.0.

En utilisant pip + 1.18.4 et scipy 1.4.1, j'obtiens le même ensemble d'erreurs.

Ce sont vraiment courants:

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

Lorsque je cours avec 1.18.5 + MKL, je n'obtiens aucune erreur. Il est difficile de dire s'il s'agit probablement d'un bogue OpenBLAS ou d'un bogue Windows. Probablement ce dernier, mais il sera vraiment difficile d'y accéder et le diagnostic dépasse mes capacités de débogage de bas niveau.

Sur la même machine physique, lorsque j'exécute dans Ubuntu en utilisant des packages pip, je ne vois aucune erreur.

C'est le comportement le plus étrange. Échec au premier appel, fonctionne sur le deuxième et les suivants. Un autre comportement difficile à comprendre est que si j'exécute le test d'échec de manière isolée, je ne vois pas l'erreur.

svd

Une dernière mise à jour: si je teste en utilisant une version source de NumPy sans BLAS optimisé, je vois toujours des erreurs bien qu'elles ne soient pas un ensemble identique.

Cela vaut peut-être la peine d'envoyer un ping aux développeurs OpenBLAS. Cela se produit-il avec float32 aussi souvent que float64?

Lorsque j'exécute un test complet de NumPy 1.19.0, python -c "import numpy;numpy.test('full')" je vois les mêmes erreurs que ci-dessus:

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

Je pense que si vous n'exécutez le test que de manière exclusive, il devrait réussir si je me souviens bien d'avoir envoyé un ping aux choses, ce qui signifie un comportement encore plus étrange.

J'ai déposé auprès de Microsoft la seule façon dont je sais:

https://aka.ms/AA8xe7q

Publication au cas où d'autres trouveraient cela grâce à la recherche:

Les utilisateurs de Windows doivent utiliser Conda / MKL si en 2004 jusqu'à ce que cela soit résolu

Voici un petit exemple de reproduction:

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)

Produit

 ** 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 compte-t-il entre 0 ou 1? Toutes les valeurs illégales semblent être des entiers:
DGEBAL
DGEHRD
DORGHR
DHSEQR

Cela ressemble plus à un problème OpenBlas (ou quelque chose entre 2004 et OpenBLAS). Voici mon résumé:

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

  • Pas de BLAS optimisé: passe plein
  • OpenBLAS: échec complet
  • MKL: réussite complète

tests de statsmodels pytest statsmodels

  • Pip NumPy et SciPy: échec lié au code associé SVD et QR
  • MKL NumPy et SciPy: réussite
  • Pas de BLAS optimisé: échec , mais moins qui impliquent toutes des routines scipy.linalg , qui utilisent OpenBLAS.
  • Pas de BLAS optimisé, pas de Linalg SciPY: Réussi

Ce serait bien d'apprendre ce qui a changé en 2004. Peut-être avons-nous besoin d'un indicateur différent lors de la compilation / liaison de la bibliothèque?

_S'il s'agit d'un bogue OpenBLAS, il est peu probable qu'ils l'auront vu car aucun des CI Windows n'utilise la build 19041 (alias Windows 10 2004) ou une version ultérieure.

Pour être clair, il est vrai qu'aucun de ces rapports n'implique WSL?

Non. Tous avec soit fourni par conda python.exe ou python.org fourni python.exe

Le test échoue-t-il si la variable d'environnement OPENBLAS_CORETYPE=Haswell ou OPENBLAS_CORETYPE=NEHALEM est explicitement définie?

J'ai essayé Atom, SandyBridge, Haswell, Prescott et Nehalem, tous avec des résultats identiques.

La chose la plus étrange est que si tu cours

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)

le deuxième (et tout autre) appel à eig réussit.

SciPy a une erreur similaire dans

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) 

qui soulève

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

Remarque finale, la conversion en np.complex128 soulève également, tandis que la conversion en np.float32 ou np.complex64 fonctionne sans problème.

Parties Python du code compilées avec des entiers longs mais OpenBLAS construit sans INTERFACE64 = 1 dans les parties fortran (LAPACK)?
(Cela n'expliquerait toujours pas pourquoi le premier appel échoue mais que les suivants réussissent, ni pourquoi cela fonctionnait avant la mise à jour 19041)

Les utilisateurs de Windows 10 peuvent voter pour ce problème dans le hub de commentaires de Microsoft.

https://aka.ms/AA8xe7q

À la demande de @bashtage , j'ai creusé un peu le code, et je suppose que certains aspects de l'état en virgule flottante sont maintenant différents à l'entrée. Cela semble être confirmé par ceci:

la conversion en np.complex128 soulève également, tandis que la conversion en np.float32 ou np.complex64 fonctionne sans problème.

Le premier message d'avertissement (qui ne semble pas apparaître en cas de succès) "Lors de l'entrée dans le paramètre DGEBAL numéro 3 avait une valeur illégale" est causé par cette condition https://github.com/xianyi/OpenBLAS/blob/ce3651516f12079f3ca2418aa85b9ad571c3a391/lapack -netlib / SRC / dgebal.f # L336 qui pourrait être causé par n'importe quel nombre de calculs antérieurs allant à NaN.

En jouant avec les étapes de repro, j'ai trouvé que faire le mod en tant que float32 le "corrige":

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)

Donc, je suppose qu'il y a quelque chose dans ce chemin de code qui réinitialise correctement l'état, même si je ne suis pas sûr de ce que c'est. Espérons que quelqu'un plus familier avec les composants internes de numpy pourra savoir où cela pourrait se produire.

Cela me rappelle un vieux bogue que nous avons vu avec mingw sur Windows, où la configuration du registre à virgule flottante n'était pas héritée par les threads de travail, conduisant à ce que les dénominations ne soient pas vidées à zéro et gâchent parfois les calculs ultérieurs.
Je ne sais pas si cela est en quelque sorte pertinent pour Windows actuel sur le matériel actuel, mais il pourrait être intéressant de savoir si votre
La construction d'OpenBLAS a été faite avec CONSISTENT_FPCSR = 1 (ou si l'ajout de cette option de construction aide).

@mattip Savez-vous si CONSISTENT_FPCSR = 1 dans la version OpenBLAS?

Eh bien, au moins, c'est à l'écart alors. la connexion semblait assez lointaine de toute façon.

Salut! Je rencontre un problème similaire depuis un certain temps maintenant et tous mes tests indiquent quelque chose de louche entre Windows 10 (2004) et OpenBlas. J'exécute généralement mes programmes sur 3 PC (2 postes de travail Windows 10 et un ancien ordinateur portable Windows 7). Mes scripts python ont commencé à mal se comporter avec des erreurs liées à la convergence linalg et svd () au moment où j'ai mis à niveau mes 2 postes de travail vers la version 2004 de Windows 10. J'ai également rencontré des plantages la première fois que j'ai exécuté le script, mais la plupart du temps, il travaillé à un deuxième essai (exécutant des notebooks Jupyter). L'ancien ordinateur portable continuait d'exécuter les mêmes programmes sans erreurs! J'ai miniconda, python 3.6 et tous les packages sont installés à l'aide de pip (l'environnement est exactement le même sur les 3 machines).
Aujourd'hui, j'ai supprimé l'installation de pip default numpy (1.19.0) et installé la version numpy + mkl (numpy-1.19.1 + mkl-cp36-cp36m-win_amd64.whl) de https://www.lfd.uci.edu/ ~ gohlke / pythonlibs /. Jusqu'à présent, les erreurs liées à la convergence linalg et svd () ont disparu. Si je trouve autre chose, je reviens ici et je le signale.

Dário

Il est étrange que la dll OpenBLAS soit créée par la version VC9 de lib.exe? C'est la version qui a été utilisée avec Python 2.7. Cela n'a peut-être pas d'importance, mais cela semble étrange étant donné que VC9 n'est utilisé nulle part.

La prochaine étape pour quelqu'un (peut-être moi) serait de créer un maître NumPy avec un OpenBLAS monothread ( USE_THREAD=0 ) pour voir si cela résout les problèmes.

J'ai essayé quelques expériences sans succès:

  • Désactiver les threads USE_THREADS=0
  • ILP64 INTERFACE64=1 <- Segfault dans le test de NumPy avec violation d'accès

Pouvez-vous exécuter la suite de tests LAPACK avec cette configuration Win10? J'avais récemment corrigé la construction de cmake pour le produire, peut-être que cela fournit un indice sans aucun engourdissement.

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

Bien que je vois beaucoup de lignes comme

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

donc je ne suis pas sûr que ceux-ci soient dignes de confiance.

On dirait que la majorité des tests sont des tests de segmentation, mais les tests qui ont survécu sont parfaits ... c'est un peu plus extrême que ce à quoi je m'attendais.
(Le COMPLEX et le COMPLEX16 sont un peu exigeants en termes de taille de pile, donc les échecs sont beaucoup plus probables avec les paramètres par défaut du système d'exploitation, mais REAL et DOUBLE afficheraient normalement environ 1200000 tests exécutés. Cela me fait me demander si MS a changé quelque chose par rapport à la pile par défaut limite ou disposition cependant)

Un peu de contexte. Tout est en cours de construction avec gcc.exe / gfortran.exe. Ceux-ci sont utilisés pour produire un fichier .a, qui est ensuite intégré dans une DLL. Plus précisément:

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

Je pense vraiment que le problème réside dans le transfert entre NumPy et OpenBLAS. Je ne peux pas imaginer comment ce comportement pourrait se produire lorsque le premier appel est une erreur, mais le deuxième et les suivants sont tous très bien. Comment le résoudre (ou TBH diagnostiquer même avec précision le problème profond) cependant ...?

Abolir la plateforme MS et vivre heureux pour toujours? En cas d'échec des tests de lapack, le problème de transfert se situe entre Fortran (= partie LAPACK d'OpenBLAS) et C, ou Fortran et «autre chose».

Je serais curieux de savoir s'il est possible de construire Numpy avec OpenBLAS en utilisant icc
et ifort alors voyez si le problème persiste. C'est une grande demande cependant.

Le mer.12 août 2020 à 19:04, Martin Kroeker [email protected] a écrit:

Abolir la plateforme MS et vivre heureux pour toujours? S'il échoue, le
lapack teste le problème de transfert se situe entre Fortran (= partie LAPACK de
OpenBLAS) et C, ou Fortran et «autre chose».

-
Vous recevez cela parce que vous avez été mentionné.
Répondez directement à cet e-mail, affichez-le sur GitHub
https://github.com/numpy/numpy/issues/16744#issuecomment-673026759 , ou
Se désabonner
https://github.com/notifications/unsubscribe-auth/ABKTSRLSHZ2XWF4OE7J3QO3SALKSJANCNFSM4OP5IXNQ
.

Serait probablement suffisant pour simplement construire OpenBLAS avec les compilateurs Intel (bien que cela semble être assez problématique au moins avec VS de ce qui est apparu récemment, et je n'ai pas de licence valide pour ifc / ifort pour le moment.

Les utilisateurs de Windows doivent utiliser Conda / MKL si en 2004 jusqu'à ce que cela soit résolu

@bashtage Merci pour votre suggestion.
Dans mon cas, j'ai une erreur lorsque j'utilise sqlite en utilisant par pandasql après avoir appliqué la version Conda de numpy.

mais je n'ai aucun problème lorsque j'utilise cette version de numpy + mkl .

@bashtage il semble qu'il existe une nouvelle version préliminaire de MSVC avec un correctif pour ce problème de lien de rouille, cela vaut peut-être la peine d'essayer?

FYI: problème lié à SciPy: https://github.com/scipy/scipy/issues/12747

Il y a un rapport que Windows build 17763.1397 (11 août) résout le problème, voir # 17082.

Il y a un rapport que Windows build 17763.1397 (11 août) résout le problème, voir # 17082.

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

Build 17763.1397 est uniquement pour Windows 10, version 1809 (s'applique à: Windows 10, version 1809, toutes les éditionsWindows Server version 1809Windows Server 2019, toutes les éditions).
Il n'y a aucun problème dans ce cas pour Windows 10, version 1809.

Ceci est la version récemment mise à jour de Windows 10, version 2004.
https://support.microsoft.com/en-us/help/4566782
11 août 2020 - KB4566782 (build du système d'exploitation 19041.450).

J'ai toujours le même problème sous Windows 10, version 2004

image

Mêmes échecs sur 19042.487 (c'est la branche 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)

Je peux reproduire les échecs (partiels) dans le test lapack d'OpenBLAS - n'affectant que les tests EIG (valeur propre), qui sont connus pour avoir des exigences de stacksize inhabituellement élevées. Là, le SIGSEGV se produit dans __chkstk_ms_ qui est entré avant même main (). Doubler les valeurs par défaut de «taille réservée de la pile» et de la «taille de validation de la pile» de l'exécutable respectif avec l'utilitaire peflags (par exemple peflags -x4194304 -X4194304 EIG/xeigtsts.exe ) fait fonctionner les programmes normalement, suggérant que l'interaction C / Fortran et le passage des arguments comme tels sont pas problématique. Je n'ai pas encore essayé de l'appliquer au cas numpy (je ne sais même pas quel paramètre peflag y ajuster - python.exe?) Mais OpenBLAS lui-même semble fonctionner normalement lorsqu'il est construit avec la version msys2 mingw64 de gcc 9.1.0 sur 19041.450 aka 2004

@ martin-frbg Cela ressemble à un progrès.

Je suis allé dans un terrier pour essayer d'installer toutes les dépendances pour la construction de numpy sur Windows / MSYS2, donc aucun progrès supplémentaire.

@ martin-frbg, le package numpy basé sur Msys2 peut être installé avec pacman. Les scripts de construction et les correctifs Msys2 sont disponibles ici: https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-python-numpy et https://github.com/msys2/MINGW-packages/tree / master / mingw-w64-openblas.

Lors d'une dernière réunion de triage, cela est apparu comme une priorité relativement élevée, et @hameerabbasi et moi sommes prêts à aider. Que pouvons-nous faire?

@bashtage pourriez-vous essayer d'agrandir la pile avec editbin /STACK:3145728 python.exe

Existe-t-il un moyen d'essayer de construire NumPy avec les versions OpenBLAS des bibliothèques au lieu de celles que nous construisons? Peut-être que nos constructions sont un peu décalées.

Il serait probablement possible de remplacer le libopenblas.dll dans votre build par un créé à partir de la branche actuelle develop ou d'une version plus ancienne telle que 0.3.8 ou 0.3.9 pour voir si cela a un effet? (Non pas que j'aie à l'esprit un engagement spécifique en ce moment qui aurait pu avoir une incidence sur cela). Malheureusement, je rencontre toujours des erreurs d'installation même avec les packages msys2, actuellement je ne peux pas exécuter les tests apparemment en raison de self.ld_version ne renvoyant rien dans une vérification de version.

Merci. J'essaye de mettre à jour mes fenêtres pour construire 2004, voyons si je termine avant le week-end

De plus, le "petit exemple de reproduction" de bashtage de https://github.com/numpy/numpy/issues/16744#issuecomment -655430682 ne soulève aucune erreur dans ma configuration msys2. (Autant que je sache, leur libopenblas dans mingw64 / usr / lib est un 0.3.10 mono-thread construit pour Haswell)

@ martin-frbg Est-il possible de construire OpenBLAS en utilisant MSVC?

MSVC ordinaire? Faisable mais donne une bibliothèque mal optimisée car MSVC ne prend pas en charge les noyaux d'assemblage - pratiquement la même chose que si vous aviez construit OpenBLAS pour TARGET = GENERIC.

De plus, le "petit exemple de reproduction" de bashtage de # 16744 (commentaire) ne soulève aucune erreur dans ma configuration msys2. (Autant que je sache, leur libopenblas dans mingw64 / usr / lib est un 0.3.10 mono-thread construit pour Haswell)

Je suis presque sûr que c'est quelque chose à voir avec l'interface entre NumPy et OpenBLAS. La version 32 bits de NumPy n'a pas non plus ce problème. Les idées des personnes de Microsoft avec qui j'ai parlé selon lesquelles il s'agit probablement d'un problème de synchronisation des threads semblent être les plus plausibles. Cela pourrait expliquer comment la mauvaise valeur est présente dans le premier appel, puis corrigée dans les appels suivants.

Je suis allé dans un terrier pour essayer d'installer toutes les dépendances pour la construction de numpy sur Windows / MSYS2, donc aucun progrès supplémentaire.

C'est une douleur. Je l'ai fait, mais l'automatiser pour essayer certaines expériences prenait beaucoup de temps. Cela nécessite essentiellement de copier les étapes de https://github.com/MacPython/openblas-libs pour obtenir les fichiers .a, puis de copier les étapes de https://github.com/numpy/numpy/blob/master/ azure-steps-windows.yml pour générer NumPy. C'est particulièrement difficile car certaines parties veulent le MSYS2 standard et d'autres ont besoin de leur disparition, donc vous finissez par installer et désinstaller la plupart de gcc à chaque fois que vous voulez faire une expérience.

Le moyen le plus simple d'obtenir une compilation DLL est d'ouvrir un compte appveyor, puis de cloner https://github.com/MacPython/openblas-libs. À la fin de votre construction, il y a un artefact que vous pouvez trouver sur le site Web à télécharger et qui contient la dll (et le fichier .a). Ceci est cependant lent, prenant 3 heures pour construire les 3 versions.

En regardant https://github.com/MacPython/openblas-libs , OpenBLAS semble être construit avec INTERFACE64=1 . Ce n'est pas le cas pour Msys2 build OpenBLAS et numpy.

@carlkl Ce problème ne concerne pas la version Msys2 de NumPy ou OpenBLAS. Il s'agit de la version Win32 / AMD64 qui utilise le gfortran fourni par Msys2 pour compiler les sources fortran, mais construit ensuite une DLL Win32 à partir de la bibliothèque compilée à l'aide de lib.exe de MS.

@bashtage J'ai mentionné cela, car il a été signalé https://github.com/numpy/numpy/issues/16744#issuecomment -689785607, que le segfault ne pouvait pas se reproduire dans msys2. Et je suppose que l'environnement msys2 mentionné contient les packages binaires openblas et numpy fournis par msys2.

Je n'ai aucune idée, si le numpy de Windows 64bit est compilé avec un drapeau similaire avec MSVC ou non.

BTW: Je ne trouve pas le drapeau -fdefault-integer-8 dans le référentiel scipy.
Je ne sais pas si le code compilé avec -fdefault-integer-8 est compatible ABI avec le code compilé sans cet indicateur.

Un autre aspect me vient à l'esprit: peut-être que -fdefault-integer-8 devrait être combiné avec -mcmodel=large .

EDIT: Rappelez-vous: Windows64 a un modèle de mémoire LLP64, pas ILP64.
LLP64 signifie: long: 32 bits, pointeur: 64 bits

Alors, quelle taille d'entiers utilise la construction numpy qui rencontre le problème Win10-2004? Cela correspondrait mieux à ce pour quoi OpenBLAS a été construit, mais IIRC ce sujet a déjà été abordé plus tôt dans ce fil (et une incompatibilité conduirait probablement à une rupture plus prononcée quel que soit le niveau de patch Windows)

Au moins Openblas peut être construit en trois variantes avec https://github.com/MacPython/openblas-libs (voir appveyor.yml):

  • 32 bits
  • 64 bits
  • 64 bits avec INTEGER64

mais si je n'ai aucune idée de ce qui est utilisé pour les builds numpy 64bit sur Windows.

_et une discordance conduirait probablement à une rupture plus prononcée quel que soit le niveau de patch Windows_

-fdefault-integer-8 s'applique uniquement à la partie fortran de Lapack. Cela ne change pas le modèle de mémoire sous-jacent (LLP64), donc je ne suis pas sûr que nous devrions nous attendre à des problèmes en dehors des parties Fortran Lapack.

hmm,

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

- 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_'
toutes les autres versions ( Python36-64bit-full , Python37-64bit-full ) sont construites sans NPY_USE_BLAS_ILP64.

Les binaires Numpy sur pypi.org sont tous construits avec des openblas entiers 32 bits. https://github.com/MacPython/numpy-wheels/blob/v1.19.x/azure/windows.yml

Pour les détails du processus de construction gfortran vs MSVC, cliquez ici . Le Microsoft lib.exe n'est pas impliqué dans la production de la DLL openblas, c'est toute la chaîne d'outils mingw. Numpy utilise le fichier openblas.a et génère la DLL à l'aide de gfortran. https://github.com/numpy/numpy/blob/74712a53df240f1661fbced15ae984888fd9afa6/numpy/distutils/fcompiler/gnu.py#L442 Les outils MSVC sont utilisés pour produire le fichier .lib à partir du fichier .def, et le code Numpy C compilé avec MSVC est lié à l'aide de ce fichier .lib à la DLL produite par gfortran.

Une possibilité théorique qui pourrait mal tourner est s'il y a une sorte d'incompatibilité de version de mingw entre mingw qui a produit l'artefact statique openblas.a et la version mingw utilisée lors de la construction de numpy. Cependant, je ne sais pas si cela est possible car cela peut causer des problèmes.

choco install -y mingw --forcex86 --force --version=5.3.0 utilisé dans windows.yml semble être obsolète. Pourquoi ne pas utiliser 7.3.0 ou 8.1.0 ? Je me souviens des problèmes que j'ai rencontrés avec gcc-5.x il y a deux ou trois ans.

choco install -y mingw --forcex86 --force --version = 5.3.0 utilisé dans windows.yml semble être obsolète

C'est pour la version Windows 32 bits uniquement, donc probablement pas lié à ce problème.

toutes les autres versions ( Python36-64bit-full , Python37-64bit-full ) sont construites sans NPY_USE_BLAS_ILP64.

Mêmes erreurs sur Python 3.6 et 3.8.

Il reste une idée (je creuse dans le noir):

OpenBLAS est maintenant compilé avec -fno-optimize-sibling-calls , voir https://github.com/xianyi/OpenBLAS/issues/2154 , https://github.com/xianyi/OpenBLAS/pull/2157 et https: // gcc .gnu.org / bugzilla / show_bug.cgi? id = 90329.
Edit: voir aussi: https://gcc.gnu.org/legacy-ml/fortran/2019-05/msg00181.html

Numpy n'a pas appliqué ce drapeau dans sa partie gfortran des distutils. Je sais que numpy est compilé avec MSVC. Par conséquent, je m'attendrais à des problèmes avec scipy plutôt qu'avec numpy, ce pourrait donc être à nouveau un mauvais voyage.

Les binaires Numpy sur pypi.org sont tous construits avec des openblas entiers 32 bits. https://github.com/MacPython/numpy-wheels/blob/v1.19.x/azure/windows.yml

Pourquoi les configurations de build utilisées dans les tests sont-elles différentes de celles utilisées dans la version? Cela ressemble à un risque.

Pourrions-nous ajouter des artefacts aux builds Azure? Cela rendrait beaucoup plus simple l'obtention de roues pour les tests. Ma seule préoccupation ici est que la limite d'artefacts gratuits est assez petite IIRC, 1 Go, et je ne sais pas ce qui se passe lorsque vous l'atteignez (FIFO serait bien, mais peut faire d'autres choses, y compris une erreur).

Pourquoi les configurations de build utilisées dans les tests sont-elles différentes de celles utilisées dans la version?

Nous testons toutes les versions de python prises en charge dans Windows sans NPY_USE_BLAS_ILP64 , et testons également python 3.8 avec NPY_USE_BLAS_ILP64 , voir https://github.com/numpy/numpy/blob/v1.19.2/azure -pipelines.yml # L195. Ainsi, les versions hebdomadaires sont correctes en utilisant des openblas entiers 32 bits.

Pourrions-nous ajouter des artefacts aux builds Azure?

Probablement facile de l'essayer et de découvrir les limites en cas d'erreur. Cependant, les roues hebdomadaires sont destinées à recréer fidèlement les versions de test. Tout écart doit être traité comme une erreur et corrigé.

Probablement facile de l'essayer et de découvrir les limites en cas d'erreur. Cependant, les roues hebdomadaires sont destinées à recréer fidèlement les versions de test. Tout écart doit être traité comme une erreur et corrigé.

Je pensais qu'il serait plus facile d'expérimenter dans un PR au repo principal et de récupérer l'artefact à tester en 2004.

Logique.

Vous pouvez activer les pipelines Azure dans votre repo bashtage / numpy

Un peu plus d'informations: le premier appel qui échoue est parce que DNRM2 intérieur d'OpenBLAS renvoie un NAN. Pour moi, c'est reproductible: chaque appel à

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

affiche ** On entry to DGEBAL parameter number 3 had an illegal value , ce qui est une autre façon de dire " DNRM2 retourné NAN". L'opération mod est critique, sans elle l'appel à eig n'affiche pas cette erreur.

Comment pourrait-il y avoir une interaction entre le mod ufunc et l'appel à OpenBLAS?

L'opération mod est critique, sans elle l'appel à eig n'imprime pas cette erreur.

La construction de ce même tableau exact déclenche-t-elle manuellement l'erreur de manière répétée?

Ce code ne déclenche pas l'échec:

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

Le mod précédent pourrait-il laisser un registre dans un état indéfini? Je n'ai pas encore vérifié le nrm2.S, mais je pense que nous avons eu il y a quelques années des problèmes de montage XORing un registre avec lui-même pour l'effacer, ce qui échouerait sur NaN.

Pour ceux qui suivent, float64 % finit par appeler npy_divmod pour chaque valeur.

... qui, sur la première ligne, appelle npy_fmod() , qui est fmod () . Voici quelques changements que j'ai essayés. "Erreur" signifie que je reçois le message "Valeur illégale" d'OpenBLAS lors de l'exécution du code qui appelle a % 17; np.linalg.eig(a)
code | résultat
--- | ---
mod = npy_fmod@c@(a, b); (code original) | Erreur
mod = 100; //npy_fmod@c@(a, b); | Pas d'erreur
mod = npy_fmod@c@(a, b); mod = 100.0; | Erreur

Il semble donc que fmod de MSVC fasse quelque chose qui confond OpenBLAS.

C'est intéressant et bizarre.

Pouvez-vous utiliser une version naïve (non fournie par la plate-forme) de fmod pour voir si cela a résolu le problème?

Ou forcez simplement HAVE_MODF à 0 .

Je ne pense pas que nous ayons une version naïve de fmod, n'est-ce pas?

Je vois qu'il existe une macro HAVE_MODF, mais où mène ce chemin ?

On dirait que cela revient à la version double s'il manque un flotteur et un long double. La version double est obligatoire pour construire numpy. Le undef est probablement d'éviter les fonctions en ligne du compilateur, ISTR que c'était un problème sur Windows il y a longtemps.

Je voulais "prouver" que le problème est l'implémentation fmod , qui vient de ucrtbase.dll . J'ai donc écrit un petit contournement qui utilise des ctypes pour extraire la fonction de la dll et l'utiliser pour appeler directement fmod . Les tests échouent toujours. Ensuite, je suis passé à une ancienne version de ucrtbase.dll (uniquement pour la fonction fmod ). Les tests réussissent. J'ai ouvert un fil sur le forum Visual Studio . Si quelqu'un connaît un meilleur moyen de contacter Microsoft, ce serait formidable.

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

Que faire si vous ajoutez du code après l'appel fmod, de sorte que ST(0) ne contienne pas nan? Ou le régler sur nan de manière synthétique?
Les conventions d'appel imposent-elles des contraintes sur le comportement de ces registres?

Je voulais "prouver" que le problème est l'implémentation fmod , qui vient de ucrtbase.dll . J'ai donc écrit un petit contournement qui utilise des ctypes pour extraire la fonction de la dll et l'utiliser pour appeler directement fmod . Les tests échouent toujours. Ensuite, je suis passé à une ancienne version de ucrtbase.dll (uniquement pour la fonction fmod ). Les tests réussissent. J'ai ouvert un fil sur le forum Visual Studio . Si quelqu'un connaît un meilleur moyen de contacter Microsoft, ce serait formidable.

Au minimum, toute personne disposant d'un compte Azure, ce qui est probablement beaucoup de gens ici, peut voter pour lui. Je vais contacter certains contacts que j'ai pris lorsque ce problème est apparu à l'origine et qui travaillent dans Azure ML pour voir s'ils peuvent faire quelque chose.

Au minimum, toute personne disposant d'un compte Azure, ce qui est probablement beaucoup de gens ici, peut voter pour lui.

Merci pour le conseil, voté pour!

Je ne pense pas que nous ayons une version naïve de fmod, n'est-ce pas?

Non. C'est une fonction délicate qui est requise par la spécification IEEE-754 pour avoir un certain comportement. Il est également très lent, ce qui est probablement lié à la spécification.

Le travail acharné de fmod est effectué par l'instuction fprem x87, même dans la variante VS2019 - voir l' essentiel de https://gist.github.com/mattip / d9e1f3f88ce77b9fde6a285d585c738e. ( fprem1 est la variante remainder btw.)

Des précautions doivent être prises lors de l'utilisation en conjonction avec des registres MMX ou SSE - comme décrit ici: https://stackoverflow.com/questions/48332763/where-does-the-xmm-instruction-divsd-store-the-remainder.

Il existe des implémentations alternatives disponibles comme décrit dans https://github.com/xianyi/OpenBLAS/issues/2709#issuecomment -702634696. Cependant: tous ceux-ci ont besoin de gcc (mingw-w64) pour la compilation. OpenLIBM ne compile pas avec MSVC AFAIK. Et le code assembleur en ligne n'est pas autorisé avec MSVC. En principe, on pourrait construire (mingw-w64) et utiliser (MSVC) une bibliothèque d'assistance fmod pendant la construction numpy.

Et si vous ajoutez du code après l'appel fmod, de sorte que ST (0) ne contienne pas nan? Ou le régler sur nan de manière synthétique? Les conventions d'appel imposent-elles des contraintes sur le comportement de ces registres?

Je suppose que nous pourrions ajouter un petit morceau d'assemblage pour effacer les registres avant d'appeler OpenBLAS sous Windows. J'ai essayé de faire cela dans une petite configuration de test, mais mon assemblage masm foo est faible. J'ai essayé d'écrire une procédure qui appelle simplement fldz plusieurs fois, lorsque je l'utilise, j'obtiens une exception. Aidez-moi?

En lots_of_fldz.asm :

.code
lots_of_fldz proc
    fldz
    fldz
    fldz
    fldz
    fldz
    fldz

lots_of_fldz endp
end

Dans un autre fichier:

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

Placez-les dans un projet VisualStudio et suivez ce guide pour activer la compilation masm

@mattip , j'ai créé un fichier assembleur pour la fonction fmod 64 bits qui crée un segment text: identique fmod correspondante de mingw-w64 (64 bits). Aucune idée si cela fonctionne en remplacement de la fonction buggy fmod, mais au moins un devrait l'essayer. Le fichier obj résultant pourrait être ajouté à 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

commande masm: ml64.exe /c fmod.asm crée fmod.obj (utilisez la variante 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 merci. Je serais plus heureux avec un morceau d'assembleur qui réinitialise les registres ST (N) que nous pourrions utiliser sur x86_64 avant d'appeler les fonctions OpenBLAS. Aujourd'hui, ce problème est survenu à cause d'un changement de fmod , demain, ce sera peut-être une fonction différente. Je ne suis pas sûr que des fonctions soient nécessaires pour réinitialiser les registres ST(N) au retour. S'il n'y a pas une telle exigence, fmod n'est pas réellement bogué et la modification de Windows a révélé un échec d'OpenBLAS pour réinitialiser les registres avant de les utiliser, que nous devrions les aider à corriger ou à contourner le problème.

J'ai essayé de réinitialiser les registres en utilisant fldz dans le commentaire ci-dessus mais mon programme de test ne fonctionne pas.

@mattip , ma connaissance de l'assembleur est aussi plus ou moins basique. Cependant, vous pouvez trouver une réponse possible dans ce fil de discussion 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.

Je suppose que nous pourrions également appeler fninit au début de OpenBLAS nrm2.S (après la macro PROFCODE) pour vérifier cette théorie

Un peu intéressant de la
Interface binaire d'application System VSupplément de processeur d'architecture AMD64Version préliminaire 0.99.6

_Les bits de contrôle du registre MXCSR sont sauvegardés par l'appelé (conservés entre les appels), tandis que les bits d'état sont sauvegardés par l'appelant (non conservés) ._

_Le registre de mot d'état x87 est enregistré par l'appelant, tandis que le mot de contrôle x87 est enregistré par l'appelé.

_Tous les registres x87 sont enregistrés par l'appelant, donc les appelants qui utilisent les registres MMX peuvent utiliser l'instruction femms plus rapide.

Très différent de la convention d'appel Windows 64 bits.

@ martin-frbg, fninit est dangereux: The FPU control word is set to 037FH (round to nearest, all exceptions masked, 64-bit precision). précision étendue X87 n'est pas souhaitée dans tous les cas, en particulier sous Windows.

Je ne voudrais pas cela pour une version commerciale, juste pour un test rapide. Toujours pas tout à fait convaincu qu'OpenBLAS devrait en quelque sorte nettoyer "avant" lui-même, mais je ne trouve pas de documentation claire sur le comportement de Windows avec le fpu x87 hérité. J'ai remarqué qu'Agner Fog a un document sur les conventions d'appel à http://www.agner.org/optimize/calling_conventions.pdf (la discussion sur la gestion Win64 des registres FP commence à la page 13 mais se concentre sur la disponibilité de base et le comportement entre les commutateurs de contexte).

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

Je suppose que cela signifie: n'utilisez pas les instructions x87 (Win64). Si vous le faites, bonne chance. Ou en d'autres termes: l'appelé est responsable de ne pas porter préjudice.

Hm qui semble décrire le comportement du compilateur MSVC spécifiquement, alors que je pense que nous sommes dans un écosystème mingw?

Non, Numpy (Pypi) est compilé avec MSVC (Visual Studio 2019) sous Windows. Pour OpenBLAS, mingw-w64 est utilisé (en raison des pièces Fortran). Les parties de Scipy Fortran sont également compilées avec mingw-w64. Cependant, CPython et ses extensions binaires sont fortement basés sur les normes définies par MSVC.

BTW: c'était la raison du développement de https://github.com/mingwpy qui est actuellement en train de reprendre vie. (prise sans vergogne)

Un autre peu:

mingw-w64 utilise (presque) les mêmes conventions d'appel que MSVC. Les seules différences notables sont l'alignement différent de la pile sur x86 (32 bits) - pertinent pour SIMD et le vectorcall .

Intéressant. x86 n'est pas affecté. Uniquement AMD64.

Le dimanche 4 octobre 2020, 22:19 carlkl [email protected] a écrit:

Un autre peu:

mingw-w64 utilise (presque) les mêmes conventions d'appel que MSVC. Le seul
les différences notables sont l'alignement de pile différent sur x86 (32 bits) -
pertinent pour SIMD et l'appel vectoriel non pris en charge.

-
Vous recevez cela parce que vous avez été mentionné.
Répondez directement à cet e-mail, affichez-le sur GitHub
https://github.com/numpy/numpy/issues/16744#issuecomment-703317784 , ou
Se désabonner
https://github.com/notifications/unsubscribe-auth/ABKTSRMFHWZVLDYDFGBM6YDSJDRGTANCNFSM4OP5IXNQ
.

MSVC 32bit n'a peut-être pas renié le fpu? Je vais juste faire un remplacement provisoire du nrm2.S utilisant fpu par soit nrm2_see2.S (si c'est viable, malheureusement, il existe un certain nombre de routines d'assemblage inutilisées mais mortelles flottant dans la base de code) ou la version C pour OS == Windows alors. (L'autre problème discuté ici doit être autre chose cependant, car je pense que toutes les autres anciennes routines d'assemblage pour x86_64 sont au moins SSE2)

@mattip , peut-être qu'un appel à _fpreset après divmod est suffisant pour réinitialiser à partir d'un état FPU foiré?

peut-être un appel à _fpreset

Non, il ne réinitialise pas les registres ST(N) , ni ne corrige les tests qui ont échoué.

Avez-vous essayé _fninit ? Cela devrait réinitialiser la pile FPU. Ou ffree ou fstp au lieu de fldz comme mentionné dans https://stackoverflow.com/questions/19892215/free-the-x87-fpu-stack-ia32/33575875 ?

J'essaierais volontiers les commandes de l'assembleur, mais le projet de test dans le commentaire ci-dessus plante. Quelqu'un doit corriger mon code pour le faire fonctionner (en effet, fninit semble être un bon candidat) alors je peux émettre des instructions d'assembleur pour réinitialiser les registres dans NumPy avant d'appeler OpenBLAS.

Quelque chose comme ça?

.code
reset_fpu proc
    finit
    fldz
reset_fpu endp
end

finit ist wait plus fninit . Je ne suis pas sûr que fldz soit nécessaire après fninit .

Comme je l'ai dit dans le commentaire, il manque quelque chose pour que l'appel au code d'assemblage compilé fonctionne correctement. C'est à peu près ce que j'avais dans ce commentaire. Le code plante avec exited with code -2147483645 . Veuillez jeter un œil au code complet et voir si vous pouvez le faire fonctionner.

Je peux l'essayer (demain). Cependant, ces extraits peuvent être utiles:

https://www.website.masmforum.com/tutorials/fptute/fpuchap4.htm
(l'un des sites les plus lisibles sur ce sujet que j'ai trouvé)

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. 

Si je comprends bien, fldz peut segfault si st (7) est utilisé, par conséquent:

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. 

vous pouvez essayer:

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

Désolé, je ne suis pas clair. Le problème immédiat n'est pas de savoir quel assembleur appelle. Le problème immédiat est de savoir comment créer correctement une procédure appelable de manière à pouvoir l'utiliser, et démontrer que dans un fichier à deux ( *.asm et main.c / main.cpp ) projet qui compile et s'exécute. Une fois que nous avons cela, je peux continuer à explorer différents appels et comment ils influencent OpenBLAS.

@mattip , je comprends. Je vais certainement l'essayer, mais cela peut prendre son temps.

J'ai eu l'impression que le mauvais comportement _tempory_ de fmod dans UCRT devrait être _healed_ par OpenBLAS: https://github.com/xianyi/OpenBLAS/pull/2882 et non par numpy car numpy n'utilise pas le FPU sur WIN64. Et bien sûr, MS devrait résoudre ce problème avec un correctif Windows.
Le correctif numpy dans ce cas serait de garantir l'utilisation d'une version d'OpenBLAS lors de la construction pas plus ancienne que la prochaine version d'OpenBLAS.

@matti Il y a un contrôle de bon sens dans numpy/__init__.py . Y a-t-il un test simple et fiable que nous pourrions ajouter pour détecter ce problème?

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

@mattip , merci pour l'extrait. Mais il me faudra du temps pour avoir accès à un bureau sur lequel je pourrai faire ce genre de tests. En ce moment, je travaille la plupart du temps avec un ordinateur portable avec un environnement de programmation minimal où je ne peux presque rien installer.

Nous avons fusionné une mise à jour vers OpenBLAS v0.3.12 et une version locale utilisant cette version + la mise à jour de Windows 2004 passe la suite de tests.

Laisser cela ouvert jusqu'aux mises à jour de Windows.

Les roues de pré-lancement ont-elles été construites avec le nouvel OpenBLAS? Heureux de faire d'autres tests avec des projets en aval qui rencontraient ce bogue.

Les roues de pré-version de Windows 3.9 sont actuellement manquantes en raison d'erreurs de test (maintenant corrigées). La bibliothèque fixe sera utilisée dans la version 1.19.3 qui sortira aujourd'hui ou demain.

L'option /MT active la liaison statique sous Windows. Il peut être possible d'établir un lien statique avec libucrt.lib à l'aide de la version 1909 du Microsoft SDK. Cela pourrait agir comme une solution de contournement pour le bogue ucrtbase.dll en 2004 et 20H2. Cela rendrait les roues plus grosses, ce qui est un inconvénient.

Je n'ai aucune idée si ce problème / MT est toujours valide, mais il devrait être pris en compte.

Je pense que si NumPy est le seul module qui se construit avec MT, cela pourrait être
D'ACCORD. Bien sûr, il se peut que si NumPy est MT, alors tout
en aval devrait également être MT, ce qui poserait donc un problème.

Le lun.2 novembre 2020, 19:37 carlkl [email protected] a écrit:

Je n'ai aucune idée si ce problème / MT
https://stevedower.id.au/blog/building-for-python-3-5-part-two est toujours
valide, mais il devrait être considéré.

-
Vous recevez cela parce que vous avez été mentionné.
Répondez directement à cet e-mail, affichez-le sur GitHub
https://github.com/numpy/numpy/issues/16744#issuecomment-720682011 , ou
Se désabonner
https://github.com/notifications/unsubscribe-auth/ABKTSRJIVAQLECK4E2EVSSDSN4C65ANCNFSM4OP5IXNQ
.

Des solutions de contournement recommandées pour ce problème? Ma situation est que je suis sur une machine mise à jour à la mise à jour 2004 et que j'ai un logiciel de bureau qui utilise pip pour installer numpy / scipy / pandas, etc. Tous ces logiciels sont affectés par ce problème causé par la mise à jour de Microsoft.

Toutes les recommandations seraient appréciées, car l'utilisation de conda pour installer numpy n'est pas une option pour le logiciel sur lequel je travaille.

Si vous n'avez pas besoin de docker, vous pouvez épingler 1.19.3. Il passe tous les tests sur mes systèmes Windows.

Merci. 1.19.3 fonctionne avec pip sur le problème.

Le lien dans la mauvaise détection BLAS génère beaucoup de messages bruyants sur le site de MS. J'espère que cela ne finira pas par exploser.

Je suppose qu'une autre alternative est d'utiliser un fmod tiers sur Win64.

Je me demande quelle serait la réponse si NumPy avait un bug non corrigé aussi grave pendant quatre mois après une sortie, surtout si nous ne fournissions pas d'instructions claires aux utilisateurs pour revenir à la version précédente. Les utilisateurs peuvent facilement épingler la 1.19.3, mais cela ne résoudra pas le problème, cela ne le déplacera que vers un autre paquet qui utilise les registres après qu'ils ont été foirés: peut-être scipy, peut-être tensorflow.

Une autre idée pour une solution de contournement: voyez s'il y a une autre fonction dans ucrt qui utilise le FPU et laisse son état en bon état. S'il y en a un, nous pourrions l'appeler après fmod. Cela aurait l'avantage sur la solution de contournement de l' assemblage écrite par

Je ne pense pas que nous devrions investir plus d'efforts pour contourner ce problème. Tout travail supplémentaire que nous effectuons pour atténuer le problème prendra un temps précieux aux développeurs et réduira la pression exercée sur Microsoft pour résoudre ce problème. De plus, comme mentionné ci-dessus, tout code dans d'autres projets qui appelle fmod et / ou utilise les registres peut rencontrer ce problème sans connexion à NumPy.

Je ne pense pas que nous devrions investir plus d'efforts pour contourner ce problème. Tout travail supplémentaire que nous effectuons pour atténuer le problème prendra un temps précieux aux développeurs et réduira la pression exercée sur Microsoft pour résoudre ce problème. De plus, comme mentionné ci-dessus, tout code dans d'autres projets qui appelle fmod et / ou utilise les registres peut rencontrer ce problème sans connexion à NumPy.

Après avoir vu la réaction au message d'erreur, ce n'est clairement pas très utile. Il devrait, par exemple, suggérer aux utilisateurs de Windows qui souhaitent utiliser les dernières fonctionnalités de NumPy d'utiliser une distribution livrée avec MKL plutôt que la molette pip. Il devrait également inclure un lien vers ce fil.

Bien que ce soit clairement la responsabilité de MS de résoudre ce problème, amener les utilisateurs à signaler la faute de quelqu'un d'autre est rarement un bon moyen pour un projet de maintenir sa bonne volonté.

@bashtage Je ne sais pas trop ce que vous entendez par causer de la douleur. Nous pourrions supprimer le lien et demander aux utilisateurs d'atterrir ici à la place, mais nous devons avertir les utilisateurs que lorsqu'ils s'exécutent en 2004, les résultats ne peuvent pas être fiables, et si vous ne pouvez pas faire confiance aux résultats d'un calcul, vous devez éviter le calcul sur cette plate-forme.

Je ne sais pas trop ce que vous entendez par causer de la douleur.

L'importation de NumPy échoue de façon spectaculaire et aucune solution de contournement n'est fournie. Il serait très utile pour la plupart des utilisateurs que la liste des solutions de contournement connues soit clairement visible:

(a) Utilisation d'une distribution basée sur MKL telle que conda ou Enthought Deployment Manager qui évite cela mais dans un code d'algèbre linéaire
(b) Revenez à NumPy 1.19.3 qui est livré avec une version d'OpenBLAS protégée contre le bogue. Cette option peut ne pas convenir aux utilisateurs qui s'exécutent dans des conteneurs.
(c) Construire à partir de la source. Cette option aura un BLAS peu performant, mais peut convenir dans les environnements où la distribution tierce n'est pas autorisée et où des conteneurs sont utilisés ou une fonctionnalité récente ou une correction de bogue dans NumPy est requise.

Je ne pense pas qu'il soit erroné d'attirer l'attention sur le bogue fmod, mais cela envoie les utilisateurs sur ce forum comme s'il y avait une solution qui les attendait.

Nous pourrions supprimer le lien et demander aux utilisateurs d'atterrir ici à la place, mais nous devons avertir les utilisateurs que lorsqu'ils s'exécutent en 2004, les résultats ne peuvent pas être fiables, et si vous ne pouvez pas faire confiance aux résultats d'un calcul, vous devez éviter le calcul sur cette plate-forme.

Ce n'est pas une option. Les utilisateurs doivent uniquement éviter NumPy + OpenBLAS (ex 0.3.12). Ils n'ont pas besoin d'éviter NumPy + Windows (2004 / 20H2 (il y a maintenant 2 versions publiées affectées)).

Distribution basée sur MKL

Des problèmes avec MKL ont également été signalés.

Revenir à NumPy 1.19.3

Mais cela ne résoudra pas d'autres problèmes potentiels résultant de l'utilisation de fmod. Le problème est qu'il n'y a aucun moyen d'être sûr que les résultats sont corrects.

Les gens ne devraient pas utiliser Python en 2004, peut-être utiliser WSL à la place? Je serais également d'accord pour inclure un ancien ucrt avec les roues Windows si cela était possible, mais qu'en est-il des autres projets? Existe-t-il un moyen simple de revenir aux versions antérieures de Windows?

Des problèmes avec MKL ont également été signalés.

NumPy n'a pas de test qui échoue sur MKL. Il semble difficile de présumer qu'il y a un problème alors qu'aucune panne n'est signalée. Le bogue fmod ne se manifeste pas dans le BLAS de MKL (probablement parce qu'il n'utilise pas FPU).

Mais cela ne résoudra pas d'autres problèmes potentiels résultant de l'utilisation de fmod. Le problème est qu'il n'y a aucun moyen d'être sûr que les résultats sont corrects.

Non, mais cela ne résoudra pas non plus les problèmes de sécurité de Windows, ni de nombreux autres bogues. Le problème ici est très particulier.

  1. fmod est bien en ce sens qu'il produit des résultats corrects
  2. Vous devez avoir du code écrit dans l'assembleur pour rencontrer ce problème car le compilateur système ne produira pas de code x87.

Ces deux éléments me suggèrent que le problème est très difficile à atteindre pour presque tout le code. Seuls les codes les plus performants comme OpenBLAS, les bibliothèques FFT contenant des noyaux écrits à la main ou MKL sont susceptibles de déclencher # 2.

Je pense également qu'il est raisonnable de publier le correctif car si OpenBLAS 0.3.12 fonctionnait comme prévu, NumPy aurait été publié et ce problème n'aurait jamais été signalé aux utilisateurs.

Les gens ne devraient pas utiliser Python en 2004, peut-être utiliser WSL à la place? Je serais également d'accord pour inclure un ancien ucrt avec les roues Windows si cela était possible, mais qu'en est-il des autres projets? Existe-t-il un moyen simple de revenir aux versions antérieures de Windows?

Je soupçonne que pour de nombreux utilisateurs, ce n'est pas vraiment une option pour de nombreux utilisateurs: les utilisateurs d'entreprise sur un bureau d'entreprise, les étudiants novices (qui devraient utiliser conda) ou toute personne ayant acheté un ordinateur portable avec 2004 ou 20H2 qui ne peut pas rétrograder.

Notez que non seulement Condas est lié numpy avec MLK, mais il fournit également sa propre version de ucrtbase.dll qui apparaît comme une version plus ancienne (10.0.17134.12)

Largement d'accord avec @bashtage ici, une importation échouant sans recommandation raisonnable de le réparer est un peu hostile aux utilisateurs (malgré le principal défaut de Microsoft).

@jenshnielsen : Notez que non seulement Condas est lié numpy avec MLK [...]

Les builds empaquetés par conda-forge permettent de désactiver l'implémentation blas / lapack (hors openblas / mkl / blis / netlib), elle ne _have_ pas être MKL.

Les gens ne devraient pas utiliser Python en 2004, peut-être utiliser WSL à la place?

Ce n'est pas le mode de fonctionnement par défaut pour la plupart des utilisateurs.

Je serais également d'accord pour inclure un ancien ucrt avec les roues Windows si cela était possible, mais qu'en est-il des autres projets?

Les autres projets ne sont pas de notre responsabilité.

Existe-t-il un moyen simple de revenir aux versions antérieures de Windows?

Si vous avez effectué une nouvelle installation ou nettoyé votre espace disque, il devient presque impossible de le faire.

Largement d'accord avec @bashtage ici, une importation échouant sans recommandation raisonnable de le réparer est un peu hostile aux utilisateurs (malgré le principal défaut de Microsoft).

Je suis d'accord. Nous pourrions finir par perdre beaucoup d'utilisateurs si nous ne résolvons pas ce problème.

Je serais également d'accord pour inclure un ancien ucrt avec les roues Windows si cela était possible, mais qu'en est-il des autres projets?

@charris , cela n'aidera pas sous Windows 10. Si vous déployez un ucrt différent avec python ou numpy, il ne sera

@carlkl
Le python emballé par conda s'interpose en fait dans la résolution du chemin de recherche DLL (ce qui - inchangé - serait probablement la raison pour laquelle vous dites qu'il ne peut jamais fonctionner sous Windows 10), et c'est AFAICT également la raison pour laquelle conda _does_ fournit un ucrtbase.dll , comme l'écrit @jenshnielsen .

@ h-vetinari, le déploiement Universal CRT indique clairement:

_Il y a deux restrictions sur le déploiement local à connaître:
Sous Windows 10, Universal CRT dans le répertoire système est toujours utilisé, même si une application inclut une copie locale de l'application de Universal CRT. C'est vrai même lorsque la copie locale est plus récente, car Universal CRT est un composant de base du système d'exploitation sous Windows 10._

BTW: je l'ai testé moi-même. Aucun moyen de charger un autre UCRT que l'UCRT disponible déployé avec Windows 10.

Je pense également qu'il est raisonnable de publier le correctif

par cela, je pense que vous voulez dire ajouter PR gh-17547?

Preuve du point de

image

Ce bug, causé par MS lui-même, devrait être appelé Heisenbug . Il était coûteux et difficile de trouver la cause: le fmod UCRT Windows 2004 laisse les registres FPU dans un état bâclé dans certaines circonstances. Cela peut entraîner des erreurs de calcul numériques beaucoup plus tard lors de la réutilisation de la FPU. Les erreurs de calcul n'apparaissent généralement pas dans les codes utilisateur si elles ne sont pas rigoureusement testées. Cela peut signifier que des erreurs numériques importantes ne sont pas détectées pendant longtemps. Cela pourrait difficilement être pire.

par cela, je pense que vous voulez dire ajouter PR gh-17547 ?

Désolé, j'ai écrit la mauvaise chose.

Le seul changement que je suggère est que NumPy fournit plus d'informations dans l'exception soulevée lors de l'importation qui suggère des moyens pour qu'un utilisateur puisse obtenir un environnement sur Windows 2004 / H2 qui lui permettrait de continuer son travail / école / passe-temps.

  1. WSL
  2. conda / enthought
  3. 1.19.3
  4. Construire à partir de la source

[Cette commande est ma préférence quant à la qualité de la solution]

Je pense qu'il serait également judicieux d'établir un lien avec ce problème ou avec un problème un peu plus clair qui fournit une explication plus approfondie. Ce deuxième lien pourrait également être vers certaines notes de publication dans la documentation, plutôt que vers un problème github.

Les builds empaquetés par conda-forge permettent de désactiver l'implémentation blas / lapack (hors openblas / mkl / blis / netlib), elle ne _have_ pas être MKL.

@ h-vetinari Est-ce que conda-forge + OpenBLAS construit avec succès les tests sur 2004 / H2?

Je viens de vérifier et coda-forge expédie OpenBlas 0.3.12. Est-ce que cela plante alors les conteneurs?

Utiliser la méthode de guérison de l'état du FPU avec l'instruction EMMS dans OpenBLAS-0.3.12 devrait bien sûr aider à nettoyer les tests numpy et scipy, mais comme @charris l'a déclaré, appeler fmod(0,x) in Les instructions CPython puis FPU appelées plus tard (dans un package différent d'OpenBLAS) pourraient également se produire. Dans ce cas, le problème n'est que déplacé ailleurs.

Le meilleur pari est en effet de forcer MS à corriger ce comportement de buggy. Peut-être que Steve Dower peut vous aider?

Cela pourrait également être une histoire intéressante pour Agner Fog ou peut-être Bruce Dawson: voir par exemple cette histoire liée dans son blog:
Tout ce qui est vieux est nouveau et un bogue du compilateur

Probablement le bogue d'OpenBlas 0.3.12. Notez la colonne Octets privés:

image

Cela vaut probablement par défaut 24 threads BLAS puisque j'ai 24 processeurs logiques.

Il s'agit d'OpenBLAS 0.3.12 avec NumPy 1.19.2 de conda-forge.

Le réglage de $env:OPENBLAS_NUM_THREADS=1 permet une réduction spectaculaire

image

Et avec les fils $env:OPENBLAS_NUM_THREADS=4 :

image

@bashtage : pourriez-vous continuer à discuter d'OpenBLAS 0.3.12 dans OpenBLAS xianyi / OpenBLAS # 2970?

@mattip J'essayais de déterminer si conda + OpenBLAS était une alternative crédible. Je ne pense pas que cela résout quoi que ce soit que 1.19.3 résout après avoir vu ces résultats.

@bashtage : Preuve du point de

Étant donné que le python empaqueté par conda contourne activement la résolution DLL standard de Windows, je ne sais pas à quel point un outil Windows sera une preuve. J'ai rencontré ce problème par exemple avec libcrypto.dll obsolète dans C:\Windows\System32 , voir par exemple https://github.com/conda-forge/staged-recipes/pull/11452. En bref, la bibliothèque système obsolète n'a été détectée que par un échec de test dans la suite de tests cryptography , puis - en utilisant CONDA_DLL_SEARCH_MODIFICATION_ENABLE - l'utilisation de l'openssl fourni par conda pouvait être forcée.

@bashtage : @ h-vetinari Les builds conda-forge + OpenBLAS réussissent-ils les tests sur 2004 / H2?

Le CI qui construit les packages n'est probablement pas sur une telle version actuelle, et il m'a fallu un peu de temps pour le construire moi-même. Je tourne actuellement sur une machine 2004, et voici le résultat - très positif **:

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

@bashtage : Je viens de vérifier et conda-forge expédie OpenBlas 0.3.12. Est-ce que cela plante alors les conteneurs?

conda-forge n'est livré avec aucune version fixe d'Openblas - la version blas peut même être "échangée à chaud" (par exemple entre openblas, mkl, blis), donc la version n'est pas un gros problème. Cependant, en général, il utilisera la dernière version packagée. Je ne peux pas vérifier si le crash se reproduit ou non dans des conteneurs.

@bashtage :: @mattip J'essayais de déterminer si conda + OpenBLAS était une alternative crédible. Je ne pense pas que cela résout quoi que ce soit que 1.19.3 résout après avoir vu ces résultats.

L'augmentation de la mémoire était due à un changement dans openblas 0.3.12, comme discuté plus loin dans xianyi / OpenBLAS # 2970. Jusqu'à présent, conda-forge me semble une alternative crédible - au moins, il n'est pas directement affecté par l'erreur.

** J'ai utilisé le master actuel de https://github.com/conda-forge/numpy-feedstock , qui est toujours sur 1.19.2, couplé avec openblas 0.3.12. Je pourrais aussi essayer https://github.com/conda-forge/numpy-feedstock/pull/210 + openblas 0.3.12, si les gens sont intéressés.

Bonne nouvelle, MS est revenu sur le forum VS et a suggéré qu'un correctif pourrait être disponible d'ici la fin de janvier 2021. Compte tenu de cette mise à jour, je pense que la seule question est de savoir s'il y a une valeur à mettre à jour le message d'erreur qui est généré lorsque le la fonction buggy est détectée.

Étant donné que le python empaqueté par conda contourne activement la résolution DLL standard de Windows, je ne sais pas à quel point un outil Windows sera une preuve. J'ai rencontré ce problème par exemple avec libcrypto.dll obsolète dans C:\Windows\System32 , voir par exemple conda-forge / staged-recettes # 11452 . En bref, la bibliothèque système obsolète n'a été détectée que par un échec de test dans la suite de tests cryptography , puis - en utilisant CONDA_DLL_SEARCH_MODIFICATION_ENABLE - l'utilisation de l'openssl fourni par conda pouvait être forcée.

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

les sorties

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

Cela montre que lorsque l'ancien OpenBLAS est utilisé, la fonction de buggy de la DLL ucrt actuelle est utilisée.

Seul openblas = 0.3.12 de conda forge passera les tests, mais c'est le même que celui livré dans NumPy 1.19.3.

Qu'est-ce qui parle contre une nouvelle version numpy compilée avec un OpenBLAS-0.3.12 désarmé? Réduction de la taille de la mémoire tampon et peut-être du nombre de threads au moment de la compilation d'OpenBLAS utilisé pour numpy. Cela devrait réduire la consommation de mémoire d'OpenBLAS et devrait aider non seulement dans le cas de test Docker, mais également aux utilisateurs moins bien équipés
boîtes de fenêtres.

Voici le rapport de bogue https://tinyurl.com/y3dm3h86 depuis Python. Tout d'abord, merci d'avoir fourni une version qui fonctionne sous Windows pour l'instant (1.19.3).

Je comprends que la version 1.19.3 ne fonctionne pas sous Linux et la 1.19.4 ne fonctionne pas sous Windows (tant qu'elle a le bogue).

Serait-il possible de créer la dernière version sur pypi 1.19.3 pour Windows et 1.19.4 pour toutes les autres plates-formes? En d'autres termes, supprimez simplement https://files.pythonhosted.org/packages/33/26/c448c5203823d744b7e71b81c2b6dcbcd4bff972897ce989b437ee836b2b/numpy-1.19.4-cp36-cp36m-win_amd64.whl (entièrement les versions 3.764 / 3.764 correspondantes) pour l'instant?

@luciansmith Tant que la source est disponible pour la version 1.19.4, pip essaiera d'utiliser cette version à moins que des indicateurs supplémentaires ne soient passés. Je pense que la plupart des utilisateurs ne passeraient des indicateurs supplémentaires que s'ils connaissaient le problème, mais ils pourraient simplement épingler 1.19.3.

Ma préférence serait d'avoir un 1.19.5 qui utilise OpenBLAS 0.3.9 sous Linux et 0.3.12 sous Windows, mais je ne sais pas si cela est possible.

Cette page vous a été utile?
0 / 5 - 0 notes