GPU kernels
Every par block becomes a GPU kernel, generated by xcc and carried inside the executable.
This is zero-dependency GPU inlining: building needs no CUDA toolkit, no shader
compiler, no Metal toolchain and no GPU SDK, and running needs only the driver the operating
system already provides.
Four kernel languages, one compiler
Section titled “Four kernel languages, one compiler”xcc’s own printers turn a block’s IR into each GPU’s kernel language:
| GPU API | Kernel form | Generated as | Compiled for the GPU by |
|---|---|---|---|
| Metal | Metal Shading Language | text | the system Metal framework, at first use |
| CUDA | PTX | text | the NVIDIA driver’s JIT, at first use |
| Vulkan | SPIR-V | binary | the Vulkan driver |
| WebGPU | WGSL | text | the browser |
Kernels are printed from a copy of the block’s IR that has been through the kernel optimiser first. Where a GPU needs a different form, xcc prints one: a block whose range fits 32 bits gets a SPIR-V form with no 64-bit integers, which the Raspberry Pi 5’s VideoCore GPU runs, and a variant that runs several loop trips per exit test is chosen on the GPUs where it is faster.
Inside the executable
Section titled “Inside the executable”Each block’s kernels sit in one constant blob in the program’s data, one section per form, each with a header the runtime reads: the range, the buffers and globals, the reductions, each array’s footprint per item, the cost-model figures and any run-time guards. Which forms a program carries follows its target:
| Target | Kernel forms |
|---|---|
| macOS on Apple silicon | Metal |
| Linux x86-64, Windows x64 | PTX and SPIR-V |
| Linux arm64, Android | SPIR-V |
| WebAssembly in a browser | WGSL |
-fpar-kernels=all puts every form in, so that a GPU on another
machine finds the one it takes.
At run time
Section titled “At run time”Each GPU runtime is opened the first time a block asks for a GPU: Metal through the system
framework, CUDA through the driver library (libcuda, nvcuda.dll), Vulkan through the
loader (libvulkan, vulkan-1.dll), WebGPU through the browser. Where none is present,
every block runs on the CPU, and the program still works.
What the dependence on the driver means in practice:
- the driver, framework or browser compiles the kernel text at its first use, inside the block’s first, uncounted run;
- a GPU driver is a shared library, so a Linux program linked with
-staticruns its blocks on the CPU; - CUDA is used on Windows and x86-64 Linux; elsewhere an NVIDIA card is reached through Vulkan;
- WebGPU in a browser also needs JavaScript Promise Integration.