Skip to main content

ferrum_interfaces/vnext/operation/
weight_contract.rs

1use std::collections::BTreeSet;
2
3use serde::{Deserialize, Deserializer, Serialize};
4
5use super::super::{
6    CanonicalRational, ContractVersion, QuantizationFormatId, VNextError, WeightFormatId, WeightId,
7    WeightLayoutId,
8};
9use super::ElementType;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
12#[serde(rename_all = "snake_case")]
13pub enum QuantizationPacking {
14    Linear,
15    Interleaved,
16    Tiled,
17}
18
19/// How values are partitioned along a quantized layout's `group_axis`.
20///
21/// `WholeAxis` is shape-relative by design: all values on the group axis
22/// share one scale. This represents channelwise quantization without making a
23/// matrix dimension part of the otherwise stable quantization-format ABI.
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
25#[serde(tag = "kind", rename_all = "snake_case")]
26pub enum QuantizationGrouping {
27    Fixed { size: u32 },
28    WholeAxis,
29}
30
31impl QuantizationGrouping {
32    pub const fn fixed(size: u32) -> Self {
33        Self::Fixed { size }
34    }
35
36    pub const fn fixed_size(self) -> Option<u32> {
37        match self {
38            Self::Fixed { size } => Some(size),
39            Self::WholeAxis => None,
40        }
41    }
42
43    pub const fn resolved_size(self, axis_extent: u64) -> u64 {
44        match self {
45            Self::Fixed { size } => size as u64,
46            Self::WholeAxis => axis_extent,
47        }
48    }
49
50    const fn is_valid(self) -> bool {
51        match self {
52            Self::Fixed { size } => size != 0 && size.is_power_of_two(),
53            Self::WholeAxis => true,
54        }
55    }
56}
57
58#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
59pub struct QuantizationSpec {
60    pub format_id: QuantizationFormatId,
61    pub bits_per_weight: u8,
62    pub grouping: QuantizationGrouping,
63    pub packing: QuantizationPacking,
64    pub scale_type: ElementType,
65    pub zero_point_type: Option<ElementType>,
66}
67
68impl QuantizationSpec {
69    pub fn validate(&self) -> Result<(), VNextError> {
70        if !(1..=8).contains(&self.bits_per_weight)
71            || !self.grouping.is_valid()
72            || !matches!(
73                self.scale_type,
74                ElementType::F16 | ElementType::Bf16 | ElementType::F32
75            )
76            || self.zero_point_type.is_some_and(|element_type| {
77                !matches!(
78                    element_type,
79                    ElementType::U8 | ElementType::U32 | ElementType::I8 | ElementType::I32
80                )
81            })
82        {
83            return Err(VNextError::InvalidExecutionPlan {
84                reason: format!("invalid quantization format `{}`", self.format_id),
85            });
86        }
87        Ok(())
88    }
89}
90
91/// Self-contained fixed-size quantization blocks such as GGML/GGUF Q4_K and
92/// Q6_K. Per-block scales, minima, and packed values are part of the opaque
93/// block ABI identified by `format_id`; providers must not reinterpret these
94/// bytes as the separate-scale [`QuantizationSpec`] representation.
95#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
96pub struct BlockQuantizationSpec {
97    pub format_id: QuantizationFormatId,
98    pub logical_values_per_block: u32,
99    pub bytes_per_block: u32,
100}
101
102impl BlockQuantizationSpec {
103    pub fn validate(&self) -> Result<(), VNextError> {
104        if self.logical_values_per_block == 0 || self.bytes_per_block == 0 {
105            return Err(VNextError::InvalidExecutionPlan {
106                reason: format!("invalid block quantization format `{}`", self.format_id),
107            });
108        }
109        Ok(())
110    }
111}
112
113#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
114#[serde(rename_all = "snake_case")]
115pub enum WeightEncoding {
116    Dense {
117        element_type: ElementType,
118    },
119    /// Dense floating-point values materialized after applying
120    /// `logical = physical * scale + bias` element-wise. This keeps checkpoint
121    /// representation semantics in the typed weight schema rather than in a
122    /// backend provider or model-name branch.
123    DenseAffine {
124        element_type: ElementType,
125        scale: CanonicalRational,
126        bias: CanonicalRational,
127    },
128    Quantized(QuantizationSpec),
129    BlockQuantized(BlockQuantizationSpec),
130}
131
132impl WeightEncoding {
133    pub const fn dense_element_type(&self) -> Option<ElementType> {
134        match self {
135            Self::Dense { element_type } | Self::DenseAffine { element_type, .. } => {
136                Some(*element_type)
137            }
138            Self::Quantized(_) | Self::BlockQuantized(_) => None,
139        }
140    }
141
142    pub(crate) fn physical_bytes(
143        &self,
144        dimensions: &[u64],
145        component_id: &WeightId,
146    ) -> Result<u64, VNextError> {
147        let elements =
148            checked_elements(dimensions).ok_or_else(|| VNextError::InvalidExecutionPlan {
149                reason: format!("physical component `{component_id}` size overflows u64"),
150            })?;
151        match self {
152            Self::Dense { element_type } | Self::DenseAffine { element_type, .. } => elements
153                .checked_mul(element_type.size_bytes())
154                .ok_or_else(|| VNextError::InvalidExecutionPlan {
155                    reason: format!("physical component `{component_id}` byte size overflows u64"),
156                }),
157            Self::Quantized(_) => Ok(elements),
158            Self::BlockQuantized(spec) => {
159                spec.validate()?;
160                elements
161                    .checked_mul(u64::from(spec.bytes_per_block))
162                    .ok_or_else(|| VNextError::InvalidExecutionPlan {
163                        reason: format!(
164                            "physical block component `{component_id}` byte size overflows u64"
165                        ),
166                    })
167            }
168        }
169    }
170}
171
172/// Structural role of a physical component in a weight format. The role is
173/// intentionally independent of any named quantization or model family.
174#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
175#[serde(rename_all = "snake_case")]
176pub enum WeightComponentRole {
177    Values,
178    PackedValues,
179    Scales,
180    ZeroPoints,
181    Indices,
182    Permutation,
183    Codebook,
184    Metadata,
185}
186
187/// Padding is always explicit and carries the exact semantic padded shape.
188/// `Exact` has no hidden storage extension. `ZeroFill` must increase at least
189/// one dimension and, for tiled or grouped storage, must be the unique minimal
190/// shape implied by that contract.
191#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
192#[serde(rename_all = "snake_case")]
193pub enum PhysicalWeightPadding {
194    Exact,
195    ZeroFill { padded_dimensions: Vec<u64> },
196}
197
198/// Storage geometry for one physical component binding. Strides are measured
199/// in the component's schema storage unit: elements for dense encodings,
200/// bytes for separate-component packing, and blocks for block quantization.
201/// The component's declared dimensions describe its raw stored span, while
202/// this geometry maps the semantic component shape onto that span without
203/// inference or hidden padding.
204#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
205#[serde(rename_all = "snake_case")]
206pub enum PhysicalStorageLayout {
207    Contiguous {
208        padding: PhysicalWeightPadding,
209    },
210    Strided {
211        strides_in_elements: Vec<u64>,
212        padding: PhysicalWeightPadding,
213    },
214    Tiled {
215        tile_shape: Vec<u64>,
216        /// Physical tile-grid axis -> semantic component axis.
217        axis_order: Vec<u32>,
218        tile_strides_in_elements: Vec<u64>,
219        padding: PhysicalWeightPadding,
220    },
221}
222
223impl PhysicalStorageLayout {
224    pub fn exact_contiguous() -> Self {
225        Self::Contiguous {
226            padding: PhysicalWeightPadding::Exact,
227        }
228    }
229}
230
231#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
232pub struct PhysicalWeightComponentBinding {
233    pub component_id: WeightId,
234    pub storage: PhysicalStorageLayout,
235}
236
237impl PhysicalWeightComponentBinding {
238    pub fn exact_contiguous(component_id: WeightId) -> Self {
239        Self {
240            component_id,
241            storage: PhysicalStorageLayout::exact_contiguous(),
242        }
243    }
244}
245
246#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
247pub struct AxisWeightComponent {
248    pub component: PhysicalWeightComponentBinding,
249    pub axis: u32,
250}
251
252#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
253pub struct CompositeWeightPart {
254    pub layout: Box<PhysicalWeightLayout>,
255    pub logical_offsets: Vec<u64>,
256    pub extents: Vec<u64>,
257}
258
259/// Hard bounds keep directly constructed and deserialized recursive schemas
260/// cheap to validate. Ownership makes cycles unrepresentable; these limits
261/// additionally bound adversarial depth and fan-out.
262pub const MAX_PHYSICAL_WEIGHT_LAYOUT_DEPTH: usize = 16;
263pub const MAX_PHYSICAL_WEIGHT_LAYOUT_NODES: usize = 4096;
264
265/// Typed physical storage tree for one logical weight. Every leaf binds one
266/// physical component exactly once. Recursive composition allows indexing or
267/// expert stacking around dense, tiled, strided, or quantized values without
268/// architecture-specific cases.
269#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
270#[serde(rename_all = "snake_case")]
271pub enum PhysicalWeightLayout {
272    /// Exact, contiguous dense values. This common leaf deliberately remains
273    /// compact; use `Stored` for explicit stride, tile, or padding geometry.
274    Dense {
275        component_id: WeightId,
276    },
277    Stored {
278        component: PhysicalWeightComponentBinding,
279    },
280    Composite {
281        parts: Vec<CompositeWeightPart>,
282    },
283    Quantized {
284        packed_values: PhysicalWeightComponentBinding,
285        /// Semantic packed-storage shape before the binding's optional
286        /// stride/tile mapping. Its element product must equal the exact byte
287        /// count implied by logical elements and `bits_per_weight`.
288        packed_dimensions: Vec<u64>,
289        scales: PhysicalWeightComponentBinding,
290        zero_points: Option<PhysicalWeightComponentBinding>,
291        /// Optional packed storage shape for asymmetric zero points. When
292        /// absent, one dense zero-point scalar is stored per quantization
293        /// group. When present, it must contain exactly `bits_per_weight`
294        /// bits per group and the bound component dtype describes the packed
295        /// storage word (for example I32 words containing eight INT4 values).
296        zero_point_packed_dimensions: Option<Vec<u64>>,
297        /// Per-coordinate group assignment. Its semantic shape is the one
298        /// dimensional logical axis extent, not the multi-dimensional group
299        /// tensor shape.
300        axis_indices: Option<AxisWeightComponent>,
301        permutation: Option<AxisWeightComponent>,
302        codebook: Option<PhysicalWeightComponentBinding>,
303        group_axis: u32,
304        group_padding: PhysicalWeightPadding,
305    },
306    /// One opaque, self-contained quantization block represents a fixed
307    /// number of logical values along `block_axis`. The bound component shape
308    /// is the padded logical shape with that axis divided by the block width.
309    BlockQuantized {
310        blocks: PhysicalWeightComponentBinding,
311        block_axis: u32,
312        block_padding: PhysicalWeightPadding,
313    },
314    /// A contiguous logical subrange on one axis is stored by reshaping that
315    /// subrange and permuting the reshape axes. This captures checkpoint
316    /// layouts such as grouped-to-tiled head order without a model flag,
317    /// synthetic index tensor, or eager repack.
318    AxisReshapePermutation {
319        values: Box<PhysicalWeightLayout>,
320        axis: u32,
321        logical_offset: u64,
322        extent: u64,
323        reshape: Vec<u64>,
324        /// Stored axis position -> reshaped logical axis, matching an
325        /// n-dimensional transpose/permute order.
326        stored_axis_order: Vec<u32>,
327    },
328    Indexed {
329        indices: AxisWeightComponent,
330        values: Box<PhysicalWeightLayout>,
331        source_axis_extent: u64,
332    },
333    ExpertStack {
334        experts: Vec<PhysicalWeightLayout>,
335        expert_axis: u32,
336    },
337}
338
339impl PhysicalWeightLayout {
340    pub(crate) fn normalize(&mut self) {
341        match self {
342            Self::Composite { parts } => {
343                for part in parts.iter_mut() {
344                    part.layout.normalize();
345                }
346                // Offsets make composite placement semantic and order-free.
347                // Validation subsequently proves that no two placements
348                // overlap, so this order cannot reorder an ordered sequence.
349                parts.sort_by(|left, right| {
350                    left.logical_offsets
351                        .cmp(&right.logical_offsets)
352                        .then_with(|| left.extents.cmp(&right.extents))
353                });
354            }
355            Self::AxisReshapePermutation { values, .. } | Self::Indexed { values, .. } => {
356                values.normalize()
357            }
358            Self::ExpertStack { experts, .. } => {
359                // Expert vector position is the expert index and is therefore
360                // semantic. Normalize descendants without sorting the vector.
361                for expert in experts {
362                    expert.normalize();
363                }
364            }
365            Self::Dense { .. }
366            | Self::Stored { .. }
367            | Self::Quantized { .. }
368            | Self::BlockQuantized { .. } => {}
369        }
370    }
371}
372
373/// Provider-visible physical identity for one component of a resolved weight.
374/// Source file names are intentionally excluded: source provenance belongs to
375/// the prepared family fingerprint, while providers need shape, role, and ABI.
376#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
377pub struct ResolvedWeightComponentLayout {
378    component_id: WeightId,
379    role: WeightComponentRole,
380    physical_dimensions: Vec<u64>,
381    encoding: WeightEncoding,
382}
383
384impl ResolvedWeightComponentLayout {
385    pub(crate) fn from_parts(
386        component_id: WeightId,
387        role: WeightComponentRole,
388        physical_dimensions: Vec<u64>,
389        encoding: WeightEncoding,
390    ) -> Self {
391        Self {
392            component_id,
393            role,
394            physical_dimensions,
395            encoding,
396        }
397    }
398
399    pub fn component_id(&self) -> &WeightId {
400        &self.component_id
401    }
402
403    pub const fn role(&self) -> WeightComponentRole {
404        self.role
405    }
406
407    pub fn physical_dimensions(&self) -> &[u64] {
408        &self.physical_dimensions
409    }
410
411    pub fn encoding(&self) -> &WeightEncoding {
412        &self.encoding
413    }
414
415    pub fn physical_bytes(&self) -> Result<u64, VNextError> {
416        self.encoding
417            .physical_bytes(&self.physical_dimensions, &self.component_id)
418    }
419
420    pub fn physical_element_type(&self) -> ElementType {
421        self.encoding
422            .dense_element_type()
423            .unwrap_or(ElementType::U8)
424    }
425}
426
427/// Immutable physical weight contract carried by an execution-plan binding.
428/// This prevents the provider boundary from collapsing a quantized/composite
429/// layout into only resource ranges and a synthetic `u8` dtype.
430///
431/// `schema_format_id` identifies the enclosing source or materialized schema.
432/// It is a planning compatibility key, not the physical ABI of every component
433/// referenced by this binding. Providers must decode components from
434/// `physical_layout` and `components`.
435#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
436pub struct ResolvedWeightBinding {
437    weight_id: WeightId,
438    #[serde(rename = "format_id")]
439    schema_format_id: WeightFormatId,
440    layout_id: WeightLayoutId,
441    schema_version: ContractVersion,
442    physical_layout: PhysicalWeightLayout,
443    components: Vec<ResolvedWeightComponentLayout>,
444}
445
446/// Operation-owned capability for validating a resolved physical binding
447/// against the logical tensor contract supplied by the model layer.
448///
449/// The physical ABI stays independent of model schemas; the model owner
450/// provides the schema-aware implementation without introducing an
451/// operation-to-model dependency.
452pub(crate) trait ResolvedWeightLogicalValidation {
453    fn validate_logical_contract(
454        &self,
455        logical_dimensions: &[u64],
456        logical_element_type: ElementType,
457    ) -> Result<(), VNextError>;
458}
459
460#[derive(Deserialize)]
461#[serde(deny_unknown_fields)]
462struct ResolvedWeightBindingWire {
463    weight_id: WeightId,
464    format_id: WeightFormatId,
465    layout_id: WeightLayoutId,
466    schema_version: ContractVersion,
467    physical_layout: PhysicalWeightLayout,
468    components: Vec<ResolvedWeightComponentLayout>,
469}
470
471impl<'de> Deserialize<'de> for ResolvedWeightBinding {
472    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
473    where
474        D: Deserializer<'de>,
475    {
476        let wire = ResolvedWeightBindingWire::deserialize(deserializer)?;
477        Self::from_parts(
478            wire.weight_id,
479            wire.format_id,
480            wire.layout_id,
481            wire.schema_version,
482            wire.physical_layout,
483            wire.components,
484        )
485        .map_err(serde::de::Error::custom)
486    }
487}
488
489impl ResolvedWeightBinding {
490    pub(crate) fn from_parts(
491        weight_id: WeightId,
492        schema_format_id: WeightFormatId,
493        layout_id: WeightLayoutId,
494        schema_version: ContractVersion,
495        physical_layout: PhysicalWeightLayout,
496        components: Vec<ResolvedWeightComponentLayout>,
497    ) -> Result<Self, VNextError> {
498        let binding = Self {
499            weight_id,
500            schema_format_id,
501            layout_id,
502            schema_version,
503            physical_layout,
504            components,
505        };
506        binding.validate_structure()?;
507        Ok(binding)
508    }
509
510    pub(crate) fn validate_structure(&self) -> Result<(), VNextError> {
511        validate_physical_layout_budget(&self.physical_layout).map_err(|reason| {
512            VNextError::InvalidExecutionPlan {
513                reason: format!("resolved weight `{}` layout: {reason}", self.weight_id),
514            }
515        })?;
516        let referenced = physical_component_ids(&self.physical_layout).map_err(|reason| {
517            VNextError::InvalidExecutionPlan {
518                reason: format!("resolved weight `{}` layout: {reason}", self.weight_id),
519            }
520        })?;
521        let component_ids = self
522            .components
523            .iter()
524            .map(|component| component.component_id.clone())
525            .collect::<BTreeSet<_>>();
526        let canonical_components = self
527            .components
528            .windows(2)
529            .all(|pair| pair[0].component_id < pair[1].component_id);
530        if self.schema_version.major == 0
531            || self.components.is_empty()
532            || !canonical_components
533            || component_ids.len() != self.components.len()
534            || component_ids != referenced
535            || self.components.iter().any(|component| {
536                component.physical_dimensions.is_empty()
537                    || component
538                        .physical_dimensions
539                        .iter()
540                        .any(|extent| *extent == 0)
541                    || component.physical_bytes().is_err()
542            })
543        {
544            return Err(VNextError::InvalidExecutionPlan {
545                reason: format!(
546                    "resolved weight `{}` physical identity is invalid or non-canonical",
547                    self.weight_id
548                ),
549            });
550        }
551        Ok(())
552    }
553
554    pub fn weight_id(&self) -> &WeightId {
555        &self.weight_id
556    }
557
558    /// Enclosing schema/container identity used by provider selection.
559    ///
560    /// This must not be used to infer a bound component's physical encoding.
561    pub(crate) fn schema_format_id(&self) -> &WeightFormatId {
562        &self.schema_format_id
563    }
564
565    pub fn layout_id(&self) -> &WeightLayoutId {
566        &self.layout_id
567    }
568
569    pub const fn schema_version(&self) -> ContractVersion {
570        self.schema_version
571    }
572
573    pub fn physical_layout(&self) -> &PhysicalWeightLayout {
574        &self.physical_layout
575    }
576
577    pub fn components(&self) -> &[ResolvedWeightComponentLayout] {
578        &self.components
579    }
580
581    pub fn quantization_formats(&self) -> BTreeSet<QuantizationFormatId> {
582        self.components
583            .iter()
584            .filter_map(|component| match &component.encoding {
585                WeightEncoding::Quantized(spec) => Some(spec.format_id.clone()),
586                WeightEncoding::BlockQuantized(spec) => Some(spec.format_id.clone()),
587                WeightEncoding::Dense { .. } | WeightEncoding::DenseAffine { .. } => None,
588            })
589            .collect()
590    }
591}
592
593fn push_physical_layout_child<'a>(
594    stack: &mut Vec<(&'a PhysicalWeightLayout, usize)>,
595    child: &'a PhysicalWeightLayout,
596    child_depth: usize,
597    visited: usize,
598) -> Result<(), String> {
599    if visited
600        .checked_add(stack.len())
601        .is_none_or(|pending| pending >= MAX_PHYSICAL_WEIGHT_LAYOUT_NODES)
602    {
603        return Err(format!(
604            "physical layout node count exceeds {MAX_PHYSICAL_WEIGHT_LAYOUT_NODES}"
605        ));
606    }
607    stack.push((child, child_depth));
608    Ok(())
609}
610
611pub(crate) fn validate_physical_layout_budget(layout: &PhysicalWeightLayout) -> Result<(), String> {
612    let mut stack = vec![(layout, 1_usize)];
613    let mut visited = 0_usize;
614    while let Some((node, depth)) = stack.pop() {
615        if depth > MAX_PHYSICAL_WEIGHT_LAYOUT_DEPTH {
616            return Err(format!(
617                "physical layout depth exceeds {MAX_PHYSICAL_WEIGHT_LAYOUT_DEPTH}"
618            ));
619        }
620        let direct_bindings = match node {
621            PhysicalWeightLayout::Dense { .. } | PhysicalWeightLayout::Stored { .. } => 1,
622            PhysicalWeightLayout::Quantized {
623                zero_points,
624                axis_indices,
625                permutation,
626                codebook,
627                ..
628            } => {
629                2 + usize::from(zero_points.is_some())
630                    + usize::from(axis_indices.is_some())
631                    + usize::from(permutation.is_some())
632                    + usize::from(codebook.is_some())
633            }
634            PhysicalWeightLayout::BlockQuantized { .. } => 1,
635            PhysicalWeightLayout::AxisReshapePermutation { .. } => 0,
636            PhysicalWeightLayout::Indexed { .. } => 1,
637            PhysicalWeightLayout::Composite { .. } | PhysicalWeightLayout::ExpertStack { .. } => 0,
638        };
639        visited = visited
640            .checked_add(1 + direct_bindings)
641            .ok_or_else(|| "physical layout node count overflows usize".to_owned())?;
642        if visited > MAX_PHYSICAL_WEIGHT_LAYOUT_NODES {
643            return Err(format!(
644                "physical layout node count exceeds {MAX_PHYSICAL_WEIGHT_LAYOUT_NODES}"
645            ));
646        }
647        let child_depth = depth
648            .checked_add(1)
649            .ok_or_else(|| "physical layout depth overflows usize".to_owned())?;
650        match node {
651            PhysicalWeightLayout::Composite { parts } => {
652                for part in parts {
653                    push_physical_layout_child(&mut stack, &part.layout, child_depth, visited)?;
654                }
655            }
656            PhysicalWeightLayout::AxisReshapePermutation { values, .. }
657            | PhysicalWeightLayout::Indexed { values, .. } => {
658                push_physical_layout_child(&mut stack, values, child_depth, visited)?;
659            }
660            PhysicalWeightLayout::ExpertStack { experts, .. } => {
661                for expert in experts {
662                    push_physical_layout_child(&mut stack, expert, child_depth, visited)?;
663                }
664            }
665            PhysicalWeightLayout::Dense { .. }
666            | PhysicalWeightLayout::Stored { .. }
667            | PhysicalWeightLayout::Quantized { .. }
668            | PhysicalWeightLayout::BlockQuantized { .. } => {}
669        }
670    }
671    Ok(())
672}
673
674pub(crate) fn physical_component_ids(
675    layout: &PhysicalWeightLayout,
676) -> Result<BTreeSet<WeightId>, String> {
677    validate_physical_layout_budget(layout)?;
678    let mut ids = BTreeSet::new();
679    let mut stack = vec![layout];
680    while let Some(node) = stack.pop() {
681        let mut insert_binding = |binding: &PhysicalWeightComponentBinding| {
682            ids.insert(binding.component_id.clone());
683        };
684        match node {
685            PhysicalWeightLayout::Dense { component_id } => {
686                ids.insert(component_id.clone());
687            }
688            PhysicalWeightLayout::Stored { component } => insert_binding(component),
689            PhysicalWeightLayout::Composite { parts } => {
690                stack.extend(parts.iter().map(|part| part.layout.as_ref()));
691            }
692            PhysicalWeightLayout::Quantized {
693                packed_values,
694                scales,
695                zero_points,
696                axis_indices,
697                permutation,
698                codebook,
699                ..
700            } => {
701                insert_binding(packed_values);
702                insert_binding(scales);
703                if let Some(binding) = zero_points {
704                    insert_binding(binding);
705                }
706                if let Some(axis_component) = axis_indices {
707                    insert_binding(&axis_component.component);
708                }
709                if let Some(axis_component) = permutation {
710                    insert_binding(&axis_component.component);
711                }
712                if let Some(binding) = codebook {
713                    insert_binding(binding);
714                }
715            }
716            PhysicalWeightLayout::BlockQuantized { blocks, .. } => insert_binding(blocks),
717            PhysicalWeightLayout::AxisReshapePermutation { values, .. } => stack.push(values),
718            PhysicalWeightLayout::Indexed {
719                indices, values, ..
720            } => {
721                insert_binding(&indices.component);
722                stack.push(values);
723            }
724            PhysicalWeightLayout::ExpertStack { experts, .. } => {
725                stack.extend(experts);
726            }
727        }
728    }
729    Ok(ids)
730}
731
732pub(crate) fn checked_elements(dimensions: &[u64]) -> Option<u64> {
733    dimensions
734        .iter()
735        .try_fold(1_u64, |elements, extent| elements.checked_mul(*extent))
736}