Repository navigation
Conversation
|
Thanks @gounthar. I appreciate the introduction as well (that's new in our PR template, you may be the first one to use it!). Note that this won't close the linked issue, because that's asking for wheels on PyPI rather than only a CI job. We don't publish from this repo, so this does only the latter. Before I trigger a whole battery of CI, let me ask if you have a CI log of a passing build on your own fork? That's the usual way to develop a new job, since you can run just that one job rather than ~70 jobs. |
|
Thanks for the welcome @rgommers! Here's a passing CI run on our fork: https://github.com/gounthar/numpy/actions/runs/22899916618 It builds the Happy to adjust anything based on your review. |
|
FWIW, 38 minutes is longer than any other CI job we're currently running. |
|
@ngoldbaum Fair concern on the 38-minute build time: that's QEMU emulation overhead. A native riscv64 build would be significantly faster. 🤞 https://cloud-v.co/ provides free self-hosted GitHub Actions runners on real riscv64 hardware to open source projects. If NumPy is open to a self-hosted runner approach, that would cut the build time substantially and also give more reliable test results than emulation. In the meantime, is the 38-minute QEMU job acceptable as a starting point, or would you prefer to wait for a native runner solution? |
|
This is really quite slow, and it doesn't add much over this job which tests most of the very platform-specific code we have: numpy/.github/workflows/linux_qemu.yml Line 71 in 581d10f So I'd prefer to only add a new job if we can have a native runner with reasonable stability and performance. I commented at #30216 (comment) with my preferred option. |
|
Makes sense: QEMU is indeed painfully slow for a full test suite. I'll rework this PR to target Cloud-V native runners instead. I'll install the Cloud-V GitHub App on my fork first to validate the workflow (runner provisioning, caching, build times) and update this PR once it's working reliably. |
|
Sounds good, thanks @gounthar |
|
Things are progressing in #30216 thanks to the help of rise. |
53b0205 to
a955ae2
Compare
|
Updated this PR to use native riscv64 runners from RISE instead of QEMU emulation. Build time: ~3.5 minutes on native hardware vs ~38 minutes under QEMU. The approach was validated on a fork with RISE runners: riseproject-dev#1 Key changes from the original PR:
Thanks to @luhenry and the RISE project for providing the native runners and for their support on the riscv64 Python ecosystem. |
|
Thanks for the update, that sounds promising.
The latest CI log seems to say 18 minutes in total, and the tests didn't get run? Is that run-to-run variation with getting different hardware allocated to the job, or something else? |
|
@rgommers Good catch — let me clarify the numbers:
The Docker image pull is a one-time cost that would be cached on subsequent runs. The build step itself is comparable to other architectures. Regarding tests: the current PR uses a smoke test ( Once the RISE runners are installed on numpy's org, we can iterate on getting the full test suite working in CI. |
|
Not quite I think. At least in the raw GitHub log with timestamps, the build lasts from 18:46:21 to 18:58:04, which is 11 min 45 sec. And pulling the Either way, we can give it a go though. |
|
@rgommers You're right, I was looking at a different metric. The actual wheel build is ~12 minutes, not 3.5. Thanks for the careful log analysis. Still a big improvement over 38 minutes under QEMU, and the Docker pull will cache on subsequent runs. Glad we can give it a go! I'm running the full numpy test suite natively on the BananaPi F3 right now (skipping f2py which needs gfortran for test collection). Will share the results once it completes. |
|
@rgommers Full native test suite results from BananaPi F3 (SpacemiT K1, rv64gc): 47,447 passed, 4 failed, 1,301 skipped, 10 errors in 42 minutes. Pass rate: 99.97% The 4 failures are NOT riscv64-specific:
The 10 errors are all f2py tests were excluded (need gfortran for test collection, separate from numpy core). numpy works on RISC-V. |
|
Update: installed Cython + meson on the F3; Updated numbers: 47,448 passed, 3 failed, 1,301 skipped, 10 errors: 99.97% pass rate on native riscv64. |
|
@rgommers very good to meet at PyTorch Conf this week! Please let me know how you would want to proceed, and happy to help in any way. |
a955ae2 to
114521c
Compare
andyfaff
left a comment
There was a problem hiding this comment.
Has the RISE Github app already been connected?
|
@andyfaff Not yet. The RISE runners app would need to be installed on the numpy org by a maintainer. My fork validation ran on riseproject-dev/numpy where it's already set up. @luhenry can help with any questions on the runner side if needed. |
|
@gounthar the actions/setup-python should now work with |
@rgommers would know more about that AFAIU |
|
Simplifying the change at https://github.com/luhenry/numpy/tree/add-riscv64-wheels. I'm debugging an issue with the |
|
Getting there, down to 34 minutes in this job after including test selection changes in gh-31420:
Build and test phase are then taking about as long. We may indeed want to consider changing this job to use I think we don't necessarily need to keep things in |
|
@rgommers the first line did it: |
|
I see it also on the BananaPi F3: |
|
I ran this on some new RISC-V hardware,SpacemiT K3. I ran this in a Fedora 43 container. That was my setup: Ran NumPy's bundled test suite; it failed with a bunch of tests I've attached the full log here (232KB): |
|
Thanks @kashyapc! Could you post a traceback on one of the |
|
Reproduced on my BananaPi F3 (SpaceMiT K1, rv64gc). Walking back my earlier "0 accuracy failures" comment, that was based on a different setup (system numpy with system OpenBLAS), not this PR's wheel. Sorry for the noise. Running rgommers' minimal repro with the wheel from runs/25744398974: Same machine, swapping in system numpy 2.4.3 with system OpenBLAS 0.3.29 (libopenblas0 0.3.29+ds-3, Debian 13 trixie): cholesky succeeds. So cholesky is correctly rejecting a matrix that the matmul step computed wrong. The bug is upstream of cholesky, in OpenBLAS GEMM/SYRK on K1. Either a regression between 0.3.29 and 0.3.33, or a packaging difference between Debian's build and scipy-openblas's. Both targets compile to riscv64_generic, so it's not vector-related. Lines up with what eshattow showed: Pine64 Star64 (StarFive JH-7110, SiFive U74) doesn't reproduce this, while threexc's Muse Pi Pro and my F3 (both K1) do. K1-specific so far. I can bisect 0.3.30 through 0.3.32 and open an upstream OpenBLAS issue once I've narrowed the range. Will report back. |
|
Bisected on the BananaPi F3 (LD_PRELOAD swap of
Clean break between OpenBLAS 0.3.31 and 0.3.33 (no 0.3.32 in scipy-openblas64 PyPI). The K1 has no RVV, so DYNAMIC_ARCH dispatches to riscv64_generic kernels. 250 commits between the v0.3.31 and v0.3.33 tags. Filing an upstream OpenBLAS issue with the repro and this bisect range. Will link back here. |
|
Upstream issue filed: OpenMathLib/OpenBLAS#5811 |
What do you mean by "no RVV"? The K1 is advertised as RVA22 + RVV 1.0. |
Of course if 34 minutes is tolerance for a little while, we can also decide to just merge this as is now, so we get some hands-on experience. If new hardware is coming in the summer that's 2-3x faster, that will address the performance and it'll be fine with no further changes needed. Currently the other two slowest jobs:
We can turn off the Qemu riscv64 test if this new one is stable, so the overall extra runtime before that new hardware arrives only takes a minor hit. There's something to say for any of these options:
@andyfaff any preferences? |
|
I think options 2 or 3 are preferable . |
Looking at the data, there are around ~300-350 wheels.yml workflow runs / 30day. At 30min per run, the load on the infra infrastructure would be negligible. (we are currently at the 300-500 runs/day and the infra is far from peak capacity).
To me, the main question is what you, as maintainers, are happy to take on. We should make the load as small as possible for everyday's maintainers and contributors, and riscv64 shouldn't be a pain point. I don't think we are in such a rush (we all want to see it integrated!) that we can't work on some workarounds before merging (split out of wheels.yml? ccache? all of the above?). Integrating
It's worth trying out, I can give it a try today or tomorrow. |
|
Okay, option (3) it is:)
Interesting, I didn't see that before. We normally use regular https://github.com/actions/cache and set In SciPy we recently overhauled this and made sure the behavior was optimal for cache hits and storage consumption. It uses a generic composite action (this one) and then there's still two job steps per job that uses If https://github.com/hendrikmuhs/ccache-action works the same, I think we can use that.
Agreed.
That isn't even necessary (except for
That would be great, thanks. I'd suggest creating a new |
The main advantage I saw to this https://github.com/hendrikmuhs/ccache-action is that you can selectively save. You can save on workflows to main, and never save on workflows on pull requests for example. This way you have a good "hot" cache but don't pollute it with many from pull requests.
We would want to mount the ccache dir from the host and so need to point the ccache inside the container to that directory. So if meson automatically picks it up it's a lot easier indeed. |
|
You're right, I had this completely wrong. The K1 X60 cores do implement RVV 1.0 (the ISA string in /proc/cpuinfo shows Re-checked with So OpenBLAS DYNAMIC_ARCH dispatches to the riscv64_zvl256b kernels on the K1, not generic. The bisect range is unchanged (0.3.31.188.0 OK, 0.3.33.0.0 broken), but the regression is somewhere in the vector kernels (or something they call), not the scalar generic path. That actually fits the earlier observation that the Pine64 Star64 (SiFive U74, no RVV, dispatches to riscv64_generic) does not reproduce. Same regression range, different kernel path, different result, and the failing path is the vectorized one. Updating OpenMathLib/OpenBLAS#5811 with the corrected dispatch info. |
@rgommers Hey, can you please try again the link in my comment here. (I fixed the formatting, but the same link worked for me.) As for traceback, I'll let you know once I get it. |
|
The 8 The 9 So nothing in this PR's diff is implicated by either bucket: the build is clean and the job is green. The Cholesky path will stay red on K1/K3 hardware until the OpenBLAS fix lands, and I'm tracking that at #5811. |
The relevant part of the traceback is this: At first sight that looks like an incomplete Python install, e.g. |
|
Confirming @rgommers's read with a data point from native riscv64. On the BPI-F3 (SpaceMiT K1, Armbian trixie), the same cp312 wheel from this PR's CI ( The only difference is the Python: the venv here uses a standalone 3.12 that ships |
|
Submitted a PR for adding ccache support: #31474 |
|
Go for it, Ludovic. You've already got the working version in #31474, so it makes sense for you to extract it rather than me copying it over. Once linux_riscv64.yml is up I'll run it against the Banana Pi F3 (native K1) and review. Thanks for offering either way. |
|
Thank you for being understanding, https://github.com/numpy/numpy/blob/main/.github/workflows/linux-ibm.yml is an example to base the file off. |
|
gh-31488 was merged and incorporated most of this PR, so I'll close this now. Thanks all! |

PR summary
Add
manylinux_riscv64to the wheel build matrix using native riscv64 runners provided by the RISE RISC-V Software Ecosystem project.Changes:
.github/workflows/wheels.yml: Add[ubuntu-24.04-riscv, manylinux_riscv64, ""]to the build matrix. Install cibuildwheel directly (actions/setup-python lacks riscv64 pre-built binaries). Use smoke test for riscv64 test phase.pyproject.toml: Addmanylinux-riscv64-image = "manylinux_2_39"(manylinux_2_28 has no riscv64 support).Why native runners instead of QEMU:
The RISE RISC-V runners are free for open source projects and provide native hardware (Scaleway EM-RV1). numpy is a priority project for RISE with no limitations on concurrent jobs.
Reference: Ludovic Henry's comment on #30216
Evidence:
numpy-2.5.0.dev0-cp312-cp312-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whlFirst time committer introduction
I'm Bruno Verachten (@gounthar), working on RISC-V software ecosystem enablement since 2022. I maintain a community PEP 503 index with 50+ riscv64 Python wheels built natively on BananaPi F3 boards. I use NumPy for data processing and benchmarking on RISC-V hardware, and I'm collaborating with the RISE project to bring native riscv64 CI to key Python packages.
AI Disclosure
No AI tools used.
Note: this work is part of the RISE Project effort to improve Python ecosystem support on riscv64 platforms.