Every PHOBOS_* variable the tree reads, what it takes and what it does.
Nothing here is a user setting in the ordinary sense: phobos-cli’s flags
are the user’s choices, and these are the knobs behind them for measuring,
debugging and sweeping. A variable a document does not list is a variable
the tree does not read; add it here when adding it there.
Two spellings apply throughout, and every toggle uses one of them:
- opt-in: on for
1, on, yes or true; off otherwise, including
unset.
- opt-out: off for
0, off, no or false; on otherwise, including
unset.
A variable that takes a value says so. Where a value fails to parse the
default applies. Most are read once, at backend construction or first use,
so they have to be set before the process starts. The helpers are
phobos_base::env::flag (opt-in), flag_on (opt-out) and flag_set
(opt-out, with unset told apart for a toggle that falls back to a wider
one, as the PHOBOS_FUSED_* stages fall back to PHOBOS_FUSED).
| variable |
takes |
default |
effect |
PHOBOS_LOG |
off/none/0, info, debug, trace |
info |
The level phobos_base::log emits at, for every crate’s messages. |
PHOBOS_TRACE |
opt-in |
off |
Prints each block’s per-token activation RMS during a forward pass (llama, qwen35), a readback per block, so only for a diagnosis. |
PHOBOS_PASS_REPORT |
a replay number, or empty |
unset |
On the device backend, prints the launch census of that replay of the pass (kernel, launches, blocks, registers, shared memory, occupancy). Empty means the fourth replay, past the prefill and the warmup passes whose scratch is still growing. |
PHOBOS_VRAM |
opt-in |
off |
Prints free device memory at each pass boundary and every large allocation, constant and scratch, with the pool’s free list; how a residency problem is found. |
PHOBOS_CHECK_BUFS |
opt-in |
off |
Checks at every launch that a kernel’s destination is not one of its sources. A debugging aid; it reads the slot table per launch. |
| variable |
takes |
default |
effect |
PHOBOS_KERNEL_CACHE_DIR |
a directory, or empty |
kernel-cache beside the binary, read-only, then ~/.phobos/kernel-cache |
Where compiled PTX is cached across processes, one subdirectory per chip (sm_75/, sm_86/, …). A release ships its cache beside the binary; new entries go to the user’s. Set, it is the one cache read and written; empty turns caching off. |
PHOBOS_KERNEL_MANIFEST |
a directory |
unset |
Records every kernel compile request, hit or miss, into that directory, one file each, without the chip. phobos-cache warm --manifest DIR compiles them for every supported chip with no GPU. A GGUF run on the device compiles every format’s kernels while it records, not just its model’s, so the manifest covers formats no recorded model holds. |
PHOBOS_KERNEL_CACHE_EPOCH |
any string |
the compiler’s build fingerprint |
Replaces the fingerprint that keys the cache, so a stale cache can be forced cold or two builds made to share one. |
PHOBOS_CHIP |
an SM target, sm_75, sm_80 |
the newest supported chip the card runs, or the context default |
The target kernels compile for: on the device path, in place of the card’s, and in phobos-lang’s emit and ir examples, to reach a code path the default never takes. |
PHOBOS_INDEX_BITS |
32 or 64 |
32, widened to 64 by a kernel that wants ldmatrix |
The index width those examples compile with; mma.sync and cp.async want 64. |
PHOBOS_PRINT_PHASES |
opt-in |
off |
phobos-compile prints each lowering phase’s IR. |
PHOBOS_DUMP_DIR |
a directory |
unset |
Codegen tests and the raw-format kernel dump write every kernel source they compile there as .ph, so the emit sweep covers them. |
PHOBOS_SNAPSHOT_SRC |
a directory |
unset |
The IR builder’s test walks every source there and checks each builds, or fails where its .err says it should. Skipped without it. |
| variable |
takes |
default |
effect |
PHOBOS_ARENA |
opt-out |
on |
Weights go into a few large arena slabs rather than an allocation apiece; WDDM keeps a small set of large allocations resident where it fails a large set of small ones. |
PHOBOS_ARENA_CONST |
opt-in |
off |
f32 constants go into the arena too. |
PHOBOS_STATE_ARENA |
opt-in |
off |
A sequence’s recurrent state goes into an arena of its own, reset when the sequence ends. |
PHOBOS_SLAB_MIB |
MiB |
128 |
Arena slab size. A tensor larger than a slab gets one to itself, which is how the output head can be evicted on its own. |
PHOBOS_DEQUANT_MIB |
MiB |
32 |
Budget of the strip a prompt pass dequantizes a raw-format weight into, for formats without a fused projection. Smaller buys residency and costs launches. |
PHOBOS_DENSE_SCRATCH |
opt-out |
on |
The prompt pass’s dense scratch is one shared allocation for the whole model rather than one per weight. |
PHOBOS_TRIM |
opt-in |
off |
After a prompt pass, hand the dense scratch and the pool’s free list back to the driver at the next pass boundary. |
| variable |
takes |
default |
effect |
PHOBOS_FUSED |
opt-out |
on |
The fusion pass as a whole: chains of decode stages lowered into one persistent kernel. Off, every stage launches on its own. |
PHOBOS_FUSED_MLP |
opt-out |
on |
The decode MLP (norm, gate and up, SwiGLU, down) as one fused kernel. |
PHOBOS_FUSED_PROJ |
opt-out |
on |
A normalization and the projection reading it as one kernel. |
PHOBOS_FUSED_MIX |
opt-out |
on |
The delta net’s convolution and gates as the tail of the fused projection; costs a barrier, so gated apart. |
PHOBOS_FUSED_ATTN_OUT |
opt-out |
on |
Attention’s output epilogue (quantize, output projection into the residual) as one kernel. |
PHOBOS_FUSED_STORE2D |
opt-out |
on |
Attention’s key and value cache writes in one launch instead of two. |
PHOBOS_DELTA_SCAN |
opt-out |
on |
A prompt’s gated delta rule as the register-state scan (delta_scan_t), one pass over the positions with the state in registers. Off, the chunked form (delta_wy and delta_scan). |
PHOBOS_ATTN_TC |
opt-out |
on |
The tensor-core prompt attention: every head’s scores written out, a softmax in place, and the mix, for a prompt whose rows, cache depth and head dimension tile by 64 and whose scores fit 128 MiB. Off, the blocked kernel. |
PHOBOS_ATTN_PERSIST |
opt-out |
on |
The decode attention’s persistent split-and-merge kernel. Off, the launched split path. Kept apart from PHOBOS_FUSED since a grid_barrier that does not fit hangs rather than slows; occupancy is checked before it is taken. |
PHOBOS_IQ1S_DP4A |
opt-out |
on |
The dp4a decode matvecs against an int8 activation, for every raw format. Off, the f32 matvec. It quantizes the activation where the host reference does not, so device against host cannot judge it; backend_check runs both device ways instead. |
PHOBOS_QGEMM |
opt-out |
on |
The staged tensor-core prompt projection for the raw formats. Off, the register form or the dense expansion. |
PHOBOS_QGEMM_SPLIT |
opt-out |
on |
Split-K on the staged projection when its grid is under three quarters of a wave (two CTAs per SM), which a short prompt or a wide card leaves it. Splits only while each slice stays deep enough to pay for the reduction pass. |
PHOBOS_RAW_QMMA |
opt-out, or a comma list of formats (IQ1_S,IQ2_XXS) |
on, all formats |
Which raw formats take the fused prompt projection rather than expansion. A list names them; an opt-out spelling means all or none. |
PHOBOS_QMMA_SPLIT |
opt-out |
on |
Split-K on the Q8_0 prompt projection’s deep tile when the grid is starved, which a short prompt leaves it. Up to 48 SMs only an eight-way split is taken, since a smaller one does not pay for its reduction pass; past 48 SMs a grid under two blocks per SM splits at least four ways. |
PHOBOS_QMMA_NARROW |
opt-in |
off |
The narrow-CTA form of the Q8_0 prompt projection’s deep tile. Wins at pp128, regresses pp512 on some models; opt-in for that reason. |
PHOBOS_QMMA_TILE |
TMxTNxCTA, e.g. 128x64x256 |
the format’s |
The fused prompt projection’s tile and CTA, for a sweep without a rebuild. Each distinct value is a distinct compiled kernel. |
PHOBOS_QMMA_STAGE |
opt-out |
on |
The staged (shared-memory) form of IQ1_S’s fused projection. 0 goes back to the register form. |
PHOBOS_QDOT_I8_CTA |
threads |
256 |
Threads those matvecs launch with, clamped so a warp’s columns fill the CTA whole. Wider reads faster alone and loses in the model. |
PHOBOS_ATTN_PREP |
opt-out |
on |
A decode row’s query and key normalization, rotation, gate split and cache stores run as two launches, one program per head. Off, they run as the eight separate ops. |
PHOBOS_GATE_Q |
opt-out |
on |
Attention’s output gate writes the quantized copy the output projection reads in the same launch. Off, the gate and the quantization are two launches. |
PHOBOS_QDOT_SPLIT |
opt-out |
on |
A K-quant decode matvec over a k of 4096 or more whose tiles give fewer than two programs a multiprocessor splits along k into partials and a sum. Off, one program per tile walks all of k. |
PHOBOS_PERSIST_QDOT |
opt-in |
off |
The persistent (card-sized grid) form of the Q8_0 decode matvec, which exists to be measured against the launched one. |
PHOBOS_PERSIST_BLOCKS |
a block count |
the occupancy answer |
Forces that grid’s block count, to ask what a matvec loses at the count a fused kernel is stuck with. |
The mixture-of-experts path (qwen35moe) keeps a model’s experts in a
pinned host mirror and a device cache; see docs/MOE-QWEN36-35B-A3B.md for
the design and every measurement behind these defaults, on an RTX 2080
SUPER whose PCIe link runs at x8. The two on by default won the prompt pass
there; the two opt-ins lost and exist for a wider bus or a faster host.
| variable |
takes |
default |
effect |
PHOBOS_MOE_GROUPED |
opt-out |
on |
Run a pass whose rows choose more experts than a block’s cache holds as grouped GEMMs over rows sorted by expert, each expert copied once a block, rather than row by row with the cache thrashing. Off, a 512-token prompt on the 35B runs at a sixth of the rate. |
PHOBOS_MOE_HOST |
opt-out |
on |
In a grouped prompt pass, give the lightest experts by rows to the host’s AVX2 K-quant kernels (simd) while the device works the rest, each one sparing the bus a copy; the host’s share of a block’s experts follows the last block’s host and device times. Off, the prompt pass runs at a third of the rate. |
PHOBOS_MOE_HOST_DECODE |
opt-out |
on |
A decode step’s misses on the host’s kernels while the device runs the hits and the next block is recorded; each block’s most heavily weighted miss is also copied into a slot for later tokens. A host miss costs a quarter of a copy on an x8 link. Off, every miss is copied on the step’s critical path and the 35B decodes at half the rate. |
PHOBOS_MOE_LOOKAHEAD |
opt-in |
off |
At each block’s sync point, run the next block’s router on the residual as it stands and copy its predicted misses early on a second stream. Right four times in five; the wrong fifth costs more bytes on an x8 link than the overlap buys. |
PHOBOS_HOST_THREADS |
a count |
half the logical CPUs |
Workers of the host expert kernels (simd): the pool a prompt pass’s share runs on, and the team a decode step’s misses run on. Two threads on one core share its vector units and measured slower than one. |
| variable |
takes |
default |
effect |
PHOBOS_ATTNDECODE_LENGTH |
a cache length |
unset |
attndecode sweeps only that length, so an external profiler can isolate one launch. |
PHOBOS_ATTNDECODE_SHAPE |
a substring of a shape name |
unset |
attndecode sweeps only the shapes whose name contains it. |
scripts/bench.py prints the PHOBOS_* variables in its environment as
phobos env: before a run, since a benchmark taken with one of these set
is not comparable to one taken without; PHOBOS_VRAM in particular has
been found inherited by a shell and left on.