Coverage Report

Created: 2026-07-16 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/llama.cpp/ggml/src/ggml-cpu/repack.cpp
Line
Count
Source
1
#define GGML_COMMON_IMPL_CPP
2
#define GGML_COMMON_DECL_CPP
3
#include "ggml-common.h"
4
#include "ggml-backend-impl.h"
5
6
#include "ggml-impl.h"
7
#include "ggml-cpu.h"
8
#include "ggml-cpu-impl.h"
9
#include "simd-mappings.h"
10
#include "traits.h"
11
12
#include "arch-fallback.h"
13
14
#include <cmath>
15
#include <cstring>
16
#include <cassert>
17
#include <cstdio>  // for GGML_ASSERT
18
19
#include "repack.h"
20
21
#if defined(__GNUC__)
22
#pragma GCC diagnostic ignored "-Woverlength-strings"
23
#endif
24
25
0
#define UNUSED GGML_UNUSED
26
27
0
static inline int nearest_int(float fval) {
28
0
    assert(fabsf(fval) <= 4194303.f);
29
0
    float val = fval + 12582912.f;
30
0
    int i; memcpy(&i, &val, sizeof(int));
31
0
    return (i & 0x007fffff) - 0x00400000;
32
0
}
33
34
// Functions to create the interleaved data layout formats
35
36
// interleave 4 block_q4_0s in blocks of blck_size_interleave
37
// returns an interleaved block_q4_0x4
38
// in the interleaved block_q4_0x4, place deltas for 4 block_q4_0 blocks
39
// first, then interleave quants from 4 block_q4_0s in blocks of blck_size_interleave
40
//
41
// - in                  : an array of block_q4_0 pointers
42
// - blck_size_interleave : the block_q4_0 quants bytes are interleaved in blocks of
43
//                         blck_size_interleave bytes
44
// - xor_mask            : the mask to convert the nibbles in block_q4_0 quants bytes
45
//                         from bias offset form to pure sign form (this saves subtract
46
//                         operations durin unpacking)
47
//
48
49
extern "C" {
50
51
#if defined __riscv_zvfh
52
void ggml_quantize_mat_q8_0_4x1_generic(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t k) {
53
    assert(QK8_0 == 32);
54
    assert(k % QK8_0 == 0);
55
    const int nb = k / QK8_0;
56
57
    block_q8_0x4 * GGML_RESTRICT y = (block_q8_0x4 *) vy;
58
59
    // scalar
60
    const int blck_size_interleave = 1;
61
    float srcv[4][QK8_0];
62
    float id[4];
63
64
    for (int i = 0; i < nb; i++) {
65
        for (int row_iter = 0; row_iter < 4; row_iter++) {
66
            float amax = 0.0f; // absolute max
67
68
            for (int j = 0; j < QK8_0; j++) {
69
                srcv[row_iter][j] = x[row_iter * k + i * QK8_0 + j];
70
                amax = MAX(amax, fabsf(srcv[row_iter][j]));
71
            }
72
73
            const float d = amax / ((1 << 7) - 1);
74
            id[row_iter] = d ? 1.0f / d : 0.0f;
75
76
            y[i].d[row_iter] = GGML_CPU_FP32_TO_FP16(d);
77
        }
78
79
        for (int j = 0; j < QK8_0 * 4; j++) {
80
            int src_offset = (j / (4 * blck_size_interleave)) * blck_size_interleave;
81
            int src_id = (j % (4 * blck_size_interleave)) / blck_size_interleave;
82
            src_offset += (j % blck_size_interleave);
83
84
            float x0 = srcv[src_id][src_offset] * id[src_id];
85
            y[i].qs[j] = roundf(x0);
86
        }
87
    }
88
}
89
90
void ggml_quantize_mat_q8_K_4x1_generic(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t k) {
91
    assert(QK_K == 256);
92
    assert(k % QK_K == 0);
93
    const int nb = k / QK_K;
94
95
    block_q8_Kx4 * GGML_RESTRICT y = (block_q8_Kx4 *) vy;
96
97
    const int blck_size_interleave = 1;
98
    float srcv[4][QK_K];
99
    float iscale[4];
100
101
    for (int i = 0; i < nb; i++) {
102
        for (int row_iter = 0; row_iter < 4; row_iter++) {
103
            float amax = 0.0f; // absolute max
104
            float max = 0;
105
106
            for (int j = 0; j < QK_K; j++) {
107
                srcv[row_iter][j] = x[row_iter * k + i * QK_K + j];
108
                // Update the maximum value of the corresponding super block
109
                if(amax < fabsf(srcv[row_iter][j])) {
110
                    amax = fabsf(srcv[row_iter][j]);
111
                    max = srcv[row_iter][j];
112
                }
113
            }
114
115
            iscale[row_iter] = amax ? -127.f/max : 0;
116
            y[i].d[row_iter] = amax ? 1/iscale[row_iter] : 0;
117
        }
118
119
        for (int j = 0; j < QK_K / 4; j++) {
120
            y[i].bsums[j] = 0;
121
        }
122
        for (int j = 0; j < QK_K * 4; j++) {
123
            int src_id = j % 4;
124
            int src_offset = j / 4;
125
            int index = ((j >> 6) << 2) + (j & 3);
126
127
            float x0 = srcv[src_id][src_offset] * iscale[src_id];
128
            y[i].qs[j] = nearest_int(x0);
129
            y[i].bsums[index] += y[i].qs[j];
130
        }
131
    }
132
}
133
#endif
134
135
0
void ggml_quantize_mat_q8_0_4x4_generic(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t k) {
136
0
    assert(QK8_0 == 32);
137
0
    assert(k % QK8_0 == 0);
138
0
    const int nb = k / QK8_0;
139
140
0
    block_q8_0x4 * GGML_RESTRICT y = (block_q8_0x4 *) vy;
141
142
    // scalar
143
0
    const int blck_size_interleave = 4;
144
0
    float srcv[4][QK8_0];
145
0
    float id[4];
146
147
0
    for (int i = 0; i < nb; i++) {
148
0
        for (int row_iter = 0; row_iter < 4; row_iter++) {
149
0
            float amax = 0.0f; // absolute max
150
151
0
            for (int j = 0; j < QK8_0; j++) {
152
0
                srcv[row_iter][j] = x[row_iter * k + i * QK8_0 + j];
153
0
                amax = MAX(amax, fabsf(srcv[row_iter][j]));
154
0
            }
155
156
0
            const float d = amax / ((1 << 7) - 1);
157
0
            id[row_iter] = d ? 1.0f / d : 0.0f;
158
159
0
            y[i].d[row_iter] = GGML_CPU_FP32_TO_FP16(d);
160
0
        }
161
162
0
        for (int j = 0; j < QK8_0 * 4; j++) {
163
0
            int src_offset = (j / (4 * blck_size_interleave)) * blck_size_interleave;
164
0
            int src_id = (j % (4 * blck_size_interleave)) / blck_size_interleave;
165
0
            src_offset += (j % blck_size_interleave);
166
167
0
            float x0 = srcv[src_id][src_offset] * id[src_id];
168
0
            y[i].qs[j] = roundf(x0);
169
0
        }
170
0
    }
171
0
}
172
173
0
void ggml_quantize_mat_q8_0_4x8_generic(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t k) {
174
0
    assert(QK8_0 == 32);
175
0
    assert(k % QK8_0 == 0);
176
0
    const int nb = k / QK8_0;
177
178
0
    block_q8_0x4 * GGML_RESTRICT y = (block_q8_0x4 *) vy;
179
180
    // scalar
181
0
    const int blck_size_interleave = 8;
182
0
    float srcv[4][QK8_0];
183
0
    float id[4];
184
185
0
    for (int i = 0; i < nb; i++) {
186
0
        for (int row_iter = 0; row_iter < 4; row_iter++) {
187
0
            float amax = 0.0f; // absolute max
188
189
0
            for (int j = 0; j < QK8_0; j++) {
190
0
                srcv[row_iter][j] = x[row_iter * k + i * QK8_0 + j];
191
0
                amax = MAX(amax, fabsf(srcv[row_iter][j]));
192
0
            }
193
194
0
            const float d = amax / ((1 << 7) - 1);
195
0
            id[row_iter] = d ? 1.0f / d : 0.0f;
196
197
0
            y[i].d[row_iter] = GGML_CPU_FP32_TO_FP16(d);
198
0
        }
199
200
0
        for (int j = 0; j < QK8_0 * 4; j++) {
201
0
            int src_offset = (j / (4 * blck_size_interleave)) * blck_size_interleave;
202
0
            int src_id = (j % (4 * blck_size_interleave)) / blck_size_interleave;
203
0
            src_offset += (j % blck_size_interleave);
204
205
0
            float x0 = srcv[src_id][src_offset] * id[src_id];
206
0
            y[i].qs[j] = roundf(x0);
207
0
        }
208
0
    }
209
0
}
210
211
0
void ggml_quantize_mat_q8_K_4x4_generic(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t k) {
212
0
    assert(QK_K == 256);
213
0
    assert(k % QK_K == 0);
214
0
    const int nb = k / QK_K;
215
216
0
    block_q8_Kx4 * GGML_RESTRICT y = (block_q8_Kx4 *) vy;
217
218
    // scalar
219
0
    const int blck_size_interleave = 4;
220
0
    float srcv[4][QK_K];
221
0
    float iscale[4];
222
223
0
    for (int i = 0; i < nb; i++) {
224
0
        for (int row_iter = 0; row_iter < 4; row_iter++) {
225
0
            float amax = 0.0f; // absolute max
226
0
            float max = 0;
227
228
0
            for (int j = 0; j < QK_K; j++) {
229
0
                srcv[row_iter][j] = x[row_iter * k + i * QK_K + j];
230
                // Update the maximum value of the corresponding super block
231
0
                if(amax < fabsf(srcv[row_iter][j])) {
232
0
                    amax = fabsf(srcv[row_iter][j]);
233
0
                    max = srcv[row_iter][j];
234
0
                }
235
0
            }
236
237
0
            iscale[row_iter] = amax ? -127.f/max : 0;
238
239
0
            y[i].d[row_iter] = amax ? 1/iscale[row_iter] : 0;
240
0
        }
241
242
0
        for (int j = 0; j < QK_K / 4; j++) {
243
0
            y[i].bsums[j] = 0;
244
0
        }
245
246
        // Quants values are interleaved in sequence of four bytes from corresponding super blocks
247
        // Bsums values are interleaved in sequence of four bsums from each super block taken for interleaving
248
        // i.e first four bsums from the first super block, followed by first four bsums from second super block and so on
249
0
        for (int j = 0; j < QK_K * 4; j++) {
250
0
            int src_offset = (j / (4 * blck_size_interleave)) * blck_size_interleave;
251
0
            int src_id     = (j % (4 * blck_size_interleave)) / blck_size_interleave;
252
0
            src_offset += (j % blck_size_interleave);
253
0
            int index = (((j & 15) >> 2) << 2) + ((j >> 8) << 4) + ((j >> 6) & 3);
254
255
0
            float x0 = srcv[src_id][src_offset] * iscale[src_id];
256
0
            y[i].qs[j] = nearest_int(x0);
257
0
            y[i].bsums[index] += y[i].qs[j];
258
0
        }
259
0
    }
260
0
}
261
262
0
void ggml_quantize_mat_q8_K_4x8_generic(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t k) {
263
0
    assert(QK_K == 256);
264
0
    assert(k % QK_K == 0);
265
0
    const int nb = k / QK_K;
266
267
0
    block_q8_Kx4 * GGML_RESTRICT y = (block_q8_Kx4 *) vy;
268
269
    // scalar
270
0
    const int blck_size_interleave = 8;
271
0
    float srcv[4][QK_K];
272
0
    float iscale[4];
273
274
0
    for (int i = 0; i < nb; i++) {
275
0
        for (int row_iter = 0; row_iter < 4; row_iter++) {
276
0
            float amax = 0.0f; // absolute max
277
0
            float max = 0;
278
279
0
            for (int j = 0; j < QK_K; j++) {
280
0
                srcv[row_iter][j] = x[row_iter * k + i * QK_K + j];
281
                // Update the maximum value of the corresponding super block
282
0
                if(amax < fabsf(srcv[row_iter][j])) {
283
0
                    amax = fabsf(srcv[row_iter][j]);
284
0
                    max = srcv[row_iter][j];
285
0
                }
286
0
            }
287
288
0
            iscale[row_iter] = amax ? -127.f/max : 0;
289
290
0
            y[i].d[row_iter] = amax ? 1/iscale[row_iter] : 0;
291
0
        }
292
293
0
        for (int j = 0; j < QK_K / 4; j++) {
294
0
            y[i].bsums[j] = 0;
295
0
        }
296
297
        // Quants values are interleaved in sequence of eight bytes from corresponding super blocks
298
        // Bsums values are interleaved in sequence of four bsums from each super block taken for interleaving
299
        // i.e first four bsums from the first super block, followed by first four bsums from second super block and so on
300
0
        for (int j = 0; j < QK_K * 4; j++) {
301
0
            int src_offset = (j / (4 * blck_size_interleave)) * blck_size_interleave;
302
0
            int src_id     = (j % (4 * blck_size_interleave)) / blck_size_interleave;
303
0
            src_offset += (j % blck_size_interleave);
304
0
            int index = (((j & 31) >> 3) << 2) + ((j >> 8) << 4) + ((j >> 6) & 3);
305
306
0
            float x0 = srcv[src_id][src_offset] * iscale[src_id];
307
0
            y[i].qs[j] = nearest_int(x0);
308
0
            y[i].bsums[index] += y[i].qs[j];
309
0
        }
310
0
    }
311
0
}
312
313
} // extern "C"
314
315
template <int64_t INTER_SIZE, ggml_type PARAM_TYPE>
316
void ggml_quantize_mat_t(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t nrow, int64_t n_per_row);
317
318
0
template <> void ggml_quantize_mat_t<4, GGML_TYPE_Q8_0>(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t nrow, int64_t n_per_row) {
319
0
    assert(nrow == 4);
320
0
    UNUSED(nrow);
321
0
    ggml_quantize_mat_q8_0_4x4(x, vy, n_per_row);
322
0
}
323
324
0
template <> void ggml_quantize_mat_t<8, GGML_TYPE_Q8_0>(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t nrow, int64_t n_per_row) {
325
0
    assert(nrow == 4);
326
0
    UNUSED(nrow);
327
0
    ggml_quantize_mat_q8_0_4x8(x, vy, n_per_row);
328
0
}
329
330
0
template <> void ggml_quantize_mat_t<4, GGML_TYPE_Q8_K>(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t nrow, int64_t n_per_row) {
331
0
    assert(nrow == 4);
332
0
    UNUSED(nrow);
333
0
    ggml_quantize_mat_q8_K_4x4(x, vy, n_per_row);
334
0
}
335
336
0
template <> void ggml_quantize_mat_t<8, GGML_TYPE_Q8_K>(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t nrow, int64_t n_per_row) {
337
0
    assert(nrow == 4);
338
0
    UNUSED(nrow);
339
0
    ggml_quantize_mat_q8_K_4x8(x, vy, n_per_row);
340
0
}
341
342
#if defined __riscv_zvfh
343
template <> void ggml_quantize_mat_t<1, GGML_TYPE_Q8_0>(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t nrow, int64_t n_per_row) {
344
    assert(nrow == 4);
345
    UNUSED(nrow);
346
    ggml_quantize_mat_q8_0_4x1(x, vy, n_per_row);
347
}
348
349
template <> void ggml_quantize_mat_t<1, GGML_TYPE_Q8_K>(const float * GGML_RESTRICT x, void * GGML_RESTRICT vy, int64_t nrow, int64_t n_per_row) {
350
    assert(nrow == 4);
351
    UNUSED(nrow);
352
    ggml_quantize_mat_q8_K_4x1(x, vy, n_per_row);
353
}
354
#endif
355
356
template <int M, int N>
357
static void ggml_gemv_q6_K_NxM_q8_K_generic_impl(int                        n,
358
                                                 float * GGML_RESTRICT      s,
359
                                                 size_t                     bs,
360
                                                 const void * GGML_RESTRICT vx,
361
                                                 const void * GGML_RESTRICT vy,
362
                                                 int                        nr,
363
0
                                                 int                        nc) {
364
0
    constexpr int blocklen          = M;
365
0
    constexpr int ncols_interleaved = N;
366
0
    const int     qk                = QK_K;
367
0
    const int     nb                = n / qk;
368
0
    const int     blocks_per_half   = 64 / blocklen;
369
370
0
    assert(n % qk == 0);
371
0
    assert(nc % ncols_interleaved == 0);
372
373
0
    UNUSED(bs);
374
0
    UNUSED(nr);
375
376
0
    float sumf[8];
377
378
0
    const block_q8_K * a_ptr = (const block_q8_K *) vy;
379
0
    for (int x = 0; x < nc / ncols_interleaved; x++) {
380
0
        const block_q6_Kx8 * b_ptr = (const block_q6_Kx8 *) vx + (x * nb);
381
382
0
        for (int j = 0; j < ncols_interleaved; j++) {
383
0
            sumf[j] = 0.0f;
384
0
        }
385
386
0
        for (int l = 0; l < nb; l++) {
387
0
            for (int k = 0; k < (qk / (2 * blocklen)); k++) {
388
0
                const int base_l = (k / blocks_per_half) * 128 + (k % blocks_per_half) * blocklen;
389
0
                const int base_h = base_l + 64;
390
391
0
                const int scale_idx_l = base_l / 16;
392
0
                const int scale_idx_h = base_h / 16;
393
394
0
                const int qh_shift_l = ((base_l % 128) / 32) * 2;
395
0
                const int qh_shift_h = ((base_h % 128) / 32) * 2;
396
397
0
                const int qh_half_l = (base_l / 128) * 32;
398
0
                const int qh_half_h = (base_h / 128) * 32;
399
400
0
                for (int j = 0; j < ncols_interleaved; j++) {
401
0
                    const int8_t scale_l = b_ptr[l].scales[scale_idx_l * ncols_interleaved + j];
402
0
                    const int8_t scale_h = b_ptr[l].scales[scale_idx_h * ncols_interleaved + j];
403
404
0
                    int sumi_l = 0;
405
0
                    int sumi_h = 0;
406
407
0
                    for (int i = 0; i < blocklen; i++) {
408
0
                        const int ql_pos = k * ncols_interleaved * blocklen + j * blocklen + i;
409
0
                        const int l_4    = b_ptr[l].ql[ql_pos] & 0xF;
410
0
                        const int hi_4   = (b_ptr[l].ql[ql_pos] >> 4) & 0xF;
411
412
0
                        const int qh_idx_l    = qh_half_l + ((base_l + i) % 32);
413
0
                        const int qh_chunk_l  = qh_idx_l / blocklen;
414
0
                        const int qh_pos_l    = qh_idx_l % blocklen;
415
0
                        const int qh_offset_l = qh_chunk_l * (blocklen * ncols_interleaved) + j * blocklen + qh_pos_l;
416
0
                        const int hi_2_l      = (b_ptr[l].qh[qh_offset_l] >> qh_shift_l) & 0x3;
417
418
0
                        const int qh_idx_h    = qh_half_h + ((base_h + i) % 32);
419
0
                        const int qh_chunk_h  = qh_idx_h / blocklen;
420
0
                        const int qh_pos_h    = qh_idx_h % blocklen;
421
0
                        const int qh_offset_h = qh_chunk_h * (blocklen * ncols_interleaved) + j * blocklen + qh_pos_h;
422
0
                        const int hi_2_h      = (b_ptr[l].qh[qh_offset_h] >> qh_shift_h) & 0x3;
423
424
0
                        const int q_l = ((hi_2_l << 4) | l_4) - 32;
425
0
                        const int q_h = ((hi_2_h << 4) | hi_4) - 32;
426
427
0
                        const int8_t a_l = a_ptr[l].qs[base_l + i];
428
0
                        const int8_t a_h = a_ptr[l].qs[base_h + i];
429
430
0
                        sumi_l += q_l * a_l;
431
0
                        sumi_h += q_h * a_h;
432
0
                    }
433
434
0
                    sumf[j] +=
435
0
                        (sumi_l * scale_l + sumi_h * scale_h) * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * a_ptr[l].d;
436
0
                }
437
0
            }
438
0
        }
439
440
0
        for (int j = 0; j < ncols_interleaved; j++) {
441
0
            s[x * ncols_interleaved + j] = sumf[j];
442
0
        }
443
0
    }
444
0
}
Unexecuted instantiation: repack.cpp:void ggml_gemv_q6_K_NxM_q8_K_generic_impl<4, 8>(int, float*, unsigned long, void const*, void const*, int, int)
Unexecuted instantiation: repack.cpp:void ggml_gemv_q6_K_NxM_q8_K_generic_impl<8, 8>(int, float*, unsigned long, void const*, void const*, int, int)
445
446
template <int M, int N>
447
static void ggml_gemm_q6_K_NxM_q8_K_generic_impl(int                        n,
448
                                                 float * GGML_RESTRICT      s,
449
                                                 size_t                     bs,
450
                                                 const void * GGML_RESTRICT vx,
451
                                                 const void * GGML_RESTRICT vy,
452
                                                 int                        nr,
453
0
                                                 int                        nc) {
454
0
    constexpr int blocklen          = M;
455
0
    constexpr int ncols_interleaved = N;
456
0
    const int     qk                = QK_K;
457
0
    const int     nb                = n / qk;
458
0
    const int     blocks_per_half   = 64 / blocklen;
459
0
    const int     q8_half_stride    = 512;
460
0
    const int     q8_low_high_step  = 256;
461
462
0
    assert(n % qk == 0);
463
0
    assert(nr % 4 == 0);
464
0
    assert(nc % ncols_interleaved == 0);
465
466
0
    UNUSED(bs);
467
468
0
    float sumf[4][8];
469
470
0
    for (int y = 0; y < nr / 4; y++) {
471
0
        const block_q8_Kx4 * a_ptr = (const block_q8_Kx4 *) vy + (y * nb);
472
0
        for (int x = 0; x < nc / ncols_interleaved; x++) {
473
0
            const block_q6_Kx8 * b_ptr = (const block_q6_Kx8 *) vx + (x * nb);
474
475
0
            for (int m = 0; m < 4; m++) {
476
0
                for (int j = 0; j < ncols_interleaved; j++) {
477
0
                    sumf[m][j] = 0.0f;
478
0
                }
479
0
            }
480
481
0
            for (int l = 0; l < nb; l++) {
482
0
                for (int k = 0; k < (qk / (2 * blocklen)); k++) {
483
0
                    const int base_l = (k / blocks_per_half) * 128 + (k % blocks_per_half) * blocklen;
484
0
                    const int base_h = base_l + 64;
485
486
0
                    const int scale_idx_l = base_l / 16;
487
0
                    const int scale_idx_h = base_h / 16;
488
489
0
                    const int qh_shift_l = ((base_l % 128) / 32) * 2;
490
0
                    const int qh_shift_h = ((base_h % 128) / 32) * 2;
491
492
0
                    const int qh_half_l = (base_l / 128) * 32;
493
0
                    const int qh_half_h = (base_h / 128) * 32;
494
495
0
                    const int q8_base = (k / blocks_per_half) * q8_half_stride + (k % blocks_per_half) * (blocklen * 4);
496
497
0
                    for (int m = 0; m < 4; m++) {
498
0
                        for (int j = 0; j < ncols_interleaved; j++) {
499
0
                            const int8_t scale_l = b_ptr[l].scales[scale_idx_l * ncols_interleaved + j];
500
0
                            const int8_t scale_h = b_ptr[l].scales[scale_idx_h * ncols_interleaved + j];
501
502
0
                            int sumi_l = 0;
503
0
                            int sumi_h = 0;
504
505
0
                            for (int i = 0; i < blocklen; i++) {
506
0
                                const int ql_pos = k * ncols_interleaved * blocklen + j * blocklen + i;
507
0
                                const int l_4    = b_ptr[l].ql[ql_pos] & 0xF;
508
0
                                const int hi_4   = (b_ptr[l].ql[ql_pos] >> 4) & 0xF;
509
510
0
                                const int qh_idx_l   = qh_half_l + ((base_l + i) % 32);
511
0
                                const int qh_chunk_l = qh_idx_l / blocklen;
512
0
                                const int qh_pos_l   = qh_idx_l % blocklen;
513
0
                                const int qh_offset_l =
514
0
                                    qh_chunk_l * (blocklen * ncols_interleaved) + j * blocklen + qh_pos_l;
515
0
                                const int hi_2_l = (b_ptr[l].qh[qh_offset_l] >> qh_shift_l) & 0x3;
516
517
0
                                const int qh_idx_h   = qh_half_h + ((base_h + i) % 32);
518
0
                                const int qh_chunk_h = qh_idx_h / blocklen;
519
0
                                const int qh_pos_h   = qh_idx_h % blocklen;
520
0
                                const int qh_offset_h =
521
0
                                    qh_chunk_h * (blocklen * ncols_interleaved) + j * blocklen + qh_pos_h;
522
0
                                const int hi_2_h = (b_ptr[l].qh[qh_offset_h] >> qh_shift_h) & 0x3;
523
524
0
                                const int q_l = ((hi_2_l << 4) | l_4) - 32;
525
0
                                const int q_h = ((hi_2_h << 4) | hi_4) - 32;
526
527
0
                                const int8_t q8_l = a_ptr[l].qs[q8_base + m * blocklen + i];
528
0
                                const int8_t q8_h = a_ptr[l].qs[q8_base + m * blocklen + i + q8_low_high_step];
529
530
0
                                sumi_l += q_l * q8_l;
531
0
                                sumi_h += q_h * q8_h;
532
0
                            }
533
534
0
                            sumf[m][j] += (sumi_l * scale_l + sumi_h * scale_h) * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) *
535
0
                                          a_ptr[l].d[m];
536
0
                        }
537
0
                    }
538
0
                }
539
0
            }
540
541
0
            for (int m = 0; m < 4; m++) {
542
0
                for (int j = 0; j < ncols_interleaved; j++) {
543
0
                    s[(y * 4 + m) * bs + x * ncols_interleaved + j] = sumf[m][j];
544
0
                }
545
0
            }
546
0
        }
547
0
    }
548
0
}
Unexecuted instantiation: repack.cpp:void ggml_gemm_q6_K_NxM_q8_K_generic_impl<4, 8>(int, float*, unsigned long, void const*, void const*, int, int)
Unexecuted instantiation: repack.cpp:void ggml_gemm_q6_K_NxM_q8_K_generic_impl<8, 8>(int, float*, unsigned long, void const*, void const*, int, int)
549
550
template <int M, int N>
551
static void ggml_gemv_q5_K_NxM_q8_K_generic_impl(int                        n,
552
                                                 float * GGML_RESTRICT      s,
553
                                                 size_t                     bs,
554
                                                 const void * GGML_RESTRICT vx,
555
                                                 const void * GGML_RESTRICT vy,
556
                                                 int                        nr,
557
0
                                                 int                        nc) {
558
0
    constexpr int         blocklen          = M;
559
0
    constexpr int         ncols_interleaved = N;
560
0
    const int             qk                = QK_K;
561
0
    const int             nb                = n / qk;
562
0
    static const uint32_t kmask1            = 0x3f3f3f3f;
563
0
    static const uint32_t kmask2            = 0x0f0f0f0f;
564
0
    static const uint32_t kmask3            = 0x03030303;
565
566
0
    assert(n % qk == 0);
567
0
    assert(nc % ncols_interleaved == 0);
568
569
0
    UNUSED(bs);
570
0
    UNUSED(nr);
571
572
0
    float    sumf[ncols_interleaved];
573
0
    float    sum_minf[ncols_interleaved];
574
0
    uint32_t utmp[32];
575
0
    int      sumi1;
576
0
    int      sumi2;
577
0
    int      sumi;
578
579
0
    const block_q8_K * a_ptr = (const block_q8_K *) vy;
580
0
    for (int x = 0; x < nc / ncols_interleaved; x++) {
581
0
        const block_q5_Kx8 * b_ptr = (const block_q5_Kx8 *) vx + (x * nb);
582
583
0
        for (int j = 0; j < ncols_interleaved; j++) {
584
0
            sumf[j]     = 0.0;
585
0
            sum_minf[j] = 0.0;
586
0
        }
587
0
        for (int l = 0; l < nb; l++) {
588
0
            for (int sb = 0; sb < 8; sb++) {
589
0
                memcpy(utmp + sb * 4, b_ptr[l].scales + sb * K_SCALE_SIZE, K_SCALE_SIZE);
590
0
                utmp[sb * 4 + 3]      = ((utmp[sb * 4 + 2] >> 4) & kmask2) | (((utmp[sb * 4 + 1] >> 6) & kmask3) << 4);
591
0
                const uint32_t uaux_0 = utmp[sb * 4 + 1] & kmask1;
592
0
                utmp[sb * 4 + 1]      = (utmp[sb * 4 + 2] & kmask2) | (((utmp[sb * 4 + 0] >> 6) & kmask3) << 4);
593
0
                utmp[sb * 4 + 2]      = uaux_0;
594
0
                utmp[sb * 4 + 0] &= kmask1;
595
0
            }
596
0
            for (int k = 0; k < (qk / (2 * blocklen)); k++) {
597
0
                constexpr int scale_stride = 32;
598
0
                uint8_t *     scales_0     = (uint8_t *) utmp + (k / (32 / blocklen)) * scale_stride;
599
0
                uint8_t *     scales_1     = (uint8_t *) utmp + (k / (32 / blocklen)) * scale_stride + 16;
600
601
0
                const int qh_shift = (k / (32 / blocklen)) * 2;
602
0
                for (int j = 0; j < ncols_interleaved; j++) {
603
0
                    sumi1 = 0;
604
0
                    sumi2 = 0;
605
0
                    sumi  = 0;
606
0
                    for (int i = 0; i < blocklen; ++i) {
607
0
                        const int b_qs_offset = k * ncols_interleaved * blocklen + j * blocklen + i;
608
609
0
                        const int qh_idx      = (k * blocklen + i) % 32;
610
0
                        const int qh_chunk    = qh_idx / blocklen;
611
0
                        const int qh_pos      = qh_idx % blocklen;
612
0
                        const int b_qh_offset = qh_chunk * (blocklen * ncols_interleaved) + j * blocklen + qh_pos;
613
614
0
                        const uint8_t qh_val = b_ptr[l].qh[b_qh_offset];
615
0
                        const uint8_t h0     = (qh_val >> qh_shift) & 1;
616
0
                        const uint8_t h1     = (qh_val >> (qh_shift + 1)) & 1;
617
618
0
                        const int v0 = (int8_t) ((b_ptr[l].qs[b_qs_offset] & 0xF) | (h0 << 4));
619
0
                        const int v1 = (int8_t) ((b_ptr[l].qs[b_qs_offset] >> 4) | (h1 << 4));
620
621
0
                        const int q8_offset = (k / (32 / blocklen)) * 64 + (k % (32 / blocklen)) * blocklen + i;
622
623
0
                        sumi1 = (v0 * a_ptr[l].qs[q8_offset]);
624
0
                        sumi2 = (v1 * a_ptr[l].qs[q8_offset + 32]);
625
0
                        sumi1 = sumi1 * scales_0[j];
626
0
                        sumi2 = sumi2 * scales_1[j];
627
0
                        sumi += sumi1 + sumi2;
628
0
                    }
629
0
                    sumf[j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * a_ptr[l].d;
630
0
                }
631
0
            }
632
0
            for (int sb = 0; sb < 8; sb++) {
633
0
                uint8_t * mins = (uint8_t *) utmp + 8 + sb * 16;
634
0
                for (int j = 0; j < ncols_interleaved; j++) {
635
0
                    sum_minf[j] += mins[j] * (a_ptr[l].bsums[sb * 2] + a_ptr[l].bsums[sb * 2 + 1]) *
636
0
                                   GGML_CPU_FP16_TO_FP32(b_ptr[l].dmin[j]) * a_ptr[l].d;
637
0
                }
638
0
            }
639
0
        }
640
0
        for (int j = 0; j < ncols_interleaved; j++) {
641
0
            s[x * ncols_interleaved + j] = sumf[j] - sum_minf[j];
642
0
        }
643
0
    }
644
0
}
Unexecuted instantiation: repack.cpp:void ggml_gemv_q5_K_NxM_q8_K_generic_impl<4, 8>(int, float*, unsigned long, void const*, void const*, int, int)
Unexecuted instantiation: repack.cpp:void ggml_gemv_q5_K_NxM_q8_K_generic_impl<8, 8>(int, float*, unsigned long, void const*, void const*, int, int)
645
646
template <int M, int N>
647
static void ggml_gemm_q5_K_NxM_q8_K_generic_impl(int                        n,
648
                                                 float * GGML_RESTRICT      s,
649
                                                 size_t                     bs,
650
                                                 const void * GGML_RESTRICT vx,
651
                                                 const void * GGML_RESTRICT vy,
652
                                                 int                        nr,
653
0
                                                 int                        nc) {
654
0
    constexpr int         blocklen          = M;
655
0
    constexpr int         ncols_interleaved = N;
656
0
    const int             qk                = QK_K;
657
0
    const int             nb                = n / qk;
658
0
    static const uint32_t kmask1            = 0x3f3f3f3f;
659
0
    static const uint32_t kmask2            = 0x0f0f0f0f;
660
0
    static const uint32_t kmask3            = 0x03030303;
661
662
0
    assert(n % qk == 0);
663
0
    assert(nr % 4 == 0);
664
0
    assert(nc % ncols_interleaved == 0);
665
666
0
    float    sumf[4][ncols_interleaved];
667
0
    float    sum_minf[4][ncols_interleaved];
668
0
    uint32_t utmp[32];
669
0
    int      sumi1;
670
0
    int      sumi2;
671
0
    int      sumi;
672
673
0
    for (int y = 0; y < nr / 4; y++) {
674
0
        const block_q8_Kx4 * a_ptr = (const block_q8_Kx4 *) vy + (y * nb);
675
0
        for (int x = 0; x < nc / ncols_interleaved; x++) {
676
0
            const block_q5_Kx8 * b_ptr = (const block_q5_Kx8 *) vx + (x * nb);
677
0
            for (int m = 0; m < 4; m++) {
678
0
                for (int j = 0; j < ncols_interleaved; j++) {
679
0
                    sumf[m][j]     = 0.0;
680
0
                    sum_minf[m][j] = 0.0;
681
0
                }
682
0
            }
683
0
            for (int l = 0; l < nb; l++) {
684
0
                for (int sb = 0; sb < 8; sb++) {
685
0
                    memcpy(utmp + sb * 4, b_ptr[l].scales + sb * K_SCALE_SIZE, K_SCALE_SIZE);
686
0
                    utmp[sb * 4 + 3] = ((utmp[sb * 4 + 2] >> 4) & kmask2) | (((utmp[sb * 4 + 1] >> 6) & kmask3) << 4);
687
0
                    const uint32_t uaux_0 = utmp[sb * 4 + 1] & kmask1;
688
0
                    utmp[sb * 4 + 1]      = (utmp[sb * 4 + 2] & kmask2) | (((utmp[sb * 4 + 0] >> 6) & kmask3) << 4);
689
0
                    utmp[sb * 4 + 2]      = uaux_0;
690
0
                    utmp[sb * 4 + 0] &= kmask1;
691
0
                }
692
0
                for (int k = 0; k < (qk / (2 * blocklen)); k++) {
693
0
                    constexpr int scale_stride = 32;
694
0
                    uint8_t *     scales_0     = (uint8_t *) utmp + (k / (32 / blocklen)) * scale_stride;
695
0
                    uint8_t *     scales_1     = (uint8_t *) utmp + (k / (32 / blocklen)) * scale_stride + 16;
696
697
0
                    const int qh_shift = (k / (32 / blocklen)) * 2;
698
0
                    for (int m = 0; m < 4; m++) {
699
0
                        for (int j = 0; j < ncols_interleaved; j++) {
700
0
                            sumi1 = 0;
701
0
                            sumi2 = 0;
702
0
                            sumi  = 0;
703
0
                            for (int i = 0; i < blocklen; ++i) {
704
0
                                const int b_qs_offset = k * ncols_interleaved * blocklen + j * blocklen + i;
705
706
0
                                const int qh_idx   = (k * blocklen + i) % 32;
707
0
                                const int qh_chunk = qh_idx / blocklen;
708
0
                                const int qh_pos   = qh_idx % blocklen;
709
0
                                const int b_qh_offset =
710
0
                                    qh_chunk * (blocklen * ncols_interleaved) + j * blocklen + qh_pos;
711
712
0
                                const uint8_t qh_val = b_ptr[l].qh[b_qh_offset];
713
0
                                const uint8_t h0     = (qh_val >> qh_shift) & 1;
714
0
                                const uint8_t h1     = (qh_val >> (qh_shift + 1)) & 1;
715
716
0
                                const int v0 = (int8_t) ((b_ptr[l].qs[b_qs_offset] & 0xF) | (h0 << 4));
717
0
                                const int v1 = (int8_t) ((b_ptr[l].qs[b_qs_offset] >> 4) | (h1 << 4));
718
719
0
                                const int q8_offset = (k / (32 / blocklen)) * 256 +
720
0
                                                      (k % (32 / blocklen)) * 4 * blocklen + m * blocklen + i;
721
722
0
                                sumi1 = (v0 * a_ptr[l].qs[q8_offset]);
723
0
                                sumi2 = (v1 * a_ptr[l].qs[q8_offset + 128]);
724
0
                                sumi1 = sumi1 * scales_0[j];
725
0
                                sumi2 = sumi2 * scales_1[j];
726
0
                                sumi += sumi1 + sumi2;
727
0
                            }
728
0
                            sumf[m][j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * a_ptr[l].d[m];
729
0
                        }
730
0
                    }
731
0
                }
732
0
                for (int sb = 0; sb < 8; sb++) {
733
0
                    uint8_t * mins = (uint8_t *) utmp + 8 + sb * 16;
734
0
                    for (int m = 0; m < 4; m++) {
735
0
                        const int16_t * bsums = a_ptr[l].bsums + (sb * 8) + (m * 4) - ((sb % 2) * 6);
736
0
                        for (int j = 0; j < ncols_interleaved; j++) {
737
0
                            sum_minf[m][j] += mins[j] * (bsums[0] + bsums[1]) *
738
0
                                              GGML_CPU_FP16_TO_FP32(b_ptr[l].dmin[j]) * a_ptr[l].d[m];
739
0
                        }
740
0
                    }
741
0
                }
742
0
            }
743
0
            for (int m = 0; m < 4; m++) {
744
0
                for (int j = 0; j < ncols_interleaved; j++) {
745
0
                    s[(y * 4 + m) * bs + x * ncols_interleaved + j] = sumf[m][j] - sum_minf[m][j];
746
0
                }
747
0
            }
748
0
        }
749
0
    }
750
0
}
Unexecuted instantiation: repack.cpp:void ggml_gemm_q5_K_NxM_q8_K_generic_impl<4, 8>(int, float*, unsigned long, void const*, void const*, int, int)
Unexecuted instantiation: repack.cpp:void ggml_gemm_q5_K_NxM_q8_K_generic_impl<8, 8>(int, float*, unsigned long, void const*, void const*, int, int)
751
752
extern "C" {
753
754
0
void ggml_gemv_q4_0_4x4_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
755
0
    const int qk = QK8_0;
756
0
    const int nb = n / qk;
757
0
    const int ncols_interleaved = 4;
758
0
    const int blocklen = 4;
759
760
0
    assert(nr == 1);
761
0
    assert(n % qk == 0);
762
0
    assert(nc % ncols_interleaved == 0);
763
764
0
    UNUSED(s);
765
0
    UNUSED(bs);
766
0
    UNUSED(vx);
767
0
    UNUSED(vy);
768
0
    UNUSED(nr);
769
0
    UNUSED(nc);
770
0
    UNUSED(nb);
771
0
    UNUSED(ncols_interleaved);
772
0
    UNUSED(blocklen);
773
774
0
    float sumf[4];
775
0
    int sumi;
776
777
0
    const block_q8_0 * a_ptr = (const block_q8_0 *) vy;
778
0
    for (int x = 0; x < nc / ncols_interleaved; x++) {
779
0
        const block_q4_0x4 * b_ptr = (const block_q4_0x4 *) vx + (x * nb);
780
781
0
        for (int j = 0; j < ncols_interleaved; j++) sumf[j] = 0.0;
782
0
        for (int l = 0; l < nb; l++) {
783
0
            for (int k = 0; k < (qk / (2 * blocklen)); k++) {
784
0
                for (int j = 0; j < ncols_interleaved; j++) {
785
0
                    sumi = 0;
786
0
                    for (int i = 0; i < blocklen; ++i) {
787
0
                        const int v0 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] << 4);
788
0
                        const int v1 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0xF0);
789
0
                        sumi += ((v0 * a_ptr[l].qs[k * blocklen + i]) + (v1 * a_ptr[l].qs[k * blocklen + i + qk / 2])) >> 4;
790
0
                    }
791
0
                    sumf[j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d);
792
0
                }
793
0
            }
794
0
        }
795
0
        for (int j = 0; j < ncols_interleaved; j++) s[x * ncols_interleaved + j] = sumf[j];
796
0
    }
797
0
}
798
799
0
void ggml_gemv_q4_0_4x8_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
800
0
    const int qk = QK8_0;
801
0
    const int nb = n / qk;
802
0
    const int ncols_interleaved = 4;
803
0
    const int blocklen = 8;
804
805
0
    assert (n % qk == 0);
806
0
    assert (nc % ncols_interleaved == 0);
807
808
0
    UNUSED(s);
809
0
    UNUSED(bs);
810
0
    UNUSED(vx);
811
0
    UNUSED(vy);
812
0
    UNUSED(nr);
813
0
    UNUSED(nc);
814
0
    UNUSED(nb);
815
0
    UNUSED(ncols_interleaved);
816
0
    UNUSED(blocklen);
817
818
0
    float sumf[4];
819
0
    int sumi;
820
821
0
    const block_q8_0 * a_ptr = (const block_q8_0 *) vy;
822
0
    for (int x = 0; x < nc / ncols_interleaved; x++) {
823
0
        const block_q4_0x4 * b_ptr = (const block_q4_0x4 *) vx + (x * nb);
824
825
0
        for (int j = 0; j < ncols_interleaved; j++) sumf[j] = 0.0;
826
0
        for (int l = 0; l < nb; l++) {
827
0
            for (int k = 0; k < (qk / (2 * blocklen)); k++) {
828
0
                for (int j = 0; j < ncols_interleaved; j++) {
829
0
                    sumi = 0;
830
0
                    for (int i = 0; i < blocklen; ++i) {
831
0
                        const int v0 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] << 4);
832
0
                        const int v1 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0xF0);
833
0
                        sumi += ((v0 * a_ptr[l].qs[k * blocklen + i]) + (v1 * a_ptr[l].qs[k * blocklen + i + qk / 2])) >> 4;
834
0
                    }
835
0
                    sumf[j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d);
836
0
                }
837
0
            }
838
0
        }
839
0
        for (int j = 0; j < ncols_interleaved; j++) s[x * ncols_interleaved + j] = sumf[j];
840
0
    }
841
0
}
842
843
0
void ggml_gemv_q4_0_8x8_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
844
0
    const int qk = QK8_0;
845
0
    const int nb = n / qk;
846
0
    const int ncols_interleaved = 8;
847
0
    const int blocklen = 8;
848
849
0
    assert (n % qk == 0);
850
0
    assert (nc % ncols_interleaved == 0);
851
852
0
    UNUSED(s);
853
0
    UNUSED(bs);
854
0
    UNUSED(vx);
855
0
    UNUSED(vy);
856
0
    UNUSED(nr);
857
0
    UNUSED(nc);
858
0
    UNUSED(nb);
859
0
    UNUSED(ncols_interleaved);
860
0
    UNUSED(blocklen);
861
862
0
    float sumf[8];
863
0
    int sumi;
864
865
0
    const block_q8_0 * a_ptr = (const block_q8_0 *) vy;
866
0
    for (int x = 0; x < nc / ncols_interleaved; x++) {
867
0
        const block_q4_0x8 * b_ptr = (const block_q4_0x8 *) vx + (x * nb);
868
869
0
        for (int j = 0; j < ncols_interleaved; j++) sumf[j] = 0.0;
870
0
        for (int l = 0; l < nb; l++) {
871
0
            for (int k = 0; k < (qk / (2 * blocklen)); k++) {
872
0
                for (int j = 0; j < ncols_interleaved; j++) {
873
0
                    sumi = 0;
874
0
                    for (int i = 0; i < blocklen; ++i) {
875
0
                        const int v0 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] << 4);
876
0
                        const int v1 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0xF0);
877
0
                        sumi += ((v0 * a_ptr[l].qs[k * blocklen + i]) + (v1 * a_ptr[l].qs[k * blocklen + i + qk / 2])) >> 4;
878
0
                    }
879
0
                    sumf[j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d);
880
0
                }
881
0
            }
882
0
        }
883
0
        for (int j = 0; j < ncols_interleaved; j++) s[x * ncols_interleaved + j] = sumf[j];
884
0
    }
885
0
}
886
887
0
void ggml_gemv_q4_K_8x4_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
888
0
    const int qk = QK_K;
889
0
    const int nb = n / qk;
890
0
    const int ncols_interleaved = 8;
891
0
    const int blocklen = 4;
892
0
    static const uint32_t kmask1 = 0x3f3f3f3f;
893
0
    static const uint32_t kmask2 = 0x0f0f0f0f;
894
0
    static const uint32_t kmask3 = 0x03030303;
895
896
0
    assert (n % qk == 0);
897
0
    assert (nc % ncols_interleaved == 0);
898
899
0
    UNUSED(bs);
900
0
    UNUSED(nr);
901
902
0
    float sumf[8];
903
0
    float sum_minf[8];
904
0
    uint32_t utmp[32];
905
0
    int sumi1;
906
0
    int sumi2;
907
0
    int sumi;
908
909
0
    const block_q8_K * a_ptr = (const block_q8_K *) vy;
910
0
    for (int x = 0; x < nc / ncols_interleaved; x++) {
911
0
        const block_q4_Kx8 * b_ptr = (const block_q4_Kx8 *) vx + (x * nb);
912
913
0
        for (int j = 0; j < ncols_interleaved; j++) {
914
0
            sumf[j] = 0.0;
915
0
            sum_minf[j] = 0.0;
916
0
        }
917
0
        for (int l = 0; l < nb; l++) {
918
0
            for (int sb = 0; sb < 8; sb++) {
919
0
                memcpy(utmp + sb * 4, b_ptr[l].scales + sb * 12, 12);
920
0
                utmp[sb * 4 + 3] = ((utmp[sb * 4 + 2] >> 4) & kmask2) | (((utmp[sb * 4 + 1] >> 6) & kmask3) << 4);
921
0
                const uint32_t uaux_0 = utmp[sb * 4 + 1] & kmask1;
922
0
                utmp[sb * 4 + 1] = (utmp[sb * 4 + 2] & kmask2) | (((utmp[sb * 4 + 0] >> 6) & kmask3) << 4);
923
0
                utmp[sb * 4 + 2] = uaux_0;
924
0
                utmp[sb * 4 + 0] &= kmask1;
925
0
            }
926
0
            for (int k = 0; k < (qk / (2 * blocklen)); k++) {
927
0
                uint8_t * scales_0 = (uint8_t *) utmp + (k / 8) * 32;
928
0
                uint8_t * scales_1 = (uint8_t *) utmp + (k / 8) * 32 + 16;
929
0
                for (int j = 0; j < ncols_interleaved; j++) {
930
0
                    sumi1 = 0;
931
0
                    sumi2 = 0;
932
0
                    sumi = 0;
933
0
                    for (int i = 0; i < blocklen; ++i) {
934
0
                        const int v0 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0xF);
935
0
                        const int v1 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] >> 4);
936
0
                        sumi1 = (v0 * a_ptr[l].qs[(k / 8) * 64 + (k % 8) * blocklen + i]);
937
0
                        sumi2 = (v1 * a_ptr[l].qs[(k / 8) * 64 + (k % 8) * blocklen + i + 32]);
938
0
                        sumi1 = sumi1 * scales_0[j];
939
0
                        sumi2 = sumi2 * scales_1[j];
940
0
                        sumi += sumi1 + sumi2;
941
0
                    }
942
0
                    sumf[j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * a_ptr[l].d;
943
0
                }
944
0
            }
945
0
            for (int sb = 0; sb < 8; sb++) {
946
0
                uint8_t * mins = (uint8_t *) utmp + 8 + sb * 16;
947
0
                for (int j = 0; j < ncols_interleaved; j++) {
948
0
                    sum_minf[j] += mins[j] * (a_ptr[l].bsums[sb * 2] + a_ptr[l].bsums[sb * 2 + 1]) * GGML_CPU_FP16_TO_FP32(b_ptr[l].dmin[j]) * a_ptr[l].d;
949
0
                }
950
0
            }
951
0
        }
952
0
        for (int j = 0; j < ncols_interleaved; j++) {
953
0
            s[x * ncols_interleaved + j] = sumf[j] - sum_minf[j];
954
0
        }
955
0
    }
956
0
}
957
958
0
void ggml_gemv_q4_K_8x8_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
959
0
    const int qk = QK_K;
960
0
    const int nb = n / qk;
961
0
    const int ncols_interleaved = 8;
962
0
    const int blocklen = 8;
963
0
    static const uint32_t kmask1 = 0x3f3f3f3f;
964
0
    static const uint32_t kmask2 = 0x0f0f0f0f;
965
0
    static const uint32_t kmask3 = 0x03030303;
966
967
0
    assert (n % qk == 0);
968
0
    assert (nc % ncols_interleaved == 0);
969
970
0
    UNUSED(bs);
971
0
    UNUSED(nr);
972
973
0
    float sumf[8];
974
0
    float sum_minf[8];
975
0
    uint32_t utmp[32];
976
0
    int sumi1;
977
0
    int sumi2;
978
0
    int sumi;
979
980
0
    const block_q8_K * a_ptr = (const block_q8_K *) vy;
981
0
    for (int x = 0; x < nc / ncols_interleaved; x++) {
982
0
        const block_q4_Kx8 * b_ptr = (const block_q4_Kx8 *) vx + (x * nb);
983
984
0
        for (int j = 0; j < ncols_interleaved; j++) {
985
0
            sumf[j] = 0.0;
986
0
            sum_minf[j] = 0.0;
987
0
        }
988
0
        for (int l = 0; l < nb; l++) {
989
0
            for (int sb = 0; sb < 8; sb++) {
990
0
                memcpy(utmp + sb * 4, b_ptr[l].scales + sb * 12, 12);
991
0
                utmp[sb * 4 + 3] = ((utmp[sb * 4 + 2] >> 4) & kmask2) | (((utmp[sb * 4 + 1] >> 6) & kmask3) << 4);
992
0
                const uint32_t uaux_0 = utmp[sb * 4 + 1] & kmask1;
993
0
                utmp[sb * 4 + 1] = (utmp[sb * 4 + 2] & kmask2) | (((utmp[sb * 4 + 0] >> 6) & kmask3) << 4);
994
0
                utmp[sb * 4 + 2] = uaux_0;
995
0
                utmp[sb * 4 + 0] &= kmask1;
996
0
            }
997
0
            for (int k = 0; k < (qk / (2 * blocklen)); k++) {
998
0
                uint8_t *scales_0 = (uint8_t*) utmp + (k / 4) * 32;
999
0
                uint8_t *scales_1 = (uint8_t*) utmp + (k / 4) * 32 + 16;
1000
0
                for (int j = 0; j < ncols_interleaved; j++) {
1001
0
                    sumi1 = 0;
1002
0
                    sumi2 = 0;
1003
0
                    sumi = 0;
1004
0
                    for (int i = 0; i < blocklen; ++i) {
1005
0
                        const int v0 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0xF);
1006
0
                        const int v1 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] >> 4);
1007
0
                        sumi1 = (v0 * a_ptr[l].qs[(k >> 2) * 64 + (k % 4) * blocklen + i]);
1008
0
                        sumi2 = (v1 * a_ptr[l].qs[(k >> 2) * 64 + (k % 4) * blocklen + i + 32]);
1009
0
                        sumi1 = sumi1 * scales_0[j];
1010
0
                        sumi2 = sumi2 * scales_1[j];
1011
0
                        sumi += sumi1 + sumi2;
1012
0
                    }
1013
0
                    sumf[j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * a_ptr[l].d;
1014
0
                }
1015
0
            }
1016
0
            for (int sb = 0; sb < 8; sb++) {
1017
0
                uint8_t *mins = (uint8_t*) utmp + 8 + sb * 16;
1018
0
                for (int j = 0; j < ncols_interleaved; j++) {
1019
0
                    sum_minf[j] += mins[j] * (a_ptr[l].bsums[sb * 2] + a_ptr[l].bsums[sb * 2 + 1]) * GGML_CPU_FP16_TO_FP32(b_ptr[l].dmin[j]) * a_ptr[l].d;
1020
0
                }
1021
0
            }
1022
0
        }
1023
0
        for (int j = 0; j < ncols_interleaved; j++) {
1024
0
            s[x * ncols_interleaved + j] = sumf[j] - sum_minf[j];
1025
0
        }
1026
0
    }
1027
0
}
1028
1029
0
void ggml_gemv_q2_K_8x8_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
1030
0
    const int qk = QK_K;
1031
0
    const int nb = n / qk;
1032
0
    const int ncols_interleaved = 8;
1033
0
    const int blocklen = 8;
1034
1035
0
    assert (n % qk == 0);
1036
0
    assert (nc % ncols_interleaved == 0);
1037
1038
0
    UNUSED(s);
1039
0
    UNUSED(bs);
1040
0
    UNUSED(vx);
1041
0
    UNUSED(vy);
1042
0
    UNUSED(nr);
1043
0
    UNUSED(nc);
1044
0
    UNUSED(nb);
1045
0
    UNUSED(ncols_interleaved);
1046
0
    UNUSED(blocklen);
1047
1048
0
    float sumf[8];
1049
0
    float sum_minf[8];
1050
0
    int sumi1,sumi2,sumi3,sumi4;
1051
0
    int sumi;
1052
1053
0
    const block_q8_K * a_ptr = (const block_q8_K *)vy;
1054
0
    for(int x = 0; x < nc / ncols_interleaved; x++) {
1055
0
        const block_q2_Kx8 * b_ptr = (const block_q2_Kx8 *) vx + (x * nb);
1056
0
        for (int j = 0; j < ncols_interleaved; j++) {
1057
0
            sumf[j] = 0.0;
1058
0
            sum_minf[j] = 0.0;
1059
0
        }
1060
0
        for (int l = 0; l < nb; l++) {
1061
0
            for (int k = 0; k < (qk / (4 * blocklen)); k++) {
1062
0
                const uint8_t *scales_0 = b_ptr[l].scales + (k / 4) * 64 ;
1063
0
                const uint8_t *scales_1 = b_ptr[l].scales + (k / 4) * 64 + 16;
1064
0
                const uint8_t *scales_2 = b_ptr[l].scales + (k / 4) * 64 + 32;
1065
0
                const uint8_t *scales_3 = b_ptr[l].scales + (k / 4) * 64 + 48;
1066
0
                for (int j = 0; j < ncols_interleaved; j++) {
1067
0
                    sumi1 = 0;
1068
0
                    sumi2 = 0;
1069
0
                    sumi3 = 0;
1070
0
                    sumi4 = 0;
1071
0
                    sumi = 0;
1072
0
                    int offset = ((k / 2) % 2) + j * 2;
1073
0
                    for (int i = 0; i < blocklen; ++i){
1074
0
                        const int v0 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 3);
1075
0
                        const int v1 = (int8_t) ((b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] >> 2 ) & 3);
1076
0
                        const int v2 = (int8_t) ((b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] >> 4 ) & 3);
1077
0
                        const int v3 = (int8_t) ((b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] >> 6 ) & 3);
1078
0
                        sumi1 = (v0 * a_ptr[l].qs[(k >> 2) * 128 + (k % 4) * blocklen + i]);
1079
0
                        sumi2 = (v1 * a_ptr[l].qs[(k >> 2) * 128 + (k % 4) * blocklen + i + 32]);
1080
0
                        sumi3 = (v2 * a_ptr[l].qs[(k >> 2) * 128 + (k % 4) * blocklen + i + 64]);
1081
0
                        sumi4 = (v3 * a_ptr[l].qs[(k >> 2) * 128 + (k % 4) * blocklen + i + 96]);
1082
1083
0
                        sumi1 = sumi1 * (scales_0[offset] & 0xF);
1084
0
                        sumi2 = sumi2 * (scales_1[offset] & 0xF);
1085
0
                        sumi3 = sumi3 * (scales_2[offset] & 0xF);
1086
0
                        sumi4 = sumi4 * (scales_3[offset] & 0xF);
1087
0
                        sumi += sumi1 + sumi2 + sumi3 + sumi4;
1088
0
                    }
1089
0
                    sumf[j] += sumi * GGML_FP16_TO_FP32(b_ptr[l].d[j]) * a_ptr[l].d;
1090
0
                }
1091
0
            }
1092
0
            for(int sb = 0; sb < 8; sb++) {
1093
0
                const uint8_t *mins = b_ptr[l].scales + sb * 16;
1094
0
                for(int j = 0; j < ncols_interleaved; j++){
1095
0
                    sum_minf[j] += ((mins[j * 2] >> 4) * a_ptr[l].bsums[sb * 2] + (mins[(j * 2)+ 1] >> 4) * a_ptr[l].bsums[sb * 2 + 1]) * GGML_FP16_TO_FP32(b_ptr[l].dmin[j]) * a_ptr[l].d;
1096
0
                }
1097
0
            }
1098
0
        }
1099
0
        for (int j = 0; j < ncols_interleaved; j++) {
1100
0
            s[x * ncols_interleaved + j] = sumf[j] - sum_minf[j];
1101
0
        }
1102
0
    }
1103
0
}
1104
1105
0
void ggml_gemv_q5_K_8x4_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
1106
0
    ggml_gemv_q5_K_NxM_q8_K_generic_impl<4, 8>(n, s, bs, vx, vy, nr, nc);
1107
0
}
1108
1109
0
void ggml_gemv_q5_K_8x8_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
1110
0
    ggml_gemv_q5_K_NxM_q8_K_generic_impl<8, 8>(n, s, bs, vx, vy, nr, nc);
1111
0
}
1112
1113
1114
0
void ggml_gemv_q6_K_8x4_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
1115
0
    ggml_gemv_q6_K_NxM_q8_K_generic_impl<4, 8>(n, s, bs, vx, vy, nr, nc);
1116
0
}
1117
1118
0
void ggml_gemv_q6_K_8x8_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
1119
0
    ggml_gemv_q6_K_NxM_q8_K_generic_impl<8, 8>(n, s, bs, vx, vy, nr, nc);
1120
0
}
1121
1122
0
void ggml_gemv_iq4_nl_4x4_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
1123
0
    const int qk = QK8_0;
1124
0
    const int nb = n / qk;
1125
0
    const int ncols_interleaved = 4;
1126
0
    const int blocklen = 4;
1127
1128
0
    assert(nr == 1);
1129
0
    assert(n % qk == 0);
1130
0
    assert(nc % ncols_interleaved == 0);
1131
1132
0
    UNUSED(bs);
1133
0
    UNUSED(nr);
1134
1135
0
    float sumf[4];
1136
0
    int sumi;
1137
1138
0
    const block_q8_0 * a_ptr = (const block_q8_0 *) vy;
1139
0
    for (int x = 0; x < nc / ncols_interleaved; x++) {
1140
0
        const block_iq4_nlx4 * b_ptr = (const block_iq4_nlx4 *) vx + (x * nb);
1141
1142
0
        for (int j = 0; j < ncols_interleaved; j++) sumf[j] = 0.0;
1143
0
        for (int l = 0; l < nb; l++) {
1144
0
            for (int k = 0; k < (qk / (2 * blocklen)); k++) {
1145
0
                for (int j = 0; j < ncols_interleaved; j++) {
1146
0
                    sumi = 0;
1147
0
                    for (int i = 0; i < blocklen; ++i) {
1148
0
                        const int v0 = kvalues_iq4nl[b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0x0F];
1149
0
                        const int v1 = kvalues_iq4nl[b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] >> 4];
1150
0
                        sumi += ((v0 * a_ptr[l].qs[k * blocklen + i]) + (v1 * a_ptr[l].qs[k * blocklen + i + qk / 2]));
1151
0
                    }
1152
0
                    sumf[j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d);
1153
0
                }
1154
0
            }
1155
0
        }
1156
0
        for (int j = 0; j < ncols_interleaved; j++) s[x * ncols_interleaved + j] = sumf[j];
1157
0
    }
1158
0
}
1159
1160
0
void ggml_gemv_iq4_nl_8x8_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
1161
0
    const int qk = QK8_0;
1162
0
    const int nb = n / qk;
1163
0
    const int ncols_interleaved = 8;
1164
0
    const int blocklen = 8;
1165
1166
0
    assert(nr == 1);
1167
0
    assert(n % qk == 0);
1168
0
    assert(nc % ncols_interleaved == 0);
1169
1170
0
    UNUSED(bs);
1171
0
    UNUSED(nr);
1172
1173
0
    float sumf[8];
1174
0
    int sumi;
1175
1176
0
    const block_q8_0 * a_ptr = (const block_q8_0 *) vy;
1177
0
    for (int x = 0; x < nc / ncols_interleaved; x++) {
1178
0
        const block_iq4_nlx8 * b_ptr = (const block_iq4_nlx8 *) vx + (x * nb);
1179
1180
0
        for (int j = 0; j < ncols_interleaved; j++) sumf[j] = 0.0;
1181
0
        for (int l = 0; l < nb; l++) {
1182
0
            for (int k = 0; k < (qk / (2 * blocklen)); k++) {
1183
0
                for (int j = 0; j < ncols_interleaved; j++) {
1184
0
                    sumi = 0;
1185
0
                    for (int i = 0; i < blocklen; ++i) {
1186
0
                        const int v0 = kvalues_iq4nl[b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0x0F];
1187
0
                        const int v1 = kvalues_iq4nl[b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] >> 4];
1188
0
                        sumi += ((v0 * a_ptr[l].qs[k * blocklen + i]) + (v1 * a_ptr[l].qs[k * blocklen + i + qk / 2]));
1189
0
                    }
1190
0
                    sumf[j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d);
1191
0
                }
1192
0
            }
1193
0
        }
1194
0
        for (int j = 0; j < ncols_interleaved; j++) s[x * ncols_interleaved + j] = sumf[j];
1195
0
    }
1196
0
}
1197
1198
0
void ggml_gemv_mxfp4_4x4_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
1199
0
    const int qk = QK8_0;
1200
0
    const int nb = n / qk;
1201
0
    const int ncols_interleaved = 4;
1202
0
    const int blocklen = 4;
1203
1204
0
    assert(nr == 1);
1205
0
    assert(n % qk == 0);
1206
0
    assert(nc % ncols_interleaved == 0);
1207
1208
0
    UNUSED(bs);
1209
0
    UNUSED(nr);
1210
1211
0
    float sumf[4];
1212
0
    int sumi;
1213
1214
0
    const block_q8_0 * a_ptr = (const block_q8_0 *) vy;
1215
0
    for (int x = 0; x < nc / ncols_interleaved; x++) {
1216
0
        const block_mxfp4x4 * b_ptr = (const block_mxfp4x4 *) vx + (x * nb);
1217
1218
0
        for (int j = 0; j < ncols_interleaved; j++) sumf[j] = 0.0;
1219
0
        for (int l = 0; l < nb; l++) {
1220
0
            for (int k = 0; k < (qk / (2 * blocklen)); k++) {
1221
0
                for (int j = 0; j < ncols_interleaved; j++) {
1222
0
                    sumi = 0;
1223
0
                    for (int i = 0; i < blocklen; ++i) {
1224
0
                        const int v0 = kvalues_mxfp4[b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0x0F];
1225
0
                        const int v1 = kvalues_mxfp4[b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] >> 4];
1226
0
                        sumi += ((v0 * a_ptr[l].qs[k * blocklen + i]) + (v1 * a_ptr[l].qs[k * blocklen + i + qk / 2]));
1227
0
                    }
1228
0
                    sumf[j] += sumi * GGML_CPU_E8M0_TO_FP32_HALF(b_ptr[l].e[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d);
1229
0
                }
1230
0
            }
1231
0
        }
1232
0
        for (int j = 0; j < ncols_interleaved; j++) s[x * ncols_interleaved + j] = sumf[j];
1233
0
    }
1234
0
}
1235
1236
0
void ggml_gemv_mxfp4_8x8_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
1237
0
    const int qk = QK8_0;
1238
0
    const int nb = n / qk;
1239
0
    const int ncols_interleaved = 8;
1240
0
    const int blocklen = 8;
1241
1242
0
    assert(nr == 1);
1243
0
    assert(n % qk == 0);
1244
0
    assert(nc % ncols_interleaved == 0);
1245
1246
0
    UNUSED(bs);
1247
0
    UNUSED(nr);
1248
1249
0
    float sumf[8];
1250
0
    int sumi;
1251
1252
0
    const block_q8_0 * a_ptr = (const block_q8_0 *) vy;
1253
0
    for (int x = 0; x < nc / ncols_interleaved; x++) {
1254
0
        const block_mxfp4x8 * b_ptr = (const block_mxfp4x8 *) vx + (x * nb);
1255
1256
0
        for (int j = 0; j < ncols_interleaved; j++) sumf[j] = 0.0;
1257
0
        for (int l = 0; l < nb; l++) {
1258
0
            for (int k = 0; k < (qk / (2 * blocklen)); k++) {
1259
0
                for (int j = 0; j < ncols_interleaved; j++) {
1260
0
                    sumi = 0;
1261
0
                    for (int i = 0; i < blocklen; ++i) {
1262
0
                        const int v0 = kvalues_mxfp4[b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0x0F];
1263
0
                        const int v1 = kvalues_mxfp4[b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] >> 4];
1264
0
                        sumi += ((v0 * a_ptr[l].qs[k * blocklen + i]) + (v1 * a_ptr[l].qs[k * blocklen + i + qk / 2]));
1265
0
                    }
1266
0
                    sumf[j] += sumi * GGML_CPU_E8M0_TO_FP32_HALF(b_ptr[l].e[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d);
1267
0
                }
1268
0
            }
1269
0
        }
1270
0
        for (int j = 0; j < ncols_interleaved; j++) s[x * ncols_interleaved + j] = sumf[j];
1271
0
    }
1272
0
}
1273
1274
void ggml_gemv_q8_0_4x4_q8_0_generic(int                        n,
1275
                                     float * GGML_RESTRICT      s,
1276
                                     size_t                     bs,
1277
                                     const void * GGML_RESTRICT vx,
1278
                                     const void * GGML_RESTRICT vy,
1279
                                     int                        nr,
1280
0
                                     int                        nc) {
1281
0
    const int qk                = QK8_0;
1282
0
    const int nb                = n / qk;
1283
0
    const int ncols_interleaved = 4;
1284
0
    const int blocklen          = 4;
1285
1286
0
    assert(nr == 1);
1287
0
    assert(n % qk == 0);
1288
0
    assert(nc % ncols_interleaved == 0);
1289
1290
0
    UNUSED(bs);
1291
0
    UNUSED(nr);
1292
1293
0
    float sumf[4];
1294
0
    int   sumi;
1295
1296
0
    const block_q8_0 * a_ptr = (const block_q8_0 *) vy;
1297
0
    for (int x = 0; x < nc / ncols_interleaved; x++) {
1298
0
        const block_q8_0x4 * b_ptr = (const block_q8_0x4 *) vx + (x * nb);
1299
1300
0
        for (int j = 0; j < ncols_interleaved; j++) {
1301
0
            sumf[j] = 0.0;
1302
0
        }
1303
0
        for (int l = 0; l < nb; l++) {
1304
0
            for (int k = 0; k < (qk / blocklen); k++) {
1305
0
                for (int j = 0; j < ncols_interleaved; j++) {
1306
0
                    sumi = 0;
1307
0
                    for (int i = 0; i < blocklen; ++i) {
1308
0
                        const int v0 = b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i];
1309
0
                        sumi += v0 * a_ptr[l].qs[k * blocklen + i];
1310
0
                    }
1311
0
                    sumf[j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d);
1312
0
                }
1313
0
            }
1314
0
        }
1315
0
        for (int j = 0; j < ncols_interleaved; j++) {
1316
0
            s[x * ncols_interleaved + j] = sumf[j];
1317
0
        }
1318
0
    }
1319
0
}
1320
1321
void ggml_gemv_q8_0_4x8_q8_0_generic(int                        n,
1322
                                     float * GGML_RESTRICT      s,
1323
                                     size_t                     bs,
1324
                                     const void * GGML_RESTRICT vx,
1325
                                     const void * GGML_RESTRICT vy,
1326
                                     int                        nr,
1327
0
                                     int                        nc) {
1328
0
    const int qk                = QK8_0;
1329
0
    const int nb                = n / qk;
1330
0
    const int ncols_interleaved = 4;
1331
0
    const int blocklen          = 8;
1332
1333
0
    assert(nr == 1);
1334
0
    assert(n % qk == 0);
1335
0
    assert(nc % ncols_interleaved == 0);
1336
1337
0
    UNUSED(bs);
1338
0
    UNUSED(nr);
1339
1340
0
    float sumf[4];
1341
0
    int   sumi;
1342
1343
0
    const block_q8_0 * a_ptr = (const block_q8_0 *) vy;
1344
0
    for (int x = 0; x < nc / ncols_interleaved; x++) {
1345
0
        const block_q8_0x4 * b_ptr = (const block_q8_0x4 *) vx + (x * nb);
1346
1347
0
        for (int j = 0; j < ncols_interleaved; j++) {
1348
0
            sumf[j] = 0.0;
1349
0
        }
1350
0
        for (int l = 0; l < nb; l++) {
1351
0
            for (int k = 0; k < (qk / blocklen); k++) {
1352
0
                for (int j = 0; j < ncols_interleaved; j++) {
1353
0
                    sumi = 0;
1354
0
                    for (int i = 0; i < blocklen; ++i) {
1355
0
                        const int v0 = b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i];
1356
0
                        sumi += v0 * a_ptr[l].qs[k * blocklen + i];
1357
0
                    }
1358
0
                    sumf[j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d);
1359
0
                }
1360
0
            }
1361
0
        }
1362
0
        for (int j = 0; j < ncols_interleaved; j++) {
1363
0
            s[x * ncols_interleaved + j] = sumf[j];
1364
0
        }
1365
0
    }
1366
0
}
1367
1368
// Only enable these for RISC-V.
1369
#if defined __riscv_zvfh
1370
void ggml_gemv_q4_0_16x1_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
1371
    const int qk = QK8_0;
1372
    const int nb = n / qk;
1373
    const int ncols_interleaved = 16;
1374
    const int blocklen = 1;
1375
1376
    assert (n % qk == 0);
1377
    assert (nc % ncols_interleaved == 0);
1378
1379
    UNUSED(s);
1380
    UNUSED(bs);
1381
    UNUSED(vx);
1382
    UNUSED(vy);
1383
    UNUSED(nr);
1384
    UNUSED(nc);
1385
    UNUSED(nb);
1386
    UNUSED(ncols_interleaved);
1387
    UNUSED(blocklen);
1388
1389
    float sumf[16];
1390
    int sumi;
1391
1392
    const block_q8_0 * a_ptr = (const block_q8_0 *) vy;
1393
    for (int x = 0; x < nc / ncols_interleaved; x++) {
1394
        const block_q4_0x16 * b_ptr = (const block_q4_0x16 *) vx + (x * nb);
1395
1396
        for (int j = 0; j < ncols_interleaved; j++) sumf[j] = 0.0;
1397
        for (int l = 0; l < nb; l++) {
1398
            for (int k = 0; k < (qk / (2 * blocklen)); k++) {
1399
                for (int j = 0; j < ncols_interleaved; j++) {
1400
                    sumi = 0;
1401
                    for (int i = 0; i < blocklen; ++i) {
1402
                        const int v0 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] << 4);
1403
                        const int v1 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0xF0);
1404
                        sumi += ((v0 * a_ptr[l].qs[k * blocklen + i]) + (v1 * a_ptr[l].qs[k * blocklen + i + qk / 2])) >> 4;
1405
                    }
1406
                    sumf[j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d);
1407
                }
1408
            }
1409
        }
1410
        for (int j = 0; j < ncols_interleaved; j++) s[x * ncols_interleaved + j] = sumf[j];
1411
    }
1412
}
1413
1414
void ggml_gemv_q4_K_16x1_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
1415
    const int qk = QK_K;
1416
    const int nb = n / qk;
1417
    const int ncols_interleaved = 16;
1418
    const int blocklen = 1;
1419
    assert (n % qk == 0);
1420
    assert (nc % ncols_interleaved == 0);
1421
    UNUSED(s);
1422
    UNUSED(bs);
1423
    UNUSED(vx);
1424
    UNUSED(vy);
1425
    UNUSED(nr);
1426
    UNUSED(nc);
1427
    UNUSED(nb);
1428
    UNUSED(ncols_interleaved);
1429
    UNUSED(blocklen);
1430
    float sumf[16];
1431
    float sum_minf[16];
1432
    uint8_t scales[128];
1433
    uint8_t mins[128];
1434
    int sumi1;
1435
    int sumi2;
1436
    int sumi;
1437
    const block_q8_K * a_ptr = (const block_q8_K *) vy;
1438
    for (int x = 0; x < nc / ncols_interleaved; x++) {
1439
        const block_q4_Kx16 * b_ptr = (const block_q4_Kx16 *) vx + (x * nb);
1440
        for (int j = 0; j < ncols_interleaved; j++) {
1441
            sumf[j] = 0.0f;
1442
            sum_minf[j] = 0.0f;
1443
        }
1444
        for (int l = 0; l < nb; l++) {
1445
            for (int i = 0; i < 128; i++) {
1446
                scales[i] = b_ptr[l].scales[i] & 0x0F;
1447
                mins[i] = b_ptr[l].scales[i] >> 4;
1448
            }
1449
            for (int i = 0; i < 64; i++) {
1450
                scales[i] |= (b_ptr[l].scales[128 + i] & 0x03) << 4;
1451
                mins[i] |= (b_ptr[l].scales[128 + i] & 0x0C) << 2;
1452
                scales[i + 64] |= (b_ptr[l].scales[128 + i] & 0x30);
1453
                mins[i + 64] |= (b_ptr[l].scales[128 + i] & 0xC0) >> 2;
1454
            }
1455
            for (int sb = 0; sb < 8; sb++) {
1456
                uint8_t *min = &mins[sb * 16];
1457
                for (int j = 0; j < ncols_interleaved; j++) {
1458
                    sum_minf[j] += min[j] * (a_ptr[l].bsums[sb * 2] + a_ptr[l].bsums[sb * 2 + 1]) * GGML_CPU_FP16_TO_FP32(b_ptr[l].dmin[j]) * a_ptr[l].d;
1459
                }
1460
            }
1461
            for (int sb = 0; sb < 8; sb += 2) {
1462
                uint8_t *scales_0 = &scales[sb * 16];
1463
                uint8_t *scales_1 = &scales[(sb + 1) * 16];
1464
                for (int i = 0; i < QK4_0; i++) {
1465
                    for (int j = 0; j < ncols_interleaved; j++) {
1466
                        sumi1 = 0;
1467
                        sumi2 = 0;
1468
                        sumi = 0;
1469
                        const int v0 = (int8_t) (b_ptr[l].qs[sb * 256 + i * 16 + j] & 0xF);
1470
                        const int v1 = (int8_t) (b_ptr[l].qs[sb * 256 + i * 16 + j] >> 4);
1471
                        sumi1 = (v0 * a_ptr[l].qs[sb * 32 + i]);
1472
                        sumi2 = (v1 * a_ptr[l].qs[sb * 32 + 32 + i]);
1473
                        sumi1 = sumi1 * scales_0[j];
1474
                        sumi2 = sumi2 * scales_1[j];
1475
                        sumi += sumi1 + sumi2;
1476
                        sumf[j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * a_ptr[l].d;
1477
                    }
1478
                }
1479
            }
1480
        }
1481
        for (int j = 0; j < ncols_interleaved; j++) {
1482
            s[x * ncols_interleaved + j] = sumf[j] - sum_minf[j];
1483
        }
1484
    }
1485
}
1486
1487
void ggml_gemv_iq4_nl_16x1_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
1488
    const int qk = QK8_0;
1489
    const int nb = n / qk;
1490
    const int ncols_interleaved = 16;
1491
    const int blocklen = 1;
1492
1493
    assert(nr == 1);
1494
    assert(n % qk == 0);
1495
    assert(nc % ncols_interleaved == 0);
1496
1497
    UNUSED(bs);
1498
    UNUSED(nr);
1499
1500
    float sumf[16];
1501
    int sumi;
1502
1503
    const block_q8_0 * a_ptr = (const block_q8_0 *) vy;
1504
    for (int x = 0; x < nc / ncols_interleaved; x++) {
1505
        const block_iq4_nlx16 * b_ptr = (const block_iq4_nlx16 *) vx + (x * nb);
1506
1507
        for (int j = 0; j < ncols_interleaved; j++) sumf[j] = 0.0;
1508
        for (int l = 0; l < nb; l++) {
1509
            for (int k = 0; k < (qk / (2 * blocklen)); k++) {
1510
                for (int j = 0; j < ncols_interleaved; j++) {
1511
                    sumi = 0;
1512
                    for (int i = 0; i < blocklen; ++i) {
1513
                        const int v0 = kvalues_iq4nl[b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0x0F];
1514
                        const int v1 = kvalues_iq4nl[b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] >> 4];
1515
                        sumi += ((v0 * a_ptr[l].qs[k * blocklen + i]) + (v1 * a_ptr[l].qs[k * blocklen + i + qk / 2]));
1516
                    }
1517
                    sumf[j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d);
1518
                }
1519
            }
1520
        }
1521
        for (int j = 0; j < ncols_interleaved; j++) s[x * ncols_interleaved + j] = sumf[j];
1522
    }
1523
}
1524
1525
void ggml_gemv_q8_0_16x1_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
1526
    const int qk                = QK8_0;
1527
    const int nb                = n / qk;
1528
    const int ncols_interleaved = 16;
1529
    const int blocklen          = 1;
1530
1531
    assert(nr == 1);
1532
    assert(n % qk == 0);
1533
    assert(nc % ncols_interleaved == 0);
1534
1535
    UNUSED(bs);
1536
    UNUSED(nr);
1537
1538
    float sumf[16];
1539
    int   sumi;
1540
1541
    const block_q8_0 * a_ptr = (const block_q8_0 *) vy;
1542
    for (int x = 0; x < nc / ncols_interleaved; x++) {
1543
        const block_q8_0x16 * b_ptr = (const block_q8_0x16 *) vx + (x * nb);
1544
1545
        for (int j = 0; j < ncols_interleaved; j++) {
1546
            sumf[j] = 0.0;
1547
        }
1548
        for (int l = 0; l < nb; l++) {
1549
            for (int k = 0; k < (qk / blocklen); k++) {
1550
                for (int j = 0; j < ncols_interleaved; j++) {
1551
                    sumi = 0;
1552
                    for (int i = 0; i < blocklen; ++i) {
1553
                        const int v0 = b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i];
1554
                        sumi += v0 * a_ptr[l].qs[k * blocklen + i];
1555
                    }
1556
                    sumf[j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d);
1557
                }
1558
            }
1559
        }
1560
        for (int j = 0; j < ncols_interleaved; j++) {
1561
            s[x * ncols_interleaved + j] = sumf[j];
1562
        }
1563
    }
1564
}
1565
1566
void ggml_gemv_q2_K_16x1_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
1567
    assert(n % QK_K == 0);
1568
    assert(nr == 1);
1569
    assert(nc % 16 == 0);
1570
1571
    UNUSED(bs);
1572
    UNUSED(nr);
1573
1574
    const int nb = n / QK_K;
1575
    const block_q2_Kx16 * x = (const block_q2_Kx16 *)vx;
1576
    const block_q8_K    * y = (const block_q8_K *)vy;
1577
1578
    // Layout: Even-Low(0,2,4,6), Odd-Low(1,3,5,7), Even-High(8...), Odd-High(9...)
1579
    const int sb_perm[16] = {
1580
        0, 4, 1, 5, 2, 6, 3, 7,  // 0-7
1581
        8, 12, 9, 13, 10, 14, 11, 15 // 8-15
1582
    };
1583
1584
    for (int col_tile = 0; col_tile < nc; col_tile += 16) {
1585
        const block_q2_Kx16 * x_ptr = x + (col_tile / 16) * nb;
1586
        const block_q8_K    * y_ptr = y;
1587
1588
        float sumf[16] = {0};
1589
1590
        // Loop over K-blocks
1591
        for (int k_block = 0; k_block < nb; ++k_block) {
1592
            int32_t isum[16]  = {0};
1593
            int32_t summs[16] = {0};
1594
1595
            const uint8_t * qs_rhs = x_ptr[k_block].qs;
1596
            const uint8_t * sc_rhs = x_ptr[k_block].scales;
1597
            const int8_t  * qs_lhs = y_ptr[k_block].qs;
1598
            const int16_t * bs_lhs = y_ptr[k_block].bsums;
1599
1600
            // Iterate over sub-blocks 0..15
1601
            for (int sb = 0; sb < 16; ++sb) {
1602
                // Correction Term
1603
                int16_t bsum = bs_lhs[sb];
1604
                int scale_offset = sb_perm[sb] * 16;
1605
1606
                for (int col = 0; col < 16; ++col) {
1607
                    uint8_t sc_val = sc_rhs[scale_offset + col];
1608
                    summs[col] += bsum * (sc_val >> 4); // Min is high 4 bits
1609
                }
1610
1611
                // Main Dot Product
1612
                // Calculate base offsets for Q2 unpacking based on SB
1613
                int byte_base;
1614
                if (sb < 8) byte_base = (sb % 2 == 0) ? 0 : 16;
1615
                else        byte_base = (sb % 2 == 0) ? 32 : 48;
1616
1617
                int shift = ((sb / 2) % 4) * 2;
1618
1619
                for (int col = 0; col < 16; ++col) {
1620
                    uint8_t sc_val = sc_rhs[scale_offset + col];
1621
                    int32_t d_sb = sc_val & 0xF; // Scale is low 4 bits
1622
1623
                    // Process 16 elements (l=0..15)
1624
                    for (int l = 0; l < 16; ++l) {
1625
                        // Q2: Interleaved by column. Byte `l` contains 4 k-values.
1626
                        int qs_idx = (byte_base + l) * 16 + col;
1627
                        uint8_t q2_val = (qs_rhs[qs_idx] >> shift) & 3;
1628
1629
                        // Q8: Linear access
1630
                        int k = sb * 16 + l;
1631
                        int8_t q8_val = qs_lhs[k];
1632
1633
                        isum[col] += q8_val * q2_val * d_sb;
1634
                    }
1635
                }
1636
            }
1637
1638
            // Finalize K-Block
1639
            for (int col = 0; col < 16; ++col) {
1640
                float d_lhs = y_ptr[k_block].d;
1641
                float d_rhs = GGML_FP16_TO_FP32(x_ptr[k_block].d[col]);
1642
                float dm_rhs = GGML_FP16_TO_FP32(x_ptr[k_block].dmin[col]);
1643
1644
                float d_all = d_lhs * d_rhs;
1645
                float d_min = d_lhs * dm_rhs;
1646
1647
                sumf[col] += (isum[col] * d_all) - (summs[col] * d_min);
1648
            }
1649
        }
1650
1651
        for (int col = 0; col < 16; ++col) {
1652
            s[col_tile + col] = sumf[col];
1653
        }
1654
    }
1655
}
1656
#endif
1657
1658
0
void ggml_gemm_q4_0_4x4_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
1659
0
    const int qk = QK8_0;
1660
0
    const int nb = n / qk;
1661
0
    const int ncols_interleaved = 4;
1662
0
    const int blocklen = 4;
1663
1664
0
    assert (n % qk == 0);
1665
0
    assert (nr % 4 == 0);
1666
0
    assert (nc % ncols_interleaved == 0);
1667
1668
0
    UNUSED(s);
1669
0
    UNUSED(bs);
1670
0
    UNUSED(vx);
1671
0
    UNUSED(vy);
1672
0
    UNUSED(nr);
1673
0
    UNUSED(nc);
1674
0
    UNUSED(nb);
1675
0
    UNUSED(ncols_interleaved);
1676
0
    UNUSED(blocklen);
1677
1678
0
    {
1679
0
        float sumf[4][4];
1680
0
        int sumi;
1681
1682
0
        for (int y = 0; y < nr / 4; y++) {
1683
0
            const block_q8_0x4 * a_ptr = (const block_q8_0x4 *) vy + (y * nb);
1684
0
            for (int x = 0; x < nc / ncols_interleaved; x++) {
1685
0
                const block_q4_0x4 * b_ptr = (const block_q4_0x4 *) vx + (x * nb);
1686
0
                for (int m = 0; m < 4; m++) {
1687
0
                    for (int j = 0; j < ncols_interleaved; j++) sumf[m][j] = 0.0;
1688
0
                }
1689
0
                for (int l = 0; l < nb; l++) {
1690
0
                    for (int k = 0; k < (qk / (2 * blocklen)); k++) {
1691
0
                        for (int m = 0; m < 4; m++) {
1692
0
                            for (int j = 0; j < ncols_interleaved; j++) {
1693
0
                                sumi = 0;
1694
0
                                for (int i = 0; i < blocklen; ++i) {
1695
0
                                    const int v0 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] << 4);
1696
0
                                    const int v1 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0xF0);
1697
0
                                    sumi += ((v0 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i]) +
1698
0
                                            (v1 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i + qk / 2 * 4])) >> 4;
1699
0
                                }
1700
0
                                sumf[m][j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d[m]);
1701
0
                            }
1702
0
                        }
1703
0
                    }
1704
0
                }
1705
0
                for (int m = 0; m < 4; m++) {
1706
0
                    for (int j = 0; j < ncols_interleaved; j++)
1707
0
                        s[(y * 4 + m) * bs + x * ncols_interleaved + j] = sumf[m][j];
1708
0
                }
1709
0
            }
1710
0
        }
1711
0
    }
1712
0
}
1713
1714
0
void ggml_gemm_q4_0_4x8_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
1715
0
    const int qk = QK8_0;
1716
0
    const int nb = n / qk;
1717
0
    const int ncols_interleaved = 4;
1718
0
    const int blocklen = 8;
1719
1720
0
    assert (n % qk == 0);
1721
0
    assert (nr % 4 == 0);
1722
0
    assert (nc % ncols_interleaved == 0);
1723
1724
0
    UNUSED(s);
1725
0
    UNUSED(bs);
1726
0
    UNUSED(vx);
1727
0
    UNUSED(vy);
1728
0
    UNUSED(nr);
1729
0
    UNUSED(nc);
1730
0
    UNUSED(nb);
1731
0
    UNUSED(ncols_interleaved);
1732
0
    UNUSED(blocklen);
1733
1734
0
    float sumf[4][4];
1735
0
    int sumi;
1736
1737
0
    for (int y = 0; y < nr / 4; y++) {
1738
0
        const block_q8_0x4 * a_ptr = (const block_q8_0x4 *) vy + (y * nb);
1739
0
        for (int x = 0; x < nc / ncols_interleaved; x++) {
1740
0
            const block_q4_0x4 * b_ptr = (const block_q4_0x4 *) vx + (x * nb);
1741
0
            for (int m = 0; m < 4; m++) {
1742
0
                for (int j = 0; j < ncols_interleaved; j++) sumf[m][j] = 0.0;
1743
0
            }
1744
0
            for (int l = 0; l < nb; l++) {
1745
0
                for (int k = 0; k < (qk / (2 * blocklen)); k++) {
1746
0
                    for (int m = 0; m < 4; m++) {
1747
0
                        for (int j = 0; j < ncols_interleaved; j++) {
1748
0
                            sumi = 0;
1749
0
                            for (int i = 0; i < blocklen; ++i) {
1750
0
                                const int v0 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] << 4);
1751
0
                                const int v1 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0xF0);
1752
0
                                sumi += ((v0 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i]) +
1753
0
                                        (v1 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i + qk / 2 * 4])) >> 4;
1754
0
                            }
1755
0
                            sumf[m][j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d[m]);
1756
0
                        }
1757
0
                    }
1758
0
                }
1759
0
            }
1760
0
            for (int m = 0; m < 4; m++) {
1761
0
                for (int j = 0; j < ncols_interleaved; j++)
1762
0
                    s[(y * 4 + m) * bs + x * ncols_interleaved + j] = sumf[m][j];
1763
0
            }
1764
0
        }
1765
0
    }
1766
0
}
1767
1768
0
void ggml_gemm_q4_0_8x8_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
1769
0
    const int qk = QK8_0;
1770
0
    const int nb = n / qk;
1771
0
    const int ncols_interleaved = 8;
1772
0
    const int blocklen = 8;
1773
1774
0
    assert (n % qk == 0);
1775
0
    assert (nr % 4 == 0);
1776
0
    assert (nc % ncols_interleaved == 0);
1777
1778
0
    UNUSED(s);
1779
0
    UNUSED(bs);
1780
0
    UNUSED(vx);
1781
0
    UNUSED(vy);
1782
0
    UNUSED(nr);
1783
0
    UNUSED(nc);
1784
0
    UNUSED(nb);
1785
0
    UNUSED(ncols_interleaved);
1786
0
    UNUSED(blocklen);
1787
1788
0
    float sumf[4][8];
1789
0
    int sumi;
1790
1791
0
    for (int y = 0; y < nr / 4; y++) {
1792
0
        const block_q8_0x4 * a_ptr = (const block_q8_0x4 *) vy + (y * nb);
1793
0
        for (int x = 0; x < nc / ncols_interleaved; x++) {
1794
0
            const block_q4_0x8 * b_ptr = (const block_q4_0x8 *) vx + (x * nb);
1795
0
            for (int m = 0; m < 4; m++) {
1796
0
                for (int j = 0; j < ncols_interleaved; j++) sumf[m][j] = 0.0;
1797
0
            }
1798
0
            for (int l = 0; l < nb; l++) {
1799
0
                for (int k = 0; k < (qk / (2 * blocklen)); k++) {
1800
0
                    for (int m = 0; m < 4; m++) {
1801
0
                        for (int j = 0; j < ncols_interleaved; j++) {
1802
0
                            sumi = 0;
1803
0
                            for (int i = 0; i < blocklen; ++i) {
1804
0
                                const int v0 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] << 4);
1805
0
                                const int v1 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0xF0);
1806
0
                                sumi += ((v0 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i]) +
1807
0
                                         (v1 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i + qk / 2 * 4])) >> 4;
1808
0
                            }
1809
0
                            sumf[m][j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d[m]);
1810
0
                        }
1811
0
                    }
1812
0
                }
1813
0
            }
1814
0
            for (int m = 0; m < 4; m++) {
1815
0
                for (int j = 0; j < ncols_interleaved; j++)
1816
0
                    s[(y * 4 + m) * bs + x * ncols_interleaved + j] = sumf[m][j];
1817
0
            }
1818
0
        }
1819
0
    }
1820
0
}
1821
1822
0
void ggml_gemm_q4_K_8x4_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
1823
0
    const int qk = QK_K;
1824
0
    const int nb = n / qk;
1825
0
    const int ncols_interleaved = 8;
1826
0
    const int blocklen = 4;
1827
0
    static const uint32_t kmask1 = 0x3f3f3f3f;
1828
0
    static const uint32_t kmask2 = 0x0f0f0f0f;
1829
0
    static const uint32_t kmask3 = 0x03030303;
1830
1831
0
    assert (n % qk == 0);
1832
0
    assert (nr % 4 == 0);
1833
0
    assert (nc % ncols_interleaved == 0);
1834
1835
0
    UNUSED(nb);
1836
0
    UNUSED(ncols_interleaved);
1837
0
    UNUSED(blocklen);
1838
1839
0
    float sumf[4][8];
1840
0
    float sum_minf[4][8];
1841
0
    uint32_t utmp[32];
1842
0
    int sumi1;
1843
0
    int sumi2;
1844
0
    int sumi;
1845
1846
0
    for (int y = 0; y < nr / 4; y++) {
1847
0
        const block_q8_Kx4 * a_ptr = (const block_q8_Kx4 *) vy + (y * nb);
1848
0
        for (int x = 0; x < nc / ncols_interleaved; x++) {
1849
0
            const block_q4_Kx8 * b_ptr = (const block_q4_Kx8 *) vx + (x * nb);
1850
0
            for (int m = 0; m < 4; m++) {
1851
0
                for (int j = 0; j < ncols_interleaved; j++) {
1852
0
                    sumf[m][j] = 0.0;
1853
0
                    sum_minf[m][j] = 0.0;
1854
0
                }
1855
0
            }
1856
0
            for (int l = 0; l < nb; l++) {
1857
0
                for (int sb = 0; sb < 8; sb++) {
1858
0
                    memcpy(utmp + sb * 4, b_ptr[l].scales + sb * 12, 12);
1859
0
                    utmp[sb * 4 + 3] = ((utmp[sb * 4 + 2] >> 4) & kmask2) | (((utmp[sb * 4 + 1] >> 6) & kmask3) << 4);
1860
0
                    const uint32_t uaux_0 = utmp[sb * 4 + 1] & kmask1;
1861
0
                    utmp[sb * 4 + 1] = (utmp[sb * 4 + 2] & kmask2) | (((utmp[sb * 4 + 0] >> 6) & kmask3) << 4);
1862
0
                    utmp[sb * 4 + 2] = uaux_0;
1863
0
                    utmp[sb * 4 + 0] &= kmask1;
1864
0
                }
1865
0
                for (int k = 0; k < (qk / (2 * blocklen)); k++) {
1866
0
                    uint8_t * scales_0 = (uint8_t *) utmp + (k / 8) * 32;
1867
0
                    uint8_t * scales_1 = (uint8_t *) utmp + (k / 8) * 32 + 16;
1868
0
                    for (int m = 0; m < 4; m++) {
1869
0
                        for (int j = 0; j < ncols_interleaved; j++) {
1870
0
                            sumi1 = 0;
1871
0
                            sumi2 = 0;
1872
0
                            sumi = 0;
1873
0
                            for (int i = 0; i < blocklen; ++i) {
1874
0
                                const int v0 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0xF);
1875
0
                                const int v1 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] >> 4);
1876
0
                                sumi1 = (v0 * a_ptr[l].qs[(k / 8) * 256 + (k % 8) * 4 * blocklen + m * blocklen + i]);
1877
0
                                sumi2 = (v1 * a_ptr[l].qs[(k / 8) * 256 + (k % 8) * 4 * blocklen + m * blocklen + i + 128]);
1878
0
                                sumi1 = sumi1 * scales_0[j];
1879
0
                                sumi2 = sumi2 * scales_1[j];
1880
0
                                sumi += sumi1 + sumi2;
1881
0
                            }
1882
0
                            sumf[m][j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * a_ptr[l].d[m];
1883
0
                        }
1884
0
                    }
1885
0
                }
1886
0
                for (int sb = 0; sb < 8; sb++) {
1887
0
                    uint8_t * mins = (uint8_t *) utmp + 8 + sb * 16;
1888
0
                    for(int m = 0; m < 4; m++) {
1889
0
                        const int16_t * bsums = a_ptr[l].bsums + (sb * 8) + (m * 4) - ((sb % 2) * 6);
1890
0
                        for(int j = 0; j < ncols_interleaved; j++) {
1891
0
                            sum_minf[m][j] += mins[j] * (bsums[0] + bsums[1]) * GGML_CPU_FP16_TO_FP32(b_ptr[l].dmin[j]) * a_ptr[l].d[m];
1892
0
                        }
1893
0
                    }
1894
0
                }
1895
0
            }
1896
0
            for (int m = 0; m < 4; m++) {
1897
0
                for (int j = 0; j < ncols_interleaved; j++) {
1898
0
                    s[(y * 4 + m) * bs + x * ncols_interleaved + j] = sumf[m][j] - sum_minf[m][j];
1899
0
                }
1900
0
            }
1901
0
        }
1902
0
    }
1903
0
}
1904
1905
0
void ggml_gemm_q4_K_8x8_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
1906
0
    const int qk = QK_K;
1907
0
    const int nb = n / qk;
1908
0
    const int ncols_interleaved = 8;
1909
0
    const int blocklen = 8;
1910
0
    static const uint32_t kmask1 = 0x3f3f3f3f;
1911
0
    static const uint32_t kmask2 = 0x0f0f0f0f;
1912
0
    static const uint32_t kmask3 = 0x03030303;
1913
1914
0
    assert (n % qk == 0);
1915
0
    assert (nr % 4 == 0);
1916
0
    assert (nc % ncols_interleaved == 0);
1917
1918
0
    UNUSED(bs);
1919
1920
0
    float sumf[4][8];
1921
0
    float sum_minf[4][8];
1922
0
    uint32_t utmp[32];
1923
0
    int sumi1;
1924
0
    int sumi2;
1925
0
    int sumi;
1926
1927
0
    for (int y = 0; y < nr / 4; y++) {
1928
0
        const block_q8_Kx4 * a_ptr = (const block_q8_Kx4 *) vy + (y * nb);
1929
0
        for (int x = 0; x < nc / ncols_interleaved; x++) {
1930
0
            const block_q4_Kx8 * b_ptr = (const block_q4_Kx8 *) vx + (x * nb);
1931
0
            for (int m = 0; m < 4; m++) {
1932
0
                for (int j = 0; j < ncols_interleaved; j++) {
1933
0
                    sumf[m][j] = 0.0;
1934
0
                    sum_minf[m][j] = 0.0;
1935
0
                }
1936
0
            }
1937
0
            for (int l = 0; l < nb; l++) {
1938
0
                for (int sb = 0; sb < 8; sb++) {
1939
0
                    memcpy(utmp + sb * 4, b_ptr[l].scales + sb * 12, 12);
1940
0
                    utmp[sb * 4 + 3] = ((utmp[sb * 4 + 2] >> 4) & kmask2) | (((utmp[sb * 4 + 1] >> 6) & kmask3) << 4);
1941
0
                    const uint32_t uaux_0 = utmp[sb * 4 + 1] & kmask1;
1942
0
                    utmp[sb * 4 + 1] = (utmp[sb * 4 + 2] & kmask2) | (((utmp[sb * 4 + 0] >> 6) & kmask3) << 4);
1943
0
                    utmp[sb * 4 + 2] = uaux_0;
1944
0
                    utmp[sb * 4 + 0] &= kmask1;
1945
0
                }
1946
0
                for (int k = 0; k < (qk / (2 * blocklen)); k++) {
1947
0
                    uint8_t *scales_0 = (uint8_t*) utmp + (k / 4) * 32;
1948
0
                    uint8_t *scales_1 = (uint8_t*) utmp + (k / 4) * 32 + 16;
1949
0
                    for (int m = 0; m < 4; m++) {
1950
0
                        for (int j = 0; j < ncols_interleaved; j++) {
1951
0
                            sumi1 = 0;
1952
0
                            sumi2 = 0;
1953
0
                            sumi = 0;
1954
0
                            for (int i = 0; i < blocklen; ++i) {
1955
0
                                const int v0 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0xF);
1956
0
                                const int v1 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] >> 4);
1957
0
                                sumi1 = (v0 * a_ptr[l].qs[(k >> 2) * 256 + (k % 4) * 4 * blocklen + m * blocklen + i]);
1958
0
                                sumi2 = (v1 * a_ptr[l].qs[(k >> 2) * 256 + (k % 4) * 4 * blocklen + m * blocklen + i + 128]);
1959
0
                                sumi1 = sumi1 * scales_0[j];
1960
0
                                sumi2 = sumi2 * scales_1[j];
1961
0
                                sumi += sumi1 + sumi2;
1962
0
                            }
1963
0
                            sumf[m][j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * a_ptr[l].d[m];
1964
0
                        }
1965
0
                    }
1966
0
                }
1967
0
                for (int sb = 0; sb < 8; sb++) {
1968
0
                    uint8_t *mins = (uint8_t*) utmp + 8 + sb * 16;
1969
0
                    for(int m = 0; m < 4; m++) {
1970
0
                        const int16_t *bsums = a_ptr[l].bsums + (sb * 8) + (m * 4) - ((sb % 2) * 6);
1971
0
                        for(int j = 0; j < ncols_interleaved; j++) {
1972
0
                            sum_minf[m][j] += mins[j] * (bsums[0] + bsums[1]) * GGML_CPU_FP16_TO_FP32(b_ptr[l].dmin[j]) * a_ptr[l].d[m];
1973
0
                        }
1974
0
                    }
1975
0
                }
1976
0
            }
1977
0
            for (int m = 0; m < 4; m++) {
1978
0
                for (int j = 0; j < ncols_interleaved; j++) {
1979
0
                    s[(y * 4 + m) * bs + x * ncols_interleaved + j] = sumf[m][j] - sum_minf[m][j];
1980
0
                }
1981
0
            }
1982
0
        }
1983
0
    }
1984
0
}
1985
1986
0
void ggml_gemm_q2_K_8x8_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
1987
0
    const int qk = QK_K;
1988
0
    const int nb = n / qk;
1989
0
    const int ncols_interleaved = 8;
1990
0
    const int blocklen = 8;
1991
1992
0
    assert (n % qk == 0);
1993
0
    assert (nr % 4 == 0);
1994
0
    assert (nc % ncols_interleaved == 0);
1995
1996
0
    UNUSED(s);
1997
0
    UNUSED(bs);
1998
0
    UNUSED(vx);
1999
0
    UNUSED(vy);
2000
0
    UNUSED(nr);
2001
0
    UNUSED(nc);
2002
0
    UNUSED(nb);
2003
0
    UNUSED(ncols_interleaved);
2004
0
    UNUSED(blocklen);
2005
2006
0
    float sumf[4][8];
2007
0
    float sum_minf[4][8];
2008
0
    int sumi1, sumi2, sumi3, sumi4;
2009
0
    int sumi;
2010
2011
0
    for (int y = 0; y < nr / 4; y++) {
2012
0
        const block_q8_Kx4 * a_ptr = (const block_q8_Kx4 *) vy + (y * nb);
2013
0
        for (int x = 0; x < nc / ncols_interleaved; x++) {
2014
0
            const block_q2_Kx8 * b_ptr = (const block_q2_Kx8 *) vx + (x * nb);
2015
0
            for (int m = 0; m < 4; m++) {
2016
0
                for (int j = 0; j < ncols_interleaved; j++) {
2017
0
                    sumf[m][j] = 0.0;
2018
0
                    sum_minf[m][j] = 0.0;
2019
0
                }
2020
0
            }
2021
0
            for (int l = 0; l < nb; l++) {
2022
0
                for (int k = 0; k < (qk / (4 * blocklen)); k++) {
2023
2024
0
                    const uint8_t *scales_0 = b_ptr[l].scales + (k / 4) * 64 ;
2025
0
                    const uint8_t *scales_1 = b_ptr[l].scales + (k / 4) * 64 + 16;
2026
0
                    const uint8_t *scales_2 = b_ptr[l].scales + (k / 4) * 64 + 32;
2027
0
                    const uint8_t *scales_3 = b_ptr[l].scales + (k / 4) * 64 + 48;
2028
0
                    for (int m = 0; m < 4; m++) {
2029
0
                        for (int j = 0; j < ncols_interleaved; j++) {
2030
0
                            sumi1 = 0;
2031
0
                            sumi2 = 0;
2032
0
                            sumi3 = 0;
2033
0
                            sumi4 = 0;
2034
0
                            sumi = 0;
2035
0
                            int offset = ((k / 2) % 2) + j * 2;
2036
0
                            for (int i = 0; i < blocklen; ++i){
2037
0
                                const int v0 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 3);
2038
0
                                const int v1 = (int8_t) ((b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] >> 2 ) & 3);
2039
0
                                const int v2 = (int8_t) ((b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] >> 4 ) & 3);
2040
0
                                const int v3 = (int8_t) ((b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] >> 6 ) & 3);
2041
0
                                sumi1 = (v0 * a_ptr[l].qs[(k >> 2) * 512 + (k % 4) * 4 * blocklen + m * blocklen + i]);
2042
0
                                sumi2 = (v1 * a_ptr[l].qs[(k >> 2) * 512  + (k % 4) * 4 * blocklen + m * blocklen + i + 128]);
2043
0
                                sumi3 = (v2 * a_ptr[l].qs[(k >> 2) * 512  + (k % 4) * 4 * blocklen + m * blocklen + i + 256]);
2044
0
                                sumi4 = (v3 * a_ptr[l].qs[(k >> 2) * 512  + (k % 4) * 4 * blocklen + m * blocklen + i + 384]);
2045
0
                                sumi1 = sumi1 * (scales_0[offset] & 0xF);
2046
0
                                sumi2 = sumi2 * (scales_1[offset] & 0xF);
2047
0
                                sumi3 = sumi3 * (scales_2[offset] & 0xF);
2048
0
                                sumi4 = sumi4 * (scales_3[offset] & 0xF);
2049
0
                                sumi += sumi1 + sumi2 + sumi3 + sumi4;
2050
0
                            }
2051
0
                            sumf[m][j] += sumi * GGML_FP16_TO_FP32(b_ptr[l].d[j]) * a_ptr[l].d[m];
2052
0
                        }
2053
0
                    }
2054
0
                }
2055
0
                for(int sb = 0; sb < 8; sb++) {
2056
0
                    const uint8_t *mins = b_ptr[l].scales + sb * 16;
2057
0
                    for(int m = 0; m < 4; m++) {
2058
0
                        const int16_t *bsums = a_ptr[l].bsums + (sb * 8) + (m * 4) - ((sb % 2) *  6);
2059
0
                        for(int j = 0; j < ncols_interleaved; j++) {
2060
0
                            int mins_prod = ((mins[j * 2] >> 4) * bsums[0] + (mins[(j * 2)+ 1] >> 4) * bsums[1]);
2061
0
                            sum_minf[m][j] += (mins_prod) * GGML_FP16_TO_FP32(b_ptr[l].dmin[j]) * a_ptr[l].d[m];
2062
0
                        }
2063
0
                    }
2064
0
                }
2065
0
            }
2066
2067
0
            for (int m = 0; m < 4; m++) {
2068
0
                for (int j = 0; j < ncols_interleaved; j++) {
2069
0
                    s[(y * 4 + m) * bs + x * ncols_interleaved + j] = sumf[m][j] - sum_minf[m][j];
2070
0
                }
2071
0
            }
2072
0
        }
2073
0
    }
2074
0
}
2075
2076
0
void ggml_gemm_q5_K_8x4_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
2077
0
    ggml_gemm_q5_K_NxM_q8_K_generic_impl<4, 8>(n, s, bs, vx, vy, nr, nc);
2078
0
}
2079
2080
0
void ggml_gemm_q5_K_8x8_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
2081
0
    ggml_gemm_q5_K_NxM_q8_K_generic_impl<8, 8>(n, s, bs, vx, vy, nr, nc);
2082
0
}
2083
2084
0
void ggml_gemm_q6_K_8x4_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
2085
0
    ggml_gemm_q6_K_NxM_q8_K_generic_impl<4, 8>(n, s, bs, vx, vy, nr, nc);
2086
0
}
2087
2088
0
void ggml_gemm_q6_K_8x8_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
2089
0
   ggml_gemm_q6_K_NxM_q8_K_generic_impl<8, 8>(n, s, bs, vx, vy, nr, nc);
2090
0
}
2091
2092
0
void ggml_gemm_iq4_nl_4x4_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
2093
0
    const int qk = QK8_0;
2094
0
    const int nb = n / qk;
2095
0
    const int ncols_interleaved = 4;
2096
0
    const int blocklen = 4;
2097
2098
0
    assert (n % qk == 0);
2099
0
    assert (nr % 4 == 0);
2100
0
    assert (nc % ncols_interleaved == 0);
2101
2102
0
    UNUSED(s);
2103
0
    UNUSED(bs);
2104
0
    UNUSED(vx);
2105
0
    UNUSED(vy);
2106
0
    UNUSED(nr);
2107
0
    UNUSED(nc);
2108
0
    UNUSED(nb);
2109
0
    UNUSED(ncols_interleaved);
2110
0
    UNUSED(blocklen);
2111
2112
0
    {
2113
0
        float sumf[4][4];
2114
0
        int sumi;
2115
2116
0
        for (int y = 0; y < nr / 4; y++) {
2117
0
            const block_q8_0x4 * a_ptr = (const block_q8_0x4 *) vy + (y * nb);
2118
0
            for (int x = 0; x < nc / ncols_interleaved; x++) {
2119
0
                const block_iq4_nlx4 * b_ptr = (const block_iq4_nlx4 *) vx + (x * nb);
2120
0
                for (int m = 0; m < 4; m++) {
2121
0
                    for (int j = 0; j < ncols_interleaved; j++) sumf[m][j] = 0.0;
2122
0
                }
2123
0
                for (int l = 0; l < nb; l++) {
2124
0
                    for (int k = 0; k < (qk / (2 * blocklen)); k++) {
2125
0
                        for (int m = 0; m < 4; m++) {
2126
0
                            for (int j = 0; j < ncols_interleaved; j++) {
2127
0
                                sumi = 0;
2128
0
                                for (int i = 0; i < blocklen; ++i) {
2129
0
                                    const int v0 = kvalues_iq4nl[b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0x0F];
2130
0
                                    const int v1 = kvalues_iq4nl[b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] >> 4];
2131
0
                                    sumi += ((v0 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i]) +
2132
0
                                            (v1 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i + qk / 2 * 4]));
2133
0
                                }
2134
0
                                sumf[m][j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d[m]);
2135
0
                            }
2136
0
                        }
2137
0
                    }
2138
0
                }
2139
0
                for (int m = 0; m < 4; m++) {
2140
0
                    for (int j = 0; j < ncols_interleaved; j++)
2141
0
                        s[(y * 4 + m) * bs + x * ncols_interleaved + j] = sumf[m][j];
2142
0
                }
2143
0
            }
2144
0
        }
2145
0
    }
2146
0
}
2147
2148
0
void ggml_gemm_iq4_nl_8x8_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
2149
0
    const int qk = QK8_0;
2150
0
    const int nb = n / qk;
2151
0
    const int ncols_interleaved = 8;
2152
0
    const int blocklen = 8;
2153
2154
0
    assert(n % qk == 0);
2155
0
    assert(nr % 4 == 0);
2156
0
    assert(nc % ncols_interleaved == 0);
2157
2158
0
    float sumf[4][8];
2159
0
    int sumi;
2160
2161
0
    for (int y = 0; y < nr / 4; y++) {
2162
0
        const block_q8_0x4 * a_ptr = (const block_q8_0x4 *) vy + (y * nb);
2163
0
        for (int x = 0; x < nc / ncols_interleaved; x++) {
2164
0
            const block_iq4_nlx8 * b_ptr = (const block_iq4_nlx8 *) vx + (x * nb);
2165
0
            for (int m = 0; m < 4; m++) {
2166
0
                for (int j = 0; j < ncols_interleaved; j++) sumf[m][j] = 0.0;
2167
0
            }
2168
0
            for (int l = 0; l < nb; l++) {
2169
0
                for (int k = 0; k < (qk / (2 * blocklen)); k++) {
2170
0
                    for (int m = 0; m < 4; m++) {
2171
0
                        for (int j = 0; j < ncols_interleaved; j++) {
2172
0
                            sumi = 0;
2173
0
                            for (int i = 0; i < blocklen; ++i) {
2174
0
                                const int v0 = kvalues_iq4nl[b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0x0F];
2175
0
                                const int v1 = kvalues_iq4nl[b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] >> 4];
2176
0
                                sumi += ((v0 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i]) +
2177
0
                                         (v1 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i + qk / 2 * 4]));
2178
0
                            }
2179
0
                            sumf[m][j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d[m]);
2180
0
                        }
2181
0
                    }
2182
0
                }
2183
0
            }
2184
0
            for (int m = 0; m < 4; m++) {
2185
0
                for (int j = 0; j < ncols_interleaved; j++)
2186
0
                    s[(y * 4 + m) * bs + x * ncols_interleaved + j] = sumf[m][j];
2187
0
            }
2188
0
        }
2189
0
    }
2190
0
}
2191
2192
0
void ggml_gemm_mxfp4_4x4_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
2193
0
    const int qk = QK8_0;
2194
0
    const int nb = n / qk;
2195
0
    const int ncols_interleaved = 4;
2196
0
    const int blocklen = 4;
2197
2198
0
    assert(n % qk == 0);
2199
0
    assert(nr % 4 == 0);
2200
0
    assert(nc % ncols_interleaved == 0);
2201
2202
0
    float sumf[4][4];
2203
0
    int sumi;
2204
2205
0
    for (int y = 0; y < nr / 4; y++) {
2206
0
        const block_q8_0x4 * a_ptr = (const block_q8_0x4 *) vy + (y * nb);
2207
0
        for (int x = 0; x < nc / ncols_interleaved; x++) {
2208
0
            const block_mxfp4x4 * b_ptr = (const block_mxfp4x4 *) vx + (x * nb);
2209
0
            for (int m = 0; m < 4; m++) {
2210
0
                for (int j = 0; j < ncols_interleaved; j++) sumf[m][j] = 0.0;
2211
0
            }
2212
0
            for (int l = 0; l < nb; l++) {
2213
0
                for (int k = 0; k < (qk / (2 * blocklen)); k++) {
2214
0
                    for (int m = 0; m < 4; m++) {
2215
0
                        for (int j = 0; j < ncols_interleaved; j++) {
2216
0
                            sumi = 0;
2217
0
                            for (int i = 0; i < blocklen; ++i) {
2218
0
                                const int v0 = kvalues_mxfp4[b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0x0F];
2219
0
                                const int v1 = kvalues_mxfp4[b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] >> 4];
2220
0
                                sumi += ((v0 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i]) +
2221
0
                                         (v1 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i + qk / 2 * 4]));
2222
0
                            }
2223
0
                            sumf[m][j] += sumi * GGML_CPU_E8M0_TO_FP32_HALF(b_ptr[l].e[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d[m]);
2224
0
                        }
2225
0
                    }
2226
0
                }
2227
0
            }
2228
0
            for (int m = 0; m < 4; m++) {
2229
0
                for (int j = 0; j < ncols_interleaved; j++)
2230
0
                    s[(y * 4 + m) * bs + x * ncols_interleaved + j] = sumf[m][j];
2231
0
            }
2232
0
        }
2233
0
    }
2234
0
}
2235
2236
0
void ggml_gemm_mxfp4_8x8_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
2237
0
    const int qk = QK8_0;
2238
0
    const int nb = n / qk;
2239
0
    const int ncols_interleaved = 8;
2240
0
    const int blocklen = 8;
2241
2242
0
    assert(n % qk == 0);
2243
0
    assert(nr % 4 == 0);
2244
0
    assert(nc % ncols_interleaved == 0);
2245
2246
0
    float sumf[4][8];
2247
0
    int sumi;
2248
2249
0
    for (int y = 0; y < nr / 4; y++) {
2250
0
        const block_q8_0x4 * a_ptr = (const block_q8_0x4 *) vy + (y * nb);
2251
0
        for (int x = 0; x < nc / ncols_interleaved; x++) {
2252
0
            const block_mxfp4x8 * b_ptr = (const block_mxfp4x8 *) vx + (x * nb);
2253
0
            for (int m = 0; m < 4; m++) {
2254
0
                for (int j = 0; j < ncols_interleaved; j++) sumf[m][j] = 0.0;
2255
0
            }
2256
0
            for (int l = 0; l < nb; l++) {
2257
0
                for (int k = 0; k < (qk / (2 * blocklen)); k++) {
2258
0
                    for (int m = 0; m < 4; m++) {
2259
0
                        for (int j = 0; j < ncols_interleaved; j++) {
2260
0
                            sumi = 0;
2261
0
                            for (int i = 0; i < blocklen; ++i) {
2262
0
                                const int v0 = kvalues_mxfp4[b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0x0F];
2263
0
                                const int v1 = kvalues_mxfp4[b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] >> 4];
2264
0
                                sumi += ((v0 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i]) +
2265
0
                                         (v1 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i + qk / 2 * 4]));
2266
0
                            }
2267
0
                            sumf[m][j] += sumi * GGML_CPU_E8M0_TO_FP32_HALF(b_ptr[l].e[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d[m]);
2268
0
                        }
2269
0
                    }
2270
0
                }
2271
0
            }
2272
0
            for (int m = 0; m < 4; m++) {
2273
0
                for (int j = 0; j < ncols_interleaved; j++)
2274
0
                    s[(y * 4 + m) * bs + x * ncols_interleaved + j] = sumf[m][j];
2275
0
            }
2276
0
        }
2277
0
    }
2278
0
}
2279
2280
void ggml_gemm_q8_0_4x4_q8_0_generic(int                        n,
2281
                                     float * GGML_RESTRICT      s,
2282
                                     size_t                     bs,
2283
                                     const void * GGML_RESTRICT vx,
2284
                                     const void * GGML_RESTRICT vy,
2285
                                     int                        nr,
2286
0
                                     int                        nc) {
2287
0
    const int qk                = QK8_0;
2288
0
    const int nb                = n / qk;
2289
0
    const int ncols_interleaved = 4;
2290
0
    const int blocklen          = 4;
2291
2292
0
    assert(n % qk == 0);
2293
0
    assert(nr % 4 == 0);
2294
0
    assert(nc % ncols_interleaved == 0);
2295
2296
0
    float sumf[4][4];
2297
0
    int   sumi;
2298
2299
0
    for (int y = 0; y < nr / 4; y++) {
2300
0
        const block_q8_0x4 * a_ptr = (const block_q8_0x4 *) vy + (y * nb);
2301
0
        for (int x = 0; x < nc / ncols_interleaved; x++) {
2302
0
            const block_q8_0x4 * b_ptr = (const block_q8_0x4 *) vx + (x * nb);
2303
0
            for (int m = 0; m < 4; m++) {
2304
0
                for (int j = 0; j < ncols_interleaved; j++) {
2305
0
                    sumf[m][j] = 0.0;
2306
0
                }
2307
0
            }
2308
0
            for (int l = 0; l < nb; l++) {
2309
0
                for (int k = 0; k < (qk / blocklen); k++) {
2310
0
                    for (int m = 0; m < 4; m++) {
2311
0
                        for (int j = 0; j < ncols_interleaved; j++) {
2312
0
                            sumi = 0;
2313
0
                            for (int i = 0; i < blocklen; ++i) {
2314
0
                                const int v0 = b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i];
2315
0
                                sumi += v0 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i];
2316
0
                            }
2317
0
                            sumf[m][j] +=
2318
0
                                sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d[m]);
2319
0
                        }
2320
0
                    }
2321
0
                }
2322
0
            }
2323
0
            for (int m = 0; m < 4; m++) {
2324
0
                for (int j = 0; j < ncols_interleaved; j++) {
2325
0
                    s[(y * 4 + m) * bs + x * ncols_interleaved + j] = sumf[m][j];
2326
0
                }
2327
0
            }
2328
0
        }
2329
0
    }
2330
0
}
2331
2332
2333
2334
void ggml_gemm_q8_0_4x8_q8_0_generic(int                        n,
2335
                                     float * GGML_RESTRICT      s,
2336
                                     size_t                     bs,
2337
                                     const void * GGML_RESTRICT vx,
2338
                                     const void * GGML_RESTRICT vy,
2339
                                     int                        nr,
2340
0
                                     int                        nc) {
2341
0
    const int qk                = QK8_0;
2342
0
    const int nb                = n / qk;
2343
0
    const int ncols_interleaved = 4;
2344
0
    const int blocklen          = 8;
2345
2346
0
    assert(n % qk == 0);
2347
0
    assert(nr % 4 == 0);
2348
0
    assert(nc % ncols_interleaved == 0);
2349
2350
0
    float sumf[4][4];
2351
0
    int   sumi;
2352
2353
0
    for (int y = 0; y < nr / 4; y++) {
2354
0
        const block_q8_0x4 * a_ptr = (const block_q8_0x4 *) vy + (y * nb);
2355
0
        for (int x = 0; x < nc / ncols_interleaved; x++) {
2356
0
            const block_q8_0x4 * b_ptr = (const block_q8_0x4 *) vx + (x * nb);
2357
0
            for (int m = 0; m < 4; m++) {
2358
0
                for (int j = 0; j < ncols_interleaved; j++) {
2359
0
                    sumf[m][j] = 0.0;
2360
0
                }
2361
0
            }
2362
0
            for (int l = 0; l < nb; l++) {
2363
0
                for (int k = 0; k < (qk / blocklen); k++) {
2364
0
                    for (int m = 0; m < 4; m++) {
2365
0
                        for (int j = 0; j < ncols_interleaved; j++) {
2366
0
                            sumi = 0;
2367
0
                            for (int i = 0; i < blocklen; ++i) {
2368
0
                                const int v0 = b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i];
2369
0
                                sumi += v0 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i];
2370
0
                            }
2371
0
                            sumf[m][j] +=
2372
0
                                sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d[m]);
2373
0
                        }
2374
0
                    }
2375
0
                }
2376
0
            }
2377
0
            for (int m = 0; m < 4; m++) {
2378
0
                for (int j = 0; j < ncols_interleaved; j++) {
2379
0
                    s[(y * 4 + m) * bs + x * ncols_interleaved + j] = sumf[m][j];
2380
0
                }
2381
0
            }
2382
0
        }
2383
0
    }
2384
0
}
2385
2386
// Only enable these for RISC-V.
2387
#if defined __riscv_zvfh
2388
void ggml_gemm_q4_0_16x1_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
2389
    const int qk = QK8_0;
2390
    const int nb = n / qk;
2391
    const int ncols_interleaved = 16;
2392
    const int blocklen = 1;
2393
2394
    assert (n % qk == 0);
2395
    assert (nr % 4 == 0);
2396
    assert (nc % ncols_interleaved == 0);
2397
2398
    UNUSED(s);
2399
    UNUSED(bs);
2400
    UNUSED(vx);
2401
    UNUSED(vy);
2402
    UNUSED(nr);
2403
    UNUSED(nc);
2404
    UNUSED(nb);
2405
    UNUSED(ncols_interleaved);
2406
    UNUSED(blocklen);
2407
2408
    float sumf[4][16];
2409
    int sumi;
2410
2411
    for (int y = 0; y < nr / 4; y++) {
2412
        const block_q8_0x4 * a_ptr = (const block_q8_0x4 *) vy + (y * nb);
2413
        for (int x = 0; x < nc / ncols_interleaved; x++) {
2414
            const block_q4_0x16 * b_ptr = (const block_q4_0x16 *) vx + (x * nb);
2415
            for (int m = 0; m < 4; m++) {
2416
                for (int j = 0; j < ncols_interleaved; j++) sumf[m][j] = 0.0;
2417
            }
2418
            for (int l = 0; l < nb; l++) {
2419
                for (int k = 0; k < (qk / (2 * blocklen)); k++) {
2420
                    for (int m = 0; m < 4; m++) {
2421
                        for (int j = 0; j < ncols_interleaved; j++) {
2422
                            sumi = 0;
2423
                            for (int i = 0; i < blocklen; ++i) {
2424
                                const int v0 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] << 4);
2425
                                const int v1 = (int8_t) (b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0xF0);
2426
                                sumi += ((v0 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i]) +
2427
                                         (v1 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i + qk / 2 * 4])) >> 4;
2428
                            }
2429
                            sumf[m][j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d[m]);
2430
                        }
2431
                    }
2432
                }
2433
            }
2434
            for (int m = 0; m < 4; m++) {
2435
                for (int j = 0; j < ncols_interleaved; j++)
2436
                    s[(y * 4 + m) * bs + x * ncols_interleaved + j] = sumf[m][j];
2437
            }
2438
        }
2439
    }
2440
}
2441
2442
void ggml_gemm_q4_K_16x1_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
2443
    const int qk = QK_K;
2444
    const int nb = n / qk;
2445
    const int ncols_interleaved = 16;
2446
    const int blocklen = 1;
2447
2448
    assert (n % qk == 0);
2449
    assert (nr % 4 == 0);
2450
    assert (nc % ncols_interleaved == 0);
2451
2452
    UNUSED(s);
2453
    UNUSED(bs);
2454
    UNUSED(vx);
2455
    UNUSED(vy);
2456
    UNUSED(nr);
2457
    UNUSED(nc);
2458
    UNUSED(nb);
2459
    UNUSED(ncols_interleaved);
2460
    UNUSED(blocklen);
2461
2462
    float sumf[4][16];
2463
    float sum_minf[4][16];
2464
    uint8_t scales[128];
2465
    uint8_t mins[128];
2466
    int sumi1;
2467
    int sumi2;
2468
    int sumi;
2469
2470
    for (int y = 0; y < nr / 4; y++) {
2471
        const block_q8_Kx4 * a_ptr = (const block_q8_Kx4 *) vy + (y * nb);
2472
        for (int x = 0; x < nc / ncols_interleaved; x++) {
2473
            const block_q4_Kx16 * b_ptr = (const block_q4_Kx16 *) vx + (x * nb);
2474
            for (int m = 0; m < 4; m++) {
2475
                for (int j = 0; j < ncols_interleaved; j++) {
2476
                    sumf[m][j] = 0.0;
2477
                    sum_minf[m][j] = 0.0;
2478
                }
2479
            }
2480
            for (int l = 0; l < nb; l++) {
2481
                for (int i = 0; i < 128; i++) {
2482
                    scales[i] = b_ptr[l].scales[i] & 0x0F;
2483
                    mins[i] = b_ptr[l].scales[i] >> 4;
2484
                }
2485
                for (int i = 0; i < 64; i++) {
2486
                    scales[i] |= (b_ptr[l].scales[128 + i] & 0x03) << 4;
2487
                    mins[i] |= (b_ptr[l].scales[128 + i] & 0x0C) << 2;
2488
                    scales[i + 64] |= (b_ptr[l].scales[128 + i] & 0x30);
2489
                    mins[i + 64] |= (b_ptr[l].scales[128 + i] & 0xC0) >> 2;
2490
                }
2491
2492
                for (int sb = 0; sb < 8; sb++) {
2493
                    uint8_t *min = &mins[sb * 16];
2494
                    for(int m = 0; m < 4; m++) {
2495
                        const int16_t bsums = a_ptr[l].bsums[sb * 8 + m] + a_ptr[l].bsums[sb * 8 + m + 4];
2496
                        for(int j = 0; j < ncols_interleaved; j++) {
2497
                            sum_minf[m][j] += min[j] * bsums * GGML_CPU_FP16_TO_FP32(b_ptr[l].dmin[j]) * a_ptr[l].d[m];
2498
                        }
2499
                    }
2500
                }
2501
2502
                for (int sb = 0; sb < 8; sb += 2) {
2503
                    uint8_t *scales_0 = &scales[sb * 16];
2504
                    uint8_t *scales_1 = &scales[(sb + 1) * 16];
2505
2506
                    for (int i = 0; i < QK4_0; i++) {
2507
                        for (int m = 0; m < 4; m++) {
2508
                            for (int j = 0; j < ncols_interleaved; j++) {
2509
                                sumi1 = 0;
2510
                                sumi2 = 0;
2511
                                sumi = 0;
2512
2513
                                const int v0 = (int8_t) (b_ptr[l].qs[sb * 256 + i * 16 + j] & 0xF);
2514
                                const int v1 = (int8_t) (b_ptr[l].qs[sb * 256 + i * 16 + j] >> 4);
2515
                                sumi1 = (v0 * a_ptr[l].qs[sb * 4 * 32 + i * 4 + m]);
2516
                                sumi2 = (v1 * a_ptr[l].qs[sb * 4 * 32 + 32 * 4 + i * 4 + m]);
2517
                                sumi1 = sumi1 * scales_0[j];
2518
                                sumi2 = sumi2 * scales_1[j];
2519
                                sumi += sumi1 + sumi2;
2520
2521
                                sumf[m][j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * a_ptr[l].d[m];
2522
                            }
2523
                        }
2524
                    }
2525
                }
2526
            }
2527
            for (int m = 0; m < 4; m++) {
2528
                for (int j = 0; j < ncols_interleaved; j++) {
2529
                    s[(y * 4 + m) * bs + x * ncols_interleaved + j] = sumf[m][j] - sum_minf[m][j];
2530
                }
2531
            }
2532
        }
2533
    }
2534
}
2535
2536
void ggml_gemm_iq4_nl_16x1_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
2537
    const int qk = QK8_0;
2538
    const int nb = n / qk;
2539
    const int ncols_interleaved = 16;
2540
    const int blocklen = 1;
2541
2542
    assert(n % qk == 0);
2543
    assert(nr % 4 == 0);
2544
    assert(nc % ncols_interleaved == 0);
2545
2546
    float sumf[4][16];
2547
    int sumi;
2548
2549
    for (int y = 0; y < nr / 4; y++) {
2550
        const block_q8_0x4 * a_ptr = (const block_q8_0x4 *) vy + (y * nb);
2551
        for (int x = 0; x < nc / ncols_interleaved; x++) {
2552
            const block_iq4_nlx16 * b_ptr = (const block_iq4_nlx16 *) vx + (x * nb);
2553
            for (int m = 0; m < 4; m++) {
2554
                for (int j = 0; j < ncols_interleaved; j++) sumf[m][j] = 0.0;
2555
            }
2556
            for (int l = 0; l < nb; l++) {
2557
                for (int k = 0; k < (qk / (2 * blocklen)); k++) {
2558
                    for (int m = 0; m < 4; m++) {
2559
                        for (int j = 0; j < ncols_interleaved; j++) {
2560
                            sumi = 0;
2561
                            for (int i = 0; i < blocklen; ++i) {
2562
                                const int v0 = kvalues_iq4nl[b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] & 0x0F];
2563
                                const int v1 = kvalues_iq4nl[b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i] >> 4];
2564
                                sumi += ((v0 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i]) +
2565
                                         (v1 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i + (qk / 2) * 4]));
2566
                            }
2567
                            sumf[m][j] += sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d[m]);
2568
                        }
2569
                    }
2570
                }
2571
            }
2572
            for (int m = 0; m < 4; m++) {
2573
                for (int j = 0; j < ncols_interleaved; j++)
2574
                    s[(y * 4 + m) * bs + x * ncols_interleaved + j] = sumf[m][j];
2575
            }
2576
        }
2577
    }
2578
}
2579
2580
void ggml_gemm_q8_0_16x1_q8_0_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
2581
    const int qk                = QK8_0;
2582
    const int nb                = n / qk;
2583
    const int ncols_interleaved = 16;
2584
    const int blocklen          = 1;
2585
2586
    assert(n % qk == 0);
2587
    assert(nr % 4 == 0);
2588
    assert(nc % ncols_interleaved == 0);
2589
2590
    float sumf[4][16];
2591
    int   sumi;
2592
2593
    for (int y = 0; y < nr / 4; y++) {
2594
        const block_q8_0x4 * a_ptr = (const block_q8_0x4 *) vy + (y * nb);
2595
        for (int x = 0; x < nc / ncols_interleaved; x++) {
2596
            const block_q8_0x16 * b_ptr = (const block_q8_0x16 *) vx + (x * nb);
2597
            for (int m = 0; m < 4; m++) {
2598
                for (int j = 0; j < ncols_interleaved; j++) {
2599
                    sumf[m][j] = 0.0;
2600
                }
2601
            }
2602
            for (int l = 0; l < nb; l++) {
2603
                for (int k = 0; k < (qk / blocklen); k++) {
2604
                    for (int m = 0; m < 4; m++) {
2605
                        for (int j = 0; j < ncols_interleaved; j++) {
2606
                            sumi = 0;
2607
                            for (int i = 0; i < blocklen; ++i) {
2608
                                const int v0 = b_ptr[l].qs[k * ncols_interleaved * blocklen + j * blocklen + i];
2609
                                sumi += v0 * a_ptr[l].qs[k * 4 * blocklen + m * blocklen + i];
2610
                            }
2611
                            sumf[m][j] +=
2612
                                sumi * GGML_CPU_FP16_TO_FP32(b_ptr[l].d[j]) * GGML_CPU_FP16_TO_FP32(a_ptr[l].d[m]);
2613
                        }
2614
                    }
2615
                }
2616
            }
2617
            for (int m = 0; m < 4; m++) {
2618
                for (int j = 0; j < ncols_interleaved; j++) {
2619
                    s[(y * 4 + m) * bs + x * ncols_interleaved + j] = sumf[m][j];
2620
                }
2621
            }
2622
        }
2623
    }
2624
}
2625
2626
2627
void ggml_gemm_q2_K_16x1_q8_K_generic(int n, float * GGML_RESTRICT s, size_t bs, const void * GGML_RESTRICT vx, const void * GGML_RESTRICT vy, int nr, int nc) {
2628
    assert(n % QK_K == 0);
2629
    assert(nr % 4 == 0);
2630
    assert(nc % 16 == 0);
2631
    const int nb = n / QK_K;
2632
    const block_q2_Kx16 * x = (const block_q2_Kx16 *)vx;
2633
    const block_q8_Kx4  * y = (const block_q8_Kx4 *)vy;
2634
2635
    const int sb_perm[16] = {
2636
        0, 4, 1, 5, 2, 6, 3, 7,
2637
        8, 12, 9, 13, 10, 14, 11, 15
2638
    };
2639
2640
    // Iterate Rows in tiles of 4
2641
    for (int row_tile = 0; row_tile < nr; row_tile += 4) {
2642
        // Iterate Columns in tiles of 16
2643
        for (int col_tile = 0; col_tile < nc; col_tile += 16) {
2644
2645
            const block_q2_Kx16 * x_ptr = x + (col_tile / 16) * nb;
2646
            const block_q8_Kx4  * y_ptr = y + (row_tile / 4) * nb;
2647
2648
            float sumf[4][16];
2649
            memset(sumf, 0, sizeof(sumf));
2650
2651
            for (int k_block = 0; k_block < nb; ++k_block) {
2652
                int32_t isum[4][16];
2653
                int32_t summs[4][16];
2654
                memset(isum, 0, sizeof(isum));
2655
                memset(summs, 0, sizeof(summs));
2656
2657
                const uint8_t * qs_rhs = x_ptr[k_block].qs;
2658
                const uint8_t * sc_rhs = x_ptr[k_block].scales;
2659
                const int8_t  * qs_lhs = y_ptr[k_block].qs;
2660
                const int16_t * bs_lhs = y_ptr[k_block].bsums;
2661
2662
                for (int sb = 0; sb < 16; ++sb) {
2663
                    int scale_offset = sb_perm[sb] * 16;
2664
2665
                    int byte_base;
2666
                    if (sb < 8) byte_base = (sb % 2 == 0) ? 0 : 16;
2667
                    else        byte_base = (sb % 2 == 0) ? 32 : 48;
2668
                    int shift = ((sb / 2) % 4) * 2;
2669
2670
                    for (int col = 0; col < 16; ++col) {
2671
                        uint8_t sc_val = sc_rhs[scale_offset + col];
2672
                        int32_t d_sb = sc_val & 0xF;
2673
                        int32_t m_sb = sc_val >> 4;
2674
2675
                        // Correction Term
2676
                        for (int r = 0; r < 4; ++r) {
2677
                            int bsum_idx = (sb / 4) * 16 + r * 4 + (sb % 4);
2678
                            summs[r][col] += bs_lhs[bsum_idx] * m_sb;
2679
                        }
2680
2681
                        // Main Dot Product
2682
                        for (int l = 0; l < 16; ++l) {
2683
                            int qs_idx = (byte_base + l) * 16 + col;
2684
                            uint8_t q2_val = (qs_rhs[qs_idx] >> shift) & 3;
2685
2686
                            // Calculate Q8 index for this specific k and row
2687
                            int k = sb * 16 + l;
2688
                            int q8_idx = (k / 4) * 16 + (k % 4);
2689
2690
                            for (int r = 0; r < 4; ++r) {
2691
                                // Add r*4 to jump to the correct row within the 4x4 chunk
2692
                                int8_t q8_val = qs_lhs[q8_idx + r * 4];
2693
                                isum[r][col] += q8_val * q2_val * d_sb;
2694
                            }
2695
                        }
2696
                    }
2697
                }
2698
2699
                // Finalize K-Block
2700
                for (int col = 0; col < 16; ++col) {
2701
                    float d_rhs = GGML_FP16_TO_FP32(x_ptr[k_block].d[col]);
2702
                    float dm_rhs = GGML_FP16_TO_FP32(x_ptr[k_block].dmin[col]);
2703
2704
                    for (int r = 0; r < 4; ++r) {
2705
                        float d_lhs = y_ptr[k_block].d[r];
2706
                        float d_all = d_lhs * d_rhs;
2707
                        float d_min = d_lhs * dm_rhs;
2708
                        sumf[r][col] += (isum[r][col] * d_all) - (summs[r][col] * d_min);
2709
                    }
2710
                }
2711
            }
2712
2713
            for (int r = 0; r < 4; ++r) {
2714
                for (int col = 0; col < 16; ++col) {
2715
                    s[(row_tile + r) * bs + (col_tile + col)] = sumf[r][col];
2716
                }
2717
            }
2718
        }
2719
    }
2720
}
2721
#endif
2722
2723
} // extern "C"
2724
2725
0
static block_q8_0x4 make_block_q8_0x4(block_q8_0 * in, unsigned int blck_size_interleave) {
2726
0
    block_q8_0x4 out;
2727
2728
0
    for (int i = 0; i < 4; i++) {
2729
0
        out.d[i] = in[i].d;
2730
0
    }
2731
2732
0
    const int end = QK8_0 * 4 / blck_size_interleave;
2733
0
    for (int i = 0; i < end; ++i) {
2734
0
        int src_id     = i % 4;
2735
0
        int src_offset = (i / 4) * blck_size_interleave;
2736
0
        int dst_offset = i * blck_size_interleave;
2737
0
        memcpy(&out.qs[dst_offset], &in[src_id].qs[src_offset], blck_size_interleave);
2738
0
    }
2739
0
    return out;
2740
0
}
2741
2742
0
static block_q4_0x4 make_block_q4_0x4(block_q4_0 * in, unsigned int blck_size_interleave) {
2743
0
    block_q4_0x4 out;
2744
2745
0
    for (int i = 0; i < 4; i++) {
2746
0
        out.d[i] = in[i].d;
2747
0
    }
2748
2749
0
    const int end = QK4_0 * 2 / blck_size_interleave;
2750
2751
0
    if (blck_size_interleave == 8) {
2752
0
        const uint64_t xor_mask = 0x8888888888888888ULL;
2753
0
        for (int i = 0; i < end; ++i) {
2754
0
            int src_id = i % 4;
2755
0
            int src_offset = (i / 4) * blck_size_interleave;
2756
0
            int dst_offset = i * blck_size_interleave;
2757
2758
0
            uint64_t elems;
2759
            // Using memcpy to avoid unaligned memory accesses
2760
0
            memcpy(&elems, &in[src_id].qs[src_offset], sizeof(uint64_t));
2761
0
            elems ^= xor_mask;
2762
0
            memcpy(&out.qs[dst_offset], &elems, sizeof(uint64_t));
2763
0
        }
2764
0
    } else if (blck_size_interleave == 4) {
2765
0
        const uint32_t xor_mask = 0x88888888;
2766
0
        for (int i = 0; i < end; ++i) {
2767
0
            int src_id = i % 4;
2768
0
            int src_offset = (i / 4) * blck_size_interleave;
2769
0
            int dst_offset = i * blck_size_interleave;
2770
2771
0
            uint32_t elems;
2772
0
            memcpy(&elems, &in[src_id].qs[src_offset], sizeof(uint32_t));
2773
0
            elems ^= xor_mask;
2774
0
            memcpy(&out.qs[dst_offset], &elems, sizeof(uint32_t));
2775
0
        }
2776
0
    } else {
2777
0
        GGML_ASSERT(false);
2778
0
    }
2779
2780
0
    return out;
2781
0
}
2782
2783
// interleave 8 block_q4_0s in blocks of blck_size_interleave
2784
// returns an interleaved block_q4_0x8
2785
// in the interleaved block_q4_0x8, place deltas for 8 block_q4_0 blocks
2786
// first, then interleave quants from 8 block_q4_0s in blocks of blck_size_interleave
2787
0
static block_q4_0x8 make_block_q4_0x8(block_q4_0 * in, unsigned int blck_size_interleave) {
2788
0
    block_q4_0x8 out;
2789
2790
0
    for (int i = 0; i < 8; i++) {
2791
0
        out.d[i] = in[i].d;
2792
0
    }
2793
2794
0
    const int end = QK4_0 * 4 / blck_size_interleave;
2795
0
    const uint64_t xor_mask = 0x8888888888888888ULL;
2796
2797
0
    for (int i = 0; i < end; ++i) {
2798
0
        int src_id = i % 8;
2799
0
        int src_offset = (i / 8) * blck_size_interleave;
2800
0
        int dst_offset = i * blck_size_interleave;
2801
2802
0
        uint64_t elems;
2803
0
        memcpy(&elems, &in[src_id].qs[src_offset], sizeof(uint64_t));
2804
0
        elems ^= xor_mask;
2805
0
        memcpy(&out.qs[dst_offset], &elems, sizeof(uint64_t));
2806
0
    }
2807
2808
0
    return out;
2809
0
}
2810
2811
0
static block_q4_0x16 make_block_q4_0x16(block_q4_0 * in, unsigned int blck_size_interleave) {
2812
0
    block_q4_0x16 out;
2813
0
2814
0
    for (int i = 0; i < 16; i++) {
2815
0
        out.d[i] = in[i].d;
2816
0
    }
2817
0
2818
0
    const int end = QK4_0 * 8 / blck_size_interleave;
2819
0
2820
0
    if (blck_size_interleave == 1) {
2821
0
        const uint8_t xor_mask = 0x88;
2822
0
        for (int i = 0; i < end; ++i) {
2823
0
            int src_id = i % 16;
2824
0
            int src_offset = i / 16;
2825
0
            int dst_offset = i;
2826
0
2827
0
            out.qs[dst_offset] = in[src_id].qs[src_offset] ^ xor_mask;
2828
0
        }
2829
0
    } else {
2830
0
        GGML_ASSERT(false);
2831
0
    }
2832
0
2833
0
    return out;
2834
0
}
2835
2836
0
static block_q4_Kx8 make_block_q4_Kx8(block_q4_K * in, unsigned int blck_size_interleave) {
2837
0
    block_q4_Kx8 out;
2838
    //Delta(scale) and dmin values of the eight Q4_K structures are copied onto the output interleaved structure
2839
0
    for (int i = 0; i < 8; i++) {
2840
0
        out.d[i] = in[i].GGML_COMMON_AGGR_U.GGML_COMMON_AGGR_S.d;
2841
0
    }
2842
2843
0
    for (int i = 0; i < 8; i++) {
2844
0
        out.dmin[i] = in[i].GGML_COMMON_AGGR_U.GGML_COMMON_AGGR_S.dmin;
2845
0
    }
2846
2847
0
    const int end = QK_K * 4 / blck_size_interleave;
2848
2849
    // Interleave Q4_K quants by taking 8 bytes at a time
2850
0
    for (int i = 0; i < end; ++i) {
2851
0
        int src_id = i % 8;
2852
0
        int src_offset = (i / 8) * blck_size_interleave;
2853
0
        int dst_offset = i * blck_size_interleave;
2854
2855
        // buffer large enough for the max interleave block size (8 bytes)
2856
0
        uint64_t elems;
2857
0
        memcpy(&elems, &in[src_id].qs[src_offset], blck_size_interleave);
2858
0
        memcpy(&out.qs[dst_offset], &elems, blck_size_interleave);
2859
0
    }
2860
2861
    // The below logic is designed so as to unpack and rearrange scales and mins values in Q4_K
2862
    // Currently the Q4_K structure has 8 scales and 8 mins packed in 12 bytes ( 6 bits for each value)
2863
    // The output Q4_Kx8 structure has 96 bytes
2864
    // Every 12 byte is packed such that it contains scales and mins for corresponding sub blocks from Q4_K structure
2865
    // For eg - First 12 bytes contains 8 scales and 8 mins - each of first sub block from different Q4_K structures
2866
0
    uint8_t s[8], m[8];
2867
2868
0
    for (int i = 0; i < 4; i++) {
2869
0
        for (int j = 0; j < 8; j++) {
2870
0
            s[j] = in[j].scales[i] & 63;
2871
0
            m[j] = in[j].scales[i + 4] & 63;
2872
0
        }
2873
2874
0
        out.scales[i * 12]      = (s[0] & 63) + ((s[4] & 48) << 2);
2875
0
        out.scales[i * 12 + 1]  = (s[1] & 63) + ((s[5] & 48) << 2);
2876
0
        out.scales[i * 12 + 2]  = (s[2] & 63) + ((s[6] & 48) << 2);
2877
0
        out.scales[i * 12 + 3]  = (s[3] & 63) + ((s[7] & 48) << 2);
2878
0
        out.scales[i * 12 + 4]  = (m[0] & 63) + ((m[4] & 48) << 2);
2879
0
        out.scales[i * 12 + 5]  = (m[1] & 63) + ((m[5] & 48) << 2);
2880
0
        out.scales[i * 12 + 6]  = (m[2] & 63) + ((m[6] & 48) << 2);
2881
0
        out.scales[i * 12 + 7]  = (m[3] & 63) + ((m[7] & 48) << 2);
2882
0
        out.scales[i * 12 + 8]  = (s[4] & 15) + ((m[4] & 15) << 4);
2883
0
        out.scales[i * 12 + 9]  = (s[5] & 15) + ((m[5] & 15) << 4);
2884
0
        out.scales[i * 12 + 10] = (s[6] & 15) + ((m[6] & 15) << 4);
2885
0
        out.scales[i * 12 + 11] = (s[7] & 15) + ((m[7] & 15) << 4);
2886
2887
0
    }
2888
2889
0
    for (int i = 0; i < 4; i++) {
2890
0
        for (int j = 0; j < 8; j++) {
2891
0
            s[j] = ((in[j].scales[i] & 192) >> 2) | (in[j].scales[i+8] & 15);
2892
0
            m[j] = ((in[j].scales[i + 4] & 192) >> 2) | ((in[j].scales[i+8] & 240) >> 4);
2893
0
        }
2894
2895
0
        out.scales[i * 12 + 48] = (s[0] & 63) + ((s[4] & 48) << 2);
2896
0
        out.scales[i * 12 + 49] = (s[1] & 63) + ((s[5] & 48) << 2);
2897
0
        out.scales[i * 12 + 50] = (s[2] & 63) + ((s[6] & 48) << 2);
2898
0
        out.scales[i * 12 + 51] = (s[3] & 63) + ((s[7] & 48) << 2);
2899
0
        out.scales[i * 12 + 52] = (m[0] & 63) + ((m[4] & 48) << 2);
2900
0
        out.scales[i * 12 + 53] = (m[1] & 63) + ((m[5] & 48) << 2);
2901
0
        out.scales[i * 12 + 54] = (m[2] & 63) + ((m[6] & 48) << 2);
2902
0
        out.scales[i * 12 + 55] = (m[3] & 63) + ((m[7] & 48) << 2);
2903
0
        out.scales[i * 12 + 56] = (s[4] & 15) + ((m[4] & 15) << 4);
2904
0
        out.scales[i * 12 + 57] = (s[5] & 15) + ((m[5] & 15) << 4);
2905
0
        out.scales[i * 12 + 58] = (s[6] & 15) + ((m[6] & 15) << 4);
2906
0
        out.scales[i * 12 + 59] = (s[7] & 15) + ((m[7] & 15) << 4);
2907
2908
0
    }
2909
2910
0
    return out;
2911
0
}
2912
2913
0
static block_q4_Kx16 make_block_q4_Kx16(block_q4_K * in, unsigned int blck_size_interleave) {
2914
0
    block_q4_Kx16 out;
2915
0
    //Delta(scale) and dmin values of the 16 Q4_K structures are copied onto the output interleaved structure
2916
0
    for (int i = 0; i < 16; i++) {
2917
0
        out.d[i] = in[i].GGML_COMMON_AGGR_U.GGML_COMMON_AGGR_S.d;
2918
0
    }
2919
0
2920
0
    for (int i = 0; i < 16; i++) {
2921
0
        out.dmin[i] = in[i].GGML_COMMON_AGGR_U.GGML_COMMON_AGGR_S.dmin;
2922
0
    }
2923
0
2924
0
    const int end = QK_K * 8 / blck_size_interleave;
2925
0
2926
0
    if (blck_size_interleave == 1) {
2927
0
        for (int i = 0; i < end; ++i) {
2928
0
            int src_id = i % 16;
2929
0
            int src_offset = i / 16;
2930
0
            int dst_offset = i;
2931
0
2932
0
            out.qs[dst_offset] = in[src_id].qs[src_offset];
2933
0
        }
2934
0
2935
0
        // RVV repacking.
2936
0
        //
2937
0
        // Extract sums and mins for all 8 sub-blocks for each block of Q4_K.
2938
0
        uint8_t s[128], m[128];
2939
0
        for (int i = 0; i < 4; i++) {
2940
0
            for (int j = 0; j < 16; j++) {
2941
0
                s[i * 16 + j] = in[j].scales[i] & 63;
2942
0
                m[i * 16 + j] = in[j].scales[i + 4] & 63;
2943
0
            }
2944
0
        }
2945
0
        for (int i = 0; i < 4; i++) {
2946
0
            for (int j = 0; j < 16; j++) {
2947
0
                s[64 + i * 16 + j] = ((in[j].scales[i] & 192) >> 2) | (in[j].scales[i+8] & 15);
2948
0
                m[64 + i * 16 + j] = ((in[j].scales[i + 4] & 192) >> 2) | ((in[j].scales[i+8] & 240) >> 4);
2949
0
            }
2950
0
        }
2951
0
2952
0
        for (int i = 0; i < 128; i++) {
2953
0
            out.scales[i] = (s[i] & 15) | ((m[i] & 15) << 4);
2954
0
        }
2955
0
        for (int i = 0; i < 64; i++) {
2956
0
            out.scales[128 + i] = ((s[i] & 48) >> 4) | ((m[i] & 48) >> 2) | (s[64 + i] & 48) | ((m[64 + i] & 48) << 2);
2957
0
        }
2958
0
    } else {
2959
0
        GGML_ASSERT(false);
2960
0
    }
2961
0
2962
0
    return out;
2963
0
}
2964
2965
0
static block_q2_Kx8 make_block_q2_Kx8(block_q2_K * in, unsigned int blck_size_interleave) {
2966
0
    block_q2_Kx8 out;
2967
2968
    // Delta(scale) and dmin values of the eight Q2_K structures are copied onto the output interleaved structure
2969
0
    for (int i = 0; i < 8; i++) {
2970
0
        out.d[i] = in[i].GGML_COMMON_AGGR_U.GGML_COMMON_AGGR_S.d;
2971
0
    }
2972
2973
0
    for (int i = 0; i < 8; i++) {
2974
0
        out.dmin[i] = in[i].GGML_COMMON_AGGR_U.GGML_COMMON_AGGR_S.dmin;
2975
0
    }
2976
2977
0
    const int end = QK_K * 2 / blck_size_interleave;
2978
2979
    // Interleave Q2_K quants by taking 8 bytes at a time
2980
0
    for (int i = 0; i < end; ++i) {
2981
0
        int src_id = i % 8;
2982
0
        int src_offset = (i / 8) * blck_size_interleave;
2983
0
        int dst_offset = i * blck_size_interleave;
2984
2985
0
        uint64_t elems;
2986
0
        memcpy(&elems, &in[src_id].qs[src_offset], sizeof(uint64_t));
2987
0
        memcpy(&out.qs[dst_offset], &elems, sizeof(uint64_t));
2988
0
    }
2989
2990
    // The below logic is designed so as to unpack and rearrange scales and mins values in Q2_K
2991
    // Currently the Q2_K structure has 16 scales and 16 mins packed in 16 bytes ( 4 bits for each value)
2992
    // The output Q2_Kx8 structure has 128 bytes for storing scales and mins
2993
    // Every 16 byte is packed such that it contains scales and mins for corresponding sub blocks from Q2_K structure
2994
    // For eg - First 16 bytes contains 16 scales and 16 mins - each of first and second sub blocks from different Q2_K structures
2995
2996
0
    for (int i = 0; i < 128; i++) {
2997
        // Index for selecting which q2k super block
2998
0
        int src1 = (i % 16) / 2;
2999
        // Index for selecting scale
3000
0
        int src2 = ((i / 16) * 2) + (i % 2);
3001
3002
0
        out.scales[i] = in[src1].scales[src2];
3003
0
    }
3004
0
    return out;
3005
0
}
3006
3007
0
static block_q5_Kx8 make_block_q5_Kx8(block_q5_K * in, unsigned int blck_size_interleave) {
3008
0
    block_q5_Kx8 out;
3009
    //Delta(scale) and dmin values of the eight Q5_K structures are copied onto the output interleaved structure
3010
0
    for (int i = 0; i < 8; i++) {
3011
0
        out.d[i] = in[i].GGML_COMMON_AGGR_U.GGML_COMMON_AGGR_S.d;
3012
0
    }
3013
3014
0
    for (int i = 0; i < 8; i++) {
3015
0
        out.dmin[i] = in[i].GGML_COMMON_AGGR_U.GGML_COMMON_AGGR_S.dmin;
3016
0
    }
3017
3018
0
    const int end = QK_K * 4 / blck_size_interleave;
3019
3020
    // Interleave Q5_K quants by taking blck_size_interleave bytes at a time
3021
0
    for (int i = 0; i < end; ++i) {
3022
0
        int src_id     = i % 8;
3023
0
        int src_offset = (i / 8) * blck_size_interleave;
3024
0
        int dst_offset = i * blck_size_interleave;
3025
3026
0
        memcpy(&out.qs[dst_offset], &in[src_id].qs[src_offset], blck_size_interleave);
3027
0
    }
3028
3029
    // Repeat for high bits with the same chunk size, since
3030
    // the high bits are interleaved in Q5_K and the index is
3031
    // qh_idx = (qs_idx % 32);
3032
    // qh_val = qh[qh_idx] >> (qs_idx / 32);
3033
0
    for (int i = 0; i < end / 4; ++i) {
3034
0
        int src_id     = i % 8;
3035
0
        int src_offset = (i / 8) * blck_size_interleave;
3036
0
        int dst_offset = i * blck_size_interleave;
3037
3038
0
        memcpy(&out.qh[dst_offset], &in[src_id].qh[src_offset], blck_size_interleave);
3039
0
    }
3040
3041
    // The below logic is copied over from Q4_K
3042
    // The point is to unpack all the scales and mins for each sub block every time we load 12 bytes.
3043
    // Currently the Q5_K structure has 8 scales and 8 mins packed in 12 bytes ( 6 bits for each value)
3044
    // The output Q5_Kx8 structure has 96 bytes
3045
    // Every 12 byte is packed such that it contains scales and mins for corresponding sub blocks from Q5_K structure
3046
    // For eg - First 12 bytes contains 8 scales and 8 mins - each of first sub block from different Q5_K structures
3047
0
    uint8_t s[8], m[8];
3048
3049
0
    for (int i = 0; i < 4; i++) {
3050
0
        for (int j = 0; j < 8; j++) {
3051
0
            s[j] = in[j].scales[i] & 63;
3052
0
            m[j] = in[j].scales[i + 4] & 63;
3053
0
        }
3054
3055
0
        out.scales[i * 12]      = (s[0] & 63) + ((s[4] & 48) << 2);
3056
0
        out.scales[i * 12 + 1]  = (s[1] & 63) + ((s[5] & 48) << 2);
3057
0
        out.scales[i * 12 + 2]  = (s[2] & 63) + ((s[6] & 48) << 2);
3058
0
        out.scales[i * 12 + 3]  = (s[3] & 63) + ((s[7] & 48) << 2);
3059
0
        out.scales[i * 12 + 4]  = (m[0] & 63) + ((m[4] & 48) << 2);
3060
0
        out.scales[i * 12 + 5]  = (m[1] & 63) + ((m[5] & 48) << 2);
3061
0
        out.scales[i * 12 + 6]  = (m[2] & 63) + ((m[6] & 48) << 2);
3062
0
        out.scales[i * 12 + 7]  = (m[3] & 63) + ((m[7] & 48) << 2);
3063
0
        out.scales[i * 12 + 8]  = (s[4] & 15) + ((m[4] & 15) << 4);
3064
0
        out.scales[i * 12 + 9]  = (s[5] & 15) + ((m[5] & 15) << 4);
3065
0
        out.scales[i * 12 + 10] = (s[6] & 15) + ((m[6] & 15) << 4);
3066
0
        out.scales[i * 12 + 11] = (s[7] & 15) + ((m[7] & 15) << 4);
3067
0
    }
3068
3069
0
    for (int i = 0; i < 4; i++) {
3070
0
        for (int j = 0; j < 8; j++) {
3071
0
            s[j] = ((in[j].scales[i] & 192) >> 2) | (in[j].scales[i + 8] & 15);
3072
0
            m[j] = ((in[j].scales[i + 4] & 192) >> 2) | ((in[j].scales[i + 8] & 240) >> 4);
3073
0
        }
3074
3075
0
        out.scales[i * 12 + 48] = (s[0] & 63) + ((s[4] & 48) << 2);
3076
0
        out.scales[i * 12 + 49] = (s[1] & 63) + ((s[5] & 48) << 2);
3077
0
        out.scales[i * 12 + 50] = (s[2] & 63) + ((s[6] & 48) << 2);
3078
0
        out.scales[i * 12 + 51] = (s[3] & 63) + ((s[7] & 48) << 2);
3079
0
        out.scales[i * 12 + 52] = (m[0] & 63) + ((m[4] & 48) << 2);
3080
0
        out.scales[i * 12 + 53] = (m[1] & 63) + ((m[5] & 48) << 2);
3081
0
        out.scales[i * 12 + 54] = (m[2] & 63) + ((m[6] & 48) << 2);
3082
0
        out.scales[i * 12 + 55] = (m[3] & 63) + ((m[7] & 48) << 2);
3083
0
        out.scales[i * 12 + 56] = (s[4] & 15) + ((m[4] & 15) << 4);
3084
0
        out.scales[i * 12 + 57] = (s[5] & 15) + ((m[5] & 15) << 4);
3085
0
        out.scales[i * 12 + 58] = (s[6] & 15) + ((m[6] & 15) << 4);
3086
0
        out.scales[i * 12 + 59] = (s[7] & 15) + ((m[7] & 15) << 4);
3087
0
    }
3088
3089
0
    return out;
3090
0
}
3091
3092
0
static block_q6_Kx8 make_block_q6_Kx8(block_q6_K * in, unsigned int blck_size_interleave) {
3093
0
    block_q6_Kx8  out;
3094
0
    constexpr int n_blocks = 8;  // Kx8
3095
0
    for (int i = 0; i < n_blocks; i++) {
3096
0
        out.d[i] = in[i].d;
3097
0
    }
3098
3099
0
    const int end_ls = QK_K * 4 / blck_size_interleave;
3100
    // Interleave Q6_K quants by taking blck_size_interleave bytes at a time
3101
0
    for (int i = 0; i < end_ls; ++i) {
3102
0
        int src_id     = i % n_blocks;
3103
0
        int src_offset = (i / n_blocks) * blck_size_interleave;
3104
0
        int dst_offset = i * blck_size_interleave;
3105
3106
0
        uint64_t elem_ls;
3107
0
        memcpy(&elem_ls, &in[src_id].ql[src_offset], blck_size_interleave);
3108
0
        memcpy(&out.ql[dst_offset], &elem_ls, blck_size_interleave);
3109
0
    }
3110
3111
    // Interleave high bits using same chunk size as low bits
3112
0
    const int end_hs = end_ls / 2;
3113
0
    for (int i = 0; i < end_hs; ++i) {
3114
0
        int src_id     = i % n_blocks;
3115
0
        int src_offset = (i / n_blocks) * blck_size_interleave;
3116
0
        int dst_offset = i * blck_size_interleave;
3117
3118
0
        uint64_t elem_hs;
3119
0
        memcpy(&elem_hs, &in[src_id].qh[src_offset], blck_size_interleave);
3120
0
        memcpy(&out.qh[dst_offset], &elem_hs, blck_size_interleave);
3121
0
    }
3122
3123
    // The below logic is designed so as to unpack and rearrange scales in Q6_K
3124
    // The output Q6_Kx8 structure interleaves the 8 bit scales in the same fashion as the quants
3125
    // Q6_K structure has an 8-bit scale per 16 elements -> 16 scales
3126
    // scales: [0 bl0 0 bl1 ... 0 bl7][1 bl0 ... 1 bl7] ... [15 bl0 ... 15 bl7]  (bl = block)
3127
0
    constexpr int n_scales = QK_K / 16;
3128
3129
0
    for (int i = 0; i < n_blocks; i++) {
3130
0
        for (int j = 0; j < n_scales; j++) {
3131
0
            out.scales[j * n_blocks + i] = in[i].scales[j];
3132
0
        }
3133
0
    }
3134
3135
0
    return out;
3136
0
}
3137
3138
0
static block_q2_Kx16 make_block_q2_Kx16(const block_q2_K * in, unsigned int blck_size_interleave) {
3139
0
    block_q2_Kx16 out;
3140
0
    constexpr int N_COLS = 16;
3141
0
3142
0
    // 1. Copy Super-Scales (d) and Super-Mins (dmin)
3143
0
    for (int i = 0; i < N_COLS; i++) {
3144
0
        out.d[i]    = in[i].GGML_COMMON_AGGR_U.GGML_COMMON_AGGR_S.d;
3145
0
        out.dmin[i] = in[i].GGML_COMMON_AGGR_U.GGML_COMMON_AGGR_S.dmin;
3146
0
    }
3147
0
3148
0
    // 2. Interleave Q2_K Data
3149
0
    const int bytes_per_col = 64;
3150
0
    const int total_bytes = N_COLS * bytes_per_col;
3151
0
    const int end = total_bytes / blck_size_interleave;
3152
0
3153
0
    for (int i = 0; i < end; ++i) {
3154
0
        int src_col_id = i % N_COLS;
3155
0
        int src_offset = (i / N_COLS) * blck_size_interleave;
3156
0
        int dst_offset = i * blck_size_interleave;
3157
0
        memcpy(&out.qs[dst_offset], &in[src_col_id].qs[src_offset], blck_size_interleave);
3158
0
    }
3159
0
3160
0
    // 3. Repack Scales into the Optimized "Sequential-Parallel" Layout
3161
0
    int out_idx = 0;
3162
0
3163
0
    // Arrays define the sub-block order for each group
3164
0
    const int even_low_sbs[]  = {0, 2, 4, 6};
3165
0
    const int odd_low_sbs[]   = {1, 3, 5, 7};
3166
0
    const int even_high_sbs[] = {8, 10, 12, 14};
3167
0
    const int odd_high_sbs[]  = {9, 11, 13, 15};
3168
0
3169
0
    // Pack Group 1: Even-Low
3170
0
    for (int sb : even_low_sbs) {
3171
0
        for (int col = 0; col < N_COLS; col++) {
3172
0
            out.scales[out_idx++] = in[col].scales[sb];
3173
0
        }
3174
0
    }
3175
0
3176
0
    // Pack Group 2: Odd-Low
3177
0
    for (int sb : odd_low_sbs) {
3178
0
        for (int col = 0; col < N_COLS; col++) {
3179
0
            out.scales[out_idx++] = in[col].scales[sb];
3180
0
        }
3181
0
    }
3182
0
3183
0
    // Pack Group 3: Even-High
3184
0
    for (int sb : even_high_sbs) {
3185
0
        for (int col = 0; col < N_COLS; col++) {
3186
0
            out.scales[out_idx++] = in[col].scales[sb];
3187
0
        }
3188
0
    }
3189
0
3190
0
    // Pack Group 4: Odd-High
3191
0
    for (int sb : odd_high_sbs) {
3192
0
        for (int col = 0; col < N_COLS; col++) {
3193
0
            out.scales[out_idx++] = in[col].scales[sb];
3194
0
        }
3195
0
    }
3196
0
3197
0
    return out;
3198
0
}
3199
3200
0
static int repack_q4_0_to_q4_0_4_bl(struct ggml_tensor * t, int interleave_block, const void * GGML_RESTRICT data, size_t data_size) {
3201
0
    GGML_ASSERT(t->type == GGML_TYPE_Q4_0);
3202
0
    GGML_ASSERT(interleave_block == 4 || interleave_block == 8);
3203
0
    constexpr int nrows_interleaved = 4;
3204
3205
0
    block_q4_0x4 * dst = (block_q4_0x4 *)t->data;
3206
0
    const block_q4_0 * src = (const block_q4_0 *)data;
3207
0
    block_q4_0 dst_tmp[4];
3208
0
    int nrow = ggml_nrows(t);
3209
0
    int nblocks = t->ne[0] / QK4_0;
3210
3211
0
    GGML_ASSERT(data_size == nrow * nblocks * sizeof(block_q4_0));
3212
3213
0
    if (t->ne[1] % nrows_interleaved != 0 || t->ne[0] % 8 != 0) {
3214
0
        return -1;
3215
0
    }
3216
3217
0
    for (int b = 0; b < nrow; b += nrows_interleaved) {
3218
0
        for (int64_t x = 0; x < nblocks; x++) {
3219
0
            for (int i = 0; i < nrows_interleaved; i++) {
3220
0
                dst_tmp[i] = src[x + i * nblocks];
3221
0
            }
3222
0
            *dst++ = make_block_q4_0x4(dst_tmp, interleave_block);
3223
0
        }
3224
0
        src += nrows_interleaved * nblocks;
3225
0
    }
3226
0
    return 0;
3227
3228
0
    GGML_UNUSED(data_size);
3229
0
}
3230
3231
0
static int repack_q4_K_to_q4_K_8_bl(struct ggml_tensor * t, int interleave_block, const void * GGML_RESTRICT data, size_t data_size) {
3232
0
    GGML_ASSERT(t->type == GGML_TYPE_Q4_K);
3233
0
    GGML_ASSERT(interleave_block == 8 || interleave_block == 4);
3234
0
    constexpr int nrows_interleaved = 8;
3235
3236
0
    block_q4_Kx8 * dst = (block_q4_Kx8*)t->data;
3237
0
    const block_q4_K * src = (const block_q4_K*) data;
3238
0
    block_q4_K dst_tmp[8];
3239
0
    int nrow = ggml_nrows(t);
3240
0
    int nblocks = t->ne[0] / QK_K;
3241
3242
0
    GGML_ASSERT(data_size == nrow * nblocks * sizeof(block_q4_K));
3243
3244
0
    if (t->ne[1] % nrows_interleaved != 0 || t->ne[0] % 8 != 0) {
3245
0
        return -1;
3246
0
    }
3247
3248
0
    for (int b = 0; b < nrow; b += nrows_interleaved) {
3249
0
        for (int64_t x = 0; x < nblocks; x++) {
3250
0
            for (int i  = 0; i < nrows_interleaved; i++ ) {
3251
0
                dst_tmp[i] = src[x + i * nblocks];
3252
0
            }
3253
0
            *dst++ = make_block_q4_Kx8(dst_tmp, interleave_block);
3254
0
        }
3255
0
        src += nrows_interleaved * nblocks;
3256
0
    }
3257
0
    return 0;
3258
3259
0
    GGML_UNUSED(data_size);
3260
0
}
3261
3262
0
static int repack_q4_K_to_q4_K_16_bl(struct ggml_tensor * t, int interleave_block, const void * GGML_RESTRICT data, size_t data_size) {
3263
0
    GGML_ASSERT(t->type == GGML_TYPE_Q4_K);
3264
0
    constexpr int nrows_interleaved = 16;
3265
0
3266
0
    block_q4_Kx16 * dst = (block_q4_Kx16*)t->data;
3267
0
    const block_q4_K * src = (const block_q4_K*) data;
3268
0
    block_q4_K dst_tmp[16];
3269
0
    int nrow = ggml_nrows(t);
3270
0
    int nblocks = t->ne[0] / QK_K;
3271
0
3272
0
    GGML_ASSERT(data_size == nrow * nblocks * sizeof(block_q4_K));
3273
0
3274
0
    if (t->ne[1] % nrows_interleaved != 0 || t->ne[0] % 8 != 0) {
3275
0
        return -1;
3276
0
    }
3277
0
3278
0
    for (int b = 0; b < nrow; b += nrows_interleaved) {
3279
0
        for (int64_t x = 0; x < nblocks; x++) {
3280
0
            for (int i  = 0; i < nrows_interleaved; i++ ) {
3281
0
                dst_tmp[i] = src[x + i * nblocks];
3282
0
            }
3283
0
            *dst++ = make_block_q4_Kx16(dst_tmp, interleave_block);
3284
0
        }
3285
0
        src += nrows_interleaved * nblocks;
3286
0
    }
3287
0
    return 0;
3288
0
3289
0
    GGML_UNUSED(data_size);
3290
0
}
3291
3292
0
static int repack_q2_K_to_q2_K_8_bl(struct ggml_tensor * t, int interleave_block, const void * GGML_RESTRICT data, size_t data_size) {
3293
0
    GGML_ASSERT(t->type == GGML_TYPE_Q2_K);
3294
0
    GGML_ASSERT(interleave_block == 8);
3295
0
    constexpr int nrows_interleaved = 8;
3296
3297
0
    block_q2_Kx8 * dst = (block_q2_Kx8*)t->data;
3298
0
    const block_q2_K * src = (const block_q2_K*) data;
3299
0
    block_q2_K dst_tmp[8];
3300
0
    int nrow = ggml_nrows(t);
3301
0
    int nblocks = t->ne[0] / QK_K;
3302
3303
0
    GGML_ASSERT(data_size == nrow * nblocks * sizeof(block_q2_K));
3304
3305
0
    if (t->ne[1] % nrows_interleaved != 0 || t->ne[0] % 8 != 0) {
3306
0
        return -1;
3307
0
    }
3308
3309
0
    for (int b = 0; b < nrow; b += nrows_interleaved) {
3310
0
        for (int64_t x = 0; x < nblocks; x++) {
3311
0
            for (int i = 0; i < nrows_interleaved; i++) {
3312
0
                dst_tmp[i] = src[x + i * nblocks];
3313
0
            }
3314
0
            *dst++ = make_block_q2_Kx8(dst_tmp, interleave_block);
3315
0
        }
3316
0
        src += nrows_interleaved * nblocks;
3317
0
    }
3318
0
    return 0;
3319
3320
0
    GGML_UNUSED(data_size);
3321
0
}
3322
3323
0
static int repack_q2_K_to_q2_K_16_bl(struct ggml_tensor * t, int interleave_block, const void * GGML_RESTRICT data, size_t data_size) {
3324
0
    GGML_ASSERT(t->type == GGML_TYPE_Q2_K);
3325
0
    constexpr int nrows_interleaved = 16;
3326
0
3327
0
    block_q2_Kx16 * dst = (block_q2_Kx16*)t->data;
3328
0
    const block_q2_K * src = (const block_q2_K*) data;
3329
0
3330
0
    block_q2_K dst_tmp[nrows_interleaved];
3331
0
3332
0
    int nrow = ggml_nrows(t);
3333
0
    int nblocks = t->ne[0] / QK_K;
3334
0
3335
0
    GGML_ASSERT(data_size == nrow * nblocks * sizeof(block_q2_K));
3336
0
3337
0
    if (t->ne[1] % nrows_interleaved != 0 || t->ne[0] % 8 != 0) {
3338
0
        return -1;
3339
0
    }
3340
0
3341
0
    for (int b = 0; b < nrow; b += nrows_interleaved) {
3342
0
        for (int64_t x = 0; x < nblocks; x++) {
3343
0
            // This loop gathers 16 separate blocks (one from each column)
3344
0
            // that correspond to the same K-dimension chunk.
3345
0
            for (int i  = 0; i < nrows_interleaved; i++ ) {
3346
0
                dst_tmp[i] = src[x + i * nblocks];
3347
0
            }
3348
0
3349
0
            *dst++ = make_block_q2_Kx16(dst_tmp, interleave_block);
3350
0
        }
3351
0
        src += nrows_interleaved * nblocks;
3352
0
    }
3353
0
    return 0;
3354
0
3355
0
    GGML_UNUSED(data_size);
3356
0
}
3357
3358
0
static int repack_q4_0_to_q4_0_16_bl(struct ggml_tensor * t, int interleave_block, const void * GGML_RESTRICT data, size_t data_size) {
3359
0
    GGML_ASSERT(t->type == GGML_TYPE_Q4_0);
3360
0
    constexpr int nrows_interleaved = 16;
3361
0
3362
0
    block_q4_0x16 * dst = (block_q4_0x16*)t->data;
3363
0
    const block_q4_0 * src = (const block_q4_0*) data;
3364
0
    block_q4_0 dst_tmp[16];
3365
0
    int nrow = ggml_nrows(t);
3366
0
    int nblocks = t->ne[0] / QK4_0;
3367
0
3368
0
    GGML_ASSERT(data_size == nrow * nblocks * sizeof(block_q4_0));
3369
0
3370
0
    if (t->ne[1] % nrows_interleaved != 0 || t->ne[0] % 8 != 0) {
3371
0
        return -1;
3372
0
    }
3373
0
3374
0
    for (int b = 0; b < nrow; b += nrows_interleaved) {
3375
0
        for (int64_t x = 0; x < nblocks; x++) {
3376
0
            for (int i  = 0; i < nrows_interleaved; i++ ) {
3377
0
                dst_tmp[i] = src[x + i * nblocks];
3378
0
            }
3379
0
            *dst++ = make_block_q4_0x16(dst_tmp, interleave_block);
3380
0
        }
3381
0
        src += nrows_interleaved * nblocks;
3382
0
    }
3383
0
    return 0;
3384
0
3385
0
    GGML_UNUSED(data_size);
3386
0
}
3387
3388
static int repack_q5_K_to_q5_K_8_bl(struct ggml_tensor *       t,
3389
                                    int                        interleave_block,
3390
                                    const void * GGML_RESTRICT data,
3391
0
                                    size_t                     data_size) {
3392
0
    GGML_ASSERT(t->type == GGML_TYPE_Q5_K);
3393
0
    GGML_ASSERT(interleave_block == 4 || interleave_block == 8);
3394
0
    constexpr int nrows_interleaved = 8;
3395
3396
0
    block_q5_Kx8 *     dst = (block_q5_Kx8 *) t->data;
3397
0
    const block_q5_K * src = (const block_q5_K *) data;
3398
0
    block_q5_K         dst_tmp[8];
3399
0
    int                nrow    = ggml_nrows(t);
3400
0
    int                nblocks = t->ne[0] / QK_K;
3401
3402
0
    GGML_ASSERT(data_size == nrow * nblocks * sizeof(block_q5_K));
3403
3404
0
    if (t->ne[1] % nrows_interleaved != 0 || t->ne[0] % 8 != 0) {
3405
0
        return -1;
3406
0
    }
3407
3408
0
    for (int b = 0; b < nrow; b += nrows_interleaved) {
3409
0
        for (int64_t x = 0; x < nblocks; x++) {
3410
0
            for (int i = 0; i < nrows_interleaved; i++) {
3411
0
                dst_tmp[i] = src[x + i * nblocks];
3412
0
            }
3413
0
            *dst++ = make_block_q5_Kx8(dst_tmp, interleave_block);
3414
0
        }
3415
0
        src += nrows_interleaved * nblocks;
3416
0
    }
3417
0
    return 0;
3418
0
}
3419
3420
0
static int repack_q6_K_to_q6_K_8_bl(struct ggml_tensor * t, int interleave_block, const void * GGML_RESTRICT data, size_t data_size) {
3421
0
    GGML_ASSERT(t->type == GGML_TYPE_Q6_K);
3422
0
    GGML_ASSERT(interleave_block == 4 || interleave_block == 8);
3423
0
    constexpr int nrows_interleaved = 8;
3424
3425
0
    block_q6_Kx8 * dst = (block_q6_Kx8 *)t->data;
3426
0
    const block_q6_K * src = (const block_q6_K *) data;
3427
0
    block_q6_K dst_tmp[8];
3428
0
    int nrow = ggml_nrows(t);
3429
0
    int nblocks = t->ne[0] / QK_K;
3430
3431
0
    GGML_ASSERT(data_size == nrow * nblocks * sizeof(block_q6_K));
3432
3433
0
    if (t->ne[1] % nrows_interleaved != 0 || t->ne[0] % 8 != 0) {
3434
0
        return -1;
3435
0
    }
3436
3437
0
    for (int b = 0; b < nrow; b += nrows_interleaved) {
3438
0
        for (int64_t x = 0; x < nblocks; x++) {
3439
0
            for (int i = 0; i < nrows_interleaved; i++) {
3440
0
                dst_tmp[i] = src[x + i * nblocks];
3441
0
            }
3442
0
            *dst++ = make_block_q6_Kx8(dst_tmp, interleave_block);
3443
0
        }
3444
0
        src += nrows_interleaved * nblocks;
3445
0
    }
3446
0
    return 0;
3447
0
}
3448
3449
0
static int repack_q4_0_to_q4_0_8_bl(struct ggml_tensor * t, int interleave_block, const void * GGML_RESTRICT data, size_t data_size) {
3450
0
    GGML_ASSERT(t->type == GGML_TYPE_Q4_0);
3451
0
    GGML_ASSERT(interleave_block == 8);
3452
0
    constexpr int nrows_interleaved = 8;
3453
3454
0
    block_q4_0x8 * dst = (block_q4_0x8*)t->data;
3455
0
    const block_q4_0 * src = (const block_q4_0*) data;
3456
0
    block_q4_0 dst_tmp[8];
3457
0
    int nrow = ggml_nrows(t);
3458
0
    int nblocks = t->ne[0] / QK4_0;
3459
3460
0
    GGML_ASSERT(data_size == nrow * nblocks * sizeof(block_q4_0));
3461
3462
0
    if (t->ne[1] % nrows_interleaved != 0 || t->ne[0] % 8 != 0) {
3463
0
        return -1;
3464
0
    }
3465
3466
0
    for (int b = 0; b < nrow; b += nrows_interleaved) {
3467
0
        for (int64_t x = 0; x < nblocks; x++) {
3468
0
            for (int i  = 0; i < nrows_interleaved; i++ ) {
3469
0
                dst_tmp[i] = src[x + i * nblocks];
3470
0
            }
3471
0
            *dst++ = make_block_q4_0x8(dst_tmp, interleave_block);
3472
0
        }
3473
0
        src += nrows_interleaved * nblocks;
3474
0
    }
3475
0
    return 0;
3476
3477
0
    GGML_UNUSED(data_size);
3478
0
}
3479
3480
static int repack_q8_0_to_q8_0_4_bl(struct ggml_tensor *       t,
3481
                                    int                        interleave_block,
3482
                                    const void * GGML_RESTRICT data,
3483
0
                                    size_t                     data_size) {
3484
0
    GGML_ASSERT(t->type == GGML_TYPE_Q8_0);
3485
0
    GGML_ASSERT(interleave_block == 4 || interleave_block == 8);
3486
0
    constexpr int nrows_interleaved = 4;
3487
3488
0
    block_q8_0x4 *     dst = (block_q8_0x4 *) t->data;
3489
0
    const block_q8_0 * src = (const block_q8_0 *) data;
3490
0
    block_q8_0         dst_tmp[4];
3491
0
    int                nrow    = ggml_nrows(t);
3492
0
    int                nblocks = t->ne[0] / QK8_0;
3493
3494
0
    GGML_ASSERT(data_size == nrow * nblocks * sizeof(block_q8_0));
3495
3496
0
    if (t->ne[1] % nrows_interleaved != 0 || t->ne[0] % 8 != 0) {
3497
0
        return -1;
3498
0
    }
3499
3500
0
    for (int b = 0; b < nrow; b += nrows_interleaved) {
3501
0
        for (int64_t x = 0; x < nblocks; x++) {
3502
0
            for (int i = 0; i < nrows_interleaved; i++) {
3503
0
                dst_tmp[i] = src[x + i * nblocks];
3504
0
            }
3505
0
            *dst++ = make_block_q8_0x4(dst_tmp, interleave_block);
3506
0
        }
3507
0
        src += nrows_interleaved * nblocks;
3508
0
    }
3509
0
    return 0;
3510
0
}
3511
3512
0
static block_q8_0x16 make_block_q8_0x16(block_q8_0 * in, unsigned int blck_size_interleave) {
3513
0
    block_q8_0x16 out;
3514
0
3515
0
    for (int i = 0; i < 16; i++) {
3516
0
        out.d[i] = in[i].d;
3517
0
    }
3518
0
3519
0
    const int end = QK8_0 * 16 / blck_size_interleave;
3520
0
3521
0
    if (blck_size_interleave == 1) {
3522
0
        for (int i = 0; i < end; ++i) {
3523
0
            int src_id     = i % 16;
3524
0
            int src_offset = i / 16;
3525
0
            int dst_offset = i;
3526
0
            out.qs[dst_offset] = in[src_id].qs[src_offset];
3527
0
        }
3528
0
    } else {
3529
0
        GGML_ASSERT(false);
3530
0
    }
3531
0
3532
0
    return out;
3533
0
}
3534
3535
static int repack_q8_0_to_q8_0_16_bl(struct ggml_tensor *       t,
3536
                                    int                        interleave_block,
3537
                                    const void * GGML_RESTRICT data,
3538
0
                                    size_t                     data_size) {
3539
0
    GGML_ASSERT(t->type == GGML_TYPE_Q8_0);
3540
0
    constexpr int nrows_interleaved = 16;
3541
0
3542
0
    block_q8_0x16 *     dst = (block_q8_0x16 *) t->data;
3543
0
    const block_q8_0 * src = (const block_q8_0 *) data;
3544
0
    block_q8_0         dst_tmp[16];
3545
0
    int                nrow    = ggml_nrows(t);
3546
0
    int                nblocks = t->ne[0] / QK8_0;
3547
0
3548
0
    GGML_ASSERT(data_size == nrow * nblocks * sizeof(block_q8_0));
3549
0
3550
0
    if (t->ne[1] % nrows_interleaved != 0 || t->ne[0] % 8 != 0) {
3551
0
        return -1;
3552
0
    }
3553
0
3554
0
    for (int b = 0; b < nrow; b += nrows_interleaved) {
3555
0
        for (int64_t x = 0; x < nblocks; x++) {
3556
0
            for (int i = 0; i < nrows_interleaved; i++) {
3557
0
                dst_tmp[i] = src[x + i * nblocks];
3558
0
            }
3559
0
            *dst++ = make_block_q8_0x16(dst_tmp, interleave_block);
3560
0
        }
3561
0
        src += nrows_interleaved * nblocks;
3562
0
    }
3563
0
    return 0;
3564
0
}
3565
3566
0
static block_iq4_nlx4 make_block_iq4_nlx4(block_iq4_nl * in, unsigned int blck_size_interleave) {
3567
0
    block_iq4_nlx4 out;
3568
3569
0
    for (int i = 0; i < 4; i++) {
3570
0
        out.d[i] = in[i].d;
3571
0
    }
3572
3573
0
    const int end = QK4_NL * 2 / blck_size_interleave;
3574
3575
    // TODO: this branch seems wrong
3576
    //if (blck_size_interleave == 8) {
3577
    //    for (int i = 0; i < end; ++i) {
3578
    //        int src_id = i % 4;
3579
    //        int src_offset = (i / 4) * blck_size_interleave;
3580
    //        int dst_offset = i * blck_size_interleave;
3581
3582
    //        // Using memcpy to avoid unaligned memory accesses
3583
    //        memcpy(&out.qs[dst_offset], &in[src_id].qs[src_offset], sizeof(uint64_t));
3584
    //    }
3585
    //} else
3586
0
    if (blck_size_interleave == 4) {
3587
0
        for (int i = 0; i < end; ++i) {
3588
0
            int src_id = i % 4;
3589
0
            int src_offset = (i / 4) * blck_size_interleave;
3590
0
            int dst_offset = i * blck_size_interleave;
3591
3592
0
            memcpy(&out.qs[dst_offset], &in[src_id].qs[src_offset], sizeof(uint32_t));
3593
0
        }
3594
0
    } else {
3595
0
        GGML_ASSERT(false);
3596
0
    }
3597
3598
0
    return out;
3599
0
}
3600
3601
0
static int repack_iq4_nl_to_iq4_nl_4_bl(struct ggml_tensor * t, int interleave_block, const void * GGML_RESTRICT data, size_t data_size) {
3602
0
    GGML_ASSERT(t->type == GGML_TYPE_IQ4_NL);
3603
0
    GGML_ASSERT(interleave_block == 4);
3604
3605
0
    const block_iq4_nl   * src = (const block_iq4_nl   *)data;
3606
0
          block_iq4_nlx4 * dst = (      block_iq4_nlx4 *)t->data;
3607
3608
0
    block_iq4_nl dst_tmp[4];
3609
3610
0
    int nrow = ggml_nrows(t);
3611
0
    int nrows_interleaved = 4;
3612
0
    int nblocks = t->ne[0] / QK4_NL;
3613
3614
0
    GGML_ASSERT(data_size == nrow * nblocks * sizeof(block_iq4_nl));
3615
3616
0
    if (t->ne[1] % nrows_interleaved != 0 || t->ne[0] % 8 != 0) {
3617
0
        return -1;
3618
0
    }
3619
3620
0
    for (int b = 0; b < nrow; b += nrows_interleaved) {
3621
0
        for (int64_t x = 0; x < nblocks; x++) {
3622
0
            for (int i = 0; i < nrows_interleaved; i++) {
3623
0
                dst_tmp[i] = src[x + i * nblocks];
3624
0
            }
3625
0
            *dst++ = make_block_iq4_nlx4(dst_tmp, interleave_block);
3626
0
        }
3627
0
        src += nrows_interleaved * nblocks;
3628
0
    }
3629
0
    return 0;
3630
3631
0
    GGML_UNUSED(data_size);
3632
0
}
3633
3634
0
static block_iq4_nlx8 make_block_iq4_nlx8(block_iq4_nl * in, unsigned int blck_size_interleave) {
3635
0
    block_iq4_nlx8 out;
3636
3637
0
    for (int i = 0; i < 8; i++) {
3638
0
        out.d[i] = in[i].d;
3639
0
    }
3640
3641
0
    const int end = QK4_NL * 4 / blck_size_interleave;
3642
3643
0
    if (blck_size_interleave == 8) {
3644
0
        for (int i = 0; i < end; ++i) {
3645
0
            int src_id = i % 8;
3646
0
            int src_offset = (i / 8) * blck_size_interleave;
3647
0
            int dst_offset = i * blck_size_interleave;
3648
3649
0
            memcpy(&out.qs[dst_offset], &in[src_id].qs[src_offset], sizeof(uint64_t));
3650
0
        }
3651
0
    } else {
3652
0
        GGML_ASSERT(false);
3653
0
    }
3654
3655
0
    return out;
3656
0
}
3657
3658
0
static int repack_iq4_nl_to_iq4_nl_8_bl(struct ggml_tensor * t, int interleave_block, const void * GGML_RESTRICT data, size_t data_size) {
3659
0
    GGML_ASSERT(t->type == GGML_TYPE_IQ4_NL);
3660
0
    GGML_ASSERT(interleave_block == 8);
3661
3662
0
    const block_iq4_nl   * src = (const block_iq4_nl   *)data;
3663
0
          block_iq4_nlx8 * dst = (      block_iq4_nlx8 *)t->data;
3664
3665
0
    block_iq4_nl dst_tmp[8];
3666
3667
0
    int nrow = ggml_nrows(t);
3668
0
    int nrows_interleaved = 8;
3669
0
    int nblocks = t->ne[0] / QK4_NL;
3670
3671
0
    GGML_ASSERT(data_size == nrow * nblocks * sizeof(block_iq4_nl));
3672
3673
0
    if (t->ne[1] % nrows_interleaved != 0) {
3674
0
        return -1;
3675
0
    }
3676
3677
0
    for (int b = 0; b < nrow; b += nrows_interleaved) {
3678
0
        for (int64_t x = 0; x < nblocks; x++) {
3679
0
            for (int i = 0; i < nrows_interleaved; i++) {
3680
0
                dst_tmp[i] = src[x + i * nblocks];
3681
0
            }
3682
0
            *dst++ = make_block_iq4_nlx8(dst_tmp, interleave_block);
3683
0
        }
3684
0
        src += nrows_interleaved * nblocks;
3685
0
    }
3686
0
    return 0;
3687
3688
0
    GGML_UNUSED(data_size);
3689
0
}
3690
3691
0
static block_iq4_nlx16 make_block_iq4_nlx16(block_iq4_nl * in, unsigned int blck_size_interleave) {
3692
0
    block_iq4_nlx16 out;
3693
0
3694
0
    for (int i = 0; i < 16; i++) {
3695
0
        out.d[i] = in[i].d;
3696
0
    }
3697
0
3698
0
    const int end = QK4_NL * 8 / blck_size_interleave;
3699
0
3700
0
    if (blck_size_interleave == 1) {
3701
0
        for (int i = 0; i < end; ++i) {
3702
0
            int src_id = i % 16;
3703
0
            int src_offset = i / 16;
3704
0
            int dst_offset = i;
3705
0
3706
0
            out.qs[dst_offset] = in[src_id].qs[src_offset];
3707
0
        }
3708
0
    } else {
3709
0
        GGML_ASSERT(false);
3710
0
    }
3711
0
3712
0
    return out;
3713
0
}
3714
3715
0
static int repack_iq4_nl_to_iq4_nl_16_bl(struct ggml_tensor * t, int interleave_block, const void * GGML_RESTRICT data, size_t data_size) {
3716
0
    GGML_ASSERT(t->type == GGML_TYPE_IQ4_NL);
3717
0
    GGML_ASSERT(interleave_block == 1);
3718
0
3719
0
    const block_iq4_nl    * src = (const block_iq4_nl   *)data;
3720
0
          block_iq4_nlx16 * dst = (      block_iq4_nlx16 *)t->data;
3721
0
3722
0
    block_iq4_nl dst_tmp[16];
3723
0
3724
0
    int nrow = ggml_nrows(t);
3725
0
    int nrows_interleaved = 16;
3726
0
    int nblocks = t->ne[0] / QK4_NL;
3727
0
3728
0
    GGML_ASSERT(data_size == nrow * nblocks * sizeof(block_iq4_nl));
3729
0
3730
0
    if (t->ne[1] % nrows_interleaved != 0) {
3731
0
        return -1;
3732
0
    }
3733
0
3734
0
    for (int b = 0; b < nrow; b += nrows_interleaved) {
3735
0
        for (int64_t x = 0; x < nblocks; x++) {
3736
0
            for (int i = 0; i < nrows_interleaved; i++) {
3737
0
                dst_tmp[i] = src[x + i * nblocks];
3738
0
            }
3739
0
            *dst++ = make_block_iq4_nlx16(dst_tmp, interleave_block);
3740
0
        }
3741
0
        src += nrows_interleaved * nblocks;
3742
0
    }
3743
0
    return 0;
3744
0
3745
0
    GGML_UNUSED(data_size);
3746
0
}
3747
3748
0
static block_mxfp4x4 make_block_mxfp4x4(block_mxfp4 * in, unsigned int blck_size_interleave) {
3749
0
    block_mxfp4x4 out;
3750
3751
0
    for (int i = 0; i < 4; i++) {
3752
0
        out.e[i] = in[i].e;
3753
0
    }
3754
3755
0
    const int end = QK_MXFP4 * 2 / blck_size_interleave;
3756
3757
0
    if (blck_size_interleave == 4) {
3758
0
        for (int i = 0; i < end; ++i) {
3759
0
            int src_id = i % 4;
3760
0
            int src_offset = (i / 4) * blck_size_interleave;
3761
0
            int dst_offset = i * blck_size_interleave;
3762
3763
0
            memcpy(&out.qs[dst_offset], &in[src_id].qs[src_offset], sizeof(uint32_t));
3764
0
        }
3765
0
    } else {
3766
0
        GGML_ASSERT(false);
3767
0
    }
3768
3769
0
    return out;
3770
0
}
3771
3772
0
static int repack_mxfp4_to_mxfp4_4_bl(struct ggml_tensor * t, int interleave_block, const void * GGML_RESTRICT data, size_t data_size) {
3773
0
    GGML_ASSERT(t->type == GGML_TYPE_MXFP4);
3774
0
    GGML_ASSERT(interleave_block == 4);
3775
3776
0
    const block_mxfp4   * src = (const block_mxfp4   *)data;
3777
0
          block_mxfp4x4 * dst = (      block_mxfp4x4 *)t->data;
3778
3779
0
    block_mxfp4 dst_tmp[4];
3780
3781
0
    int nrow = ggml_nrows(t);
3782
0
    int nrows_interleaved = 4;
3783
0
    int nblocks = t->ne[0] / QK_MXFP4;
3784
3785
0
    GGML_ASSERT(data_size == nrow * nblocks * sizeof(block_mxfp4));
3786
3787
0
    if (t->ne[1] % nrows_interleaved != 0 || t->ne[0] % 8 != 0) {
3788
0
        return -1;
3789
0
    }
3790
3791
0
    for (int b = 0; b < nrow; b += nrows_interleaved) {
3792
0
        for (int64_t x = 0; x < nblocks; x++) {
3793
0
            for (int i = 0; i < nrows_interleaved; i++) {
3794
0
                dst_tmp[i] = src[x + i * nblocks];
3795
0
            }
3796
0
            *dst++ = make_block_mxfp4x4(dst_tmp, interleave_block);
3797
0
        }
3798
0
        src += nrows_interleaved * nblocks;
3799
0
    }
3800
0
    return 0;
3801
3802
0
    GGML_UNUSED(data_size);
3803
0
}
3804
3805
0
static block_mxfp4x8 make_block_mxfp4x8(block_mxfp4 * in, unsigned int blck_size_interleave) {
3806
0
    block_mxfp4x8 out;
3807
3808
0
    for (int i = 0; i < 8; i++) {
3809
0
        out.e[i] = in[i].e;
3810
0
    }
3811
3812
0
    const int end = QK_MXFP4 * 4 / blck_size_interleave;
3813
3814
0
    if (blck_size_interleave == 8) {
3815
0
        for (int i = 0; i < end; ++i) {
3816
0
            int src_id = i % 8;
3817
0
            int src_offset = (i / 8) * blck_size_interleave;
3818
0
            int dst_offset = i * blck_size_interleave;
3819
3820
0
            memcpy(&out.qs[dst_offset], &in[src_id].qs[src_offset], sizeof(uint64_t));
3821
0
        }
3822
0
    } else {
3823
0
        GGML_ASSERT(false);
3824
0
    }
3825
3826
0
    return out;
3827
0
}
3828
3829
0
static int repack_mxfp4_to_mxfp4_8_bl(struct ggml_tensor * t, int interleave_block, const void * GGML_RESTRICT data, size_t data_size) {
3830
0
    GGML_ASSERT(t->type == GGML_TYPE_MXFP4);
3831
0
    GGML_ASSERT(interleave_block == 8);
3832
3833
0
    const block_mxfp4   * src = (const block_mxfp4   *)data;
3834
0
          block_mxfp4x8 * dst = (      block_mxfp4x8 *)t->data;
3835
3836
0
    block_mxfp4 dst_tmp[8];
3837
3838
0
    int nrow = ggml_nrows(t);
3839
0
    int nrows_interleaved = 8;
3840
0
    int nblocks = t->ne[0] / QK_MXFP4;
3841
3842
0
    GGML_ASSERT(data_size == nrow * nblocks * sizeof(block_mxfp4));
3843
3844
0
    if (t->ne[1] % nrows_interleaved != 0) {
3845
0
        return -1;
3846
0
    }
3847
3848
0
    for (int b = 0; b < nrow; b += nrows_interleaved) {
3849
0
        for (int64_t x = 0; x < nblocks; x++) {
3850
0
            for (int i = 0; i < nrows_interleaved; i++) {
3851
0
                dst_tmp[i] = src[x + i * nblocks];
3852
0
            }
3853
0
            *dst++ = make_block_mxfp4x8(dst_tmp, interleave_block);
3854
0
        }
3855
0
        src += nrows_interleaved * nblocks;
3856
0
    }
3857
0
    return 0;
3858
3859
0
    GGML_UNUSED(data_size);
3860
0
}
3861
3862
namespace ggml::cpu::repack {
3863
// repack
3864
template <typename BLOC_TYPE, int64_t INTER_SIZE, int64_t NB_COLS>
3865
int repack(struct ggml_tensor *, const void *, size_t);
3866
3867
// TODO: generalise.
3868
0
template <> int repack<block_q4_0, 4, 4>(struct ggml_tensor * t, const void * data, size_t data_size) {
3869
0
    return repack_q4_0_to_q4_0_4_bl(t, 4, data, data_size);
3870
0
}
3871
3872
0
template <> int repack<block_q4_0, 8, 4>(struct ggml_tensor * t, const void * data, size_t data_size) {
3873
0
    return repack_q4_0_to_q4_0_4_bl(t, 8, data, data_size);
3874
0
}
3875
3876
0
template <> int repack<block_q4_0, 8, 8>(struct ggml_tensor * t, const void * data, size_t data_size) {
3877
0
    return repack_q4_0_to_q4_0_8_bl(t, 8, data, data_size);
3878
0
}
3879
3880
0
template <> int repack<block_q4_K, 8, 8>(struct ggml_tensor * t, const void * data, size_t data_size) {
3881
0
    return repack_q4_K_to_q4_K_8_bl(t, 8, data, data_size);
3882
0
}
3883
3884
0
template <> int repack<block_q4_K, 4, 8>(struct ggml_tensor * t, const void * data, size_t data_size) {
3885
0
    return repack_q4_K_to_q4_K_8_bl(t, 4, data, data_size);
3886
0
}
3887
3888
0
template <> int repack<block_q2_K, 8, 8>(struct ggml_tensor * t, const void * data, size_t data_size) {
3889
0
    return repack_q2_K_to_q2_K_8_bl(t, 8, data, data_size);
3890
0
}
3891
3892
0
template <> int repack<block_q5_K, 4, 8>(struct ggml_tensor * t, const void * data, size_t data_size) {
3893
0
    return repack_q5_K_to_q5_K_8_bl(t, 4, data, data_size);
3894
0
}
3895
3896
0
template <> int repack<block_q5_K, 8, 8>(struct ggml_tensor * t, const void * data, size_t data_size) {
3897
0
    return repack_q5_K_to_q5_K_8_bl(t, 8, data, data_size);
3898
0
}
3899
3900
0
template <> int repack<block_q6_K, 4, 8>(struct ggml_tensor * t, const void * data, size_t data_size) {
3901
0
    return repack_q6_K_to_q6_K_8_bl(t, 4, data, data_size);
3902
0
}
3903
3904
0
template <> int repack<block_q6_K, 8, 8>(struct ggml_tensor * t, const void * data, size_t data_size) {
3905
0
    return repack_q6_K_to_q6_K_8_bl(t, 8, data, data_size);
3906
0
}
3907
3908
0
template <> int repack<block_iq4_nl, 4, 4>(struct ggml_tensor * t, const void * data, size_t data_size) {
3909
0
    return repack_iq4_nl_to_iq4_nl_4_bl(t, 4, data, data_size);
3910
0
}
3911
3912
// TODO: needs to be revisited
3913
//template <> int repack<block_iq4_nl, 8, 4>(struct ggml_tensor * t, const void * data, size_t data_size) {
3914
//    return repack_iq4_nl_to_iq4_nl_4_bl(t, 8, data, data_size);
3915
//}
3916
3917
0
template <> int repack<block_iq4_nl, 8, 8>(struct ggml_tensor * t, const void * data, size_t data_size) {
3918
0
    return repack_iq4_nl_to_iq4_nl_8_bl(t, 8, data, data_size);
3919
0
}
3920
3921
0
template <> int repack<block_mxfp4, 4, 4>(struct ggml_tensor * t, const void * data, size_t data_size) {
3922
0
    return repack_mxfp4_to_mxfp4_4_bl(t, 4, data, data_size);
3923
0
}
3924
3925
0
template <> int repack<block_mxfp4, 8, 8>(struct ggml_tensor * t, const void * data, size_t data_size) {
3926
0
    return repack_mxfp4_to_mxfp4_8_bl(t, 8, data, data_size);
3927
0
}
3928
3929
0
template <> int repack<block_q8_0, 4, 4>(struct ggml_tensor * t, const void * data, size_t data_size) {
3930
0
    return repack_q8_0_to_q8_0_4_bl(t, 4, data, data_size);
3931
0
}
3932
3933
0
template <> int repack<block_q8_0, 8, 4>(struct ggml_tensor * t, const void * data, size_t data_size) {
3934
0
    return repack_q8_0_to_q8_0_4_bl(t, 8, data, data_size);
3935
0
}
3936
3937
#if defined __riscv_zvfh
3938
template <> int repack<block_q4_0, 1, 16>(struct ggml_tensor * t, const void * data, size_t data_size) {
3939
    return repack_q4_0_to_q4_0_16_bl(t, 1, data, data_size);
3940
}
3941
3942
template <> int repack<block_q4_K, 1, 16>(struct ggml_tensor * t, const void * data, size_t data_size) {
3943
    return repack_q4_K_to_q4_K_16_bl(t, 1, data, data_size);
3944
}
3945
3946
template <> int repack<block_iq4_nl, 1, 16>(struct ggml_tensor * t, const void * data, size_t data_size) {
3947
    return repack_iq4_nl_to_iq4_nl_16_bl(t, 1, data, data_size);
3948
}
3949
3950
template <> int repack<block_q8_0, 1, 16>(struct ggml_tensor * t, const void * data, size_t data_size) {
3951
    return repack_q8_0_to_q8_0_16_bl(t, 1, data, data_size);
3952
}
3953
3954
template <> int repack<block_q2_K, 1, 16>(struct ggml_tensor * t, const void * data, size_t data_size) {
3955
    return repack_q2_K_to_q2_K_16_bl(t, 1, data, data_size);
3956
}
3957
#endif
3958
3959
// gemv
3960
template <typename BLOC_TYPE, int64_t INTER_SIZE, int64_t NB_COLS, ggml_type PARAM_TYPE>
3961
void gemv(int, float *, size_t, const void *, const void *, int, int);
3962
3963
0
template <> void gemv<block_q4_0, 4, 4, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
3964
0
    ggml_gemv_q4_0_4x4_q8_0(n, s, bs, vx, vy, nr, nc);
3965
0
}
3966
3967
0
template <> void gemv<block_q4_0, 8, 4, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
3968
0
    ggml_gemv_q4_0_4x8_q8_0(n, s, bs, vx, vy, nr, nc);
3969
0
}
3970
3971
0
template <> void gemv<block_q4_0, 8, 8, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
3972
0
    ggml_gemv_q4_0_8x8_q8_0(n, s, bs, vx, vy, nr, nc);
3973
0
}
3974
3975
template <>
3976
void gemv<block_q2_K, 8, 8, GGML_TYPE_Q8_K>(int          n,
3977
                                            float *      s,
3978
                                            size_t       bs,
3979
                                            const void * vx,
3980
                                            const void * vy,
3981
                                            int          nr,
3982
0
                                            int          nc) {
3983
0
    ggml_gemv_q2_K_8x8_q8_K(n, s, bs, vx, vy, nr, nc);
3984
0
}
3985
3986
0
template <> void gemv<block_q4_K, 4, 8, GGML_TYPE_Q8_K>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
3987
0
    ggml_gemv_q4_K_8x4_q8_K(n, s, bs, vx, vy, nr, nc);
3988
0
}
3989
3990
0
template <> void gemv<block_q4_K, 8, 8, GGML_TYPE_Q8_K>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
3991
0
    ggml_gemv_q4_K_8x8_q8_K(n, s, bs, vx, vy, nr, nc);
3992
0
}
3993
3994
0
template <> void gemv<block_q5_K, 4, 8, GGML_TYPE_Q8_K>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
3995
0
    ggml_gemv_q5_K_8x4_q8_K(n, s, bs, vx, vy, nr, nc);
3996
0
}
3997
3998
0
template <> void gemv<block_q5_K, 8, 8, GGML_TYPE_Q8_K>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
3999
0
    ggml_gemv_q5_K_8x8_q8_K(n, s, bs, vx, vy, nr, nc);
4000
0
}
4001
4002
0
template <> void gemv<block_q6_K, 4, 8, GGML_TYPE_Q8_K>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4003
0
    ggml_gemv_q6_K_8x4_q8_K(n, s, bs, vx, vy, nr, nc);
4004
0
}
4005
4006
0
template <> void gemv<block_q6_K, 8, 8, GGML_TYPE_Q8_K>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4007
0
    ggml_gemv_q6_K_8x8_q8_K(n, s, bs, vx, vy, nr, nc);
4008
0
}
4009
4010
0
template <> void gemv<block_iq4_nl, 4, 4, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4011
0
    ggml_gemv_iq4_nl_4x4_q8_0(n, s, bs, vx, vy, nr, nc);
4012
0
}
4013
4014
0
template <> void gemv<block_iq4_nl, 8, 8, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4015
0
    ggml_gemv_iq4_nl_8x8_q8_0(n, s, bs, vx, vy, nr, nc);
4016
0
}
4017
4018
0
template <> void gemv<block_mxfp4, 4, 4, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4019
0
    ggml_gemv_mxfp4_4x4_q8_0(n, s, bs, vx, vy, nr, nc);
4020
0
}
4021
4022
0
template <> void gemv<block_mxfp4, 8, 8, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4023
0
    ggml_gemv_mxfp4_8x8_q8_0(n, s, bs, vx, vy, nr, nc);
4024
0
}
4025
4026
0
template <> void gemv<block_q8_0, 4, 4, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4027
0
    ggml_gemv_q8_0_4x4_q8_0(n, s, bs, vx, vy, nr, nc);
4028
0
}
4029
4030
0
template <> void gemv<block_q8_0, 8, 4, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4031
0
    ggml_gemv_q8_0_4x8_q8_0(n, s, bs, vx, vy, nr, nc);
4032
0
}
4033
4034
#if defined __riscv_zvfh
4035
template <> void gemv<block_q4_0, 1, 16, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4036
    ggml_gemv_q4_0_16x1_q8_0(n, s, bs, vx, vy, nr, nc);
4037
}
4038
4039
template <> void gemv<block_q4_K, 1, 16, GGML_TYPE_Q8_K>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4040
    ggml_gemv_q4_K_16x1_q8_K(n, s, bs, vx, vy, nr, nc);
4041
}
4042
4043
template <> void gemv<block_iq4_nl, 1, 16, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4044
    ggml_gemv_iq4_nl_16x1_q8_0(n, s, bs, vx, vy, nr, nc);
4045
}
4046
4047
template <> void gemv<block_q8_0, 1, 16, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4048
    ggml_gemv_q8_0_16x1_q8_0(n, s, bs, vx, vy, nr, nc);
4049
}
4050
4051
template <> void gemv<block_q2_K, 1, 16, GGML_TYPE_Q8_K>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4052
    ggml_gemv_q2_K_16x1_q8_K(n, s, bs, vx, vy, nr, nc);
4053
}
4054
#endif
4055
4056
// gemm
4057
template <typename BLOC_TYPE, int64_t INTER_SIZE, int64_t NB_COLS, ggml_type PARAM_TYPE>
4058
void gemm(int, float *, size_t, const void *, const void *, int, int);
4059
4060
0
template <> void gemm<block_q4_0, 4, 4, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4061
0
    ggml_gemm_q4_0_4x4_q8_0(n, s, bs, vx, vy, nr, nc);
4062
0
}
4063
4064
0
template <> void gemm<block_q4_0, 8, 4, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4065
0
    ggml_gemm_q4_0_4x8_q8_0(n, s, bs, vx, vy, nr, nc);
4066
0
}
4067
4068
template <>
4069
void gemm<block_q4_0, 8, 8, GGML_TYPE_Q8_0>(int          n,
4070
                                            float *      s,
4071
                                            size_t       bs,
4072
                                            const void * vx,
4073
                                            const void * vy,
4074
                                            int          nr,
4075
0
                                            int          nc) {
4076
0
    ggml_gemm_q4_0_8x8_q8_0(n, s, bs, vx, vy, nr, nc);
4077
0
}
4078
4079
0
template <> void gemm<block_q2_K, 8, 8, GGML_TYPE_Q8_K>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4080
0
    ggml_gemm_q2_K_8x8_q8_K(n, s, bs, vx, vy, nr, nc);
4081
0
}
4082
4083
0
template <> void gemm<block_q4_K, 4, 8, GGML_TYPE_Q8_K>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4084
0
    ggml_gemm_q4_K_8x4_q8_K(n, s, bs, vx, vy, nr, nc);
4085
0
}
4086
4087
0
template <> void gemm<block_q4_K, 8, 8, GGML_TYPE_Q8_K>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4088
0
    ggml_gemm_q4_K_8x8_q8_K(n, s, bs, vx, vy, nr, nc);
4089
0
}
4090
4091
0
template <> void gemm<block_q5_K, 4, 8, GGML_TYPE_Q8_K>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4092
0
    ggml_gemm_q5_K_8x4_q8_K(n, s, bs, vx, vy, nr, nc);
4093
0
}
4094
4095
0
template <> void gemm<block_q5_K, 8, 8, GGML_TYPE_Q8_K>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4096
0
    ggml_gemm_q5_K_8x8_q8_K(n, s, bs, vx, vy, nr, nc);
4097
0
}
4098
4099
0
template <> void gemm<block_q6_K, 4, 8, GGML_TYPE_Q8_K>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4100
0
    ggml_gemm_q6_K_8x4_q8_K(n, s, bs, vx, vy, nr, nc);
4101
0
}
4102
4103
0
template <> void gemm<block_q6_K, 8, 8, GGML_TYPE_Q8_K>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4104
0
    ggml_gemm_q6_K_8x8_q8_K(n, s, bs, vx, vy, nr, nc);
4105
0
}
4106
4107
0
template <> void gemm<block_iq4_nl, 4, 4, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4108
0
    ggml_gemm_iq4_nl_4x4_q8_0(n, s, bs, vx, vy, nr, nc);
4109
0
}
4110
4111
0
template <> void gemm<block_iq4_nl, 8, 8, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4112
0
    ggml_gemm_iq4_nl_8x8_q8_0(n, s, bs, vx, vy, nr, nc);
4113
0
}
4114
4115
0
template <> void gemm<block_mxfp4, 4, 4, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4116
0
    ggml_gemm_mxfp4_4x4_q8_0(n, s, bs, vx, vy, nr, nc);
4117
0
}
4118
4119
0
template <> void gemm<block_mxfp4, 8, 8, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4120
0
    ggml_gemm_mxfp4_8x8_q8_0(n, s, bs, vx, vy, nr, nc);
4121
0
}
4122
4123
0
template <> void gemm<block_q8_0, 4, 4, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4124
0
    ggml_gemm_q8_0_4x4_q8_0(n, s, bs, vx, vy, nr, nc);
4125
0
}
4126
4127
0
template <> void gemm<block_q8_0, 8, 4, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4128
0
    ggml_gemm_q8_0_4x8_q8_0(n, s, bs, vx, vy, nr, nc);
4129
0
}
4130
4131
#if defined __riscv_zvfh
4132
template <> void gemm<block_q4_0, 1, 16, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4133
    ggml_gemm_q4_0_16x1_q8_0(n, s, bs, vx, vy, nr, nc);
4134
}
4135
4136
template <> void gemm<block_q4_K, 1, 16, GGML_TYPE_Q8_K>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4137
    ggml_gemm_q4_K_16x1_q8_K(n, s, bs, vx, vy, nr, nc);
4138
}
4139
4140
template <> void gemm<block_iq4_nl, 1, 16, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4141
    ggml_gemm_iq4_nl_16x1_q8_0(n, s, bs, vx, vy, nr, nc);
4142
}
4143
4144
template <> void gemm<block_q8_0, 1, 16, GGML_TYPE_Q8_0>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4145
    ggml_gemm_q8_0_16x1_q8_0(n, s, bs, vx, vy, nr, nc);
4146
}
4147
4148
template <> void gemm<block_q2_K, 1, 16, GGML_TYPE_Q8_K>(int n, float * s, size_t bs, const void * vx, const void * vy, int nr, int nc) {
4149
    ggml_gemm_q2_K_16x1_q8_K(n, s, bs, vx, vy, nr, nc);
4150
}
4151
#endif
4152
4153
class tensor_traits_base : public ggml::cpu::tensor_traits {
4154
  public:
4155
    virtual int repack(struct ggml_tensor * t, const void * data, size_t data_size) = 0;
4156
};
4157
4158
template <typename BLOC_TYPE, int64_t INTER_SIZE, int64_t NB_COLS, ggml_type PARAM_TYPE> class tensor_traits : public tensor_traits_base {
4159
4160
0
    bool work_size(int /* n_threads */, const struct ggml_tensor * op, size_t & size) override {
4161
        // not realy a GGML_TYPE_Q8_0 but same size.
4162
0
        switch (op->op) {
4163
0
            case GGML_OP_MUL_MAT:
4164
0
                {
4165
0
                    size = ggml_row_size(PARAM_TYPE, ggml_nelements(op->src[1]));
4166
0
                    return true;
4167
0
                }
4168
0
            case GGML_OP_MUL_MAT_ID:
4169
0
                {
4170
0
                    size = ggml_row_size(PARAM_TYPE, ggml_nelements(op->src[1]));
4171
0
                    size = GGML_PAD(size, sizeof(int64_t)); // + padding for next block.
4172
4173
0
                    const int64_t ne02 = op->src[0]->ne[2]; // n_as, n_expert
4174
0
                    const int64_t ne12 = op->src[1]->ne[2]; // n_tokens
4175
4176
0
                    const size_t sizeof_mmid_row_mapping = sizeof(int64_t);
4177
4178
0
                    size += sizeof_mmid_row_mapping*ne02*(ne12 + 1);
4179
4180
0
                    return true;
4181
0
                }
4182
0
            default:
4183
                // GGML_ABORT("fatal error");
4184
0
                break;
4185
0
        }
4186
0
        return false;
4187
0
    }
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_0, 4l, 4l, (ggml_type)8>::work_size(int, ggml_tensor const*, unsigned long&)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_0, 8l, 4l, (ggml_type)8>::work_size(int, ggml_tensor const*, unsigned long&)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_0, 8l, 8l, (ggml_type)8>::work_size(int, ggml_tensor const*, unsigned long&)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_K, 4l, 8l, (ggml_type)15>::work_size(int, ggml_tensor const*, unsigned long&)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_K, 8l, 8l, (ggml_type)15>::work_size(int, ggml_tensor const*, unsigned long&)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q5_K, 4l, 8l, (ggml_type)15>::work_size(int, ggml_tensor const*, unsigned long&)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q5_K, 8l, 8l, (ggml_type)15>::work_size(int, ggml_tensor const*, unsigned long&)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q6_K, 4l, 8l, (ggml_type)15>::work_size(int, ggml_tensor const*, unsigned long&)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q6_K, 8l, 8l, (ggml_type)15>::work_size(int, ggml_tensor const*, unsigned long&)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q2_K, 8l, 8l, (ggml_type)15>::work_size(int, ggml_tensor const*, unsigned long&)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_iq4_nl, 4l, 4l, (ggml_type)8>::work_size(int, ggml_tensor const*, unsigned long&)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_iq4_nl, 8l, 8l, (ggml_type)8>::work_size(int, ggml_tensor const*, unsigned long&)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_mxfp4, 4l, 4l, (ggml_type)8>::work_size(int, ggml_tensor const*, unsigned long&)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_mxfp4, 8l, 8l, (ggml_type)8>::work_size(int, ggml_tensor const*, unsigned long&)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q8_0, 4l, 4l, (ggml_type)8>::work_size(int, ggml_tensor const*, unsigned long&)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q8_0, 8l, 4l, (ggml_type)8>::work_size(int, ggml_tensor const*, unsigned long&)
4188
4189
0
    bool compute_forward(struct ggml_compute_params * params, struct ggml_tensor * op) override {
4190
0
        switch (op->op) {
4191
0
            case GGML_OP_MUL_MAT:
4192
0
                forward_mul_mat(params, op);
4193
0
                return true;
4194
0
            case GGML_OP_MUL_MAT_ID:
4195
0
                forward_mul_mat_id(params, op);
4196
0
                return true;
4197
0
            default:
4198
                // GGML_ABORT("fatal error");
4199
0
                break;
4200
0
        }
4201
0
        return false;
4202
0
    }
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_0, 4l, 4l, (ggml_type)8>::compute_forward(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_0, 8l, 4l, (ggml_type)8>::compute_forward(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_0, 8l, 8l, (ggml_type)8>::compute_forward(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_K, 4l, 8l, (ggml_type)15>::compute_forward(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_K, 8l, 8l, (ggml_type)15>::compute_forward(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q5_K, 4l, 8l, (ggml_type)15>::compute_forward(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q5_K, 8l, 8l, (ggml_type)15>::compute_forward(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q6_K, 4l, 8l, (ggml_type)15>::compute_forward(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q6_K, 8l, 8l, (ggml_type)15>::compute_forward(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q2_K, 8l, 8l, (ggml_type)15>::compute_forward(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_iq4_nl, 4l, 4l, (ggml_type)8>::compute_forward(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_iq4_nl, 8l, 8l, (ggml_type)8>::compute_forward(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_mxfp4, 4l, 4l, (ggml_type)8>::compute_forward(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_mxfp4, 8l, 8l, (ggml_type)8>::compute_forward(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q8_0, 4l, 4l, (ggml_type)8>::compute_forward(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q8_0, 8l, 4l, (ggml_type)8>::compute_forward(ggml_compute_params*, ggml_tensor*)
4203
4204
    void forward_mul_mat_one_chunk(ggml_compute_params * params,
4205
                                   ggml_tensor *         op,
4206
                                   int64_t               src0_start,
4207
                                   int64_t               src0_end,
4208
                                   int64_t               src1_start,
4209
0
                                   int64_t               src1_end) {
4210
0
        const ggml_tensor * src0 = op->src[0];
4211
0
        const ggml_tensor * src1 = op->src[1];
4212
0
        ggml_tensor *       dst  = op;
4213
4214
0
        GGML_TENSOR_BINARY_OP_LOCALS
4215
4216
0
        const size_t src1_col_stride = ggml_row_size(PARAM_TYPE, ne10);
4217
4218
0
        GGML_ASSERT(ne03 == 1 && ne13 == 1);
4219
0
        GGML_ASSERT(ne12 % ne02 == 0);
4220
0
        const int64_t r2 = ne12 / ne02;
4221
4222
0
        const int64_t i12 = src1_start / ne1;
4223
0
        const int64_t i11 = src1_start - i12 * ne1;
4224
4225
        // Determine batch index
4226
0
        const int64_t i02 = i12 / r2;
4227
4228
0
        const int64_t i1 = i11;
4229
0
        const int64_t i2 = i12;
4230
4231
0
        const char * src0_ptr = (const char *) src0->data + i02 * nb02;
4232
0
        const char * src1_ptr = (const char *) params->wdata + (i11 + i12 * ne11) * src1_col_stride;
4233
0
        char *       dst_ptr  = ((char *) dst->data + (i1 * nb1 + i2 * nb2));
4234
4235
0
        const int64_t nrows = src1_end - src1_start;
4236
0
        const int64_t ncols = src0_end - src0_start;
4237
4238
0
        GGML_ASSERT(src1_ptr + src1_col_stride * nrows <= (const char *) params->wdata + params->wsize);
4239
4240
        // If there are more than three rows in src1, use gemm; otherwise, use gemv.
4241
0
        if (nrows > 3) {
4242
0
            gemm<BLOC_TYPE, INTER_SIZE, NB_COLS, PARAM_TYPE>(ne00, (float *) (dst_ptr) + src0_start, nb1 / nb0,
4243
0
                                                             src0_ptr + src0_start * nb01, src1_ptr,
4244
0
                                                             nrows - (nrows % 4), ncols);
4245
0
        }
4246
0
        for (int iter = nrows - (nrows % 4); iter < nrows; iter++) {
4247
0
            gemv<BLOC_TYPE, INTER_SIZE, NB_COLS, PARAM_TYPE>(ne00, (float *) (dst_ptr + (iter * nb1)) + src0_start,
4248
0
                                                             ne01, src0_ptr + src0_start * nb01,
4249
0
                                                             src1_ptr + (src1_col_stride * iter), 1 /* nrows */, ncols);
4250
0
        }
4251
0
    }
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_0, 4l, 4l, (ggml_type)8>::forward_mul_mat_one_chunk(ggml_compute_params*, ggml_tensor*, long, long, long, long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_0, 8l, 4l, (ggml_type)8>::forward_mul_mat_one_chunk(ggml_compute_params*, ggml_tensor*, long, long, long, long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_0, 8l, 8l, (ggml_type)8>::forward_mul_mat_one_chunk(ggml_compute_params*, ggml_tensor*, long, long, long, long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_K, 4l, 8l, (ggml_type)15>::forward_mul_mat_one_chunk(ggml_compute_params*, ggml_tensor*, long, long, long, long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_K, 8l, 8l, (ggml_type)15>::forward_mul_mat_one_chunk(ggml_compute_params*, ggml_tensor*, long, long, long, long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q5_K, 4l, 8l, (ggml_type)15>::forward_mul_mat_one_chunk(ggml_compute_params*, ggml_tensor*, long, long, long, long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q5_K, 8l, 8l, (ggml_type)15>::forward_mul_mat_one_chunk(ggml_compute_params*, ggml_tensor*, long, long, long, long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q6_K, 4l, 8l, (ggml_type)15>::forward_mul_mat_one_chunk(ggml_compute_params*, ggml_tensor*, long, long, long, long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q6_K, 8l, 8l, (ggml_type)15>::forward_mul_mat_one_chunk(ggml_compute_params*, ggml_tensor*, long, long, long, long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q2_K, 8l, 8l, (ggml_type)15>::forward_mul_mat_one_chunk(ggml_compute_params*, ggml_tensor*, long, long, long, long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_iq4_nl, 4l, 4l, (ggml_type)8>::forward_mul_mat_one_chunk(ggml_compute_params*, ggml_tensor*, long, long, long, long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_iq4_nl, 8l, 8l, (ggml_type)8>::forward_mul_mat_one_chunk(ggml_compute_params*, ggml_tensor*, long, long, long, long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_mxfp4, 4l, 4l, (ggml_type)8>::forward_mul_mat_one_chunk(ggml_compute_params*, ggml_tensor*, long, long, long, long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_mxfp4, 8l, 8l, (ggml_type)8>::forward_mul_mat_one_chunk(ggml_compute_params*, ggml_tensor*, long, long, long, long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q8_0, 4l, 4l, (ggml_type)8>::forward_mul_mat_one_chunk(ggml_compute_params*, ggml_tensor*, long, long, long, long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q8_0, 8l, 4l, (ggml_type)8>::forward_mul_mat_one_chunk(ggml_compute_params*, ggml_tensor*, long, long, long, long)
4252
4253
0
    void forward_mul_mat(ggml_compute_params * params, ggml_tensor * op) {
4254
0
        const ggml_tensor * src0 = op->src[0];
4255
0
        const ggml_tensor * src1 = op->src[1];
4256
0
        ggml_tensor *       dst  = op;
4257
4258
0
        GGML_TENSOR_BINARY_OP_LOCALS
4259
4260
0
        const int ith = params->ith;
4261
0
        const int nth = params->nth;
4262
4263
0
        GGML_ASSERT(ne0 == ne01);
4264
0
        GGML_ASSERT(ne1 == ne11);
4265
0
        GGML_ASSERT(ne2 == ne12);
4266
0
        GGML_ASSERT(ne3 == ne13);
4267
4268
        // dst cannot be transposed or permuted
4269
0
        GGML_ASSERT(nb0 == sizeof(float));
4270
0
        GGML_ASSERT(nb0 <= nb1);
4271
0
        GGML_ASSERT(nb1 <= nb2);
4272
0
        GGML_ASSERT(nb2 <= nb3);
4273
4274
        // TODO: General batched mul mat for 4D tensors
4275
        // Currently only supports 3D tensors
4276
0
        GGML_ASSERT(ne03 == 1);
4277
0
        GGML_ASSERT(ne13 == 1);
4278
0
        GGML_ASSERT(ne3 == 1);
4279
4280
0
        GGML_ASSERT(src1->type == GGML_TYPE_F32);
4281
4282
0
        GGML_ASSERT(ggml_n_dims(op->src[0]) == 2);
4283
        // GGML_ASSERT(ggml_n_dims(op->src[1]) == 2);
4284
4285
0
        char *       wdata = static_cast<char *>(params->wdata);
4286
0
        const size_t nbw1  = ggml_row_size(PARAM_TYPE, ne10);
4287
0
        const size_t nbw2  = nbw1 * ne11;
4288
4289
0
        assert(params->wsize >= nbw2 * ne12);
4290
4291
0
        const ggml_from_float_t from_float = ggml_get_type_traits_cpu(PARAM_TYPE)->from_float;
4292
4293
        // INFO: Quantization is done in planes to avoid extra complexity in chunking.
4294
        // Flattening dimensions not multiple of INTER_SIZE would require extra handling depending on how
4295
        // the planes are broadcast.
4296
0
        for (int64_t i12 = 0; i12 < ne12; i12++) {
4297
0
            char * data_ptr  = (char *) src1->data + i12 * nb12;
4298
0
            char * wdata_ptr = wdata + i12 * nbw2;
4299
4300
0
            for (int64_t i11 = ith * 4; i11 < ne11 - ne11 % 4; i11 += nth * 4) {
4301
0
                ggml_quantize_mat_t<INTER_SIZE, PARAM_TYPE>((float *) (data_ptr + i11 * nb11),
4302
0
                                                            (void *) (wdata_ptr + i11 * nbw1), 4, ne10);
4303
0
            }
4304
4305
0
            const int64_t i11_processed = ne11 - ne11 % 4;
4306
0
            for (int64_t i11 = i11_processed + ith; i11 < ne11; i11 += nth) {
4307
0
                from_float((float *) (data_ptr + i11 * nb11), (void *) (wdata_ptr + i11 * nbw1), ne10);
4308
0
            }
4309
0
        }
4310
4311
        // disable for NUMA
4312
0
        const bool disable_chunking = ggml_is_numa();
4313
4314
        // 4x chunks per thread
4315
0
        const int64_t nr0 = ggml_nrows(op->src[0]);
4316
4317
0
        int     nth_scaled  = nth * 4;
4318
0
        int64_t chunk_size0 = (nr0 + nth_scaled - 1) / nth_scaled;
4319
0
        int64_t nchunk0     = (nr0 + chunk_size0 - 1) / chunk_size0;
4320
4321
        // src1 is chunked only by full planes.
4322
        // When we flatten we need to address dimensions not multiple of the q8 INTER_SIZE
4323
        // to route them thorugh GEMV.
4324
        // nchunk1 = ne12 also avoids messing the chunking for models with no 3d tensors
4325
        // to avoid affecting their performance
4326
0
        int64_t nchunk1 = ne12;
4327
4328
        // Ensure minimum chunk size to avoid alignment issues with high thread counts
4329
        // Minimum chunk size should be at least NB_COLS to prevent overlapping chunks after alignment
4330
0
        const int64_t min_chunk_size = NB_COLS;
4331
0
        if (nchunk0 > 0 && (nr0 / nchunk0) < min_chunk_size && nr0 >= min_chunk_size) {
4332
0
            nchunk0 = (nr0 + min_chunk_size - 1) / min_chunk_size;
4333
0
        }
4334
4335
0
        int64_t dr0 = (nr0 + nchunk0 - 1) / nchunk0;
4336
        // Only increase nchunk0 to nth if it won't make chunks too small
4337
0
        if (nth == 1 || ((nchunk0 < nth || disable_chunking) && (nr0 + nth - 1) / nth >= min_chunk_size)) {
4338
0
            nchunk0 = nth;
4339
0
            dr0 = (nr0 + nchunk0 - 1) / nchunk0;
4340
0
        }
4341
4342
        // Ensure nchunk doesn't exceed the number of rows divided by minimum chunk size
4343
        // This prevents creating too many tiny chunks that could overlap after alignment
4344
0
        const int64_t max_nchunk = (nr0 + min_chunk_size - 1) / min_chunk_size;
4345
0
        nchunk0                  = MIN(nchunk0, max_nchunk);
4346
4347
0
        if (ith == 0) {
4348
            // Every thread starts at ith, so the first unprocessed chunk is nth.  This save a bit of coordination right at the start.
4349
0
            ggml_threadpool_chunk_set(params->threadpool, nth);
4350
0
        }
4351
4352
0
        ggml_barrier(params->threadpool);
4353
4354
        // The first chunk comes from our thread_id, the rest will get auto-assigned.
4355
0
        int current_chunk = ith;
4356
4357
0
        while (current_chunk < nchunk0 * nchunk1) {
4358
0
            const int64_t ith0 = current_chunk % nchunk0;
4359
0
            const int64_t ith1 = current_chunk / nchunk0;
4360
4361
0
            int64_t src0_start = dr0 * ith0;
4362
0
            int64_t src0_end   = MIN(src0_start + dr0, nr0);
4363
4364
            // full-plane range for src1
4365
0
            int64_t src1_start = ith1 * ne11;
4366
0
            int64_t src1_end = (ith1 + 1) * ne11;
4367
4368
            // Align boundaries to NB_COLS - round up to ensure all data is included
4369
            // The chunk size limiting above ensures chunks are large enough to prevent overlaps
4370
0
            src0_start = (src0_start % NB_COLS) ? src0_start + NB_COLS - (src0_start % NB_COLS) : src0_start;
4371
0
            src0_end   = (src0_end % NB_COLS) ? src0_end + NB_COLS - (src0_end % NB_COLS) : src0_end;
4372
0
            src0_end   = MIN(src0_end, ne01);
4373
4374
            // Make sure current plane is the last one before exiting
4375
0
            if (src0_start >= src0_end) {
4376
0
                current_chunk = ggml_threadpool_chunk_add(params->threadpool, 1);
4377
0
                continue;
4378
0
            }
4379
4380
0
            forward_mul_mat_one_chunk(params, dst, src0_start, src0_end, src1_start, src1_end);
4381
4382
0
            current_chunk = ggml_threadpool_chunk_add(params->threadpool, 1);
4383
0
        }
4384
0
    }
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_0, 4l, 4l, (ggml_type)8>::forward_mul_mat(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_0, 8l, 4l, (ggml_type)8>::forward_mul_mat(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_0, 8l, 8l, (ggml_type)8>::forward_mul_mat(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_K, 4l, 8l, (ggml_type)15>::forward_mul_mat(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_K, 8l, 8l, (ggml_type)15>::forward_mul_mat(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q5_K, 4l, 8l, (ggml_type)15>::forward_mul_mat(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q5_K, 8l, 8l, (ggml_type)15>::forward_mul_mat(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q6_K, 4l, 8l, (ggml_type)15>::forward_mul_mat(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q6_K, 8l, 8l, (ggml_type)15>::forward_mul_mat(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q2_K, 8l, 8l, (ggml_type)15>::forward_mul_mat(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_iq4_nl, 4l, 4l, (ggml_type)8>::forward_mul_mat(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_iq4_nl, 8l, 8l, (ggml_type)8>::forward_mul_mat(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_mxfp4, 4l, 4l, (ggml_type)8>::forward_mul_mat(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_mxfp4, 8l, 8l, (ggml_type)8>::forward_mul_mat(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q8_0, 4l, 4l, (ggml_type)8>::forward_mul_mat(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q8_0, 8l, 4l, (ggml_type)8>::forward_mul_mat(ggml_compute_params*, ggml_tensor*)
4385
4386
0
    void forward_mul_mat_id(ggml_compute_params * params, ggml_tensor * op) {
4387
0
        const ggml_tensor * src0 = op->src[0];
4388
0
        const ggml_tensor * src1 = op->src[1];
4389
0
        const ggml_tensor * ids  = op->src[2];
4390
0
        ggml_tensor *       dst  = op;
4391
4392
0
        GGML_TENSOR_BINARY_OP_LOCALS
4393
4394
0
        const int ith = params->ith;
4395
0
        const int nth = params->nth;
4396
4397
0
        const ggml_from_float_t from_float = ggml_get_type_traits_cpu(PARAM_TYPE)->from_float;
4398
4399
        // we don't support permuted src0 or src1
4400
0
        GGML_ASSERT(nb00 == ggml_type_size(src0->type));
4401
0
        GGML_ASSERT(nb10 == ggml_type_size(src1->type));
4402
4403
        // dst cannot be transposed or permuted
4404
0
        GGML_ASSERT(nb0 == sizeof(float));
4405
0
        GGML_ASSERT(nb0 <= nb1);
4406
0
        GGML_ASSERT(nb1 <= nb2);
4407
0
        GGML_ASSERT(nb2 <= nb3);
4408
4409
0
        GGML_ASSERT(ne03 == 1);
4410
0
        GGML_ASSERT(ne13 == 1);
4411
0
        GGML_ASSERT(ne3  == 1);
4412
4413
0
        GGML_ASSERT(src1->type == GGML_TYPE_F32);
4414
4415
        // row groups
4416
0
        const int n_ids = ids->ne[0]; // n_expert_used
4417
0
        const int n_as  = ne02;       // n_expert
4418
4419
0
        const size_t nbw1 = ggml_row_size(PARAM_TYPE, ne10);
4420
0
        const size_t nbw2 = nbw1*ne11;
4421
0
        const size_t nbw3 = nbw2*ne12;
4422
4423
0
        struct mmid_row_mapping {
4424
0
            int32_t i1;
4425
0
            int32_t i2;
4426
0
        };
4427
4428
0
        GGML_ASSERT(params->wsize >=
4429
0
                (GGML_PAD(nbw3, sizeof(int64_t)) +
4430
0
                 n_as*(ne12 + 1)*sizeof(mmid_row_mapping))
4431
0
                );
4432
4433
0
        auto * wdata          = (char *)params->wdata;
4434
0
        auto * wdata_src1_end = (char *)wdata + GGML_PAD(nbw3, sizeof(int64_t));
4435
4436
        // total of [n_as][ne12 + 1] elements of type mmid_row_mapping (2*int32_t = int64_t)
4437
0
        auto * matrix_row_counts = (int64_t *) (wdata_src1_end);                                        // [n_as]
4438
0
        struct mmid_row_mapping * matrix_rows = (struct mmid_row_mapping *) (matrix_row_counts + n_as); // [n_as][ne12]
4439
4440
        // src1: float32 => param type
4441
0
        for (int64_t i12 = 0; i12 < ne12; ++i12) {
4442
0
            for (int64_t i11 = ith; i11 < ne11; i11 += nth) {
4443
0
                from_float((float *)((char *) src1->data + i12 * nb12 + i11 * nb11),
4444
0
                           (void *)               (wdata + i12 * nbw2 + i11 * nbw1),
4445
0
                           ne10);
4446
0
            }
4447
0
        }
4448
4449
0
#define MMID_MATRIX_ROW(row_id, i1) matrix_rows[(row_id) * ne12 + (i1)]
4450
4451
0
        if (ith == 0) {
4452
            // initialize matrix_row_counts
4453
0
            memset(matrix_row_counts, 0, n_as * sizeof(int64_t));
4454
4455
            // group rows by src0 matrix
4456
0
            for (int32_t iid1 = 0; iid1 < ids->ne[1]; ++iid1) {
4457
0
                for (int32_t id = 0; id < n_ids; ++id) {
4458
0
                    const int32_t i02 =
4459
0
                        *(const int32_t *) ((const char *) ids->data + iid1 * ids->nb[1] + id * ids->nb[0]);
4460
4461
0
                    GGML_ASSERT(i02 >= 0 && i02 < n_as);
4462
4463
0
                    MMID_MATRIX_ROW(i02, matrix_row_counts[i02]) = { id, iid1 };
4464
0
                    matrix_row_counts[i02] += 1;
4465
0
                }
4466
0
            }
4467
0
        }
4468
4469
0
        ggml_barrier(params->threadpool);
4470
4471
        // compute each matrix multiplication in sequence
4472
0
        for (int cur_a = 0; cur_a < n_as; ++cur_a) {
4473
0
            const int64_t cne1 = matrix_row_counts[cur_a];
4474
4475
0
            if (cne1 == 0) {
4476
0
                continue;
4477
0
            }
4478
4479
0
            const auto * src0_cur = (const char *) src0->data + cur_a*nb02;
4480
4481
            //const int64_t nr0 = ne01; // src0 rows
4482
0
            const int64_t nr1 = cne1; // src1 rows
4483
4484
0
            int64_t src0_cur_start = (ith * ne01) / nth;
4485
0
            int64_t src0_cur_end   = ((ith + 1) * ne01) / nth;
4486
4487
            // Align boundaries to NB_COLS - round up to ensure all data is included
4488
0
            src0_cur_start = (src0_cur_start % NB_COLS) ? src0_cur_start + NB_COLS - (src0_cur_start % NB_COLS) : src0_cur_start;
4489
0
            src0_cur_end   = (src0_cur_end   % NB_COLS) ? src0_cur_end   + NB_COLS - (src0_cur_end   % NB_COLS) : src0_cur_end;
4490
0
            if (src0_cur_end > ne01) {
4491
0
                src0_cur_end = ne01;
4492
0
            }
4493
4494
0
            if (src0_cur_start >= src0_cur_end) {
4495
0
                return;
4496
0
            }
4497
4498
0
            for (int ir1 = 0; ir1 < nr1; ir1++) {
4499
0
                struct mmid_row_mapping row_mapping = MMID_MATRIX_ROW(cur_a, ir1);
4500
4501
0
                const int id = row_mapping.i1;  // selected expert index
4502
4503
0
                const int64_t i11 = id % ne11;
4504
0
                const int64_t i12 = row_mapping.i2;  // row index in src1
4505
4506
0
                const int64_t i1 = id;               // selected expert index
4507
0
                const int64_t i2 = i12;              // row
4508
4509
0
                const auto * src1_col = (const char *) wdata + (i11 * nbw1 + i12 * nbw2);
4510
4511
0
                gemv<BLOC_TYPE, INTER_SIZE, NB_COLS, PARAM_TYPE>(
4512
0
                    ne00, (float *) ((char *) dst->data + (i1 * nb1 + i2 * nb2)) + src0_cur_start, ne01,
4513
0
                    src0_cur + src0_cur_start * nb01, src1_col, 1, src0_cur_end - src0_cur_start);
4514
0
            }
4515
0
        }
4516
0
#undef MMID_MATRIX_ROW
4517
0
    }
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_0, 4l, 4l, (ggml_type)8>::forward_mul_mat_id(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_0, 8l, 4l, (ggml_type)8>::forward_mul_mat_id(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_0, 8l, 8l, (ggml_type)8>::forward_mul_mat_id(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_K, 4l, 8l, (ggml_type)15>::forward_mul_mat_id(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_K, 8l, 8l, (ggml_type)15>::forward_mul_mat_id(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q5_K, 4l, 8l, (ggml_type)15>::forward_mul_mat_id(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q5_K, 8l, 8l, (ggml_type)15>::forward_mul_mat_id(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q6_K, 4l, 8l, (ggml_type)15>::forward_mul_mat_id(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q6_K, 8l, 8l, (ggml_type)15>::forward_mul_mat_id(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q2_K, 8l, 8l, (ggml_type)15>::forward_mul_mat_id(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_iq4_nl, 4l, 4l, (ggml_type)8>::forward_mul_mat_id(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_iq4_nl, 8l, 8l, (ggml_type)8>::forward_mul_mat_id(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_mxfp4, 4l, 4l, (ggml_type)8>::forward_mul_mat_id(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_mxfp4, 8l, 8l, (ggml_type)8>::forward_mul_mat_id(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q8_0, 4l, 4l, (ggml_type)8>::forward_mul_mat_id(ggml_compute_params*, ggml_tensor*)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q8_0, 8l, 4l, (ggml_type)8>::forward_mul_mat_id(ggml_compute_params*, ggml_tensor*)
4518
4519
0
    int repack(struct ggml_tensor * t, const void * data, size_t data_size) override {
4520
0
        GGML_LOG_DEBUG("%s: repack tensor %s with %s_%dx%d\n", __func__, t->name, ggml_type_name(t->type),
4521
0
                       (int) NB_COLS, (int) INTER_SIZE);
4522
0
        return ggml::cpu::repack::repack<BLOC_TYPE, INTER_SIZE, NB_COLS>(t, data, data_size);
4523
0
    }
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_0, 4l, 4l, (ggml_type)8>::repack(ggml_tensor*, void const*, unsigned long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_0, 8l, 4l, (ggml_type)8>::repack(ggml_tensor*, void const*, unsigned long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_0, 8l, 8l, (ggml_type)8>::repack(ggml_tensor*, void const*, unsigned long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_K, 4l, 8l, (ggml_type)15>::repack(ggml_tensor*, void const*, unsigned long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q4_K, 8l, 8l, (ggml_type)15>::repack(ggml_tensor*, void const*, unsigned long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q5_K, 4l, 8l, (ggml_type)15>::repack(ggml_tensor*, void const*, unsigned long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q5_K, 8l, 8l, (ggml_type)15>::repack(ggml_tensor*, void const*, unsigned long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q6_K, 4l, 8l, (ggml_type)15>::repack(ggml_tensor*, void const*, unsigned long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q6_K, 8l, 8l, (ggml_type)15>::repack(ggml_tensor*, void const*, unsigned long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q2_K, 8l, 8l, (ggml_type)15>::repack(ggml_tensor*, void const*, unsigned long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_iq4_nl, 4l, 4l, (ggml_type)8>::repack(ggml_tensor*, void const*, unsigned long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_iq4_nl, 8l, 8l, (ggml_type)8>::repack(ggml_tensor*, void const*, unsigned long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_mxfp4, 4l, 4l, (ggml_type)8>::repack(ggml_tensor*, void const*, unsigned long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_mxfp4, 8l, 8l, (ggml_type)8>::repack(ggml_tensor*, void const*, unsigned long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q8_0, 4l, 4l, (ggml_type)8>::repack(ggml_tensor*, void const*, unsigned long)
Unexecuted instantiation: ggml::cpu::repack::tensor_traits<block_q8_0, 8l, 4l, (ggml_type)8>::repack(ggml_tensor*, void const*, unsigned long)
4524
};
4525
4526
}  // namespace ggml::cpu::repack
4527
4528
0
static const ggml::cpu::tensor_traits * ggml_repack_get_optimal_repack_type(const struct ggml_tensor * cur) {
4529
    // instance for Q4
4530
0
    static const ggml::cpu::repack::tensor_traits<block_q4_0, 4, 4, GGML_TYPE_Q8_0> q4_0_4x4_q8_0;
4531
0
    static const ggml::cpu::repack::tensor_traits<block_q4_0, 8, 4, GGML_TYPE_Q8_0> q4_0_4x8_q8_0;
4532
0
    static const ggml::cpu::repack::tensor_traits<block_q4_0, 8, 8, GGML_TYPE_Q8_0> q4_0_8x8_q8_0;
4533
4534
    // instance for Q4_K
4535
0
    static const ggml::cpu::repack::tensor_traits<block_q4_K, 4, 8, GGML_TYPE_Q8_K> q4_K_8x4_q8_K;
4536
0
    static const ggml::cpu::repack::tensor_traits<block_q4_K, 8, 8, GGML_TYPE_Q8_K> q4_K_8x8_q8_K;
4537
4538
    // instance for Q5_K
4539
0
    static const ggml::cpu::repack::tensor_traits<block_q5_K, 4, 8, GGML_TYPE_Q8_K> q5_K_8x4_q8_K;
4540
0
    static const ggml::cpu::repack::tensor_traits<block_q5_K, 8, 8, GGML_TYPE_Q8_K> q5_K_8x8_q8_K;
4541
4542
    // instance for Q6_K
4543
0
    static const ggml::cpu::repack::tensor_traits<block_q6_K, 4, 8, GGML_TYPE_Q8_K> q6_K_8x4_q8_K;
4544
0
    static const ggml::cpu::repack::tensor_traits<block_q6_K, 8, 8, GGML_TYPE_Q8_K> q6_K_8x8_q8_K;
4545
4546
    // instance for Q2
4547
0
    static const ggml::cpu::repack::tensor_traits<block_q2_K, 8, 8, GGML_TYPE_Q8_K> q2_K_8x8_q8_K;
4548
4549
    // instance for IQ4
4550
0
    static const ggml::cpu::repack::tensor_traits<block_iq4_nl, 4, 4, GGML_TYPE_Q8_0> iq4_nl_4x4_q8_0;
4551
0
    static const ggml::cpu::repack::tensor_traits<block_iq4_nl, 8, 8, GGML_TYPE_Q8_0> iq4_nl_8x8_q8_0;
4552
4553
    // instance for MXFP4
4554
0
    static const ggml::cpu::repack::tensor_traits<block_mxfp4, 4, 4, GGML_TYPE_Q8_0> mxfp4_4x4_q8_0;
4555
0
    static const ggml::cpu::repack::tensor_traits<block_mxfp4, 8, 8, GGML_TYPE_Q8_0> mxfp4_8x8_q8_0;
4556
4557
    // instance for Q8_0
4558
0
    static const ggml::cpu::repack::tensor_traits<block_q8_0, 4, 4, GGML_TYPE_Q8_0> q8_0_4x4_q8_0;
4559
0
    static const ggml::cpu::repack::tensor_traits<block_q8_0, 8, 4, GGML_TYPE_Q8_0> q8_0_4x8_q8_0;
4560
4561
    // instances for RISC-V
4562
    //
4563
    // These implement outer-product style matrix multiplication kernels with
4564
    // an interleave of 1.
4565
#if defined __riscv_zvfh
4566
    static const ggml::cpu::repack::tensor_traits<block_q4_0, 1, 16, GGML_TYPE_Q8_0> q4_0_16x1_q8_0;
4567
    static const ggml::cpu::repack::tensor_traits<block_q4_K, 1, 16, GGML_TYPE_Q8_K> q4_K_16x1_q8_K;
4568
    static const ggml::cpu::repack::tensor_traits<block_iq4_nl, 1, 16, GGML_TYPE_Q8_0> iq4_nl_16x1_q8_0;
4569
    static const ggml::cpu::repack::tensor_traits<block_q8_0, 1, 16, GGML_TYPE_Q8_0> q8_0_16x1_q8_0;
4570
    static const ggml::cpu::repack::tensor_traits<block_q2_K, 1, 16, GGML_TYPE_Q8_K> q2_K_16x1_q8_K;
4571
#endif
4572
4573
0
    if (cur->type == GGML_TYPE_Q4_0) {
4574
0
        if (ggml_cpu_has_avx2() || (ggml_cpu_has_sve() && ggml_cpu_has_matmul_int8() && ggml_cpu_get_sve_cnt() == QK8_0)) {
4575
0
            if (cur->ne[1] % 8 == 0) {
4576
0
                return &q4_0_8x8_q8_0;
4577
0
            }
4578
0
        }
4579
0
        if (ggml_cpu_has_neon() && ggml_cpu_has_matmul_int8()) {
4580
0
            if (cur->ne[1] % 4 == 0) {
4581
0
                return &q4_0_4x8_q8_0;
4582
0
            }
4583
0
        }
4584
0
        if (ggml_cpu_has_neon() && ggml_cpu_has_dotprod()) {
4585
0
            if (cur->ne[1] % 4 == 0) {
4586
0
                return &q4_0_4x4_q8_0;
4587
0
            }
4588
0
        }
4589
0
        if (ggml_cpu_has_riscv_v()) {
4590
            #if defined __riscv_zvfh
4591
            switch (__riscv_vlenb() * 8) {
4592
                case 128:  { break; } // TODO
4593
                case 256:  { if (cur->ne[1] % 16 == 0) { return &q4_0_16x1_q8_0; } break; }
4594
                case 512:  { break; } // TODO
4595
                case 1024: { break; } // TODO
4596
                default:   { return nullptr; }
4597
            }
4598
            #endif
4599
0
        }
4600
0
    } else if (cur->type == GGML_TYPE_Q4_K) {
4601
0
        if (ggml_cpu_has_avx2()) {
4602
0
            if (cur->ne[1] % 8 == 0) {
4603
0
                return &q4_K_8x8_q8_K;
4604
0
            }
4605
0
        }
4606
0
        if (ggml_cpu_has_neon() && ggml_cpu_has_matmul_int8()) {
4607
0
            if (cur->ne[1] % 8 == 0) {
4608
0
                return &q4_K_8x8_q8_K;
4609
0
            }
4610
0
        }
4611
0
        if (ggml_cpu_has_neon() && ggml_cpu_has_dotprod()) {
4612
0
            if (cur->ne[1] % 8 == 0) {
4613
0
                return &q4_K_8x4_q8_K;
4614
0
            }
4615
0
        }
4616
0
        if (ggml_cpu_has_riscv_v()) {
4617
            #if defined __riscv_zvfh
4618
            switch (__riscv_vlenb() * 8) {
4619
                case 128:  { break; } // TODO
4620
                case 256:  { if (cur->ne[1] % 16 == 0) { return &q4_K_16x1_q8_K; } break; }
4621
                case 512:  { break; } // TODO
4622
                case 1024: { break; } // TODO
4623
                default:   { return nullptr; }
4624
            }
4625
            #endif
4626
0
        }
4627
0
    } else if (cur->type == GGML_TYPE_Q2_K) {
4628
0
        if (ggml_cpu_has_avx512()) {
4629
0
            if (cur->ne[1] % 8 == 0) {
4630
0
                return &q2_K_8x8_q8_K;
4631
0
            }
4632
0
        }
4633
0
        if (ggml_cpu_has_riscv_v()) {
4634
            #if defined __riscv_zvfh
4635
            switch (__riscv_vlenb() * 8) {
4636
                case 128:  { break; } // TODO
4637
                case 256:  { if (cur->ne[1] % 16 == 0) { return &q2_K_16x1_q8_K; } break; }
4638
                case 512:  { break; } // TODO
4639
                case 1024: { break; } // TODO
4640
                default:   { return nullptr; }
4641
            }
4642
            #endif
4643
0
        }
4644
0
    } else if (cur->type == GGML_TYPE_Q5_K) {
4645
0
        if (ggml_cpu_has_neon() && ggml_cpu_has_matmul_int8()) {
4646
0
            if (cur->ne[1] % 8 == 0) {
4647
0
                return &q5_K_8x8_q8_K;
4648
0
            }
4649
0
        }
4650
0
        if (ggml_cpu_has_neon() && ggml_cpu_has_dotprod()) {
4651
0
            if (cur->ne[1] % 8 == 0) {
4652
0
                return &q5_K_8x4_q8_K;
4653
0
            }
4654
0
        }
4655
0
    } else if (cur->type == GGML_TYPE_Q6_K) {
4656
0
        if (ggml_cpu_has_neon() && ggml_cpu_has_matmul_int8()) {
4657
0
            if (cur->ne[1] % 8 == 0) {
4658
0
                return &q6_K_8x8_q8_K;
4659
0
            }
4660
0
        }
4661
0
        if (ggml_cpu_has_neon() && ggml_cpu_has_dotprod()) {
4662
0
            if (cur->ne[1] % 8 == 0) {
4663
0
                return &q6_K_8x4_q8_K;
4664
0
            }
4665
0
        }
4666
0
    } else if (cur->type == GGML_TYPE_IQ4_NL) {
4667
0
        if (ggml_cpu_has_avx2()) {
4668
0
            if (cur->ne[1] % 8 == 0) {
4669
0
                return &iq4_nl_8x8_q8_0;
4670
0
            }
4671
0
        }
4672
0
        if (ggml_cpu_has_neon() && ggml_cpu_has_dotprod()) {
4673
0
            if (cur->ne[1] % 4 == 0) {
4674
0
                return &iq4_nl_4x4_q8_0;
4675
0
            }
4676
0
        }
4677
0
        if (ggml_cpu_has_riscv_v()) {
4678
            #if defined __riscv_zvfh
4679
            switch (__riscv_vlenb() * 8) {
4680
                case 128:  { break; } // TODO
4681
                case 256:  { if (cur->ne[1] % 16 == 0) { return &iq4_nl_16x1_q8_0; } break; }
4682
                case 512:  { break; } // TODO
4683
                case 1024: { break; } // TODO
4684
                default:   { return nullptr; }
4685
            }
4686
            #endif
4687
0
        }
4688
0
    } else if (cur->type == GGML_TYPE_MXFP4) {
4689
0
        if (ggml_cpu_has_avx2()) {
4690
0
            if (cur->ne[1] % 8 == 0) {
4691
0
                return &mxfp4_8x8_q8_0;
4692
0
            }
4693
0
        }
4694
0
        if (ggml_cpu_has_neon() && ggml_cpu_has_dotprod()) {
4695
0
            if (cur->ne[1] % 4 == 0) {
4696
0
                return &mxfp4_4x4_q8_0;
4697
0
            }
4698
0
        }
4699
0
    } else if (cur->type == GGML_TYPE_Q8_0) {
4700
0
        if (ggml_cpu_has_neon() && ggml_cpu_has_matmul_int8()) {
4701
0
            if (cur->ne[1] % 4 == 0) {
4702
0
                return &q8_0_4x8_q8_0;
4703
0
            }
4704
0
        }
4705
0
        if (ggml_cpu_has_neon() && ggml_cpu_has_dotprod()) {
4706
0
            if (cur->ne[1] % 4 == 0) {
4707
0
                return &q8_0_4x4_q8_0;
4708
0
            }
4709
0
        }
4710
0
        if (ggml_cpu_has_riscv_v()) {
4711
            #if defined __riscv_zvfh
4712
            switch (__riscv_vlenb() * 8) {
4713
                case 128:  { break; } // TODO
4714
                case 256:  { if (cur->ne[1] % 16 == 0) { return &q8_0_16x1_q8_0; } break; }
4715
                case 512:  { break; } // TODO
4716
                case 1024: { break; } // TODO
4717
                default:   { return nullptr; }
4718
            }
4719
            #endif
4720
0
        }
4721
0
    }
4722
4723
0
    return nullptr;
4724
0
}
4725
4726
0
static enum ggml_status ggml_backend_cpu_repack_buffer_init_tensor(ggml_backend_buffer_t buffer, struct ggml_tensor * tensor) {
4727
0
    tensor->extra = (void *) const_cast<ggml::cpu::tensor_traits *>(ggml_repack_get_optimal_repack_type(tensor));
4728
4729
0
    GGML_UNUSED(buffer);
4730
0
    return GGML_STATUS_SUCCESS;
4731
0
}
4732
4733
static void ggml_backend_cpu_repack_buffer_set_tensor(ggml_backend_buffer_t buffer, struct ggml_tensor * tensor,
4734
0
                                                       const void * data, size_t offset, size_t size) {
4735
0
    GGML_ASSERT(offset == 0);
4736
0
    GGML_ASSERT(size == ggml_nbytes(tensor));
4737
4738
0
    auto tensor_traits = (ggml::cpu::repack::tensor_traits_base *) tensor->extra;
4739
0
    auto OK            = tensor_traits->repack(tensor, data, size);
4740
4741
0
    GGML_ASSERT(OK == 0);
4742
0
    GGML_UNUSED(buffer);
4743
0
}
4744
4745
0
static const char * ggml_backend_cpu_repack_buffer_type_get_name(ggml_backend_buffer_type_t buft) {
4746
0
    return "CPU_REPACK";
4747
4748
0
    GGML_UNUSED(buft);
4749
0
}
4750
4751
0
static ggml_backend_buffer_t ggml_backend_cpu_repack_buffer_type_alloc_buffer(ggml_backend_buffer_type_t buft, size_t size) {
4752
0
    ggml_backend_buffer_t buffer = ggml_backend_buft_alloc_buffer(ggml_backend_cpu_buffer_type(), size);
4753
4754
0
    if (buffer == nullptr) {
4755
0
        return nullptr;
4756
0
    }
4757
4758
0
    buffer->buft              = buft;
4759
0
    buffer->iface.init_tensor = ggml_backend_cpu_repack_buffer_init_tensor;
4760
0
    buffer->iface.set_tensor  = ggml_backend_cpu_repack_buffer_set_tensor;
4761
0
    buffer->iface.get_tensor  = nullptr;
4762
0
    buffer->iface.cpy_tensor  = nullptr;
4763
0
    return buffer;
4764
0
}
4765
4766
0
static size_t ggml_backend_cpu_repack_buffer_type_get_alignment(ggml_backend_buffer_type_t buft) {
4767
0
    return TENSOR_ALIGNMENT;
4768
4769
0
    GGML_UNUSED(buft);
4770
0
}
4771
4772
namespace ggml::cpu::repack {
4773
class extra_buffer_type : ggml::cpu::extra_buffer_type {
4774
0
    bool supports_op(ggml_backend_dev_t, const struct ggml_tensor * op) override {
4775
0
        if (    op->op == GGML_OP_MUL_MAT &&
4776
0
                op->src[0]->buffer &&
4777
0
                (ggml_n_dims(op->src[0]) == 2) &&
4778
0
                op->src[0]->buffer->buft == ggml_backend_cpu_repack_buffer_type() &&
4779
0
                ggml_repack_get_optimal_repack_type(op->src[0])
4780
0
                ) {
4781
0
            if (op->src[1]->buffer && !ggml_backend_buft_is_host(op->src[1]->buffer->buft)) {
4782
0
                return false;
4783
0
            }
4784
0
            if (op->src[1]->type == GGML_TYPE_F32) {
4785
0
                return true;
4786
0
            }
4787
            //if (op->src[1]->type == GGML_TYPE_Q8_0) {
4788
            //    return true;
4789
            //}
4790
            // may be possible if Q8_0 packed...
4791
0
        } else if (op->op == GGML_OP_MUL_MAT_ID
4792
0
                && op->src[0]->buffer
4793
0
                && (ggml_n_dims(op->src[0]) == 3)
4794
0
                && op->src[0]->buffer->buft == ggml_backend_cpu_repack_buffer_type()
4795
0
                && ggml_repack_get_optimal_repack_type(op->src[0])
4796
0
                ) {
4797
0
            if (op->src[1]->buffer && !ggml_backend_buft_is_host(op->src[1]->buffer->buft)) {
4798
0
                return false;
4799
0
            }
4800
0
            if (op->src[1]->type == GGML_TYPE_F32) {
4801
0
                return true;
4802
0
            }
4803
            //if (op->src[1]->type == GGML_TYPE_Q8_0) {
4804
            //    return true;
4805
            //}
4806
0
        }
4807
0
        return false;
4808
0
    }
4809
4810
0
    ggml::cpu::tensor_traits * get_tensor_traits(const struct ggml_tensor * op) override {
4811
0
        if (op->op == GGML_OP_MUL_MAT || op->op == GGML_OP_MUL_MAT_ID) {
4812
0
            if (op->src[0]->buffer && op->src[0]->buffer->buft == ggml_backend_cpu_repack_buffer_type()) {
4813
0
                return (ggml::cpu::tensor_traits *) op->src[0]->extra;
4814
0
            }
4815
0
        }
4816
0
        return nullptr;
4817
0
    }
4818
};
4819
}  // namespace ggml::cpu::repack
4820
4821
0
ggml_backend_buffer_type_t ggml_backend_cpu_repack_buffer_type(void) {
4822
0
    static struct ggml_backend_buffer_type ggml_backend_cpu_buffer_type_repack = {
4823
0
        /* .iface    = */ {
4824
0
                           /* .get_name         = */ ggml_backend_cpu_repack_buffer_type_get_name,
4825
0
                           /* .alloc_buffer     = */ ggml_backend_cpu_repack_buffer_type_alloc_buffer,
4826
0
                           /* .get_alignment    = */ ggml_backend_cpu_repack_buffer_type_get_alignment,
4827
0
                           /* .get_max_size     = */ nullptr,  // defaults to SIZE_MAX
4828
0
                           /* .get_alloc_size   = */ nullptr,  // defaults to ggml_nbytes
4829
0
                           /* .is_host          = */ nullptr,
4830
0
                           },
4831
0
        /* .device  = */ ggml_backend_reg_dev_get(ggml_backend_cpu_reg(), 0),
4832
0
        /* .context = */ new ggml::cpu::repack::extra_buffer_type(),
4833
0
    };
4834
4835
0
    return &ggml_backend_cpu_buffer_type_repack;
4836
0
}