Skip to content

RISC-V cross-compilation

Running on a platform like RISC-V involves cross-compiling from a host platform (e.g. Linux) to a target platform (a specific RISC-V CPU architecture and operating system):

  • IREE's compiler is built on the host and is used there to generate modules for the target
  • IREE's runtime is built on the host for the target. The runtime is then pushed to the target to run natively.

Prerequisites

Host environment setup

You should already be able to build IREE from source on your host platform. Please make sure you have followed the getting started steps.

Install RISC-V cross-compile toolchain and emulator

You'll need a RISC-V LLVM compilation toolchain and a RISC-V enabled QEMU emulator.

See instructions in the following links

Note

The RISCV_TOOLCHAIN_ROOT environment variable needs to be set to the root directory of the installed GNU toolchain when building the RISC-V compiler target and the runtime library.

Install prebuilt RISC-V tools (RISC-V 64-bit Linux toolchain)

Execute the following script to download the prebuilt RISC-V toolchain and QEMU from the IREE root directory:

./build_tools/riscv/riscv_bootstrap.sh

Support vector extension

For RISC-V vector extensions support, see additional instructions

Configure and build

Host configuration

Build and install on your host machine:

cmake -GNinja -B ../iree-build/ \
  -DCMAKE_C_COMPILER=clang \
  -DCMAKE_CXX_COMPILER=clang++ \
  -DCMAKE_INSTALL_PREFIX=../iree-build/install \
  -DCMAKE_BUILD_TYPE=RelWithDebInfo \
  .
cmake --build ../iree-build/ --target install

Target configuration

The following instruction shows how to build for a RISC-V 64-bit Linux machine. For other RISC-V targets, please refer to riscv.toolchain.cmake as a reference of how to set up the cmake configuration.

RISC-V 64-bit Linux target

cmake -GNinja -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 \
  -DRISCV_TOOLCHAIN_ROOT=${RISCV_TOOLCHAIN_ROOT} \
  .

Running IREE bytecode modules on the RISC-V system

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 path to qemu-riscv64 Linux 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>

Invoke the host compiler tools to produce a bytecode module flatbuffer:

../iree-build/install/bin/iree-translate \
  -iree-mlir-to-vm-bytecode-module \
  -iree-hal-target-backends=vmvx \
  iree/samples/models/simple_abs.mlir \
  -o /tmp/simple_abs_vmvx.vmfb

Run the RISC-V emulation:

${QEMU_BIN} \
  -cpu rv64 \
  -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

Optional configuration

RISC-V Vector extensions allows SIMD code to run more efficiently. To enable the vector extension for the compiler toolchain and the emulator, build the tools from the following sources:

The SIMD code can be generated following the IREE dynamic library CPU HAL driver flow with the additional command-line flags

iree/tools/iree-translate \
  -iree-mlir-to-vm-bytecode-module \
  -iree-hal-target-backends=dylib-llvm-aot \
  -iree-llvm-target-triple=riscv64 \
  -iree-llvm-target-cpu=generic-rv64 \
  -iree-llvm-target-abi=lp64d \
  -iree-llvm-target-cpu-features="+m,+a,+f,+d,+v" \
  -riscv-v-vector-bits-min=256 -riscv-v-fixed-length-vector-lmul-max=8 \
  iree_input.mlir -o mobilenet-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=mobilenet-dylib.vmfb \
  --entry_function=predict \
  --function_input="1x224x224x3xf32=0"
Back to top