1use super::fit::{fit_qk_super_block, make_qkx2_quants, QkFit, QK_SUB_ELEMS};
37use crate::{Q4_K_BLOCK_BYTES, Q4_K_BLOCK_ELEMS};
38
39const Q4_K_FIT: QkFit = QkFit {
43 nmax: 15,
44 rmin: -1.0,
45 rdelta: 0.1,
46 nstep: 20,
47 imatrix_clamps_scale_codes: false,
48};
49
50#[doc(hidden)]
59pub fn probe_sub_block(xs: &[f32]) -> (f32, f32) {
60 assert_eq!(xs.len(), QK_SUB_ELEMS);
61 let mut l = [0u8; QK_SUB_ELEMS];
62 let mut laux = [0u8; QK_SUB_ELEMS];
63 let mut weights = [0f32; QK_SUB_ELEMS];
64 super::fit::qk_sub_block_weights(xs, &mut weights);
65 make_qkx2_quants(
66 xs,
67 &weights,
68 &mut l,
69 &mut laux,
70 Q4_K_FIT.nmax,
71 Q4_K_FIT.rmin,
72 Q4_K_FIT.rdelta,
73 Q4_K_FIT.nstep,
74 false,
75 )
76}
77
78pub fn encode_block_q4_k(
84 block: &[f32; Q4_K_BLOCK_ELEMS],
85 qw: Option<&[f32; Q4_K_BLOCK_ELEMS]>,
86 out: &mut Vec<u8>,
87) {
88 let fitted = fit_qk_super_block(block, Q4_K_FIT, qw);
89
90 out.reserve(Q4_K_BLOCK_BYTES);
91 out.extend_from_slice(&fitted.d.to_le_bytes());
92 out.extend_from_slice(&fitted.dmin.to_le_bytes());
93 out.extend_from_slice(&fitted.packed);
94 for j in (0..Q4_K_BLOCK_ELEMS).step_by(64) {
98 for i in 0..32 {
99 out.push(fitted.l[j + i] | (fitted.l[j + i + 32] << 4));
100 }
101 }
102}
103
104pub fn encode_row_q4_k(src: &[f32], qw: Option<&[f32]>, out: &mut Vec<u8>) -> Option<()> {
121 let (blocks, rest) = src.as_chunks::<Q4_K_BLOCK_ELEMS>();
122 if !rest.is_empty() {
123 return None;
124 }
125 let qw_blocks = super::imatrix_blocks::<Q4_K_BLOCK_ELEMS>(qw, blocks.len())?;
126 out.reserve(blocks.len() * Q4_K_BLOCK_BYTES);
127 for (i, block) in blocks.iter().enumerate() {
128 encode_block_q4_k(block, qw_blocks.map(|q| &q[i]), out);
129 }
130 Some(())
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136 use crate::encode::fit::QK_SUBS;
137 use crate::encode::testdata::k_quant_fixture;
138 use crate::{dequant_q4_k, q4_k_scale_min, Q4_K_SCALE_BYTES};
139 use half::f16;
140
141 const LLAMA_CPP_Q4_K_GOLDEN: [u8; 12 * Q4_K_BLOCK_BYTES] = [
153 0x32, 0x10, 0x14, 0x1c, 0x05, 0x0c, 0x59, 0xff, 0x04, 0x0b, 0x58, 0xff, 0x55, 0xcc, 0x8a,
154 0xb3, 0xed, 0xc8, 0xba, 0x4e, 0xeb, 0x91, 0x85, 0xa6, 0x9c, 0x87, 0xd8, 0xab, 0x42, 0xe9,
155 0x87, 0x0b, 0xb3, 0x82, 0x59, 0xb2, 0xc0, 0x80, 0x87, 0xa7, 0x98, 0x62, 0x75, 0x94, 0x31,
156 0x0a, 0x89, 0xda, 0xc5, 0x32, 0xd4, 0xfa, 0xf6, 0xd6, 0xc1, 0xbd, 0xf1, 0xc8, 0x6c, 0xbf,
157 0xc4, 0xa0, 0xeb, 0x46, 0x7d, 0xb0, 0xf4, 0xb7, 0x95, 0xbc, 0xd1, 0xe6, 0x84, 0x8d, 0x77,
158 0x1d, 0x01, 0xd7, 0x1f, 0xda, 0x1b, 0xf6, 0x4f, 0x62, 0x3f, 0xce, 0x28, 0x47, 0x5b, 0xba,
159 0xeb, 0xfc, 0x04, 0xb3, 0xba, 0x44, 0x94, 0xe0, 0xd6, 0xbf, 0x7e, 0x02, 0xf0, 0xac, 0x4c,
160 0xda, 0xbf, 0x21, 0x4d, 0xc7, 0xd1, 0xb0, 0x6b, 0xf0, 0xb2, 0x0a, 0x8d, 0x25, 0xbc, 0x2c,
161 0xda, 0xd7, 0xa9, 0x51, 0x32, 0xa2, 0xc0, 0x5e, 0x1c, 0x86, 0x95, 0x53, 0x40, 0x7d, 0xf1,
162 0xf5, 0x34, 0xf8, 0x9c, 0xf0, 0x9f, 0xa8, 0x4c, 0x48, 0x2d, 0x10, 0xeb, 0x1b, 0x00, 0x10,
163 0x48, 0xc6, 0x00, 0x00, 0x40, 0xcf, 0x45, 0xcc, 0xaa, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
164 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
165 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xe6, 0xba, 0x13,
166 0x8b, 0x45, 0x3b, 0x24, 0x4e, 0x69, 0xbb, 0x96, 0xd7, 0xc9, 0xe9, 0x13, 0xad, 0x75, 0xeb,
167 0xeb, 0x8a, 0x0e, 0x9e, 0x76, 0xfb, 0x0d, 0x17, 0xfe, 0x5a, 0x07, 0x7e, 0x6d, 0x95, 0xa5,
168 0x30, 0x33, 0xe7, 0xf1, 0x3d, 0x29, 0xfa, 0x07, 0x84, 0x99, 0xea, 0xca, 0x06, 0xe3, 0x27,
169 0xa5, 0x40, 0x07, 0x12, 0xf3, 0x55, 0x72, 0xe5, 0xa1, 0x12, 0x35, 0xee, 0x06, 0xf2, 0x51,
170 0x0d, 0x11, 0x70, 0x92, 0xc1, 0xd3, 0x7c, 0x99, 0x33, 0x74, 0x49, 0x6e, 0x6d, 0x2a, 0xdc,
171 0xa2, 0x57, 0x35, 0xbe, 0xd3, 0x65, 0xbb, 0xf1, 0x14, 0x05, 0x09, 0xd4, 0x87, 0x3e, 0xbf,
172 0x4c, 0xc8, 0xd1, 0x30, 0x10, 0xdc, 0x1b, 0x05, 0x00, 0x58, 0xff, 0x05, 0x00, 0x58, 0xff,
173 0x55, 0xdd, 0x89, 0xce, 0x44, 0xa8, 0xc2, 0x9c, 0xec, 0x84, 0x2c, 0x8f, 0x6f, 0x30, 0x74,
174 0xae, 0x66, 0x2b, 0x16, 0x5b, 0xe6, 0xe0, 0x96, 0x69, 0x66, 0x8f, 0xe4, 0x5c, 0x57, 0x24,
175 0x06, 0x52, 0x67, 0xa1, 0xa0, 0x43, 0xaa, 0x5d, 0x43, 0x4d, 0x7c, 0xbf, 0x78, 0x16, 0x59,
176 0xf9, 0x30, 0x58, 0x03, 0x12, 0x73, 0xed, 0x8d, 0x00, 0xdd, 0x49, 0xe2, 0xf9, 0xa1, 0x88,
177 0x2c, 0x80, 0x90, 0x0f, 0xb3, 0x2b, 0xf5, 0xc9, 0x72, 0x61, 0x6a, 0x85, 0x99, 0xc3, 0x02,
178 0xd4, 0xd8, 0x2a, 0xee, 0x20, 0xa9, 0xcd, 0x9a, 0xa8, 0xed, 0x6b, 0x95, 0x98, 0x8c, 0x96,
179 0x6f, 0x1f, 0xda, 0x13, 0xf9, 0xc7, 0x75, 0xdd, 0x55, 0x17, 0x71, 0xd4, 0xbd, 0xc5, 0x79,
180 0xa0, 0x2d, 0xcb, 0x7b, 0x40, 0x76, 0x1b, 0xf4, 0x04, 0x56, 0xd2, 0x1b, 0x24, 0x44, 0x25,
181 0x68, 0x01, 0x33, 0xa1, 0x92, 0xf5, 0x1f, 0x69, 0xed, 0xd1, 0xa8, 0x28, 0x3c, 0x10, 0x2d,
182 0x1c, 0x05, 0x0c, 0x58, 0xff, 0x05, 0x0c, 0x53, 0xff, 0x55, 0xcc, 0x88, 0x9f, 0xba, 0xf2,
183 0xc5, 0x51, 0xfe, 0x43, 0xec, 0x47, 0x96, 0x64, 0x14, 0x78, 0xf3, 0x6b, 0x46, 0x52, 0x79,
184 0x15, 0x26, 0x05, 0x50, 0x9f, 0xdd, 0xec, 0x0b, 0x0d, 0x5a, 0x8f, 0xe1, 0x15, 0x76, 0x87,
185 0x1c, 0x6a, 0xf7, 0xe1, 0xe2, 0x46, 0xc4, 0xcc, 0x90, 0x95, 0x40, 0x67, 0xdb, 0x70, 0x53,
186 0xd4, 0x70, 0xb4, 0xcd, 0x80, 0x52, 0xb4, 0x0b, 0xc1, 0xd5, 0xda, 0x17, 0x15, 0x1e, 0x99,
187 0x57, 0x22, 0x9c, 0x58, 0xc3, 0xc4, 0x5e, 0xd2, 0x78, 0x37, 0x69, 0xe2, 0x21, 0xf7, 0x83,
188 0x5c, 0xa1, 0x6a, 0xbd, 0xbe, 0x72, 0xa4, 0x3d, 0x61, 0x76, 0xcb, 0x55, 0x2a, 0x01, 0x8d,
189 0x14, 0xcb, 0xdc, 0x4f, 0x6f, 0x15, 0x46, 0x6e, 0xe8, 0x5d, 0x6d, 0xf0, 0xea, 0x0d, 0xaa,
190 0x8f, 0xdd, 0xd7, 0x3e, 0x52, 0x20, 0x24, 0x1b, 0x15, 0x62, 0x98, 0x0a, 0xf4, 0x42, 0x9b,
191 0xdc, 0x8a, 0xb7, 0xab, 0xae, 0x57, 0xb2, 0x04, 0x0f, 0x11, 0xe9, 0xe8, 0xf8, 0xf4, 0xac,
192 0xa9, 0xb1, 0xd7, 0xc6, 0xc5, 0x5c, 0xff, 0x7c, 0xa8, 0xf7, 0x8b, 0x09, 0x68, 0x8b, 0xa0,
193 0x69, 0x6f, 0x9d, 0xb0, 0xbb, 0xe7, 0xc9, 0x87, 0x6e, 0xfe, 0x58, 0xca, 0x56, 0xad, 0xb9,
194 0xb4, 0xd4, 0x7b, 0x96, 0x0b, 0x19, 0x71, 0xea, 0xd2, 0x87, 0x37, 0x18, 0x9e, 0x47, 0x09,
195 0x0b, 0x37, 0x05, 0x22, 0x43, 0x2a, 0x6a, 0x7a, 0x07, 0x3d, 0x53, 0x0f, 0x28, 0x37, 0x57,
196 0x3b, 0x7b, 0x68, 0x7c, 0x55, 0x99, 0x0a, 0x6c, 0x26, 0x20, 0xf7, 0x81, 0x7c, 0x53, 0x43,
197 0xf5, 0xd4, 0x77, 0x37, 0x66, 0x89, 0xc7, 0x17, 0xbf, 0xad, 0x73, 0x48, 0xc2, 0x86, 0x39,
198 0x7e, 0x86, 0x63, 0x5d, 0x5c, 0xb0, 0x73, 0x04, 0x77, 0x98, 0x72, 0xd3, 0xcd, 0x97, 0x44,
199 0x35, 0xb6, 0xb5, 0x06, 0x75, 0xcc, 0xb2, 0x81, 0xa5, 0xe7, 0x67, 0x76, 0xf1, 0xbc, 0x4a,
200 0xa6, 0x77, 0x9b, 0x78, 0x95, 0xb5, 0x96, 0x53, 0x95, 0x9e, 0xd2, 0x61, 0x86, 0xa9, 0x90,
201 0xfe, 0x09, 0x83, 0x16, 0xb6, 0xb2, 0xa9, 0xff, 0xad, 0xa8, 0xaa, 0xbf, 0x3b, 0x7a, 0xcf,
202 0x04, 0xc8, 0xba, 0x14, 0x42, 0x87, 0x7a, 0xb5, 0x8a, 0x65, 0x84, 0x84, 0x04, 0x56, 0x96,
203 0xab, 0x24, 0xb2, 0x61, 0xc8, 0x85, 0x53, 0x84, 0x65, 0x80, 0x6e, 0x57, 0x73, 0x7a, 0x35,
204 0x5a, 0x0b, 0xf7, 0xbc, 0x88, 0xa8, 0xca, 0x82, 0x85, 0x30, 0xba, 0xaa, 0x98, 0x97, 0x88,
205 0x78, 0xfc, 0x7a, 0x96, 0xd8, 0x07, 0x9d, 0x98, 0x6c, 0x88, 0x78, 0x7a, 0xa2, 0x4b, 0x8b,
206 0xa8, 0xcf, 0xdd, 0x85, 0xb4, 0xc7, 0x93, 0xa8, 0x6e, 0x47, 0x26, 0x74, 0x96, 0x53, 0xba,
207 0x53, 0xba, 0x67, 0x79, 0xc5, 0x06, 0xf6, 0x9a, 0xe0, 0x4e, 0x74, 0x03, 0x74, 0x83, 0x82,
208 0xa8, 0x9a, 0x8a, 0xb6, 0xad, 0xbb, 0x74, 0x7f, 0x37, 0xc0, 0x49, 0x9b, 0x16, 0x68, 0x84,
209 0x89, 0x39, 0x98, 0x49, 0x7c, 0x25, 0x5a, 0x23, 0x99, 0x37, 0x45, 0x05, 0x03, 0x27, 0x35,
210 0x49, 0x32, 0xed, 0x65, 0x1b, 0x34, 0xcd, 0xa6, 0x89, 0x58, 0x09, 0x9c, 0x14, 0xb0, 0xe2,
211 0xbf, 0xee, 0xe8, 0xe5, 0xbf, 0xfa, 0xaf, 0x12, 0xff, 0xf2, 0x76, 0x65, 0x95, 0x54, 0x70,
212 0x99, 0xa5, 0x14, 0x00, 0xfc, 0x93, 0xa3, 0x24, 0xc7, 0x78, 0x27, 0x58, 0x73, 0x54, 0x53,
213 0x5c, 0xf6, 0x3a, 0xa4, 0x56, 0xaa, 0x64, 0x36, 0x83, 0x6d, 0x72, 0x7f, 0xe6, 0x57, 0x57,
214 0x67, 0xc2, 0x98, 0x54, 0x06, 0x86, 0x58, 0xbf, 0x7a, 0x99, 0xf4, 0xb7, 0xa8, 0xf6, 0x7b,
215 0xc9, 0xb8, 0x58, 0x97, 0x96, 0xc5, 0x30, 0xb8, 0xa6, 0x77, 0x89, 0x99, 0xd4, 0xa7, 0x46,
216 0x79, 0x8a, 0x89, 0x9c, 0x78, 0x09, 0x83, 0x99, 0x2c, 0x74, 0x75, 0x78, 0xb9, 0x89, 0x40,
217 0x88, 0xfa, 0x84, 0x6e, 0x7c, 0x93, 0xab, 0x26, 0x87, 0x4e, 0xa8, 0x5c, 0x6a, 0x97, 0xaa,
218 0x57, 0x92, 0x84, 0x96, 0xd0, 0x93, 0x6c, 0x07, 0x86, 0x87, 0xa5, 0x8b, 0xc9, 0xd9, 0xa9,
219 0xa4, 0x98, 0x81, 0xc6, 0x94, 0xeb, 0xd4, 0x9a, 0x74, 0xaa, 0x4a, 0x85, 0x5f, 0x33, 0x7c,
220 0x86, 0x5a, 0xd6, 0xb7, 0x08, 0x9e, 0x15, 0xf5, 0xfa, 0xf6, 0xff, 0xa1, 0x9c, 0xa1, 0xbf,
221 0xc8, 0x69, 0x65, 0xcf, 0x13, 0x08, 0x63, 0x85, 0x10, 0x75, 0x37, 0x21, 0x5b, 0xb1, 0x27,
222 0x07, 0xe7, 0x18, 0x17, 0x12, 0x13, 0x8b, 0x51, 0x64, 0x2f, 0x35, 0x67, 0x73, 0x37, 0x62,
223 0x25, 0x96, 0xbe, 0x4b, 0x93, 0x44, 0xb5, 0x81, 0x98, 0x95, 0x96, 0xa5, 0x43, 0xba, 0x6a,
224 0x06, 0x9d, 0xb9, 0x9a, 0xc8, 0xc4, 0xf3, 0x82, 0xa4, 0xdc, 0xc0, 0xb6, 0xd7, 0xb4, 0xa5,
225 0x90, 0xaf, 0xbb, 0x7a, 0xad, 0x75, 0xc2, 0x97, 0x69, 0x23, 0x72, 0xaa, 0x73, 0x25, 0x9e,
226 0x4c, 0xa8, 0xe8, 0x74, 0x65, 0x6d, 0xf2, 0x84, 0xa9, 0xa0, 0x4c, 0xc8, 0x87, 0xb5, 0x4a,
227 0xa4, 0x5c, 0x8d, 0x85, 0xc3, 0xd2, 0x33, 0xa3, 0x87, 0x0b, 0x0b, 0x75, 0x4f, 0x97, 0x77,
228 0x84, 0xa8, 0xb9, 0xc8, 0x8a, 0x97, 0x66, 0x65, 0x9b, 0x68, 0xf4, 0x6c, 0x86, 0x49, 0x80,
229 0x66, 0x35, 0x75, 0x75, 0xb2, 0x74, 0x26, 0x88, 0x5b, 0xa3, 0x65, 0xa9, 0x80, 0x09, 0x7e,
230 0x16, 0xfb, 0xf5, 0xf9, 0xb5, 0xa6, 0xb2, 0xf4, 0x6c, 0x60, 0x2f, 0xfb, 0xed, 0x56, 0x2a,
231 0xf7, 0x93, 0xc5, 0xb5, 0x85, 0xc5, 0xb5, 0x83, 0xa4, 0x79, 0xb2, 0x74, 0x96, 0x98, 0x79,
232 0x96, 0x38, 0xb2, 0xc8, 0xb7, 0x66, 0x85, 0x46, 0x8f, 0x44, 0x95, 0x6d, 0xb8, 0xa7, 0x00,
233 0x7b, 0x40, 0x7b, 0x58, 0x8f, 0xa9, 0xc6, 0x9b, 0x6d, 0x6e, 0x55, 0x8c, 0x49, 0xd9, 0xe8,
234 0x61, 0x29, 0x8b, 0x88, 0x76, 0x95, 0x1a, 0xb9, 0x45, 0x6f, 0x0f, 0x89, 0xf6, 0x86, 0x5d,
235 0x7a, 0xaa, 0x8d, 0x48, 0xa1, 0xa7, 0x29, 0x47, 0x97, 0x74, 0x57, 0x69, 0x3b, 0x98, 0x51,
236 0x78, 0x79, 0x40, 0x68, 0x42, 0x5d, 0x09, 0x8c, 0x5f, 0x78, 0x94, 0xf6, 0x89, 0x98, 0x62,
237 0x46, 0x5a, 0x68, 0x34, 0x98, 0x0b, 0x4a, 0x4b, 0x9c, 0x28, 0x7e, 0x00, 0x66, 0xad, 0xca,
238 0x69, 0x4d, 0x7c, 0x8a, 0xc6, 0x7e, 0x8e, 0x27, 0x3d, 0x2b, 0x6f, 0x0a, 0x7c, 0x79, 0xa6,
239 0xaa, 0xf7, 0x6e, 0x06, 0xbb, 0x49, 0xaf, 0x08, 0x4f, 0x14, 0xfe, 0xb6, 0xef, 0xfb, 0xff,
240 0xee, 0xed, 0xed, 0xef, 0x9e, 0xb9, 0xee, 0xb8, 0x17, 0x4b, 0xbf, 0x84, 0x35, 0x98, 0x98,
241 0x59, 0x18, 0xe0, 0x64, 0x45, 0xc6, 0x04, 0x58, 0xa6, 0xac, 0x44, 0x67, 0x9a, 0x59, 0x98,
242 0xc5, 0x12, 0x44, 0xf8, 0x20, 0x63, 0x66, 0x18, 0x59, 0xe2, 0x23, 0x32, 0xb9, 0x49, 0x28,
243 0x6d, 0x86, 0x4a, 0xdb, 0xbb, 0xa7, 0x75, 0x32, 0x05, 0x7a, 0x18, 0x3c, 0x4f, 0x16, 0x05,
244 0xd0, 0x85, 0x84, 0x58, 0x21, 0x96, 0xa7, 0x62, 0x8b, 0xa9, 0x73, 0x1a, 0xf8, 0xd7, 0x83,
245 0x57, 0x57, 0x53, 0x6f, 0x80, 0x56, 0xcb, 0xaa, 0x96, 0x73, 0x79, 0xf6, 0xa5, 0xb8, 0x47,
246 0x78, 0x14, 0xad, 0xa7, 0xb3, 0x08, 0xd5, 0xb3, 0xd6, 0xf4, 0x48, 0xf3, 0x7a, 0x49, 0xa5,
247 0x94, 0x35, 0xeb, 0x98, 0x5d, 0x0f, 0x82, 0x66, 0x88, 0x77, 0x46, 0xac, 0x2c, 0x67, 0xc7,
248 0x72, 0x98, 0xf7, 0x78, 0x50, 0x75, 0x7d, 0x32, 0x92, 0xa5, 0xcd, 0x9a, 0x59, 0x60, 0xf9,
249 0xd9, 0x0a, 0x01, 0x18, 0xb0, 0xf4, 0xfd, 0xf5, 0x6b, 0x68, 0xb3, 0xdf, 0x9d, 0x7c, 0x7f,
250 0xf9, 0x94, 0xd8, 0xa7, 0xf0, 0x7e, 0x9f, 0x9a, 0x99, 0x7e, 0x35, 0x85, 0x6c, 0x69, 0x5a,
251 0x74, 0x0d, 0x98, 0x76, 0x64, 0x99, 0x38, 0x8c, 0x5d, 0x74, 0x6a, 0xb4, 0x8e, 0x77, 0x8c,
252 0x63, 0x7a, 0x8d, 0x07, 0xb7, 0x77, 0x88, 0x4c, 0x6a, 0xf8, 0x35, 0x9b, 0x53, 0x83, 0x23,
253 0x28, 0xc4, 0x48, 0x5a, 0x84, 0x45, 0x4c, 0x17, 0xc2, 0x38, 0xa7, 0xc5, 0x90, 0x4f, 0x7c,
254 0x47, 0x86, 0x89, 0x79, 0x58, 0x3a, 0x41, 0x92, 0x7b, 0x41, 0x30, 0x25, 0x69, 0x89, 0x22,
255 0x37, 0x05, 0x25, 0x64, 0xf5, 0x38, 0x42, 0x32, 0x22, 0x54, 0x5a, 0x0f, 0x52, 0x52, 0x94,
256 0xa4, 0x21, 0x20, 0x79, 0x2c, 0x17, 0x46, 0xa2, 0x96, 0xa5, 0xc5, 0xb6, 0x97, 0xa6, 0xc5,
257 0xb5, 0xa0, 0x87, 0x93, 0xb3, 0xb2, 0xb9, 0x87, 0xd6, 0xa4, 0x0b, 0xb7, 0x6a, 0xc6, 0x3b,
258 0xf7, 0xc2, 0xc2, 0x85, 0xc5, 0xb7, 0xa6, 0x7b, 0xef, 0x45, 0x0b, 0xc5, 0x16, 0xf5, 0xf0,
259 0xaf, 0xef, 0xef, 0xfd, 0xa4, 0xf2, 0x87, 0x43, 0x8b, 0xff, 0xc7, 0x1b, 0x83, 0xc9, 0x19,
260 0x36, 0x72, 0x75, 0xcf, 0x90, 0xcc, 0x88, 0xf7, 0x54, 0x52, 0x2a, 0x0e, 0x85, 0x8a, 0x17,
261 0xaa, 0xe1, 0xa6, 0xd6, 0xe4, 0xe4, 0x73, 0xd3, 0xf7, 0xfd, 0xa6, 0x7d, 0xb7, 0x34, 0x87,
262 0x68, 0xd7, 0x52, 0xc2, 0xb3, 0xb3, 0x39, 0xa4, 0xc5, 0xcc, 0x80, 0x21, 0xd5, 0x5c, 0x64,
263 0x83, 0x99, 0x66, 0x76, 0x85, 0x6a, 0xea, 0x8e, 0xb3, 0xb2, 0x9f, 0x29, 0x52, 0x07, 0x47,
264 0x46, 0x69, 0x77, 0x89, 0x8a, 0x48, 0xa4, 0x8c, 0x82, 0xa7, 0x6a, 0x78, 0x66, 0xaf, 0x99,
265 0x61, 0x77, 0xb4, 0xb8, 0x26, 0x65, 0xba, 0x7a, 0xed, 0x59, 0x09, 0xab, 0x80, 0xf6, 0x16,
266 0x2b, 0xa6, 0x62, 0x9b, 0x53, 0x17, 0x5c, 0xb4, 0x8a, 0xd7, 0x87, 0xd0, 0x4d, 0x69, 0xac,
267 0x8b, 0x39, 0x0d, 0x97, 0x54, 0x84, 0x8b, 0xb9, 0xa7, 0xff, 0x75, 0x60, 0x8a, 0x7d, 0xb7,
268 0xa8, 0x98, 0x57,
269 ];
270
271 #[test]
279 fn q4_k_matches_llama_cpp_quantize_row_q4_k_ref() {
280 let x = k_quant_fixture();
281 let mut got = Vec::new();
282 encode_row_q4_k(&x, None, &mut got).unwrap();
283 assert_eq!(got.len(), LLAMA_CPP_Q4_K_GOLDEN.len());
284 for (b, (g, w)) in got
285 .as_chunks::<Q4_K_BLOCK_BYTES>()
286 .0
287 .iter()
288 .zip(LLAMA_CPP_Q4_K_GOLDEN.as_chunks::<Q4_K_BLOCK_BYTES>().0)
289 .enumerate()
290 {
291 assert_eq!(g, w, "super-block {b} disagrees with llama.cpp");
292 }
293 }
294
295 #[test]
300 fn a_row_that_is_not_a_whole_number_of_super_blocks_is_refused() {
301 let mut out = Vec::new();
302 assert!(encode_row_q4_k(&[0.5; Q4_K_BLOCK_ELEMS + 1], None, &mut out).is_none());
303 assert!(encode_row_q4_k(&[0.5; 32], None, &mut out).is_none());
306 assert!(encode_row_q4_k(&[], None, &mut out).is_some());
307 assert!(encode_row_q4_k(&[0.5; Q4_K_BLOCK_ELEMS], Some(&[1.0; 32]), &mut out).is_none());
311 }
312
313 #[test]
331 fn every_element_lands_on_its_nearest_representable_level() {
332 let x = k_quant_fixture();
333 let mut bytes = Vec::new();
334 encode_row_q4_k(&x, None, &mut bytes).unwrap();
335 let back = dequant_q4_k(&bytes).unwrap();
336 assert_eq!(back.len(), x.len());
337
338 for (b, block) in bytes.as_chunks::<Q4_K_BLOCK_BYTES>().0.iter().enumerate() {
339 let d = f16::from_le_bytes([block[0], block[1]]).to_f32();
340 let dmin = f16::from_le_bytes([block[2], block[3]]).to_f32();
341 let packed: [u8; Q4_K_SCALE_BYTES] = block[4..16].try_into().unwrap();
342 for j in 0..QK_SUBS {
343 let (sc, m) = q4_k_scale_min(j, &packed);
344 let (dj, dm) = (d * sc as f32, dmin * m as f32);
345 for ii in 0..QK_SUB_ELEMS {
346 let idx = b * Q4_K_BLOCK_ELEMS + QK_SUB_ELEMS * j + ii;
347 let chosen = (x[idx] - back[idx]).abs();
348 for k in 0..=15u8 {
349 let level = dj * k as f32 - dm;
350 assert!(
351 (x[idx] - level).abs() >= chosen,
352 "block {b} sub-block {j} element {ii}: {} is closer to {} than to the \
353 chosen {}",
354 x[idx],
355 level,
356 back[idx]
357 );
358 }
359 }
360 }
361 }
362 }
363}