1use super::fit::{fit_qk_super_block, QkFit};
31use crate::{Q5_K_BLOCK_BYTES, Q5_K_BLOCK_ELEMS};
32
33const Q5_K_FIT: QkFit = QkFit {
39 nmax: 31,
40 rmin: -0.5,
41 rdelta: 0.1,
42 nstep: 15,
43 imatrix_clamps_scale_codes: true,
44};
45
46const QH_BYTES: usize = Q5_K_BLOCK_ELEMS / 8;
48
49pub fn encode_block_q5_k(
55 block: &[f32; Q5_K_BLOCK_ELEMS],
56 qw: Option<&[f32; Q5_K_BLOCK_ELEMS]>,
57 out: &mut Vec<u8>,
58) {
59 let fitted = fit_qk_super_block(block, Q5_K_FIT, qw);
60
61 let mut qh = [0u8; QH_BYTES];
62 let mut ql = [0u8; Q5_K_BLOCK_ELEMS / 2];
63 let (mut m1, mut m2) = (1u8, 2u8);
64 for (g, n) in (0..Q5_K_BLOCK_ELEMS).step_by(64).enumerate() {
65 for j in 0..32 {
66 let mut l1 = fitted.l[n + j];
74 if l1 > 15 {
75 l1 -= 16;
76 qh[j] |= m1;
77 }
78 let mut l2 = fitted.l[n + j + 32];
79 if l2 > 15 {
80 l2 -= 16;
81 qh[j] |= m2;
82 }
83 ql[g * 32 + j] = l1 | (l2 << 4);
84 }
85 m1 <<= 2;
86 m2 <<= 2;
87 }
88
89 out.reserve(Q5_K_BLOCK_BYTES);
90 out.extend_from_slice(&fitted.d.to_le_bytes());
91 out.extend_from_slice(&fitted.dmin.to_le_bytes());
92 out.extend_from_slice(&fitted.packed);
93 out.extend_from_slice(&qh);
94 out.extend_from_slice(&ql);
95}
96
97pub fn encode_row_q5_k(src: &[f32], qw: Option<&[f32]>, out: &mut Vec<u8>) -> Option<()> {
111 let (blocks, rest) = src.as_chunks::<Q5_K_BLOCK_ELEMS>();
112 if !rest.is_empty() {
113 return None;
114 }
115 let qw_blocks = super::imatrix_blocks::<Q5_K_BLOCK_ELEMS>(qw, blocks.len())?;
116 out.reserve(blocks.len() * Q5_K_BLOCK_BYTES);
117 for (i, block) in blocks.iter().enumerate() {
118 encode_block_q5_k(block, qw_blocks.map(|q| &q[i]), out);
119 }
120 Some(())
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126 use crate::encode::testdata::k_quant_fixture;
127 use crate::{dequant_q5_k, q4_k_scale_min, Q4_K_SCALE_BYTES};
128 use half::f16;
129
130 const LLAMA_CPP_Q5_K_GOLDEN: [u8; 12 * Q5_K_BLOCK_BYTES] = [
145 0x1f, 0x0c, 0x06, 0x1c, 0x04, 0x0c, 0x59, 0xff, 0x04, 0x0c, 0x58, 0xff, 0x55, 0xcc, 0x89,
146 0xc3, 0x5b, 0xa3, 0x9b, 0x4d, 0xdb, 0x3a, 0xda, 0x4e, 0xdb, 0xbb, 0xf7, 0x3f, 0x08, 0xab,
147 0xbf, 0x41, 0x66, 0xaa, 0xa9, 0x3a, 0x1a, 0x4e, 0xab, 0xbb, 0x1b, 0xfc, 0xf0, 0x86, 0xd0,
148 0xe9, 0x67, 0x6f, 0xef, 0x94, 0x7a, 0x9f, 0xeb, 0x31, 0x2b, 0x4f, 0x4f, 0x11, 0xb5, 0x5b,
149 0xa4, 0xe6, 0x22, 0x0c, 0x77, 0x25, 0xb8, 0x86, 0x91, 0x10, 0x12, 0x51, 0x43, 0xe4, 0xfc,
150 0x4b, 0x72, 0x1a, 0x25, 0xc8, 0x7a, 0x65, 0xb9, 0xe4, 0xfd, 0xac, 0x72, 0x6b, 0xe2, 0x9f,
151 0xc7, 0x6e, 0x87, 0x41, 0xc6, 0x8c, 0xeb, 0x70, 0xf8, 0x6d, 0x3a, 0x67, 0xa2, 0xcd, 0x07,
152 0x1b, 0xfe, 0x1a, 0x02, 0xaf, 0x2f, 0xa4, 0x26, 0xfc, 0x8e, 0xc4, 0x6e, 0x7c, 0x50, 0x7e,
153 0xa6, 0x74, 0xc7, 0xe9, 0x07, 0x75, 0x64, 0x79, 0x39, 0xb0, 0xac, 0x7e, 0xec, 0x04, 0xf0,
154 0x47, 0x98, 0xb3, 0x5f, 0x41, 0x7a, 0x9f, 0xa2, 0x70, 0xc7, 0xf0, 0x65, 0x04, 0x0b, 0x5a,
155 0x79, 0x49, 0xb5, 0xaf, 0x42, 0xa2, 0x74, 0x43, 0x80, 0x9e, 0x29, 0x1d, 0x2a, 0xa7, 0x90,
156 0xdb, 0xe2, 0xe9, 0x58, 0xf1, 0x39, 0xf0, 0x3f, 0x51, 0x89, 0x82, 0x08, 0x0c, 0xcf, 0x1b,
157 0x00, 0x10, 0x48, 0xc6, 0x00, 0x00, 0x40, 0xcf, 0x45, 0xcc, 0xaa, 0xff, 0x2a, 0x0e, 0x82,
158 0xae, 0xa2, 0x56, 0xd2, 0x36, 0x06, 0x6e, 0x7a, 0x7a, 0x7e, 0xce, 0xa2, 0x0e, 0x22, 0xce,
159 0x8e, 0x0e, 0xe6, 0x8e, 0x02, 0x2e, 0x66, 0x82, 0x8e, 0x76, 0xc2, 0x66, 0xc6, 0x9a, 0xf0,
160 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
161 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
162 0xf0, 0xdb, 0x54, 0x17, 0x07, 0x8a, 0x67, 0x39, 0x7d, 0xc2, 0x76, 0x3d, 0xaf, 0x83, 0xc3,
163 0x16, 0x4b, 0xea, 0xd6, 0xc6, 0x05, 0x0c, 0x2e, 0xec, 0xf6, 0x0c, 0x2f, 0xfe, 0xa4, 0x0e,
164 0xde, 0xcb, 0x2a, 0x4a, 0x60, 0x67, 0xce, 0xf1, 0x6b, 0x33, 0xf4, 0x0f, 0x08, 0x12, 0xd4,
165 0x85, 0x0d, 0xc7, 0x5f, 0x5a, 0x70, 0x0e, 0x34, 0xf7, 0xa9, 0xe3, 0xcb, 0x41, 0x34, 0x7a,
166 0xcd, 0x0c, 0xf5, 0xa2, 0x0a, 0x21, 0xe0, 0x24, 0x91, 0xa5, 0xf8, 0x23, 0x66, 0xf7, 0x72,
167 0xce, 0xcb, 0x45, 0xa9, 0x54, 0xbe, 0x7a, 0x7d, 0xc5, 0xca, 0x67, 0xf3, 0x17, 0x0a, 0x03,
168 0xa8, 0x0f, 0x6d, 0x6f, 0x89, 0x90, 0xb2, 0x21, 0x0c, 0xe7, 0x1b, 0x05, 0x00, 0x58, 0xff,
169 0x05, 0x00, 0x59, 0xff, 0x55, 0xdd, 0x88, 0xcc, 0x0c, 0x87, 0xd2, 0xa7, 0x77, 0xae, 0x45,
170 0xe3, 0x75, 0x1c, 0x32, 0x47, 0xb0, 0x31, 0x30, 0xbd, 0x7e, 0x12, 0x2e, 0x35, 0x78, 0x2f,
171 0x1a, 0x9d, 0xb4, 0x88, 0x78, 0x64, 0xc8, 0xb6, 0xca, 0x4c, 0x87, 0x60, 0xa5, 0x38, 0xe8,
172 0x27, 0x58, 0x2f, 0xde, 0x70, 0x07, 0x6c, 0xcb, 0x47, 0x1d, 0xa5, 0xec, 0xf0, 0x4c, 0xd3,
173 0xcd, 0x2e, 0xf8, 0xa8, 0xaf, 0x48, 0x0c, 0xa5, 0xce, 0x53, 0x51, 0x97, 0x55, 0xaa, 0x96,
174 0x8b, 0xea, 0x7f, 0xe0, 0x1d, 0xb3, 0xe4, 0x51, 0xa1, 0x07, 0x35, 0xe7, 0xcb, 0x1b, 0x00,
175 0xbb, 0x84, 0xd5, 0xe3, 0x43, 0x00, 0x59, 0x02, 0x31, 0x0f, 0x66, 0x47, 0xeb, 0x94, 0xf3,
176 0xd2, 0xd5, 0x1b, 0x23, 0x87, 0x04, 0xb9, 0xa0, 0x44, 0xdc, 0x40, 0x41, 0x9b, 0x24, 0x41,
177 0xda, 0xd6, 0x3a, 0x10, 0x19, 0x3d, 0xbe, 0x1e, 0xb5, 0x35, 0xe2, 0x9f, 0xfb, 0xba, 0xab,
178 0x2e, 0xe2, 0xc9, 0x7c, 0x8a, 0xf4, 0x50, 0x5b, 0xa8, 0xf8, 0x90, 0xfe, 0x28, 0xf9, 0x09,
179 0xad, 0xb4, 0x37, 0x58, 0x88, 0x4b, 0xd1, 0x03, 0x77, 0x42, 0x23, 0xfa, 0x2f, 0xd4, 0xdc,
180 0xc2, 0x51, 0x40, 0x16, 0x0c, 0x06, 0x1c, 0x05, 0x0c, 0x57, 0xff, 0x05, 0x0c, 0x55, 0xff,
181 0x55, 0xdc, 0x97, 0xef, 0x77, 0x16, 0x2e, 0x68, 0xdb, 0x60, 0x5b, 0x8c, 0xda, 0x68, 0xc0,
182 0xe5, 0xee, 0xd1, 0x60, 0x18, 0x31, 0x38, 0x4c, 0x28, 0x10, 0xcb, 0x67, 0xbb, 0x09, 0xdd,
183 0xc5, 0xf3, 0x86, 0xfc, 0xf4, 0x12, 0x65, 0xf4, 0x9b, 0x92, 0xfd, 0x86, 0xc8, 0x8f, 0x3d,
184 0xc7, 0x27, 0xe1, 0xf5, 0xc6, 0x9c, 0xb4, 0xf1, 0x2a, 0x4b, 0x0b, 0xb0, 0x1e, 0xab, 0xc8,
185 0x06, 0x0a, 0xa5, 0x0f, 0xd1, 0x1a, 0xdb, 0x0e, 0x1c, 0xc6, 0xf1, 0xc2, 0xd5, 0x8e, 0x89,
186 0x9b, 0x21, 0x2b, 0x80, 0xb1, 0xb9, 0xe1, 0x97, 0xaa, 0xe1, 0x7a, 0x8c, 0x00, 0xa5, 0x6a,
187 0x08, 0x83, 0xbc, 0xa7, 0x20, 0x2b, 0x1f, 0x33, 0xa0, 0x36, 0x39, 0xa0, 0x96, 0xa9, 0xcd,
188 0xc5, 0xf0, 0x7e, 0xe3, 0xd4, 0x52, 0xfe, 0x16, 0xc8, 0x61, 0xd5, 0x7a, 0x7d, 0xe4, 0x59,
189 0x7a, 0xd2, 0x0c, 0xa6, 0xcb, 0x63, 0x11, 0x2b, 0x37, 0x96, 0xc9, 0x9e, 0xef, 0x3a, 0x9c,
190 0xed, 0xe1, 0xbc, 0xdd, 0xf0, 0xe6, 0x1b, 0x65, 0x0f, 0xcb, 0xc0, 0x7e, 0xa5, 0x51, 0x58,
191 0x28, 0x3b, 0xe4, 0x42, 0x05, 0xf8, 0x94, 0x39, 0xbb, 0x15, 0x8f, 0x57, 0x6e, 0xcf, 0x53,
192 0x02, 0x2f, 0x11, 0xe8, 0xe8, 0xf5, 0xf2, 0xab, 0xa8, 0xb0, 0xd6, 0xa5, 0xd3, 0x48, 0xff,
193 0xa9, 0x13, 0x06, 0x8f, 0xa1, 0x25, 0x07, 0xc6, 0x81, 0xb1, 0xa3, 0x86, 0x77, 0x36, 0xa3,
194 0xd6, 0x61, 0xa7, 0x15, 0xd3, 0x60, 0x87, 0x97, 0x96, 0x26, 0x81, 0xce, 0x85, 0x35, 0x80,
195 0xe3, 0xba, 0xe9, 0x40, 0xef, 0x07, 0x13, 0xd1, 0x17, 0x30, 0xd4, 0xcf, 0x2a, 0x60, 0x68,
196 0xbe, 0x83, 0x1f, 0xbe, 0xfe, 0xa1, 0x86, 0xbd, 0x4b, 0x52, 0x68, 0xa7, 0xd7, 0x2d, 0x07,
197 0x23, 0xe2, 0xc5, 0xb4, 0x0f, 0x7f, 0x10, 0x3d, 0x7f, 0x14, 0x07, 0x60, 0x0b, 0x54, 0x77,
198 0x46, 0xc6, 0xe6, 0x0f, 0x6c, 0xb6, 0x0f, 0x32, 0x7e, 0xaf, 0x78, 0xf8, 0xc0, 0xfa, 0xbb,
199 0x43, 0x15, 0xd9, 0x3c, 0x30, 0xff, 0x12, 0xe8, 0xb7, 0x95, 0xfb, 0xc7, 0xfe, 0x7e, 0xdb,
200 0x22, 0xae, 0x3d, 0x8f, 0x6b, 0x05, 0x90, 0xa3, 0x2d, 0x72, 0xfd, 0x1d, 0xd5, 0xca, 0xc9,
201 0x80, 0xf6, 0x09, 0xee, 0x40, 0xe4, 0xc6, 0xaa, 0x2f, 0x98, 0x7b, 0x6d, 0x7b, 0x0d, 0xfa,
202 0x8b, 0x75, 0x03, 0x5b, 0xde, 0xd0, 0xfd, 0xf1, 0x7a, 0x96, 0x5c, 0xee, 0x29, 0xe2, 0x3b,
203 0x7b, 0x2d, 0xa6, 0x3c, 0x3e, 0xa4, 0xd3, 0x0c, 0x43, 0x20, 0xea, 0x05, 0xbc, 0x16, 0xb1,
204 0xb2, 0xa7, 0xff, 0xac, 0xaa, 0xa8, 0xbf, 0x28, 0x7b, 0xcf, 0x12, 0xff, 0x2f, 0xbc, 0x5c,
205 0xdb, 0x09, 0x42, 0xaf, 0xcc, 0x7e, 0xca, 0x7c, 0x4c, 0x1e, 0x67, 0x08, 0xee, 0x34, 0x2f,
206 0x1e, 0x04, 0x0e, 0x04, 0x66, 0x29, 0xf4, 0x3e, 0x7d, 0x2c, 0xfd, 0xb9, 0xcb, 0x93, 0x87,
207 0x39, 0x95, 0x21, 0xf7, 0x7c, 0x26, 0xdc, 0x28, 0x28, 0x0a, 0xbe, 0x3e, 0x69, 0x69, 0x74,
208 0xe2, 0x92, 0x2b, 0xb7, 0x19, 0xdb, 0x20, 0xef, 0xbf, 0x07, 0xf6, 0x8b, 0xc6, 0x19, 0xf0,
209 0x79, 0x11, 0x51, 0x95, 0x04, 0x1a, 0x70, 0x64, 0x56, 0x20, 0x3f, 0x20, 0x00, 0xf9, 0xf5,
210 0x4d, 0xb2, 0x00, 0x3c, 0x31, 0xd8, 0x10, 0xf0, 0xf5, 0x44, 0x97, 0x18, 0x51, 0x8f, 0xbb,
211 0x0b, 0x78, 0x70, 0x26, 0x51, 0xdf, 0x90, 0x4d, 0xf8, 0x2d, 0xa6, 0x75, 0xa7, 0x76, 0xcf,
212 0xf4, 0x8b, 0x1d, 0xfd, 0x35, 0xc0, 0x8e, 0xf9, 0x06, 0xe9, 0x17, 0x15, 0x41, 0x35, 0x06,
213 0x6d, 0x4d, 0x69, 0xe8, 0x0f, 0x6f, 0xa0, 0x82, 0x47, 0x3c, 0xe1, 0x29, 0x32, 0x74, 0x41,
214 0x93, 0xf9, 0x5b, 0xc6, 0x57, 0x34, 0x7e, 0x9b, 0x1b, 0x07, 0x6f, 0x7b, 0x93, 0x85, 0xfc,
215 0xda, 0x37, 0x7a, 0x9b, 0x5d, 0x13, 0x3d, 0x05, 0x8f, 0x14, 0xb0, 0xe2, 0xbf, 0xae, 0xea,
216 0xe3, 0xfe, 0xfb, 0xcd, 0x22, 0x0f, 0xfe, 0x88, 0x90, 0xb2, 0xb0, 0xb8, 0x5b, 0x12, 0xa0,
217 0xb8, 0x97, 0xce, 0xc6, 0xdc, 0xfa, 0xb9, 0xcc, 0xb9, 0xb4, 0xac, 0xdc, 0x91, 0xea, 0x39,
218 0xca, 0x60, 0x9b, 0x78, 0x10, 0xde, 0xbd, 0x78, 0x89, 0xdc, 0xbb, 0x2a, 0x98, 0xd0, 0x23,
219 0x3a, 0x19, 0x01, 0xf9, 0x16, 0x46, 0x49, 0x8f, 0xe0, 0x3e, 0xa0, 0xd6, 0x99, 0x96, 0xaa,
220 0xdc, 0x65, 0x38, 0xad, 0x34, 0xc9, 0x5c, 0x07, 0xcc, 0xc5, 0xdf, 0xcc, 0xbf, 0x9d, 0xdd,
221 0x84, 0x3f, 0xa7, 0x0c, 0x0b, 0xa0, 0x6e, 0xf5, 0x22, 0xf8, 0x7d, 0x51, 0xfc, 0xe6, 0x93,
222 0x60, 0xbf, 0x2f, 0x2c, 0xa9, 0x60, 0x6f, 0x5b, 0xdd, 0x03, 0x32, 0xc7, 0x5e, 0x8d, 0xe3,
223 0x16, 0x04, 0x39, 0xf2, 0x03, 0x06, 0x24, 0x5a, 0xe9, 0xeb, 0xe2, 0x64, 0x04, 0x80, 0x01,
224 0xf5, 0x09, 0xde, 0xe9, 0x37, 0x47, 0x4e, 0x1f, 0x9f, 0x41, 0xa9, 0xc5, 0x20, 0x55, 0xaf,
225 0x45, 0x29, 0x3d, 0xc0, 0x37, 0xd8, 0x0f, 0x2c, 0x1f, 0x6a, 0x27, 0x92, 0xd3, 0x53, 0x68,
226 0x50, 0x12, 0xbc, 0x48, 0xf7, 0xd9, 0x44, 0xf8, 0x65, 0x95, 0x29, 0xbf, 0x66, 0x09, 0x2d,
227 0xa4, 0xcc, 0x98, 0x04, 0xa2, 0x15, 0xf7, 0xf7, 0xf7, 0xff, 0xa2, 0x9d, 0xa3, 0xbf, 0xc5,
228 0x89, 0x76, 0xce, 0x58, 0x09, 0x4c, 0xba, 0x08, 0x8a, 0xf0, 0xdc, 0xf5, 0xf2, 0x8c, 0x0c,
229 0x1e, 0xed, 0x68, 0xb8, 0x68, 0x9b, 0x7c, 0xa8, 0x29, 0x1c, 0x28, 0x1a, 0xb8, 0x2c, 0x2c,
230 0xe6, 0x4f, 0xa1, 0x3a, 0xd8, 0x37, 0x10, 0xc6, 0x2a, 0x30, 0x0b, 0x7e, 0x42, 0xb6, 0x82,
231 0x6e, 0x0e, 0xfe, 0x30, 0x2d, 0x24, 0x27, 0x16, 0xb2, 0xd9, 0x5f, 0x8b, 0xde, 0x07, 0x7e,
232 0xe3, 0x5a, 0x4d, 0x8c, 0xa5, 0x47, 0x98, 0x6c, 0x13, 0x31, 0x2a, 0x3d, 0x5b, 0x87, 0x65,
233 0xc4, 0x0c, 0x3b, 0x73, 0x35, 0x91, 0x99, 0xf6, 0x05, 0x49, 0xa9, 0x80, 0x7d, 0xa0, 0x89,
234 0x5c, 0x21, 0x4f, 0x77, 0xf6, 0x4b, 0xfa, 0x96, 0x3f, 0xd3, 0x56, 0xf5, 0x66, 0xf6, 0x5b,
235 0x3f, 0x9a, 0x52, 0xe2, 0xe9, 0xeb, 0xdc, 0xf4, 0x29, 0x54, 0x60, 0x8a, 0xa2, 0x2f, 0x7c,
236 0x96, 0x59, 0xcb, 0x2c, 0x2b, 0xa7, 0xc4, 0x78, 0x56, 0x10, 0x07, 0x06, 0xfb, 0x8f, 0x3e,
237 0xfe, 0x08, 0x40, 0x82, 0x91, 0x04, 0x2e, 0xdc, 0xdb, 0x37, 0xc1, 0xf8, 0xc9, 0x1d, 0x82,
238 0x00, 0xcd, 0x7b, 0xfb, 0xea, 0x75, 0xf8, 0x4c, 0x01, 0xb6, 0x47, 0xea, 0x53, 0x57, 0x05,
239 0x6d, 0x16, 0xba, 0xf5, 0xfa, 0xb8, 0xa4, 0xb2, 0xf5, 0x6e, 0x5f, 0x3f, 0xfb, 0xfd, 0xf4,
240 0x51, 0x66, 0x66, 0xde, 0x0e, 0x68, 0x0e, 0x06, 0xd6, 0xd2, 0x7d, 0x46, 0x5c, 0xde, 0x83,
241 0x55, 0xc6, 0x19, 0x52, 0x7a, 0x56, 0x5c, 0x62, 0x64, 0xb7, 0xfc, 0x8a, 0x49, 0x17, 0xd6,
242 0x4c, 0xab, 0x44, 0xff, 0x36, 0x8a, 0x69, 0xf9, 0x89, 0x6a, 0x06, 0x48, 0xf2, 0x73, 0xe8,
243 0x3c, 0x31, 0xe2, 0x2b, 0x61, 0x73, 0x9f, 0x7e, 0xbc, 0x0a, 0x9b, 0x0f, 0x88, 0x3b, 0xbb,
244 0x60, 0x5d, 0x00, 0xf7, 0x80, 0xf6, 0x90, 0x1f, 0x52, 0x8d, 0x27, 0xda, 0xcc, 0xaa, 0x09,
245 0x82, 0xb2, 0xc0, 0xd3, 0x53, 0xf6, 0x0f, 0xed, 0x3b, 0x34, 0x62, 0x9a, 0xcf, 0x0f, 0x02,
246 0xed, 0x0c, 0xba, 0xf5, 0x44, 0x1a, 0x90, 0x51, 0x5f, 0x53, 0x8f, 0x3f, 0xf8, 0xbe, 0xd2,
247 0x76, 0x30, 0xa2, 0xf0, 0xf2, 0x80, 0xc1, 0x83, 0xba, 0x03, 0x09, 0xbf, 0xe1, 0x37, 0xfc,
248 0x13, 0x30, 0xd4, 0x9c, 0xa4, 0xd0, 0x68, 0x30, 0x07, 0x94, 0x96, 0x29, 0x4f, 0xec, 0x00,
249 0xdd, 0x6a, 0x94, 0xd3, 0x8a, 0xf9, 0x13, 0x9d, 0xfe, 0x1d, 0x5e, 0x6a, 0x56, 0xdf, 0x05,
250 0xe9, 0xf2, 0x5c, 0x54, 0xfe, 0xcd, 0x1c, 0x67, 0x93, 0x9e, 0x04, 0x72, 0x14, 0xff, 0xb4,
251 0xef, 0xf7, 0xff, 0xec, 0xed, 0xec, 0xce, 0x8e, 0xca, 0xcd, 0x5b, 0xb0, 0xa1, 0x2f, 0xc6,
252 0xc4, 0x47, 0x5b, 0xa5, 0x0d, 0xfe, 0x38, 0x28, 0xc2, 0x50, 0x25, 0xa6, 0x37, 0xc4, 0x90,
253 0x43, 0x39, 0x2b, 0x6a, 0x14, 0xa0, 0xab, 0xe8, 0xe0, 0x5c, 0x2d, 0xd1, 0x70, 0x2f, 0x96,
254 0x7f, 0x18, 0x7b, 0x31, 0x20, 0xb3, 0x20, 0xd0, 0xd9, 0x9b, 0xac, 0x09, 0xb0, 0x5c, 0x48,
255 0x88, 0xcf, 0x34, 0xa3, 0x30, 0xab, 0x15, 0x88, 0xf0, 0x41, 0xd6, 0xdc, 0x11, 0xa2, 0xf4,
256 0x46, 0x74, 0x82, 0x92, 0x41, 0xdb, 0x1c, 0x94, 0xc7, 0x88, 0x6f, 0x0b, 0x74, 0x1a, 0xf5,
257 0x20, 0x79, 0x9f, 0x2d, 0x0a, 0xc0, 0x1a, 0x29, 0xb1, 0x52, 0x3c, 0x6f, 0xd5, 0x26, 0x72,
258 0xf7, 0x34, 0xf1, 0xbe, 0x07, 0xad, 0xae, 0xb6, 0xcf, 0x00, 0xbd, 0x86, 0x44, 0x2d, 0xf6,
259 0xe3, 0xfc, 0x4a, 0x60, 0x8f, 0xe0, 0x29, 0x4b, 0x4f, 0x66, 0x00, 0xba, 0x66, 0xac, 0xf9,
260 0x71, 0xe6, 0xe5, 0x92, 0x4b, 0x29, 0x5b, 0xc6, 0x30, 0xab, 0x0e, 0x05, 0xdd, 0x10, 0xee,
261 0x9c, 0x49, 0x49, 0xcf, 0x9f, 0xe5, 0x21, 0xff, 0xe0, 0xb0, 0xfb, 0xfa, 0x75, 0x24, 0x5a,
262 0x9b, 0x44, 0xa2, 0xb1, 0xf3, 0xad, 0x06, 0x0e, 0x18, 0xb0, 0xf3, 0xfe, 0xf6, 0x6b, 0x69,
263 0xb2, 0xdf, 0x8c, 0xbd, 0x6f, 0xfa, 0x92, 0x8b, 0xa2, 0xbe, 0x87, 0x87, 0x8b, 0x93, 0xbd,
264 0x80, 0x8a, 0x81, 0x81, 0x89, 0xe4, 0x95, 0x8b, 0x80, 0x44, 0x83, 0x59, 0x97, 0x49, 0x8a,
265 0xa9, 0xa6, 0x87, 0x82, 0xbb, 0x9c, 0x45, 0xc7, 0x39, 0xc1, 0x5f, 0xf0, 0x0d, 0x4f, 0x44,
266 0x33, 0xfd, 0x7b, 0x0b, 0xe9, 0xe3, 0xb4, 0xf8, 0x0b, 0x31, 0xfc, 0xc9, 0x32, 0x70, 0x28,
267 0xba, 0x09, 0xd5, 0x88, 0x2c, 0x0e, 0x18, 0xe6, 0xf5, 0x1a, 0x0d, 0x7d, 0xef, 0x00, 0x88,
268 0xc4, 0xff, 0x6a, 0x26, 0xa6, 0x16, 0x56, 0x4f, 0x89, 0x90, 0x94, 0x18, 0x89, 0x79, 0x2e,
269 0x84, 0x70, 0x4f, 0x8a, 0x30, 0x9f, 0xf8, 0x9f, 0x1c, 0x02, 0xe2, 0xb1, 0x76, 0x92, 0x33,
270 0x07, 0xa1, 0x80, 0x6a, 0xd3, 0x12, 0x54, 0x8e, 0x2b, 0x69, 0xd9, 0xfb, 0x71, 0xa4, 0x74,
271 0x64, 0xb9, 0xc5, 0x0f, 0xc4, 0xb3, 0x39, 0x68, 0x52, 0x50, 0x02, 0x69, 0x4e, 0xac, 0x44,
272 0x3c, 0x4b, 0x8b, 0x7b, 0x2e, 0x4d, 0x9a, 0x5a, 0x40, 0x1e, 0x36, 0x76, 0x64, 0x62, 0x0e,
273 0xac, 0x57, 0x07, 0x6e, 0xc4, 0x9c, 0x77, 0xfe, 0x85, 0x95, 0x0a, 0x99, 0x6e, 0x4c, 0xe6,
274 0xdf, 0x18, 0x07, 0xc6, 0x16, 0xf5, 0xf1, 0xb0, 0xed, 0xf0, 0xff, 0xa7, 0xf3, 0x98, 0x53,
275 0x9c, 0xff, 0x8a, 0x01, 0xda, 0x07, 0x39, 0x70, 0x98, 0xe8, 0xbb, 0xa6, 0xab, 0x5b, 0x7e,
276 0xc8, 0xf0, 0x79, 0x45, 0x82, 0x2b, 0xbd, 0xc3, 0xca, 0xba, 0xd6, 0x3e, 0x1e, 0xd8, 0x7a,
277 0xae, 0xe7, 0xc2, 0x15, 0x8e, 0x27, 0x05, 0x83, 0x32, 0x7d, 0xf4, 0xfa, 0x9f, 0x30, 0xa9,
278 0x02, 0xff, 0xc9, 0xa4, 0x54, 0x0c, 0x1b, 0x25, 0x30, 0x55, 0xc3, 0x5d, 0xbc, 0xc8, 0xd8,
279 0xf7, 0xb6, 0xff, 0xfa, 0x4d, 0xfa, 0x9f, 0x79, 0x1e, 0xd0, 0xce, 0xb5, 0xa5, 0x77, 0x87,
280 0x73, 0x68, 0xab, 0x98, 0x20, 0x43, 0xca, 0xa9, 0xd9, 0x17, 0x43, 0xde, 0x0d, 0x1b, 0xd5,
281 0xf5, 0x1e, 0x88, 0x96, 0x3f, 0x54, 0xc4, 0x00, 0x8f, 0x9c, 0xc2, 0xff, 0x02, 0x15, 0x90,
282 0x58, 0x19, 0x05, 0x4e, 0xd4, 0x01, 0xcc, 0x5f, 0x33, 0xc3, 0xee, 0x78, 0x71, 0x5c, 0xcb,
283 0x73, 0xe5, 0xea, 0xa3, 0x02, 0x47, 0x00, 0xfc, 0x2d, 0x56, 0x4d, 0xc4, 0x36, 0xa6, 0x2f,
284 0x98, 0x68, 0x15, 0xbe, 0x0e, 0xa1, 0x8a, 0xd2, 0x48, 0x17, 0x63, 0x0a, 0x2e, 0xb8, 0x09,
285 0x17, 0x63, 0x5f, 0xff, 0xfb, 0xd0, 0x04, 0xea, 0x7e, 0x41, 0x30, 0xbf,
286 ];
287
288 #[test]
292 fn q5_k_matches_llama_cpp_quantize_row_q5_k_ref() {
293 let x = k_quant_fixture();
294 let mut got = Vec::new();
295 encode_row_q5_k(&x, None, &mut got).unwrap();
296 assert_eq!(got.len(), LLAMA_CPP_Q5_K_GOLDEN.len());
297 for (b, (g, w)) in got
298 .as_chunks::<Q5_K_BLOCK_BYTES>()
299 .0
300 .iter()
301 .zip(LLAMA_CPP_Q5_K_GOLDEN.as_chunks::<Q5_K_BLOCK_BYTES>().0)
302 .enumerate()
303 {
304 assert_eq!(g, w, "super-block {b} disagrees with llama.cpp");
305 }
306 }
307
308 #[test]
313 fn a_row_that_is_not_a_whole_number_of_super_blocks_is_refused() {
314 let mut out = Vec::new();
315 assert!(encode_row_q5_k(&[0.5; Q5_K_BLOCK_ELEMS + 1], None, &mut out).is_none());
316 assert!(encode_row_q5_k(&[0.5; 32], None, &mut out).is_none());
319 assert!(encode_row_q5_k(&[], None, &mut out).is_some());
320 }
321
322 #[test]
337 fn every_element_lands_on_its_nearest_representable_level() {
338 let x = k_quant_fixture();
339 let mut bytes = Vec::new();
340 encode_row_q5_k(&x, None, &mut bytes).unwrap();
341 let back = dequant_q5_k(&bytes).unwrap();
342 assert_eq!(back.len(), x.len());
343
344 for (b, block) in bytes.as_chunks::<Q5_K_BLOCK_BYTES>().0.iter().enumerate() {
345 let d = f16::from_le_bytes([block[0], block[1]]).to_f32();
346 let dmin = f16::from_le_bytes([block[2], block[3]]).to_f32();
347 let packed: [u8; Q4_K_SCALE_BYTES] = block[4..16].try_into().unwrap();
348 for j in 0..8 {
349 let (sc, m) = q4_k_scale_min(j, &packed);
350 let (dj, dm) = (d * sc as f32, dmin * m as f32);
351 for ii in 0..32 {
352 let idx = b * Q5_K_BLOCK_ELEMS + 32 * j + ii;
353 let chosen = (x[idx] - back[idx]).abs();
354 for k in 0..=31u8 {
355 let level = dj * k as f32 - dm;
356 assert!(
357 (x[idx] - level).abs() >= chosen,
358 "block {b} sub-block {j} element {ii}: {} is closer to {} than to the \
359 chosen {}",
360 x[idx],
361 level,
362 back[idx]
363 );
364 }
365 }
366 }
367 }
368 }
369
370 #[test]
375 fn the_high_bit_plane_is_not_all_zero() {
376 let x = k_quant_fixture();
377 let mut bytes = Vec::new();
378 encode_row_q5_k(&x, None, &mut bytes).unwrap();
379 for (b, block) in bytes.as_chunks::<Q5_K_BLOCK_BYTES>().0.iter().enumerate() {
380 let qh = &block[16..16 + QH_BYTES];
381 if b == 2 {
384 continue;
385 }
386 assert!(
387 qh.iter().any(|&v| v != 0),
388 "super-block {b} has an empty qh"
389 );
390 }
391 }
392}