char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

Pasha KhosraviAdd Q2_0 quantization: type definition and CPU backend (#24448)bec4772f6

char/aliceai-t5-moe
44.1 KiB1339 linesraw
1#define GGML_COMMON_IMPL_C
2#include "ggml-common.h"
3
4#include "ggml-cpu-impl.h"
5#include "simd-mappings.h"
6#include "ggml-quants.h"
7#include "quants.h"
8
9#include "arch-fallback.h"
10
11#include <string.h>
12#include <assert.h>
13#include <float.h>
14#include <stdlib.h> // for qsort
15#include <stdio.h>  // for GGML_ASSERT
16
17#define GROUP_MAX_EPS 1e-15f
18#define GROUP_MAX_EPS_IQ3_XXS 1e-8f
19#define GROUP_MAX_EPS_IQ2_S 1e-8f
20#define GROUP_MAX_EPS_IQ1_M 1e-7f
21#define GROUP_MAX_EPS_IQ1_S 1e-12f
22
23#define UNUSED GGML_UNUSED
24
25void quantize_row_q1_0(const float * GGML_RESTRICT x, void * GGML_RESTRICT y, int64_t k) {
26    quantize_row_q1_0_ref(x, y, k);
27}
28
29void quantize_row_q2_0(const float * GGML_RESTRICT x, void * GGML_RESTRICT y, int64_t k) {
30    quantize_row_q2_0_ref(x, y, k);
31}
32
33void quantize_row_q4_0(const float * GGML_RESTRICT x, void * GGML_RESTRICT y, int64_t k) {
34    quantize_row_q4_0_ref(x, y, k);
35}
36
37void quantize_row_q4_1(const float * GGML_RESTRICT x, void * GGML_RESTRICT y, int64_t k) {
38    quantize_row_q4_1_ref(x, y, k);
39}
40
41void quantize_row_q5_0(const float * GGML_RESTRICT x, void * GGML_RESTRICT y, int64_t k) {
42    quantize_row_q5_0_ref(x, y, k);
43}
44
45void quantize_row_q5_1(const float * GGML_RESTRICT x, void * GGML_RESTRICT y, int64_t k) {
46    quantize_row_q5_1_ref(x, y, k);
47}
48
49void quantize_row_q8_0_generic(const float * GGML_RESTRICT x, void * GGML_RESTRICT y, int64_t k) {
50    quantize_row_q8_0_ref(x, y, k);
51}
52
53void quantize_row_q8_1_generic(const float * GGML_RESTRICT x, void * GGML_RESTRICT y, int64_t k) {
54    quantize_row_q8_1_ref(x, y, k);
55}
56
57void quantize_row_mxfp4(const float * GGML_RESTRICT x, void * GGML_RESTRICT y, int64_t k) {
58    quantize_row_mxfp4_ref(x, y, k);
59}
60
61void quantize_row_nvfp4(const float * GGML_RESTRICT x, void * GGML_RESTRICT y, int64_t k) {
62    quantize_row_nvfp4_ref(x, y, k);
63}
64
65//
66// 2-6 bit quantization in super-blocks
67//
68
69//========================- 2-bit (de)-quantization
70
71void quantize_row_q2_K(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t k) {
72    quantize_row_q2_K_ref(x, vy, k);
73}
74
75//========================= 3-bit (de)-quantization
76
77void quantize_row_q3_K(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t k) {
78    quantize_row_q3_K_ref(x, vy, k);
79}
80
81// ====================== 4-bit (de)-quantization
82
83void quantize_row_q4_K(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t k) {
84    assert(k % QK_K == 0);
85    block_q4_K * GGML_RESTRICT y = vy;
86    quantize_row_q4_K_ref(x, y, k);
87}
88
89// ====================== 5-bit (de)-quantization
90
91void quantize_row_q5_K(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t k) {
92    assert(k % QK_K == 0);
93    block_q5_K * GGML_RESTRICT y = vy;
94    quantize_row_q5_K_ref(x, y, k);
95}
96
97// ====================== 6-bit (de)-quantization
98
99void quantize_row_q6_K(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t k) {
100    assert(k % QK_K == 0);
101    block_q6_K * GGML_RESTRICT y = vy;
102    quantize_row_q6_K_ref(x, y, k);
103}
104
105// ====================== Ternary (de)-quantization (BitNet b1.58 and TriLMs)
106
107void quantize_row_tq1_0(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t k) {
108    assert(k % QK_K == 0);
109    block_tq1_0 * GGML_RESTRICT y = vy;
110    quantize_row_tq1_0_ref(x, y, k);
111}
112
113void quantize_row_tq2_0(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t k) {
114    assert(k % QK_K == 0);
115    block_tq2_0 * GGML_RESTRICT y = vy;
116    quantize_row_tq2_0_ref(x, y, k);
117}
118
119//===================================== Q8_K ==============================================
120
121void quantize_row_q8_K_generic(const float * GGML_RESTRICT x, void * GGML_RESTRICT y, int64_t k) {
122    quantize_row_q8_K_ref(x, y, k);
123}
124
125//===================================== Dot products =================================
126
127void ggml_vec_dot_q1_0_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
128    const int qk = QK1_0;
129    const int nb = n / qk;
130
131    assert(n % qk == 0);
132    assert(nrc == 1);
133    UNUSED(nrc);
134    UNUSED(bx);
135    UNUSED(by);
136    UNUSED(bs);
137
138    const block_q1_0 * GGML_RESTRICT x = vx;
139    const block_q8_0 * GGML_RESTRICT y = vy;
140
141    float sumf = 0.0;
142
143    for (int i = 0; i < nb; i++) {
144        const float d0 = GGML_CPU_FP16_TO_FP32(x[i].d);
145
146        float sumi = 0.0f;
147
148        for (int k = 0; k < 4; k++) {
149            const block_q8_0 * GGML_RESTRICT yb = &y[i * 4 + k];
150            const float d1 = GGML_CPU_FP16_TO_FP32(yb->d);
151            int sumi_block = 0;
152
153            const uint8_t * GGML_RESTRICT bits = &x[i].qs[k * 4];
154            const int8_t  * GGML_RESTRICT qy   = yb->qs;
155
156            for (int b = 0; b < 4; ++b, qy += 8) {
157                const unsigned mask = bits[b];
158                sumi_block += ((mask & 0x01) ? qy[0] : -qy[0])
159                           +  ((mask & 0x02) ? qy[1] : -qy[1])
160                           +  ((mask & 0x04) ? qy[2] : -qy[2])
161                           +  ((mask & 0x08) ? qy[3] : -qy[3])
162                           +  ((mask & 0x10) ? qy[4] : -qy[4])
163                           +  ((mask & 0x20) ? qy[5] : -qy[5])
164                           +  ((mask & 0x40) ? qy[6] : -qy[6])
165                           +  ((mask & 0x80) ? qy[7] : -qy[7]);
166            }
167
168            sumi += d1 * sumi_block;
169        }
170
171        sumf += d0 * sumi;
172    }
173
174    *s = sumf;
175}
176
177void ggml_vec_dot_q2_0_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
178    const int qk = QK2_0;
179    const int nb = n / qk;
180
181    assert(n % qk == 0);
182    assert(nrc == 1);
183    UNUSED(nrc);
184    UNUSED(bx);
185    UNUSED(by);
186    UNUSED(bs);
187
188    const block_q2_0 * GGML_RESTRICT x = vx;
189    const block_q8_0 * GGML_RESTRICT y = vy;
190
191    float sumf = 0.0f;
192
193    for (int i = 0; i < nb; i++) {
194        const float d0 = GGML_CPU_FP16_TO_FP32(x[i].d);
195
196        float sumi = 0.0f;
197
198        // group 64: one Q2_0 block (64 weights) maps to two Q8_0 blocks (2 * 32 = 64)
199        for (int k = 0; k < 2; k++) {
200            const block_q8_0 * GGML_RESTRICT yb = &y[i * 2 + k];
201            const float d1 = GGML_CPU_FP16_TO_FP32(yb->d);
202            int sumi_block = 0;
203
204            const uint8_t * GGML_RESTRICT qs = &x[i].qs[k * 8];
205            const int8_t  * GGML_RESTRICT qy = yb->qs;
206
207            for (int b = 0; b < 8; ++b) {
208                const uint8_t byte = qs[b];
209                // Extract 4 two-bit values, map {0,1,2,3} -> {-1,0,1,2}
210                sumi_block += ((int)((byte >> 0) & 3) - 1) * qy[b*4 + 0];
211                sumi_block += ((int)((byte >> 2) & 3) - 1) * qy[b*4 + 1];
212                sumi_block += ((int)((byte >> 4) & 3) - 1) * qy[b*4 + 2];
213                sumi_block += ((int)((byte >> 6) & 3) - 1) * qy[b*4 + 3];
214            }
215
216            sumi += d1 * sumi_block;
217        }
218
219        sumf += d0 * sumi;
220    }
221
222    *s = sumf;
223}
224
225void ggml_vec_dot_q4_0_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
226    const int qk = QK8_0;
227    const int nb = n / qk;
228
229    assert(n % qk == 0);
230    assert(nrc == 1);
231    UNUSED(nrc);
232    UNUSED(bx);
233    UNUSED(by);
234    UNUSED(bs);
235
236    const block_q4_0 * GGML_RESTRICT x = vx;
237    const block_q8_0 * GGML_RESTRICT y = vy;
238
239    int ib = 0;
240    float sumf = 0;
241
242    for (; ib < nb; ++ib) {
243        int sumi0 = 0;
244        int sumi1 = 0;
245
246        for (int j = 0; j < qk/2; ++j) {
247            const int v0 = (x[ib].qs[j] & 0x0F) - 8;
248            const int v1 = (x[ib].qs[j] >>   4) - 8;
249
250            sumi0 += (v0 * y[ib].qs[j]);
251            sumi1 += (v1 * y[ib].qs[j + qk/2]);
252        }
253
254        int sumi = sumi0 + sumi1;
255        sumf += sumi*GGML_CPU_FP16_TO_FP32(x[ib].d)*GGML_CPU_FP16_TO_FP32(y[ib].d);
256    }
257
258    *s = sumf;
259}
260
261// TODO: add WASM SIMD
262void ggml_vec_dot_q4_1_q8_1_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
263    const int qk = QK8_1;
264    const int nb = n / qk;
265
266    assert(n % qk == 0);
267    assert(nrc == 1);
268    UNUSED(nrc);
269    UNUSED(bx);
270    UNUSED(by);
271    UNUSED(bs);
272
273    const block_q4_1 * GGML_RESTRICT x = vx;
274    const block_q8_1 * GGML_RESTRICT y = vy;
275
276    int ib = 0;
277    float sumf = 0;
278
279    for (; ib < nb; ++ib) {
280        int sumi0 = 0;
281        int sumi1 = 0;
282
283        for (int j = 0; j < qk/2; ++j) {
284            const int v0 = (x[ib].qs[j] & 0x0F);
285            const int v1 = (x[ib].qs[j] >>   4);
286
287            sumi0 += (v0 * y[ib].qs[j]);
288            sumi1 += (v1 * y[ib].qs[j + qk/2]);
289        }
290
291        int sumi = sumi0 + sumi1;
292        sumf += (GGML_CPU_FP16_TO_FP32(x[ib].d)*GGML_CPU_FP16_TO_FP32(y[ib].d))*sumi + GGML_CPU_FP16_TO_FP32(x[ib].m)*GGML_CPU_FP16_TO_FP32(y[ib].s);
293    }
294
295    *s = sumf;
296}
297
298void ggml_vec_dot_mxfp4_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
299    assert(nrc == 1);
300    UNUSED(nrc);
301    UNUSED(bx);
302    UNUSED(by);
303    UNUSED(bs);
304    assert(n % QK_MXFP4 == 0);
305    static_assert(QK_MXFP4 == QK8_0, "QK_MXFP4 and QK8_0 must be the same");
306
307    const block_mxfp4 * GGML_RESTRICT x = vx;
308    const block_q8_0 * GGML_RESTRICT y = vy;
309
310    const int nb = n / QK_MXFP4;
311
312    int ib = 0;
313    float sumf = 0;
314
315    for (; ib < nb; ++ib) {
316        const float d = GGML_CPU_FP16_TO_FP32(y[ib].d)*GGML_E8M0_TO_FP32_HALF(x[ib].e);
317
318        int sumi1 = 0;
319        int sumi2 = 0;
320        for (int j = 0; j < QK_MXFP4/2; ++j) {
321            sumi1 += y[ib].qs[j +          0] * kvalues_mxfp4[x[ib].qs[j] & 0xf];
322            sumi2 += y[ib].qs[j + QK_MXFP4/2] * kvalues_mxfp4[x[ib].qs[j] >>  4];
323        }
324        sumf += d * (sumi1 + sumi2);
325    }
326    *s = sumf;
327}
328
329// NVFP4: super-block of 64 elements = 4 sub-blocks of 16 = 2 q8_0 blocks
330void ggml_vec_dot_nvfp4_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
331    assert(nrc == 1);
332    UNUSED(nrc);
333    UNUSED(bx);
334    UNUSED(by);
335    UNUSED(bs);
336    assert(n % QK_NVFP4 == 0);
337
338    const block_nvfp4 * GGML_RESTRICT x = vx;
339    const block_q8_0 * GGML_RESTRICT y = vy;
340
341    const int nb = n / QK_NVFP4;
342
343    float sumf = 0;
344
345    for (int ib = 0; ib < nb; ++ib) {
346        for (int s_idx = 0; s_idx < 4; ++s_idx) {
347            const float d = ggml_ue4m3_to_fp32(x[ib].d[s_idx]);
348            const int q8_block = s_idx / 2;
349            const int q8_off   = (s_idx % 2) * QK_NVFP4_SUB;
350            const float dy = GGML_CPU_FP16_TO_FP32(y[2*ib + q8_block].d);
351
352            int sumi_lo = 0, sumi_hi = 0;
353            for (int j = 0; j < QK_NVFP4_SUB/2; ++j) {
354                const uint8_t qv = x[ib].qs[s_idx*(QK_NVFP4_SUB/2) + j];
355                sumi_lo += y[2*ib + q8_block].qs[q8_off + j +               0] * kvalues_mxfp4[qv & 0xf];
356                sumi_hi += y[2*ib + q8_block].qs[q8_off + j + QK_NVFP4_SUB/2] * kvalues_mxfp4[qv >>  4];
357            }
358
359            sumf += dy * d * (sumi_lo + sumi_hi);
360        }
361    }
362    *s = sumf;
363}
364
365void ggml_vec_dot_q5_0_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
366    const int qk = QK8_0;
367    const int nb = n / qk;
368
369    int ib = 0;
370    float sumf = 0;
371
372    assert(n % qk == 0);
373    assert(qk == QK5_0);
374    assert(nrc == 1);
375    UNUSED(nrc);
376    UNUSED(bx);
377    UNUSED(by);
378    UNUSED(bs);
379
380    const block_q5_0 * GGML_RESTRICT x = vx;
381    const block_q8_0 * GGML_RESTRICT y = vy;
382
383    for (; ib < nb; ++ib) {
384        uint32_t qh;
385        memcpy(&qh, x[ib].qh, sizeof(qh));
386
387        int sumi0 = 0;
388        int sumi1 = 0;
389
390        for (int j = 0; j < qk/2; ++j) {
391            const uint8_t xh_0 = ((qh & (1u << (j + 0 ))) >> (j + 0 )) << 4;
392            const uint8_t xh_1 = ((qh & (1u << (j + 16))) >> (j + 12));
393
394            const int32_t x0 = (int8_t)(((x[ib].qs[j] & 0x0F) | xh_0) - 16);
395            const int32_t x1 = (int8_t)(((x[ib].qs[j] >>   4) | xh_1) - 16);
396
397            sumi0 += (x0 * y[ib].qs[j]);
398            sumi1 += (x1 * y[ib].qs[j + qk/2]);
399        }
400
401        int sumi = sumi0 + sumi1;
402        sumf += (GGML_CPU_FP16_TO_FP32(x[ib].d)*GGML_CPU_FP16_TO_FP32(y[ib].d)) * sumi;
403    }
404
405    *s = sumf;
406}
407
408void ggml_vec_dot_q5_1_q8_1_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
409    const int qk = QK8_1;
410    const int nb = n / qk;
411
412    int ib = 0;
413    float sumf = 0;
414
415    assert(n % qk == 0);
416    assert(qk == QK5_1);
417    assert(nrc == 1);
418    UNUSED(nrc);
419    UNUSED(bx);
420    UNUSED(by);
421    UNUSED(bs);
422
423    const block_q5_1 * GGML_RESTRICT x = vx;
424    const block_q8_1 * GGML_RESTRICT y = vy;
425
426    for (; ib < nb; ++ib) {
427        uint32_t qh;
428        memcpy(&qh, x[ib].qh, sizeof(qh));
429
430        int sumi0 = 0;
431        int sumi1 = 0;
432
433        for (int j = 0; j < qk/2; ++j) {
434            const uint8_t xh_0 = ((qh >> (j +  0)) << 4) & 0x10;
435            const uint8_t xh_1 = ((qh >> (j + 12))     ) & 0x10;
436
437            const int32_t x0 = (x[ib].qs[j] & 0xF) | xh_0;
438            const int32_t x1 = (x[ib].qs[j] >>  4) | xh_1;
439
440            sumi0 += (x0 * y[ib].qs[j]);
441            sumi1 += (x1 * y[ib].qs[j + qk/2]);
442        }
443
444        int sumi = sumi0 + sumi1;
445        sumf += (GGML_CPU_FP16_TO_FP32(x[ib].d)*GGML_CPU_FP16_TO_FP32(y[ib].d))*sumi + GGML_CPU_FP16_TO_FP32(x[ib].m)*GGML_CPU_FP16_TO_FP32(y[ib].s);
446    }
447
448    *s = sumf;
449}
450
451void ggml_vec_dot_q8_0_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
452    const int qk = QK8_0;
453    const int nb = n / qk;
454
455    assert(n % qk == 0);
456    assert(nrc == 1);
457    UNUSED(nrc);
458    UNUSED(bx);
459    UNUSED(by);
460    UNUSED(bs);
461
462    const block_q8_0 * GGML_RESTRICT x = vx;
463    const block_q8_0 * GGML_RESTRICT y = vy;
464
465    int ib = 0;
466    float sumf = 0;
467
468    for (; ib < nb; ++ib) {
469        int sumi = 0;
470
471        for (int j = 0; j < qk; j++) {
472            sumi += x[ib].qs[j]*y[ib].qs[j];
473        }
474
475        sumf += sumi*(GGML_CPU_FP16_TO_FP32(x[ib].d)*GGML_CPU_FP16_TO_FP32(y[ib].d));
476    }
477
478    *s = sumf;
479}
480
481void ggml_vec_dot_tq1_0_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
482    assert(nrc == 1);
483    UNUSED(nrc);
484    UNUSED(bx);
485    UNUSED(by);
486    UNUSED(bs);
487
488    const block_tq1_0 * GGML_RESTRICT x = vx;
489    const block_q8_K  * GGML_RESTRICT y = vy;
490
491    const int nb = n / QK_K;
492
493    const uint8_t pow3[6] = {1, 3, 9, 27, 81, 243};
494
495    float sumf = 0.0f;
496
497    for (int i = 0; i < nb; ++i) {
498        int sum = 0;
499
500        for (size_t j = 0; j < sizeof(x->qs) - sizeof(x->qs) % 32; j += 32) {
501            for (size_t l = 0; l < 5; ++l) {
502                for (size_t m = 0; m < 32; ++m) {
503                    uint8_t q = x[i].qs[j + m] * pow3[l];
504                    uint16_t xi = ((uint16_t) q * 3) >> 8;
505                    sum += (xi - 1) * y[i].qs[j*5 + l*32 + m];
506                }
507            }
508        }
509        for (size_t j = sizeof(x->qs) - sizeof(x->qs) % 32; j < sizeof(x->qs); j += 16) {
510            for (size_t l = 0; l < 5; ++l) {
511                for (size_t m = 0; m < 16; ++m) {
512                    uint8_t q = x[i].qs[j + m] * pow3[l];
513                    uint16_t xi = ((uint16_t) q * 3) >> 8;
514                    sum += (xi - 1) * y[i].qs[j*5 + l*16 + m];
515                }
516            }
517        }
518
519        for (size_t l = 0; l < 4; ++l) {
520            for (size_t j = 0; j < sizeof(x->qh); ++j) {
521                uint8_t q = x[i].qh[j] * pow3[l];
522                uint16_t xi = ((uint16_t) q * 3) >> 8;
523                sum += (xi - 1) * y[i].qs[sizeof(x->qs)*5 + l*sizeof(x->qh) + j];
524            }
525        }
526
527        sumf += (float) sum * (GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d);
528    }
529
530    *s = sumf;
531}
532
533void ggml_vec_dot_tq2_0_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
534    assert(nrc == 1);
535    UNUSED(nrc);
536    UNUSED(bx);
537    UNUSED(by);
538    UNUSED(bs);
539
540    const block_tq2_0 * GGML_RESTRICT x = vx;
541    const block_q8_K  * GGML_RESTRICT y = vy;
542
543    const int nb = n / QK_K;
544    float sumf = 0.0f;
545
546    for (int i = 0; i < nb; ++i) {
547        int32_t sumi = 0;
548
549        for (size_t j = 0; j < sizeof(x->qs); j += 32) {
550            for (size_t l = 0; l < 4; ++l) {
551                for (size_t k = 0; k < 32; ++k) {
552                    sumi += y[i].qs[j*4 + l*32 + k] * (((x[i].qs[j + k] >> (l*2)) & 3) - 1);
553                }
554            }
555        }
556
557        const float d = y[i].d * GGML_CPU_FP16_TO_FP32(x[i].d);
558
559        sumf += (float) sumi * d;
560    }
561
562    *s = sumf;
563}
564
565void ggml_vec_dot_q2_K_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
566    assert(nrc == 1);
567    UNUSED(nrc);
568    UNUSED(bx);
569    UNUSED(by);
570    UNUSED(bs);
571
572    const block_q2_K * GGML_RESTRICT x = vx;
573    const block_q8_K * GGML_RESTRICT y = vy;
574
575    const int nb = n / QK_K;
576
577    float sumf = 0;
578
579    for (int i = 0; i < nb; ++i) {
580
581        const uint8_t * q2 = x[i].qs;
582        const  int8_t * q8 = y[i].qs;
583        const uint8_t * sc = x[i].scales;
584
585        int summs = 0;
586        for (int j = 0; j < 16; ++j) {
587            summs += y[i].bsums[j] * (sc[j] >> 4);
588        }
589
590        const float dall = y[i].d * GGML_CPU_FP16_TO_FP32(x[i].d);
591        const float dmin = y[i].d * GGML_CPU_FP16_TO_FP32(x[i].dmin);
592
593        int isum = 0;
594        int is = 0;
595        int d;
596        for (int k = 0; k < QK_K/128; ++k) {
597            int shift = 0;
598            for (int j = 0; j < 4; ++j) {
599                d = sc[is++] & 0xF;
600                int isuml = 0;
601                for (int l =  0; l < 16; ++l) isuml += q8[l] * ((q2[l] >> shift) & 3);
602                isum += d * isuml;
603                d = sc[is++] & 0xF;
604                isuml = 0;
605                for (int l = 16; l < 32; ++l) isuml += q8[l] * ((q2[l] >> shift) & 3);
606                isum += d * isuml;
607                shift += 2;
608                q8 += 32;
609            }
610            q2 += 32;
611        }
612        sumf += dall * isum - dmin * summs;
613    }
614    *s = sumf;
615}
616
617void ggml_vec_dot_q3_K_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
618    assert(n % QK_K == 0);
619    assert(nrc == 1);
620    UNUSED(nrc);
621    UNUSED(bx);
622    UNUSED(by);
623    UNUSED(bs);
624
625    const uint32_t kmask1 = 0x03030303;
626    const uint32_t kmask2 = 0x0f0f0f0f;
627
628    const block_q3_K * GGML_RESTRICT x = vx;
629    const block_q8_K * GGML_RESTRICT y = vy;
630
631    const int nb = n / QK_K;
632
633    // scalar version
634    // This function is written like this so the compiler can manage to vectorize most of it
635    // Using -Ofast, GCC and clang manage to produce code that is within a factor of 2 or so from the
636    // manually vectorized version above. Every other version I tried would run at least 4 times slower.
637    // The ideal situation would be if we could just write the code once, and the compiler would
638    // automatically produce the best possible set of machine instructions, instead of us having to manually
639    // write vectorized versions for AVX, ARM_NEON, etc.
640
641    int8_t  aux8[QK_K];
642    int16_t aux16[8];
643    float   sums [8];
644    int32_t aux32[8];
645    memset(sums, 0, 8*sizeof(float));
646
647    uint32_t auxs[4];
648    const int8_t * scales = (const int8_t*)auxs;
649
650    float sumf = 0;
651    for (int i = 0; i < nb; ++i) {
652        const uint8_t * GGML_RESTRICT q3 = x[i].qs;
653        const uint8_t * GGML_RESTRICT hm = x[i].hmask;
654        const  int8_t * GGML_RESTRICT q8 = y[i].qs;
655        memset(aux32, 0, 8*sizeof(int32_t));
656        int8_t * GGML_RESTRICT a = aux8;
657        uint8_t m = 1;
658        for (int j = 0; j < QK_K; j += 128) {
659            for (int l = 0; l < 32; ++l) a[l] = q3[l] & 3;
660            for (int l = 0; l < 32; ++l) a[l] -= (hm[l] & m ? 0 : 4);
661            a += 32; m <<= 1;
662            for (int l = 0; l < 32; ++l) a[l] = (q3[l] >> 2) & 3;
663            for (int l = 0; l < 32; ++l) a[l] -= (hm[l] & m ? 0 : 4);
664            a += 32; m <<= 1;
665            for (int l = 0; l < 32; ++l) a[l] = (q3[l] >> 4) & 3;
666            for (int l = 0; l < 32; ++l) a[l] -= (hm[l] & m ? 0 : 4);
667            a += 32; m <<= 1;
668            for (int l = 0; l < 32; ++l) a[l] = (q3[l] >> 6) & 3;
669            for (int l = 0; l < 32; ++l) a[l] -= (hm[l] & m ? 0 : 4);
670            a += 32; m <<= 1;
671            q3 += 32;
672        }
673        a = aux8;
674
675        memcpy(auxs, x[i].scales, 12);
676        uint32_t tmp = auxs[2];
677        auxs[2] = ((auxs[0] >> 4) & kmask2) | (((tmp >> 4) & kmask1) << 4);
678        auxs[3] = ((auxs[1] >> 4) & kmask2) | (((tmp >> 6) & kmask1) << 4);
679        auxs[0] = (auxs[0] & kmask2) | (((tmp >> 0) & kmask1) << 4);
680        auxs[1] = (auxs[1] & kmask2) | (((tmp >> 2) & kmask1) << 4);
681        for (int j = 0; j < QK_K/16; ++j) {
682            for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l];
683            for (int l = 0; l < 8; ++l) aux32[l] += (scales[j] - 32) * aux16[l];
684            q8 += 8; a += 8;
685            for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l];
686            for (int l = 0; l < 8; ++l) aux32[l] += (scales[j] - 32) * aux16[l];
687            q8 += 8; a += 8;
688        }
689        const float d = GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d;
690        for (int l = 0; l < 8; ++l) sums[l] += d * aux32[l];
691    }
692    for (int l = 0; l < 8; ++l) sumf += sums[l];
693    *s = sumf;
694}
695
696void ggml_vec_dot_q4_K_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
697    assert(n % QK_K == 0);
698    assert(nrc == 1);
699    UNUSED(nrc);
700    UNUSED(bx);
701    UNUSED(by);
702    UNUSED(bs);
703
704    const block_q4_K * GGML_RESTRICT x = vx;
705    const block_q8_K * GGML_RESTRICT y = vy;
706
707    const int nb = n / QK_K;
708
709    static const uint32_t kmask1 = 0x3f3f3f3f;
710    static const uint32_t kmask2 = 0x0f0f0f0f;
711    static const uint32_t kmask3 = 0x03030303;
712
713    uint32_t utmp[4];
714
715    const uint8_t * scales = (const uint8_t*)&utmp[0];
716    const uint8_t * mins   = (const uint8_t*)&utmp[2];
717
718    int8_t  aux8[QK_K];
719    int16_t aux16[8];
720    float   sums [8];
721    int32_t aux32[8];
722    memset(sums, 0, 8*sizeof(float));
723
724    float sumf = 0;
725    for (int i = 0; i < nb; ++i) {
726        const uint8_t * GGML_RESTRICT q4 = x[i].qs;
727        const  int8_t * GGML_RESTRICT q8 = y[i].qs;
728        memset(aux32, 0, 8*sizeof(int32_t));
729        int8_t * GGML_RESTRICT a = aux8;
730        for (int j = 0; j < QK_K/64; ++j) {
731            for (int l = 0; l < 32; ++l) a[l] = (int8_t)(q4[l] & 0xF);
732            a += 32;
733            for (int l = 0; l < 32; ++l) a[l] = (int8_t)(q4[l]  >> 4);
734            a += 32; q4 += 32;
735        }
736        memcpy(utmp, x[i].scales, 12);
737        utmp[3] = ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4);
738        const uint32_t uaux = utmp[1] & kmask1;
739        utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4);
740        utmp[2] = uaux;
741        utmp[0] &= kmask1;
742
743        int sumi = 0;
744        for (int j = 0; j < QK_K/16; ++j) sumi += y[i].bsums[j] * mins[j/2];
745        a = aux8;
746        int is = 0;
747        for (int j = 0; j < QK_K/32; ++j) {
748            int32_t scale = scales[is++];
749            for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l];
750            for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l];
751            q8 += 8; a += 8;
752            for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l];
753            for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l];
754            q8 += 8; a += 8;
755            for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l];
756            for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l];
757            q8 += 8; a += 8;
758            for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l];
759            for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l];
760            q8 += 8; a += 8;
761        }
762        const float d = GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d;
763        for (int l = 0; l < 8; ++l) sums[l] += d * aux32[l];
764        const float dmin = GGML_CPU_FP16_TO_FP32(x[i].dmin) * y[i].d;
765        sumf -= dmin * sumi;
766    }
767    for (int l = 0; l < 8; ++l) sumf += sums[l];
768    *s = sumf;
769}
770
771void ggml_vec_dot_q5_K_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy,  size_t by, int nrc) {
772    assert(n % QK_K == 0);
773    assert(nrc == 1);
774    UNUSED(nrc);
775    UNUSED(bx);
776    UNUSED(by);
777    UNUSED(bs);
778
779    const block_q5_K * GGML_RESTRICT x = vx;
780    const block_q8_K * GGML_RESTRICT y = vy;
781
782    const int nb = n / QK_K;
783
784    static const uint32_t kmask1 = 0x3f3f3f3f;
785    static const uint32_t kmask2 = 0x0f0f0f0f;
786    static const uint32_t kmask3 = 0x03030303;
787
788    uint32_t utmp[4];
789
790    const uint8_t * scales = (const uint8_t*)&utmp[0];
791    const uint8_t * mins   = (const uint8_t*)&utmp[2];
792
793    int8_t  aux8[QK_K];
794    int16_t aux16[8];
795    float   sums [8];
796    int32_t aux32[8];
797    memset(sums, 0, 8*sizeof(float));
798
799    float sumf = 0;
800    for (int i = 0; i < nb; ++i) {
801        const uint8_t * GGML_RESTRICT q4 = x[i].qs;
802        const uint8_t * GGML_RESTRICT hm = x[i].qh;
803        const  int8_t * GGML_RESTRICT q8 = y[i].qs;
804        memset(aux32, 0, 8*sizeof(int32_t));
805        int8_t * GGML_RESTRICT a = aux8;
806        uint8_t m = 1;
807        for (int j = 0; j < QK_K/64; ++j) {
808            for (int l = 0; l < 32; ++l) a[l] = (int8_t)(q4[l] & 0xF);
809            for (int l = 0; l < 32; ++l) a[l] += (hm[l] & m ? 16 : 0);
810            a += 32; m <<= 1;
811            for (int l = 0; l < 32; ++l) a[l] = (int8_t)(q4[l]  >> 4);
812            for (int l = 0; l < 32; ++l) a[l] += (hm[l] & m ? 16 : 0);
813            a += 32; m <<= 1;
814            q4 += 32;
815        }
816        memcpy(utmp, x[i].scales, 12);
817        utmp[3] = ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4);
818        const uint32_t uaux = utmp[1] & kmask1;
819        utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4);
820        utmp[2] = uaux;
821        utmp[0] &= kmask1;
822
823        int sumi = 0;
824        for (int j = 0; j < QK_K/16; ++j) sumi += y[i].bsums[j] * mins[j/2];
825        a = aux8;
826        int is = 0;
827        for (int j = 0; j < QK_K/32; ++j) {
828            int32_t scale = scales[is++];
829            for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l];
830            for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l];
831            q8 += 8; a += 8;
832            for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l];
833            for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l];
834            q8 += 8; a += 8;
835            for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l];
836            for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l];
837            q8 += 8; a += 8;
838            for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l];
839            for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l];
840            q8 += 8; a += 8;
841        }
842        const float d = GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d;
843        for (int l = 0; l < 8; ++l) sums[l] += d * aux32[l];
844        const float dmin = GGML_CPU_FP16_TO_FP32(x[i].dmin) * y[i].d;
845        sumf -= dmin * sumi;
846    }
847    for (int l = 0; l < 8; ++l) sumf += sums[l];
848    *s = sumf;
849}
850
851void ggml_vec_dot_q6_K_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
852    assert(n % QK_K == 0);
853    assert(nrc == 1);
854    UNUSED(nrc);
855    UNUSED(bx);
856    UNUSED(by);
857    UNUSED(bs);
858
859    const block_q6_K * GGML_RESTRICT x = vx;
860    const block_q8_K * GGML_RESTRICT y = vy;
861
862    const int nb = n / QK_K;
863
864    int8_t  aux8[QK_K];
865    int16_t aux16[8];
866    float   sums [8];
867    int32_t aux32[8];
868    memset(sums, 0, 8*sizeof(float));
869
870    float sumf = 0;
871    for (int i = 0; i < nb; ++i) {
872        const uint8_t * GGML_RESTRICT q4 = x[i].ql;
873        const uint8_t * GGML_RESTRICT qh = x[i].qh;
874        const  int8_t * GGML_RESTRICT q8 = y[i].qs;
875        memset(aux32, 0, 8*sizeof(int32_t));
876        int8_t * GGML_RESTRICT a = aux8;
877        for (int j = 0; j < QK_K; j += 128) {
878            for (int l = 0; l < 32; ++l) {
879                a[l +  0] = (int8_t)((q4[l +  0] & 0xF) | (((qh[l] >> 0) & 3) << 4)) - 32;
880                a[l + 32] = (int8_t)((q4[l + 32] & 0xF) | (((qh[l] >> 2) & 3) << 4)) - 32;
881                a[l + 64] = (int8_t)((q4[l +  0] >>  4) | (((qh[l] >> 4) & 3) << 4)) - 32;
882                a[l + 96] = (int8_t)((q4[l + 32] >>  4) | (((qh[l] >> 6) & 3) << 4)) - 32;
883            }
884            a  += 128;
885            q4 += 64;
886            qh += 32;
887        }
888        a = aux8;
889        int is = 0;
890        for (int j = 0; j < QK_K/16; ++j) {
891            int scale = x[i].scales[is++];
892            for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l];
893            for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l];
894            q8 += 8; a += 8;
895            for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l];
896            for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l];
897            q8 += 8; a += 8;
898        }
899        const float d = GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d;
900        for (int l = 0; l < 8; ++l) sums[l] += d * aux32[l];
901    }
902    for (int l = 0; l < 8; ++l) sumf += sums[l];
903    *s = sumf;
904}
905
906void ggml_vec_dot_iq2_xxs_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
907    assert(n % QK_K == 0);
908    assert(nrc == 1);
909    UNUSED(nrc);
910    UNUSED(bx);
911    UNUSED(by);
912    UNUSED(bs);
913
914    const block_iq2_xxs * GGML_RESTRICT x = vx;
915    const block_q8_K    * GGML_RESTRICT y = vy;
916
917    const int nb = n / QK_K;
918
919    uint32_t aux32[2];
920    const uint8_t * aux8 = (const uint8_t *)aux32;
921
922    float sumf = 0.f;
923    for (int i = 0; i < nb; ++i) {
924        const float d = GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d;
925        const uint16_t * GGML_RESTRICT q2 = x[i].qs;
926        const int8_t   * GGML_RESTRICT q8 = y[i].qs;
927        int32_t bsum = 0;
928        for (int ib32 = 0; ib32 < QK_K/32; ++ib32) {
929            memcpy(aux32, q2, 2*sizeof(uint32_t));
930            q2 += 4;
931            const uint32_t ls = 2*(aux32[1] >> 28) + 1;
932            int32_t sumi = 0;
933            for (int l = 0; l < 4; ++l) {
934                const uint8_t * grid = (const uint8_t *)(iq2xxs_grid + aux8[l]);
935                const uint8_t  signs = ksigns_iq2xs[(aux32[1] >> 7*l) & 127];
936                for (int j = 0; j < 8; ++j) {
937                    sumi += grid[j] * q8[j] * (signs & kmask_iq2xs[j] ? -1 : 1);
938                }
939                q8 += 8;
940            }
941            bsum += sumi * ls;
942        }
943        sumf += d * bsum;
944    }
945    *s = 0.125f * sumf;
946}
947
948void ggml_vec_dot_iq2_xs_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
949    assert(n % QK_K == 0);
950    assert(nrc == 1);
951    UNUSED(nrc);
952    UNUSED(bx);
953    UNUSED(by);
954    UNUSED(bs);
955
956    const block_iq2_xs * GGML_RESTRICT x = vx;
957    const block_q8_K   * GGML_RESTRICT y = vy;
958
959    const int nb = n / QK_K;
960
961    float sumf = 0.f;
962    for (int i = 0; i < nb; ++i) {
963        const float d = GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d;
964        const uint16_t * GGML_RESTRICT q2 = x[i].qs;
965        const uint8_t  * GGML_RESTRICT sc = x[i].scales;
966        const int8_t   * GGML_RESTRICT q8 = y[i].qs;
967        int32_t bsum = 0;
968        for (int ib32 = 0; ib32 < QK_K/32; ++ib32) {
969            const uint16_t ls1 = 2*(sc[ib32] & 0xf) + 1;
970            const uint16_t ls2 = 2*(sc[ib32] >>  4) + 1;
971            int32_t sumi = 0;
972            for (int l = 0; l < 2; ++l) {
973                const uint8_t * grid = (const uint8_t *)(iq2xs_grid + (q2[l] & 511));
974                const uint8_t  signs = ksigns_iq2xs[q2[l] >> 9];
975                for (int j = 0; j < 8; ++j) {
976                    sumi += grid[j] * q8[j] * (signs & kmask_iq2xs[j] ? -1 : 1);
977                }
978                q8 += 8;
979            }
980            bsum += sumi * ls1;
981            sumi = 0;
982            for (int l = 2; l < 4; ++l) {
983                const uint8_t * grid = (const uint8_t *)(iq2xs_grid + (q2[l] & 511));
984                const uint8_t  signs = ksigns_iq2xs[q2[l] >> 9];
985                for (int j = 0; j < 8; ++j) {
986                    sumi += grid[j] * q8[j] * (signs & kmask_iq2xs[j] ? -1 : 1);
987                }
988                q8 += 8;
989            }
990            bsum += sumi * ls2;
991            q2 += 4;
992        }
993        sumf += d * bsum;
994    }
995    *s = 0.125f * sumf;
996}
997
998void ggml_vec_dot_iq2_s_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
999    assert(n % QK_K == 0);
1000    assert(nrc == 1);
1001    UNUSED(nrc);
1002    UNUSED(bx);
1003    UNUSED(by);
1004    UNUSED(bs);
1005
1006    const block_iq2_s * GGML_RESTRICT x = vx;
1007    const block_q8_K  * GGML_RESTRICT y = vy;
1008
1009    const int nb = n / QK_K;
1010
1011    float sumf = 0;
1012    for (int i = 0; i < nb; i++) {
1013
1014        const float d = GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d;
1015        const int8_t  * q8 = y[i].qs;
1016        const uint8_t * qs = x[i].qs;
1017        const uint8_t * qh = x[i].qh;
1018        const uint8_t * signs = qs + QK_K/8;
1019
1020        int bsum = 0;
1021        for (int ib32 = 0; ib32 < QK_K/32; ++ib32) {
1022            int ls1 = 1 + 2*(x[i].scales[ib32] & 0xf);
1023            int ls2 = 1 + 2*(x[i].scales[ib32] >>  4);
1024            int sumi1 = 0, sumi2 = 0;
1025            for (int l = 0; l < 2; ++l) {
1026                const uint8_t * grid = (const uint8_t *)(iq2s_grid + (qs[l] | (qh[ib32] << (8-2*l) & 0x300)));
1027                for (int j = 0; j < 8; ++j) {
1028                    sumi1 += q8[j] * grid[j] * (signs[l] & kmask_iq2xs[j] ? -1 : 1);
1029                }
1030                q8 += 8;
1031            }
1032            for (int l = 2; l < 4; ++l) {
1033                const uint8_t * grid = (const uint8_t *)(iq2s_grid + (qs[l] | (qh[ib32] << (8-2*l) & 0x300)));
1034                for (int j = 0; j < 8; ++j) {
1035                    sumi2 += q8[j] * grid[j] * (signs[l] & kmask_iq2xs[j] ? -1 : 1);
1036                }
1037                q8 += 8;
1038            }
1039            bsum += ls1 * sumi1 + ls2 * sumi2;
1040            qs += 4;
1041            signs += 4;
1042        }
1043
1044        sumf += d * bsum;
1045    }
1046
1047    *s = 0.125f * sumf;
1048}
1049
1050void ggml_vec_dot_iq3_xxs_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
1051    assert(n % QK_K == 0);
1052    assert(nrc == 1);
1053    UNUSED(nrc);
1054    UNUSED(bx);
1055    UNUSED(by);
1056    UNUSED(bs);
1057
1058    const block_iq3_xxs * GGML_RESTRICT x = vx;
1059    const block_q8_K    * GGML_RESTRICT y = vy;
1060
1061    const int nb = n / QK_K;
1062
1063    uint32_t aux32;
1064
1065    float sumf = 0.f;
1066    for (int i = 0; i < nb; ++i) {
1067        const float d = GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d;
1068        const uint8_t * GGML_RESTRICT q3 = x[i].qs;
1069        const uint8_t * GGML_RESTRICT gas = x[i].qs + QK_K/4;
1070        const int8_t  * GGML_RESTRICT q8 = y[i].qs;
1071        int32_t bsum = 0;
1072        for (int ib32 = 0; ib32 < QK_K/32; ++ib32) {
1073            memcpy(&aux32, gas, sizeof(uint32_t)); gas += sizeof(uint32_t);
1074            const uint32_t ls = 2*(aux32 >> 28) + 1;
1075            int32_t sumi = 0;
1076            for (int l = 0; l < 4; ++l) {
1077                const uint8_t * grid1 = (const uint8_t *)(iq3xxs_grid + q3[2*l+0]);
1078                const uint8_t * grid2 = (const uint8_t *)(iq3xxs_grid + q3[2*l+1]);
1079                const uint8_t  signs = ksigns_iq2xs[(aux32 >> 7*l) & 127];
1080                for (int j = 0; j < 4; ++j) {
1081                    sumi += grid1[j] * q8[j+0] * (signs & kmask_iq2xs[j+0] ? -1 : 1);
1082                    sumi += grid2[j] * q8[j+4] * (signs & kmask_iq2xs[j+4] ? -1 : 1);
1083                }
1084                q8 += 8;
1085            }
1086            q3 += 8;
1087            bsum += sumi * ls;
1088        }
1089        sumf += d * bsum;
1090    }
1091    *s = 0.25f * sumf;
1092}
1093
1094void ggml_vec_dot_iq3_s_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
1095    assert(n % QK_K == 0);
1096    assert(nrc == 1);
1097    UNUSED(nrc);
1098    UNUSED(bx);
1099    UNUSED(by);
1100    UNUSED(bs);
1101
1102    const block_iq3_s * GGML_RESTRICT x = vx;
1103    const block_q8_K  * GGML_RESTRICT y = vy;
1104
1105    const int nb = n / QK_K;
1106
1107    float sumf = 0.f;
1108    for (int i = 0; i < nb; ++i) {
1109        const float d = GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d;
1110        const uint8_t * GGML_RESTRICT qs = x[i].qs;
1111        const uint8_t * GGML_RESTRICT qh = x[i].qh;
1112        const uint8_t * GGML_RESTRICT signs = x[i].signs;
1113        const int8_t  * GGML_RESTRICT q8 = y[i].qs;
1114        int32_t bsum = 0;
1115        for (int ib32 = 0; ib32 < QK_K/32; ib32 += 2) {
1116            const uint32_t ls1 = 2*(x[i].scales[ib32/2] & 0xf) + 1;
1117            const uint32_t ls2 = 2*(x[i].scales[ib32/2] >>  4) + 1;
1118            int32_t sumi = 0;
1119            for (int l = 0; l < 4; ++l) {
1120                const uint8_t * grid1 = (const uint8_t *)(iq3s_grid + (qs[2*l+0] | ((qh[ib32+0] << (8-2*l)) & 256)));
1121                const uint8_t * grid2 = (const uint8_t *)(iq3s_grid + (qs[2*l+1] | ((qh[ib32+0] << (7-2*l)) & 256)));
1122                for (int j = 0; j < 4; ++j) {
1123                    sumi += grid1[j] * q8[j+0] * (signs[l] & kmask_iq2xs[j+0] ? -1 : 1);
1124                    sumi += grid2[j] * q8[j+4] * (signs[l] & kmask_iq2xs[j+4] ? -1 : 1);
1125                }
1126                q8 += 8;
1127            }
1128            qs += 8;
1129            signs += 4;
1130            bsum += sumi * ls1;
1131            sumi = 0;
1132            for (int l = 0; l < 4; ++l) {
1133                const uint8_t * grid1 = (const uint8_t *)(iq3s_grid + (qs[2*l+0] | ((qh[ib32+1] << (8-2*l)) & 256)));
1134                const uint8_t * grid2 = (const uint8_t *)(iq3s_grid + (qs[2*l+1] | ((qh[ib32+1] << (7-2*l)) & 256)));
1135                for (int j = 0; j < 4; ++j) {
1136                    sumi += grid1[j] * q8[j+0] * (signs[l] & kmask_iq2xs[j+0] ? -1 : 1);
1137                    sumi += grid2[j] * q8[j+4] * (signs[l] & kmask_iq2xs[j+4] ? -1 : 1);
1138                }
1139                q8 += 8;
1140            }
1141            qs += 8;
1142            signs += 4;
1143            bsum += sumi * ls2;
1144        }
1145        sumf += d * bsum;
1146    }
1147    *s = sumf;
1148}
1149
1150void ggml_vec_dot_iq1_s_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
1151    assert(n % QK_K == 0);
1152    assert(nrc == 1);
1153    UNUSED(nrc);
1154    UNUSED(bx);
1155    UNUSED(by);
1156    UNUSED(bs);
1157
1158    const block_iq1_s * GGML_RESTRICT x = vx;
1159    const block_q8_K  * GGML_RESTRICT y = vy;
1160
1161    const int nb = n / QK_K;
1162
1163    float sumf = 0;
1164    for (int i = 0; i < nb; i++) {
1165
1166        const int8_t   * q8 = y[i].qs;
1167        const uint8_t  * qs = x[i].qs;
1168        const uint16_t * qh = x[i].qh;
1169
1170        int sumi = 0, sumi1 = 0;
1171        for (int ib = 0; ib < QK_K/32; ++ib) {
1172            const int ls = 2*((qh[ib] >> 12) & 7) + 1;
1173            const int delta = qh[ib] & 0x8000 ? -1 : 1;
1174            int lsum = 0;
1175            for (int l = 0; l < 4; ++l) {
1176                const int8_t * grid = (const int8_t *)(iq1s_grid + (qs[l] | (((qh[ib] >> 3*l) & 7) << 8)));
1177                for (int j = 0; j < 8; ++j) {
1178                    lsum += q8[j] * grid[j];
1179                }
1180                q8 += 8;
1181            }
1182            sumi  += ls * lsum;
1183            sumi1 += ls * delta * (y[i].bsums[2*ib+0] + y[i].bsums[2*ib+1]);
1184            qs += 4;
1185        }
1186
1187        sumf += GGML_CPU_FP16_TO_FP32(x[i].d) * y[i].d * (sumi + IQ1S_DELTA * sumi1);
1188    }
1189
1190    *s = sumf;
1191}
1192
1193void ggml_vec_dot_iq1_m_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
1194    assert(n % QK_K == 0);
1195    assert(nrc == 1);
1196    UNUSED(nrc);
1197    UNUSED(bx);
1198    UNUSED(by);
1199    UNUSED(bs);
1200
1201    const block_iq1_m * GGML_RESTRICT x = vx;
1202    const block_q8_K  * GGML_RESTRICT y = vy;
1203
1204    const int nb = n / QK_K;
1205
1206    iq1m_scale_t scale;
1207
1208    int sum1[2], sum2[2], delta[4];
1209
1210    float sumf = 0;
1211    for (int i = 0; i < nb; i++) {
1212
1213        const int8_t   * q8 = y[i].qs;
1214        const uint8_t  * qs = x[i].qs;
1215        const uint8_t  * qh = x[i].qh;
1216        const uint16_t * sc = (const uint16_t *)x[i].scales;
1217
1218        scale.u16 = (sc[0] >> 12) | ((sc[1] >> 8) & 0x00f0) | ((sc[2] >> 4) & 0x0f00) | (sc[3] & 0xf000);
1219
1220        int sumi1 = 0, sumi2 = 0;
1221        for (int ib = 0; ib < QK_K/32; ++ib) {
1222            delta[0] = qh[0] & 0x08 ? -1 : 1;
1223            delta[1] = qh[0] & 0x80 ? -1 : 1;
1224            delta[2] = qh[1] & 0x08 ? -1 : 1;
1225            delta[3] = qh[1] & 0x80 ? -1 : 1;
1226            sum1[0] = sum1[1] = sum2[0] = sum2[1] = 0;
1227            for (int l = 0; l < 4; ++l) {
1228                const int8_t * grid = (const int8_t *)(iq1s_grid + (qs[l] | (((uint16_t)qh[l/2] << (8 - 4*(l%2))) & 0x700)));
1229                int lsum1 = 0, lsum2 = 0;
1230                for (int j = 0; j < 8; ++j) {
1231                    lsum1 += q8[j] * grid[j];
1232                    lsum2 += q8[j];
1233                }
1234                q8 += 8;
1235                sum1[l/2] += lsum1;
1236                sum2[l/2] += lsum2*delta[l];
1237            }
1238
1239            const int ls1 = 2*((sc[ib/2] >> (6*(ib%2)+0)) & 0x7) + 1;
1240            const int ls2 = 2*((sc[ib/2] >> (6*(ib%2)+3)) & 0x7) + 1;
1241
1242            sumi1 += sum1[0] * ls1 + sum1[1] * ls2;
1243            sumi2 += sum2[0] * ls1 + sum2[1] * ls2;
1244            qs += 4;
1245            qh += 2;
1246        }
1247
1248        sumf += GGML_CPU_FP16_TO_FP32(scale.f16) * y[i].d * (sumi1 + IQ1M_DELTA * sumi2);
1249    }
1250
1251    *s = sumf;
1252}
1253
1254void ggml_vec_dot_iq4_nl_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
1255    assert(nrc == 1);
1256    UNUSED(nrc);
1257    UNUSED(bx);
1258    UNUSED(by);
1259    UNUSED(bs);
1260    assert(n % QK4_NL == 0);
1261    static_assert(QK4_NL == QK8_0, "QK4_NL and QK8_0 must be the same");
1262
1263    const block_iq4_nl * GGML_RESTRICT x = vx;
1264    const block_q8_0   * GGML_RESTRICT y = vy;
1265
1266    const int nb = n / QK4_NL;
1267
1268    int ib = 0;
1269    float sumf = 0;
1270
1271    for (; ib < nb; ++ib) {
1272        const float d = GGML_CPU_FP16_TO_FP32(y[ib].d)*GGML_CPU_FP16_TO_FP32(x[ib].d);
1273        int sumi1 = 0, sumi2 = 0;
1274        for (int j = 0; j < QK4_NL/2; ++j) {
1275            sumi1 += y[ib].qs[j+       0] * kvalues_iq4nl[x[ib].qs[j] & 0xf];
1276            sumi2 += y[ib].qs[j+QK4_NL/2] * kvalues_iq4nl[x[ib].qs[j] >>  4];
1277        }
1278        sumf += d * (sumi1 + sumi2);
1279    }
1280    *s = sumf;
1281}
1282
1283void ggml_vec_dot_iq4_xs_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, size_t bx, const void * GGML_RESTRICT vy, size_t by, int nrc) {
1284    assert(nrc == 1);
1285    UNUSED(nrc);
1286    UNUSED(bx);
1287    UNUSED(by);
1288    UNUSED(bs);
1289    assert(n % QK_K == 0);
1290
1291    const block_iq4_xs * GGML_RESTRICT x = vx;
1292    const block_q8_K   * GGML_RESTRICT y = vy;
1293
1294    const int nb = n / QK_K;
1295
1296    float sumf = 0;
1297    for (int ibl = 0; ibl < nb; ++ibl) {
1298        const float d4d8 = GGML_CPU_FP16_TO_FP32(x[ibl].d) * y[ibl].d;
1299        uint16_t h = x[ibl].scales_h;
1300        const uint8_t * qs = x[ibl].qs;
1301        const int8_t  * q8 = y[ibl].qs;
1302        for (int ib = 0; ib < QK_K/32; ib += 2) {
1303            const uint8_t ls1 = (x[ibl].scales_l[ib/2] & 0xf) | ((h << 4) & 0x30);
1304            const uint8_t ls2 = (x[ibl].scales_l[ib/2] >>  4) | ((h << 2) & 0x30);
1305            h >>= 4;
1306            const float d1 = d4d8*(ls1 - 32);
1307            const float d2 = d4d8*(ls2 - 32);
1308            int sumi1 = 0, sumi2 = 0;
1309            for (int j = 0; j < 16; ++j) {
1310                sumi1 += q8[j+ 0] * kvalues_iq4nl[qs[j] & 0xf];
1311                sumi2 += q8[j+16] * kvalues_iq4nl[qs[j] >>  4];
1312            }
1313            sumf += d1 * (sumi1 + sumi2);
1314            qs += 16;
1315            q8 += 32;
1316            sumi1 = sumi2 = 0;
1317            for (int j = 0; j < 16; ++j) {
1318                sumi1 += q8[j+ 0] * kvalues_iq4nl[qs[j] & 0xf];
1319                sumi2 += q8[j+16] * kvalues_iq4nl[qs[j] >>  4];
1320            }
1321            sumf += d2 * (sumi1 + sumi2);
1322            qs += 16;
1323            q8 += 32;
1324        }
1325    }
1326    *s = sumf;
1327}
1328
1329// ============================ 4-bit non-linear quants
1330
1331void quantize_row_iq4_nl(const float * GGML_RESTRICT x, void * GGML_RESTRICT y, int64_t k) {
1332    assert(k % QK4_NL == 0);
1333    quantize_row_iq4_nl_ref(x, y, k);
1334}
1335
1336void quantize_row_iq4_xs(const float * GGML_RESTRICT x, void * GGML_RESTRICT y, int64_t k) {
1337    assert(k % QK_K == 0);
1338    quantize_iq4_xs(x, y, 1, k, NULL);
1339}