Numpy: Os testes de regressão polyfit e eig falham após a atualização do Windows 10 para 2004

Criado em 3 jul. 2020  ·  171Comentários  ·  Fonte: numpy/numpy

Os testes estão falhando:
FALHOU .... \ lib \ tests \ test_regression.py :: TestRegression :: test_polyfit_build - numpy.linalg.LinAlgError: SVD não ...
FALHOU .... \ linalg \ tests \ test_regression.py :: TestRegression :: test_eig_build - numpy.linalg.LinAlgError: Eigenvalues ​​...
FALHOU .... \ ma \ tests \ test_extras.py :: TestPolynomial :: test_polyfit - numpy.linalg.LinAlgError: SVD não convergiu i ...

com exceções:

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

e

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

Passos dados:

  • Crie uma VM
  • Instale o Windows 10 mais recente e atualize para a versão mais recente 2004 (10.0.19041)
  • Instale Python 3.8.3
  • pip install pytest
  • pip install numpy
  • pip install hypothesis
  • execute testes no pacote

O mesmo acontece problema acontece ao executar testes no repositório.

Versão 1.19.0 do numpy

Estou faltando alguma dependência? Ou é apenas o Windows ficando maluco?

00 - Bug 32 - Installation

Comentários muito úteis

Combinamos uma atualização para OpenBLAS v0.3.12 e uma compilação local usando essa versão + atualização do Windows 2004 passa no conjunto de testes.

Todos 171 comentários

Edit: Você obviamente está usando pip.I também tive um resultado estranho no Windows AMD64 no passado recente com bibliotecas de álgebra linear e decomposições de autovalor (no contexto de execução de teste para modelos de estatísticas).

Se você tiver tempo, tente usar Python e pip de 32 bits e veja se você tem os mesmos problemas. Não consegui vê-los em janelas de 32 bits, mas eram repetíveis em janelas de 64 bits.

Se eu usar o conda, que vem com o MKL, não tenho os erros.

Editar: Eu também os vejo ao usar o NumPy 1.18.5 no Windows AMD64.

os testes falham após a última atualização do Windows 10

Os testes estavam falhando antes da atualização?

Sem @charris , antes da atualização, o conjunto de testes simplesmente passa.

@speixoto Você sabe qual atualização foi especificamente? Eu estaria interessado em ver se isso resolve meu problema com rodas instaladas com pip.

A atualização 1809 (10.0.17763) não estava causando nenhuma falha no teste @bashtage

1909 não estava causando nada também. Só começou a acontecer em 2004.

Não estou 100% convencido de que é 2004 ou algo depois. Acho que 2004 funcionou.

FWIW Não consigo reproduzir essas falhas no CI (Azure ou appveyor), mas faço isso localmente em 2 máquinas que são AMD64 e atualizam em 2004.

Algum de vocês já tentou ver se os conseguiu no Python de 32 bits?

Parece que houve vários problemas relatados na atualização de 2004. Talvez isso deva ser relatado também?

Acabei de executar o seguinte na nova instalação de 1909 e 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

Em 1909, sem falhas. Em 2004, 30 falhas, todas relacionadas a funções de álgebra linear.

Quando eu executo testes em 2004 em um depurador, noto que a primeira chamada para uma função geralmente retorna com resultado incorreto, mas chamar novamente produz o resultado correto (que permanece correto se repetidamente chamado). Não tenho certeza se esta é uma informação útil para adivinhar uma causa.

As versões anteriores do NumPy também apresentam problemas? Presumo que você esteja executando o 1.19.0.

Usando pip + 1.18.4 e scipy 1.4.1, obtenho o mesmo conjunto de erros.

São muito comuns:

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

Quando executo usando 1.18.5 + MKL, não recebo erros. É difícil dizer se isso é provavelmente um bug do OpenBLAS ou do Windows. Provavelmente o último, mas será realmente difícil de chegar e o diagnóstico está além de minhas capacidades para depuração de baixo nível.

Na mesma máquina física, quando executo o Ubuntu usando pacotes pip, não vejo erros.

Este é o comportamento mais estranho. Falha na primeira chamada, funciona na segunda e nas subsequentes. Outro comportamento difícil de entender é que, se eu executar o teste de falha isoladamente, não vejo o erro.

svd

Uma atualização final: se eu testar usando uma compilação de origem do NumPy sem BLAS otimizado, ainda vejo erros, embora eles não sejam um conjunto idêntico.

Talvez valha a pena fazer o ping nos desenvolvedores do OpenBLAS. Isso acontece com float32 tão frequentemente quanto float64?

Quando executo um teste completo do NumPy 1.19.0, python -c "import numpy;numpy.test('full')" vejo os mesmos erros acima:

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

Eu acho que se você apenas executar o teste exclusivamente, ele deve passar se bem me lembro de fazer o ping das coisas, o que significa um comportamento ainda mais estranho.

Eu entrei na Microsoft da única maneira que sei:

https://aka.ms/AA8xe7q

Postar no caso de outras pessoas descobrirem através da pesquisa:

Os usuários do Windows devem usar Conda / MKL se em 2004 até que isso seja resolvido

Aqui está um pequeno exemplo de reprodução:

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)

Produz

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

O LAPACK conta de 0 ou 1? Todos os valores ilegais parecem ser inteiros:
DGEBAL
DGEHRD
DORGHR
DHSEQR

Parece mais um problema do OpenBlas (ou algo entre 2004 e o OpenBLAS). Aqui está meu resumo:

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

  • Sem BLAS otimizado: passe completo
  • OpenBLAS: Falha completa
  • MKL: Passe total

modelos estatísticos testando pytest statsmodels

  • Pip NumPy e SciPy: falha relacionada ao código SVD e QR relacionado
  • MKL NumPy e SciPy: Pass
  • Nenhum BLAS otimizado: falha , mas menos que todos envolvam scipy.linalg rotinas, que usam OpenBLAS.
  • Sem BLAS otimizado, sem SciPY linalg: Pass

Seria bom saber o que mudou em 2004. Talvez precisemos de um sinalizador diferente ao compilar / vincular a biblioteca?

_Se_ for um bug do OpenBLAS, é improvável que eles o tenham visto, pois nenhum dos CIs baseados em Windows está usando a compilação 19041 (também conhecida como Windows 10 2004) ou posterior.

Só para ficar claro, é verdade que nenhum desses relatórios envolve a WSL?

Não. Todos com python.exe fornecido por conda ou python.org fornecido python.exe

O teste falha se a variável de ambiente OPENBLAS_CORETYPE=Haswell ou OPENBLAS_CORETYPE=NEHALEM é explicitamente definida?

Tentei Atom, SandyBridge, Haswell, Prescott e Nehalem, todos com resultados idênticos.

O mais estranho é que se você correr

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)

a segunda (e quaisquer outras) chamadas para eig bem-sucedidas.

SciPy tem um erro semelhante em

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) 

o que aumenta

 ** On entry to DGEBAL parameter number  3 had an illegal value
 ** On entry to DGEHRD  parameter number  2 had an illegal value
 ** On entry to DORGHR DORGQR parameter number  2 had an illegal value
 ** On entry to DHSEQR parameter number  4 had an illegal value
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-58-8dfe8125dfe3> in <module>
      4 a.shape = (13, 13)
      5 a = a % 17
----> 6 va, ve = scipy.linalg.eig(a)

c:\anaconda\envs\py-pip\lib\site-packages\scipy\linalg\decomp.py in eig(a, b, left, right, overwrite_a, overwrite_b, check_finite, homogeneous_eigvals)
    245         w = _make_eigvals(w, None, homogeneous_eigvals)
    246
--> 247     _check_info(info, 'eig algorithm (geev)',
    248                 positive='did not converge (only eigenvalues '
    249                          'with order >= %d have converged)')

c:\anaconda\envs\py-pip\lib\site-packages\scipy\linalg\decomp.py in _check_info(info, driver, positive)
   1348     """Check info return value."""
   1349     if info < 0:
-> 1350         raise ValueError('illegal value in argument %d of internal %s'
   1351                          % (-info, driver))
   1352     if info > 0 and positive:

ValueError: illegal value in argument 4 of internal eig algorithm (geev)

Nota final, a conversão para np.complex128 também aumenta, enquanto a conversão para np.float32 ou np.complex64 funcionam sem problemas.

Partes Python do código compiladas com inteiros longos, mas OpenBLAS construído sem INTERFACE64 = 1 nas partes do fortran (LAPACK)?
(Isso ainda não explicaria por que a primeira chamada falha, mas todas as subsequentes são bem-sucedidas, nem por que funcionou antes da atualização 19041)

Os usuários do Windows 10 podem votar a favor desse problema no Centro de Feedback da Microsoft.

https://aka.ms/AA8xe7q

A pedido de @bashtage , eu

a conversão para np.complex128 também aumenta, enquanto a conversão para np.float32 ou np.complex64 funcionam sem problemas.

A primeira mensagem de aviso (que não parece aparecer em caso de sucesso) "Na entrada do parâmetro DGEBAL número 3 tinha um valor ilegal" é causada por esta condição https://github.com/xianyi/OpenBLAS/blob/ce3651516f12079f3ca2418aa85b9ad571c3a391/lapack -netlib / SRC / dgebal.f # L336 que pode ser causado por qualquer número de cálculos anteriores indo para NaN.

Brincando com as etapas de reprodução, descobri que fazer o mod como float32 "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)

Então, meu palpite é que há algo nesse caminho de código que está redefinindo o estado corretamente, embora eu não tenha certeza do que seja. Esperançosamente, alguém mais familiarizado com as partes internas do numpy pode saber onde isso pode estar acontecendo.

Meio que me lembra de um bug antigo que vimos com o mingw no WIndows, onde a configuração do registro de ponto flutuante não era herdada por threads de trabalho, fazendo com que os denormais não chegassem a zero e, às vezes, bagunçassem os cálculos subsequentes.
Não tenho certeza se isso é de alguma forma relevante para o Windows atual no hardware atual, mas pode ser interessante saber se o seu
A construção do OpenBLAS foi feita com CONSISTENT_FPCSR = 1 (ou se adicionar essa opção de construção ajudar).

@mattip Você sabe se CONSISTENT_FPCSR = 1 na compilação do OpenBLAS?

Bem, pelo menos isso está fora do caminho então. a conexão parecia bastante remota de qualquer maneira.

Oi! Eu tenho experimentado um problema semelhante há algum tempo e todos os meus testes apontam para algo suspeito entre o Windows 10 (2004) e o OpenBlas. Eu geralmente executo meus programas em 3 PCs (2 estações de trabalho Windows 10 e um laptop Windows 7 mais antigo). Meus scripts python começaram a apresentar problemas de comportamento com erros relacionados à convergência linalg e svd () na época em que atualizei minhas 2 estações de trabalho para a versão 2004 do Windows 10. Também tive travamentos na primeira vez que executei o script, mas na maioria das vezes trabalhou em uma segunda tentativa (executando notebooks Jupyter). O antigo laptop continuou rodando os mesmos programas sem erros! Eu tenho miniconda, python 3.6 e todos os pacotes são instalados usando pip (o env é exatamente o mesmo nas 3 máquinas).
Hoje, removi a instalação padrão do pip numpy (1.19.0) e instalei a versão numpy + mkl (numpy-1.19.1 + mkl-cp36-cp36m-win_amd64.whl) de https://www.lfd.uci.edu/ ~ gohlke / pythonlibs /. Até agora, os erros relacionados à convergência linalg e svd () desapareceram. Se eu encontrar algo mais, voltarei aqui e relatarei.

Dário

É estranho que a dll do OpenBLAS esteja sendo criada pela versão VC9 do lib.exe? Esta é a versão que foi usada com Python 2.7. Pode não importar, mas parece estranho, visto que o VC9 não é usado em lugar nenhum.

O próximo passo para alguém (talvez eu) seria construir o mestre NumPy com um OpenBLAS de thread único ( USE_THREAD=0 ) para ver se isso corrige os problemas.

Eu tentei alguns experimentos sem sucesso:

  • Desativar tópicos USE_THREADS=0
  • ILP64 INTERFACE64=1 <- Segfault no teste de NumPy com violação de acesso

Você pode executar a suíte de testes LAPACK com essa configuração Win10? Eu havia consertado recentemente a compilação do cmake para produzi-lo, talvez ele forneça alguma pista sem qualquer envolvimento.

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

Embora eu veja muitas linhas como

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

portanto, não tenho certeza se eles são confiáveis.

Parece que a maioria dos testes são segfaulting, mas os sobreviventes são perfeitos ... isso é um pouco mais extremo do que eu esperava.
(O COMPLEX e o COMPLEX16 são um pouco exigentes em termos de tamanho de pilha, portanto, as falhas são muito mais prováveis ​​com as configurações padrão do sistema operacional, mas REAL e DOUBLE normalmente mostrariam cerca de 1200000 testes executados. Isso me faz pensar se o MS mudou algo em relação à pilha padrão limite ou layout embora)

Alguns antecedentes. Tudo está sendo construído com gcc.exe / gfortran.exe. Eles são usados ​​para produzir um arquivo .a, que é então compactado em uma DLL. Especificamente:

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

Eu realmente acho que o problema está na transferência entre o NumPy e o OpenBLAS. Não consigo imaginar de que outra forma esse comportamento poderia ocorrer onde a primeira chamada é um erro, mas a segunda e as subsequentes estão bem. Como resolver isso (ou a TBH até mesmo diagnosticar com precisão o problema profundo) embora ...?

Abolir a plataforma MS e viver feliz para sempre? Se falhar nos testes de lapack, o problema de transferência está entre Fortran (= parte LAPACK do OpenBLAS) e C, ou Fortran e "qualquer outra coisa".

Eu ficaria curioso se é possível construir o Numpy com OpenBLAS usando icc
e verifique se o problema persiste. Essa é uma grande pergunta.

Na quarta-feira, 12 de agosto de 2020, 19:04 Martin Kroeker [email protected] escreveu:

Abolir a plataforma MS e viver feliz para sempre? Se falhar no
lapack testa se o problema de transferência está entre Fortran (= parte LAPACK de
OpenBLAS) e C, ou Fortran e "qualquer outra coisa".

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/numpy/numpy/issues/16744#issuecomment-673026759 ou
Cancelar subscrição
https://github.com/notifications/unsubscribe-auth/ABKTSRLSHZ2XWF4OE7J3QO3SALKSJANCNFSM4OP5IXNQ
.

Provavelmente seria suficiente apenas construir OpenBLAS com os compiladores Intel (embora isso pareça ser bastante problemático, pelo menos com o VS do que surgiu recentemente, e eu não tenho uma licença válida para ifc / ifort no momento.

Os usuários do Windows devem usar Conda / MKL se em 2004 até que isso seja resolvido

@bashtage Obrigado por sua sugestão.
No meu caso, recebi um erro ao usar sqlite usando por pandasql após aplicar a versão Conda do numpy.

mas não tenho nenhum problema quando uso esta versão do numpy + mkl .

@bashtage , parece que há um novo pré-lançamento do MSVC com uma correção para o problema de ferrugem. Vale a pena tentar?

Para sua informação: problema relacionado ao SciPy: https://github.com/scipy/scipy/issues/12747

Há um relatório de que o Windows build 17763.1397 (11 de agosto) corrige o problema, consulte # 17082.

Há um relatório de que o Windows build 17763.1397 (11 de agosto) corrige o problema, consulte # 17082.

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

Compilação 17763.1397 é apenas para Windows 10, versão 1809 (aplica-se a: Windows 10, versão 1809, todas as ediçõesWindows Server versão 1809Windows Server 2019, todas as edições).
Não há problemas neste caso para o Windows 10, versão 1809.

Esta é a versão de atualização recente do Windows 10, versão 2004.
https://support.microsoft.com/en-us/help/4566782
11 de agosto de 2020 - KB4566782 (OS Build 19041.450).

Ainda tenho o mesmo problema no Windows 10, versão 2004

image

Mesmas falhas em 19042.487 (este é o ramal 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)

Posso reproduzir as falhas (parciais) no teste lapack do OpenBLAS - afetando apenas os testes EIG (autovalor), que são conhecidos por terem alguns requisitos de tamanho de pilha excepcionalmente altos. Lá, o SIGSEGV ocorre em __chkstk_ms_ que é inserido antes mesmo de main (). Dobrar os valores padrão de "tamanho reservado da pilha" e "tamanho de confirmação da pilha" do respectivo executável com o utilitário peflags (por exemplo, peflags -x4194304 -X4194304 EIG/xeigtsts.exe ) faz os programas funcionarem normalmente, sugerindo que a interação C / Fortran e a passagem de argumentos como tal é não problemático. Eu ainda não tentei aplicar isso ao caso numpy (não tenho certeza mesmo de qual configuração peflag ajustar lá - python.exe?), Mas o próprio OpenBLAS parece funcionar normalmente quando construído com a versão msys2 mingw64 do gcc 9.1.0 em 19041.450 aka 2004

@ martin-frbg Isso parece progresso.

Desceu por uma toca de coelho tentando obter todas as dependências instaladas para a construção numpy no Windows / MSYS2 para que nenhum progresso posterior.

@ martin-frbg, o pacote numpy baseado em Msys2 pode ser instalado com o pacman. Os scripts de compilação e patches do Msys2 estão disponíveis aqui: https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-python-numpy e https://github.com/msys2/MINGW-packages/tree / master / mingw-w64-openblas.

Em uma última reunião de triagem, isso surgiu como uma prioridade relativamente alta, e @hameerabbasi e eu estamos dispostos a ajudar. O que podemos fazer?

@bashtage você poderia tentar aumentar a pilha com editbin /STACK:3145728 python.exe

Existe uma maneira de tentar construir o NumPy com as versões das bibliotecas do OpenBLAS em vez das que construímos? Talvez nossas construções estejam um pouco erradas.

Provavelmente seria possível substituir o libopenblas.dll em sua compilação por um criado a partir do branch develop atual ou de uma versão mais antiga como 0.3.8 ou 0.3.9 para ver se isso tem algum efeito? (Não que eu tenha qualquer compromisso específico em mente agora que possa ter alguma relação com isso). Infelizmente, ainda estou tendo erros de instalação, mesmo com os pacotes msys2, atualmente não consigo executar os testes, aparentemente devido a self.ld_version não retornar nada em uma verificação de versão.

Obrigado. Estou tentando atualizar meu windows para construir 2004, vamos ver se termino antes do fim de semana

Além disso, o "pequeno exemplo de reprodução" do bashtage em https://github.com/numpy/numpy/issues/16744#issuecomment -655430682 não levanta nenhum erro na configuração do msys2. (Pelo que eu posso dizer, seu libopenblas em mingw64 / usr / lib é um single-threaded 0.3.10 construído para Haswell)

@ martin-frbg É possível construir OpenBLAS usando MSVC?

MSVC simples? Possível, mas oferece uma biblioteca mal otimizada, pois o MSVC não suporta os kernels de montagem - praticamente o mesmo que se você construísse o OpenBLAS para TARGET = GENERIC.

Além disso, o "pequeno exemplo de reprodução" do bashtage de # 16744 (comentário) não levanta nenhum erro na configuração do msys2. (Pelo que eu posso dizer, seu libopenblas em mingw64 / usr / lib é um single-threaded 0.3.10 construído para Haswell)

Tenho certeza de que é algo a ver com a interface entre NumPy e OpenBLAS. A compilação de 32 bits do NumPy também não tem esse problema. As ideias do pessoal da Microsoft com quem conversei de que esse é provavelmente um problema de sincronização de thread parecem ser as mais plausíveis. Isso poderia explicar como o valor errado está presente na primeira chamada e, em seguida, corrigido nas chamadas subsequentes.

Desceu por uma toca de coelho tentando obter todas as dependências instaladas para a construção numpy no Windows / MSYS2 para que nenhum progresso posterior.

É uma dor. Eu fiz isso, mas automatizá-lo para tentar alguns experimentos estava demorando muito. Basicamente, é necessário copiar as etapas de https://github.com/MacPython/openblas-libs para obter os arquivos .a e, em seguida, copiar as etapas de https://github.com/numpy/numpy/blob/master/ azure-steps-windows.yml para construir o NumPy. É particularmente difícil porque algumas partes querem o MSYS2 padrão e outras precisam que ele desapareça, então você acaba instalando e desinstalando a maior parte do gcc toda vez que deseja fazer um experimento.

A maneira mais fácil de obter uma construção de DLL é abrir uma conta appveyor e, em seguida, clonar https://github.com/MacPython/openblas-libs. No final de sua construção, há um artefato que você pode encontrar no site para fazer o download, que contém a dll (e o arquivo .a). No entanto, isso é lento, levando 3 horas para construir todas as 3 versões.

Olhando para https://github.com/MacPython/openblas-libs , OpenBLAS parece ter sido construído com INTERFACE64=1 . Este não é o caso para Msys2 build OpenBLAS e numpy.

@carlkl Este problema não é sobre a compilação Msys2 do NumPy ou OpenBLAS. É sobre a construção Win32 / AMD64 que faz uso do gfortran fornecido pelo Msys2 para compilar fontes do fortran, mas então constrói uma DLL Win32 a partir da biblioteca compilada usando o lib.exe do MS.

@bashtage Mencionei isso, porque foi relatado https://github.com/numpy/numpy/issues/16744#issuecomment -689785607, que o segfault não pôde ser reproduzido no msys2. E eu acho que o ambiente msys2 mencionado contém os pacotes binários openblas e numpy fornecidos por msys2.

Não tenho ideia, se o numpy de 64 bits do windows é compilado com uma bandeira semelhante com MSVC ou não.

BTW: Não consigo encontrar o sinalizador -fdefault-integer-8 no repositório scipy.
Não tenho certeza se o código compilado com -fdefault-integer-8 é compatível com ABI com o código compilado sem este sinalizador.

Outro aspecto me vem à mente: talvez -fdefault-integer-8 deva ser combinado com -mcmodel=large .

EDIT: Lembre-se: o Windows64 tem um modelo de memória LLP64, não ILP64.
LLP64 significa: longo: 32 bits, ponteiro: 64 bits

Então, que tamanho inteiros a compilação numpy que experimenta o problema Win10-2004 usa? É melhor que corresponda ao que o OpenBLAS foi desenvolvido, mas esse tópico do IIRC já foi abordado anteriormente neste tópico (e uma incompatibilidade provavelmente levaria a uma quebra mais pronunciada, independentemente do nível de patch do Windows)

Pelo menos Openblas pode ser construído em três variantes com https://github.com/MacPython/openblas-libs (consulte appveyor.yml):

  • 32 bits
  • 64 bits
  • 64 bits com INTEGER64

mas se não tiver ideia do que é usado para as compilações de 64 bits no windows.

_e uma incompatibilidade provavelmente levaria a uma quebra mais pronunciada, independentemente do nível de patch do Windows_

-fdefault-integer-8 só se aplica à parte fortran do Lapack. Ele não muda o modelo de memória subjacente (LLP64), então não tenho certeza se devemos esperar problemas fora das peças Fortran Lapack.

Hmm,

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

- job: Windows pool: vmImage: 'VS2017-Win2016' ... Python38-64bit-full: PYTHON_VERSION: '3.8' PYTHON_ARCH: 'x64' TEST_MODE: full BITS: 64 NPY_USE_BLAS_ILP64: '1' OPENBLAS_SUFFIX: '64_'
todas as outras versões ( Python36-64bit-full , Python37-64bit-full ) são compiladas sem NPY_USE_BLAS_ILP64.

Os binários do Numpy em pypi.org são todos construídos com openblas inteiros de 32 bits. https://github.com/MacPython/numpy-wheels/blob/v1.19.x/azure/windows.yml

Para obter detalhes sobre o processo de compilação gfortran vs. MSVC, consulte aqui . O lib.exe da Microsoft não está envolvido na produção da DLL openblas, é toda uma cadeia de ferramentas mingw. O Numpy usa o arquivo openblas.a e gera a DLL usando o gfortran. https://github.com/numpy/numpy/blob/74712a53df240f1661fbced15ae984888fd9afa6/numpy/distutils/fcompiler/gnu.py#L442 As ferramentas MSVC são usadas para produzir o arquivo .lib a partir do arquivo .def e o código Numpy C compilado com o MSVC está vinculado usando esse arquivo .lib à DLL produzida pelo gfortran.

Uma possibilidade teórica de que pode dar errado é se houver algum tipo de incompatibilidade de versão do mingw entre o mingw que produziu o artefato openblas.a estático e a versão do mingw usada quando o numpy é construído. No entanto, não tenho certeza se isso pode causar problemas.

choco install -y mingw --forcex86 --force --version=5.3.0 usados ​​em windows.yml parecem estar desatualizados. Por que não usar 7.3.0 ou 8.1.0 ? Lembro-me de problemas que tive com o gcc-5.x há dois ou três anos.

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

Isso é apenas para a construção do Windows de 32 bits, então provavelmente não está relacionado a esse problema.

todas as outras versões ( Python36-64bit-full , Python37-64bit-full ) são compiladas sem NPY_USE_BLAS_ILP64.

Mesmos erros no Python 3.6 e 3.8.

Resta uma ideia (estou cavando no escuro):

OpenBLAS agora está compilado com -fno-optimize-sibling-calls , consulte https://github.com/xianyi/OpenBLAS/issues/2154 , https://github.com/xianyi/OpenBLAS/pull/2157 e https: // gcc .gnu.org / bugzilla / show_bug.cgi? id = 90329.
Editar: veja também: https://gcc.gnu.org/legacy-ml/fortran/2019-05/msg00181.html

Numpy não aplicou este sinalizador em sua parte gfortran de distutils. Eu sei que o numpy é compilado com MSVC. Portanto, eu esperaria problemas com scipy em vez de numpy, então esta pode ser uma viagem errada.

Os binários do Numpy em pypi.org são todos construídos com openblas inteiros de 32 bits. https://github.com/MacPython/numpy-wheels/blob/v1.19.x/azure/windows.yml

Por que as configurações de compilação usadas no teste são diferentes das usadas na versão? Isso soa como um risco.

Podemos adicionar artefatos às compilações do Azure? Isso tornaria muito mais simples obter rodas para teste. Minha única preocupação aqui é que o limite de artefato livre é muito pequeno, IIRC, 1 GB, e não sei o que acontece quando você o atinge (FIFO seria bom, mas pode fazer outras coisas, incluindo erro).

Por que as configurações de compilação usadas no teste são diferentes das usadas na versão?

Testamos todas as versões de python com suporte no Windows sem NPY_USE_BLAS_ILP64 e também testamos o python 3.8 com NPY_USE_BLAS_ILP64 , consulte https://github.com/numpy/numpy/blob/v1.19.2/azure -pipelines.yml # L195. Portanto, as compilações semanais estão corretas no uso de openblas inteiros de 32 bits.

Podemos adicionar artefatos às compilações do Azure?

Provavelmente fácil de tentar isso e descobrir sobre os limites se houver erros. No entanto, as rodas semanais são destinadas a recriar fielmente as compilações de teste. Quaisquer discrepâncias devem ser tratadas como erros e corrigidas.

Provavelmente fácil de tentar isso e descobrir sobre os limites se houver erros. No entanto, as rodas semanais são destinadas a recriar fielmente as compilações de teste. Quaisquer discrepâncias devem ser tratadas como erros e corrigidas.

Eu estava pensando que seria mais fácil experimentar em um PR para o repo principal e pegar o artefato para testar em 2004.

Faz sentido.

Você pode ativar os pipelines do Azure em seu repo bashtage / numpy

Um pouco mais de informação: a primeira chamada que falha é porque DNRM2 dentro do OpenBLAS retorna um NAN. Para mim, isso é repetível: cada chamada para

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

imprime ** On entry to DGEBAL parameter number 3 had an illegal value , que é outra maneira de dizer " DNRM2 NAN devolvido". A operação mod é crítica, sem ela a chamada a eig não exibe este erro.

Como poderia haver alguma interação entre o mod ufunc e a chamada para OpenBLAS?

A operação mod é crítica, sem ela a chamada a eig não exibe este erro.

Construir exatamente a mesma matriz manualmente, de forma repetitiva, aciona o erro?

Este código não aciona a falha:

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

O mod anterior poderia deixar um registro em um estado indefinido? Eu não verifiquei o nrm2.S novamente, mas acho que tivemos alguns problemas anos atrás desde a montagem XORing um registro com ele mesmo para limpá-lo, que falharia no NaN.

Para aqueles que estão acompanhando, float64 % acaba chamando npy_divmod para cada valor.

... que, na primeira linha chama npy_fmod() , que é fmod () . Aqui estão algumas mudanças que tentei. "Erro" significa que recebo a mensagem de "valor ilegal" do OpenBLAS ao executar o código que chama a % 17; np.linalg.eig(a)
código | resultado
--- | ---
mod = npy_fmod@c@(a, b); (código original) | Erro
mod = 100; //npy_fmod@c@(a, b); | Sem erro
mod = npy_fmod@c@(a, b); mod = 100.0; | Erro

Portanto, parece que fmod do MSVC está fazendo algo que confunde o OpenBLAS.

Isso é interessante e estranho.

Você pode usar uma versão ingênua (não fornecida pela plataforma) do fmod para ver se isso corrigiu?

Ou apenas force HAVE_MODF a 0 .

Acho que não temos uma versão ingênua do fmod, temos?

Vejo que há uma macro HAVE_MODF, mas para onde esse caminho leva?

Parece que volta para a versão dupla se float e double long estão faltando. A versão dupla é obrigatória para construir numpy. O undef é provavelmente para evitar funções embutidas do compilador, ISTR que isso era um problema no Windows há muito tempo.

Eu queria "provar" que o problema é a implementação de fmod , que vem de ucrtbase.dll . Então, escrevi uma pequena solução alternativa que usa ctypes para extrair a função da dll e usá-la em vez de chamar diretamente fmod . Os testes ainda falham. Então eu mudei para uma versão mais antiga de ucrtbase.dll (apenas para a função fmod ). Os testes passam. Abri um tópico no fórum do Visual Studio . Se alguém souber a melhor maneira de entrar em contato com a Microsoft, isso seria ótimo.

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

E se você adicionar algum código após a chamada de fmod, de forma que ST(0) não contenha nan? Ou configurá-lo para nan sinteticamente?
As convenções de chamada impõem algumas restrições sobre como esses registradores devem se comportar?

Eu queria "provar" que o problema é a implementação de fmod , que vem de ucrtbase.dll . Então, escrevi uma pequena solução alternativa que usa ctypes para extrair a função da dll e usá-la em vez de chamar diretamente fmod . Os testes ainda falham. Então eu mudei para uma versão mais antiga de ucrtbase.dll (apenas para a função fmod ). Os testes passam. Abri um tópico no fórum do Visual Studio . Se alguém souber a melhor maneira de entrar em contato com a Microsoft, isso seria ótimo.

No mínimo, qualquer pessoa com uma conta azul, o que provavelmente é muitas pessoas aqui, pode votar a favor. Vou entrar em contato com alguns contatos que fiz quando esse problema apareceu originalmente que trabalham no Azure ML para ver se eles podem fazer alguma coisa.

No mínimo, qualquer pessoa com uma conta azul, o que provavelmente é muitas pessoas aqui, pode votar a favor.

Obrigado pela dica, voto positivo!

Acho que não temos uma versão ingênua do fmod, temos?

Não. É uma função complicada exigida pela especificação IEEE-754 para ter certo comportamento. Também é muito lento, o que provavelmente está relacionado às especificações.

O trabalho árduo de fmod é realizado pela instituição fprem x87, mesmo na variante VS2019 - consulte a essência de @mattip (última linha) https://gist.github.com/mattip / d9e1f3f88ce77b9fde6a285d585c738e. ( fprem1 é a remainder variante aliás.)

Deve-se ter cuidado quando usado em conjunto com registros MMX ou SSE - conforme descrito aqui: https://stackoverflow.com/questions/48332763/where-does-the-xmm-instruction-divsd-store-the-remainder.

Existem algumas implementações alternativas disponíveis, conforme descrito em https://github.com/xianyi/OpenBLAS/issues/2709#issuecomment -702634696. No entanto: todos eles precisam do gcc (mingw-w64) para compilação. OpenLIBM não compila com MSVC AFAIK. E código assembler embutido não é permitido com MSVC. Em princípio, pode-se construir (mingw-w64) e usar (MSVC) uma biblioteca auxiliar fmod durante a compilação numpy.

E se você adicionar algum código após a chamada fmod, de modo que ST (0) não contenha nan? Ou configurá-lo para nan sinteticamente? As convenções de chamada impõem algumas restrições sobre como esses registradores devem se comportar?

Acho que poderíamos adicionar um pequeno pedaço de montagem para limpar os registros antes de chamar o OpenBLAS no Windows. Eu tentei fazer isso em uma pequena configuração de teste, mas meu masm assembly foo está fraco. Tentei escrever um procedimento que apenas chama fldz várias vezes, ao usá-lo recebo uma exceção. Socorro?

Em lots_of_fldz.asm :

.code
lots_of_fldz proc
    fldz
    fldz
    fldz
    fldz
    fldz
    fldz

lots_of_fldz endp
end

Em outro arquivo:

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

Coloque-os em um projeto VisualStudio e siga este guia para ativar a compilação de masm

@mattip , criei um arquivo assembler para a função fmod de 64 bits que cria um segmento text: idêntico conforme encontrado na função fmod de mingw-w64 (64 bits). Não tenho ideia se isso funciona como um substituto para a função fmod com erros, mas pelo menos um deve tentar. O arquivo obj resultante pode ser adicionado a npymath.lib.

fmod.asm: (64 bits)

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

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

``

objdump -D fmod.obj
....
Disassembly of section .text$mn:
0000000000000000 <fmod>:
   0:   48 83 ec 18            sub    $0x18,%rsp
   4:   f2 0f 11 44 24 08      movsd  %xmm0,0x8(%rsp)
   a:   dd 44 24 08            fldl   0x8(%rsp)
   e:   f2 0f 11 4c 24 08      movsd  %xmm1,0x8(%rsp)
  14:   dd 44 24 08            fldl   0x8(%rsp)
  18:   d9 c9                  fxch   %st(1)
  1a:   d9 f8                  fprem
  1c:   9b df e0               fstsw  %ax
  1f:   9e                     sahf
  20:   7a f8                  jp     1a <fmod+0x1a>
  22:   dd d9                  fstp   %st(1)
  24:   dd 5c 24 08            fstpl  0x8(%rsp)
  28:   f2 0f 10 44 24 08      movsd  0x8(%rsp),%xmm0
  2e:   48 83 c4 18            add    $0x18,%rsp
  32:   c3                     retq

@carlkl obrigado. Eu ficaria mais feliz com um montador que redefine os registradores ST (N) que poderíamos usar em x86_64 antes de chamar as funções do OpenBLAS. Hoje esse problema surgiu por causa de uma mudança em fmod , amanhã pode ser uma função diferente. Não tenho certeza se as funções são necessárias para redefinir os registros ST(N) no retorno. Se não houver tal requisito, fmod não é realmente bugado e a mudança no Windows expôs uma falha no OpenBLAS para redefinir os registros antes de usá-los que devemos ajudá-los a corrigir ou contornar isso.

Tentei redefinir os registros usando fldz no comentário acima, mas meu programa de teste não funciona.

@mattip , meu https://stackoverflow.com/questions/19892215/free-the-x87-fpu-stack-ia32/33575875

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

Acho que também poderíamos chamar fninit no início do OpenBLAS nrm2.S (após a macro PROFCODE) para verificar essa teoria

Parte interessante do
Interface binária do aplicativo System VSuplemento de processador de arquitetura AMD64Rascunho da versão 0.99.6

_Os bits de controle do registro MXCSR são salvos pelo callee (preservados nas chamadas), enquanto os bits de status são salvos pelo chamador (não preservados) ._

_O registrador de palavra de status x87 é salvo pelo chamador, enquanto a palavra de controle x87 é salva pelo receptor._

_Todos os registros x87 são salvos pelo chamador, então chamadas que fazem uso dos registros MMX podem usar a instrução femms mais rápida.

Muito diferente em comparação com a convenção de chamada do Windows de 64 bits.

@ martin-frbg, fninit é perigoso: The FPU control word is set to 037FH (round to nearest, all exceptions masked, 64-bit precision). A precisão estendida do X87 não é a que você deseja em todos os casos, especialmente no Windows.

Eu não gostaria disso para uma versão de lançamento, apenas para um teste rápido. Ainda não estou muito convencido de que o OpenBLAS deve de alguma forma limpar "antes" de si mesmo, mas não consigo encontrar nenhuma documentação clara sobre o comportamento do Windows em relação ao x87 fpu legado. Notei que a Agner Fog tem um documento sobre convenções de chamada em http://www.agner.org/optimize/calling_conventions.pdf (a discussão sobre o manuseio do Win64 de registradores FP começa na página 13, mas se concentra na disponibilidade básica e no comportamento nas alternâncias de contexto).

Consulte https://github.com/numpy/numpy/issues/16744#issuecomment -703305582:

The x87 register stack is unused. It may be used by the callee, but consider it volatile across function calls.

Eu acho que isso significa: não use instruções x87 (Win64). Se você fizer isso, boa sorte. Ou em outras palavras: o receptor é responsável por não sofrer danos.

Hm, isso parece descrever o comportamento do compilador MSVC especificamente, enquanto eu _penso_ que estamos em um ecossistema mingw?

Não, o Numpy (Pypi) é compilado com MSVC (Visual Studio 2019) no Windows. Para OpenBLAS, mingw-w64 é usado (devido às peças Fortran). Além disso, as peças do Fortran Scipy são compiladas com o mingw-w64. No entanto, CPython e suas extensões binárias são fortemente baseadas nos padrões definidos pelo MSVC.

BTW: esta foi a razão para o desenvolvimento de https://github.com/mingwpy, que está sendo respirado de volta à vida. (plug sem vergonha)

Outra parte:

mingw-w64 usa (quase) as mesmas convenções de chamada do MSVC. As únicas diferenças notáveis ​​são o alinhamento de pilha diferente no x86 (32 bits) - relevante para SIMD e o não suportado vectorcall .

Interessante. x86 não é afetado. Apenas AMD64.

No domingo, 4 de outubro de 2020, 22:19 carlkl [email protected] escreveu:

Outra parte:

mingw-w64 usa (quase) as mesmas convenções de chamada do MSVC. O único
diferenças notáveis ​​são diferentes alinhamentos de pilha em x86 (32 bits) -
relevante para SIMD e a chamada de vetor não suportada.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/numpy/numpy/issues/16744#issuecomment-703317784 ou
Cancelar subscrição
https://github.com/notifications/unsubscribe-auth/ABKTSRMFHWZVLDYDFGBM6YDSJDRGTANCNFSM4OP5IXNQ
.

MSVC 32bit não deserdou o fpu, talvez? Vou apenas fazer uma substituição temporária do fpu-using nrm2.S por nrm2_see2.S (se for viável, infelizmente há uma série de rotinas de montagem não utilizadas, mas mortais flutuando na base de código) ou a versão C simples para OS == Windows então. (O outro problema discutido aqui tem que ser outra coisa, entretanto, como eu acho que todas as outras rotinas de montagem mais antigas para x86_64 são SSE2, pelo menos)

@mattip , talvez uma chamada para _fpreset após divmod seja suficiente para reiniciar de um estado confuso de FPU?

talvez uma chamada para _fpreset

Não, ele não zera os registradores ST(N) , nem corrige os testes com falha.

Você deu uma chance a _fninit ? Isso deve redefinir a pilha de FPU. Ou ffree ou fstp vez de fldz conforme mencionado em https://stackoverflow.com/questions/19892215/free-the-x87-fpu-stack-ia32/33575875 ?

Eu ficaria feliz em tentar os comandos do montador, mas o projeto de teste no comentário acima falha. Alguém precisa corrigir meu código para fazê-lo funcionar (de fato, fninit parece um bom candidato), então posso emitir instruções do assembler para redefinir os registros em NumPy antes de chamar o OpenBLAS.

Algo assim?

.code
reset_fpu proc
    finit
    fldz
reset_fpu endp
end

finit ist wait mais fninit . Não tenho certeza se fldz é necessário após fninit .

Como eu disse no comentário, há algo faltando para fazer a chamada para o código assembly compilado funcionar corretamente. Isso é basicamente o que eu tinha naquele comentário. O código falha com exited with code -2147483645 . Por favor, dê uma olhada no código completo e veja se você pode fazê-lo funcionar.

Eu posso tentar (amanhã). No entanto, talvez esses snippets sejam úteis:

https://www.website.masmforum.com/tutorials/fptute/fpuchap4.htm
(um dos sites mais legíveis sobre esses tópicos que encontrei)

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. 

Pelo que entendi, fldz pode falhar em segfault se st (7) estiver em uso, portanto:

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. 

você pode tentar:

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

Desculpe, não estou sendo claro. O problema imediato não é quais chamadas de assembler devem ser feitas. O problema imediato é como criar apropriadamente um procedimento chamável de uma forma que possamos usá-lo e demonstrar isso em um arquivo de dois ( *.asm e main.c / main.cpp ) projeto que compila e executa. Assim que tivermos isso, posso continuar a explorar diferentes chamadas e como elas influenciam o OpenBLAS.

@mattip , eu entendo. Com certeza vou tentar, mas pode levar algum tempo.

Tive a impressão de que o mau comportamento _tempory_ de fmod em UCRT deveria ser _recuperado_ por OpenBLAS: https://github.com/xianyi/OpenBLAS/pull/2882 e não por numpy já que numpy não usa FPU no WIN64. E, claro, a MS deve corrigir esse problema com um patch do Windows.
O patch numpy, neste caso, seria garantir o uso de uma versão do OpenBLAS durante a compilação, não mais antiga do que a próxima versão do OpenBLAS.

@matti Há uma verificação de sanidade em numpy/__init__.py . Existe um teste simples e confiável que podemos adicionar para detectar esse problema?

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

@mattip , obrigado pelo snippet. Mas vou precisar de algum tempo para ter acesso a um desktop onde poderei fazer esse tipo de testes. No momento, estou trabalhando na maior parte do tempo com um laptop com um ambiente de programação mínimo onde não consigo instalar quase nada.

Combinamos uma atualização para OpenBLAS v0.3.12 e uma compilação local usando essa versão + atualização do Windows 2004 passa no conjunto de testes.

Deixando aberto até a atualização do Windows.

As rodas de pré-lançamento foram construídas com o novo OpenBLAS? Fico feliz em fazer mais alguns testes com projetos downstream que apresentavam esse bug.

As rodas de pré-lançamento do Windows 3.9 estão ausentes porque houve erros de teste (agora corrigidos). A biblioteca fixa será usada em 1.19.3 saindo hoje ou amanhã.

A opção /MT permite links estáticos no Windows. Pode ser possível vincular estaticamente ao libucrt.lib usando a versão 1909 do Microsoft SDK. Isso poderia funcionar como uma solução alternativa para o bug ucrtbase.dll em 2004 e 20H2. Isso tornaria as rodas maiores, o que é uma desvantagem.

Não tenho ideia se este problema / MT ainda é válido, mas deve ser considerado.

Eu acho que se NumPy é o único módulo que constrói com MT, então pode ser
ESTÁ BEM. Claro, pode ser o caso de que, se NumPy for MT, então qualquer
downstream também precisaria ser MT, e isso seria um problema.

Na segunda-feira, 2 de novembro de 2020, 19:37 carlkl [email protected] escreveu:

Não tenho ideia se este problema / MT
https://stevedower.id.au/blog/building-for-python-3-5-part-two ainda é
válido, mas deve ser considerado.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/numpy/numpy/issues/16744#issuecomment-720682011 ou
Cancelar subscrição
https://github.com/notifications/unsubscribe-auth/ABKTSRJIVAQLECK4E2EVSSDSN4C65ANCNFSM4OP5IXNQ
.

Alguma solução alternativa recomendada para esse problema? Minha situação é que estou em uma máquina atualizada para a atualização de 2004 e tenho um software de desktop que usa pip para instalar numpy / scipy / pandas etc. Todo esse software é afetado por esse problema causado pela atualização da Microsoft.

Qualquer recomendação seria apreciada, porque usar o conda para instalar o numpy não é uma opção para o software em que estou trabalhando.

Se você não precisa do docker, pode fixar 1.19.3. Ele passa em todos os testes em meus sistemas Windows.

Obrigado. 1.19.3 trabalha com pip neste problema.

O link na detecção de BLAS ruim está gerando muitos posts barulhentos no site da MS. Espero que isso não acabe explodindo.

Suponho que outra alternativa seja usar um fmod de terceiros no Win64.

Eu me pergunto qual seria a resposta se o NumPy tivesse um bug não corrigido tão sério por quatro meses após o lançamento, especialmente se não fornecêssemos instruções claras para os usuários fazerem o downgrade para a versão anterior. Os usuários podem facilmente fixar em 1.19.3, mas isso não resolverá o problema, apenas irá movê-lo para outro pacote que usa os registradores depois que eles foram desordenados: talvez scipy, talvez tensorflow.

Outra ideia para uma solução alternativa: veja se há alguma outra função em ucrt que use a FPU e deixe seu estado em boas condições. Se houver, poderíamos chamá-lo após fmod. Isso teria uma vantagem sobre a solução alternativa de montagem que @mattip escreveu, uma vez que não precisaria de nenhum arquivo especial ou processo de construção.

Não acho que devemos investir mais esforços para contornar este problema. Qualquer trabalho adicional que façamos para mitigar o problema consumirá um tempo valioso do desenvolvedor e reduzirá a pressão sobre a Microsoft para corrigir isso. Além disso, como mencionado acima, qualquer código em outros projetos que chame fmod e / ou use os registradores pode ter esse problema sem conexão com NumPy.

Não acho que devemos investir mais esforços para contornar este problema. Qualquer trabalho adicional que façamos para mitigar o problema consumirá um tempo valioso do desenvolvedor e reduzirá a pressão sobre a Microsoft para corrigir isso. Além disso, como mencionado acima, qualquer código em outros projetos que chame fmod e / ou use os registradores pode ter esse problema sem conexão com NumPy.

Tendo visto a reação à mensagem de erro, é evidente que não é muito útil. Deve, por exemplo, sugerir que os usuários do Windows que desejam usar os recursos mais recentes do NumPy devem usar uma distribuição que vem com o MKL em vez do pip wheel. Ele também deve incluir um link para este tópico.

Embora seja claramente responsabilidade da MS consertar, causar dor aos usuários ao apontar a falha de outra pessoa raramente é uma boa maneira de qualquer projeto manter a boa vontade.

@bashtage Não tenho certeza do que você quer dizer sobre causar dor. Poderíamos remover o link e fazer com que os usuários chegassem aqui, mas devemos alertar os usuários de que quando eles rodarem em 2004, os resultados não serão confiáveis ​​e, se você não puder confiar nos resultados de um cálculo, deve evitar o cálculo nessa plataforma.

Não tenho certeza do que você quis dizer sobre causar dor.

A importação do NumPy falha espetacularmente e não há solução alternativa fornecida. Seria mais útil para a maioria dos usuários se a lista de soluções alternativas conhecidas estivesse claramente visível:

(a) Usando uma distribuição baseada em MKL, como conda ou Enthought Deployment Manager, que evita isso, mas em código de álgebra linear
(b) Reverter para NumPy 1.19.3 que vem com uma versão do OpenBLAS que é protegida contra o bug. Esta opção pode não ser adequada para usuários que executam em contêineres.
(c) Construir a partir da fonte. Esta opção terá BLAS de baixo desempenho, mas pode ser adequada em ambientes onde a distribuição de terceiros não é permitida e os contêineres são usados ​​ou um recurso recente ou correção de bug no NumPy é necessário.

Não acho errado chamar a atenção para o bug do fmod, mas então ele direciona os usuários para aquele fórum como se houvesse alguma solução esperando por eles.

Poderíamos remover o link e fazer com que os usuários chegassem aqui, mas devemos alertar os usuários de que quando eles rodarem em 2004, os resultados não serão confiáveis ​​e, se você não puder confiar nos resultados de um cálculo, deve evitar o cálculo nessa plataforma.

Esta não é uma opção. Os usuários só precisam evitar NumPy + OpenBLAS (ex 0.3.12). Eles não precisam evitar o NumPy + Windows (2004 / 20H2 (agora existem 2 versões lançadas afetadas)).

Distribuição baseada em MKL

Também houve um relatório de problemas com o MKL.

Reverter para NumPy 1.19.3

Mas isso não resolverá outros problemas potenciais resultantes do uso de fmod. O problema é que não há como ter certeza de que os resultados estão corretos.

As pessoas não deveriam usar Python em 2004, talvez usar WSL em vez disso? Eu também aceitaria incluir um documento mais antigo com as rodas das janelas, se isso fosse possível, mas e outros projetos? Existe uma maneira fácil de voltar às versões anteriores do Windows?

Também houve um relatório de problemas com o MKL.

NumPy não tem um teste que falhe no MKL. Parece difícil presumir que há um problema quando não há falhas relatadas. O bug do fmod não se manifesta no BLAS do MKL (provavelmente porque ele não usa FPU).

Mas isso não resolverá outros problemas potenciais resultantes do uso de fmod. O problema é que não há como ter certeza de que os resultados estão corretos.

Não, mas também não corrigirá problemas de segurança do Windows ou muitos outros bugs. A questão aqui é muito particular.

  1. fmod é bom em que é produzido resultados corretos
  2. Você precisa ter o código escrito em assembler para encontrar esse problema, pois o compilador do sistema não produzirá o código x87.

Esses dois me sugerem que o problema é muito desafiador para atingir quase todo o código. Apenas o código de desempenho mais alto, como OpenBLAS, bibliotecas FFT contendo kernels escritos à mão ou MKL, provavelmente irão acionar o # 2.

Eu também acho que é razoável liberar a correção, pois se o OpenBLAS 0.3.12 funcionasse como esperado, o NumPy teria lançado e este problema nunca teria sido levantado para os usuários.

As pessoas não deveriam usar Python em 2004, talvez usar WSL em vez disso? Eu também aceitaria incluir um documento mais antigo com as rodas das janelas, se isso fosse possível, mas e outros projetos? Existe uma maneira fácil de voltar às versões anteriores do Windows?

Suspeito que para muitos usuários esta não é realmente uma opção para muitos usuários: usuários corporativos em desktops corporativos, alunos novatos (que deveriam usar o conda) ou qualquer pessoa que comprou um laptop com 2004 ou 20H2 que não pode fazer o downgrade.

Observe que o Condas numpy não está apenas vinculado ao MLK, mas também já envia sua própria versão de ucrtbase.dll que parece ser uma versão mais antiga (10.0.17134.12)

Concordo em grande parte com @bashtage aqui, uma importação com falha sem nenhuma recomendação razoável para consertar é um pouco hostil para os usuários (apesar da falha principal ser com a microsoft).

@jenshnielsen : Observe que o

Os builds empacotados pelo conda-forge permitem a troca da implementação blas / lapack (de openblas / mkl / blis / netlib), ela não _tem_ de ser MKL.

As pessoas não deveriam usar Python em 2004, talvez usar WSL em vez disso?

Esse não é o modo de operação padrão para a maioria dos usuários.

Eu também aceitaria incluir um documento mais antigo com as rodas das janelas, se isso fosse possível, mas e outros projetos?

Outros projetos não são de nossa responsabilidade.

Existe uma maneira fácil de voltar às versões anteriores do Windows?

Se você fez uma nova instalação ou limpou o espaço em disco, torna-se quase impossível fazer isso.

Concordo em grande parte com @bashtage aqui, uma importação com falha sem nenhuma recomendação razoável para consertar é um pouco hostil para os usuários (apesar da falha principal ser com a microsoft).

Concordo. Podemos acabar perdendo muitos usuários se não corrigirmos isso.

Eu também aceitaria incluir um documento mais antigo com as rodas das janelas, se isso fosse possível, mas e outros projetos?

@charris , isso não ajudará no Windows 10. Se você implantar um ucrt diferente junto com o python ou numpy, ele nunca será carregado no Windows 10. Este método se aplica apenas a versões anteriores do Windows (Windows 7, 8, 8.1).

@carlkl
O python empacotado com conda na verdade se interpõe na resolução do caminho de pesquisa DLL (que - inalterado - provavelmente seria o motivo pelo qual você diz que ele nunca funcionará no Windows 10), e este é AFAICT também o motivo pelo qual conda _does_ fornece um ucrtbase.dll , como escreveu @jenshnielsen .

@ h-vetinari, a implantação do CRT universal afirma claramente:

_Há duas restrições à implantação local que você deve conhecer:
No Windows 10, o Universal CRT no diretório do sistema é sempre usado, mesmo se um aplicativo incluir uma cópia local do aplicativo do Universal CRT. É verdade mesmo quando a cópia local é mais recente, porque o CRT Universal é um componente central do sistema operacional no Windows 10._

BTW: Eu mesmo testei. Nenhuma maneira de carregar outro UCRT além do UCRT disponível implantado com o Windows 10.

Eu também acho que é razoável liberar a correção

com isso, acho que você quer dizer adicionar PR gh-17547?

Prova do ponto de

image

Esse bug, causado pelo próprio MS, deve ser chamado de Heisenbug . Foi caro e difícil encontrar a causa: o fmod UCRT do Windows 2004 deixa os registros da FPU em um estado mal-sucedido sob certas circunstâncias. Isso pode levar a erros de cálculo numérico muito mais tarde, ao usar a FPU novamente. Erros de cálculo geralmente não aparecem nos códigos de usuário se não forem rigorosamente testados. Isso pode significar que erros numéricos significativos permanecem não detectados por um longo tempo. Não poderia ser pior.

com isso, acho que você quer dizer adicionar PR gh-17547 ?

Desculpe, escrevi algo errado.

A única mudança que estou sugerindo é que o NumPy fornece mais informações na exceção levantada na importação que sugere maneiras de um usuário obter um ambiente no Windows 2004 / H2 que o deixaria continuar com seu trabalho / escola / hobby.

  1. WSL
  2. conda / enthought
  3. 1.19.3
  4. Construir da fonte

[Esta ordem é minha preferência quanto à qualidade da solução]

Acho que também faria sentido vincular a este problema, ou a um problema um pouco mais claro que forneça uma explicação mais profunda. Este segundo link também pode ser para algumas notas de lançamento nos documentos, em vez de um problema do github.

Os builds empacotados pelo conda-forge permitem a troca da implementação blas / lapack (de openblas / mkl / blis / netlib), ela não _tem_ de ser MKL.

@ h-vetinari As compilações conda-forge + OpenBLAS passam nos testes de 2004 / H2?

Acabei de verificar e coda-forge envia o OpenBlas 0.3.12. Isso trava os contêineres?

Usar o método de cura do estado FPU com a instrução EMMS em OpenBLAS-0.3.12 deve ajudar, é claro, a limpar os testes numpy e scipy, mas como @charris afirmou, chamando fmod(0,x) em As instruções CPython e FPU chamadas posteriormente (em um pacote diferente do OpenBLAS) também podem acontecer. Nesse caso, o problema é apenas transferido para outro lugar.

A melhor aposta é forçar a MS a corrigir esse comportamento de bugs. Talvez Steve Dower possa ajudar?

Esta também pode ser uma história interessante para Agner Fog ou talvez Bruce Dawson: Veja, por exemplo, esta história relacionada em seu blog:
Tudo o que é velho é novo de novo, e um bug do compilador

Provavelmente o bug no OpenBlas 0.3.12. Observe a coluna Private Bytes:

image

Provavelmente, o padrão é 24 threads BLAS, já que tenho 24 CPUs lógicas.

Este é o OpenBLAS 0.3.12 com NumPy 1.19.2 do conda-forge.

Definir $env:OPENBLAS_NUM_THREADS=1 proporciona uma redução dramática

image

E com $env:OPENBLAS_NUM_THREADS=4 threads:

image

@bashtage : você poderia continuar discutindo o OpenBLAS 0.3.12 no OpenBLAS xianyi / OpenBLAS # 2970?

@mattip Eu estava tentando determinar se conda + OpenBLAS era uma alternativa confiável. Não acho que resolve nada que 1.19.3 resolve depois de ver esses resultados.

@bashtage : Prova do ponto de

Como o python empacotado com conda contorna ativamente a resolução DLL padrão do Windows, não tenho certeza de quanto uma ferramenta do Windows será uma prova. Encontrei este problema, por exemplo, com libcrypto.dll desatualizado em C:\Windows\System32 , consulte, por exemplo, https://github.com/conda-forge/staged-recipes/pull/11452. Resumindo, a biblioteca de sistema desatualizada só foi detectada por uma falha de teste no conjunto de testes cryptography e então - usando CONDA_DLL_SEARCH_MODIFICATION_ENABLE - o uso do openssl fornecido pelo conda poderia ser forçado.

@bashtage : @ h-vetinari Conda-forge + OpenBLAS builds passam nos testes em 2004 / H2?

O CI que está construindo os pacotes provavelmente não está em uma versão atual, e demorei um pouco para construí-lo sozinho. Estou rodando em uma máquina de 2004 atualmente, e este é o resultado - muito positivo - **:

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

@bashtage : Acabei de verificar e conda-forge envia o OpenBlas 0.3.12. Isso trava os contêineres?

conda-forge não vem com nenhuma versão fixa do openblas - a versão blas pode até ser "hotswapped" (por exemplo, entre openblas, mkl, blis), então a versão não é nada demais. Geralmente, porém, ele usará a versão empacotada mais recente. Não consigo verificar se a falha reproduz ou não dentro dos contêineres.

@bashtage :: @mattip Eu estava tentando determinar se conda + OpenBLAS era uma alternativa confiável. Não acho que resolve nada que 1.19.3 resolve depois de ver esses resultados.

O aumento da memória foi devido a uma mudança no openblas 0.3.12, conforme discutido mais adiante em xianyi / OpenBLAS # 2970. Até agora, conda-forge parece uma alternativa confiável para mim - pelo menos não é afetado diretamente pelo erro.

** Usei o mestre atual de https://github.com/conda-forge/numpy-feedstock , que ainda está em 1.19.2, juntamente com openblas 0.3.12. Eu também poderia tentar https://github.com/conda-forge/numpy-feedstock/pull/210 + openblas 0.3.12, se as pessoas estiverem interessadas.

Como uma boa notícia, a MS voltou ao fórum do VS e sugeriu que uma correção poderia ser lançada até o final de janeiro de 2021. Dada essa atualização, acho que a única questão é se há algum valor em atualizar a mensagem de erro que é gerada quando o função com erros foi detectada.

Como o python empacotado com conda contorna ativamente a resolução DLL padrão do Windows, não tenho certeza de quanto uma ferramenta do Windows será uma prova. Encontrei este problema, por exemplo, com libcrypto.dll desatualizado em C:\Windows\System32 , consulte, por exemplo, conda-forge / staged-recipes # 11452 . Resumindo, a biblioteca de sistema desatualizada só foi detectada por uma falha de teste no conjunto de testes cryptography e então - usando CONDA_DLL_SEARCH_MODIFICATION_ENABLE - o uso do openssl fornecido pelo conda poderia ser forçado.

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

saídas

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

Isso mostra que quando o OpenBLAS antigo é usado, a função com erros da DLL ucrt atual está sendo usada.

Apenas openblas = 0.3.12 de conda forge irá passar nos testes, mas este é o mesmo fornecido no NumPy 1.19.3.

O que fala contra um novo lançamento numpy compilado com um OpenBLAS-0.3.12 desarmado? Buffersize reduzido e talvez número reduzido de threads em tempo de compilação do OpenBLAS usado para numpy. Isso deve reduzir o consumo de memória do OpenBLAS e deve ajudar não só no caso de teste do Docker, mas também usuários com menos
caixas de janelas.

Aqui, no https://tinyurl.com/y3dm3h86 relatório de bug de dentro do Python. Em primeiro lugar, obrigado por fornecer uma versão que funciona no Windows por enquanto (1.19.3).

Eu entendo que 1.19.3 não funciona no Linux e 1.19.4 não funciona no Windows (embora tenha o bug).

Seria possível fazer a versão mais recente em pypi 1.19.3 para Windows e 1.19.4 para todas as outras plataformas? Em outras palavras, simplesmente exclua https://files.pythonhosted.org/packages/33/26/c448c5203823d744b7e71b81c2b6dcbcd4bff972897ce989b437ee836b2b/numpy-1.19.4-cp36-cp36m-win_amd64.whl) e as versões 3.764 / 3.864 correspondentes inteiramente por enquanto?

@luciansmith Contanto que o código-fonte esteja disponível para 1.19.4, o pip tentará e usará esta versão, a menos que sinalizadores adicionais sejam passados. Acho que a maioria dos usuários só passaria sinalizadores adicionais se soubessem do problema, mas então eles poderiam apenas fixar 1.19.3.

Minha preferência seria ter um 1.19.5 que usasse OpenBLAS 0.3.9 no Linux e 0.3.12 no Windows, mas não sei se isso é possível.

Esta página foi útil?
0 / 5 - 0 avaliações