char-fork/llama.cpp

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

Neo Zhang[SYCL] support the missed types in cpy (#26005)d5d3e05bf

char/aliceai-t5-moe
15.1 KiB537 linesraw
1#ifndef GGML_SYCL_CPY_HPP
2#define GGML_SYCL_CPY_HPP
3
4#include "common.hpp"
5#include <float.h>
6
7typedef void (*cpy_kernel_t)(const char * cx, char * cdst);
8
9__dpct_inline__ int best_index_int8(int n, const int8_t * val, float x) {
10    if (x <= val[0]) {
11        return 0;
12    }
13    if (x >= val[n - 1]) {
14        return n - 1;
15    }
16    int ml = 0, mu = n - 1;
17    while (mu - ml > 1) {
18        int mav = (ml + mu) / 2;
19        if (x < val[mav]) {
20            mu = mav;
21        } else {
22            ml = mav;
23        }
24    }
25    return x - val[mu - 1] < val[mu] - x ? mu - 1 : mu;
26}
27
28inline void cpy_blck_f32_q8_0(const char * cxi, char * cdsti) {
29    const float * xi   = (const float *) cxi;
30    block_q8_0 *  dsti = (block_q8_0 *) cdsti;
31
32    float amax = 0.0f;  // absolute max
33
34    for (int j = 0; j < QK8_0; j++) {
35        const float v = xi[j];
36        amax          = sycl::fmax(amax, sycl::fabs((float) v));
37    }
38
39    const float d  = amax / ((1 << 7) - 1);
40    const float id = d ? 1.0f / d : 0.0f;
41
42    dsti->d = d;
43
44    for (int j = 0; j < QK8_0; ++j) {
45        const float x0 = xi[j] * id;
46
47        dsti->qs[j] = sycl::round((float) x0);
48    }
49}
50
51inline void cpy_blck_f32_q1_0(const char * cxi, char * cdsti) {
52    const float * xi   = (const float *) cxi;
53    block_q1_0 *  dsti = (block_q1_0 *) cdsti;
54
55    float sum_abs = 0.0f;
56    for (int j = 0; j < QK1_0; ++j) {
57        sum_abs += sycl::fabs((float) xi[j]);
58    }
59
60    dsti->d = sum_abs / QK1_0;
61
62    for (int j = 0; j < QK1_0 / 8; ++j) {
63        dsti->qs[j] = 0;
64    }
65
66    for (int j = 0; j < QK1_0; ++j) {
67        if (xi[j] >= 0.0f) {
68            dsti->qs[j / 8] |= (1u << (j % 8));
69        }
70    }
71}
72
73inline int round_nearest_int(float x) {
74    return (int)(x >= 0.0f ? x + 0.5f : x - 0.5f);
75}
76
77inline void cpy_blck_f32_q2_0(const char * cxi, char * cdsti) {
78    const float * xi   = (const float *) cxi;
79    block_q2_0 *  dsti = (block_q2_0 *) cdsti;
80
81    float amax = 0.0f;
82
83    for (int j = 0; j < QK2_0; ++j) {
84        amax = sycl::fmax(amax, sycl::fabs((float) xi[j]));
85    }
86
87    const float d  = amax;
88    const float id = d > 0.0f ? 1.0f / d : 0.0f;
89
90    dsti->d = d;
91
92    for (int j = 0; j < QK2_0 / 4; ++j) {
93        dsti->qs[j] = 0;
94    }
95
96    for (int j = 0; j < QK2_0; ++j) {
97        int q = round_nearest_int(xi[j] * id) + 1;
98        q = dpct::max(0, dpct::min(3, q));
99
100        const int byte_index = j / 4;
101        const int bit_offset = (j % 4) * 2;
102        dsti->qs[byte_index] |= (uint8_t) q << bit_offset;
103    }
104}
105
106inline int best_index_mxfp4(const float x, const float e) {
107    int best_index = 0;
108    float best_err = sycl::fabs((float) (kvalues_mxfp4[0] * e - x));
109    for (int i = 1; i < 16; ++i) {
110        const float err = sycl::fabs((float) (kvalues_mxfp4[i] * e - x));
111        if (err < best_err) {
112            best_index = i;
113            best_err = err;
114        }
115    }
116    return best_index;
117}
118
119inline int nearest_int_sycl(float x) {
120    const float val = x + 12582912.0f;
121    int i;
122    memcpy(&i, &val, sizeof(int));
123    return (i & 0x007fffff) - 0x00400000;
124}
125
126inline int nearest_int_ggml_sycl(float x) {
127    return (int) sycl::round((float) x);
128}
129
130inline uint8_t clamp_u8(const int x, const int lo, const int hi) {
131    return (uint8_t) dpct::max(lo, dpct::min(hi, x));
132}
133
134inline int8_t clamp_i8(const int x, const int lo, const int hi) {
135    return (int8_t) dpct::max(lo, dpct::min(hi, x));
136}
137
138constexpr float GROUP_MAX_EPS_SYCL = 1e-15f;
139
140inline float make_qx_quants_sycl(int n, int nmax, const float * x, int8_t * L, int rmse_type, const float * qw) {
141    float max = 0.0f;
142    float amax = 0.0f;
143    for (int i = 0; i < n; ++i) {
144        const float ax = sycl::fabs(x[i]);
145        if (ax > amax) {
146            amax = ax;
147            max = x[i];
148        }
149    }
150    if (amax < GROUP_MAX_EPS_SYCL) {
151        for (int i = 0; i < n; ++i) {
152            L[i] = 0;
153        }
154        return 0.0f;
155    }
156
157    float iscale = -nmax / max;
158    if (rmse_type == 0) {
159        for (int i = 0; i < n; ++i) {
160            int l = nearest_int_ggml_sycl(iscale * x[i]);
161            L[i] = (int8_t) (nmax + dpct::max(-nmax, dpct::min(nmax - 1, l)));
162        }
163        return 1.0f / iscale;
164    }
165
166    bool return_early = false;
167    if (rmse_type < 0) {
168        rmse_type = -rmse_type;
169        return_early = true;
170    }
171
172    float sumlx = 0.0f;
173    float suml2 = 0.0f;
174    for (int i = 0; i < n; ++i) {
175        int l = nearest_int_ggml_sycl(iscale * x[i]);
176        l = dpct::max(-nmax, dpct::min(nmax - 1, l));
177        L[i] = (int8_t) (l + nmax);
178
179        const float w = qw ? qw[i] : (rmse_type == 1 ? x[i] * x[i] :
180            rmse_type == 2 ? 1.0f : rmse_type == 3 ? sycl::fabs(x[i]) : sycl::sqrt(sycl::fabs(x[i])));
181
182        sumlx += w * x[i] * l;
183        suml2 += w * l * l;
184    }
185
186    float scale = suml2 ? sumlx / suml2 : 0.0f;
187    if (return_early) {
188        return suml2 > 0.0f ? 0.5f * (scale + 1.0f / iscale) : 1.0f / iscale;
189    }
190
191    float best = scale * sumlx;
192    for (int is = -9; is <= 9; ++is) {
193        if (is == 0) {
194            continue;
195        }
196        iscale = -(nmax + 0.1f * is) / max;
197        sumlx = 0.0f;
198        suml2 = 0.0f;
199        for (int i = 0; i < n; ++i) {
200            int l = nearest_int_ggml_sycl(iscale * x[i]);
201            l = dpct::max(-nmax, dpct::min(nmax - 1, l));
202            const float w = qw ? qw[i] : (rmse_type == 1 ? x[i] * x[i] :
203                rmse_type == 2 ? 1.0f : rmse_type == 3 ? sycl::fabs(x[i]) : sycl::sqrt(sycl::fabs(x[i])));
204            sumlx += w * x[i] * l;
205            suml2 += w * l * l;
206        }
207
208        if (suml2 > 0.0f && sumlx * sumlx > best * suml2) {
209            for (int i = 0; i < n; ++i) {
210                int l = nearest_int_ggml_sycl(iscale * x[i]);
211                L[i] = (int8_t) (nmax + dpct::max(-nmax, dpct::min(nmax - 1, l)));
212            }
213            scale = sumlx / suml2;
214            best = scale * sumlx;
215        }
216    }
217
218    return scale;
219}
220
221inline float make_q3_quants_sycl(int n, int nmax, const float * x, int8_t * L, bool do_rmse) {
222    float max = 0.0f;
223    float amax = 0.0f;
224    for (int i = 0; i < n; ++i) {
225        const float ax = sycl::fabs(x[i]);
226        if (ax > amax) {
227            amax = ax;
228            max = x[i];
229        }
230    }
231
232    if (amax < GROUP_MAX_EPS_SYCL) {
233        for (int i = 0; i < n; ++i) {
234            L[i] = 0;
235        }
236        return 0.0f;
237    }
238
239    const float iscale = -nmax / max;
240    if (do_rmse) {
241        float sumlx = 0.0f;
242        float suml2 = 0.0f;
243        for (int i = 0; i < n; ++i) {
244            int l = nearest_int_ggml_sycl(iscale * x[i]);
245            l = dpct::max(-nmax, dpct::min(nmax - 1, l));
246            L[i] = (int8_t) l;
247            const float w = x[i] * x[i];
248            sumlx += w * x[i] * l;
249            suml2 += w * l * l;
250        }
251
252        for (int itry = 0; itry < 5; ++itry) {
253            int n_changed = 0;
254            for (int i = 0; i < n; ++i) {
255                const float w = x[i] * x[i];
256                float slx = sumlx - w * x[i] * L[i];
257                if (slx > 0.0f) {
258                    float sl2 = suml2 - w * L[i] * L[i];
259                    int new_l = nearest_int_ggml_sycl(x[i] * sl2 / slx);
260                    new_l = dpct::max(-nmax, dpct::min(nmax - 1, new_l));
261                    if (new_l != L[i]) {
262                        slx += w * x[i] * new_l;
263                        sl2 += w * new_l * new_l;
264                        if (sl2 > 0.0f && slx * slx * suml2 > sumlx * sumlx * sl2) {
265                            L[i] = (int8_t) new_l;
266                            sumlx = slx;
267                            suml2 = sl2;
268                            ++n_changed;
269                        }
270                    }
271                }
272            }
273            if (!n_changed) {
274                break;
275            }
276        }
277
278        for (int i = 0; i < n; ++i) {
279            L[i] += nmax;
280        }
281        return suml2 > 0.0f ? sumlx / suml2 : 0.0f;
282    }
283
284    for (int i = 0; i < n; ++i) {
285        int l = nearest_int_ggml_sycl(iscale * x[i]);
286        l = dpct::max(-nmax, dpct::min(nmax - 1, l));
287        L[i] = (int8_t) (l + nmax);
288    }
289
290    return 1.0f / iscale;
291}
292
293inline void set_scale_min_k4(int j, uint8_t * q, uint8_t d, uint8_t m) {
294    if (j < 4) {
295        q[j]     = (q[j] & 0xC0) | (d & 0x3F);
296        q[j + 4] = (q[j + 4] & 0xC0) | (m & 0x3F);
297    } else {
298        q[j + 4] = (d & 0x0F) | ((m & 0x0F) << 4);
299        q[j - 4] = (q[j - 4] & 0x3F) | ((d >> 4) << 6);
300        q[j - 0] = (q[j - 0] & 0x3F) | ((m >> 4) << 6);
301    }
302}
303
304inline void get_scale_min_k4_local(int j, const uint8_t * q, uint8_t & d, uint8_t & m) {
305    if (j < 4) {
306        d = q[j] & 63;
307        m = q[j + 4] & 63;
308    } else {
309        d = (q[j + 4] & 0xF) | ((q[j - 4] >> 6) << 4);
310        m = (q[j + 4] >> 4) | ((q[j - 0] >> 6) << 4);
311    }
312}
313
314inline void cpy_blck_f32_mxfp4(const char * cxi, char * cdsti) {
315    const float *   xi   = (const float *) cxi;
316    block_mxfp4 *   dsti = (block_mxfp4 *) cdsti;
317
318    float amax = 0.0f;
319    for (int j = 0; j < QK_MXFP4; ++j) {
320        amax = sycl::fmax(amax, sycl::fabs((float) xi[j]));
321    }
322
323    const uint8_t e = amax > 0.0f ? (uint8_t) (sycl::floor(sycl::log2(amax)) - 2 + 127) : 0;
324    const float d = GGML_E8M0_TO_FP32_HALF(e);
325
326    dsti->e = e;
327
328    for (int j = 0; j < QK_MXFP4 / 2; ++j) {
329        const uint8_t x0 = best_index_mxfp4(xi[0 + j], d);
330        const uint8_t x1 = best_index_mxfp4(xi[QK_MXFP4 / 2 + j], d);
331
332        dsti->qs[j]  = x0;
333        dsti->qs[j] |= x1 << 4;
334    }
335}
336
337inline void cpy_blck_f32_nvfp4(const char * cxi, char * cdsti) {
338    const float *   xi   = (const float *) cxi;
339    block_nvfp4 *   dsti = (block_nvfp4 *) cdsti;
340
341    constexpr int n_sub = QK_NVFP4 / QK_NVFP4_SUB;
342
343    for (int s = 0; s < n_sub; ++s) {
344        const float * xb = xi + s * QK_NVFP4_SUB;
345
346        float amax = 0.0f;
347        for (int j = 0; j < QK_NVFP4_SUB; ++j) {
348            amax = sycl::fmax(amax, sycl::fabs((float) xb[j]));
349        }
350
351        const uint8_t ue = ggml_fp32_to_ue4m3(amax / 6.0f);
352        dsti->d[s] = ue;
353        const float d = ggml_sycl_ue4m3_to_fp32(ue);
354
355        for (int j = 0; j < QK_NVFP4_SUB / 2; ++j) {
356            const uint8_t x0 = best_index_mxfp4(xb[0 + j], d);
357            const uint8_t x1 = best_index_mxfp4(xb[QK_NVFP4_SUB / 2 + j], d);
358
359            dsti->qs[s * (QK_NVFP4_SUB / 2) + j] = x0 | (x1 << 4);
360        }
361    }
362}
363
364
365inline void cpy_blck_f32_q4_0(const char * cxi, char * cdsti) {
366    const float * xi   = (const float *) cxi;
367    block_q4_0 *  dsti = (block_q4_0 *) cdsti;
368
369    float amax = 0.0f;
370    float vmax = 0.0f;
371
372    for (int j = 0; j < QK4_0; ++j) {
373        const float v = xi[j];
374        if (amax < sycl::fabs((float) v)) {
375            amax = sycl::fabs((float) v);
376            vmax = v;
377        }
378    }
379
380    const float d  = vmax / -8;
381    const float id = d ? 1.0f / d : 0.0f;
382
383    dsti->d = d;
384
385    for (int j = 0; j < QK4_0 / 2; ++j) {
386        const float x0 = xi[0 + j] * id;
387        const float x1 = xi[QK4_0 / 2 + j] * id;
388
389        const uint8_t xi0 = dpct::min(15, (int8_t) (x0 + 8.5f));
390        const uint8_t xi1 = dpct::min(15, (int8_t) (x1 + 8.5f));
391
392        dsti->qs[j] = xi0;
393        dsti->qs[j] |= xi1 << 4;
394    }
395}
396
397inline void cpy_blck_f32_q4_1(const char * cxi, char * cdsti) {
398    const float * xi   = (const float *) cxi;
399    block_q4_1 *  dsti = (block_q4_1 *) cdsti;
400
401    float vmin = FLT_MAX;
402    float vmax = -FLT_MAX;
403
404    for (int j = 0; j < QK4_1; ++j) {
405        const float v = xi[j];
406
407        vmin = sycl::min(v, vmin);
408        vmax = sycl::max(v, vmax);
409    }
410
411    const float d  = (vmax - vmin) / ((1 << 4) - 1);
412    const float id = d ? 1.0f / d : 0.0f;
413
414    dsti->dm.x() = d;
415    dsti->dm.y() = vmin;
416
417    for (int j = 0; j < QK4_1 / 2; ++j) {
418        const float x0 = (xi[0 + j] - vmin) * id;
419        const float x1 = (xi[QK4_1 / 2 + j] - vmin) * id;
420
421        const uint8_t xi0 = dpct::min(15, (int8_t) (x0 + 0.5f));
422        const uint8_t xi1 = dpct::min(15, (int8_t) (x1 + 0.5f));
423
424        dsti->qs[j] = xi0;
425        dsti->qs[j] |= xi1 << 4;
426    }
427}
428
429inline void cpy_blck_f32_q5_0(const char * cxi, char * cdsti) {
430    const float * xi   = (const float *) cxi;
431    block_q5_0 *  dsti = (block_q5_0 *) cdsti;
432
433    float amax = 0.0f;
434    float vmax = 0.0f;
435
436    for (int j = 0; j < QK5_0; ++j) {
437        const float v = xi[j];
438        if (amax < sycl::fabs((float) v)) {
439            amax = sycl::fabs((float) v);
440            vmax = v;
441        }
442    }
443
444    const float d  = vmax / -16;
445    const float id = d ? 1.0f / d : 0.0f;
446
447    dsti->d = d;
448
449    uint32_t qh = 0;
450    for (int j = 0; j < QK5_0 / 2; ++j) {
451        const float x0 = xi[0 + j] * id;
452        const float x1 = xi[QK5_0 / 2 + j] * id;
453
454        const uint8_t xi0 = dpct::min(31, (int8_t) (x0 + 16.5f));
455        const uint8_t xi1 = dpct::min(31, (int8_t) (x1 + 16.5f));
456
457        dsti->qs[j] = (xi0 & 0xf) | ((xi1 & 0xf) << 4);
458        qh |= ((xi0 & 0x10u) >> 4) << (j + 0);
459        qh |= ((xi1 & 0x10u) >> 4) << (j + QK5_0 / 2);
460    }
461    memcpy(dsti->qh, &qh, sizeof(qh));
462}
463
464inline void cpy_blck_f32_q5_1(const char * cxi, char * cdsti) {
465    const float * xi   = (const float *) cxi;
466    block_q5_1 *  dsti = (block_q5_1 *) cdsti;
467
468    float min = xi[0];
469    float max = xi[0];
470
471    for (int j = 1; j < QK5_1; ++j) {
472        const float v = xi[j];
473        min           = v < min ? v : min;
474        max           = v > max ? v : max;
475    }
476
477    const float d  = (max - min) / 31;
478    const float id = d ? 1.0f / d : 0.0f;
479
480    dsti->dm.x() = d;
481    dsti->dm.y() = min;
482
483    uint32_t qh = 0;
484    for (int j = 0; j < QK5_1 / 2; ++j) {
485        const float x0 = (xi[0 + j] - min) * id;
486        const float x1 = (xi[QK5_1 / 2 + j] - min) * id;
487
488        const uint8_t xi0 = (uint8_t) (x0 + 0.5f);
489        const uint8_t xi1 = (uint8_t) (x1 + 0.5f);
490
491        dsti->qs[j] = (xi0 & 0xf) | ((xi1 & 0xf) << 4);
492        qh |= ((xi0 & 0x10u) >> 4) << (j + 0);
493        qh |= ((xi1 & 0x10u) >> 4) << (j + QK5_1 / 2);
494    }
495    memcpy(dsti->qh, &qh, sizeof(qh));
496}
497
498inline void cpy_blck_f32_iq4_nl(const char * cxi, char * cdsti) {
499    const float *  xi   = (const float *) cxi;
500    block_iq4_nl * dsti = (block_iq4_nl *) cdsti;
501
502    float amax = 0.0f;
503    float vmax = 0.0f;
504
505    for (int j = 0; j < QK4_NL; ++j) {
506        const float v = xi[j];
507        if (amax < sycl::fabs((float) v)) {
508            amax = sycl::fabs((float) v);
509            vmax = v;
510        }
511    }
512
513    float       d  = vmax / kvalues_iq4nl[0];
514    const float id = d ? 1.0f / d : 0.0f;
515
516    float sumqx = 0, sumq2 = 0;
517    for (int j = 0; j < QK4_NL / 2; ++j) {
518        const float   x0  = xi[0 + j] * id;
519        const float   x1  = xi[QK4_NL / 2 + j] * id;
520        const uint8_t xi0 = best_index_int8(16, kvalues_iq4nl, x0);
521        const uint8_t xi1 = best_index_int8(16, kvalues_iq4nl, x1);
522        dsti->qs[j]       = xi0 | (xi1 << 4);
523        const float v0    = kvalues_iq4nl[xi0];
524        const float v1    = kvalues_iq4nl[xi1];
525        const float w0    = xi[0 + j] * xi[0 + j];
526        const float w1    = xi[QK4_NL / 2 + j] * xi[QK4_NL / 2 + j];
527        sumqx += w0 * v0 * xi[j] + w1 * v1 * xi[QK4_NL / 2 + j];
528        sumq2 += w0 * v0 * v0 + w1 * v1 * v1;
529    }
530
531    dsti->d = sumq2 > 0 ? sumqx / sumq2 : d;
532}
533
534void ggml_sycl_cpy(ggml_backend_sycl_context & ctx, const ggml_tensor * src0, const ggml_tensor * src1);
535void ggml_sycl_dup(ggml_backend_sycl_context & ctx, ggml_tensor * dst);
536
537#endif  // GGML_SYCL_CPY_HPP