pub struct CacheSnapshot {
pub kv_len: Vec<Option<usize>>,
pub tp_kv_len: Vec<Option<usize>>,
pub conv: Vec<Option<CudaSlice<f32>>>,
pub ssm: Vec<Option<CudaSlice<f32>>>,
pub pos: usize,
}Expand description
Snapshot of the dual cache taken BEFORE a spec-decode draft+verify round (MTP-PLAN §C/§D.4).
- Full-attn KV: only the per-layer
lenis recorded; rollback truncates (append-only, position-addressed — no copy). C.1. - Linear-attn conv/ssm: real device-to-device COPIES of the recurrent state, because those
buffers are mutated IN PLACE by the verify pass and have no position index to truncate. C.2.
(We alloc fresh + memcpy_dtod. NOTE, corrected memra-next#23: the parenthetical here used
to justify that with “CudaSlice::clone is an Arc refcount, NOT a buffer copy”, which is
false in the LOCKED cudarc 0.19.8 —
Cloneistry_clone().unwrap()= alloc + D2D copy. The explicit copy is still the right call here, for two reasons that are NOT aliasing: it is fallible rather than panicking, and it places the copy on the calling engine’s current stream instead of the source slice’s. Genuine aliasing needs anArc<CudaSlice<T>>.)
IT COVERS TWO OF THE CACHE’S FOUR STATE PLANES, AND THAT IS A KNOWN HOLE
(lane/prefix-restore-toolcall, 2026-08-28). Cache also has tp_kv (recorded here as
tp_kv_len) and latent, and NOTHING in this struct or in Cache::rollback mentions
latent. A StatePlan::LatentKvCache layer keeps its FULL-ATTENTION history there, so
rolling back a latent-bearing cache moves pos while every MLA layer keeps its longer
len: the next tokens append past the boundary and attend stale rows. The identical
two-plane assumption in the server’s PrefixEntry is what made a glm5_next prefix-cache
hit restore an EMPTY attention history while reporting cached_tokens: N of N, and it
fabricated instead of failing (research/prefix-restore-toolcall-20260828/).
Today nothing reaches it: maybe_plain_checkpoint refuses to arm on a latent-bearing
cache, and the spec rewind cannot fire because every latent model is EAGER-ONLY with no
drafter. IT BECOMES LIVE THE MOMENT A LATENT MODEL GETS A SPEC ARM. Growing latent
awareness here is not a symmetric addition: the rows are unquantized f32, index_rows is
a tail ring rather than a flat addressable plane, and index_pool_keys /
index_pools_ready carry an append-only finality invariant (truncate_index_pool_keys
exists precisely because a len that moves backwards invalidates them).
Fields§
§kv_len: Vec<Option<usize>>§tp_kv_len: Vec<Option<usize>>§conv: Vec<Option<CudaSlice<f32>>>§ssm: Vec<Option<CudaSlice<f32>>>§pos: usize