Skip to main content

MaskPlan

Struct MaskPlan 

Source
pub struct MaskPlan { /* private fields */ }
Expand description

Per-layer attention-mask variation — the axis GAP-029 measured across increment 3’s families and the earlier six-axis check could not see, every one of its axes being model-scalar.

Note the axis is named for the behaviour that varies, not the first mechanism found: three families vary by sliding window, SmolLm3 varies by skipping RoPE entirely, and a checklist keyed on sliding_window would have cleared SmolLm3 outright.

§Shape in the graph

The mask Const is [n_variants, 1, seq, max_seq_len]; the build path hoists n_variants width-1 slices once, before the layer loop, and layer i takes variant_for_layer(i). DecodeTokenData, DecodeSession and the rebind driver are untouched — still one mask Arc, one mask_node.

n_variants == 1 mints [1, 1, seq, max_seq_len] and emits no slice node at all, so a uniform family’s graph is byte-identical to the pre-GAP-029 one. That is asserted, not claimed: see mask_variants_are_byte_identical_ to_the_dense_builder_when_uniform.

Implementations§

Source§

impl MaskPlan

Source

pub fn dense(n_layers: usize) -> Self

The uniform dense plan — every layer attends causally to the whole prefix. What LlamaModel and every other non-varying family use, and byte-identical to the pre-GAP-029 single-mask decode path.

Source

pub fn new(windows: Vec<Option<usize>>, per_layer: Vec<usize>) -> Result<Self>

Validated at construction, per the build-time-validation rule: an out-of-range variant index would otherwise surface as a panic deep in the layer loop, or — worse — as a silently mis-masked layer.

Source

pub fn split_window(n_layers: usize, split: usize, window: usize) -> Self

The layer_idx < split plan: the first split layers attend through a window, the rest densely. This is exactly the predicate Qwen2, Qwen3 and Qwen3Moe share (use_sliding_window && layer_idx < max_window_layers), so all three express their variation by calling this rather than hand-rolling a variant table.

Total by construction — no Result, no panic. Both degenerate splits collapse to a single variant, so a model that is entirely dense or entirely windowed emits no slice node and pays nothing: split == 0 is Self::dense, split >= n_layers is one windowed variant.

Source

pub fn per_layer_window( n_layers: usize, window: usize, uses_window: impl Fn(usize) -> bool, ) -> Self

Arbitrary per-layer window selection, TOTAL by construction.

Self::split_window covers the prefix predicate Qwen2/Qwen3/Qwen3Moe share. Gemma3’s is modular ((i + 1) % sliding_window_pattern > 0), so it needs a free selector — and it cannot use Self::new, because decode_mask_plan is infallible and expect-ing a Result on a production path is exactly the never-panic violation this project bans. A closure returning bool over exactly two defined variants cannot produce an out-of-range index, so this needs no Result at all.

Collapses to a single variant when the selector is constant, so a config that happens to window every layer (or none) still emits no slice.

Source

pub fn n_variants(&self) -> usize

Source

pub fn n_layers(&self) -> usize

Source

pub fn variant_for_layer(&self, layer_idx: usize) -> usize

Source

pub fn window_for_layer(&self, layer_idx: usize) -> Option<usize>

This layer’s window width, or None if it attends densely.

The single source shared with the mask bytes — the CUDA flash arm’s window_size_* and the mask Const come from the same plan entry, so they cannot disagree. A family deriving the window separately for the arm would be free to drift from the mask it actually applies, and “arm says dense, mask says windowed” is precisely the silent defect GAP-194 was filed about.

Source

pub fn mix_into(&self, h: &mut ShapeKeyHasher)

Mix the plan’s structural content into a decode shape key.

The variant count and the per-layer assignment change the graph’s shape and wiring, so a session built under one plan must not be reused under another. The window widths are deliberately excluded: they are data, rebound per token like the RoPE tables, and baking them would forfeit plan reuse across a change that is already handled correctly — the same argument decode_shape_key’s own doc makes for rope_base.

Trait Implementations§

Source§

impl Clone for MaskPlan

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 Debug for MaskPlan

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for MaskPlan

Source§

impl PartialEq for MaskPlan

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for MaskPlan

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

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, !>

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

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more