Skip to main content

KvCache

Struct KvCache 

Source
pub struct KvCache {
    pub n_kv_heads: usize,
    pub head_dim: usize,
    pub k: Vec<f32>,
    pub v: Vec<f32>,
    pub seq_len: usize,
    /* private fields */
}

Fields§

§n_kv_heads: usize§head_dim: usize§k: Vec<f32>§v: Vec<f32>§seq_len: usize

Implementations§

Source§

impl KvCache

Source

pub fn new(n_kv_heads: usize, head_dim: usize) -> Self

Source

pub fn with_capacity( n_kv_heads: usize, head_dim: usize, max_seq_len: usize, ) -> Self

Pre-allocates storage for up to max_seq_len positions, so push never triggers a reallocation-and-copy during decode. Use this when the maximum context length is known ahead of time

Source

pub fn with_pool( n_kv_heads: usize, head_dim: usize, pool: Arc<Mutex<KvBlockPool>>, max_seq_len: usize, ) -> Result<Self, KvPoolExhausted>

Acquires up front however many blocks from pool are needed to cover max_seq_len positions (at least one, even if max_seq_len is 0), so a caller that knows its worst-case sequence length ahead of time (as ferrox-server does: prompt length + max_tokens) never needs to acquire another block mid-decode. This matters beyond performance: push growing past its currently held capacity can fail if the pool is exhausted by other requests by then, and callers like ferrox_models::Decoder::forward_token treat push as infallible for non-pooled caches – a pooled cache that under-reserves at construction and then fails to grow later would violate that assumption and panic mid-decode. Sizing to max_seq_len up front turns that into an admission-control decision made once, honestly, before any generation work starts, exactly mirroring with_capacity’s worst-case pre-allocation – just drawn from a shared pool instead of a private allocation. Returns Err(KvPoolExhausted) without mutating anything if the pool doesn’t have that many blocks free.

Source

pub fn push( &mut self, k_step: &[f32], v_step: &[f32], ) -> Result<(), KvPoolExhausted>

Appends one position’s key/value vectors (each n_kv_heads * head_dim long) to the cache. For pool-backed caches, this may need to acquire another block first; if the shared pool has none free, no data is appended and Err(KvPoolExhausted) is returned. Caches built with new or with_capacity always return Ok.

Source

pub fn advance_len(&mut self, n: usize) -> Result<(), KvPoolExhausted>

Advance length by n positions without storing real K/V values (zero-fill). Used when Metal owns the KV plane and the host cache only needs matching seq_len for sync checks.

Source

pub fn release_to_pool(&mut self)

Returns this cache’s blocks to its shared pool immediately (rather than waiting for Drop) and detaches it from pool accounting; a no-op for caches that aren’t pool-backed, and idempotent if called more than once.

Source

pub fn clear(&mut self)

Source

pub fn truncate(&mut self, new_seq_len: usize)

Rolls the cache back to exactly new_seq_len positions, discarding everything after. Used to reject speculatively decoded draft tokens that turned out wrong: their K/V were already pushed during batched verification, and rejection means removing them so the next real decode step continues from the last accepted position, not the last attempted one.

Source

pub fn allocated_bytes(&self) -> usize

Bytes currently resident for this cache’s K and V buffers combined (actual allocated capacity, not just used length) – the number that matters for “does this fit in the context budget,”

Source

pub fn is_within_planned_capacity(&self) -> bool

True if this cache was pre-allocated via with_capacity and has not yet grown past that planned capacity (i.e. push has never had to reallocate). Useful for tests/diagnostics confirming the pre-allocation path actually avoided reallocs.

Trait Implementations§

Source§

impl Clone for KvCache

Cloning a pool-backed cache detaches the clone from pool accounting (its k/v/seq_len data is copied normally, but the clone does not hold or later release any blocks itself) – mirroring how ferrox-models::prefix_cache already uses KvCache::clone to fork a cached prefix into a new, independent request’s cache. Only the original cache’s blocks are released, exactly once, when it drops.

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Drop for KvCache

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.