Thanks to visit codestin.com
Credit goes to github.com

Skip to content

BUG: Fixes for building on Cygwin. #18102

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 31 commits into from
Closed

Conversation

charris
Copy link
Member

@charris charris commented Dec 31, 2020

Rebase of #16246.

Changes needed to get numpy to compile on Cygwin, then a few changes to try to reduce the number of test failures due to extension module overlap, then marking differences I think are due to floating-point implementation or fork() failures.

Someone should probably check whether the list of ignored floating-point failures is reasonable.
Most of those have been around since 1.16 a while back.

Rebased to get all the commits gathered together and on top of master. Should probably all be squashed at some point,
this is for review.

@DWesl ping.

DWesl added 30 commits December 31, 2020 16:12
Leaving it later can lead to some headers getting confused, because
they're included with one set of feature flags, but the headers they
depend on were included with a different set of feature flags.
…rebase.

Cygwin needs each DLL to have a unique address for fork() emulation to
work.  I'm hoping that calling rebase on a complete list of modules
compiled in this session, plus those installed globally, will allow
the test suite to get an accurate result for more tests.
… on cygwin.

Most likely I should be testing for newlib (the C runtime, roughly
takes the place of glibc, I think), not cygwin (the emulation layer on
Windows), but I have no idea how to do that from within python.  If
someone working on embedded systems runs into this issue, this
hopefully gives them some idea where to start.
…win.

See two commits back for an explanation of why fork() fails on cygwin.
Alternately, see the much better explanation at:
https://cygwin.com/cygwin-ug-net/highlights.html#ov-hi-process
with hints on error messages and workarounds at:
https://cygwin.com/faq.html#faq.using.fixing-fork-failures
These changes made some sense when compiling only for cygwin.  They do
not belong in NumPy master.
I don't know if the list should be the same as one of the Windows
lists, or if this should instead be a Newlib list.  I know how to make
a Cygwin list, so I did that.  It didn't always work, though.
The generic "this doesn't work" was confusing people.  Specifying what
"this" is and what happed works better.
Mark tests suddenly passing, and also document how I expect them to
fail.
This was actually making the situation worse, I think because I forgot
to include the NumPy dlls themselves.  Removing this made for many
fewer fork() failures when I tried it.

`python3 -m pip show numpy --files | grep dll`
will give a list of dlls, with at least a relative path.  This can be
done in python with subprocess (will require adding pip as a runtime
dependency), but I'm not sure that's in scope here.
These should primarily be on test functions.
Unconditional access to np.complex256 triggers an error in test collection on platforms where the dtype does not exist.
Find another way to test the dtype for equality.
I changed this for the one test, but forgot to do so for the other.  Hopefully this actually fixes the problem.
Presumably whoever wrote this code had reasons for leaving this out, and making a separate class for `gfortran`
Including both 'gfortran' and '/usr/bin/gfortran' should be redundant, and I'm not sure even my platform ever needed this.  Remove it.
Workaround for GCC bug 65782.
Fixes numpy issue 14787.
I forgot the function returned bytes, not str.
I also accidentally passed an extra argument.
The problem seems to have gone away on 64-bit.
It may be worth broadening the platform list, since I believe the
error this tries to fix is in the MS ABI/CRT rather than in the Cygwin
runtime.
Allows more precise xfail.
I think these are the tests where the "branch cut code doesn't use
sign of zero" became relevant.
This was trying to ensure the definition of symbols that depend on
feature macros set in "Python.h".  That issue seems to have resolved
itself.
I think I saw a test failure because the generated tempfile name
contained the string "mkl".  I think what the code is trying to do is
to change the "[mkl]" section to a "[DEFAULT]" section without
changing any of the contents of that section.  I think this change
should do the trick.
The implementation currently segfaults.
I'll report this to the developers soon;
hopefully it can be re-enabled soon.
32-bit modfl appears to work fine.  Problem exists in Cygwin 3.1.5 to 3.1.7 and should be fixed in 3.2.0.
@charris
Copy link
Member Author

charris commented Dec 31, 2020

A lot of the fixes look to be disabling tests, which seems not quite right. Ideally the tests would pass without fixing. Its might be that we should just wait for Cygwin to improve or stop supporting it.

@DWesl
Copy link
Contributor

DWesl commented Jan 1, 2021

A lot of those xfail marks are for fork() failures on 32-bit Cygwin, which the Cygwin maintainers have been discouraging people from using for a year or so now because there are so many, so just dropping those would work for me. If that becomes a problem on 64-bit again I can mark the failing tests then.

The edits to npy_common.h to mark which floating functions have trouble should probably stay in, and the note that the Windows dynamic loader doesn't really have a concept of rpath should probably also stay. I'm fine with keeping the list of floating-point tests that give weird results as a local patch or note to self.

Should I start the PR over? Proposed commit order:

  1. Change some tests with loops to use pytest.mark.parametrize
  2. The test_system_into patch to avoid weird behavior with certain tempfile names
  3. Tell fcompiler.gnu that Windows doesn't do rpath
  4. Tell npy_common.h which functions numpy should use its own versions for

The first two might work better as separate PRs.

@charris
Copy link
Member Author

charris commented Jan 1, 2021

Should I start the PR over? Proposed commit order:

You are in a better position to carry this forward than I am. How would you like to proceed?

@DWesl
Copy link
Contributor

DWesl commented Jan 1, 2021

The added compiler flags to avoid a ufunc crash got merged in another PR, and my fork problems on 64-bit seem to have resolved themselves, so those portions of the PR are gone now, and there's not terribly much left.

@DWesl
Copy link
Contributor

DWesl commented Jan 1, 2021

Should I start the PR over? Proposed commit order:

You are in a better position to carry this forward than I am. How would you like to proceed?

The first two changes in that list aren't really connected to the others, so I should probably separate those into different PRs focused on just those. I'm not sure if the Cygwin-specific changes would be better handled on this PR or as a new PR or what.

@charris
Copy link
Member Author

charris commented Jan 1, 2021

@DWesl I would prefer to close this and deal with new PRs. I want to know what would be most convenient for you.

@DWesl
Copy link
Contributor

DWesl commented Jan 3, 2021

The Test_SIMD_ALL_256_FMA3__AVX2_[usf]{8,16,32,64} tests are segfaulting, as are the Test_SIMD_FP_256_FMA3__AVX2_f{32,64} tests and the Test_SIMD_INT_256_FMA3__AVX2_[us]{8,16,32,64} tests and the Test_SIMD_BOOL_256_FMA3__AVX2_b{8,16,32,64} tests. I'll try to figure out how to skip those so I can avoid using pytest-forked, which makes the tests really slow.

I should probably also figure out why they're segfaulting at some point. /proc/cpuinfo mentions AVX2 and FMA but not FMA3, and that roughly exhausts my knowledge of how to debug the crashes.

@rgommers
Copy link
Member

I should probably also figure out why they're segfaulting at some point. /proc/cpuinfo mentions AVX2 and FMA but not FMA3, and that roughly exhausts my knowledge of how to debug the crashes.

@seiko2plus or @mattip any advice here on how to debug?

@seiko2plus
Copy link
Member

@DWesl, we use the term FMA3 instead of FMA to avoid any confusion with AMD/FMA4.

@rgommers,

any advice here on how to debug?

  • Testing CPU detecting mechanism -> python runtests.py -t numpy/core/tests/test_cpu_features.py
    NOTE: You will have to patch test_cpu_features.py to enables Cygwin.
  • Testing _SIMD module itself without any dispatched features:
    • python runtests.py --cpu-dispatch="none" -t numpy/core/tests/test_simd_module.py
    • python runtests.py --cpu-dispatch="none" -t numpy/core/tests/test_simd.py
  • Testing _SIMD module with certain dispatched features, e.g. sse41
    python runtests.py --simd-test="baseline sse41" -t numpy/core/tests/test_simd.py
  • Checking the build log, and finally GDB or LLDB

@DWesl
Copy link
Contributor

DWesl commented Jan 31, 2021

@DWesl, we use the term FMA3 instead of FMA to avoid any confusion with AMD/FMA4.

@rgommers,

any advice here on how to debug?

* Testing CPU detecting mechanism -> `python runtests.py -t numpy/core/tests/test_cpu_features.py`
  NOTE: You will have to patch `test_cpu_features.py` to enables `Cygwin`.
python runtests.py -t numpy/core/tests/test_cpu_features.py
Building, see build.log...
Build OK
NumPy version 1.21.0.dev0+393.g0386777c3
NumPy relaxed strides checking option: True
NumPy CPU features: SSE SSE2 SSE3 SSSE3* SSE41* POPCNT* SSE42* AVX* F16C* FMA3* AVX2* AVX512F? AVX512CD? AVX512_KNL? AVX512_KNM? AVX512_SKX? AVX512_CLX? AVX512_CNL? AVX512_ICL?
.ss                                                            [100%]
1 passed, 2 skipped in 0.08s
* Testing `_SIMD` module itself without any dispatched features:
  
  * `python runtests.py --cpu-dispatch="none" -t numpy/core/tests/test_simd_module.py`
python runtests.py --cpu-dispatch="none" -t numpy/core/tests/test_simd_module.py
Building, see build.log...
    ... build in progress
Build OK
NumPy version 1.21.0.dev0+393.g0386777c3
NumPy relaxed strides checking option: True
NumPy CPU features: SSE SSE2 SSE3
.........................s..........                                   [100%]
35 passed, 1 skipped in 0.43s
  * `python runtests.py --cpu-dispatch="none" -t numpy/core/tests/test_simd.py`
python runtests.py --cpu-dispatch="none" -t numpy/core/tests/test_simd.py
Building, see build.log...
Build OK
NumPy version 1.21.0.dev0+393.g0386777c3
NumPy relaxed strides checking option: True
NumPy CPU features: SSE SSE2 SSE3
.......................................................................................................................................................................................................... [ 84%]
....................................                                                                                                                                                                       [100%]
238 passed in 1.89s
* Testing `_SIMD` module with certain dispatched features, e.g. `sse41`
  `python runtests.py --simd-test="baseline sse41" -t numpy/core/tests/test_simd.py`
python runtests.py --simd-test="baseline sse41" -t numpy/core/tests/test_simd.py
Building, see build.log...
    ... build in progress
    ... build in progress
Build OK
NumPy version 1.21.0.dev0+393.g0386777c3
NumPy relaxed strides checking option: True
NumPy CPU features: SSE SSE2 SSE3 SSSE3* SSE41* POPCNT* SSE42* AVX* F16C* FMA3* AVX2* AVX512F? AVX512CD? AVX512_KNL? AVX512_KNM? AVX512_SKX? AVX512_CLX? AVX512_CNL? AVX512_ICL?
........................................................................ [ 15%]
........................................................................ [ 30%]
........................................................................ [ 45%]
........................................................................ [ 60%]
........................................................................ [ 75%]
........................................................................ [ 90%]
............................................                             [100%]
476 passed in 7.31s

$ python runtests.py --simd-test="baseline sse41 sse42 avx avx2 fma" -t numpy/core/tests/test_simd.py
Building, see build.log...
    ... build in progress
    ... build in progress
Build OK
NumPy version 1.21.0.dev0+393.g0386777c3
NumPy relaxed strides checking option: True
NumPy CPU features: SSE SSE2 SSE3 SSSE3* SSE41* POPCNT* SSE42* AVX* F16C* FMA3* AVX2* AVX512F? AVX512CD? AVX512_KNL? AVX512_KNM? AVX512_SKX? AVX512_CLX? AVX512_CNL? AVX512_ICL?
........................................................................ [ 15%]
........................................................................ [ 30%]
........................................................................ [ 45%]
........................................................................ [ 60%]
........................................................................ [ 75%]
........................................................................ [ 90%]
............................................                             [100%]
476 passed in 7.40s

$ python runtests.py -t numpy/core/tests/test_simd.py
Building, see build.log...
Build OK
NumPy version 1.21.0.dev0+393.g0386777c3
NumPy relaxed strides checking option: True
NumPy CPU features: SSE SSE2 SSE3 SSSE3* SSE41* POPCNT* SSE42* AVX* F16C* FMA3* AVX2* AVX512F? AVX512CD? AVX512_KNL? AVX512_KNM? AVX512_SKX? AVX512_CLX? AVX512_CNL? AVX512_ICL?
........................................................................ [ 15%]
........................................................................ [ 30%]
........................................................................ [ 45%]
........................................................................ [ 60%]
........................................................................ [ 75%]
........................................................................ [ 90%]
............................................                             [100%]
476 passed in 3.55s
* Checking the build log, and finally GDB or LLDB

After following the above steps, I can run the whole testsuite with no segfaults. If I run git clean -xdf first, I get segfaults. I have no idea why, but at least I have a workaround now.

DWesl added a commit to DWesl/numpy that referenced this pull request Feb 1, 2021
This was suggested by @seiko2plus for debugging a segfault in the
tests on Cygwin:
numpy#18102 (comment)

This test passes on Cygwin, and the whole testsuite has only the
failures I expect from running on Cygwin (see numpy#18102 and numpy#16246).
@DWesl
Copy link
Contributor

DWesl commented Feb 2, 2021

Out of curiosity, should abs(inf + nanj) be inf or nan? My first thought was nan because there's a nan in there, but the tests seem to be expecting inf.

@seberg
Copy link
Member

seberg commented Feb 2, 2021

should abs(inf + nanj) be inf or nan?

I am sure NaN is correct. If an inf result is tested, that could well be a bug in the complex abs implementation.

EDIT: I am basing this on the fact that "all NaNs are NaNs" for complex numbers (i.e. inf+nanj should be the same as nan+nanj). If you disregard that, I guess an inf result does make sense. A NaN result would seem safer to me though.

@DWesl
Copy link
Contributor

DWesl commented Feb 2, 2021

should abs(inf + nanj) be inf or nan?

I am sure NaN is correct. If an inf result is tested, that could well be a bug in the complex abs implementation.

Okay, I recently wrote a C program to check cabsl(+-inf + nanj) and cabsl(nan +- infj), since those tests have been failing for months. All four return nan. The corresponding tests fail:

FAILED numpy/core/tests/test_multiarray.py::test_npymath_complex[complex256-inf-nan-npy_cabs-absolute] - AssertionError:
FAILED numpy/core/tests/test_multiarray.py::test_npymath_complex[complex256--inf-nan-npy_cabs-absolute] - AssertionError:
FAILED numpy/core/tests/test_multiarray.py::test_npymath_complex[complex256-nan-inf-npy_cabs-absolute] - AssertionError:
FAILED numpy/core/tests/test_multiarray.py::test_npymath_complex[complex256-nan--inf-npy_cabs-absolute] - AssertionError:

with the error:

E       AssertionError:
E       Not equal to tolerance rtol=1e-07, atol=0
E
E       x and y nan location mismatch:
E        x: array(inf)
E        y: array(nan, dtype=float128)

I just noticed the dtype for x isn't right, so I'll look into fixing that.

@DWesl
Copy link
Contributor

DWesl commented Feb 2, 2021

I tracked the numpy.core._multiarray_tests.npy_cabs call to numpy/core/src/npymath/npy_math_complex.c.src line 121, where it calls npy_hypotl and got stuck there. I'm going to leave that be and post my other work.

@charris
Copy link
Member Author

charris commented Feb 2, 2021

@DWesl Do you want me to keep this up?

@DWesl
Copy link
Contributor

DWesl commented Feb 2, 2021

You can close it if you want. I'm running a last round of tests before creating the pull request, to see if any of the failing tests are passing now.

@WarrenWeckesser
Copy link
Member

Out of curiosity, should abs(inf + nanj) be inf or nan?

Actually, it looks like the result should be inf, based on behavior specified in IEEE 754-2008. I haven't read the full specification; this comment is based on a comment that @mdickinson made in a Python bug report. And inf is the value returned by Python's abs and by np.abs in 1.19.5:

In [1]: import math                                                                                                 

In [2]: z = complex(math.inf, math.nan)                                                                             

In [3]: abs(z)                                                                                                      
Out[3]: inf

In [4]: import numpy as np                                                                                          

In [5]: np.__version__                                                                                              
Out[5]: '1.19.5'

In [6]: np.abs(z)                                                                                                   
Out[6]: inf

And there is also

In [11]: np.hypot(np.inf, np.nan)                                                                                   
Out[11]: inf

@seberg
Copy link
Member

seberg commented Feb 2, 2021

Makes sense, the usual safe bet is to say is to replace NaN with "any possible value". The oddball is just that for complex two values for which np.isnan() is True, will have different values for these cases. But I suppose that isn't really an issue.

@charris charris closed this Feb 3, 2021
@charris charris deleted the rebase-16246 branch February 3, 2021 01:15
@mdickinson
Copy link
Contributor

Annex G of the C standard is also a useful (and more easily available) source of information for these corner cases. For the C11 standard, §G.6p6 has:

Each of the functions cabs and carg is specified by a formula in terms of a real function (whose special cases are covered in annex F): cabs(x + iy) = hypot(x, y) [...]

while §F.10.4.3p1 has:

hypot(±∞, y) returns +∞, even if y is a NaN.

DWesl added a commit to DWesl/numpy that referenced this pull request Apr 14, 2021
This was suggested by @seiko2plus for debugging a segfault in the
tests on Cygwin:
numpy#18102 (comment)

This test passes on Cygwin, and the whole testsuite has only the
failures I expect from running on Cygwin (see numpy#18102 and numpy#16246).
DWesl added a commit to DWesl/numpy that referenced this pull request Jul 21, 2021
This was suggested by @seiko2plus for debugging a segfault in the
tests on Cygwin:
numpy#18102 (comment)

This test passes on Cygwin, and the whole testsuite has only the
failures I expect from running on Cygwin (see numpy#18102 and numpy#16246).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants