Construct from an explicit header, packed-bit slice, and sparse outlier list. `outliers` is a slice of `(dim_index, value)` pairs. The `outlier_bitmask` in `header` must have exactly one bit set for each entry in `outliers`, and bits must correspond to entries in ascending `dim_index` order (i.e. popcnt-dense order). # Errors Returns [`CodecError::LayoutError`] if: - `outliers.len()` does not
(
header: QuantHeader,
packed_bits: &[u8],
outliers: &[(u32, f32)],
)
| 156 | /// - `outliers.len()` does not match `popcnt(header.outlier_bitmask)`. |
| 157 | /// - Any `dim_index` in `outliers` is ≥ 64 (bitmask only covers 64 dims). |
| 158 | pub fn new( |
| 159 | header: QuantHeader, |
| 160 | packed_bits: &[u8], |
| 161 | outliers: &[(u32, f32)], |
| 162 | ) -> Result<Self, CodecError> { |
| 163 | let expected_outlier_count = header.outlier_bitmask.count_ones() as usize; |
| 164 | if outliers.len() != expected_outlier_count { |
| 165 | return Err(CodecError::LayoutError { |
| 166 | detail: format!( |
| 167 | "outlier count mismatch: bitmask has {} bits set but {} outliers provided", |
| 168 | expected_outlier_count, |
| 169 | outliers.len() |
| 170 | ), |
| 171 | }); |
| 172 | } |
| 173 | for &(dim_idx, _) in outliers { |
| 174 | if dim_idx >= 64 { |
| 175 | return Err(CodecError::LayoutError { |
| 176 | detail: format!("outlier dim_index {dim_idx} exceeds bitmask capacity of 64"), |
| 177 | }); |
| 178 | } |
| 179 | } |
| 180 | |
| 181 | let header_bytes = core::mem::size_of::<QuantHeader>(); |
| 182 | let outlier_bytes = outliers.len() * OUTLIER_ENTRY_BYTES; |
| 183 | let raw = header_bytes + packed_bits.len() + outlier_bytes; |
| 184 | let total = round_up_128(raw); |
| 185 | |
| 186 | let mut buf = vec![0u8; total]; |
| 187 | |
| 188 | // Write header via raw copy (QuantHeader is repr(C), no padding issues). |
| 189 | let header_src = unsafe { |
| 190 | core::slice::from_raw_parts(&header as *const QuantHeader as *const u8, header_bytes) |
| 191 | }; |
| 192 | buf[..header_bytes].copy_from_slice(header_src); |
| 193 | |
| 194 | // Write packed bits. |
| 195 | let pb_start = header_bytes; |
| 196 | let pb_end = pb_start + packed_bits.len(); |
| 197 | buf[pb_start..pb_end].copy_from_slice(packed_bits); |
| 198 | |
| 199 | // Write outlier payload: each entry is u32 dim_index || f32 value (LE). |
| 200 | let mut off = pb_end; |
| 201 | for &(dim_idx, value) in outliers { |
| 202 | buf[off..off + 4].copy_from_slice(&dim_idx.to_le_bytes()); |
| 203 | buf[off + 4..off + 8].copy_from_slice(&value.to_le_bytes()); |
| 204 | off += OUTLIER_ENTRY_BYTES; |
| 205 | } |
| 206 | |
| 207 | Ok(Self { |
| 208 | buf, |
| 209 | packed_bits_len: packed_bits.len(), |
| 210 | }) |
| 211 | } |
| 212 | |
| 213 | // ── Accessors ──────────────────────────────────────────────────────────── |
| 214 |
nothing calls this directly
no test coverage detected