forked from JuliaLang/julia
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial support for RISC-V (JuliaLang#56105)
Rebase and extension of @alexfanqi's initial work on porting Julia to RISC-V. Requires LLVM 19. Tested on a VisionFive2, built with: ```make MARCH := rv64gc_zba_zbb MCPU := sifive-u74 USE_BINARYBUILDER:=0 DEPS_GIT = llvm override LLVM_VER=19.1.1 override LLVM_BRANCH=julia-release/19.x override LLVM_SHA1=julia-release/19.x ``` ```julia-repl ❯ ./julia _ _ _ _(_)_ | Documentation: https://docs.julialang.org (_) | (_) (_) | _ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help. | | | | | | |/ _` | | | | |_| | | | (_| | | Version 1.12.0-DEV.1374 (2024-10-14) _/ |\__'_|_|_|\__'_| | riscv/25092a3982* (fork: 1 commits, 0 days) |__/ | julia> versioninfo(; verbose=true) Julia Version 1.12.0-DEV.1374 Commit 25092a3* (2024-10-14 09:57 UTC) Platform Info: OS: Linux (riscv64-unknown-linux-gnu) uname: Linux 6.11.3-1-riscv64 #1 SMP Debian 6.11.3-1 (2024-10-10) riscv64 unknown CPU: unknown: speed user nice sys idle irq #1 1500 MHz 922 s 0 s 265 s 160953 s 0 s #2 1500 MHz 457 s 0 s 280 s 161521 s 0 s #3 1500 MHz 452 s 0 s 270 s 160911 s 0 s #4 1500 MHz 638 s 15 s 301 s 161340 s 0 s Memory: 7.760246276855469 GB (7474.08203125 MB free) Uptime: 16260.13 sec Load Avg: 0.25 0.23 0.1 WORD_SIZE: 64 LLVM: libLLVM-19.1.1 (ORCJIT, sifive-u74) Threads: 1 default, 0 interactive, 1 GC (on 4 virtual cores) Environment: HOME = /home/tim PATH = /home/tim/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/games TERM = xterm-256color julia> ccall(:jl_dump_host_cpu, Nothing, ()) CPU: sifive-u74 Features: +zbb,+d,+i,+f,+c,+a,+zba,+m,-zvbc,-zksed,-zvfhmin,-zbkc,-zkne,-zksh,-zfh,-zfhmin,-zknh,-v,-zihintpause,-zicboz,-zbs,-zvknha,-zvksed,-zfa,-ztso,-zbc,-zvknhb,-zihintntl,-zknd,-zvbb,-zbkx,-zkt,-zvkt,-zicond,-zvksh,-zvfh,-zvkg,-zvkb,-zbkb,-zvkned julia> @code_native debuginfo=:none 1+2. .text .attribute 4, 16 .attribute 5, "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zba1p0_zbb1p0" .file "+" .globl "julia_+_3003" .p2align 1 .type "julia_+_3003",@function "julia_+_3003": addi sp, sp, -16 sd ra, 8(sp) sd s0, 0(sp) addi s0, sp, 16 fcvt.d.l fa5, a0 ld ra, 8(sp) ld s0, 0(sp) fadd.d fa0, fa5, fa0 addi sp, sp, 16 ret .Lfunc_end0: .size "julia_+_3003", .Lfunc_end0-"julia_+_3003" .type ".L+Core.Float64#3005",@object .section .data.rel.ro,"aw",@progbits .p2align 3, 0x0 ".L+Core.Float64#3005": .quad ".L+Core.Float64#3005.jit" .size ".L+Core.Float64#3005", 8 .set ".L+Core.Float64#3005.jit", 272467692544 .size ".L+Core.Float64#3005.jit", 8 .section ".note.GNU-stack","",@progbits ``` Lots of bugs guaranteed, but with this we at least have a functional build and REPL for further development by whoever is interested. Also requires Linux 6.4+, since the fallback processor detection used here relies on LLVM's `sys::getHostCPUFeatures`, which for RISC-V is implemented using hwprobe introduced in 6.4. We could probably add a fallback that parses `/proc/cpuinfo`, either by building a CPU database much like how we've done for AArch64, or by parsing the actual ISA string contained there. That would probably also be a good place to add support for profiles, which are supposedly the way forward to package RISC-V binaries. That can happen in follow-up PRs though. For now, on older kernels, use the `-C` arg to Julia to specify an ISA. Co-authored-by: Alex Fan <alex.fan.q@gmail.com>
- Loading branch information
Showing
26 changed files
with
609 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// This file is a part of Julia. License is MIT: https://julialang.org/license | ||
|
||
#include "common.h" | ||
#include "../../src/jl_exported_funcs.inc" | ||
|
||
#define SEP ; | ||
|
||
#define XX(name) \ | ||
.global CNAME(name) SEP \ | ||
.cfi_startproc SEP \ | ||
.p2align 2 SEP \ | ||
CNAME(name)##: SEP \ | ||
auipc t3, %pcrel_hi(CNAMEADDR(name)) SEP \ | ||
ld t3, %pcrel_lo(CNAME(name))(t3) SEP \ | ||
jr t3 SEP \ | ||
.cfi_endproc SEP \ | ||
|
||
JL_RUNTIME_EXPORTED_FUNCS(XX) | ||
JL_CODEGEN_EXPORTED_FUNCS(XX) | ||
#undef XX |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
# RISC-V (Linux) | ||
|
||
Julia has experimental support for 64-bit RISC-V (RV64) processors running | ||
Linux. This file provides general guidelines for compilation, in addition to | ||
instructions for specific devices. | ||
|
||
A list of [known issues](https://github.com/JuliaLang/julia/labels/system:riscv) | ||
for RISC-V is available. If you encounter difficulties, please create an issue | ||
including the output from `cat /proc/cpuinfo`. | ||
|
||
|
||
## Compiling Julia | ||
|
||
For now, Julia will need to be compiled entirely from source, i.e., including | ||
all of its dependencies. This can be accomplished with the following | ||
`Make.user`: | ||
|
||
```make | ||
USE_BINARYBUILDER := 0 | ||
``` | ||
|
||
Additionally, it is required to indicate what architecture, and optionally which | ||
CPU to build for. This can be done by setting the `MARCH` and `MCPU` variables | ||
in `Make.user` | ||
|
||
The `MARCH` variable needs to be set to a RISC-V ISA string, which can be found by | ||
looking at the documentation of your device, or by inspecting `/proc/cpuinfo`. Only | ||
use flags that your compiler supports, e.g., run `gcc -march=help` to see a list of | ||
supported flags. A common value is `rv64gc`, which is a good starting point. | ||
|
||
The `MCPU` variable is optional, and can be used to further optimize the | ||
generated code for a specific CPU. If you are unsure, it is recommended to leave | ||
it unset. You can find a list of supported values by running `gcc --target-help`. | ||
|
||
For example, if you are using a StarFive VisionFive2, which contains a JH7110 | ||
processor based on the SiFive U74, you can set these flags as follows: | ||
|
||
```make | ||
MARCH := rv64gc_zba_zbb | ||
MCPU := sifive-u74 | ||
``` | ||
|
||
If you prefer a portable build, you could use: | ||
|
||
```make | ||
MARCH := rv64gc | ||
|
||
# also set JULIA_CPU_TARGET to the expanded form of rv64gc | ||
# (it normally copies the value of MCPU, which we don't set) | ||
JULIA_CPU_TARGET := generic-rv64,i,m,a,f,d,zicsr,zifencei,c | ||
``` | ||
|
||
### Cross-compilation | ||
|
||
A native build on a RISC-V device may take a very long time, so it's also | ||
possible to cross-compile Julia on a faster machine. | ||
|
||
First, get a hold of a RISC-V cross-compilation toolchain that provides | ||
support for C, C++ and Fortran. This can be done by checking-out the | ||
[riscv-gnu-toolchain](https://github.com/riscv-collab/riscv-gnu-toolchain) | ||
repository and building it as follows: | ||
|
||
```sh | ||
sudo mkdir /opt/riscv && sudo chown $USER /opt/riscv | ||
./configure --prefix=/opt/riscv --with-languages=c,c++,fortran | ||
make linux -j$(nproc) | ||
``` | ||
|
||
Then, install the QEMU user-mode emulator for RISC-V, along with `binfmt` | ||
support to enable execution of RISC-V binaries on the host machine. The | ||
exact steps depend on your distribution, e.g., on Arch Linux it involves | ||
installing the `qemu-user-static` and `qemu-user-static-binfmt` packages. | ||
Note that to actually execute RISC-V binaries, QEMU will need to be able to | ||
find the RISC-V system root, which can be achieved by setting the | ||
`QEMU_LD_PREFIX` environment variable to the path of the root filesystem. | ||
|
||
Finally, compile Julia with the following `Make.user` variables (in addition to | ||
the ones from the previous section): | ||
|
||
```make | ||
XC_HOST=riscv64-unknown-linux-gnu | ||
OS=Linux | ||
export QEMU_LD_PREFIX=/opt/riscv/sysroot | ||
``` | ||
|
||
Note that you will have to execute `make` with `PATH` set to include the | ||
cross-compilation toolchain, e.g., by running: | ||
|
||
```sh | ||
PATH=/opt/riscv/bin:$PATH make -j$(nproc) | ||
``` | ||
|
||
Because of the RISC-V sysroot we use being very barren, you may need to | ||
add additional libraries that the Julia build system currently expects | ||
to be available system-wide. For example, the build currently relies on | ||
a system-provided `libz`, so you may need to copy this library from the | ||
Julia build into the system root: | ||
|
||
```sh | ||
make -C deps install-zlib | ||
cp -v usr/lib/libz.* /opt/riscv/sysroot/usr/lib | ||
cp -v usr/include/z*.h /opt/riscv/sysroot/usr/include | ||
``` |
Oops, something went wrong.