This guide walks through cross-compiling IREE core runtime towards the RISC-V Linux platform. Cross-compiling IREE compilers towards RISC-V is not supported at the moment.
Cross-compilation involves both a host platform and a target platform. One invokes compiler toolchains on the host platform to generate libraries and executables that can be run on the target platform.
You'll need a RISC-V LLVM compilation toolchain and a RISC-V enabled QEMU emulator.
rvv-1.0.x-zfh
branch manually.An environment variable RISCV_TOOLCHAIN_ROOT
needs to be set to the root directory of the installed GNU toolchain. The variable can be used in building the RISCV target and a LLVM AOT module.
Execute the following script to download the prebuilt RISC-V toolchain and QEMU:
# In IREE source root $ ./build_tools/riscv/riscv_bootstrap.sh
NOTE:
RISCV_TOOLCHAIN_ROOT
(default at ${HOME}/riscv/toolchain/clang/linux/RISCV).Build and install at least the compiler tools on your host machine, or install them from a binary distribution:
$ cmake -G Ninja -B ../iree-build-host/ \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ -DCMAKE_INSTALL_PREFIX=../iree-build-host/install \ . $ cmake --build ../iree-build-host/ --target install
Debugging note: if IREE_LLVMAOT_LINKER_PATH
is set for targeting RISC-V then the build above will fail, and you should run unset IREE_LLVMAOT_LINKER_PATH
.
The following instruction shows how to build for the RISC-V 64-bit Linux machine and 32-bit bare-metal machine. For other RISC-V targets, please refer to riscv.toolchain.cmake as a reference of how to set up the cmake configuration.
$ cmake -G Ninja -B ../iree-build-riscv/ \ -DCMAKE_TOOLCHAIN_FILE="./build_tools/cmake/riscv.toolchain.cmake" \ -DIREE_HOST_BINARY_ROOT=$(realpath ../iree-build-host/install) \ -DRISCV_CPU=rv64 \ -DIREE_BUILD_COMPILER=OFF \ -DIREE_BUILD_SAMPLES=ON \ -DRISCV_TOOLCHAIN_ROOT=${RISCV_TOOLCHAIN_ROOT} \ .
For the RISC-V 32-bit bare-metal config, append the following CMake options
-DRISCV_CPU=rv32-baremetal \ -DIREE_BUILD_TESTS=OFF
$ cmake --build ../iree-build-riscv/
NOTE:The following instructions are meant for the RISC-V 64-bit Linux target. For the bare-metal target, please refer to simple_embedding to see how to build a ML workload for a bare-metal machine.
Set the environment variable RISCV_TOOLCHAIN_ROOT
if it is not set yet:
$ export RISCV_TOOLCHAIN_ROOT=<root directory of the RISC-V GNU toolchain>
Translate a source MLIR into IREE module:
$ ../iree-build-host/install/bin/iree-translate \ -iree-mlir-to-vm-bytecode-module \ -iree-hal-target-backends=vmvx \ ${PWD}/iree/samples/models/simple_abs.mlir \ -o /tmp/simple_abs_vmvx.vmfb
Then run on the RISC-V QEMU:
Set the path to qemu-riscv64 emulator binary in the QEMU_BIN
environment variable. If it is installed with riscv_bootstrap.sh
, the path is default at ${HOME}/riscv/qemu/linux/RISCV/bin/qemu-riscv64.
$ export QEMU_BIN=<path to qemu-riscv64 binary>
$ ${QEMU_BIN} \ -cpu rv64,x-v=true,x-k=true,vlen=256,elen=64,vext_spec=v1.0 \ -L ${RISCV_TOOLCHAIN_ROOT}/sysroot/ \ ../iree-build-riscv/iree/tools/iree-run-module \ --driver=vmvx \ --module_file=/tmp/simple_abs_vmvx.vmfb \ --entry_function=abs \ --function_input=f32=-5
Output:
I ../iree/tools/utils/vm_util.cc:227] Creating driver and device for 'vmvx'... EXEC @abs f32=5
To compile an IREE module using the Dylib LLVM ahead-of-time (AOT) backend for a RISC-V target we need to use the corresponding cross-compile toolchain.
Translate a source MLIR into an IREE module:
$ ../iree-build-host/install/bin/iree-translate \ -iree-mlir-to-vm-bytecode-module \ -iree-hal-target-backends=dylib-llvm-aot \ -iree-llvm-target-triple=riscv64 \ -iree-llvm-target-cpu=sifive-u74 \ -iree-llvm-target-abi=lp64d \ ${PWD}/iree/samples/models/simple_abs.mlir \ -o /tmp/simple_abs_dylib.vmfb
Then run on the RISC-V QEMU:
$ ${QEMU_BIN} \ -cpu rv64,x-v=true,x-k=true,vlen=256,elen=64,vext_spec=v1.0 \ -L ${RISCV_TOOLCHAIN_ROOT}/sysroot/ \ ../iree-build-riscv/iree/tools/iree-run-module \ --driver=dylib \ --module_file=/tmp/simple_abs_dylib.vmfb \ --entry_function=abs \ --function_input=f32=-5
Output:
I ../iree/tools/utils/vm_util.cc:227] Creating driver and device for 'dylib'... EXEC @abs f32=5
Through IREE's vectorization pass and LLVM backend, we can generate RVV VLS(Vector Length Specific) style codes.
$ ../iree-build-host/install/bin/iree-translate \ -iree-mlir-to-vm-bytecode-module \ -iree-hal-target-backends=dylib-llvm-aot \ -iree-llvm-target-triple=riscv64 \ -iree-llvm-target-cpu=sifive-7-rv64 \ -iree-llvm-target-abi=lp64d \ -iree-llvm-target-cpu-features="+m,+a,+d,+experimental-v" \ -riscv-v-vector-bits-min=128 -riscv-v-fixed-length-vector-lmul-max=8 \ /path/to/input.mlir -o /tmp/output-rvv.vmfb
Then run on the RISC-V QEMU:
$ ${QEMU_BIN} \ -cpu rv64,x-v=true,x-k=true,vlen=256,elen=64,vext_spec=v1.0 \ -L ${RISCV_TOOLCHAIN_ROOT}/sysroot/ \ ../iree-build-riscv/iree/tools/iree-run-module --driver=dylib \ --flagfile=/path/to/flagfile