{"record":{"id":"eb9a2b6153cbb8e4","repo":"tracel-ai/burn","slug":"not-yet-supported-eb9a2b","errorCode":null,"errorMessage":"Not yet supported","messagePattern":"Not yet supported","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-std/src/tensor/quantization.rs","lineNumber":341,"sourceCode":"        }\n\n        let (values, qparams) = match self.scheme.store {\n            QuantStore::Native => self.split_i8_values(scale_bytes),\n            QuantStore::PackedU32(_) => match self.scheme.value {\n                QuantValue::Q8F | QuantValue::Q8S => self.split_i8_values(scale_bytes),\n                QuantValue::Q4F | QuantValue::Q4S | QuantValue::Q2F | QuantValue::Q2S => {\n                    let split_at =\n                        self.bytes.len().checked_sub(scale_bytes).expect(\n                            \"quantized tensor data is shorter than its scheme's parameters\",\n                        );\n                    let qparams = self.bytes[split_at..].to_vec();\n                    let values = bytemuck::cast_slice::<_, u32>(&self.bytes[..split_at]);\n                    // Sub-byte values are unpacked as i8s for value equality tests\n                    let values = unpack_q_to_i8s(values, self.num_elements(), &self.scheme.value);\n                    (values, qparams)\n                }\n                QuantValue::E4M3 | QuantValue::E5M2 | QuantValue::E2M1 => {\n                    unimplemented!(\"Not yet supported\")\n                }\n            },\n            QuantStore::PackedNative(_) => unimplemented!(\"Not yet supported\"),\n        };\n\n        (values, (qparams, num_params))\n    }\n}\n\n/// Round a scale up to the smallest value representable by the scale dtype that is no smaller.\n///\n/// Backends that keep scales in `f32` must apply this when quantizing, so that the scale they\n/// divide by is the one that will actually be stored. Otherwise a tensor dequantizes differently\n/// after a save/load round trip.\n///\n/// Up rather than to nearest, because a scale is derived from the largest magnitude it has to\n/// cover. Rounding down puts that value past the end of the quantized range, where it clips, which\n/// measured several times worse than the coarser step rounding up costs.","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-std/src/tensor/quantization.rs#L323-L359","documentation":"QuantizedBytes::split_values_off (crates/burn-std/src/tensor/quantization.rs:313-348) splits quantized values from quantization parameters. For PackedU32 storage it handles Q8/Q4/Q2 values (unpacking sub-byte data to i8), but for float-point values E4M3/E5M2/E2M1 in PackedU32 storage, and for any PackedNative storage, it panics with `unimplemented!(\"Not yet supported\")` — packed float-point-quantized data cannot yet be split/unpacked.","triggerScenarios":"Calling into_vec_i8() (which calls split_values_off) on a QuantizedBytes with scheme.store == QuantStore::PackedU32 and scheme.value of E4M3/E5M2/E2M1, or with store == QuantStore::PackedNative (any value).","commonSituations":"Comparing or converting packed FP8/FP4 quantized tensor data (e.g. deserialized from a checkpoint saved with packing enabled) where the code path needs values as i8/floats.","solutions":["Avoid packed storage for E4M3/E5M2/E2M1 schemes: use QuantStore::Native (byte-aligned float-point values) so split_i8_values runs instead.","Dequantize via a supported path (native-store dequantize) instead of into_vec_i8 for packed float-point data.","If packing is not needed, construct the scheme with no packed dimension (packed_dim 0 / native store).","Track upstream burn for packed float-point quantization support and upgrade."],"exampleFix":"// before\nlet scheme = QuantScheme::default().with_value(QuantValue::E4M3); // may pack E4M3 -> PackedU32\nlet (vals, params) = q_bytes.into_vec_i8(); // panics\n// after\nlet f_data = quantized.dequantize(); // supported float-point path\nlet vals = f_data.iter::<f32>().collect::<Vec<_>>();","handlingStrategy":"type-guard","validationCode":"fn can_split_values(scheme: &QuantScheme) -> bool {\n    match scheme.store {\n        QuantStore::Native => true,\n        QuantStore::PackedU32(_) => !matches!(\n            scheme.value,\n            QuantValue::E4M3 | QuantValue::E5M2 | QuantValue::E2M1\n        ),\n        QuantStore::PackedNative(_) => false,\n    }\n}","typeGuard":"fn split_supported(store: &QuantStore) -> bool {\n    !matches!(store, QuantStore::PackedNative(_))\n}","tryCatchPattern":"// into_vec_i8 panics on unsupported stores; check first\nif can_split_values(&scheme) {\n    let (vals, params) = q_bytes.into_vec_i8();\n} else {\n    let floats = dequantize_native(&q_bytes); // alternate supported path\n}","preventionTips":["Store E4M3/E5M2/E2M1 quantized data with QuantStore::Native, not packed.","Never call into_vec_i8 on PackedNative data — it is unconditionally unimplemented.","Validate scheme.store and scheme.value in deserialization/pipeline code before conversion."],"tags":["rust","burn","quantization","packed-u32","unimplemented"],"backgroundTag":"unimplemented-feature-panic","analyzedSha":"d16f7ba2ed0d41408189384044cc886fb4c8f957","analyzedAt":"2026-09-05T13:19:14.260Z","contentChangedAt":"2026-09-05T13:19:14.260Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}