Skip to main content

Module dsv4_gpu

Module dsv4_gpu 

Source
Expand description

DeepSeek-V4-Flash GPU trunk forward (lane 4): 2-card layer-split placement, correctness bring-up gated against the lane-2/3 CPU oracle fixtures.

Plan of record: wt-dsv4-loader research/dsv4-flash-loader-20260818/RECEIPTS.md “Lane 4” (placement math, quant rungs, threshold derivation — banked BEFORE this module was written). Semantic law: darklanes SEMANTICS.md; arithmetic contract: the lane-3 CPU oracle (memra_gguf::dsv4_forward), whose host-side pieces (hc_split_sinkhorn, rope tables, index builders, routing math) are REUSED here verbatim so the CPU/GPU forks share one implementation of every host-side rule.

Rungs (explicit): trunk routed experts stay AS-STORED NVFP4 on GPU and are dequantized per activated expert into a reused bf16 scratch (exact in bf16), all other quantized linears are host-dequantized (lane-1 proven decoders) to bf16 at load with a bit-level exactness refusal; f32 islands (SEMANTICS §7.2) run in dedicated f32/f64 kernels or on the host. bf16 enters ONLY at the activation inputs of the non-island GEMMs (cuBLASLt bf16, f32 accumulate).

Multi-GPU: PP layer split (the engine’s only executing multi-GPU idiom, pp.rs / Step-3.7-Flash precedent), split point derived from per-layer byte math, ONE hc-state boundary copy per forward via host bounce (peer copy is a perf-lane step).

NOT a serving path: prefill-only, greedy continuation by re-prefill per step (the accepted O(n²) bring-up rung). Decode KV caching, CUDA-graph, batched serving and any perf claims belong to later lanes.

Structs§

CmpDev
DecodeState
Whole-trunk decode state: one LayerCache per trunk layer + the stream position. pos = tokens consumed so far (the next decode_step processes position pos).
DsparkCaptureOut
DsparkDev
DSpark drafter on the LAST stage (iteration 3; semantics DSPARK-SEMANTICS.md, numeric truth = the lane-10 CPU oracle memra_gguf::dsv4_dspark). Loaded only under MEMRA_DSV4_DRAFTER=dspark (≈10.7 GiB resident on dev1 — VRAM plan in the iteration-3 receipts); config census pins ride the oracle’s own DsparkConfig::load (refuse-on-drift, NextN refusal included).
DsparkProposal
One drafter proposal (host view). out_ids[0] is the input token; margins/top1 are adjudication instruments (populated only under capture).
DsparkState
DSpark decode-side state: the 3 per-block main_kv rings, each allocated [win + block_size, hd] — rows [0, win) are the persistent ring (slot = pos % win, M:783), rows [win, win+block) hold the CURRENT round’s transient draft kv (the M:784 cat([kv_cache, draft_kv]) gather realized in one buffer; rewritten every propose, never read as ring). Rings advance ONLY for committed positions (dspark_write_rings) — the §3.1 drafter rule.
Dsv4Gpu
Dsv4Phase
A named, nestable phase bracket. Constructed through the phase! macro, which supplies a NUL-terminated literal so the NVTX push needs no allocation.
ForwardOut
A full-trunk forward’s outputs: last-position logits + the final hc state (resident on the LAST stage — the MTP drafter’s input).
Fp8Dense
Iteration-5 FP8 dense arm (MEMRA_DSV4_DENSE_ARM=fp8): an FP8-blk linear held AS-STORED — e4m3 codes [rows, cols] plus the 128x128 block-scale grid decoded to f32 on the host (exact: every e8m0 code is a pow2; 0xFF refused at load). The device GEMV twins decode e4m3(code) * scale in-register — the SAME f32 value the bf16 dequant slab holds (the loader’s f32_to_bf16_exact refusal proves exactness), with the accumulation order VERBATIM — so the arm is bit-identical to the bf16 arm by construction and its gate is a no-regression proof. It5 ledger item 3: when this pair exists, the bf16 twin is NOT device-resident — it drops to DenseBf16::Host staged residency (the dual-residency +~2.7 GiB/card is gone).
GpuCapture
Fixture-array capture (GPU twin of the oracle’s BlockCapture, gathered host-side).
IdxDev
LayerCache
Lane-6 decode cache for ONE trunk layer, on the layer’s owning stage. Layout mirrors the reference (model.py:473-474, :491): kvc = [win + cap_blocks, hd] f32 with the 128-slot window ring at rows [0, win) (slot = pos % win, M:530) and compressed block j at row win + j (decode index offset = win, M:509). Pending state = RAW wkv/wgate rows (ape added at pool time — see the lane-6 receipts): fine [2·ratio, latent] with rows [0, ratio) = previous block / [ratio, 2·ratio) = current (M:344-370 state machine); coarse [ratio, latent]. pend_score is initialized to −inf so a block with no predecessor reproduces the reference j==0 masking bit-exactly.
LayerDev
MtpDev
MTP (NextN) block on the LAST stage (pp idiom: MTP -> last stage). Shares the trunk embed (host-gathered) and head; own norms/projections/block/hc_head (SEMANTICS §5).
SpecRoundGpu
One verify round’s bookkeeping (the device twin of spec_oracle::SpecRound).
SpecRunGpu
Stage
One stage = one GPU: its runtime handle plus the resident weights of its layer range.
StepWs
Lane-8 per-stage decode workspace: every per-step buffer preallocated ONCE (the legacy path issues ~3,086 allocAsync+memset+free triplets per step — rung-0 profile). Every buffer is fully rewritten before it is read within a step; the consumers (sink_attn via idx pads, combine via order, top-k via exact nb) read exactly the regions written this step, so no per-step zeroing exists at all.
VerifyState
Whole-round verify state: the per-stage arenas + the per-layer §3.1 checkpoints.
VerifyWs
Per-stage batched-verify workspace: the lane-8 arena widened to tmax rows. Held separately from StepWs so the gated single-position path’s allocations, launches and bytes are literally untouched by this rung.

Enums§

DW
Dense-weight pointer for the device-path GEMV wrappers: the bf16 dequant slab, or the as-stored FP8 pair when the dense arm is on. Copy of raw pointers only — built per call from the owning slabs via [dwsel].
DecodePath
Lane 8: which decode-step realization runs (RECEIPTS.md “Lane 8”). Legacy = the lane-6/7 gated host-driven loop, byte-stable. Device = the device-resident step: preallocated workspace arena, device index build / fine top-k / router / Sinkhorn / head gate, one-launch-per-projection indirect expert dispatch, peer-copy PP boundary. host_math: true (seam device-hostmath) keeps Sinkhorn + router + fine-top-k + head-gate math on the HOST — the byte-identity instrument for the mechanical rungs; false (seam device) runs them as kernels (expf/log1pf realization fork, gated at class bounds per the lane-6/7 doctrine). Selected by MEMRA_DSV4_DECODE_PATH — read once at load and printed; one binary carries both arms for the interleaved A/B law.
DenseBf16
It5 ledger item 3 — residency of a dense bf16 slab. Dev = device-resident, today’s exact bytes: the only realization when the dense arm is bf16, and always the realization for the drafter/MTP blocks (no fp8 twins this rung). Host = the fp8 dense arm’s STAGED residency: the same host-dequantized bf16 bytes the loader would have uploaded, kept host-side; the fp8 pair owns every device decode/verify read (via [dwsel]) and the prefill pass stages these bytes H2D per consuming call, the transient copy freed stream-ordered when the DenseView drops. This is the engine’s existing staged-residency idiom (hybrid EDGE-1 HostExps / the moe-cache host-resident expert staging) translated to dsv4; dsv4 has no CUDA-graph capture, so the “release after capture” boundary degenerates to “never resident outside a prefill pass”. Prefill’s bf16 path is byte-identical by construction: the staged upload is the SAME f32_to_bf16_exact byte vector the resident slab held.
DenseView
A borrowed resident slab or a staged transient copy — see DenseBf16::staged.
ExpertArm
Lane 7: which expert-GEMM realization runs. Bf16Dequant = the lane-4 gated rung (on-the-fly exact dequant + cuBLASLt bf16, the fallback and A/B reference). Native = the reference-law quantized GEMMs (act_quant per-128 FP8 codes × as-stored NVFP4/MXFP4 slabs, kernel.py fp4_gemm arithmetic — RECEIPTS.md “Lane 7”). Selected by MEMRA_DSV4_EXPERT_ARM=native via [memra_gguf::dsv4_forward:: expert_arm_native] — the SAME seam the CPU oracle reads, so one invocation can never mix numeric classes.
ExpertKind
Routed-expert quantization recipe of a layer (lane-1 census: trunk = modelopt NVFP4, MTP = OCP MXFP4). Never inferred from ancestry — detected from the stored dtypes and sibling names, refused on any surprise.

Functions§

dsv4_phase_report
Print the accumulated itemisation. plain_us is the measured PLAIN step wall time so each row can be quoted in plain steps, which is the unit F is expressed in; pass 0.0 to omit.
dsv4_phase_reset
Drop everything accumulated so far (used to keep the plain arm’s brackets out of the drafted arm’s table).
dsv4_prof_on
True when either phase instrument is armed. Checked first in Dsv4Phase::new so an unprofiled build pays one relaxed load per bracket and nothing else.
resolve_dense_arm
The dense-arm resolution, pure for the flip’s toothed tests (owner ratification 2026-08-20, executed v0.98): unset = fp8 on the DEVICE decode path, bf16 on legacy (device-scoped default, the 82a754fbec dots-default shape); explicit values keep their exact prior semantics including the legacy+fp8 refusal and the unknown-value refusal.