pub struct SharedKVPool {
pub manifest: PoolManifest,
pub layers: Vec<PoolLayer>,
pub policy: CompressionPolicy,
}Expand description
A shared, compressed KV cache pool.
The pool holds fib-quant compressed KV blocks for tokens shared across agents. It is immutable after construction. Agent shells can be materialized from this pool by adding agent-specific tokens compressed with turbo-quant.
Fields§
§manifest: PoolManifestPool manifest with shape, policy, timestamps.
layers: Vec<PoolLayer>One PoolLayer per transformer layer.
policy: CompressionPolicyThe compression policy used.
Implementations§
Sourcepub fn build(
corpus: &[(String, Vec<f32>)],
shape: &KvTensorShape,
seed: u64,
) -> Result<(Self, PoolBuildReceipt)>
pub fn build( corpus: &[(String, Vec<f32>)], shape: &KvTensorShape, seed: u64, ) -> Result<(Self, PoolBuildReceipt)>
Build a shared KV pool from a corpus of token vectors.
§Arguments
corpus- List of (token_id, kv_vector) pairs. Each kv_vector must be the concatenated keys and values for all layers and heads:[layer0_head0_key, layer0_head0_value, layer0_head1_key, ...].shape- The tensor shape describing the model architecture.seed- Deterministic seed for codec operations.
§Returns
The built SharedKVPool and a PoolBuildReceipt.
Sourcepub fn materialize_shell(
&self,
agent_id: &str,
agent_tokens: &[(String, Vec<f32>)],
seed: u64,
) -> Result<(AgentShell, ShellMaterializeReceipt)>
pub fn materialize_shell( &self, agent_id: &str, agent_tokens: &[(String, Vec<f32>)], seed: u64, ) -> Result<(AgentShell, ShellMaterializeReceipt)>
Materialize an agent shell from this pool.
Agent-specific tokens (not in the shared corpus) are compressed with turbo-quant and appended as shell layers. Tokens already in the pool are referenced by digest only.
§Arguments
agent_id- Identifier for this agent.agent_tokens- Token vectors specific to this agent.seed- Deterministic seed for turbo-quant operations.
§Returns
An AgentShell and a ShellMaterializeReceipt.
Sourcepub fn inject_into_cache(
_shell: &AgentShell,
_base_cache: &mut dyn CacheTarget,
) -> Result<InjectionReceipt>
pub fn inject_into_cache( _shell: &AgentShell, _base_cache: &mut dyn CacheTarget, ) -> Result<InjectionReceipt>
Inject a shell into a KV cache.
The injection receipt traces every block from its source (pool or shell) to its target position in the cache.
Sourcepub fn decompress_layer(&self, layer_idx: usize) -> Result<DecompressedLayer>
pub fn decompress_layer(&self, layer_idx: usize) -> Result<DecompressedLayer>
Decompress all shared-pool blocks for a single layer, returning the reconstructed K and V tensors in the original model layout.
Output shape: keys[head_idx] is a flat Vec<f32> of length
num_tokens * head_dim containing all tokens’ K vectors for that
head, in token order. Same for values. Lossy (fib-quant) but
reproducible: same corpus + same seed + same codec yields the same
reconstructed floats.
This is the inverse of build and the symmetric counterpart of
materialize_shell’s per-agent shell decompression. It’s the
path HuggingFace DynamicCache.update() and similar KV-cache
integrations use to populate a fresh cache from the pool.
Sourcepub fn attention_topk_compressed(
&self,
layer_idx: usize,
head_idx: usize,
query: &[f32],
top_k: usize,
) -> Result<CompressedAttentionSelection>
pub fn attention_topk_compressed( &self, layer_idx: usize, head_idx: usize, query: &[f32], top_k: usize, ) -> Result<CompressedAttentionSelection>
Query the compressed shared cold pool without fully decoding the layer.
This scores compressed Fib codes for one layer/head, selects the top-k tokens, then decodes only the selected value vectors. It is the ProveKV cold-pool read path: compressed candidate scoring first, bounded value decode second, and a receipt proving no full-layer decode occurred.
Sourcepub fn prepare_compressed_index(
&self,
layer_idx: usize,
head_idx: usize,
) -> Result<PreparedCompressedIndex>
pub fn prepare_compressed_index( &self, layer_idx: usize, head_idx: usize, ) -> Result<PreparedCompressedIndex>
Build a prepared compressed index for one layer/head.
This decodes key/value codes and builds the FibScorer once, so that
subsequent attention_topk_compressed_prepared calls only need to
prepare the query and score candidates without rebuilding codec state.
Sourcepub fn attention_topk_compressed_prepared(
&self,
index: &PreparedCompressedIndex,
query: &[f32],
top_k: usize,
) -> Result<CompressedAttentionSelection>
pub fn attention_topk_compressed_prepared( &self, index: &PreparedCompressedIndex, query: &[f32], top_k: usize, ) -> Result<CompressedAttentionSelection>
Compressed top-k attention using a pre-built index.
This avoids rebuilding the codec adapter, decoding codes, and constructing the scorer on every call. Only the query is prepared per call (O(dim)), then candidates are scored (O(num_tokens)).
Sourcepub fn prepare_fully_compressed_index(
&self,
layer_idx: usize,
head_idx: usize,
) -> Result<FullyPreparedCompressedIndex>
pub fn prepare_fully_compressed_index( &self, layer_idx: usize, head_idx: usize, ) -> Result<FullyPreparedCompressedIndex>
Build a fully prepared index that pre-unpacks all key indices and norms.
This eliminates per-call unpack_indices() and decode_stored_norm()
overhead, making the scoring loop just Gram table lookups.
Sourcepub fn attention_topk_fully_prepared(
&self,
index: &FullyPreparedCompressedIndex,
query: &[f32],
top_k: usize,
) -> Result<CompressedAttentionSelection>
pub fn attention_topk_fully_prepared( &self, index: &FullyPreparedCompressedIndex, query: &[f32], top_k: usize, ) -> Result<CompressedAttentionSelection>
Compressed top-k attention using a fully prepared index.
Delegates to attention_topk_prefetched which pre-fetches Gram rows
into a contiguous buffer for cache-friendly scoring. This is the
fastest single-head path.
Sourcepub fn attention_topk_prefetched(
&self,
index: &FullyPreparedCompressedIndex,
query: &[f32],
top_k: usize,
) -> Result<CompressedAttentionSelection>
pub fn attention_topk_prefetched( &self, index: &FullyPreparedCompressedIndex, query: &[f32], top_k: usize, ) -> Result<CompressedAttentionSelection>
Compressed top-k attention using pre-fetched Gram rows.
This is the fastest scoring path: query preparation + Gram row pre-fetch happens once, then the per-token scoring loop is just sequential gathers from a small contiguous buffer.
Sourcepub fn attention_topk_batch_heads(
&self,
index: &FullyPreparedCompressedIndex,
queries: &[&[f32]],
top_k: usize,
) -> Result<Vec<CompressedAttentionSelection>>
pub fn attention_topk_batch_heads( &self, index: &FullyPreparedCompressedIndex, queries: &[&[f32]], top_k: usize, ) -> Result<Vec<CompressedAttentionSelection>>
Batch multi-head compressed top-k attention using pre-fetched Gram rows.
Scores all heads in one pass: prepares gram rows for each head’s query, then iterates tokens once, scoring all heads per token. This amortizes the token loop overhead across heads and improves cache utilization.
Sourcepub fn search_similar_tokens(
&self,
layer_idx: usize,
query: &[f32],
top_k: usize,
) -> Result<Vec<(usize, f32)>>
pub fn search_similar_tokens( &self, layer_idx: usize, query: &[f32], top_k: usize, ) -> Result<Vec<(usize, f32)>>
Search for tokens most similar to a query vector.
Decompresses the specified layer’s key blocks and returns the top-K token indices with exact cosine similarity scores. For small pools (<10K tokens) this is fast enough with linear scan. For larger pools, prefer a dedicated ANN index.
Sourcepub fn save_to_path(&self, path: &Path) -> Result<()>
pub fn save_to_path(&self, path: &Path) -> Result<()>
Save the pool to a JSON file.
Writes the manifest and all layers (including compressed payloads) to a single JSON file. Compressed payloads are embedded as base64. For large pools (>100K tokens), consider mmap-based persistence instead.
Sourcepub fn load_from_path(path: &Path) -> Result<Self>
pub fn load_from_path(path: &Path) -> Result<Self>
Load a pool from a JSON file previously written by [save_to_path].
Trait Implementations§
Source§fn clone(&self) -> SharedKVPool
fn clone(&self) -> SharedKVPool
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
Blanket Implementations§
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
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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 moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.