Building rusticl

OpenCL has been with me for more than a decade, back when we decided to use it in our research project to make it the foundation for accelerating synchrotron imaging. Now, as history has shown, OpenCL never really took off, partially because Apple (the initial sponsor) dropped it but more importantly NVIDIA being very successful in locking in people with their proprietary CUDA solution. Nevertheless, support by all major GPU vendors is there to some degree, so software can be accelerated in a somewhat portable way. The degree AMD has taken is somewhat questionable though: they do support OpenCL either via their open ROCm stack but just for select GPUs and short support windows or via their proprietary amdgpu-pro packages. The latter is what I use today to enable OpenCL in Darktable but it is a hack because it involves downloading Debian packages from their website and extracting them correctly.

Fast forward to 2022, Rust is on its way to become the premier systems language and heroes like Karol Herbst start writing OpenCL mesa drivers completely alleviating the need for the crap AMD is offering (well almost). Because building and using it is not very straightforward at the moment, here are some hints how to do that. I am assuming an older Ubuntu 20.04 box, so some things could be in the 22.04 repos already.

Installing tools and dependencies

Add the LLVM apt repos

deb http://apt.llvm.org/focal/ llvm-toolchain-focal-15 main
deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-15 main

to /etc/apt/sources.list and run apt update. Install

$ apt install clang-15 libclang-15-dev llvm-15 llvm-15-dev llvm-15-tools

Ubuntu 20.04 comes with a pretty old version of meson, so lets create a virtualenv and install it along with mako which is used by mesa itself:

$ python3 -mvenv .venv
$ source .venv/bin/activate
$ pip3 install meson mako

We also need bindgen to bind to C functions but luckily the bindgen program is sufficient and can be installed easily with

$ cargo install bindgen-cli

Build rusticl

At the moment the radeonsi changes are not yet merged into the main branch, hence

$ git remote add superhero https://gitlab.freedesktop.org/karolherbst/mesa.git
$ git fetch superhero
$ git checkout -t rusticl/si

For some reason, rusticl won’t build with the LLVM 15 libraries as is and we have to add clangSupport to src/gallium/targets/opencl/meson.build as yet another clang library to link against in order to find some RISCV symbols. It’s time to configure the build with meson

$ meson .. -Dgallium-rusticl=true -Dllvm=enabled -Drust_std=2021 -Dvalgrind=disabled

Note that meson does not check for existence for Valgrind on Ubuntu and enables it by default causing build errors when the development libraries are not installed. Time to build and install using ninja

$ ninja build && ninja install

Running OpenCL programs

I tend to install mesa into a custom prefix and pre-load it with my old shell script. In order to have the system-wide ICD loader find the ICD that points to rusticl, we have to set the OPENCL_VENDOR_PATH environment variable to the directory containing the .icd, i.e. <some-prefix>/etc/OpenCL/vendors. Also we have to set the RUSTICL_ENABLE environment variable to radeonsi because it is not enabled by default yet. With that set clinfo should show a platform with the name rusticl.

Setting up rust-analyzer

If you intend to dig into rusticl itself you will notice that this is not your bog standard Cargo project but intertwined with meson which takes care of building the majority of the C and C++ sources. Because of this rust-analyzer is not able to figure out the structure of the rusticl project. Luckily, meson 0.64 produces a rust-project.json file that describes the structure but unfortunately the paths in there seem to be a bit messed up. After symlinking from the root of the Git repo (so rust-analyzer can find it) and changing the paths to point to existing directories, rust-analyzer was able to make sense of the project.