Authoring kernels
poot's kernels are ordinary Rust functions, fully type- and borrow-checked, that the toolchain lowers to GPU code. There is no DSL and no separate kernel language.
What #[kernel] is
The #[kernel] attribute (from poot-kernel-attr) marks a function for import by pootc, poot's rustc
driver. Which of the attribute's two expansions a build gets is poot-kernel-attr's own device-pass
Cargo feature: extern-link a poot-kernel-attr built with
--features device-pass (the device pass) and the attribute renames each marked function into poot's
reserved namespace; pootc reads the functions from Stable MIR and lowers each kernel to SPIR-V and PTX, and
writes a module cache (poot_cache.rs) next to them. Extern-link the crate's default build (the host pass)
and the macro emits a typed host launcher that looks the compiled module up by name. There is no
cargo integration in the repository yet: you invoke pootc on the kernel source yourself, --extern-linking
whichever poot-kernel-attr build the pass needs.
Under #[cfg(test)] the same function is ordinary Rust. Call it on CPU arrays before any GPU is involved.
Minimal example
use poot_kernel_attr::kernel;
/// Elementwise add: c = a + b, one GPU thread per element.
#[kernel]
pub fn add(a: &[f32], b: &[f32], c: &mut [f32]) {
let i = thread_index();
if i < c.len() {
c[i] = a[i] + b[i];
}
}
// In a host build the macro emits `add(&ctx, &a, &b, &mut c)`, which dispatches the pootc-compiled SPIR-V.
The ABI is slices: inputs as &[T], outputs as &mut [T]. Thread index intrinsics (thread_index,
local_index, group_index, with _x/_y/_z variants) lower to the correct registers on each target.
Run the end-to-end test
cargo nextest run -p pootc --test macro_kernel
The test compiles a #[kernel] add function with pootc (device pass), reads back the emitted SPIR-V, and
dispatches it on a GPU. It skips the dispatch if no GPU is present.
Standalone imported kernel
There is no standalone example that runs an imported kernel with nothing else around it. Two test suites cover
the import-and-dispatch path: pootc's import_run test imports kernels fresh from source and runs them on a
GPU, and poot-wgpu-device's imported_kernel tests load the committed kernel assets through the
Device trait and dispatch them on wgpu.
Accepted Rust subset
The importer accepts a defined subset of Rust and rejects everything else with a named diagnostic. The subset is listed on Kernels from Rust.
Standalone kernels and generated kernels
Most kernels are never hand-authored: the planner generates a kernel body for each equation shape at compile time.
A kernel authored in Rust and committed as an asset covers what generation does not: the decode GEMVs and
prefill GEMMs over particular weight layouts, the flash-attention bodies, the on-device sampler, the KV-cache
pack and unpack pair, the packed-row gathers, and a handful of importer-capability probes. These sources live
under crates/pootc/kernels/<family>/*.rs, one subdirectory per kernel-choice family (contraction, attention,
movement, packed, sampling, and probe for kernels a backend crate loads directly).
The one kernel asset manifest
Every standalone kernel source has exactly one committed asset (<crate>/assets/<name>.kir.json) and
exactly one entry in the manifest table (one Rust file per family, aggregated into one list), the single
source of truth for which source produces which asset and who ships it. A test regenerates every asset
from its source and checks it byte-for-byte against the committed one, and separately checks that each
destination assets/ directory holds exactly its manifest's entries: a committed asset with no manifest
entry, or a manifest entry with no committed asset, fails by name. poot-codegen lowers each .kir.json asset
to SPIR-V for wgpu and raw Vulkan, PTX for NVIDIA and AMDGCN for ROCm.
After editing a kernel source under crates/pootc/kernels/<family>/*.rs, run just regen-kernel-assets to
refresh its committed .kir.json asset. pootc's own compiler fixtures (used only by pootc's own test
suite, never shipped) stay under crates/pootc/tests/kernels/*.rs.
Design depth
For the full import pipeline (MIR to kernel IR to LLVM to SPIR-V/PTX), see Kernels from Rust. For graph IR, fusion, and how kernels fit the engine, see Architecture.