1use crate::model::quant::{GgmlType, KVALUES_IQ4NL};
14
15#[derive(Clone, Copy, Debug, PartialEq, Eq)]
17pub struct Decoder {
18 pub ty: GgmlType,
19 pub offset: u32,
20 pub code_bits: u32,
21}
22
23pub const DECODERS: [Decoder; 12] = [
25 Decoder { ty: GgmlType::Q4_0, offset: 8, code_bits: 4 },
26 Decoder { ty: GgmlType::Q4_1, offset: 0, code_bits: 4 },
27 Decoder { ty: GgmlType::Q5_0, offset: 16, code_bits: 5 },
28 Decoder { ty: GgmlType::Q5_1, offset: 0, code_bits: 5 },
29 Decoder { ty: GgmlType::Q8_0, offset: 128, code_bits: 8 },
30 Decoder { ty: GgmlType::Q2K, offset: 0, code_bits: 2 },
31 Decoder { ty: GgmlType::Q3K, offset: 4, code_bits: 3 },
32 Decoder { ty: GgmlType::Q4K, offset: 0, code_bits: 4 },
33 Decoder { ty: GgmlType::Q5K, offset: 0, code_bits: 5 },
34 Decoder { ty: GgmlType::Q6K, offset: 32, code_bits: 6 },
35 Decoder { ty: GgmlType::Iq4Nl, offset: 128, code_bits: 8 },
36 Decoder { ty: GgmlType::Iq4Xs, offset: 128, code_bits: 8 },
37];
38
39pub const UNIT: usize = 16;
41
42#[derive(Clone, Debug, PartialEq, Eq)]
44pub struct Units {
45 pub code: Vec<u32>,
46 pub c: Vec<i16>,
47 pub n: Vec<i16>,
48 pub a: u16,
49 pub b: u16,
50}
51
52pub fn units(ty: GgmlType, blk: &[u8]) -> Units {
54 assert_eq!(blk.len(), ty.block_bytes(), "one {} block", ty.name());
55 let half = |at: usize| u16::from_le_bytes([blk[at], blk[at + 1]]);
56 let word = |at: usize| u32::from_le_bytes([blk[at], blk[at + 1], blk[at + 2], blk[at + 3]]);
57 let n = ty.block_len();
58 let mut code = vec![0u32; n];
59 let mut c = vec![1i16; n / UNIT];
60 let mut nn = vec![0i16; n / UNIT];
61 let (a, b) = match ty {
62 GgmlType::Q4_0 | GgmlType::Q4_1 => {
63 let qs = if ty == GgmlType::Q4_0 { 2 } else { 4 };
64 for j in 0..16 {
65 code[j] = (blk[qs + j] & 15) as u32;
66 code[j + 16] = (blk[qs + j] >> 4) as u32;
67 }
68 if ty == GgmlType::Q4_1 {
69 nn = vec![1; 2];
70 (half(0), half(2))
71 } else {
72 (half(0), 0)
73 }
74 }
75 GgmlType::Q5_0 | GgmlType::Q5_1 => {
76 let one = ty == GgmlType::Q5_1;
77 let (qh, qs) = if one { (word(4), 8) } else { (word(2), 6) };
78 for j in 0..16 {
79 code[j] = (blk[qs + j] & 15) as u32 | ((qh >> j) & 1) << 4;
80 code[j + 16] = (blk[qs + j] >> 4) as u32 | ((qh >> (j + 16)) & 1) << 4;
81 }
82 if one {
83 nn = vec![1; 2];
84 (half(0), half(2))
85 } else {
86 (half(0), 0)
87 }
88 }
89 GgmlType::Q8_0 => {
90 for j in 0..32 {
91 code[j] = (blk[2 + j] ^ 0x80) as u32;
92 }
93 (half(0), 0)
94 }
95 GgmlType::Q2K => {
96 for h in 0..2 {
97 for sh in 0..4 {
98 for hf in 0..2 {
99 let u = 8 * h + 2 * sh + hf;
100 c[u] = (blk[u] & 15) as i16;
101 nn[u] = -((blk[u] >> 4) as i16);
102 for l in 0..16 {
103 code[128 * h + 32 * sh + 16 * hf + l] = ((blk[16 + 32 * h + 16 * hf + l] >> (2 * sh)) & 3) as u32;
104 }
105 }
106 }
107 }
108 (half(80), half(82))
109 }
110 GgmlType::Q3K => {
111 let (w0, w1, w2) = (word(96), word(100), word(104));
112 let (k1, k2) = (0x0303_0303u32, 0x0f0f_0f0fu32);
113 let scales: Vec<u8> = [
114 (w0 & k2) | ((w2 & k1) << 4),
115 (w1 & k2) | (((w2 >> 2) & k1) << 4),
116 ((w0 >> 4) & k2) | (((w2 >> 4) & k1) << 4),
117 ((w1 >> 4) & k2) | (((w2 >> 6) & k1) << 4),
118 ]
119 .iter()
120 .flat_map(|v| v.to_le_bytes())
121 .collect();
122 for h in 0..2 {
123 for sh in 0..4 {
124 for hf in 0..2 {
125 let u = 8 * h + 2 * sh + hf;
126 c[u] = scales[u] as i16 - 32;
127 for l in 0..16 {
128 let low = (blk[32 + 32 * h + 16 * hf + l] >> (2 * sh)) & 3;
129 let high = (blk[16 * hf + l] >> (4 * h + sh)) & 1;
130 code[128 * h + 32 * sh + 16 * hf + l] = (high << 2 | low) as u32;
131 }
132 }
133 }
134 }
135 (half(108), 0)
136 }
137 GgmlType::Q4K | GgmlType::Q5K => {
138 let five = ty == GgmlType::Q5K;
139 let q = &blk[4..16];
140 let scale_min = |j: usize| -> (u8, u8) {
141 if j < 4 {
142 (q[j] & 63, q[j + 4] & 63)
143 } else {
144 ((q[j + 4] & 15) | ((q[j - 4] >> 6) << 4), (q[j + 4] >> 4) | ((q[j] >> 6) << 4))
145 }
146 };
147 let qs = if five { 48 } else { 16 };
148 for p in 0..4 {
149 let (s1, m1) = scale_min(2 * p);
150 let (s2, m2) = scale_min(2 * p + 1);
151 for (u, (sc, mn)) in [(4 * p, (s1, m1)), (4 * p + 1, (s1, m1)), (4 * p + 2, (s2, m2)), (4 * p + 3, (s2, m2))] {
152 c[u] = sc as i16;
153 nn[u] = -(mn as i16);
154 }
155 for l in 0..32 {
156 let byte = blk[qs + 32 * p + l];
157 let (hi1, hi2) = if five { (((blk[16 + l] >> (2 * p)) & 1) as u32, ((blk[16 + l] >> (2 * p + 1)) & 1) as u32) } else { (0, 0) };
158 code[64 * p + l] = (byte & 15) as u32 | hi1 << 4;
159 code[64 * p + 32 + l] = (byte >> 4) as u32 | hi2 << 4;
160 }
161 }
162 (half(0), half(2))
163 }
164 GgmlType::Q6K => {
165 for part in 0..2 {
166 for u in 0..8 {
167 c[8 * part + u] = blk[192 + 8 * part + u] as i8 as i16;
168 }
169 for l in 0..32 {
170 let (ql0, ql1, qh) = (blk[64 * part + l], blk[64 * part + l + 32], blk[128 + 32 * part + l]);
171 code[128 * part + l] = (ql0 & 15) as u32 | ((qh & 3) as u32) << 4;
172 code[128 * part + l + 32] = (ql1 & 15) as u32 | (((qh >> 2) & 3) as u32) << 4;
173 code[128 * part + l + 64] = (ql0 >> 4) as u32 | (((qh >> 4) & 3) as u32) << 4;
174 code[128 * part + l + 96] = (ql1 >> 4) as u32 | (((qh >> 6) & 3) as u32) << 4;
175 }
176 }
177 (half(208), 0)
178 }
179 GgmlType::Iq4Nl | GgmlType::Iq4Xs => {
180 let level = |nibble: u8| (KVALUES_IQ4NL[nibble as usize] as i32 + 128) as u32;
182 if ty == GgmlType::Iq4Nl {
183 for j in 0..16 {
184 code[j] = level(blk[2 + j] & 15);
185 code[j + 16] = level(blk[2 + j] >> 4);
186 }
187 } else {
188 let scales_h = half(2);
189 for ib in 0..8 {
190 let ls = ((blk[4 + ib / 2] >> (4 * (ib % 2))) & 0xf) as i16 | ((((scales_h >> (2 * ib)) & 3) as i16) << 4);
191 c[2 * ib] = ls - 32;
192 c[2 * ib + 1] = ls - 32;
193 for j in 0..16 {
194 code[32 * ib + j] = level(blk[8 + 16 * ib + j] & 15);
195 code[32 * ib + 16 + j] = level(blk[8 + 16 * ib + j] >> 4);
196 }
197 }
198 }
199 (half(0), 0)
200 }
201 other => panic!("no decoder for {}", other.name()),
202 };
203 Units { code, c, n: nn, a, b }
204}
205
206pub fn decoder_name(ty: GgmlType) -> String {
208 format!("logos_dec_{}", ty.name().to_lowercase())
209}
210
211pub fn weights_verilog() -> &'static str {
213 WEIGHTS_VERILOG
214}
215
216const WEIGHTS_VERILOG: &str = r#"// The block decoders: GGUF bytes to codes, unit multipliers and the block's scales.
217
218// ggml's get_scale_min_k4: sub-block j's 6-bit scale and min from a K-quant's 12 packed bytes.
219module logos_scale_min_k4(input [95:0] q, input [2:0] j, output [5:0] sc, output [5:0] mn);
220 function [7:0] qb(input [95:0] v, input [3:0] i); qb = v[8*i +: 8]; endfunction
221 wire [7:0] here = qb(q, {1'b0, j}), ahead = qb(q, {1'b0, j} + 4'd4), behind = qb(q, {1'b0, j} - 4'd4);
222 assign sc = (j < 3'd4) ? here[5:0] : {behind[7:6], ahead[3:0]};
223 assign mn = (j < 3'd4) ? ahead[5:0] : {here[7:6], ahead[7:4]};
224endmodule
225
226module logos_dec_q4_0(input [143:0] blk, output [255:0] code, output [31:0] c, output [31:0] n, output [15:0] a, output [15:0] b);
227 assign a = blk[15:0];
228 assign b = 16'd0;
229 assign c = {16'sd1, 16'sd1};
230 assign n = 32'd0;
231 genvar j;
232 generate for (j = 0; j < 16; j = j + 1) begin : e
233 assign code[8*j +: 8] = {4'd0, blk[16 + 8*j +: 4]};
234 assign code[8*(j+16) +: 8] = {4'd0, blk[20 + 8*j +: 4]};
235 end endgenerate
236endmodule
237
238module logos_dec_q4_1(input [159:0] blk, output [255:0] code, output [31:0] c, output [31:0] n, output [15:0] a, output [15:0] b);
239 assign a = blk[15:0];
240 assign b = blk[31:16];
241 assign c = {16'sd1, 16'sd1};
242 assign n = {16'sd1, 16'sd1};
243 genvar j;
244 generate for (j = 0; j < 16; j = j + 1) begin : e
245 assign code[8*j +: 8] = {4'd0, blk[32 + 8*j +: 4]};
246 assign code[8*(j+16) +: 8] = {4'd0, blk[36 + 8*j +: 4]};
247 end endgenerate
248endmodule
249
250module logos_dec_q5_0(input [175:0] blk, output [255:0] code, output [31:0] c, output [31:0] n, output [15:0] a, output [15:0] b);
251 wire [31:0] qh = blk[47:16];
252 assign a = blk[15:0];
253 assign b = 16'd0;
254 assign c = {16'sd1, 16'sd1};
255 assign n = 32'd0;
256 genvar j;
257 generate for (j = 0; j < 16; j = j + 1) begin : e
258 assign code[8*j +: 8] = {3'd0, qh[j], blk[48 + 8*j +: 4]};
259 assign code[8*(j+16) +: 8] = {3'd0, qh[j+16], blk[52 + 8*j +: 4]};
260 end endgenerate
261endmodule
262
263module logos_dec_q5_1(input [191:0] blk, output [255:0] code, output [31:0] c, output [31:0] n, output [15:0] a, output [15:0] b);
264 wire [31:0] qh = blk[63:32];
265 assign a = blk[15:0];
266 assign b = blk[31:16];
267 assign c = {16'sd1, 16'sd1};
268 assign n = {16'sd1, 16'sd1};
269 genvar j;
270 generate for (j = 0; j < 16; j = j + 1) begin : e
271 assign code[8*j +: 8] = {3'd0, qh[j], blk[64 + 8*j +: 4]};
272 assign code[8*(j+16) +: 8] = {3'd0, qh[j+16], blk[68 + 8*j +: 4]};
273 end endgenerate
274endmodule
275
276module logos_dec_q8_0(input [271:0] blk, output [255:0] code, output [31:0] c, output [31:0] n, output [15:0] a, output [15:0] b);
277 assign a = blk[15:0];
278 assign b = 16'd0;
279 assign c = {16'sd1, 16'sd1};
280 assign n = 32'd0;
281 genvar j;
282 generate for (j = 0; j < 32; j = j + 1) begin : e
283 assign code[8*j +: 8] = blk[16 + 8*j +: 8] ^ 8'h80;
284 end endgenerate
285endmodule
286
287module logos_dec_q2_k(input [671:0] blk, output [2047:0] code, output [255:0] c, output [255:0] n, output [15:0] a, output [15:0] b);
288 assign a = blk[655:640];
289 assign b = blk[671:656];
290 genvar h, s, hf, l;
291 generate
292 for (h = 0; h < 2; h = h + 1) begin : nb
293 for (s = 0; s < 4; s = s + 1) begin : sh
294 for (hf = 0; hf < 2; hf = hf + 1) begin : half
295 localparam integer U = 8*h + 2*s + hf;
296 wire [7:0] sc = blk[8*U +: 8];
297 assign c[16*U +: 16] = {12'd0, sc[3:0]};
298 assign n[16*U +: 16] = -$signed({12'd0, sc[7:4]});
299 for (l = 0; l < 16; l = l + 1) begin : el
300 wire [7:0] q = blk[128 + 8*(32*h + 16*hf + l) +: 8];
301 assign code[8*(128*h + 32*s + 16*hf + l) +: 8] = {6'd0, q[2*s +: 2]};
302 end
303 end
304 end
305 end
306 endgenerate
307endmodule
308
309module logos_dec_q3_k(input [879:0] blk, output [2047:0] code, output [255:0] c, output [255:0] n, output [15:0] a, output [15:0] b);
310 assign a = blk[879:864];
311 assign b = 16'd0;
312 assign n = 256'd0;
313 // ggml's 6-bit scales from the 12 packed bytes at 96..107.
314 wire [31:0] w0 = blk[768 +: 32], w1 = blk[800 +: 32], w2 = blk[832 +: 32];
315 wire [31:0] k1 = 32'h0303_0303, k2 = 32'h0f0f_0f0f;
316 wire [31:0] s2 = ((w0 >> 4) & k2) | (((w2 >> 4) & k1) << 4);
317 wire [31:0] s3 = ((w1 >> 4) & k2) | (((w2 >> 6) & k1) << 4);
318 wire [31:0] s0 = (w0 & k2) | ((w2 & k1) << 4);
319 wire [31:0] s1 = (w1 & k2) | (((w2 >> 2) & k1) << 4);
320 wire [127:0] scales = {s3, s2, s1, s0};
321 genvar h, s, hf, l;
322 generate
323 for (h = 0; h < 2; h = h + 1) begin : nb
324 for (s = 0; s < 4; s = s + 1) begin : sh
325 for (hf = 0; hf < 2; hf = hf + 1) begin : half
326 localparam integer U = 8*h + 2*s + hf;
327 wire [7:0] sc = scales[8*U +: 8];
328 assign c[16*U +: 16] = $signed({8'd0, sc}) - 16'sd32;
329 for (l = 0; l < 16; l = l + 1) begin : el
330 wire [7:0] q = blk[256 + 8*(32*h + 16*hf + l) +: 8];
331 wire [7:0] hm = blk[8*(16*hf + l) +: 8];
332 assign code[8*(128*h + 32*s + 16*hf + l) +: 8] = {5'd0, hm[4*h + s], q[2*s +: 2]};
333 end
334 end
335 end
336 end
337 endgenerate
338endmodule
339
340module logos_dec_q4_k(input [1151:0] blk, output [2047:0] code, output [255:0] c, output [255:0] n, output [15:0] a, output [15:0] b);
341 assign a = blk[15:0];
342 assign b = blk[31:16];
343 wire [95:0] scq = blk[127:32];
344 genvar p, l;
345 generate
346 for (p = 0; p < 4; p = p + 1) begin : pair
347 wire [5:0] s1, m1, s2, m2;
348 logos_scale_min_k4 lo(.q(scq), .j(2*p), .sc(s1), .mn(m1));
349 logos_scale_min_k4 hi(.q(scq), .j(2*p+1), .sc(s2), .mn(m2));
350 assign c[16*(4*p) +: 32] = {{10'd0, s1}, {10'd0, s1}};
351 assign c[16*(4*p+2) +: 32] = {{10'd0, s2}, {10'd0, s2}};
352 assign n[16*(4*p) +: 32] = {-$signed({10'd0, m1}), -$signed({10'd0, m1})};
353 assign n[16*(4*p+2) +: 32] = {-$signed({10'd0, m2}), -$signed({10'd0, m2})};
354 for (l = 0; l < 32; l = l + 1) begin : el
355 wire [7:0] q = blk[128 + 8*(32*p + l) +: 8];
356 assign code[8*(64*p + l) +: 8] = {4'd0, q[3:0]};
357 assign code[8*(64*p + 32 + l) +: 8] = {4'd0, q[7:4]};
358 end
359 end
360 endgenerate
361endmodule
362
363module logos_dec_q5_k(input [1407:0] blk, output [2047:0] code, output [255:0] c, output [255:0] n, output [15:0] a, output [15:0] b);
364 assign a = blk[15:0];
365 assign b = blk[31:16];
366 wire [95:0] scq = blk[127:32];
367 genvar p, l;
368 generate
369 for (p = 0; p < 4; p = p + 1) begin : pair
370 wire [5:0] s1, m1, s2, m2;
371 logos_scale_min_k4 lo(.q(scq), .j(2*p), .sc(s1), .mn(m1));
372 logos_scale_min_k4 hi(.q(scq), .j(2*p+1), .sc(s2), .mn(m2));
373 assign c[16*(4*p) +: 32] = {{10'd0, s1}, {10'd0, s1}};
374 assign c[16*(4*p+2) +: 32] = {{10'd0, s2}, {10'd0, s2}};
375 assign n[16*(4*p) +: 32] = {-$signed({10'd0, m1}), -$signed({10'd0, m1})};
376 assign n[16*(4*p+2) +: 32] = {-$signed({10'd0, m2}), -$signed({10'd0, m2})};
377 for (l = 0; l < 32; l = l + 1) begin : el
378 wire [7:0] qh = blk[128 + 8*l +: 8];
379 wire [7:0] q = blk[384 + 8*(32*p + l) +: 8];
380 assign code[8*(64*p + l) +: 8] = {3'd0, qh[2*p], q[3:0]};
381 assign code[8*(64*p + 32 + l) +: 8] = {3'd0, qh[2*p+1], q[7:4]};
382 end
383 end
384 endgenerate
385endmodule
386
387module logos_dec_q6_k(input [1679:0] blk, output [2047:0] code, output [255:0] c, output [255:0] n, output [15:0] a, output [15:0] b);
388 assign a = blk[1679:1664];
389 assign b = 16'd0;
390 assign n = 256'd0;
391 genvar part, u, l;
392 generate
393 for (part = 0; part < 2; part = part + 1) begin : pt
394 for (u = 0; u < 8; u = u + 1) begin : un
395 wire [7:0] sc = blk[8*(192 + 8*part + u) +: 8];
396 assign c[16*(8*part + u) +: 16] = {{8{sc[7]}}, sc};
397 end
398 for (l = 0; l < 32; l = l + 1) begin : el
399 wire [7:0] ql0 = blk[8*(64*part + l) +: 8];
400 wire [7:0] ql1 = blk[8*(64*part + l + 32) +: 8];
401 wire [7:0] qh = blk[8*(128 + 32*part + l) +: 8];
402 assign code[8*(128*part + l) +: 8] = {2'd0, qh[1:0], ql0[3:0]};
403 assign code[8*(128*part + l + 32) +: 8] = {2'd0, qh[3:2], ql1[3:0]};
404 assign code[8*(128*part + l + 64) +: 8] = {2'd0, qh[5:4], ql0[7:4]};
405 assign code[8*(128*part + l + 96) +: 8] = {2'd0, qh[7:6], ql1[7:4]};
406 end
407 end
408 endgenerate
409endmodule
410
411// An IQ4 nibble's level as an excess code (ggml's kvalues_iq4nl, plus 128).
412module logos_iq4_level(input [3:0] q, output reg [7:0] level);
413 always @* begin
414 case (q)
415 4'd0: level = 8'd1;
416 4'd1: level = 8'd24;
417 4'd2: level = 8'd45;
418 4'd3: level = 8'd63;
419 4'd4: level = 8'd79;
420 4'd5: level = 8'd93;
421 4'd6: level = 8'd106;
422 4'd7: level = 8'd118;
423 4'd8: level = 8'd129;
424 4'd9: level = 8'd141;
425 4'd10: level = 8'd153;
426 4'd11: level = 8'd166;
427 4'd12: level = 8'd181;
428 4'd13: level = 8'd197;
429 4'd14: level = 8'd217;
430 4'd15: level = 8'd241;
431 endcase
432 end
433endmodule
434
435module logos_dec_iq4_nl(input [143:0] blk, output [255:0] code, output [31:0] c, output [31:0] n, output [15:0] a, output [15:0] b);
436 assign a = blk[15:0];
437 assign b = 16'd0;
438 assign c = {16'sd1, 16'sd1};
439 assign n = 32'd0;
440 genvar j;
441 generate for (j = 0; j < 16; j = j + 1) begin : e
442 logos_iq4_level lo(.q(blk[16 + 8*j +: 4]), .level(code[8*j +: 8]));
443 logos_iq4_level hi(.q(blk[20 + 8*j +: 4]), .level(code[8*(j+16) +: 8]));
444 end endgenerate
445endmodule
446
447module logos_dec_iq4_xs(input [1087:0] blk, output [2047:0] code, output [255:0] c, output [255:0] n, output [15:0] a, output [15:0] b);
448 assign a = blk[15:0];
449 assign b = 16'd0;
450 assign n = 256'd0;
451 wire [15:0] scales_h = blk[31:16];
452 genvar ib, j;
453 generate
454 for (ib = 0; ib < 8; ib = ib + 1) begin : sub
455 wire [5:0] ls = {scales_h[2*ib +: 2], blk[32 + 8*(ib/2) + 4*(ib%2) +: 4]};
456 wire signed [15:0] cs = $signed({10'd0, ls}) - 16'sd32;
457 assign c[16*(2*ib) +: 16] = cs;
458 assign c[16*(2*ib + 1) +: 16] = cs;
459 for (j = 0; j < 16; j = j + 1) begin : e
460 logos_iq4_level lo(.q(blk[64 + 8*(16*ib + j) +: 4]), .level(code[8*(32*ib + j) +: 8]));
461 logos_iq4_level hi(.q(blk[68 + 8*(16*ib + j) +: 4]), .level(code[8*(32*ib + 16 + j) +: 8]));
462 end
463 end
464 endgenerate
465endmodule
466"#;