Numpy: Polyfit- und EIG-Regressionstests schlagen nach dem Windows 10-Update auf 2004 fehl

Erstellt am 3. Juli 2020  ·  171Kommentare  ·  Quelle: numpy/numpy

Tests schlagen fehl:
FAILED .... \ lib \ tests \ test_regression.py :: TestRegression :: test_polyfit_build - numpy.linalg.LinAlgError: SVD hat nicht ...
FAILED .... \ linalg \ tests \ test_regression.py :: TestRegression :: test_eig_build - numpy.linalg.LinAlgError: Eigenwerte ...
FEHLGESCHLAGEN .... \ ma \ tests \ test_extras.py :: TestPolynomial :: test_polyfit - numpy.linalg.LinAlgError: SVD konvergierte nicht i ...

mit Ausnahmen:

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

und

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

Schritte gemacht:

  • Erstellen Sie eine VM
  • Installieren Sie das neueste Windows 10 und aktualisieren Sie es auf die neueste Version 2004 (10.0.19041).
  • Installieren Sie Python 3.8.3
  • pip install pytest
  • pip install numpy
  • pip install hypothesis
  • Führen Sie Tests im Paket aus

Das gleiche Problem tritt auf, wenn Tests im Repository ausgeführt werden.

Version 1.19.0 von numpy

Vermisse ich irgendwelche Abhängigkeiten? Oder ist es nur Windows, das verrückt wird?

00 - Bug 32 - Installation

Hilfreichster Kommentar

Wir haben ein Update auf OpenBLAS v0.3.12 zusammengeführt und ein lokaler Build mit dieser Version + Windows Update 2004 besteht die Testsuite.

Alle 171 Kommentare

Bearbeiten: Sie verwenden offensichtlich pip. Ich habe in der jüngeren Vergangenheit auch unter Windows AMD64 ein seltsames Ergebnis mit linearen Algebra-Bibliotheken und Eigenwertzerlegungen erzielt (im Zusammenhang mit dem Ausführen eines Tests für Statistikmodelle).

Wenn Sie Zeit haben, versuchen Sie es mit 32-Bit-Python und -Pip und prüfen Sie, ob Sie dieselben Probleme haben. Ich konnte sie in 32-Bit-Fenstern nicht sehen, aber sie waren in 64-Bit-Fenstern wiederholbar.

Wenn ich conda verwende, das MKL versendet, habe ich keine Fehler.

Bearbeiten: Ich sehe sie auch bei Verwendung von NumPy 1.18.5 unter Windows AMD64.

Tests schlagen nach dem letzten Windows 10-Update fehl

Haben die Tests vor dem Update fehlgeschlagen?

Nein @charris , vor dem Update besteht die Testsuite nur.

@speixoto Weißt du, welches Update es speziell war? Es würde mich interessieren, ob es mein Problem mit mit Rädern installierten Rädern löst.

Das Update 1809 (10.0.17763) verursachte keinen fehlgeschlagenen Test @bashtage

1909 verursachte auch nichts. Es begann erst mit 2004.

Ich bin nicht zu 100% davon überzeugt, dass es 2004 oder so ist. Ich denke, 2004 hat funktioniert.

FWIW Ich kann diese Abstürze auf CI (Azure oder Appveyor) nicht reproduzieren, aber ich mache es lokal auf 2 Computern, die sowohl AMD64 als auch 2004 aktualisiert sind.

Hat einer von Ihnen versucht zu sehen, ob Sie sie auf 32-Bit-Python bekommen?

Anscheinend wurden im Zusammenhang mit dem Update 2004 eine Reihe von Problemen gemeldet. Vielleicht sollte dies auch gemeldet werden?

Bei der Neuinstallation von 1909 und 2004 habe ich gerade Folgendes ausgeführt:

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

Im Jahr 1909 keine Ausfälle. Im Jahr 2004 betrafen 30 Fehler alle lineare Algebra-Funktionen.

Wenn ich 2004 Tests in einem Debugger durchführe, stelle ich fest, dass der erste Aufruf einer Funktion häufig zu einem falschen Ergebnis führt, ein erneuter Aufruf jedoch das richtige Ergebnis liefert (das bei wiederholtem Aufruf korrekt bleibt). Ich bin mir nicht sicher, ob dies nützliche Informationen sind, um eine Ursache zu erraten.

Haben frühere Versionen von NumPy auch Probleme? Ich gehe davon aus, dass Sie 1.19.0 ausführen.

Mit pip + 1.18.4 und scipy 1.4.1 erhalte ich die gleichen Fehler.

Diese sind wirklich häufig:

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

Wenn ich mit 1.18.5 + MKL laufe, erhalte ich keine Fehler. Es ist schwer zu sagen, ob dies wahrscheinlich ein OpenBLAS-Fehler oder ein Windows-Fehler ist. Wahrscheinlich letzteres, aber es wird sehr schwer zu erreichen sein und die Diagnose liegt außerhalb meiner Möglichkeiten für das Debuggen auf niedriger Ebene.

Wenn ich auf Ubuntu mit Pip-Paketen laufe, werden auf demselben physischen Computer keine Fehler angezeigt.

Dies ist das seltsamste Verhalten. Schlägt beim ersten Anruf fehl, funktioniert beim zweiten und nachfolgenden. Ein anderes schwer verständliches Verhalten ist, dass ich den Fehler nicht sehe, wenn ich den fehlgeschlagenen Test isoliert ausführe.

svd

Ein letztes Update: Wenn ich mit einem Quell-Build von NumPy ohne optimiertes BLAS teste, werden immer noch Fehler angezeigt, obwohl diese nicht identisch sind.

Vielleicht lohnt es sich, die OpenBLAS-Entwickler anzupingen. Kommt es bei float32 so oft vor wie bei float64?

Wenn ich einen vollständigen Test von NumPy 1.19.0, python -c "import numpy;numpy.test('full')" die gleichen Fehler wie oben angezeigt:

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

Ich denke, wenn Sie den Test nur exklusiv ausführen, sollte er bestehen, wenn ich mich richtig daran erinnere, Dinge herumgepingt zu haben, was noch seltsameres Verhalten bedeutet.

Ich habe bei Microsoft die einzige Möglichkeit eingereicht, wie ich weiß:

https://aka.ms/AA8xe7q

Posting für den Fall, dass andere dies durch Suche finden:

Windows-Benutzer sollten Conda / MKL im Jahr 2004 verwenden, bis dies behoben ist

Hier ist ein kleines Reproduktionsbeispiel:

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)

Produziert

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

Zählt LAPACK von 0 oder 1? Alle unzulässigen Werte scheinen ganze Zahlen zu sein:
DGEBAL
DGEHRD
DORGHR
DHSEQR

Es scheint eher ein OpenBlas-Problem zu sein (oder etwas zwischen 2004 und OpenBLAS). Hier ist meine Zusammenfassung:

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

  • Keine optimierten BLAS: Pass voll
  • OpenBLAS: Ausfallen voll
  • MKL: Pass voll

Statistikmodelle testen pytest statsmodels

  • Pip NumPy und SciPy: Fehler im Zusammenhang mit SVD- und QR-Code
  • MKL NumPy und SciPy: Pass
  • Kein optimiertes BLAS: Fehlgeschlagen , aber weniger, die alle scipy.linalg -Routinen beinhalten, die OpenBLAS verwenden.
  • Kein optimiertes BLAS, kein SciPY-Linalg: Pass

Es wäre schön zu erfahren, was sich 2004 geändert hat. Vielleicht brauchen wir beim Kompilieren / Verknüpfen der Bibliothek ein anderes Flag?

_Wenn es sich um einen OpenBLAS-Fehler handelt, ist es unwahrscheinlich, dass sie ihn gesehen haben, da keines der Windows-basierten CI Build 19041 (auch bekannt als Windows 10 2004) oder höher verwendet.

Um ganz klar zu sein, stimmt es, dass keiner dieser Berichte die WSL betrifft?

Nein. Alle haben entweder python.exe oder python.org python.exe bereitgestellt

Schlägt der Test fehl, wenn die Umgebungsvariable OPENBLAS_CORETYPE=Haswell oder OPENBLAS_CORETYPE=NEHALEM explizit festgelegt ist?

Ich habe Atom, SandyBridge, Haswell, Prescott und Nehalem ausprobiert, alle mit identischen Ergebnissen.

Das Seltsamste ist, wenn du rennst

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)

Der zweite (und weitere) Aufruf von eig erfolgreich.

SciPy hat einen ähnlichen Fehler in

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) 

was erhöht

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

Die letzte Anmerkung: Die Konvertierung in np.complex128 ebenfalls erhöht, während die Konvertierung in np.float32 oder np.complex64 ohne Probleme funktioniert.

Python-Teile des Codes, die mit langen Ganzzahlen kompiliert wurden, aber OpenBLAS ohne INTERFACE64 = 1 in den fortran (LAPACK) -Teilen erstellt wurden?
(Dies würde immer noch nicht erklären, warum der erste Aufruf fehlschlägt, ein nachfolgender jedoch erfolgreich ist oder warum er vor dem Update 19041 funktioniert hat.)

Windows 10-Benutzer können dieses Problem im Feedback Hub von Microsoft bewerten.

https://aka.ms/AA8xe7q

Auf Wunsch von @bashtage habe ich mich ein wenig mit dem Code befasst, und ich vermute, dass einige Aspekte des Gleitkommazustands bei der Eingabe jetzt anders sind. Das scheint sich dadurch zu bestätigen:

Die Konvertierung in np.complex128 wird ebenfalls ausgelöst, während die Konvertierung in np.float32 oder np.complex64 problemlos funktioniert.

Die erste Warnmeldung (die bei Erfolg nicht angezeigt zu werden scheint) "Bei Eingabe von DGEBAL hatte Parameter Nummer 3 einen unzulässigen Wert" wird durch diese Bedingung verursacht: https://github.com/xianyi/OpenBLAS/blob/ce3651516f12079f3ca2418aa85b9ad571c3a391/lapack -netlib / SRC / dgebal.f # L336, was durch eine beliebige Anzahl vorheriger Berechnungen an NaN verursacht werden kann.

Als ich mit den Repro-Schritten herumspielte, stellte ich fest, dass das Ausführen des Mods als float32 das "behebt":

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)

Ich vermute also, dass sich in diesem Codepfad etwas befindet, das den Status ordnungsgemäß zurücksetzt, obwohl ich nicht sicher bin, was es ist. Hoffentlich weiß jemand, der mit Numpys Interna besser vertraut ist, wo das passieren könnte.

Erinnert mich irgendwie an einen alten Fehler, den wir mit mingw auf Windows gesehen haben, bei dem die Gleitkommaregisterkonfiguration nicht von Arbeitsthreads geerbt wurde, was dazu führte, dass Denormale nicht auf Null gespült wurden und nachfolgende Berechnungen manchmal durcheinander brachten.
Ich bin mir nicht sicher, ob dies in irgendeiner Weise für das aktuelle Windows auf der aktuellen Hardware relevant ist, aber es könnte interessant sein zu wissen, ob Ihr
Der OpenBLAS-Build wurde mit CONSISTENT_FPCSR = 1 durchgeführt (oder wenn das Hinzufügen dieser Build-Option hilfreich ist).

@mattip Wissen Sie, ob CONSISTENT_FPCSR = 1 im OpenBLAS-Build ist?

Nun, zumindest ist das dann aus dem Weg. Die Verbindung schien sowieso ziemlich abgelegen zu sein.

Hallo! Ich habe seit einiger Zeit ein ähnliches Problem und alle meine Tests deuten auf etwas faul zwischen Windows 10 (2004) und OpenBlas hin. Normalerweise führe ich meine Programme auf 3 PCs aus (2 Windows 10-Workstations und einem älteren Windows 7-Laptop). Meine Python-Skripte haben sich mit Fehlern im Zusammenhang mit der Konvergenz von linalg und svd () ungefähr zu dem Zeitpunkt schlecht verhalten, als ich meine 2 Workstations auf Version 2004 von Windows 10 aktualisiert habe. Beim ersten Ausführen des Skripts kam es auch zu Abstürzen, meistens jedoch arbeitete bei einem zweiten Versuch (laufen Jupyter-Notebooks). Auf dem alten Laptop-Rig wurden dieselben Programme fehlerfrei ausgeführt! Ich habe Miniconda, Python 3.6 und alle Pakete werden mit Pip installiert (die Umgebung ist auf den 3 Computern genau gleich).
Heute habe ich die Pip-Standardinstallation numpy (1.19.0) entfernt und die Version numpy + mkl (numpy-1.19.1 + mkl-cp36-cp36m-win_amd64.whl) von https://www.lfd.uci.edu/ installiert.

Dário

Es ist seltsam, dass die OpenBLAS-DLL von der VC9-Version von lib.exe erstellt wird. Dies ist die Version, die mit Python 2.7 verwendet wurde. Es mag keine Rolle spielen, fühlt sich aber seltsam an, da VC9 nirgendwo verwendet wird.

Der nächste Schritt für jemanden (vielleicht mich) wäre, einen NumPy-Master mit einem OpenBLAS mit einem Thread ( USE_THREAD=0 ) zu erstellen, um zu sehen, ob dies die Probleme behebt.

Ich habe einige Experimente ohne Erfolg versucht:

  • Deaktivieren Sie Threads USE_THREADS=0
  • ILP64 INTERFACE64=1 <- Segfault in NumPys Test mit Zugriffsverletzung

Können Sie die LAPACK-Testsuite mit diesem Win10-Setup ausführen? Ich hatte kürzlich den cmake-Build repariert, um ihn zu produzieren. Vielleicht liefert er einen Hinweis, ohne dass es zu einer Numpy kommt.

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

Obwohl ich viele Zeilen wie sehe

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

Ich bin mir also nicht sicher, ob diese vertrauenswürdig sind.

Es sieht so aus, als ob die meisten Tests fehlerfrei sind, aber die überlebenden sind fehlerfrei ... das ist etwas extremer als ich erwartet hatte.
(COMPLEX und COMPLEX16 sind in Bezug auf die Stapelgröße etwas anspruchsvoll, daher sind Fehler bei den Standardeinstellungen des Betriebssystems viel wahrscheinlicher, aber REAL und DOUBLE zeigen normalerweise etwa 1200000 Testläufe an. Dies hat mich gefragt, ob MS etwas am Standardstapel geändert hat Limit oder Layout)

Einige Hintergrundinformationen. Alles wird mit gcc.exe / gfortran.exe erstellt. Diese werden verwendet, um eine .a-Datei zu erstellen, die dann in eine DLL gepackt wird. Speziell:

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

Ich denke wirklich, dass das Problem in der Übergabe zwischen NumPy und OpenBLAS liegt. Ich kann mir nicht vorstellen, wie dieses Verhalten sonst auftreten könnte, wenn der erste Aufruf ein Fehler ist, aber der zweite und der nachfolgende sind alle in Ordnung. Wie kann man das Problem beheben (oder TBH kann das tiefe Problem sogar genau diagnostizieren)?

Die MS-Plattform abschaffen und glücklich leben? Wenn der Lapack-Test fehlschlägt, liegt das Übergabeproblem zwischen Fortran (= LAPACK-Teil von OpenBLAS) und C oder Fortran und "irgendetwas anderem".

Ich wäre gespannt, ob es möglich ist, Numpy mit OpenBLAS mit icc zu erstellen
und wenn ja, prüfen Sie, ob das Problem weiterhin besteht. Das ist allerdings eine große Frage.

Am Mittwoch, 12. August 2020, 19:04 schrieb Martin Kroeker [email protected] :

Die MS-Plattform abschaffen und glücklich leben? Wenn es fehlschlägt die
Lapack-Tests Das Übergabeproblem liegt zwischen Fortran (= LAPACK-Teil von
OpenBLAS) und C oder Fortran und "alles andere".

- -
Sie erhalten dies, weil Sie erwähnt wurden.
Antworte direkt auf diese E-Mail und sieh sie dir auf GitHub an
https://github.com/numpy/numpy/issues/16744#issuecomment-673026759 oder
Abmelden
https://github.com/notifications/unsubscribe-auth/ABKTSRLSHZ2XWF4OE7J3QO3SALKSJANCNFSM4OP5IXNQ
.

Wäre wahrscheinlich ausreichend, um OpenBLAS nur mit den Intel-Compilern zu erstellen (obwohl dies zumindest bei VS aus den letzten Jahren problematisch genug zu sein scheint und ich derzeit keine gültige Lizenz für ifc / ifort habe.

Windows-Benutzer sollten Conda / MKL im Jahr 2004 verwenden, bis dies behoben ist

@bashtage Vielen Dank für Ihren Vorschlag.
In meinem Fall ist ein Fehler aufgetreten, wenn ich SQLite mit pandasql verwende, nachdem ich die Conda-Version von numpy angewendet habe.

Aber ich habe kein Problem, wenn ich diese Version von numpy + mkl verwende .

@bashtage Es scheint, dass es eine neue MSVC-Vorabversion gibt, die das Problem mit dem Rostlink behebt. Vielleicht einen Versuch wert?

Zu Ihrer Information: SciPy-Problem: https://github.com/scipy/scipy/issues/12747

Es gibt einen Bericht, dass Windows Build 17763.1397 (11. August) das Problem behebt, siehe # 17082.

Es gibt einen Bericht, dass Windows Build 17763.1397 (11. August) das Problem behebt, siehe # 17082.

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

Build 17763.1397 ist nur für Windows 10, Version 1809 (Gilt für: Windows 10, Version 1809, alle EditionenWindows Server Version 1809Windows Server 2019, alle Editionen).
In diesem Fall gibt es keine Probleme für Windows 10, Version 1809.

Dies ist eine kürzlich aktualisierte Version von Windows 10, Version 2004.
https://support.microsoft.com/en-us/help/4566782
11. August 2020 - KB4566782 (OS Build 19041.450).

Ich habe immer noch das gleiche Problem unter Windows 10, Version 2004

image

Gleiche Fehler bei 19042.487 (dies ist der 20H2-Zweig):

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

Ich kann die (Teil-) Fehler im Lapack-Test von OpenBLAS reproduzieren - nur die EIG-Tests (Eigenwerttests), von denen bekannt ist, dass sie ungewöhnlich hohe Anforderungen an die Stapelgröße haben. Dort tritt das SIGSEGV in __chkstk_ms_ auf, das noch vor main () eingegeben wird. Durch Verdoppeln der Standardwerte "Stack Reserved Size" und "Stack Commit Size" der jeweiligen ausführbaren Datei mit dem Dienstprogramm peflags (z. B. peflags -x4194304 -X4194304 EIG/xeigtsts.exe ) funktionieren die Programme normal, was darauf hindeutet, dass die C / Fortran-Interaktion und die Argumentübergabe als solche gelten nicht problematisch. Ich habe noch nicht versucht, dies auf den Numpy-Fall anzuwenden (nicht sicher, wessen Peflag-Einstellung dort angepasst werden soll - python.exe?), Aber OpenBLAS selbst scheint normal zu funktionieren, wenn es mit der msys2 mingw64-Version von gcc 9.1.0 auf 19041.450 aka erstellt wird 2004

@ martin-frbg Das sieht nach Fortschritt aus.

Ging in ein Kaninchenloch und versuchte, alle Abhängigkeiten für die Erstellung von Numpy unter Windows / MSYS2 zu installieren, also keine weiteren Fortschritte.

@ martin-frbg, das auf Msys2 basierende numpy-Paket kann mit pacman installiert werden. Msys2-Build-Skripte und -Patches sind hier verfügbar: https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-python-numpy und https://github.com/msys2/MINGW-packages/tree / master / mingw-w64-openblas.

In einem letzten Triage-Meeting hatte dies eine relativ hohe Priorität, und @hameerabbasi und ich sind bereit zu helfen. Was können wir tun?

@bashtage könnten Sie versuchen, den Stapel mit editbin /STACK:3145728 python.exe vergrößern

Gibt es eine Möglichkeit, NumPy mit OpenBLAS-Versionen der Bibliotheken anstelle der von uns erstellten zu erstellen? Vielleicht sind unsere Builds etwas veraltet.

Es wäre wahrscheinlich möglich, die libopenblas.dll in Ihrem Build durch eine zu ersetzen, die entweder aus dem aktuellen Zweig develop oder einer älteren Version wie 0.3.8 oder 0.3.9 erstellt wurde, um festzustellen, ob dies Auswirkungen hat. (Nicht, dass ich momentan ein bestimmtes Commit im Sinn hätte, das sich darauf auswirken könnte). Leider treten trotz der msys2-Pakete immer noch Installationsfehler auf. Derzeit können die Tests anscheinend nicht ausgeführt werden, da self.ld_version bei einer Versionsprüfung nichts zurückgibt.

Vielen Dank. Ich versuche, meine Fenster auf Build 2004 zu aktualisieren. Mal sehen, ob ich vor dem Wochenende fertig bin

Das "kleine Wiedergabebeispiel" von bashtage von https://github.com/numpy/numpy/issues/16744#issuecomment -655430682 führt außerdem zu keinem Fehler in meinem msys2-Setup. (Soweit ich das beurteilen kann, handelt es sich bei den libopenblas in mingw64 / usr / lib um ein Single-Threaded 0.3.10, das für Haswell erstellt wurde.)

@ martin-frbg Ist es möglich, OpenBLAS mit MSVC zu erstellen?

Einfache MSVC? Machbar, bietet aber eine schlecht optimierte Bibliothek, da MSVC die Assembly-Kernel nicht unterstützt - praktisch genauso, als ob Sie OpenBLAS für TARGET = GENERIC erstellt hätten.

Außerdem löst das "kleine Wiedergabebeispiel" von bashtage aus

Ich bin mir ziemlich sicher, dass dies mit der Schnittstelle zwischen NumPy und OpenBLAS zu tun hat. Der 32-Bit-Build von NumPy hat dieses Problem ebenfalls nicht. Die Ideen der Microsoft-Mitarbeiter, mit denen ich gesprochen habe, dass dies wahrscheinlich ein Problem bei der Thread-Synchronisierung ist, scheinen am plausibelsten zu sein. Es könnte erklären, wie der falsche Wert beim ersten Aufruf vorhanden ist und bei nachfolgenden Aufrufen korrigiert wird.

Ging in ein Kaninchenloch und versuchte, alle Abhängigkeiten für die Erstellung von Numpy unter Windows / MSYS2 zu installieren, also keine weiteren Fortschritte.

Es ist ein Schmerz. Ich habe es getan, aber es hat lange gedauert, es zu automatisieren, um einige Experimente auszuprobieren. Grundsätzlich müssen die Schritte von https://github.com/MacPython/openblas-libs kopiert werden, um die .a-Dateien abzurufen, und anschließend die Schritte von https://github.com/numpy/numpy/blob/master/ kopiert werden.

Der einfachste Weg, einen DLL-Build zu erhalten, besteht darin, ein Appveyor-Konto zu eröffnen und dann https://github.com/MacPython/openblas-libs zu klonen

Unter https://github.com/MacPython/openblas-libs scheint OpenBLAS mit INTERFACE64=1 . Dies ist bei Msys2 Build OpenBLAS und Numpy nicht der Fall.

@carlkl In diesem Problem geht es nicht um den Msys2-Build von NumPy oder OpenBLAS. Es geht um den Win32 / AMD64-Build, der Msys2-bereitgestelltes gfortran zum Kompilieren von fortran-Quellen verwendet, dann aber eine Win32-DLL aus der kompilierten Bibliothek unter Verwendung von lib.exe von MS erstellt.

@bashtage Ich habe dies erwähnt, da https://github.com/numpy/numpy/issues/16744#issuecomment -689785607 gemeldet wurde, dass der Segfault nicht innerhalb von msys2 reproduziert werden konnte. Und ich denke, die erwähnte msys2-Umgebung enthält die von msys2 bereitgestellten Openblas- und Numpy-Binärpakete.

Ich habe keine Ahnung, ob die Windows 64bit Numpy mit einem ähnlichen Flag mit MSVC kompiliert wird oder nicht.

Übrigens: Ich kann das Flag -fdefault-integer-8 im Scipy-Repository nicht finden.
Ich bin nicht sicher, ob mit -fdefault-integer-8 kompilierter Code ABI-kompatibel mit Code ist, der ohne dieses Flag kompiliert wurde.

Ein weiterer Aspekt kommt mir in den Sinn: Vielleicht sollte -fdefault-integer-8 mit -mcmodel=large kombiniert werden.

BEARBEITEN: Denken Sie daran: Windows64 hat ein LLP64-Speichermodell, nicht ILP64.
LLP64 bedeutet: lang: 32 Bit, Zeiger: 64 Bit

Welche Ganzzahlgröße verwendet der Numpy, für den das Win10-2004-Problem auftritt? Es würde besser zu dem passen, wofür OpenBLAS gebaut wurde, aber IIRC dieses Thema wurde bereits früher in diesem Thread angesprochen (und eine Nichtübereinstimmung würde wahrscheinlich zu einem stärkeren Bruch führen, unabhängig vom Windows-Patchlevel).

Mindestens Openblas können mit https://github.com/MacPython/openblas-libs in drei Varianten erstellt werden (siehe appveyor.yml):

  • 32 Bit
  • 64 Bit
  • 64 Bit mit INTEGER64

aber wenn Sie keine Ahnung haben, was für die numpy 64bit verwendet wird, baut auf Windows.

_und eine Nichtübereinstimmung würde wahrscheinlich zu einem stärkeren Bruch führen, unabhängig vom Windows-Patchlevel_

-fdefault-integer-8 gilt nur für den fortran-Teil von Lapack. Das zugrunde liegende Speichermodell (LLP64) wird dadurch nicht geändert, daher bin ich mir nicht sicher, ob wir Probleme außerhalb der Fortran Lapack-Teile erwarten sollten.

hmm,

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

- 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_'
Alle anderen Versionen ( Python36-64bit-full , Python37-64bit-full ) werden ohne NPY_USE_BLAS_ILP64 erstellt.

Die Numpy-Binärdateien auf pypi.org bestehen alle aus 32-Bit-Ganzzahl-Openblas. https://github.com/MacPython/numpy-wheels/blob/v1.19.x/azure/windows.yml

Einzelheiten zum Build-Prozess von Gfortran vs. MSVC finden Sie hier . Die Microsoft lib.exe ist nicht an der Erstellung der Openblas-DLL beteiligt, sondern nur an der MingW-Toolchain. Numpy verwendet die Datei openblas.a und generiert die DLL mit gfortran. https://github.com/numpy/numpy/blob/74712a53df240f1661fbced15ae984888fd9afa6/numpy/distutils/fcompiler/gnu.py#L442 MSVC-Tools werden verwendet, um die .lib-Datei aus der .def-Datei und Numpy C-Code zu erstellen wird mithilfe dieser .lib-Datei mit der von gfortran erstellten DLL verknüpft.

Eine theoretische Möglichkeit, die schief gehen könnte, besteht darin, dass zwischen mingw, das das statische Artefakt openblas.a erzeugt hat, und der Mingw-Version, die beim Erstellen von numpy verwendet wird, eine Art Mingw-Versionsinkongruenz besteht. Ich bin mir jedoch nicht sicher, ob dies möglich ist und Probleme verursachen kann.

choco install -y mingw --forcex86 --force --version=5.3.0 die in windows.yml scheinen veraltet zu sein. Warum nicht 7.3.0 oder 8.1.0 ? Ich kann mich an Probleme erinnern, die ich vor zwei oder drei Jahren mit gcc-5.x hatte.

choco install -y mingw --forcex86 --force --version = 5.3.0, das in windows.yml verwendet wird, scheint veraltet zu sein

Dies gilt nur für den 32-Bit-Windows-Build, der wahrscheinlich nicht mit diesem Problem zusammenhängt.

Alle anderen Versionen ( Python36-64bit-full , Python37-64bit-full ) werden ohne NPY_USE_BLAS_ILP64 erstellt.

Gleiche Fehler unter Python 3.6 und 3.8.

Es gibt noch eine Idee (ich grabe im Dunkeln):

OpenBLAS wird jetzt mit -fno-optimize-sibling-calls kompiliert, siehe https://github.com/xianyi/OpenBLAS/issues/2154 , https://github.com/xianyi/OpenBLAS/pull/2157 und https: // gcc .gnu.org / bugzilla / show_bug.cgi? id = 90329.
Bearbeiten: siehe auch: https://gcc.gnu.org/legacy-ml/fortran/2019-05/msg00181.html

Numpy hat diese Flagge nicht in seinem gfortran Teil der Distutils angebracht. Ich weiß, dass numpy mit MSVC kompiliert wird. Daher würde ich Probleme mit scipy eher mit numpy erwarten, so dass dies wieder eine falsche Reise sein könnte.

Die Numpy-Binärdateien auf pypi.org bestehen alle aus 32-Bit-Ganzzahl-Openblas. https://github.com/MacPython/numpy-wheels/blob/v1.19.x/azure/windows.yml

Warum unterscheiden sich die beim Testen verwendeten Build-Konfigurationen von den im Release verwendeten? Das klingt nach einem Risiko.

Können wir den Azure-Builds Artefakte hinzufügen? Dies würde es viel einfacher machen, Räder zum Testen zu bekommen. Meine einzige Sorge hier ist, dass das freie Artefaktlimit ziemlich klein ist, IIRC, 1 GB, und ich weiß nicht, was passiert, wenn Sie es treffen (FIFO wäre gut, könnte aber andere Dinge tun, einschließlich Fehler).

Warum unterscheiden sich die beim Testen verwendeten Build-Konfigurationen von den im Release verwendeten?

Wir testen alle unterstützten Python-Versionen in Windows ohne NPY_USE_BLAS_ILP64 und testen Python 3.8 auch mit NPY_USE_BLAS_ILP64 , siehe https://github.com/numpy/numpy/blob/v1.19.2/azure -pipelines.yml # L195. Die wöchentlichen Builds sind also korrekt, wenn 32-Bit-Ganzzahl-Openblas verwendet werden.

Können wir den Azure-Builds Artefakte hinzufügen?

Wahrscheinlich ist es einfach, dies auszuprobieren und sich über Grenzen zu informieren, wenn es fehlerhaft ist. Die wöchentlichen Räder sollen jedoch die Test-Builds originalgetreu nachbilden. Unstimmigkeiten sollten als Fehler behandelt und behoben werden.

Wahrscheinlich ist es einfach, dies auszuprobieren und sich über Grenzen zu informieren, wenn es fehlerhaft ist. Die wöchentlichen Räder sollen jedoch die Test-Builds originalgetreu nachbilden. Unstimmigkeiten sollten als Fehler behandelt und behoben werden.

Ich dachte, dass es einfacher sein würde, in einer PR zum Haupt-Repo zu experimentieren und das Artefakt zu greifen, um es 2004 zu testen.

Macht Sinn.

Sie können Azure-Pipelines in Ihrem Repo-Bashtage / Numpy aktivieren

Ein bisschen mehr Information: Der erste Aufruf, der fehlschlägt, ist, weil DNRM2 in OpenBLAS eine NAN zurückgibt. Für mich ist das wiederholbar: jeder Anruf bei

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

druckt ** On entry to DGEBAL parameter number 3 had an illegal value , was eine andere Möglichkeit ist, " DNRM2 NAN zurückgegeben" zu sagen. Die Operation mod ist kritisch, ohne sie gibt der Aufruf von eig diesen Fehler nicht aus.

Wie könnte es eine Interaktion zwischen dem mod ufunc und dem Aufruf von OpenBLAS geben?

Die Operation mod ist kritisch, ohne sie gibt der Aufruf von eig diesen Fehler nicht aus.

Löst das manuelle Erstellen genau dieses Arrays den Fehler wiederholt aus?

Dieser Code löst den Fehler nicht aus:

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

Könnte das vorhergehende mod ein Register in einem undefinierten Zustand belassen? Ich habe den nrm2.S nicht noch einmal überprüft, aber ich denke, wir hatten vor einigen Jahren Probleme, XORing ein Register mit sich selbst zu erstellen, um es zu löschen, was bei NaN fehlschlagen würde.

Für diejenigen, die mitmachen, ruft float64 % npy_divmod für jeden Wert

... was in der ersten Zeile npy_fmod() aufruft, was fmod () ist . Hier sind einige Änderungen, die ich versucht habe. "Fehler" bedeutet, dass ich die Meldung "Unzulässiger Wert" von OpenBLAS erhalte, wenn ich den Code ausführe, der a % 17; np.linalg.eig(a) aufruft
Code | Ergebnis
--- | --- ---.
mod = npy_fmod@c@(a, b); (Originalcode) | Error
mod = 100; //npy_fmod@c@(a, b); | Kein Fehler
mod = npy_fmod@c@(a, b); mod = 100.0; | Error

Es scheint also, dass fmod von MSVC etwas tut, das OpenBLAS verwirrt.

Das ist interessant und komisch.

Können Sie eine naive (nicht von der Plattform bereitgestellte) Version von fmod verwenden, um zu sehen, ob dies das Problem behoben hat?

Oder erzwinge einfach HAVE_MODF auf 0 .

Ich glaube nicht, dass wir eine naive Version von fmod haben, oder?

Ich sehe, dass es ein HAVE_MODF-Makro gibt, aber wohin führt dieser Pfad ?

Sieht so aus, als würde es auf die Doppelversion zurückgreifen, wenn float und long double fehlen. Die doppelte Version ist obligatorisch, um numpy zu erstellen. Das undef ist wahrscheinlich, um Compiler-Inline-Funktionen zu vermeiden, ISTR, dass dies vor langer Zeit ein Problem unter Windows war.

Ich wollte "beweisen", dass das Problem die Implementierung von fmod , die von ucrtbase.dll . Also habe ich eine kleine Problemumgehung geschrieben, die ctypes verwendet, um die Funktion aus der DLL zu ziehen und sie zu verwenden, indem fmod direkt aufgerufen wird. Die Tests schlagen immer noch fehl. Dann wechselte ich zu einer älteren Version von ucrtbase.dll (nur für die Funktion fmod ). Die Tests bestehen. Ich habe einen Thread im Visual Studio Forum geöffnet. Wenn jemand einen besseren Weg kennt, um Microsoft zu erreichen, wäre das großartig.

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

Was ist, wenn Sie nach dem Aufruf von fmod Code hinzufügen, damit ST(0) kein Nan enthält? Oder synthetisch auf Nan setzen?
Haben Aufrufkonventionen einige Einschränkungen hinsichtlich des Verhaltens dieser Register?

Ich wollte "beweisen", dass das Problem die Implementierung von fmod , die von ucrtbase.dll . Also habe ich eine kleine Problemumgehung geschrieben, die ctypes verwendet, um die Funktion aus der DLL zu ziehen und sie zu verwenden, indem fmod direkt aufgerufen wird. Die Tests schlagen immer noch fehl. Dann wechselte ich zu einer älteren Version von ucrtbase.dll (nur für die Funktion fmod ). Die Tests bestehen. Ich habe einen Thread im Visual Studio Forum geöffnet. Wenn jemand einen besseren Weg kennt, um Microsoft zu erreichen, wäre das großartig.

Zumindest jeder mit einem Azure-Konto, bei dem es sich wahrscheinlich um viele Leute handelt, kann es positiv bewerten. Ich werde mich an einige Kontakte wenden, die ich hergestellt habe, als dieses Problem ursprünglich auftrat, und die in Azure ML arbeiten, um zu prüfen, ob sie etwas tun können.

Zumindest jeder mit einem Azure-Konto, bei dem es sich wahrscheinlich um viele Leute handelt, kann es positiv bewerten.

Danke für den Tipp, positiv bewertet!

Ich glaube nicht, dass wir eine naive Version von fmod haben, oder?

Nein. Es ist eine schwierige Funktion, die von der IEEE-754-Spezifikation benötigt wird, um ein bestimmtes Verhalten zu haben. Es ist auch sehr langsam, was wahrscheinlich mit der Spezifikation zusammenhängt.

Die harte Arbeit von fmod wird von der Anweisung fprem x87 ausgeführt, selbst in der VS2019-Variante - siehe @mattips Inhalt (letzte Zeile) https://gist.github.com/mattip / d9e1f3f88ce77b9fde6a285d585c738e. ( fprem1 ist übrigens die Variante remainder .)

Bei Verwendung in Verbindung mit MMX- oder SSE-Registern ist Vorsicht geboten - wie hier beschrieben: https://stackoverflow.com/questions/48332763/where-does-the-xmm-instruction-divsd-store-the-remainder.

Es stehen einige alternative Implementierungen zur Verfügung, wie unter https://github.com/xianyi/OpenBLAS/issues/2709#issuecomment -702634696 beschrieben. Allerdings: Alle diese benötigen zum Kompilieren gcc (mingw-w64). OpenLIBM wird nicht mit MSVC AFAIK kompiliert. Inline-Assembler-Code ist mit MSVC nicht zulässig. Im Prinzip könnte man während des Numpy-Builds eine fmod-Hilfsbibliothek erstellen (mingw-w64) und verwenden (MSVC).

Was ist, wenn Sie nach dem Aufruf von fmod Code hinzufügen, damit ST (0) kein nan enthält? Oder synthetisch auf Nan setzen? Haben Aufrufkonventionen einige Einschränkungen hinsichtlich des Verhaltens dieser Register?

Ich denke, wir könnten ein kleines Stück Assembly hinzufügen, um Register zu löschen, bevor wir OpenBLAS unter Windows aufrufen. Ich habe versucht, dies in einem kleinen Testaufbau zu tun, aber mein Masm Assembly Foo ist schwach. Ich habe versucht, eine Prozedur zu schreiben, die fldz mehrmals aufruft. Bei Verwendung erhalte ich eine Ausnahme. Hilfe?

In lots_of_fldz.asm :

.code
lots_of_fldz proc
    fldz
    fldz
    fldz
    fldz
    fldz
    fldz

lots_of_fldz endp
end

In einer anderen Datei:

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

Fügen Sie sie in ein VisualStudio-Projekt ein und befolgen Sie diese Anleitung , um die Masm-Kompilierung zu aktivieren

@mattip , ich habe eine Assembler-Datei für die 64-Bit-Funktion text: -Segment erstellt, wie es in der entsprechenden fmod -Funktion von mingw-w64 (64-Bit) zu finden ist. Keine Ahnung, ob dies als Ersatz für die fehlerhafte fmod-Funktion funktioniert, aber zumindest sollte man es versuchen. Die resultierende obj-Datei könnte zu npymath.lib hinzugefügt werden.

fmod.asm: (64-Bit)

.code
fmod PROC
    sub    rsp , 18h
    movsd  QWORD PTR [rsp+8h] , xmm0
    fld    QWORD PTR [rsp+8h]
    movsd  QWORD PTR [rsp+8h] , xmm1
    fld    QWORD PTR [rsp+8h]
    fxch   st(1)
L1:
    fprem
    fstsw  ax
    sahf
    jp     L1
    fstp   st(1)
    fstp   QWORD PTR [rsp+8h]
    movsd  xmm0 , QWORD PTR [rsp+8h]
    add    rsp,18h
    ret
fmod endp
end

masm-Befehl: ml64.exe /c fmod.asm erstellt fmod.obj (verwenden Sie die 64-Bit-Variante von 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 danke. Ich wäre glücklicher mit einem Assembler, der die ST (N) -Register zurücksetzt, die wir auf x86_64 verwenden könnten, bevor wir OpenBLAS-Funktionen aufrufen. Heute ist dieses Problem aufgrund einer Änderung von fmod aufgetreten. Morgen kann es sich um eine andere Funktion handeln. Ich bin nicht sicher, ob Funktionen erforderlich sind, um die ST(N) -Register bei der Rückkehr zurückzusetzen. Wenn es keine solche Anforderung gibt, ist fmod nicht wirklich fehlerhaft, und die Änderung in Windows hat dazu geführt, dass OpenBLAS die Register nicht zurückgesetzt hat, bevor sie verwendet werden. Wir sollten ihnen entweder helfen, das Problem zu beheben oder es zu umgehen.

Ich habe versucht, die Register mit fldz im obigen Kommentar zurückzusetzen, aber mein Testprogramm funktioniert nicht.

@mattip , mein Assembler Knowlegde ist auch mehr oder weniger einfach. Möglicherweise finden Sie jedoch eine mögliche Antwort in diesem SO-Thread: https://stackoverflow.com/questions/19892215/free-the-x87-fpu-stack-ia32/33575875

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

Vermutlich könnten wir zu Beginn von OpenBLAS nrm2.S (nach dem PROFCODE-Makro) auch fninit aufrufen, um diese Theorie zu überprüfen

Interessantes Stück aus dem
Binäre Schnittstelle der System V-AnwendungAMD64 Architecture Processor SupplementEntwurf Version 0.99.6

_Die Steuerbits des MXCSR-Registers werden in Anrufen gespeichert (über Anrufe hinweg beibehalten), während die Statusbits vom Anrufer gespeichert werden (nicht beibehalten) ._

_Das x87-Statuswortregister wird vom Anrufer gespeichert, während das x87-Steuerwort vom Angerufenen gespeichert wird._

_Alle x87-Register werden vom Anrufer gespeichert, sodass Callees, die die MMX-Register verwenden, möglicherweise den Befehl für schnellere Femms verwenden._

Ganz anders als bei der Windows 64-Bit-Aufrufkonvention.

@ martin-frbg, fninit ist gefährlich: The FPU control word is set to 037FH (round to nearest, all exceptions masked, 64-bit precision). X87 Erweiterte Präzision ist nicht in allen Fällen erwünscht, insbesondere unter Windows.

Ich würde dies nicht für eine Release-Version wollen, nur für einen kurzen Test. Immer noch nicht ganz davon überzeugt, dass OpenBLAS "vor" sich selbst irgendwie bereinigen sollte, aber ich kann keine klare Dokumentation zum Windows-Verhalten der alten x87-CPU finden. Ich habe festgestellt, dass Agner Fog unter http://www.agner.org/optimize/calling_conventions.pdf ein Dokument zum Aufrufen von Konventionen hat (die Diskussion über die Win64-Behandlung von FP-Registern beginnt auf Seite 13, konzentriert sich jedoch auf die grundlegende Verfügbarkeit und das Verhalten über Kontextwechsel hinweg).

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

Ich denke, das bedeutet: Verwenden Sie keine x87-Anweisungen (Win64). Wenn Sie das tun, viel Glück. Oder mit anderen Worten: Der Angerufene ist dafür verantwortlich, keinen Schaden zu erleiden.

Hm, das scheint das Verhalten des MSVC-Compilers spezifisch zu beschreiben, während ich denke, dass wir uns in einem Mingw-Ökosystem befinden?

Nein, Numpy (Pypi) wird mit MSVC (Visual Studio 2019) unter Windows kompiliert. Für OpenBLAS wird mingw-w64 verwendet (aufgrund der Fortran-Teile). Auch die Scipy Fortran-Teile werden mit mingw-w64 kompiliert. CPython und seine binären Erweiterungen basieren jedoch stark auf den von MSVC festgelegten Standards.

Übrigens: Dies war der Grund für die Entwicklung von https://github.com/mingwpy, das derzeit wieder zum Leben erweckt wird. (schamloser Stecker)

Noch ein bisschen:

mingw-w64 verwendet (fast) die gleichen Aufrufkonventionen wie MSVC. Die einzigen bemerkenswerten Unterschiede sind die unterschiedliche Stapelausrichtung auf x86 (32-Bit) - relevant für SIMD und das nicht unterstützte vectorcall .

Interessant. x86 ist nicht betroffen. Nur AMD64.

Am Sonntag, 4. Oktober 2020, 22:19 Uhr schrieb carlkl [email protected] :

Noch ein bisschen:

mingw-w64 verwendet (fast) die gleichen Aufrufkonventionen wie MSVC. Das einzige
Bemerkenswerte Unterschiede sind unterschiedliche Stapelausrichtungen auf x86 (32-Bit) -
relevant für SIMD und den nicht unterstützten Vectorcall.

- -
Sie erhalten dies, weil Sie erwähnt wurden.
Antworte direkt auf diese E-Mail und sieh sie dir auf GitHub an
https://github.com/numpy/numpy/issues/16744#issuecomment-703317784 oder
Abmelden
https://github.com/notifications/unsubscribe-auth/ABKTSRMFHWZVLDYDFGBM6YDSJDRGTANCNFSM4OP5IXNQ
.

MSVC 32bit hat die fpu vielleicht nicht verleugnet? Ich werde nur eine Notlösung für die fpu-verwendende nrm2.S durch nrm2_see2.S (wenn dies möglich ist, gibt es leider eine Reihe nicht verwendeter, aber tödlicher Assembly-Routinen in der Codebasis) oder die einfache C-Version für das Betriebssystem durchführen == Windows dann. (Das andere hier diskutierte Problem muss jedoch etwas anderes sein, da ich denke, dass alle anderen älteren Assembly-Routinen für x86_64 mindestens SSE2 sind.)

@mattip , vielleicht reicht ein Aufruf von _fpreset nach divmod aus, um aus einem durcheinandergebrachten FPU-Status zurückgesetzt zu werden?

Vielleicht ein Anruf bei _fpreset

Nein, es werden weder die ST(N) -Register zurückgesetzt, noch werden die fehlgeschlagenen Tests behoben.

Haben Sie _fninit ausprobiert? Dies sollte den FPU-Stapel zurücksetzen. Oder ffree oder fstp anstelle von fldz wie unter https://stackoverflow.com/questions/19892215/free-the-x87-fpu-stack-ia32/33575875 erwähnt ?

Ich würde gerne die Assembler-Befehle ausprobieren, aber das Testprojekt im obigen Kommentar stürzt ab. Jemand muss meinen Code korrigieren, damit er funktioniert (tatsächlich scheint fninit ein guter Kandidat zu sein), dann kann ich Assembler-Anweisungen ausgeben, um die Register in NumPy zurückzusetzen, bevor ich OpenBLAS aufrufe.

Etwas wie das?

.code
reset_fpu proc
    finit
    fldz
reset_fpu endp
end

finit ist wait plus fninit . Ich bin mir nicht sicher, ob fldz nach fninit .

Wie ich im Kommentar sagte, fehlt etwas, damit der Aufruf des kompilierten Assemblycodes ordnungsgemäß funktioniert. Das ist ziemlich genau das, was ich in diesem Kommentar hatte. Der Code stürzt mit exited with code -2147483645 . Bitte schauen Sie sich den vollständigen Code an und prüfen Sie, ob Sie ihn zum Laufen bringen können.

Ich kann es versuchen (morgen). Möglicherweise sind diese Schnipsel jedoch hilfreich:

https://www.website.masmforum.com/tutorials/fptute/fpuchap4.htm
(eine der am besten lesbaren Seiten zu diesem Thema, die ich gefunden habe)

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. 

Soweit ich weiß, kann fldz einen Fehler verursachen, wenn st (7) verwendet wird.

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. 

Sie können versuchen:

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

Entschuldigung, ich mache mich nicht klar. Das unmittelbare Problem ist nicht, welchen Assembler Aufrufe machen sollen. Das unmittelbare Problem besteht darin, eine aufrufbare Prozedur so zu erstellen, dass sie verwendet werden kann, und dies in zwei Dateien zu demonstrieren ( *.asm und main.c / main.cpp ) Projekt, das kompiliert und ausgeführt wird. Sobald wir das haben, kann ich weiter verschiedene Anrufe untersuchen und wie sie OpenBLAS beeinflussen.

@ Mattip , ich verstehe. Ich werde es auf jeden Fall versuchen, aber das kann einige Zeit dauern.

Ich hatte den Eindruck, dass das _tempory_ schlechte Verhalten von fmod in UCRT von OpenBLAS _ geheilt werden sollte_: https://github.com/xianyi/OpenBLAS/pull/2882 und nicht von numpy, da numpy die FPU auf WIN64 nicht verwendet. Und natürlich sollte MS dieses Problem mit einem Windows-Patch beheben.
In diesem Fall besteht der numpy-Patch darin, die Verwendung einer OpenBLAS-Version während des Builds sicherzustellen, die nicht älter als die kommende OpenBLAS-Version ist.

@matti Es gibt einen Sanity Check in numpy/__init__.py . Gibt es einen einfachen und zuverlässigen Test, den wir hinzufügen könnten, um dieses Problem zu erkennen?

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

@ Mattip , danke für das Snippet. Aber ich werde einige Zeit brauchen, um Zugang zu einem Desktop zu erhalten, auf dem ich diese Art von Tests durchführen kann. Im Moment arbeite ich die meiste Zeit mit einem Laptop mit einer minimalen Programmierumgebung, in der ich fast nichts installieren kann.

Wir haben ein Update auf OpenBLAS v0.3.12 zusammengeführt und ein lokaler Build mit dieser Version + Windows Update 2004 besteht die Testsuite.

Lassen Sie dies offen, bis Windows aktualisiert wird.

Wurden die Pre-Release-Räder mit dem neuen OpenBLAS gebaut? Gerne führen wir weitere Tests mit nachgeschalteten Projekten durch, bei denen dieser Fehler aufgetreten ist.

Die Windows 3.9 Pre-Release-Räder fehlen derzeit, da Testfehler aufgetreten sind (jetzt behoben). Die feste Bibliothek wird in 1.19.3 verwendet und kommt heute oder morgen heraus.

Die Option /MT aktiviert die statische Verknüpfung unter Windows. Mit der 1909-Version des Microsoft SDK kann möglicherweise eine statische Verknüpfung mit libucrt.lib hergestellt werden. Dies könnte als Problemumgehung für den Fehler ucrtbase.dll in den Jahren 2004 und 20H2 dienen. Es würde die Räder größer machen, was ein Nachteil ist.

Ich habe keine Ahnung, ob dieses / MT-Problem noch gültig ist, aber es sollte berücksichtigt werden.

Ich denke, wenn NumPy das einzige Modul ist, das mit MT erstellt, dann könnte es sein
IN ORDNUNG. Natürlich könnte es sein, dass wenn NumPy MT ist, dann keine
Downstream müsste auch MT sein, und das wäre ein Problem.

Am Montag, 2. November 2020, 19:37 Uhr schrieb carlkl [email protected] :

Ich habe keine Ahnung, ob dieses / MT-Problem
https://stevedower.id.au/blog/building-for-python-3-5-part-two ist noch
gültig, aber es sollte berücksichtigt werden.

- -
Sie erhalten dies, weil Sie erwähnt wurden.
Antworte direkt auf diese E-Mail und sieh sie dir auf GitHub an
https://github.com/numpy/numpy/issues/16744#issuecomment-720682011 oder
Abmelden
https://github.com/notifications/unsubscribe-auth/ABKTSRJIVAQLECK4E2EVSSDSN4C65ANCNFSM4OP5IXNQ
.

Empfohlene Problemumgehungen für dieses Problem? Meine Situation ist, dass ich mich auf einem Computer befinde, der auf das Update 2004 aktualisiert wurde, und über eine Desktop-Software verfüge, die pip verwendet, um numpy / scipy / pandas usw. zu installieren. Die gesamte Software ist von diesem Problem betroffen, das durch das Microsoft-Update verursacht wird.

Alle Empfehlungen wären willkommen, da die Verwendung von conda zur Installation von numpy für die Software, an der ich arbeite, keine Option ist.

Wenn Sie kein Docker benötigen, können Sie 1.19.3 anheften. Es besteht alle Tests auf meinen Windows-Systemen.

Vielen Dank. 1.19.3 arbeitet mit pip an dem Problem.

Der Link in der schlechten BLAS-Erkennung führt zu vielen lauten Posts auf der MS-Website. Ich hoffe, das geht nicht in die Luft.

Ich nehme an, eine andere Alternative ist die Verwendung eines fmod eines Drittanbieters unter Win64.

Ich frage mich, wie die Antwort lauten würde, wenn NumPy nach einer Veröffentlichung vier Monate lang einen so schwerwiegenden Fehler behoben hätte, insbesondere wenn wir den Benutzern keine klaren Anweisungen zum Downgrade auf die vorherige Version gegeben hätten. Benutzer können leicht auf 1.19.3 pinnen, aber das wird das Problem nicht lösen, sondern es wird nur in ein anderes Paket verschoben, das die Register verwendet, nachdem sie durcheinander gebracht wurden: vielleicht scipy, vielleicht tensorflow.

Eine weitere Idee für eine Problemumgehung: Überprüfen Sie, ob es in ucrt eine andere Funktion gibt, die die FPU verwendet, und belassen Sie den Status in einem guten Zustand. Wenn es eine gibt, könnten wir dies nach fmod aufrufen. Dies hätte den Vorteil gegenüber der Assembly- Problemumgehung, die

Ich denke nicht, dass wir mehr Anstrengungen unternehmen sollten, um dieses Problem zu umgehen. Jede zusätzliche Arbeit, die wir zur Minderung des Problems leisten, nimmt wertvolle Entwicklerzeit in Anspruch und verringert den Druck auf Microsoft, dies zu beheben. Wie oben erwähnt, kann jeder Code in anderen Projekten, der fmod aufruft und / oder die Register verwendet, dieses Problem ohne Verbindung zu NumPy lösen.

Ich denke nicht, dass wir mehr Anstrengungen unternehmen sollten, um dieses Problem zu umgehen. Jede zusätzliche Arbeit, die wir zur Minderung des Problems leisten, nimmt wertvolle Entwicklerzeit in Anspruch und verringert den Druck auf Microsoft, dies zu beheben. Wie oben erwähnt, kann jeder Code in anderen Projekten, der fmod aufruft und / oder die Register verwendet, dieses Problem ohne Verbindung zu NumPy lösen.

Die Reaktion auf die Fehlermeldung ist eindeutig nicht sehr hilfreich. Es sollte beispielsweise vorgeschlagen werden, dass Windows-Benutzer, die die neuesten NumPy-Funktionen verwenden möchten, eine Distribution verwenden sollten, die mit MKL anstelle des Pip Wheel geliefert wird. Es sollte auch einen Link zu diesem Thread enthalten.

Obwohl dies eindeutig in der Verantwortung von MS liegt, dies zu beheben, ist es für Projekte selten eine gute Möglichkeit, den guten Willen aufrechtzuerhalten, wenn die Benutzer auf die Schuld eines anderen hinweisen.

@bashtage Ich

Ich bin mir nicht ganz sicher, was du damit meinst, Schmerzen zu verursachen.

Der Import von NumPy schlägt spektakulär fehl und es wird keine Problemumgehung bereitgestellt. Für die meisten Benutzer wäre es am hilfreichsten, wenn die Liste der bekannten Problemumgehungen deutlich sichtbar wäre:

(a) Verwenden einer MKL-basierten Distribution wie conda oder Enthought Deployment Manager, die dies vermeidet, jedoch im linearen Algebra-Code
(b) Kehren Sie zu NumPy 1.19.3 zurück, das mit einer Version von OpenBLAS geliefert wird, die vor dem Fehler geschützt ist. Diese Option ist möglicherweise nicht für Benutzer geeignet, die in Containern ausgeführt werden.
(c) Aus der Quelle erstellen. Diese Option verfügt über BLAS mit geringer Leistung, ist jedoch möglicherweise in Umgebungen geeignet, in denen die Verteilung durch Dritte nicht zulässig ist und entweder Container verwendet werden oder eine aktuelle Funktion oder Fehlerbehebung in NumPy erforderlich ist.

Ich denke nicht, dass es falsch ist, auf den fmod-Fehler aufmerksam zu machen, aber dann werden Benutzer zu diesem Forum geschickt, als ob eine Lösung auf sie wartet.

Wir könnten den Link entfernen und stattdessen Benutzer hier landen lassen, aber wir sollten Benutzer warnen, dass die Ergebnisse bei der Ausführung im Jahr 2004 nicht vertrauenswürdig sind. Wenn Sie den Ergebnissen einer Berechnung nicht vertrauen können, sollten Sie die Berechnung auf dieser Plattform vermeiden.

Dies ist keine Option. Benutzer müssen nur NumPy + OpenBLAS (ex 0.3.12) vermeiden. Sie müssen NumPy + Windows (2004 / 20H2 (es sind jetzt 2 veröffentlichte Versionen betroffen) nicht vermeiden).

MKL-basierte Distribution

Es gab auch einen Bericht über Probleme mit MKL.

Zurück zu NumPy 1.19.3

Dies behebt jedoch keine anderen potenziellen Probleme, die sich aus der Verwendung von fmod ergeben. Das Problem ist, dass es keine Möglichkeit gibt, sicher zu sein, dass die Ergebnisse korrekt sind.

Leute sollten Python 2004 nicht verwenden, vielleicht stattdessen WSL? Ich wäre auch in Ordnung, wenn ich einen älteren ucrt mit den Fensterrädern einbinden würde, wenn das möglich wäre, aber was ist mit anderen Projekten? Gibt es eine einfache Möglichkeit, zu früheren Windows-Versionen zurückzukehren?

Es gab auch einen Bericht über Probleme mit MKL.

NumPy hat keinen Test, der bei MKL fehlschlägt. Es scheint schwierig anzunehmen, dass ein Problem vorliegt, wenn keine Fehler gemeldet wurden. Der fmod-Fehler manifestiert sich nicht in MKLs BLAS (vermutlich, weil keine FPU verwendet wird).

Dies behebt jedoch keine anderen potenziellen Probleme, die sich aus der Verwendung von fmod ergeben. Das Problem ist, dass es keine Möglichkeit gibt, sicher zu sein, dass die Ergebnisse korrekt sind.

Nein, aber es werden auch keine Windows-Sicherheitsprobleme oder viele andere Fehler behoben. Das Problem hier ist sehr speziell.

  1. fmod ist in Ordnung, da korrekte Ergebnisse erzielt werden
  2. Sie müssen Code in Assembler geschrieben haben, um dieses Problem zu lösen, da der System-Compiler keinen x87-Code erzeugt.

Diese beiden deuten darauf hin, dass es sehr schwierig ist, das Problem für fast den gesamten Code zu erreichen. Nur der Code mit der höchsten Leistung wie OpenBLAS, FFT-Bibliotheken mit handgeschriebenen Kerneln oder MKL lösen wahrscheinlich # 2 aus.

Ich denke auch, dass es vernünftig ist, das Update zu veröffentlichen, da NumPy veröffentlicht worden wäre, wenn OpenBLAS 0.3.12 wie erwartet funktioniert hätte, und dieses Problem niemals bei Benutzern aufgetreten wäre.

Leute sollten Python 2004 nicht verwenden, vielleicht stattdessen WSL? Ich wäre auch in Ordnung, wenn ich einen älteren ucrt mit den Fensterrädern einbinden würde, wenn das möglich wäre, aber was ist mit anderen Projekten? Gibt es eine einfache Möglichkeit, zu früheren Windows-Versionen zurückzukehren?

Ich vermute, dass dies für viele Benutzer für viele Benutzer keine Option ist: Unternehmensbenutzer auf Unternehmens-Desktops, Anfänger (die Conda verwenden sollten) oder alle, die einen Laptop mit 2004 oder 20H2 gekauft haben und kein Downgrade durchführen können.

Beachten Sie, dass Condas nicht nur mit MLK verknüpft ist, sondern auch bereits eine eigene Version von ucrtbase.dll ausliefert, die anscheinend eine ältere Version ist (10.0.17134.12).

Ich stimme

@jenshnielsen : Beachten Sie, dass nicht nur Condas numpy gepackt gegen MLK verknüpft ist [...]

Die von conda-forge gepackten Builds ermöglichen das Auswechseln der Implementierung von blas / lapack (von openblas / mkl / blis / netlib), es muss kein MKL sein.

Leute sollten Python 2004 nicht verwenden, vielleicht stattdessen WSL?

Dies ist für die meisten Benutzer nicht die Standardbetriebsart.

Ich wäre auch in Ordnung, wenn ich einen älteren ucrt mit den Fensterrädern einbinden würde, wenn das möglich wäre, aber was ist mit anderen Projekten?

Andere Projekte liegen nicht in unserer Verantwortung.

Gibt es eine einfache Möglichkeit, zu früheren Windows-Versionen zurückzukehren?

Wenn Sie eine Neuinstallation durchgeführt oder Ihren Speicherplatz bereinigt haben, ist dies fast unmöglich.

Ich stimme

Genau. Wir könnten viele Benutzer verlieren, wenn wir dies nicht beheben.

Ich wäre auch in Ordnung, wenn ich einen älteren ucrt mit den Fensterrädern einbinden würde, wenn das möglich wäre, aber was ist mit anderen Projekten?

@charris , dies hilft unter Windows 10 nicht. Wenn Sie neben Python oder Numpy ein anderes UCRT bereitstellen, wird es unter Windows 10 niemals geladen. Diese Methode gilt nur für ältere Windows-Versionen (Windows 7, 8, 8.1).

@ carlkl
Die Conda packten Python tatsächlich wirft sich in die DLL - Suchpfad Auflösung (die - unverändert - vermutlich der Grund wäre , warum Sie es sagen kann nie Arbeit unter Windows 10), und dies ist AFAICT auch der Grund , warum Conda ein _does_ bieten ucrtbase.dll , wie @jenshnielsen schreibt.

@ h-vetinari, in der universellen CRT-Bereitstellung heißt es eindeutig:

_ Bei der lokalen Bereitstellung sind zwei Einschränkungen zu beachten:
Unter Windows 10 wird immer die universelle CRT im Systemverzeichnis verwendet, auch wenn eine Anwendung eine anwendungslokale Kopie der universellen CRT enthält. Dies gilt auch dann, wenn die lokale Kopie neuer ist, da die universelle CRT eine Kernkomponente des Betriebssystems unter Windows 10._ ist.

Übrigens: Ich habe es selbst getestet. Es gibt keine Möglichkeit, ein anderes UCRT als das mit UC 10 bereitgestellte verfügbare UCRT zu laden.

Ich denke auch, dass es vernünftig ist, das Update zu veröffentlichen

Damit meine ich, dass Sie PR gh-17547 hinzufügen?

Beweis von @carlkls Punkt:

image

Dieser von MS selbst verursachte Fehler sollte als Heisenbug bezeichnet werden . Es war kostspielig und schwierig, die Ursache zu finden: Windows 2004 UCRT fmod lässt die FPU-Register unter bestimmten Umständen in einem verpfuschten Zustand. Dies kann viel später zu numerischen Berechnungsfehlern führen, wenn die FPU erneut verwendet wird. Berechnungsfehler werden normalerweise nicht in Benutzercodes angezeigt, wenn sie nicht streng getestet werden. Dies kann dazu führen, dass signifikante numerische Fehler lange Zeit unentdeckt bleiben. Es könnte kaum schlimmer sein.

Damit meine ich, dass Sie PR gh-17547 hinzufügen ?

Entschuldigung, ich habe das Falsche geschrieben.

Die einzige Änderung, die ich vorschlage, ist, dass NumPy in der beim Import ausgelösten Ausnahme weitere Informationen bereitstellt, die darauf hinweisen, wie ein Benutzer unter Windows 2004 / H2 eine Umgebung erhalten kann, in der er seinen Job / seine Schule / sein Hobby fortsetzen kann.

  1. WSL
  2. conda / begeistert
  3. 1.19.3
  4. Aus der Quelle erstellen

[Diese Bestellung ist meine Präferenz für die Qualität der Lösung]

Ich denke, es wäre auch sinnvoll, auf dieses Problem oder auf ein etwas saubereres Problem zu verweisen, das eine tiefere Erklärung bietet. Dieser zweite Link könnte auch auf einige Versionshinweise in den Dokumenten und nicht auf ein Github-Problem verweisen.

Die von conda-forge gepackten Builds ermöglichen das Auswechseln der Implementierung von blas / lapack (von openblas / mkl / blis / netlib), es muss kein MKL sein.

@ h-vetinari Bauen conda-forge + OpenBLAS die Tests für 2004 / H2?

Ich habe gerade OpenBlas 0.3.12 überprüft und Coda-Forge-Schiffe. Stürzt dieser Container dann ab?

Die Verwendung der Methode zur Heilung des FPU-Status mit der Anweisung EMMS in OpenBLAS-0.3.12 sollte natürlich helfen, die Numpy- und Scipy-Tests sauber zu halten, aber wie @charris sagte, wird fmod(0,x) in aufgerufen CPython- und dann FPU-Anweisungen, die später aufgerufen werden (in einem anderen Paket als OpenBLAS), können ebenfalls vorkommen. In diesem Fall wird das Problem nur an eine andere Stelle verschoben.

Die beste Wette ist in der Tat, MS zu zwingen, dieses fehlerhafte Verhalten zu korrigieren. Vielleicht kann Steve Dower helfen?

Dies könnte auch eine interessante Geschichte für Agner Fog oder vielleicht Bruce Dawson sein: Siehe diese verwandte Geschichte in seinem Blog:
Alles Alte ist wieder neu und ein Compiler-Bug

Wahrscheinlich der Fehler in OpenBlas 0.3.12. Beachten Sie die Spalte Private Bytes:

image

Dies ist wahrscheinlich standardmäßig 24 BLAS-Threads, da ich 24 logische CPUs habe.

Dies ist OpenBLAS 0.3.12 mit NumPy 1.19.2 von conda-forge.

Das Setzen von $env:OPENBLAS_NUM_THREADS=1 führt zu einer dramatischen Reduzierung

image

Und mit $env:OPENBLAS_NUM_THREADS=4 Threads:

image

@bashtage :

@mattip Ich habe versucht festzustellen, ob conda + OpenBLAS eine glaubwürdige Alternative ist. Ich denke nicht, dass es irgendetwas löst, was 1.19.3 löst, wenn man diese Ergebnisse gesehen hat.

@bashtage : Beweis von @carlkls Punkt:

Da die in Conditiona verpackte Python die Standard-DLL-Auflösung von Windows aktiv umgeht, bin ich mir nicht sicher, wie sicher ein Windows-Tool sein wird. Ich habe dieses Problem beispielsweise bei veralteten libcrypto.dll in C:\Windows\System32 festgestellt , siehe z https://github.com/conda-forge/staged-recipes/pull/11452. Kurz gesagt, die veraltete Systembibliothek wurde nur durch einen Testfehler in der Testsuite cryptography aufgegriffen, und dann konnte - unter Verwendung von CONDA_DLL_SEARCH_MODIFICATION_ENABLE - die Verwendung des von conda bereitgestellten openssl erzwungen werden.

@bashtage : @ h-vetinari Führen conda-forge + OpenBLAS die bestandenen Tests für 2004 / H2 durch?

Das CI, das die Pakete erstellt, basiert vermutlich nicht auf einer solchen aktuellen Version, und ich habe ein bisschen gebraucht, um es selbst zu erstellen. Ich arbeite derzeit auf einer Maschine von 2004 und dies ist das - sehr positive - Ergebnis **:

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

@bashtage : Ich habe gerade die OpenBlas 0.3.12-Schiffe überprüft und bedingt. Stürzt dieser Container dann ab?

conda-forge wird nicht mit einer festen openblas-Version ausgeliefert - die blas-Version kann sogar "hotswapped" sein (z. B. zwischen openblas, mkl, blis), daher ist die Version kein Problem. Im Allgemeinen wird jedoch die neueste Paketversion verwendet. Ich kann nicht überprüfen, ob sich der Absturz in Containern reproduziert oder nicht.

@bashtage :: @mattip Ich habe versucht festzustellen, ob conda + OpenBLAS eine glaubwürdige Alternative ist. Ich denke nicht, dass es irgendetwas löst, was 1.19.3 löst, wenn man diese Ergebnisse gesehen hat.

Der Speicheranstieg war auf eine Änderung von openblas 0.3.12 zurückzuführen, wie in xianyi / OpenBLAS # 2970 weiter erläutert. Bisher scheint mir conda-forge eine glaubwürdige Alternative zu sein - zumindest ist sie nicht direkt vom Fehler betroffen.

** Ich habe den aktuellen Master von https://github.com/conda-forge/numpy-feedstock verwendet , der noch auf 1.19.2 ist, zusammen mit openblas 0.3.12. Ich könnte auch https://github.com/conda-forge/numpy-feedstock/pull/210 + openblas 0.3.12 ausprobieren, wenn die Leute interessiert sind.

In guten Nachrichten kehrte MS in das VS-Forum zurück und schlug vor, dass ein Fix bis Ende Januar 2021 veröffentlicht werden könnte. Angesichts dieses Updates denke ich, dass die einzige Frage ist, ob die Aktualisierung der Fehlermeldung, die beim Buggy-Funktion wird erkannt.

Da die in Conditiona verpackte Python die Standard-DLL-Auflösung von Windows aktiv umgeht, bin ich mir nicht sicher, wie sicher ein Windows-Tool sein wird. Ich bin auf dieses Problem gestoßen, zum Beispiel mit veralteten libcrypto.dll in C:\Windows\System32 , siehe z. B. conda-forge / inszenierte Rezepte # 11452 . Kurz gesagt, die veraltete Systembibliothek wurde nur durch einen Testfehler in der Testsuite cryptography aufgegriffen, und dann konnte - unter Verwendung von CONDA_DLL_SEARCH_MODIFICATION_ENABLE - die Verwendung des von conda bereitgestellten openssl erzwungen werden.

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

Ausgänge

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

Dies zeigt, dass bei Verwendung des alten OpenBLAS die Buggy-Funktion der aktuellen ucrt-DLL verwendet wird.

Nur openblas = 0.3.12 von conda forge bestehen Tests, dies ist jedoch dasselbe, das in NumPy 1.19.3 geliefert wurde.

Was spricht gegen eine neue Numpy-Version, die mit einem entwaffneten OpenBLAS-0.3.12 kompiliert wurde? Reduzierte Puffergröße und möglicherweise reduzierte Anzahl von Threads zur Kompilierungszeit von OpenBLAS, das für numpy verwendet wird. Dies sollte den Speicherverbrauch von OpenBLAS reduzieren und nicht nur im Docker-Testfall helfen, sondern auch Benutzern mit weniger guter Ausstattung
Windows-Boxen.

Hier aus dem https://tinyurl.com/y3dm3h86 Fehlerbericht aus Python. Zunächst einmal vielen Dank, dass Sie eine Version bereitgestellt haben, die derzeit unter Windows funktioniert (1.19.3).

Ich verstehe, dass 1.19.3 unter Linux nicht funktioniert und 1.19.4 unter Windows nicht funktioniert (solange es den Fehler gibt).

Wäre es möglich, die neueste Version auf pypi 1.19.3 für Windows und 1.19.4 für alle anderen Plattformen zu erstellen? Mit anderen Worten, löschen Sie einfach https://files.pythonhosted.org/packages/33/26/c448c5203823d744b7e71b81c2b6dcbcd4bff972897ce989b437ee836b2b/numpy-1.19.4-cp36-cp36m-win_d zur Zeit?

@luciansmith Solange die Quelle für 1.19.4 verfügbar ist, versucht pip, diese Version zu verwenden, sofern keine zusätzlichen Flags übergeben werden. Ich denke, die meisten Benutzer würden zusätzliche Flags nur übergeben, wenn sie das Problem kennen, aber dann könnten sie einfach 1.19.3 anheften.

Ich würde eine Version 1.19.5 bevorzugen, die OpenBLAS 0.3.9 unter Linux und 0.3.12 unter Windows verwendet, aber ich weiß nicht, ob dies möglich ist.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen