Get started
Build vkML, check your GPU is usable, and train a model.
Requirements
- A C++20 compiler with
<format>. 19 source files usestd::format, which is the strictest library feature the project needs — it shipped in libstdc++ with GCC 13, in libc++ with LLVM 17, and in MSVC 19.29. - CMake 3.25 or newer — the figure in
cmake_minimum_required, not an approximation of it — and Ninja. - The Vulkan SDK, for
glslcorglslangValidator. - Python 3.10+ with NumPy, matching
requires-pythoninpyproject.toml.
Only some of that is verified. The compiler versions above are the releases
that shipped <format>, not versions this project has been built with. What is
actually known to work is GCC 14.2.1 (the development machine), MSVC 19.51 (a Windows build
with warnings as errors), and whatever g++ and clang++ the CI image
ships — which is unpinned. If you build on an older toolchain, a report either way is
useful.
PyTorch is a test-only dependency. It is the correctness oracle and is never needed at runtime.
Build
# Linux and macOS
cmake --preset release -DVKML_VULKAN=ON
cmake --build build/release -j$(nproc)
pip install -e .
cmake --preset release on its own does not enable Vulkan —
the presets set the build type and warning flags only. Without
-DVKML_VULKAN=ON you get a CPU-only build and every GPU test silently
skips.
On Windows the presets set CMAKE_BUILD_TYPE, which a multi-config generator
ignores, so pass the configuration to the build instead:
cmake -B build/msvc -DVKML_VULKAN=ON -DVKML_BUILD_PYTHON=ON
cmake --build build/msvc --config Release --parallel
Check your device
python scripts/hardware_report.py
This prints what each Vulkan device reports — required and optional features, subgroup size, workgroup limits, memory heaps. Paste it into an issue when reporting a bug; almost every portability defect in this project was found because somebody ran it on hardware the maintainers do not have.
Your first tensor
>>> import numpy as np, vkml
>>> vkml.init_vulkan(0)
'vulkan:0'
>>> dev, why = vkml.best_device()
>>> print(why)
using Vulkan device 0: AMD Radeon RX 5600M (RADV NAVI10) (discrete, Vulkan 1.4.354, driver radv) # differs per machine
>>> x = vkml.tensor(np.random.rand(1024, 1024).astype(np.float32), device=dev)
>>> vkml.matmul(x, x).shape
(1024, 1024)
Train something
Both examples train end to end and compare against a PyTorch model step for step:
python examples/mnist/train.py --device vulkan:0 --epochs 10
python examples/cifar100/train.py --device vulkan:0 --epochs 10
Batch size matters more than it looks. Measured on an RX 5600M, per-sample cost falls roughly 4× going from batch 64 to batch 512 — at small batches the GPU spends most of a step waiting for work rather than doing it. If you are benchmarking, say which batch size you used.
Run the tests
ctest --preset release # C++ suite
python -m pytest tests/python -q # Python + PyTorch validation
VKML_MIN_SPEC=1 python -m pytest tests/python -q # against Vulkan's guaranteed floor
VKML_MIN_SPEC=1 makes any device report the Vulkan 1.3 Required Limits. It only
ever reports limits smaller than the hardware has, so it can make vkML more
conservative and never less — run it before claiming a limit is satisfied.