llvmlite icon indicating copy to clipboard operation
llvmlite copied to clipboard

Wheels built with RISC-V support, and other architectures generally

Open lochsh opened this issue 3 years ago • 20 comments

I have a dependency (https://github.com/m-labs/artiq) that depends on llvmlite -- however, it requires LLVM to be built with RISC-V support. The wheels that numba distribute on pypi.org are not built with this support.

This isn't a request for numba to start releasing wheels with target support for any architecture users ask for -- I'm aware that it might be a lot of maintenance work. I also understand that adding support for more target architectures may also make the already large wheels larger than desirable. My understanding of PEP440 is that it wouldn't be possible to have version numbers like 0.37.0-risc-v either -- so the question of how to manage separate wheels built for different architectures would also be an issue.

I'm curious if numba has any guidance or suggestions on how people have handled such issues in the past. I think perhaps M-Labs might have chosen to create a llvmlite-riscv project on pypi.org and made that their dependency -- and indeed, I could do the same.

I may also create a private fork of llvmlite within my organisation, that builds and deploys a wheel to our private PyPI server.

Any suggestions or knowledge on how other teams might have handled this are welcome :slightly_smiling_face: thank you.

lochsh avatar Nov 09 '21 18:11 lochsh

@lochsh thank you for asking about this. I think @gmarkall our resident RISC-V person may have some ideas about this one.

esc avatar Nov 09 '21 18:11 esc

Are there Docker images for RISC-V, and has anyone had success running them under QEMU? If that is possible, we could also consider adding Linux RISC-V as a supported architecture for llvmlite. (Numba will be much harder, and would come later.)

seibert avatar Nov 09 '21 19:11 seibert

Are there Docker images for RISC-V, and has anyone had success running them under QEMU?

I found this tracker for the progress of Docker RISC-V support https://github.com/carlosedp/riscv-bringup#virtual-machine-and-pre-built-docker

It's not immediately clear from looking at it what the state is, but a lot of the tasks are ticked which seems promising.

This companion blog post gives some more info https://carlosedp.medium.com/docker-containers-on-risc-v-architecture-5bc45725624b it looks like the author has indeed got docker running on RISC-V, and the tracker repo suggests those changes are upstreamed.

lochsh avatar Nov 09 '21 19:11 lochsh

I think I should have been a little clearer about my requirements here. I want to run llvmlite on my x86_64 Linux computer, but generate code for a RISC-V target, specifically riscv32-unknown-linux-elf. I don't need to run llvmlite on a RISC-V host. :slightly_smiling_face:

lochsh avatar Nov 09 '21 20:11 lochsh

Oh! I think that would require us to build LLVM with the RISC-V target enabled on x86 and link to that when building the llvmlite wheels. I'm not sure what the size difference is if we turn on additional targets, but that would be the only concern.

seibert avatar Nov 09 '21 20:11 seibert

Yes, indeed :smile: I have this working locally by following the manual build instructions in the llvmlite docs, but setting the LLVM_TARGETS_TO_BUILD environment variable to host;RISCV.

lochsh avatar Nov 09 '21 21:11 lochsh

I did a quick test, and adding the RISCV target to Linux x86_64 seems to add 6 MB to the LLVM compressed package size (which llvmlite end users do not install) and only 300 kB to the final llvmlite compressed package size thanks to static linking. Given the growing interest in RISC-V for microcontroller use, I think it makes sense to add it as a target on all platforms given the minor increase in size. (We already have NVPTX and AMDGPU enabled, which are probably much larger.)

Edit: In case people are curious, this is fractionally a 1.6% and 1.3% increase in package size, respectively.

seibert avatar Nov 11 '21 19:11 seibert

Ah thanks for that @seibert -- it's less of an increase than I thought, I'm glad you think it might make sense to add RISC-V as a target.

I was reminded by a colleague that we will probably soon need ARM Cortex A-9 as a target too :laughing: It might make sense for me to open a separate ticket for that. I will see if I can do my own experiment to see how much that would increase the package sizes, so I can at least try and make a compelling case for another architecture :slightly_smiling_face: I'll also check what the actual target would be.

lochsh avatar Nov 11 '21 20:11 lochsh

@palmer-dabbelt , ping on you

advancedwebdeveloper avatar Nov 11 '21 20:11 advancedwebdeveloper

@lochsh With Nix/Nixpkgs it takes 5 minutes (excluding recompilation time) and just a few commands to set up a llvmlite Python environment with a custom LLVM build, and with ARTIQ or whatever. There are also no issues with version numbers there as Nix environments are isolated and the same package can exist with different customizations in different environments. Alternatively, the conda-forge llvmlite package (which is what we recommend for non-Nix ARTIQ installations) has RISC-V enabled, though of course customizing that one is orders of magnitude more difficult and frustrating than with nixpkgs. You can also use our conda package which has some patches that haven't been merged upstream yet. https://conda.m-labs.hk/artiq-beta/linux-64/llvmlite-0.99-0.tar.bz2

I think perhaps M-Labs might have chosen to create a llvmlite-riscv project on pypi.org and made that their dependency

I'm afraid we do not have time to do that - our quota for thankless work is already exceeded by having to support Windows :) As you suggest, it's indeed a lot of (frustrating) maintenance work that simply does not exist on Nix systems where it is largely automated.

sbourdeauducq avatar Nov 16 '21 02:11 sbourdeauducq

Thanks @sbourdeauducq

I'm afraid we do not have time to do that - our quota for thankless work is already exceeded by having to support Windows :)

:laughing: I understand :+1:. To be clear, this was not a request for you to do this. I was pointing out to numba that this is a route their users might choose to take, to demonstrate that it's not necessary for numba to add RISC-V support to their releases of llvmlite in order for users to use llvmlite with RISC-V support within the Python packaging ecosystem. It would just be very convenient if numba were to do this.

There are also no issues with version numbers there as Nix environments are isolated and the same package can exist with different customizations in different environments.

I understand that Nix has worked out well for M-Labs. I've found great success using https://python-poetry.org/ for Python dependency management and packaging, which uses the PEP518 defined pyproject.toml. I think Python packaging has come a long way in the last 5 years, with tools like poetry and pipenv making reproducible virtual environments easy by mapping the entire Python dependency tree, and wheels making it easier to distribute packages with non-Python dependencies. poetry's resolver does not have the problems that e.g. pip does, where it can silently fail when conflicting dependency requirements are present.

I think if I were to explore using Nix, it would be in conjunction with poetry, rather than as a replacement. I don't think it's necessary to use Nix to get reproducible Python dependency trees, so it feels like a heavyweight solution to that problem for me, and one that sits outside of the wider Python ecosystem I wish to be a part of. I do understand the benefits of Nix being able to isolate the wider environment, beyond Python venvs, though :+1:

But apologies -- I don't think either of us are looking to debate this here. I just wanted to make it clear why I'm not using Nix for this and why it would be helpful for numba to distribute wheels with the target support artiq requires. Thanks again :slightly_smiling_face:

lochsh avatar Nov 16 '21 14:11 lochsh

FYI: I have a PR now to add RISC-V as a target on all platforms. If accepted, it should roll out with the next Numba/llvmlite release before the end of the year.

seibert avatar Nov 16 '21 14:11 seibert

Wonderful, thank you @seibert. I'm happy for this issue to be closed if/when that PR is accepted. I will consider opening a separate issue for Cortex A9 support. It's not something I need right now, but expect to need early next year.

lochsh avatar Nov 16 '21 14:11 lochsh

@stuartarchibald has suggested just turning on all the default LLVM targets, which are (for LLVM 11): AArch64, AMDGPU, ARM, BPF, Hexagon, Mips, MSP430, NVPTX, PowerPC, Sparc, SystemZ, X86, XCore. We can add back in RISCV, and we also have webassembly turned on as an experimental target already (it apparently becomes a regular target in LLVM 13).

I'm checking now how much that increases the size of the package, but I suspect it won't be a big deal.

seibert avatar Nov 16 '21 15:11 seibert

OK, turning on all those targets adds 30% to the size of both llvmdev and llvmlite. In the case of statically linked llvmlite, it grows from 22MB to 29MB. That still seems fine to me to solve basically all possible cross-compilation requests, but we'll have to see what the other maintainers think.

seibert avatar Nov 16 '21 16:11 seibert

Thanks again @seibert, I look forward to seeing what others think.

lochsh avatar Nov 16 '21 16:11 lochsh

For all use cases I'm aware of adding 7MB to the size of llvmlite would be un-noticeable (e.g. a CUDA toolkit package installed in the env weighs in at several hundred MB) so I'd be really happy to see the addition of all targets, and to have llvmlite as an easy platform for playing with generating assembly code for other targets.

gmarkall avatar Nov 16 '21 17:11 gmarkall

I agree with @gmarkall. Further, llvmlite's release cadence is pretty slow and the number of versions of a given release is proportional to the number of Python versions supported, so I think a few extra megabytes typically every few months (assuming users have a local cache) is negligible. I suppose my only concern is if llvmlite or Numba testing picks up or misses LLVM bugs due to doing unusual things or not having physical hardware, this may present additional support requirements. That said, I think it's worth a try, worse case it can be restricted again and re-shipped with a point release.

stuartarchibald avatar Nov 16 '21 17:11 stuartarchibald

@seibert many thanks for doing the testing!

stuartarchibald avatar Nov 16 '21 17:11 stuartarchibald

OK, I've upgraded #788 to add in every default target in LLVM 11 + RISC-V.

seibert avatar Nov 16 '21 21:11 seibert

I think this can be closed now - llvmlite now generally supports RISC-V as a target, IIUC... Any objections? (I need to open a new issue at some point to keep track of RISC-V host and JIT support, which I'll do at some point in the near future)

gmarkall avatar Dec 23 '22 16:12 gmarkall

Closing as no objections to closing have been received.

gmarkall avatar Mar 20 '23 12:03 gmarkall