Skip to content

CI: Add wheel building and testing on Linux-riscv64 - #31488

Merged
rgommers merged 3 commits into
numpy:mainfrom
luhenry:riscv
May 27, 2026
Merged

rgommers merged 3 commits into
numpy:mainfrom
luhenry:riscv

Conversation

@luhenry

@luhenry luhenry commented May 22, 2026

Copy link
Copy Markdown
Contributor

PR summary

Follow up to #30995 with ccache and in a separate linux_riscv64.yml.

AI Disclosure

AI tools used for research and understanding of the problem. Artisanal coding by (human) hands

cc @rgommers @andyfaff @gounthar

@luhenry luhenry changed the title Add wheel building and testing on Linux-riscv64 CI: Add wheel building and testing on Linux-riscv64 May 22, 2026
@luhenry

luhenry commented May 22, 2026 •

Copy link
Copy Markdown
Contributor Author

Tested at luhenry#1.

step cache cold cache hot
Running before_all 1.69s 1.90s
Building wheel 975s 157s
Testing wheel 846s 841s
Total 35m 43s 22m 11s

@gounthar

Copy link
Copy Markdown

Ran your branch (9f29dbe) on a Banana Pi F3 (SpaceMiT K1, rv64gc), since the CI job here is gated on approval. Built cp312-manylinux_riscv64 with cibuildwheel straight off the branch, about 38 min native.

Test suite (label='fast') came out at 45984 passed, 8 failed.

All 8 failures are the same test: linalg/tests/test_linalg.py::TestCholesky::test_basic_property, real float32 and float64, shapes (50, 50) and (3, 10, 10). The smaller shapes pass. cholesky raises "Matrix is not positive definite" (flag=8) on matrices that are positive definite by construction.

The wheel bundles scipy-openblas 0.3.33, so this looks like OpenBLAS#5811 (the riscv64 Cholesky regression) rather than anything in the workflow. The build and test plumbing themselves work end to end.

One practical thing I'm unsure about: since the riscv64 path runs label='fast' and that set includes these Cholesky cases, I'd expect the test step to hit the same 8 failures on the RISE runners until the OpenBLAS fix lands. Might be worth xfailing those four parametrized cases on riscv64 so the job can go green in the meantime, though you'd know better than me whether the runner hardware actually reproduces it.

Happy to rerun once there's a fix, to confirm it clears.

@luhenry

luhenry commented May 22, 2026

Copy link
Copy Markdown
Contributor Author

They don't fail on the RISE runners because the machines don't have RVV, so it doesn't hit the RVV-enabled path in OpenBLAS. You're hitting it on your BananaPi because it does have RVV.

@gounthar

Copy link
Copy Markdown

Ah, that explains it. I'd assumed the runners were RVV-capable, so the job goes green as-is and the xfail idea is moot.

The flip side, if I'm reading it right: OpenBLAS's RVV kernels then stay untested in this CI, so a regression like #5811 wouldn't get caught here. Not a blocker for this PR, more something to revisit if RVV-capable runners ever join the pool. You'd know that end better than I do. Happy to rerun on the F3 once the OpenBLAS fix lands.

@luhenry

luhenry commented May 26, 2026

Copy link
Copy Markdown
Contributor Author

@rgommers @andyfaff please let me know if there is anything else I should be doing on this PR. I would love to get the workflows going so that I can make sure everything's working on the upstream infra. Thank you!

@rgommers rgommers added this to the 2.6.0 Release milestone May 26, 2026

@rgommers rgommers left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks @luhenry, this looks great. Two minor comments to ensure we save the cache on main, so it's then usable in all PRs. With those, I think this can be merged.

I also considered adding cache hit stats, we can skip that for now since it's a little annoying - has to be done outside the container cibuildwheel runs in. If we want it in the future for debugging, it should be something like:

  - name: Install ccache (host)
    run: |
      CCACHE_VERSION=4.13.6
      curl -fsSL https://github.com/ccache/ccache/releases/download/v${CCACHE_VERSION}/ccache-${CCACHE_VERSION}-linux-$(uname -m)-musl-static.tar.gz | \
        sudo tar -xzf - --strip-components 1 -C /usr/local/bin ccache-${CCACHE_VERSION}-linux-$(uname -m)-musl-static/ccache

  - name: Ccache performance
    run: |
      ccache --evict-older-than 1d
      ccache -s

Comment thread .github/workflows/linux_riscv64.yml Resolved
Comment thread .github/workflows/linux_riscv64.yml Resolved
@luhenry

luhenry commented May 27, 2026

Copy link
Copy Markdown
Contributor Author

I also considered adding cache hit stats, we can skip that for now since it's a little annoying - has to be done outside the container cibuildwheel runs in. If we want it in the future for debugging, it should be something like:

  - name: Install ccache (host)
    run: |
      CCACHE_VERSION=4.13.6
      curl -fsSL https://github.com/ccache/ccache/releases/download/v${CCACHE_VERSION}/ccache-${CCACHE_VERSION}-linux-$(uname -m)-musl-static.tar.gz | \
        sudo tar -xzf - --strip-components 1 -C /usr/local/bin ccache-${CCACHE_VERSION}-linux-$(uname -m)-musl-static/ccache

  - name: Ccache performance
    run: |
      ccache --evict-older-than 1d
      ccache -s

Yes I considered it. The easiest way would have been to do a CIBW_AFTER_ALL_LINUX, but that doesn't exist unfortunately.

@rgommers rgommers left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM now, modulo the minor issue with paths-ignore duplication, I'll fix that with a skip-ci commit, then get this in to exercise it on main and verify the caching works as expected. Thanks again @luhenry!

Comment thread .github/workflows/linux_riscv64.yml Resolved
@rgommers
rgommers merged commit ea9cae7 into numpy:main May 27, 2026
@rgommers

Copy link
Copy Markdown
Member

There's a couple of warnings visible in the logs, for pocketfft for building, and a hypothesis-internal issue for testing. Neither are critical, and can be resolved later.

@rgommers

Copy link
Copy Markdown
Member

Bad luck, the job on the merge commit segfaulted (see this CI log):

........................................................................ [  4%]
  Fatal glibc error: pthread_mutex_lock.c:94 (___pthread_mutex_lock): assertion failed: mutex->__data.__owner == 0
  Fatal Python error: Aborted
  Thread 0x0000003fbeffd180 (most recent call first):
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/execnet/gateway_base.py", line 534 in read
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/execnet/gateway_base.py", line 567 in from_io
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/execnet/gateway_base.py", line 1160 in _thread_receiver
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/execnet/gateway_base.py", line 341 in run
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/execnet/gateway_base.py", line 411 in _perform_spawn
  Thread 0x0000003fbf7fe180 (most recent call first):
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/execnet/gateway_base.py", line 534 in read
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/execnet/gateway_base.py", line 567 in from_io
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/execnet/gateway_base.py", line 1160 in _thread_receiver
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/execnet/gateway_base.py", line 341 in run
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/execnet/gateway_base.py", line 411 in _perform_spawn
  Thread 0x0000003fbffff180 (most recent call first):
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/execnet/gateway_base.py", line 534 in read
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/execnet/gateway_base.py", line 567 in from_io
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/execnet/gateway_base.py", line 1160 in _thread_receiver
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/execnet/gateway_base.py", line 341 in run
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/execnet/gateway_base.py", line 411 in _perform_spawn
  Current thread 0x0000003fc4e5d180 (most recent call first):
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/execnet/gateway_base.py", line 534 in read
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/execnet/gateway_base.py", line 567 in from_io
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/execnet/gateway_base.py", line 1160 in _thread_receiver
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/execnet/gateway_base.py", line 341 in run
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/execnet/gateway_base.py", line 411 in _perform_spawn
  Thread 0x0000003fd160f020 (most recent call first):
    File "/opt/python/cp312-cp312/lib/python3.12/threading.py", line 359 in wait
    File "/opt/python/cp312-cp312/lib/python3.12/queue.py", line 180 in get
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/xdist/dsession.py", line 154 in loop_once
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/xdist/dsession.py", line 138 in pytest_runtestloop
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/pluggy/_callers.py", line 121 in _multicall
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/pluggy/_manager.py", line 120 in _hookexec
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/pluggy/_hooks.py", line 512 in __call__
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/_pytest/main.py", line 372 in _main
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/_pytest/main.py", line 318 in wrap_session
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/_pytest/main.py", line 365 in pytest_cmdline_main
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/pluggy/_callers.py", line 121 in _multicall
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/pluggy/_manager.py", line 120 in _hookexec
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/pluggy/_hooks.py", line 512 in __call__
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/_pytest/config/__init__.py", line 199 in main
    File "/tmp/tmp.wr4falSCQb/venv/lib/python3.12/site-packages/numpy/_pytesttester.py", line 182 in __call__
    File "<string>", line 1 in <module>
  Extension modules: numpy._core._multiarray_umath, numpy.linalg._umath_linalg (total: 2)
  /project/tools/wheels/cibw_test_command.sh: line 37:  1908 Aborted                 (core dumped) python -c "import sys; import numpy; sys.exit(not numpy.test(label='fast', extra_argv=['-n=auto', '--durations=10']))"
  ....................::endgroup::Testing wheel...

Not informative. This job passes multiple times before merging, so there is a real bug but probably infrequent. Needs to be figured out, might help to add -v to the test invocation, so we at least see what it crashes on. I'll also re-run it now to make sure it succeeds once on main to populate the cache.

@luhenry

luhenry commented May 27, 2026

Copy link
Copy Markdown
Contributor Author

That is a known but very very infrequent hardware bug. In the 400-500 jobs/day I see go by, I probably see it 2-4 times/week. Bad luck indeed. The issue is the hardware has a bug in its atomic operation implementation where a CAS can sometimes return "success" when it wasn't actually a success. In this case, a pthread_mutex_lock "succeeded" when it shouldn't have as another thread was holding the mutex already.

@rgommers

Copy link
Copy Markdown
Member

Ah, good to know - "hardware bug" was not one of the things that came to mind as a candidate root cause:)

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.

4 participants