vyre_spec/data_type/
validation.rs1use super::{DataType, QuantizationScale, QuantizationZeroPoint};
4
5impl DataType {
6 pub fn validate_layout(&self) -> Result<(), String> {
19 self.validate_layout_at("DataType")
20 }
21
22 fn validate_layout_at(&self, path: &str) -> Result<(), String> {
23 match self {
24 Self::Array { element_size } => {
25 if *element_size == 0 {
26 return Err(format!(
27 "Fix: {path}::Array element_size must be > 0 for a frozen layout contract."
28 ));
29 }
30 Ok(())
31 }
32 Self::Vec { element, count } => {
33 if *count == 0 {
34 return Err(format!(
35 "Fix: {path}::Vec count must be > 0 for a frozen layout contract."
36 ));
37 }
38 element.validate_layout_at("DataType::Vec.element")
39 }
40 Self::TensorShaped { element, shape } => {
41 for (axis, &dim) in shape.iter().enumerate() {
42 if dim == 0 {
43 return Err(format!(
44 "Fix: {path}::TensorShaped shape[{axis}] must be > 0 for a frozen layout contract."
45 ));
46 }
47 }
48 element.validate_layout_at("DataType::TensorShaped.element")
49 }
50 Self::SparseCsr { element } => {
51 element.validate_layout_at("DataType::SparseCsr.element")
52 }
53 Self::SparseCoo { element } => {
54 element.validate_layout_at("DataType::SparseCoo.element")
55 }
56 Self::SparseBsr {
57 element,
58 block_rows,
59 block_cols,
60 } => {
61 if *block_rows == 0 {
62 return Err(format!(
63 "Fix: {path}::SparseBsr block_rows must be > 0 for a frozen layout contract."
64 ));
65 }
66 if *block_cols == 0 {
67 return Err(format!(
68 "Fix: {path}::SparseBsr block_cols must be > 0 for a frozen layout contract."
69 ));
70 }
71 element.validate_layout_at("DataType::SparseBsr.element")
72 }
73 Self::DeviceMesh { axes } => {
74 if axes.is_empty() {
75 return Err(format!(
76 "Fix: {path}::DeviceMesh axes must not be empty for a frozen layout contract."
77 ));
78 }
79 for (axis, &extent) in axes.iter().enumerate() {
80 if extent == 0 {
81 return Err(format!(
82 "Fix: {path}::DeviceMesh axes[{axis}] must be > 0 for a frozen layout contract."
83 ));
84 }
85 }
86 Ok(())
87 }
88 Self::Quantized {
89 storage,
90 scale,
91 zero_point,
92 } => {
93 if !storage.is_quantized_storage() {
94 return Err(format!(
95 "Fix: {path}::Quantized storage {storage} is not a supported packed quantized storage type."
96 ));
97 }
98 validate_quantization_scale(scale, path)?;
99 validate_quantization_zero_point(zero_point, path)
100 }
101 _ => Ok(()),
102 }
103 }
104}
105
106fn validate_quantization_scale(scale: &QuantizationScale, path: &str) -> Result<(), String> {
107 match scale {
108 QuantizationScale::PerGroup { group_size } if *group_size == 0 => Err(format!(
109 "Fix: {path}::Quantized scale PerGroup group_size must be > 0."
110 )),
111 _ => Ok(()),
112 }
113}
114
115fn validate_quantization_zero_point(
116 zero_point: &QuantizationZeroPoint,
117 path: &str,
118) -> Result<(), String> {
119 match zero_point {
120 QuantizationZeroPoint::PerGroup { group_size } if *group_size == 0 => Err(format!(
121 "Fix: {path}::Quantized zero_point PerGroup group_size must be > 0."
122 )),
123 _ => Ok(()),
124 }
125}