Environment switches and build options
Every VKML_* variable the library reads, generated from its call
site — so a new switch appears here the moment it is added.
These are configuration, not a control interface. Every switch is read once, at first use, and cached for the life of the process. Changing one after vkML has started has no defined effect, because pipelines are already selected and cached from the earlier value. Set them before launching.
Environment switches
The reads as column is how the value is parsed. A flag is off when the
value starts with 0 and on for anything else non-empty; an int parses
base-10 and falls back when unset or empty; a value is used as a string, and the
call site decides what it means.
Debugging
| Variable | Reads as | Default | What it does · where it is read |
|---|---|---|---|
VKML_EAGER | flag | false | Realize after every operation instead of building a graph. A failure then surfaces at the operation that caused it. Slower — every operation becomes its own submission.src/dispatch/executor.cpp:18 |
VKML_VULKAN_DEBUG | flag | false | Trace every dispatch with its shape and grid.src/backend/vulkan/vulkan_backend.cpp:789 |
VKML_VULKAN_DUMP | int | 0 | Print the first N elements of each dispatch's output. Clamped to 256.src/backend/vulkan/vulkan_backend.cpp:797 |
VKML_VULKAN_NO_PIPELINE_STATS | flag | false | Stop collecting compiler statistics per pipeline.src/backend/vulkan/vk_pipeline.cpp:172 |
VKML_VULKAN_VALIDATION | flag | true | Vulkan validation layers. On by default — this is a correctness-first project, and the cost is paid on every run unless explicitly disabled.src/backend/vulkan/vulkan_backend.cpp:2999 |
Testing
| Variable | Reads as | Default | What it does · where it is read |
|---|---|---|---|
VKML_COVERAGE | value | unset | Write an operator-coverage table to this path. Presence-and-non-empty rather than a flag, because it names a file — so 0 is a legitimate filename, not "off".src/util/coverage.cpp:63 |
VKML_MIN_SPEC | flag | false | Report the Vulkan 1.3 Required Limits on any device. Only ever reports limits smaller than the hardware has, so it can make vkML more conservative and never less. A testing facility, not a tuning knob.src/backend/vulkan/vk_device.cpp:475 |
Gemm Experiments
| Variable | Reads as | Default | What it does · where it is read |
|---|---|---|---|
VKML_GEMM_BLOCK | value | unset | Register-block geometry. Most values exist to test the register model rather than as performance candidates — 2x8 and 8x2 are the discriminating pair for a model symmetric in RM and RN.src/backend/vulkan/vulkan_backend.cpp:2206 |
VKML_GEMM_DB | flag | false | Use the double-buffered GEMM variant.src/backend/vulkan/vulkan_backend.cpp:2178 |
VKML_GEMM_KERNEL | value | unset | Select the matmul kernel: naive, tiled, or register-blocked (the default).src/backend/vulkan/vulkan_backend.cpp:2161 |
VKML_GEMM_NOLDSVEC | flag | false | Disable vectorised shared-memory loads.src/backend/vulkan/vulkan_backend.cpp:2470 |
VKML_GEMM_NOVEC | flag | false | Disable vectorised global loads, as a control.src/backend/vulkan/vulkan_backend.cpp:2456 |
VKML_GEMM_SPLITK | value | unset | Force or disable split-K. Bit-identical to the unsplit kernel by construction, not by measurement.src/backend/vulkan/vulkan_backend.cpp:538 |
VKML_GEMM_SPLITK_SPLITS | int | 4 | How many K partitions when split-K is forced. Values of 1 or less fall back to the default.src/backend/vulkan/vulkan_backend.cpp:557 |
VKML_GEMM_TILE | value | unset | Threadblock tile size. The larger tiles were measured and rejected — arithmetic intensity doubled and it was still slower, because concurrent workgroups per CU halve at each step.src/backend/vulkan/vulkan_backend.cpp:2307 |
VKML_GEMV | value | unset | Force or disable the matrix–vector kernel.src/backend/vulkan/vulkan_backend.cpp:505 |
VKML_GEMV_PAD_KB | int | 0 | The same, for GEMV.src/backend/vulkan/vulkan_backend.cpp:2108 |
VKML_SOFTMAX_PAD_KB | int | 0 | Shared-memory padding for softmax, in KiB. A discriminator for bank-conflict experiments; it changes no result.src/backend/vulkan/vulkan_backend.cpp:2020 |
Build options
Passed to CMake with -D. These are compile-time, unlike everything above.
| Option | Default | What it does |
|---|---|---|
VKML_BUILD_TESTS | ON | Build C++ unit tests |
VKML_BUILD_PYTHON | ON | Build the Python extension |
VKML_BUILD_BENCH | ON | Build benchmarks |
VKML_VULKAN | OFF | Build the Vulkan backend |
VKML_WERROR | OFF | Treat warnings as errors |
VKML_SANITIZE | OFF | Enable ASan+UBSan |
cmake --preset release does not enable Vulkan. The presets set
the build type and warning flags only, and VKML_VULKAN defaults to
OFF — so without -DVKML_VULKAN=ON you get a CPU-only build in which
every GPU test silently skips.
One getenv in the whole project
All of these go through a single helper in src/util/env.cpp, which is the only
place std::getenv is called. That is not tidiness: getenv returns a
pointer into the environment block, which a putenv from any thread may invalidate —
and vkML is embedded in Python, where os.environ[...] = ... does exactly that. The
helper returns an owned std::string, which makes the question structurally
impossible rather than merely unlikely.
It is also the single place MSVC's C4996 deprecation has to be answered, rather than in eighteen files.