pub struct DflashKv {
pub k: Vec<CudaSlice<f32>>,
pub v: Vec<CudaSlice<f32>>,
pub len: usize,
pub cap: usize,
/* private fields */
}Expand description
Draft KV cache (round-cost fix, 2026-07-13): per-layer normed+roped ctx K and raw ctx V, append-only in committed order. Block K/V land TRANSIENTLY at [len..len+b] each round (never committed — the reference crops them identically). Kills the per-round full-ctx projection recompute (first light was O(ctx)/round -> 7 tok/s).
Fields§
§k: Vec<CudaSlice<f32>>§v: Vec<CudaSlice<f32>>§len: usize§cap: usizeImplementations§
Source§impl DflashKv
impl DflashKv
Sourcepub fn export_tail(&self, e: &Engine, upto: usize) -> Option<DflashKvTail>
pub fn export_tail(&self, e: &Engine, upto: usize) -> Option<DflashKvTail>
Copy out the readable tail ending at upto (see DflashKvTail). None when there is
nothing to publish or an allocation fails — publication is always optional.
upto IS NOT self.len, and conflating them was the bug the first exactness-gate run
caught: publication happens at the scheduler’s drain sweep, by which time the session
has committed generated rows, so len had run 35 rows past the capture boundary and
every restore was refused with draft KV len 30364 != prompt 30329. The trunk planes
are copied at the capture pos for the same reason; the tail must agree with them.
Sourcepub fn from_tail(
e: &Engine,
cfg: &DflashCfg,
cap: usize,
tail: &DflashKvTail,
) -> Option<Self>
pub fn from_tail( e: &Engine, cfg: &DflashCfg, cap: usize, tail: &DflashKvTail, ) -> Option<Self>
Rebuild a draft KV from a published tail: a fresh allocation at cap, the tail copied
back to the SAME absolute rows it came from, and len restored so the next round
addresses positions exactly as a cold-primed session would.
Rows below tail.base are ZEROED, not left uninitialised. The clipped SDPA never reads
below the block’s window floor, but the legacy full-scan kernel
(MEMRA_DFLASH2_SDPA_CLIP=0, the rollback seam) scans EVERY row into the score and the
output, relying on masked rows contributing exactly zero — an identity that holds only
for finite data (0.0 * NaN = NaN, and an uninit K row can produce a NaN score that
poisons the softmax sum). Zeros keep that identity on both kernel arms, so a clip
rollback on a restore-armed box stays byte-exact instead of decoding silent garbage
(review round 3). Rows above tail.len stay uninit — equally unwritten and unread in
the cold path, so restored matches cold there.
This function still REFUSES rather than trusts the window math — if the tail does not
cover the window, the caller gets None and must cold-prime.
Sourcepub fn cfg_window_rows(&self) -> usize
pub fn cfg_window_rows(&self) -> usize
Rows a restore must carry (see DsparkSpecSession::draft_tail_rows). Stored here
because DflashKv owns the row geometry; the value comes from the drafter cfg.