vkML 0.1.0

How a Python call becomes a dispatch on the GPU, in three depths. Read the first section and stop, or keep going — each one assumes the one above it and nothing below it.

In thirty seconds

vkML is a stack of layers, and the dependency direction is enforced rather than agreed. A layer may include only from a layer below it, so every arrow in this diagram points down — if one curved upward, the build would be failing.

vkML layer dependencies Nine layers stacked by level. Every arrow points downward: a layer may include only from a layer below it, which scripts/check_layering.py enforces on every build. 7autograd2 6api4 5dispatch2 5plan 4backend/cpu11 4backend/vulkan11 3backend/api3 2graph7 1core10 0util13 level files

Generated from the same include scan that scripts/check_layering.py runs in CI, so the picture and the gate cannot disagree. plan is declared in the order and holds no files yet, so it is drawn dashed rather than hidden.

In five minutes

Nothing runs when you write it. An operator builds a graph node and returns a Tensor handle. No memory is allocated, no kernel is dispatched, nothing is computed. Work happens only when something observes a value — numpy(), item(), a backward pass — or when realize() is called explicitly.

That deferral is a performance mechanism, not an API style. Batching lets many operations share one GPU submission, and on the development hardware a submission costs about 105 µs against 9 µs for a dispatch. Reducing submissions is worth far more than making any single kernel faster, which is why the graph exists at all.

When a value is observed, the dispatcher walks the graph in topological order, asks a backend whether it supports each node, and submits. A graph runs entirely on one backend: there is no per-node fallback, so an operator the GPU cannot run is an error rather than a silent host transfer — why that is deliberate.

Two backends, and they are not peers. The CPU backend is the oracle: its job is to be right, and every Vulkan result is checked against it. The Vulkan backend is 24 compute shaders compiled to SPIR-V and dispatched with operand addresses in push constants — no descriptor sets at all.

Going deeper

Each of these traces one subsystem through the code, naming the file and line of everything it describes.

How the architecture stays true

The layer order above is not a diagram of intent. It is checked on every build, and it has already caught a real violation — autograd reaching into api. Alongside it: push-constant blocks against the 128 bytes Vulkan guarantees, the GEMM contraction contract from ADR 0005, and a mutation campaign that breaks each kernel on purpose to confirm the tests notice.

That last one matters more than it sounds. A green suite proves the tests ran, not that they can fail — see Testing and verification.

vkML — Vulkan-first machine learning in C++20. Apache-2.0. Signatures on this page are generated from the installed module.