pub struct SizeClass(pub u32);Expand description
Dispatch size bucket. One u32 field carries two representations,
disambiguated by the OpKind that always sits beside it in the
dispatch key (a matmul key is only ever compared to matmul keys):
-
Total-elements key (every non-matmul op — elementwise, reduce, cast, …): the value is
log2(total_elements). A 256×256 elementwise tensor (65,536 elements) →16; a 1024×1024 (1,048,576) →20. Built bySizeClass::from_elem_count. Two shapes that round to the same bucket share a profile entry. -
MatMul aspect key: matmul cost is aspect-dependent — a
[1,K]×[K,N]GEMV is bandwidth-bound, a square[S,S]×[S,S]GEMM of the same output size is compute-bound — solog2(total_elements)alone can’t tell them apart. A matmul packs all three dims:(log2(m·n) << 16) | (log2(m) << 8) | log2(k), read fromlhs=[…,m,k]/rhs=[…,k,n].log2(m·n)occupies the high byte soDispatchTable::pick_nearest’s magnitude ordering still tracks output size, while the low bytes distinguish aspect (a GEMV and a same-output-size square never collide, because theirlog2(m)bytes differ). Built bySizeClass::matmul.
Producer/consumer single-sourcing. The fuel-core Judge
(producer) and every consumer (the fuel-dispatch ranker at
realize time) derive the key through the SAME helpers —
SizeClass::matmul from native (m,n,k) on the producer side,
SizeClass::for_op from the operand shapes on the consumer side.
A given matmul shape therefore maps to one identical key on both
sides, so a cell the Judge profiles is found by the ranker at
dispatch time (the bug this repr fixes: the old scalar key had the
producer on m·n and the consumer on m·k, so non-square matmul
lookups always missed).
Tuple Fields§
§0: u32Implementations§
Source§impl SizeClass
impl SizeClass
Sourcepub fn from_elem_count(n: usize) -> SizeClass
pub fn from_elem_count(n: usize) -> SizeClass
Bucket a raw element count as log2(n) — the total-elements key
used by every non-matmul op. n == 0 clamps to 1 (→ 0).
Sourcepub fn matmul(m: usize, n: usize, k: usize) -> SizeClass
pub fn matmul(m: usize, n: usize, k: usize) -> SizeClass
Aspect-carrying dispatch key for a matmul [m,k] × [k,n].
THE single source of matmul-key derivation: both the Judge
(producer, from its native (m,n,k)) and the ranker (consumer,
via SizeClass::for_op from operand shapes) call this, so both
sides agree for every shape. Packs (log2(m·n) << 16) | (log2(m) << 8) | log2(k); each log2 fits a byte (≤ 63 for any
usize). A [1,K]×[K,N] GEMV (m = 1) never collides with a
square GEMM of equal output size — the log2(m) byte differs.
Sourcepub fn attention(hq: usize, k_len: usize, d: usize) -> SizeClass
pub fn attention(hq: usize, k_len: usize, d: usize) -> SizeClass
Aspect-carrying dispatch key for a decode attention op
(OpKind::FlashAttn): q = [B, Hq, Sq, D], K/V attended
length k_len, head dim d.
THE single source of attention-key derivation, mirroring
SizeClass::matmul: both the Judge (producer, from its native
OpSize::Attention (hq, k_len, d)) and the flash-vs-decomposed
bake (consumer, via SizeClass::for_op from the flash node’s
operand shapes) call this, so both sides agree for every shape.
Packs (log2(hq·k_len·d) << 16) | (log2(k_len) << 8) | log2(d):
the high 16 bits track total attention work (O(Hq·k_len·D) for
the QKᵀ + PV matmuls at seq_q=1), so DispatchTable::pick_nearest’s
magnitude ordering still follows problem size, while the low bytes
carry the k_len (context-length / bandwidth regime) and head-dim
aspects — so two decode shapes that differ only in k_len (short
vs capacity context) never collide onto one cell. Each log2 fits
a byte (≤ 63 for any usize).
Sourcepub fn for_op(op: OpKind, input_shapes: &[Shape]) -> SizeClass
pub fn for_op(op: OpKind, input_shapes: &[Shape]) -> SizeClass
Derive the dispatch key for op from its input operand shapes —
the single entry point every consumer uses. A OpKind::MatMul
reads (m,n,k) from lhs=[…,m,k] / rhs=[…,k,n] (trailing two
dims; leading batch dims don’t affect the key) and keys via
SizeClass::matmul; every other op keys on the first operand’s
total element count via SizeClass::from_elem_count. Empty
shapes (nullary op) → SizeClass(0).
Trait Implementations§
impl Copy for SizeClass
Source§impl<'de> Deserialize<'de> for SizeClass
impl<'de> Deserialize<'de> for SizeClass
Source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<SizeClass, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<SizeClass, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
impl Eq for SizeClass
Source§impl Ord for SizeClass
impl Ord for SizeClass
1.21.0 (const: unstable) · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
1.21.0 (const: unstable) · Source§fn min(self, other: Self) -> Selfwhere
Self: Sized,
fn min(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl PartialOrd for SizeClass
impl PartialOrd for SizeClass
Source§impl Serialize for SizeClass
impl Serialize for SizeClass
Source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
impl StructuralPartialEq for SizeClass
Auto Trait Implementations§
impl Freeze for SizeClass
impl RefUnwindSafe for SizeClass
impl Send for SizeClass
impl Sync for SizeClass
impl Unpin for SizeClass
impl UnsafeUnpin for SizeClass
impl UnwindSafe for SizeClass
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> Comparable<K> for Q
impl<Q, K> Comparable<K> for Q
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
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