#[non_exhaustive]pub struct BlockPagedLayout {
pub page_size: u32,
pub num_pages: u64,
pub paged_axis: u32,
pub num_seqs: u32,
pub kv_role: KvRole,
pub layer_index: Option<u32>,
pub block_table_index_type: BlockTableIndexType,
}Expand description
Descriptor for the block-paged indirect layout.
Block-paged stores a KV-cache tensor whose paged axis is divided into fixed-size pages drawn from a shared page pool, with a block table mapping each logical page position to a physical page ID. It is the interchange form of a PagedAttention KV cache.
This layout is defined only for rank-3 tensors in this version of the
specification: [total_tokens, num_heads, head_dim].
Three buffers are always required:
| Buffer | Name | Description |
|---|---|---|
| 0 | page_pool | Flat pool of fixed-size pages. |
| 1 | block_table | Concatenated per-sequence page-ID lists. |
| 2 | seq_ptr | CSR-style offset array into block_table. |
When the tensor carries quantization parameters, additional buffers appear
at indices 3 and above per docs/spec/quantization.md § Buffer Table Placement Rules.
See docs/spec/layouts/block-paged.md for the full normative definition.
§Examples
use hurray_core::layout::{BlockPagedLayout, BlockTableIndexType, KvRole, LayoutDescriptor};
let layout = BlockPagedLayout::new(16, 128, 0, 4, KvRole::Key, Some(3), BlockTableIndexType::U32);
assert_eq!(layout.page_size, 16);
assert_eq!(layout.num_pages, 128);
assert_eq!(layout.num_seqs, 4);
assert_eq!(layout.layer_index, Some(3));
let desc = LayoutDescriptor::BlockPaged(layout);
assert_eq!(desc.tag(), 0x0A);
assert_eq!(desc.buffer_count().map(|n| n.get()), Some(3));Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.page_size: u32Tokens per page. MUST be >= 1.
Common values are 16 and 32 (matching vLLM’s default block_size).
num_pages: u64Number of physical pages in page_pool.
paged_axis: u32The axis subdivided into pages. MUST be 0 in this spec version.
Kept as a field rather than a constant so that the wire format remains forward-compatible if a future spec version adds non-zero paged axes.
num_seqs: u32Number of sequences in the batch. MAY be 0 for an empty batch.
kv_role: KvRoleKV-cache role for this tensor (key, value, or fused/generic).
layer_index: Option<u32>Transformer layer index, or None if the tensor is not layer-scoped.
Wire value 0xFFFFFFFF maps to None; all other values map to Some(n).
block_table_index_type: BlockTableIndexTypeElement type for both the block_table (buffer 1) and seq_ptr (buffer 2).
U32 is the default and addresses up to 4 billion pages.
U64 is required for larger pools.
Implementations§
Source§impl BlockPagedLayout
impl BlockPagedLayout
Sourcepub fn new(
page_size: u32,
num_pages: u64,
paged_axis: u32,
num_seqs: u32,
kv_role: KvRole,
layer_index: Option<u32>,
block_table_index_type: BlockTableIndexType,
) -> Self
pub fn new( page_size: u32, num_pages: u64, paged_axis: u32, num_seqs: u32, kv_role: KvRole, layer_index: Option<u32>, block_table_index_type: BlockTableIndexType, ) -> Self
Creates a new BlockPagedLayout.
§Arguments
page_size— tokens per page (MUST be validated >= 1 later viavalidate_against_shape).num_pages— number of physical pages in the pool.paged_axis— the axis subdivided into pages (MUST be 0 in this version).num_seqs— number of sequences in the batch.kv_role— KV-cache role for this tensor.layer_index— transformer layer index (None= not layer-scoped).block_table_index_type— element type forblock_tableandseq_ptrbuffers.
This constructor does not validate page_size >= 1 or paged_axis == 0 because
the tensor shape is not available at construction time. Call
[LayoutDescriptor::validate_against_shape] to perform all invariant checks
once the shape is known.
§Examples
use hurray_core::layout::{BlockPagedLayout, BlockTableIndexType, KvRole};
// Layer-3 key cache: page_size=16, 64 pages, 2 sequences, uint32 indices.
let layout = BlockPagedLayout::new(
16, 64, 0, 2,
KvRole::Key,
Some(3),
BlockTableIndexType::U32,
);
assert_eq!(layout.page_size, 16);
assert_eq!(layout.layer_index, Some(3));Sourcepub fn validate_quantization_compatibility(
&self,
scheme_tag: u8,
quant_axis: u32,
quant_block_size: u32,
) -> Result<()>
pub fn validate_quantization_compatibility( &self, scheme_tag: u8, quant_axis: u32, quant_block_size: u32, ) -> Result<()>
Validates that a quantization scheme is compatible with this block-paged layout.
Per docs/spec/layouts/block-paged.md § Quantization Compatibility:
- Per-tensor (
scheme_tag = 0x01): always compatible. - Per-channel (
scheme_tag = 0x02): MUST NOT be applied on axis 0 (the paged / token axis).quant_axismust be 1 (num_heads) or 2 (head_dim). - Per-block-affine (
scheme_tag = 0x03):quant_axisMUST be 0 andquant_block_sizeMUST equalpage_size. - All other schemes: not validated here; returns
Ok(()).
Call this at the typed-quantization layer once you have a decoded
crate::QuantizationDescriptor. The raw-bytes descriptor layer cannot
perform this check.
§Arguments
scheme_tag— thescheme_tagbyte from the quantization descriptor header.quant_axis— theaxisfield from the quantization descriptor (relevant for per-channel and per-block-affine).quant_block_size— theblock_sizefield from the per-block-affine descriptor (ignored for all other schemes).
§Errors
Returns crate::Error::InvalidQuantization if the scheme/layout combination
violates the spec rules above.
§Examples
use hurray_core::layout::{BlockPagedLayout, BlockTableIndexType, KvRole};
let layout = BlockPagedLayout::new(16, 64, 0, 2, KvRole::Key, Some(0), BlockTableIndexType::U32);
// Per-tensor (0x01) is always valid.
assert!(layout.validate_quantization_compatibility(0x01, 0, 0).is_ok());
// Per-channel on axis 1 (num_heads) is valid.
assert!(layout.validate_quantization_compatibility(0x02, 1, 0).is_ok());
// Per-channel on axis 0 (paged axis) is forbidden.
assert!(layout.validate_quantization_compatibility(0x02, 0, 0).is_err());
// Per-block-affine with axis=0 and block_size==page_size is valid.
assert!(layout.validate_quantization_compatibility(0x03, 0, 16).is_ok());
// Per-block-affine with block_size != page_size is forbidden.
assert!(layout.validate_quantization_compatibility(0x03, 0, 32).is_err());Trait Implementations§
Source§impl Clone for BlockPagedLayout
impl Clone for BlockPagedLayout
Source§fn clone(&self) -> BlockPagedLayout
fn clone(&self) -> BlockPagedLayout
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more