8000 ENH: Enable musllinux wheels by tgross35 · Pull Request #21200 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

ENH: Enable musllinux wheels #21200

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 12 commits into from
Closed

Conversation

tgross35
Copy link

This is intended to address #20089

Per my comment here there will likely be some failures, hopefully the actions here will show exactly what needs to be addressed.

@tgross35
Copy link
Author

@mattip in this comment #20089 (comment) the GH action you linked shows the wheel build but doesn't seem to have the wheel tests. Am I missing something there?

Also, it seems like the wheel builder was skipped here, is there a way to kick it off without waiting for the cron?

@mattip mattip added the 36 - Build Build related PR label Mar 15, 2022
@mattip
Copy link
Member
mattip commented Mar 15, 2022

the wheel builder was skipped here, is there a way to kick it off without waiting for the cron?

I added the "build" label, which will trigger the cibuildwheel action whenever a commit is made. You can also trigger that by adding "[wheel build]" to the git commit message. See the documentation for more info

but doesn't seem to have the wheel tests

Open the "build wheel" task, you will see the "test wheel" subtask which runs numpy.test('full', extra_argv=['-vvv'])

@mattip
Copy link
Member
mattip commented Mar 15, 2022

Wheel building is very resource intensive: it runs ~14 jobs and each one requires between 16 and 75 minutes, so we try to keep the number of runs down to a minimum.

@mattip
Copy link
Member
mattip commented Mar 15, 2022

I think you need to add musl to the buildplatform. I am not sure what github actions calls the platform.

@tgross35
Copy link
Author

Of course, thank you for starting it. I'm surprised any pipelines run automatically on PRs at all.

Good catch, I wasn't sure about that either. Seems like this pipeline is unfortunately a waste so you're welcome to cancel. I'll look into the platform.

@tgross35
Copy link
Author

No dice on the github actions info https://docs.github.com/en/actions/using-jobs/using-a-build-matrix-for-your-jobs but I'm wondering if something like alpine-latest would work

Probably best to find an example from here https://cibuildwheel.readthedocs.io/en/latest/working-examples/ like tornado https://github.com/tornadoweb/tornado/blob/master/.github/workflows/build.yml

@tgross35
Copy link
Author

Looks like the musl failures are because of missing openblas64 libs, BlasILP64NotFoundError raised. Thinking maybe openblas_support.py needs a musl option in download_openblas, but I'm still working my way through how this works (and doesn't seem to be a musl version on https://anaconda.org/multibuild-wheels-staging/openblas-libs/files)

Also lots of warnings about distutils to take a look at. I need to figure out the differences between this environment and the default Alpine docker env. At least we have a starting point.

@mattip
Copy link
Member
mattip commented Mar 16, 2022

I opened an issue MacPython/openblas-libs#72 for openblas artifacts, but it seems there is another link in the chain that has to happen first: multibuild support for musl multi-build/multibuild#430

@tgross35
Copy link
Author

Thanks Matt, Yuck, growing needed work, but that was expected. Seems like multibuild is close, hope that rolls out soon.

@mattip
Copy link
Member
mattip commented Mar 16, 2022

Since the multibuild PR was merged, I started MacPython/openblas-libs#73 to create the OpenBLAS artifacts build for x86_64 and aarch64 (musllinux)

@lithomas1
Copy link
Collaborator

It might be nice to have 1-2 jobs in the regular CI testing musllinux. The wheel builders are somewhat hard to debug if something goes wrong because they run infrequently(only once a week).

@mattip
Copy link
Member
mattip commented Mar 17, 2022

and doesn't seem to be a musl version on https://anaconda.org/multibuild-wheels-staging/openblas-libs/files

That part should be solved in a few hours.

@tgross35
Copy link
Author

Awesome, they're there! Will take another look at this this afternoon

@rgommers
Copy link
Member

The musl OpenBLAS libraries seem to be present now.

@tgross35
Copy link
Author

Sorry, haven't had time to work on this in a bit. Will try to get back on it this week

@tgross35
Copy link
Author
tgross35 commented May 2, 2022

Should have figured this out before, can specify the build identifier for cibw local CIBW_BUILD=cp310-musllinux_x86_64 CIBW_TEST_SKIP=* cibuildwheel --platform linux [--print-build-identifiers # add to verify what will be built without actually running]

@mattip
Copy link
Member
mattip commented May 2, 2022

Please revert the whitespace changes

@mattip
Copy link
Member
mattip commented May 2, 2022

Our linting policy is to only reformat lines that the PR itself changes, not to reformat entire files.

@tgross35
Copy link
Author
tgross35 commented May 2, 2022

Yes that YAML file was an accident that I didn't notice until after my most recent commit, I just didn't want waste the CI time with a fix & push until I had something worth running it

@mattip
Copy link
Member
mattip commented May 2, 2022

There is an error AttributeError: 'MachAr' object has no attribute '_str_smallest_normal'. Any idea how it is passing locally but fails on CI?

@mattip
Copy link
Member
mattip commented May 2, 2022

xref #21425 to skip the hanging PyPy test

@tgross35
Copy link
Author
tgross35 commented May 2, 2022

No clue yet, I'm still trying to get a good debug setup working that uses an Alpine docker container and the cibuildwheel-built wheel. How are you testing locally? It doesn't show up using the quick test I had here #20089 (comment) but I guess it must have something to do with openblas or other features enabled with cibuildwheel but not build.

From here it seems like the problem is that _discovered_machar returns a MachAr, but finfo's init kind of expects a MachArLike.
https://github.com/tgross35/numpy/blob/055c19bb7511c8c204ce6e701dd31ac215ba0c99/numpy/core/getlimits.py#L333-L360

MachAr seems deprecated - I don't really understand the module enough to know if the issue is

  • MachAr shouldn't be used at all and _discovered_machar should return a MachArLike (this seems like a bit of a bug in any case)
  • There just needs to be another _KNOWN_TYPES signature
  • MachAr needs all the functions of MachArLike implemented

@tgross35
Copy link
Author
tgross35 commented May 2, 2022

In an Alpine container (just using pip install rather than a built wheel) running np.float128('-0.1').newbyteorder('<').tobytes() I get \xcd\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xfb\xbf\x00\x00\x01\x00\x00\x00, and np.float12 == ntypes.longdouble is true so it's able to find a known type with key[:10].

\x00\xd0\xcc\xcc\xcc\xcc\xcc\xcc\xfb\xbf\x9c\xee\x8a\x7f\x00\x00 is reported in the warning, no part of that is a _KNOWN_TYPES key

@tgross35
Copy link
Author
tgross35 commented May 2, 2022

I added a known type for that key pointing to float80 (same as install via build) without actually understanding what exactly it's doing, so I'll need your advice there. It at least starts to run the tests now, so we can see what else might be an issue

Also disabled other wheel builds to not waste your CPU time

@tgross35
Copy link
Author
tgross35 commented May 2, 2022

With adding that type, the following is the test report:

2022-05-02T19:37:42.2136334Z =========================== short test summary info ============================
2022-05-02T19:37:42.2136712Z FAILED core/tests/test_longdouble.py::test_repr_roundtrip - AssertionError: 
2022-05-02T19:37:42.2137146Z FAILED core/tests/test_mem_policy.py::test_new_policy - AssertionError: asser...
2022-05-02T19:37:42.2137508Z FAILED core/tests/test_print.py::TestCommaDecimalPointLocale::test_locale_longdouble
2022-05-02T19:37:42.2138004Z FAILED core/tests/test_scalar_methods.py::TestAsIntegerRatio::test_roundtrip[float128-frac_vals3-exp_vals3]
2022-05-02T19:37:42.2138382Z FAILED core/tests/test_scalarprint.py::TestRealScalars::test_dragon4_interface
2022-05-02T19:37:42.2138731Z FAILED core/tests/test_umath.py::TestComplexFunctions::test_precisions_consistent
2022-05-02T19:37:42.2139168Z FAILED core/tests/test_umath.py::TestComplexFunctions::test_branch_cuts - Ass...
2022-05-02T19:37:42.2139505Z FAILED core/tests/test_umath.py::TestComplexFunctions::test_branch_cuts_complex64
2022-05-02T19:37:42.2139917Z FAILED core/tests/test_umath.py::TestComplexFunctions::test_loss_of_precision[complex64]
2022-05-02T19:37:42.2140290Z FAILED core/tests/test_umath.py::TestComplexFunctions::test_loss_of_precision[complex128]
2022-05-02T19:37:42.2140855Z FAILED core/tests/test_umath.py::TestComplexFunctions::test_loss_of_precision[complex256]
2022-05-02T19:37:42.2141207Z = 11 failed, 20030 passed, 187 skipped, 29 xfailed, 7 xpassed, 8 warnings in 1045.56s (0:17:25) 

This is at least closer to the result of running pytest on a build-built wheel:

============================================================================================ short test summary info ============================================================================================FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[f--4] - AssertionError:
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[f--2] - AssertionError:
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[f--1] - AssertionError:
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[f-1] - AssertionError:
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[f-2] - AssertionError:
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[f-4] - AssertionError:
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[d--4] - AssertionError:
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[d--2] - AssertionError:
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[d--1] - AssertionError:
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[d-1] - AssertionError:
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[d-2] - AssertionError:
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[d-4] - AssertionError:
FAILED ../../core/tests/test_umath.py::TestComplexFunctions::test_precisions_consistent - AssertionError:
FAILED ../../core/tests/test_umath.py::TestComplexFunctions::test_branch_cuts - AssertionError: (array([-1.57079633-0.54930614j, -1.57079633+0.54930614j]), array([1.57079633-0.54930614j, 1.57079633+0.549306...FAILED ../../core/tests/test_umath.py::TestComplexFunctions::test_branch_cuts_complex64 - AssertionError: (array([-1.5707963-0.54930615j, -1.5707963+0.54930615j], dtype=complex64), array([1.5707884-0.549306...FAILED ../../core/tests/test_umath.py::TestComplexFunctions::test_loss_of_precision[complex64] - RuntimeWarning: divide by zero encountered in divide
FAILED ../../core/tests/test_umath.py::TestComplexFunctions::test_loss_of_precision[complex128] - RuntimeWarning: divide by zero encountered in divide
FAILED ../../core/tests/test_umath.py::TestComplexFunctions::test_loss_of_precision[complex256] - RuntimeWarning: divide by zero encountered in divide
ERROR ../../f2py/tests/test_return_real.py::TestCReturnReal::test_all[t4] - RuntimeError: Running f2py failed: ['-m', 'c_ext_return_real', '/tmp/tmpdhatpr1j/tmp41fs1sca.pyf']
ERROR ../../f2py/tests/test_return_real.py::TestCReturnReal::test_all[t8] - RuntimeError: Running f2py failed: ['-m', 'c_ext_return_real', '/tmp/tmpdhatpr1j/tmp41fs1sca.pyf']
ERROR ../../f2py/tests/test_return_real.py::TestCReturnReal::test_all[s4] - RuntimeError: Running f2py failed: ['-m', 'c_ext_return_real', '/tmp/tmpdhatpr1j/tmp41fs1sca.pyf']
ERROR ../../f2py/tests/test_return_real.py::TestCReturnReal::test_all[s8] - RuntimeError: Running f2py failed: ['-m', 'c_ext_return_real', '/tmp/tmpdhatpr1j/tmp41fs1sca.pyf']
ERROR ../../f2py/tests/test_semicolon_split.py::TestMultiline::test_multiline - RuntimeError: Running f2py failed: ['-m', 'multiline', '/tmp/tmpdhatpr1j/tmptm3fbnlo.pyf']
ERROR ../../f2py/tests/test_semicolon_split.py::TestCallstatement::test_callstatement - RuntimeError: Running f2py failed: ['-m', 'callstatement', '/tmp/tmpdhatpr1j/tmpn3f99var.pyf']
================================================== 18 failed, 18011 passed, 892 skipped, 1301 deselected, 31 xfailed, 5 xpassed, 6 errors in 223.07s (0:03:43) ==================================================

@tgross35
Copy link
Author
tgross35 commented May 2, 2022

The ftype == ntypes.longdouble check comes out as True, for reference

@tgross35
Copy link
Author
tgross35 commented May 3, 2022

OK I am now able to run tests on wheels built locally with cibuildwheel and tested in docker, but I can't seem to exactly replicate test results in any way. Things I've tried:

  • Test on the CI here, this is the goal to replicate. 11 failures
Test summary
2022-05-02T19:37:42.2136334Z =========================== short test summary info ============================
2022-05-02T19:37:42.2136712Z FAILED core/tests/test_longdouble.py::test_repr_roundtrip - AssertionError: 
2022-05-02T19:37:42.2137146Z FAILED core/tests/test_mem_policy.py::test_new_policy - AssertionError: asser...
2022-05-02T19:37:42.2137508Z FAILED core/tests/test_print.py::TestCommaDecimalPointLocale::test_locale_longdouble
2022-05-02T19:37:42.2138004Z FAILED core/tests/test_scalar_methods.py::TestAsIntegerRatio::test_roundtrip[float128-frac_vals3-exp_vals3]
2022-05-02T19:37:42.2138382Z FAILED core/tests/test_scalarprint.py::TestRealScalars::test_dragon4_interface
2022-05-02T19:37:42.2138731Z FAILED core/tests/test_umath.py::TestComplexFunctions::test_precisions_consistent
2022-05-02T19:37:42.2139168Z FAILED core/tests/test_umath.py::TestComplexFunctions::test_branch_cuts - Ass...
2022-05-02T19:37:42.2139505Z FAILED core/tests/test_umath.py::TestComplexFunctions::test_branch_cuts_complex64
2022-05-02T19:37:42.2139917Z FAILED core/tests/test_umath.py::TestComplexFunctions::test_loss_of_precision[complex64]
2022-05-02T19:37:42.2140290Z FAILED core/tests/test_umath.py::TestComplexFunctions::test_loss_of_precision[complex128]
2022-05-02T19:37:42.2140855Z FAILED core/tests/test_umath.py::TestComplexFunctions::test_loss_of_precision[complex256]
2022-05-02T19:37:42.2141207Z = 11 failed, 20030 passed, 187 skipped, 29 xfailed, 7 xpassed, 8 warnings in 1045.56s (0:17:25) 
  • Running CIBW_BUILD=cp310-musllinux_x86_64 --platform linux to allow cibuildwheel to build and test a wheel. It builds successfully but test fails somewhere on test_format.py Error: Command ['sh', '-c', 'bash /project/tools/wheels/cibw_test_command.sh /project'] failed with code 137.

  • Building musl wheel locally with CIBW_BUILD=cp310-musllinux_x86_64 CIBW_TEST_SKIP=* --platform linux, installing it in an Alpine container, running it in python with numpy.test('full', extra_argv=['-vvv']) to try to replicate what cibuildwheel does. Result: runs up to 55% then gets killed on test_format.py too. Same result for python runtests.py -v -n -m full.

  • Same docker setup as above, but just python runtests.py -v -n. Adding -m full Comes up with 21 failures, listed below. Same result for numpy.test('fast', extra_argv=['-vvv'])

Test report
============================================================================ short test summary info ============================================================================
FAILED ../../core/tests/test_longdouble.py::test_repr_roundtrip - AssertionError: 
FAILED ../../core/tests/test_print.py::TestCommaDecimalPointLocale::test_locale_longdouble - AssertionError: 
FAILED ../../core/tests/test_scalarprint.py::TestRealScalars::test_dragon4_interface - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[f--4] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[f--2] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[f--1] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[f-1] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[f-2] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[f-4] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[d--4] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[d--2] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[d--1] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[d-1] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[d-2] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[d-4] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestComplexFunctions::test_precisions_consistent - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestComplexFunctions::test_branch_cuts - AssertionError: (array([-1.57079633-0.54930614j, -1.57079633+0.54930614j]), array([1.57079633-...
FAILED ../../core/tests/test_umath.py::TestComplexFunctions::test_branch_cuts_complex64 - AssertionError: (array([-1.5707963-0.54930615j, -1.5707963+0.54930615j], dtype=compl...
FAILED ../../core/tests/test_umath.py::TestComplexFunctions::test_loss_of_precision[complex64] - RuntimeWarning: divide by zero encountered in divide
FAILED ../../core/tests/test_umath.py::TestComplexFunctions::test_loss_of_precision[complex128] - RuntimeWarning: divide by zero encountered in divide
FAILED ../../core/tests/test_umath.py::TestComplexFunctions::test_loss_of_precision[complex256] - RuntimeWarning: divide by zero encountered in divide
ERROR ../../f2py/tests/test_return_real.py::TestCReturnReal::test_all[t4] - RuntimeError: Running f2py failed: ['-m', 'c_ext_return_real', '/tmp/tmpdksktw9k/tmpnmodkhg5.pyf']
ERROR ../../f2py/tests/test_return_real.py::TestCReturnReal::test_all[t8] - RuntimeError: Running f2py failed: ['-m', 'c_ext_return_real', '/tmp/tmpdksktw9k/tmpnmodkhg5.pyf']
ERROR ../../f2py/tests/test_return_real.py::TestCReturnReal::test_all[s4] - RuntimeError: Running f2py failed: ['-m', 'c_ext_return_real', '/tmp/tmpdksktw9k/tmpnmodkhg5.pyf']
ERROR ../../f2py/tests/test_return_real.py::TestCReturnReal::test_all[s8] - RuntimeError: Running f2py failed: ['-m', 'c_ext_return_real', '/tmp/tmpdksktw9k/tmpnmodkhg5.pyf']
ERROR ../../f2py/tests/test_semicolon_split.py::TestMultiline::test_multiline - RuntimeError: Running f2py failed: ['-m', 'multiline', '/tmp/tmpdksktw9k/tmpfttcvnmo.pyf']
ERROR ../../f2py/tests/test_semicolon_split.py::TestCallstatement::test_callstatement - RuntimeError: Running f2py failed: ['-m', 'callstatement', '/tmp/tmpdksktw9k/tmprepopx...
================================== 21 failed, 17995 passed, 905 skipped, 1301 deselected, 31 xfailed, 5 xpassed, 6 errors in 456.55s (0:07:36) ==================================

Running test_format on its own with python numpy/runtests.py -v -n -t /venv/lib/python3.10/site-packages/numpy/lib/tests/test_format.py passes OK, so I sort of feel like the issue running a full test might be memory related. If anybody has any insights on how to better replicate the test setup, I could certainly use them.

Dockerfile I've been using is in tools/Dockerfile.musl

@tgross35
Copy link
Author
tgross35 commented May 3, 2022

Alright, looks like -m full isn't a very big deal. It's just sticking on two tests, probably a limitation of my system, but they can be skipped with python /numpy/runtests.py -vv -n -m full -- -k 'not (test_large_archive or test_big_arrays)'. Test report is basically the same as in fast mode, with the added failure of test_mem_policy.

Edit: looks like it's not just my machine, I see the same test mentioned in #21425

Test report
============================================================ short test summary info ============================================================
FAILED ../../core/tests/test_longdouble.py::test_repr_roundtrip - AssertionError: 
FAILED ../../core/tests/test_mem_policy.py::test_new_policy - AssertionError: assert False
FAILED ../../core/tests/test_print.py::TestCommaDecimalPointLocale::test_locale_longdouble - AssertionError: 
FAILED ../../core/tests/test_scalarprint.py::TestRealScalars::test_dragon4_interface - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[f--4] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[f--2] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[f--1] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[f-1] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[f-2] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[f-4] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[d--4] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[d--2] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[d--1] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[d-1] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[d-2] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestFRExp::test_frexp[d-4] - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestComplexFunctions::test_precisions_consistent - AssertionError: 
FAILED ../../core/tests/test_umath.py::TestComplexFunctions::test_branch_cuts - AssertionError: (array([-1.57079633-0.54930614j, -1.57079633+0...
FAILED ../../core/tests/test_umath.py::TestComplexFunctions::test_branch_cuts_complex64 - AssertionError: (array([-1.5707963-0.54930615j, -1.5...
FAILED ../../core/tests/test_umath.py::TestComplexFunctions::test_loss_of_precision[complex64] - RuntimeWarning: divide by zero encountered in...
FAILED ../../core/tests/test_umath.py::TestComplexFunctions::test_loss_of_precision[complex128] - RuntimeWarning: divide by zero encountered i...
FAILED ../../core/tests/test_umath.py::TestComplexFunctions::test_loss_of_precision[complex256] - RuntimeWarning: divide by zero encountered i...
ERROR ../../f2py/tests/test_return_real.py::TestCReturnReal::test_all[t4] - RuntimeError: Running f2py failed: ['-m', 'c_ext_return_real', '/t...
ERROR ../../f2py/tests/test_return_real.py::TestCReturnReal::test_all[t8] - RuntimeError: Running f2py failed: ['-m', 'c_ext_return_real', '/t...
ERROR ../../f2py/tests/test_return_real.py::TestCReturnReal::test_all[s4] - RuntimeError: Running f2py failed: ['-m', 'c_ext_return_real', '/t...
ERROR ../../f2py/tests/test_return_real.py::TestCReturnReal::test_all[s8] - RuntimeError: Running f2py failed: ['-m', 'c_ext_return_real', '/t...
ERROR ../../f2py/tests/test_semicolon_split.py::TestMultiline::test_multiline - RuntimeError: Running f2py failed: ['-m', 'multiline', '/tmp/t...
ERROR ../../f2py/tests/test_semicolon_split.py::TestCallstatement::test_callstatement - RuntimeError: Running f2py failed: ['-m', 'callstateme...
=================== 22 failed, 19253 passed, 945 skipped, 2 deselected, 31 xfailed, 5 xpassed, 6 errors in 1763.75s (0:29:23) ===================

Since barrier to entry on debugging musl wheels was brought up as an annoyance in the mailing list, it's probably a good idea to clean up tools/Dockerfile.musl a bit and keep it around. My test setup kinda-sorta works, building the docker image then running dbgtests -t /numpy/core/tests/test_longdouble.py will allow a debug session to attach (I'm using vscode) and stack trace works, but breakpoints seem to be ignored. Still working on that. Relevant launch target for anyone else using vscode:

{
    "name": "Docker: Attach",
    "type": "python",
    "request": "attach",
    "localRoot": "${workspaceFolder}",
    "remoteRoot": "/numpy",
    "port": 5678,
    "host": "localhost",
    "justMyCode": true
}

@stefanv sorry to pull you out of the blue but I notice you did the Alpine docker work for multi-build from the thread here. Do you happen to have a good workflow for working with/debugging musl wheels?

@rgommers
Copy link
Member

Alright, looks like -m full isn't a very big deal. It's just sticking on two tests, probably a limitation of my system,

There should be O(50) tests, you can identify them by searching for pytest.mark.slow. The f2py ones won't run without a Fortran compiler I believe, the rest should though.

@rgommers
Copy link
Member

A lot of the failures seem related to long double. Those are unfortunately a pain to deal with (more trouble than they're worth, but we are stuck with them for right now).

@rgommers
Copy link
Member

A lot of the failures seem related to long double. Those are unfortunately a pain to deal with (more trouble than they're worth, but we are stuck with them for right now).

Looking at this again, I think it's actually fine to skip those tests for now. There's only a couple (e.g., the frexp ones are all views with negative strides on a longdouble arrray - that's 1 issue, not 11. The rest of the failures are also for pretty marginal stuff.
@tgross35 what do you think?

For keeping this in shape, we should add a regular musl CI job I think, rather than only a wheel build job.

if "musllinux" in auditwheel_plat:
suffix = f"musllinux_1_1_{arch}.tar.gz"
typ = "tar.gz"
elif osname == "linux":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Determining the glibc is a bit obscure. Perhaps this should undergo a deeper refactoring to better differentiate between musllinux and manylinux

@rgommers
Copy link
Member

After gh-22864, there is passing musllinux CI in the main branch, so we should be good on that. There's a lot in this PR that is probably no longer needed: the openblas_support bits have been merged, Dockerfile.musl seems like something that cibuildwheel should take care of (or am I missing something @tgross35, @andyfaff?), and some patches may no longer be needed.

Getting this PR in would be quite nice I think.

@andyfaff
Copy link
Member

cibuildwheel should take care of everything. There's a lot of changes in this PR that shouldn't be needed, it can
be stripped back a lot. Here are the changes that should be needed for a wheel:

  1. Changes to pyproject.toml look ok, they now allow musllinux_x86_64 to be built. Not super necessary to add image spec.
  2. Add [ubuntu-20.04, musllinux_x86_64] to buildplat in wheels.yml.

I don't think any other changes are needed. I experimented with this on my mac M1 and things mostly worked**. Note that I'm building the aarch64 architecture because that's the native CPU type for my machine, but it shouldn't be any different on x86_64.

# make change to pyproject.toml from step 1.
# make sure docker is running on my mac.
# pip install cibuildwheel into the Python environment on my mac.
CIBW_ARCHS=aarch64 CIBW_BUILD=cp310-musllinux_aarch64 cibuildwheel --platform linux

** there are some test failures, next comment.

@andyfaff
Copy link
Member
andyfaff commented Jan 20, 2023

@rgommers the test fails were observed by @tgross35 previously. It's not clear to me why they weren't picked up by python dev.py test in the CI job. Does that not run the full test suite by default? What would the numpy devs like to do here? Mark all of them as xfail, make new issues, and make the CI job run the full test suite?

(bear in mind that I'm testing musllinux_aarch64 not musllinux_x86_64, I don't know if the two will be different)

_____________________________ test_repr_roundtrip ______________________________

    @pytest.mark.skipif(LD_INFO.precision + 2 >= repr_precision,
                        reason="repr precision not enough to show eps")
    def test_repr_roundtrip():
        # We will only see eps in repr if within printing precision.
        o = 1 + LD_INFO.eps
>       assert_equal(np.longdouble(repr(o)), o, "repr was %s" % repr(o))
E       AssertionError: 
E       Items are not equal: repr was 1.0000000000000000000000000000000002
E        ACTUAL: 1.0
E        DESIRED: 1.0000000000000000000000000000000002

o          = 1.0000000000000000000000000000000002

/tmp/tmp.INgeBH/venv/lib/python3.10/site-packages/numpy/core/tests/test_longdouble.py:38: AssertionError
______________ TestCommaDecimalPointLocale.test_locale_longdouble ______________

self = <numpy.core.tests.test_print.TestCommaDecimalPointLocale object at 0xffff64ba0d90>

    def test_locale_longdouble(self):
>       assert_equal(str(np.longdouble('1.2')), str(float(1.2)))
E       AssertionError: 
E       Items are not equal:
E        ACTUAL: '1.1999999999999999555910790149937384'
E        DESIRED: '1.2'

self       = <numpy.core.tests.test_print.TestCommaDecimalPointLocale object at 0xffff64ba0d90>

/tmp/tmp.INgeBH/venv/lib/python3.10/site-packages/numpy/core/tests/test_print.py:200: AssertionError
_______ TestAsIntegerRatio.test_roundtrip[float128-frac_vals3-exp_vals3] _______

self = <numpy.core.tests.test_scalar_methods.TestAsIntegerRatio object at 0xffff64a8c760>
ftype = <class 'numpy.float128'>
frac_vals = [0.0, 0.20492557202724854, 0.4277180662199366, 0.9888085019891495, 0.9620175814461964]
exp_vals = [0, -7400, 14266, -7822, -8721]

    @pytest.mark.parametrize("ftype, frac_vals, exp_vals", [
        # dtype test cases generated using hypothesis
        # first five generated cases per dtype
        (np.half, [0.0, 0.01154830649280303, 0.31082276347447274,
                   0.527350517124794, 0.8308562335072596],
                  [0, 1, 0, -8, 12]),
        (np.single, [0.0, 0.09248576989263226, 0.8160498218131407,
                     0.17389442853722373, 0.7956044195067877],
                    [0, 12, 10, 17, -26]),
        (np.double, [0.0, 0.031066908499895136, 0.5214135908877832,
                     0.45780736035689296, 0.5906586745934036],
                    [0, -801, 51, 194, -653]),
        pytest.param(
            np.longdouble,
            [0.0, 0.20492557202724854, 0.4277180662199366, 0.9888085019891495,
             0.9620175814461964],
            [0, -7400, 14266, -7822, -8721],
            marks=[
                pytest.mark.skipif(
                    np.finfo(np.double) == np.finfo(np.longdouble),
                    reason="long double is same as double"),
                pytest.mark.skipif(
                    platform.machine().startswith("ppc"),
                    reason="IBM double double"),
            ]
        )
    ])
    def test_roundtrip(self, ftype, frac_vals, exp_vals):
        for frac, exp in zip(frac_vals, exp_vals):
            f = np.ldexp(ftype(frac), exp)
            assert f.dtype == ftype
            n, d = f.as_integer_ratio()
    
            try:
                nf = np.longdouble(n)
                df = np.longdouble(d)
            except (OverflowError, RuntimeWarning):
                # the values may not fit in any float type
                pytest.skip("longdouble too small on this platform")
    
>           assert_equal(nf / df, f, "{}/{}".format(n, d))
E           AssertionError: 
E           Items are not equal:
E           3691610919282409/754375680691097236033584094668765944067705441889753674869485796085770092515607327880959819087415077310180831709250071778801287977936115798436742371143992368453309871339424824507370309612423991424025874726454403135880239672556286954660294121782394806511373424058465039879202642605192131185743309561773056658185643547491539724788761769210570449719361033472835592719630976282559609730666069011705207542835117783529456159976771068263443230862911070356085655512183568229525202212897582406915374431067163048920606924662447046633826157512843858040924984315002169964536919904833881600804823521998389050496201243764285020447088741911345402883776356409423618880520468699696461129565113383915078637888733348216610096416629009182140275042468304535253989090448531420190513342250077305957003590418954211756405910688496208336958811080736128883827111614802254709920609202253178469621573457448759462719349118711156981864214570260508501086198368460193729395300772852011148550274868441005428390349180473804178677855504742682719953569150709524928692141975992287146458274133866411756809197929729769982812952002538493837333502552947090842216481359257075037724248961524397639883688816153646148628194727053307179727164298352718970844091417026255969094016476863206390918289333298449771866559630416885921333953743755493548839734888473604855021779585195333732043601711181668030053412580029770776192004858284404501049116419958516004280221863344539130718890716799847298773006561233919104469517725028712116182966271984150326053820625659202133419895341643186410353978237088665855990317609669897114719909146571036161198418024588113758379810073902705587813521979935291050562779838944606837754397025785661345639033424453056427885477427402278247912504082637379955585065327609406091875295801383271067322140033858622268255767636731544112870609623732470608795732545842544909415005476326698182515362320822724958131487825195570623952649884606742148812903910210714982986036413200478042831492804684264633275837769140282453505276667858585847988388110379917363524869040482763991338620804822859199828168115455114341494723055337599462542402834637455880078429265889822008874978612108568914036745145011041758569845539707668192653549132816696385729078204249119162383710467822172412843323817984
E            ACTUAL: 0.0
E            DESIRED: 4.8935974657884746723709777503783506e-2229

d          = 754375680691097236...2172412843323817984
df         = inf
exp        = -7400
exp_vals   = [0, -7400, 14266, -7822, -8721]
f          = 4.8935974657884746723709777503783506e-2229
frac       = 0.20492557202724854
frac_vals  = [0.0, 0.20492557202724854, 0.4277180662199366, 0.9888085019891495, 0.9620175814461964]
ftype      = <class 'numpy.float128'>
n          = 3691610919282409
nf         = 3691610919282409.0
self       = <numpy.core.tests.test_scalar_methods.TestAsIntegerRatio object at 0xffff64a8c760>

/tmp/tmp.INgeBH/venv/lib/python3.10/site-packages/numpy/core/tests/test_scalar_methods.py:106: AssertionError
____________________ TestRealScalars.test_dragon4_interface ____________________

self = <numpy.core.tests.test_scalarprint.TestRealScalars object at 0xffff662639a0>

    def test_dragon4_interface(self):
        tps = [np.float16, np.float32, np.float64]
        if hasattr(np, 'float128'):
            tps.append(np.float128)
    
        fpos = np.format_float_positional
        fsci = np.format_float_scientific
    
        for tp in tps:
            # test padding
            assert_equal(fpos(tp('1.0'), pad_left=4, pad_right=4), "   1.    ")
            assert_equal(fpos(tp('-1.0'), pad_left=4, pad_right=4), "  -1.    ")
>           assert_equal(fpos(tp('-10.2'),
                         pad_left=4, pad_right=4), " -10.2   ")
E           AssertionError: 
E           Items are not equal:
E            ACTUAL: ' -10.199999999999999289457264239899814'
E            DESIRED: ' -10.2   '

fpos       = <function format_float_positional at 0xffff7b119e10>
fsci       = <function format_float_scientific at 0xffff7b119d80>
self       = <numpy.core.tests.test_scalarprint.TestRealScalars object at 0xffff662639a0>
tp         = <class 'numpy.float128'>
tps        = [<class 'numpy.float16'>, <class 'numpy.float32'>, <class 'numpy.float64'>, <class 'numpy.float128'>]

/tmp/tmp.INgeBH/venv/lib/python3.10/site-packages/numpy/core/tests/test_scalarprint.py:276: AssertionError
___________________________ TestLog.test_log_values ____________________________

self = <numpy.core.tests.test_umath.TestLog object at 0xffff5eef9fc0>

    def test_log_values(self):
        x = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
        y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        for dt in ['f', 'd', 'g']:
            log2_ = 0.69314718055994530943
            xf = np.array(x, dtype=dt)
            yf = np.array(y, dtype=dt)*log2_
            assert_almost_equal(np.log(xf), yf)
    
        # test aliasing(issue #17761)
        x = np.array([2, 0.937500, 3, 0.947500, 1.054697])
        xf = np.log(x)
        assert_almost_equal(np.log(x, out=x), xf)
    
        # test log() of max for dtype does not raise
        for dt in ['f', 'd', 'g']:
            with np.errstate(all='raise'):
                x = np.finfo(dt).max
>               np.log(x)
E               FloatingPointError: overflow encountered in log

dt         = 'g'
log2_      = 0.6931471805599453
self       = <numpy.core.tests.test_umath.TestLog object at 0xffff5eef9fc0>
x          = 1.189731495357231765085759326628007e+4932
xf         = array([ 0.69314718, -0.06453852,  1.09861229, -0.05392834,  0.05325352])
y          = [0, 1, 2, 3, 4, 5, ...]
yf         = array([0.        , 0.69314718, 1.38629436, 2.07944154, 2.77258872,
       3.4657359 , 4.15888308, 4.85203026, 5.54517744, 6.23832463,
       6.93147181], dtype=float128)

/tmp/tmp.INgeBH/venv/lib/python3.10/site-packages/numpy/core/tests/test_umath.py:1297: FloatingPointError

@tgross35
Copy link
Author

Woah, it's been a while since I touched this. If the tests are now xfail, that's perfect. Silly long double... at least it's not i128 where llvm literally violates the Linux ABI with its alignment.

Regarding the changes I had in this PR:

  • wheels.yml don't need this, this was just to test the musl build on CI which acted different from my machine
  • getlimits.py I'd assume this is fixed, better, if you're now building the musl wheels
  • Dockerfile.musl this was also just for my debugging, don't need that
  • openblas_support.py this is fixed on main. Woohoo!
  • pyproject.toml this is the only useful difference, just enabling the wheel build (looks like it's still skipped).

So building the wheels are probably pretty trivial, if that's what you'd like to do (based on your comment here #20089 (comment) I suppose you could build and publish to GH but not PyPi, or something like that). Sorry I never wrapped this up, I was waiting on openblas and some other things and forgot to ever come back to it.

@andyfaff it looks like you're taking a look at this more than I currently have time to - care to open a new PR? If so, I'll close this one.

@rgommers
Copy link
Member

It's not clear to me why they weren't picked up by python dev.py test in the CI job. Does that not run the full test suite by default?

It does. The default test command is python -m pytest --rootdir=/Users/<username>/code/numpy/build-install/usr/lib/python3.<X>/site-packages numpy, (see here), so it's defaulting to the "full" mode rather than the "fast" mode that is the default of numpy.test().

Minor floating point printing differences like those are not all that surprising - and not very relevant imho. longdouble is a general pain point as you probably know. Just xfail-ing those tests is perfectly fine I'd say.

@andyfaff
Copy link
Member
andyfaff commented Feb 1, 2023

@mattip this can be closed now.

@mattip mattip closed this Feb 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Development

Successfully merging this pull request may close these issues.

6 participants
0