pub struct KvAllocId(/* private fields */);Expand description
A process-unique, never-recycled identity for one KV allocation — the set of storage buffers a held decode plan is welded to.
§Why a held plan needs this at all
DecodeSession keeps a
base_cache holding the KV storage Arcs bound on the first decode token,
and the per-token rebind overwrites only the data Consts — token_ids,
RoPE tables, mask, offset. It never rebinds kv_nodes. So a held plan does
not read the &mut KvCache it is handed; it reads the buffers it was
built against, forever.
Geometry cannot see that. Two same-shaped caches key identically, so the slot-pooled serving happy path — retire request A, admit B on a fresh cache of the same shape, reuse the plan for speed — silently decodes B over A’s KV. Full speed, plausible distribution, nothing to report. That is why this id exists and why it is in the validity key.
§The id names the ALLOCATION, not the conversation
This distinction is the entire design, and getting it backwards breaks one of the two directions that matter:
- Re-allocate ⇒ new id. Constructing a cache, and any operation that
replaces storage under it (
KvCache::clear/KvCache::set_layer), mints a fresh id. A plan welded to the old buffers must be rebuilt. - Rewind ⇒ SAME id.
KvCache::truncate_to— speculative decoding’s reject path — movescached_lenand touches no storage. The plan is still welded to exactly the right buffers, so invalidating there would forfeit plan reuse (223× on CUDA) on every rejected draft batch, for no correctness gain.
Over-keying is the failure mode with no error message: an “always stale” predicate passes every correctness test while quietly disabling the optimization. The tests assert both halves for that reason.
Never recycled, for the same reason ModelInstanceId is: pointer identity
would be sound only while something pins the allocation, and a session
outliving its cache is exactly the case this guards. See the module docs.
Implementations§
Trait Implementations§
impl Copy for KvAllocId
impl Eq for KvAllocId
impl StructuralPartialEq for KvAllocId
Auto Trait Implementations§
impl Freeze for KvAllocId
impl RefUnwindSafe for KvAllocId
impl Send for KvAllocId
impl Sync for KvAllocId
impl Unpin for KvAllocId
impl UnsafeUnpin for KvAllocId
impl UnwindSafe for KvAllocId
Blanket Implementations§
impl<T> Boilerplate for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more