OpenCL with AMD Radeon GPUs on FreeBSD (Mesa rusticl)

There is no ROCm/HIP on FreeBSD. The path to OpenCL on AMD GPUs is Mesa’s rusticl backend, which exposes the same radeonsi Gallium driver used for desktop graphics as an OpenCL device. It works for real workloads — hashcat, OpenCL-accelerated video encoding, whisper.cpp with the OpenCL backend, the classic clinfo / clpeak suite.

Tested on FreeBSD 15.0-RELEASE amd64 with an AMD RX 6900 XT (Sienna Cichlid / navi21), but the recipe works for any AMD GPU supported by the in-kernel amdgpu driver (RDNA 1/2/3, Vega, Polaris).

TL;DR

doas pkg install -y graphics/drm-latest-kmod graphics/mesa-dri \
  graphics/mesa-libs devel/ocl-icd security/hashcat
doas sysrc kld_list+=amdgpu
doas pw groupmod video -m $(id -un)
doas shutdown -r now

# After reboot:
OCL_ICD_VENDORS=/usr/local/etc/OpenCL/vendors RUSTICL_ENABLE=radeonsi \
  hashcat -I

You should see Mesa Rusticl listed with your AMD GPU. If you get “No devices found”, scroll to the troubleshooting section.

What you’re installing and why

packagewhat it is
graphics/drm-latest-kmodThe amdgpu kernel module + GPU firmware blobs. On 14.x, use graphics/drm-61-kmod instead — it tracks the Linux 6.1 LTS DRM.
graphics/mesa-driMesa’s gallium drivers, including radeonsi for AMD GCN+ chips.
graphics/mesa-libsMesa’s userland libraries (libGL, libEGL, etc.).
devel/ocl-icdThe OpenCL ICD loader. Apps link against libOpenCL.so from this; it dispatches to whatever ICDs are installed.
security/hashcatOptional — but the easiest “is OpenCL working” test.

The Mesa packages on FreeBSD ship the rusticl ICD at /usr/local/etc/OpenCL/vendors/rusticl.icd. Hashcat (and any other Linux-leaning OpenCL app) looks at /etc/OpenCL/vendors by default, which doesn’t exist on FreeBSD. Hence the OCL_ICD_VENDORS env var later.

The two mandatory env vars

Every OpenCL run on FreeBSD with AMD needs both:

export OCL_ICD_VENDORS=/usr/local/etc/OpenCL/vendors
export RUSTICL_ENABLE=radeonsi
  • OCL_ICD_VENDORS — points the ICD loader at the right ICD directory.
  • RUSTICL_ENABLE=radeonsi — Mesa gates the radeonsi rusticl backend behind this var. Without it, rusticl loads but exposes zero devices.

Drop them into /etc/profile so login shells inherit them:

doas tee -a /etc/profile <<'EOF'
export OCL_ICD_VENDORS=/usr/local/etc/OpenCL/vendors
export RUSTICL_ENABLE=radeonsi
EOF

Cron jobs and systemd-style invocations don’t read /etc/profile; set them explicitly in those contexts.

Loading amdgpu at boot

Don’t kldload amdgpu after a desktop session is already running — on some boards the existing framebuffer console interferes and the GPU enters an inconsistent state. Always load it from kld_list:

doas sysrc kld_list+=amdgpu
doas shutdown -r now

After reboot:

$ kldstat | grep -E '(amdgpu|drm)'
 3    1 0xffffffff83400000   6ddad0 amdgpu.ko
 4    2 0xffffffff83310000    8a190 drm.ko
$ ls /dev/dri
card0  renderD128

renderD128 is what OpenCL actually uses (no display surface). card0 is for graphics.

Permissions: the video group

OpenCL apps need read/write on /dev/dri/renderD128. The default permissions are crw-rw---- root:video, so:

doas pw groupmod video -m $(id -un)
# log out and back in for the group to take effect

You can verify:

$ id
uid=1001(you) gid=1001(you) groups=1001(you),44(video),0(wheel),...
$ stat -f '%Sp %Su:%Sg' /dev/dri/renderD128
crw-rw---- root:video

Verifying

Quickest probe — clinfo from devel/clinfo:

$ doas pkg install -y devel/clinfo
$ OCL_ICD_VENDORS=/usr/local/etc/OpenCL/vendors RUSTICL_ENABLE=radeonsi clinfo
Number of platforms                               1
  Platform Name                                   rusticl
  Platform Vendor                                 Mesa/X.org
  ...
  Device Name                                     AMD Radeon RX 6900 XT (radeonsi, navi21, ...)
  Device Vendor                                   AMD
  Device Type                                     GPU
  ...

Or hashcat:

$ OCL_ICD_VENDORS=/usr/local/etc/OpenCL/vendors RUSTICL_ENABLE=radeonsi hashcat -I
OpenCL Info:
============
OpenCL Platform ID #1
  Vendor..: Mesa/X.org
  Name....: rusticl
  Version.: OpenCL 3.0
  Backend Device ID #1
    Type...........: GPU
    Vendor.ID......: 4098
    Vendor.........: AMD
    Name...........: AMD Radeon RX 6900 XT (...)
    Processor(s)...: 40
    Clock..........: 2250
    Memory.Total...: 16368 MB (free: 15234 MB)

A quick benchmark to confirm performance is reasonable:

OCL_ICD_VENDORS=/usr/local/etc/OpenCL/vendors RUSTICL_ENABLE=radeonsi \
  hashcat -b -m 0      # MD5 mode

For reference, an RX 6900 XT on rusticl gets ~50 GH/s on MD5 — within ~10% of the same card on Linux ROCm.

Performance notes

  • Multiple processes share the GPU. rusticl does not take an exclusive lock. Two hashcat runs against the same card both finish, with throughput split between them. Useful for ad-hoc short attacks alongside a long-running job.
  • No HIP, no ROCm. If a workload requires AMDGPU compute via HIP (PyTorch ROCm, llama.cpp HIP backend), it won’t work — only OpenCL via rusticl.
  • No multi-GPU peer access. Each GPU is a separate OpenCL device; you can’t do peer DMA between them.

Troubleshooting

symptomlikely cause
clinfo shows zero platformsOCL_ICD_VENDORS not set, or /usr/local/etc/OpenCL/vendors/rusticl.icd missing
clinfo shows rusticl platform but zero devicesRUSTICL_ENABLE not set
hashcat -I: “No devices found”one of the env vars; check both
radeonsi: failed to open deviceuser not in video group, or amdgpu not loaded
kldload amdgpu says firmware missinginstall/reinstall graphics/drm-latest-kmod (provides firmware)
Random GPU hangs / dmesg ring oopskldload-ed amdgpu after boot — load via kld_list and reboot instead
OpenCL works as root, not as userpw groupmod video -m $(id -un), then re-login

If you’re testing inside a jail and still get “No devices found” after both env vars are set, the host hasn’t exposed /dev/dri/* to the jail. See the companion post on OpenCL in FreeBSD jails.

See also