Module 10
AMD ROCm & Efficient GPU Training
ROCm architecture, HIP GPU kernels in Rust, and the Haskell–Rust FFI bridge for GPU-accelerated training.
Learning Objectives
- Understand ROCm architecture and HIP programming
- Set up the ROCm development environment
- Implement efficient matrix operations in Rust/ROCm
- Bridge Haskell and Rust via C FFI
- Profile and achieve good GPU utilisation
10.1 ROCm Concepts
Why ROCm over CUDA
- AMD GPUs are more cost-effective
- Open-source ecosystem
- HIP (Heterogeneous-compute Interface for Portability) is similar to CUDA
Key Concepts
- Kernels — functions executed on the GPU across many parallel threads
- Waves/Workgroups — groups of threads executing in lockstep (analogous to CUDA warps/blocks)
- Local/Global Memory — per-workgroup cache vs. global GPU VRAM
- hipBLAS — AMD's BLAS library for GPU matrix operations (use this, don't implement your own gemm)
10.2 Setting Up ROCm
Bash — Ubuntu install
wget -q -O - https://repo.radeon.com/rocm/rocm.gpg.key | sudo apt-key add -
echo 'deb [arch=amd64] https://repo.radeon.com/rocm/apt/ubuntu focal main' \
| sudo tee /etc/apt/sources.list.d/rocm.list
sudo apt update
sudo apt install -y rocm-dkms rocm-libs rocm-hipclang rocm-cmake
sudo usermod -a -G video $USER # Logout and back in after this
# Verify
rocm-smi
hipcc --version
See Resources & Setup for the full installation walkthrough and troubleshooting.
10.3 Matrix Operations in Rust/ROCm
This is where you switch from Haskell to Rust for performance-critical code. hipBLAS handles the matrix multiplications on the GPU.
Rust — GPU matrix type with hipBLAS
use std::ffi::c_void;
pub struct HipMatrix {
data: *mut f32,
rows: usize,
cols: usize,
handle: hipblasHandle_t,
}
impl HipMatrix {
pub fn new(rows: usize, cols: usize) -> Self {
let size = rows * cols;
let mut data: *mut f32 = std::ptr::null_mut();
unsafe {
hipMalloc(
&mut data as *mut _ as *mut *mut c_void,
size * std::mem::size_of::<f32>()
);
}
let mut handle: hipblasHandle_t = std::ptr::null_mut();
unsafe { hipblasCreate(&mut handle); }
HipMatrix { data, rows, cols, handle }
}
/// Matrix multiply: C = A @ B using hipBLAS SGEMM
pub fn matmul(handle: hipblasHandle_t, a: &HipMatrix, b: &HipMatrix, c: &mut HipMatrix) {
unsafe {
hipblasSgemm(
handle,
HIPBLAS_OP_N, // A not transposed
HIPBLAS_OP_N, // B not transposed
a.rows as i32,
b.cols as i32,
a.cols as i32,
&1.0f32, // alpha
a.data, a.rows as i32,
b.data, b.rows as i32,
&0.0f32, // beta
c.data, c.rows as i32,
);
}
}
}
impl Drop for HipMatrix {
fn drop(&mut self) {
unsafe {
hipFree(self.data as *mut c_void);
hipblasDestroy(self.handle);
}
}
}
Cargo.toml — shared library for FFI
[package]
name = "llm-hip-kernels"
version = "0.1.0"
edition = "2021"
[dependencies]
# HIP bindings — adjust crate/version as ecosystem matures
[lib]
crate-type = ["cdylib"] # Produce .so for Haskell FFI
10.4 Haskell–Rust FFI Bridge
Haskell — declare Rust functions via C FFI
{-# LANGUAGE ForeignFunctionInterface #-}
import Foreign.Ptr (Ptr)
import Foreign.C.Types
-- Declare the Rust function exported with #[no_mangle] as a C symbol
foreign import ccall "hip_matmul" c_hip_matmul
:: Ptr CFloat -> CInt -> CInt -- Matrix A: data, rows, cols
-> Ptr CFloat -> CInt -> CInt -- Matrix B: data, rows, cols
-> Ptr CFloat -> CInt -> CInt -- Matrix C (output)
-> IO ()
-- Haskell wrapper: converts DenseMatrix to pinned CFloat arrays and calls kernel
hipMatmul :: DenseMatrix -> DenseMatrix -> IO DenseMatrix
hipMatmul a b = do
-- Allocate pinned memory, copy data, call c_hip_matmul, read back result
undefined
10.5 Profiling & Optimisation
Bash — ROCm profiling commands
# Kernel statistics
rocprof --stats ./your_program
# Full execution trace
rocprof --trace ./your_program
# GPU utilisation monitor
watch -n 1 rocm-smi
Optimisation Checklist
- Use hipBLAS for matrix operations — never roll your own GEMM
- Fuse operations where possible (e.g., A@B + bias in one kernel)
- Use FP16 for forward/backward passes (2× speedup)
- Minimise CPU↔GPU synchronisation
- Profile before optimising — find actual bottlenecks first
- Batch small operations to amortise kernel launch overhead
Reading & Viewing
Official documentation
ROCm Documentation
rocmdocs.amd.com
HIP Programming Guide
rocmdocs.amd.com — HIP Guide
hipBLAS API Reference
rocmdocs.amd.com — API Libraries
Rust GPU crates
Burn Framework (Rust DL)
Rust deep learning framework with ROCm/CUDA/WGPU backends — useful as a reference.
burn.dev
Paper
Demystifying GPU Microarchitecture through Microbenchmarking
Understanding the GPU execution model deeply.
arxiv.org/abs/1505.06352