char-fork/llama.cpp

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

Masashi Yoshimuraggml-webgpu: add support for NVFP4 (#25143)6c5de1cc8

char/aliceai-t5-moe
28.0 KiB794 linesraw
1enable f16;
2#define DECLARE_BYTE_LOADERS_SRC
3#include "common_decls.tmpl"
4
5
6#ifdef F32_VEC
7fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
8    dst[(dst_base / 4) + offset] = src[(src_base / 4) + offset];
9}
10#endif
11
12#ifdef F32
13fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
14    dst[dst_base + offset] = src[src_base + offset];
15}
16#endif
17
18#ifdef F16
19fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
20    dst[dst_base + offset] = f32(src[src_base + offset]);
21}
22#endif
23
24#ifdef I32
25fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
26    dst[dst_base + offset] = src[src_base + offset];
27}
28#endif
29
30#ifdef Q1_0
31fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
32    let block_byte_base = (src_base + offset) * 18;
33    let d = load_f16_as_f32_at_src(block_byte_base);
34    for (var j: u32 = 0u; j < 4u; j++) {
35        let q_packed = load_u32_at_src(block_byte_base + 2u + j * 4u);
36        let dst_base128 = dst_base + offset * 128u + j * 32u;
37        for (var k: u32 = 0; k < 4u; k++) {
38            let q_byte = get_byte(q_packed, k);
39            for (var bit: u32 = 0; bit < 8u; bit++) {
40                let w = select(-d, d, ((q_byte >> bit) & 1u) != 0u);
41                dst[dst_base128 + k * 8u + bit] = w;
42            }
43        }
44    }
45}
46#endif
47
48#ifdef Q4_0
49fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
50    let block_byte_base = (src_base + offset) * 18; // Block stride: 18 bytes
51    let d = load_f16_as_f32_at_src(block_byte_base);
52    for (var j: u32 = 0u; j < 4; j++) {
53        let q_byte_offset = block_byte_base + 2 + j * 4;
54        let q_packed = load_u32_at_src(q_byte_offset);
55        for (var k: u32 = 0; k < 4; k++) {
56            let q_byte = get_byte(q_packed, k);
57            let q_hi = (f32((q_byte >> 4) & 0xF) - 8.0) * d;
58            let q_lo = (f32(q_byte & 0xFu) - 8.0) * d;
59            let dst_offset = dst_base + offset * 32 + j * 4 + k;
60            dst[dst_offset] = q_lo;
61            dst[dst_offset + 16u] = q_hi;
62        }
63    }
64}
65#endif
66
67#ifdef Q4_1
68fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
69    let block_q4_1 = src[src_base + offset];
70    let d = f32(block_q4_1.d);
71    let m = f32(block_q4_1.m);
72    for (var j: u32 = 0; j < 4; j++) {
73        let q_packed = block_q4_1.qs[j];
74        for (var k: u32 = 0; k < 4; k++) {
75            let q_byte = get_byte(q_packed, k);
76            let q_hi = f32((q_byte >> 4) & 0xF) * d + m;
77            let q_lo = f32(q_byte & 0xF) * d + m;
78            let dst_offset = dst_base + offset * 32 + j * 4 + k;
79            dst[dst_offset] = q_lo;
80            dst[dst_offset + 16] = q_hi;
81        }
82    }
83}
84#endif
85
86#ifdef Q5_0
87fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
88    let block_byte_base = (src_base + offset) * 22; // Block stride: 22 bytes
89    let d = load_f16_as_f32_at_src(block_byte_base);
90    let qh_packed = load_u32_at_src(block_byte_base + 2);
91    for (var j: u32 = 0; j < 4; j++) {
92        let q_byte_offset = block_byte_base + 6 + j * 4;
93        let q_packed = load_u32_at_src(q_byte_offset);
94
95        for (var k: u32 = 0; k < 4; k++) {
96            let q_byte = get_byte(q_packed, k);
97
98            let qh_hi = (qh_packed >> (j * 4 + k + 12)) & 0x10;
99            let q_hi = (f32(((q_byte >> 4) & 0xF) | qh_hi) - 16.0) * d;
100
101            let qh_lo = ((qh_packed >> (j * 4 + k)) << 4) & 0x10;
102            let q_lo = (f32((q_byte & 0xF) | qh_lo) - 16.0) * d;
103
104            let dst_offset = dst_base + offset * 32 + j * 4 + k;
105            dst[dst_offset] = q_lo;
106            dst[dst_offset + 16] = q_hi;
107        }
108    }
109}
110#endif
111
112#ifdef Q5_1
113fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
114    let block_q5_1 = src[src_base + offset];
115    let d = f32(block_q5_1.d);
116    let m = f32(block_q5_1.m);
117    for (var j: u32 = 0; j < 4; j++) {
118        let q_packed = block_q5_1.qs[j];
119        for (var k: u32 = 0; k < 4; k++) {
120            let q_byte = get_byte(q_packed, k);
121            let qh_hi = (block_q5_1.qh >> (j * 4 + k + 12)) & 0x10;
122            let q_hi = f32(((q_byte >> 4) & 0xF) | qh_hi) * d + m;
123            let qh_lo = ((block_q5_1.qh >> (j * 4 + k)) << 4) & 0x10;
124            let q_lo = f32((q_byte & 0xF) | qh_lo) * d + m;
125            let dst_offset = dst_base + offset * 32 + j * 4 + k;
126            dst[dst_offset] = q_lo;
127            dst[dst_offset + 16] = q_hi;
128        }
129    }
130}
131#endif
132
133#ifdef Q8_0
134fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
135    let block_byte_base = (src_base + offset) * 34; // Block stride: 34 bytes
136    let d = load_f16_as_f32_at_src(block_byte_base);
137    for (var j: u32 = 0u; j < 8u; j++) {
138        let q_byte_offset = block_byte_base + 2u + j * 4u;
139        let q_packed = load_u32_at_src(q_byte_offset);
140        for (var k: u32 = 0u; k < 4u; k++) {
141            let q_byte = get_byte_i32(q_packed, k);
142            let q_val = f32(q_byte) * d;
143            let dst_offset = dst_base + offset * 32u + j * 4u + k;
144            dst[dst_offset] = q_val;
145        }
146    }
147}
148#endif
149
150#ifdef Q2_K
151fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
152    let block = src[src_base + offset];
153    let d = f32(block.d);
154    let m = f32(block.dmin);
155    var dst_i = dst_base + offset * 256;
156    var is: u32 = 0;
157    // 2 halves of the block (128 elements each)
158    for (var q_b_idx: u32 = 0; q_b_idx < 64; q_b_idx += 32) {
159        // 4 groups (each group has 2 blocks of 16 elements)
160        for (var shift: u32 = 0; shift < 8; shift += 2) {
161            // 2 blocks
162            for (var k: u32 = 0; k < 32; k += 16) {
163                let sc = get_byte(block.scales[is / 4], is % 4);
164                is++;
165                let dl = d * f32(sc & 0xF);
166                let ml = m * f32(sc >> 4);
167                for (var l: u32 = 0u; l < 16; l++) {
168                    let q_idx = q_b_idx + k + l;
169                    let q_byte = get_byte(block.qs[q_idx / 4], q_idx % 4);
170                    let qs_val = (q_byte >> shift) & 3;
171                    dst[dst_i] = (f32(qs_val) * dl - ml);
172                    dst_i++;
173                }
174            }
175        }
176    }
177}
178#endif
179
180#ifdef Q3_K
181fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
182    let block_byte_base = (src_base + offset) * 110; // Block stride: 110 bytes
183
184    // Bytes 108-109: f16 scale 'd'
185    let d = load_f16_as_f32_at_src(block_byte_base + 108);
186
187    // Bytes 96-107: 12 bytes of scales (3 u32s)
188    let kmask1: u32 = 0x03030303;
189    let kmask2: u32 = 0x0f0f0f0f;
190
191    var scale_vals: array<u32, 4>;
192    scale_vals[0] = load_u32_at_src(block_byte_base + 96);
193    scale_vals[1] = load_u32_at_src(block_byte_base + 100);
194    scale_vals[2] = load_u32_at_src(block_byte_base + 104);
195
196    var tmp: u32 = scale_vals[2];
197    scale_vals[2] = ((scale_vals[0] >> 4) & kmask2) | (((tmp >> 4) & kmask1) << 4);
198    scale_vals[3] = ((scale_vals[1] >> 4) & kmask2) | (((tmp >> 6) & kmask1) << 4);
199    scale_vals[0] = (scale_vals[0] & kmask2) | ((tmp & kmask1) << 4);
200    scale_vals[1] = (scale_vals[1] & kmask2) | (((tmp >> 2) & kmask1) << 4);
201
202    // Bytes 0-31: 32 bytes of hmask (8 u32s)
203    var hmask_vals: array<u32, 8>;
204    for (var i: u32 = 0; i < 8; i++) {
205        hmask_vals[i] = load_u32_at_src(block_byte_base + i * 4);
206    }
207
208    // Bytes 32-95: 64 bytes of qs (16 u32s)
209    var qs_vals: array<u32, 16>;
210    for (var i: u32 = 0u; i < 16; i++) {
211        qs_vals[i] = load_u32_at_src(block_byte_base + 32 + i * 4);
212    }
213
214    var dst_i = dst_base + offset * 256;
215    var is: u32 = 0;
216    var m: u32 = 1;
217
218    // 2 halves of the block (128 elements each)
219    for (var q_b_idx: u32 = 0; q_b_idx < 64; q_b_idx += 32) {
220        // 4 groups (each group has 2 blocks of 16 elements)
221        for (var shift: u32 = 0; shift < 8; shift += 2) {
222            // 2 blocks
223            for (var k: u32 = 0; k < 32; k += 16) {
224                let sc = get_byte(scale_vals[is / 4], is % 4);
225                is++;
226                let dl = d * (f32(sc) - 32.0);
227
228                for (var l: u32 = 0; l < 16; l++) {
229                    let q_idx = q_b_idx + k + l;
230                    let hm_idx = k + l;
231                    let q_byte = get_byte(qs_vals[q_idx / 4], q_idx % 4);
232                    let hmask_byte = get_byte(hmask_vals[hm_idx / 4], hm_idx % 4);
233
234                    let hm = select(4.0, 0.0, (hmask_byte & m) != 0);
235                    let qs_val = (q_byte >> shift) & 3;
236                    dst[dst_i] = (f32(qs_val) - hm) * dl;
237                    dst_i++;
238                }
239            }
240            m <<= 1;
241        }
242    }
243}
244#endif
245
246#ifdef Q4_K
247// 8 blocks of 32 elements each
248fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
249    let block = src[src_base + offset];
250    let d = f32(block.d);
251    let m = f32(block.dmin);
252    var dst_i = dst_base + offset * 256;
253    var is: u32 = 0;
254    // 2 blocks each iteration
255    for (var q_b_idx: u32 = 0; q_b_idx < 128; q_b_idx += 32) {
256        for (var shift: u32 = 0; shift < 8; shift += 4) {
257            let scale_min = get_scale_min(is, block.scales);
258            is++;
259            let dl = d * scale_min.x;
260            let ml = m * scale_min.y;
261            for (var l: u32 = 0; l < 32; l++) {
262                let q_idx = q_b_idx + l;
263                let q_byte = get_byte(block.qs[q_idx / 4], q_idx % 4);
264                let qs_val = (q_byte >> shift) & 0xF;
265                dst[dst_i] = (f32(qs_val) * dl - ml);
266                dst_i++;
267            }
268        }
269    }
270}
271#endif
272
273#ifdef Q5_K
274fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
275    let block = src[src_base + offset];
276    let d = f32(block.d);
277    let m = f32(block.dmin);
278    var dst_i = dst_base + offset * 256;
279    var is: u32 = 0;
280    var u: u32 = 1;
281    // 2 blocks each iteration
282    for (var q_b_idx: u32 = 0; q_b_idx < 128; q_b_idx += 32) {
283        for (var shift: u32 = 0; shift < 8; shift += 4) {
284            let scale_min = get_scale_min(is, block.scales);
285            is++;
286            let dl = d * scale_min.x;
287            let ml = m * scale_min.y;
288            for (var l: u32 = 0; l < 32; l++) {
289                let q_idx = q_b_idx + l;
290                let q_byte = get_byte(block.qs[q_idx / 4], q_idx % 4);
291                let qh_byte = get_byte(block.qh[l / 4], l % 4);
292                let qs_val = (q_byte >> shift) & 0xF;
293                let qh_val = select(0.0, 16.0, (qh_byte & u) != 0);
294                dst[dst_i] = (f32(qs_val) + qh_val) * dl - ml;
295                dst_i++;
296            }
297            u <<= 1;
298        }
299    }
300}
301#endif
302
303#ifdef Q6_K
304// 16 blocks of 16 elements each
305fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
306    let block_byte_base = (src_base + offset) * 210; // Block stride: 210 bytes
307
308    // Bytes 208-209: f16 scale 'd'
309    let d = load_f16_as_f32_at_src(block_byte_base + 208);
310
311    // Bytes 0-127: 128 bytes of ql (32 u32s)
312    var ql_vals: array<u32, 32>;
313    for (var i: u32 = 0; i < 32; i++) {
314        ql_vals[i] = load_u32_at_src(block_byte_base + i * 4);
315    }
316
317    // Bytes 128-191: 64 bytes of qh (16 u32s)
318    var qh_vals: array<u32, 16>;
319    for (var i: u32 = 0; i < 16u; i++) {
320        qh_vals[i] = load_u32_at_src(block_byte_base + 128 + i * 4u);
321    }
322
323    // Bytes 192-207: 16 bytes of scales (4 u32s)
324    var scale_vals: array<u32, 4>;
325    for (var i: u32 = 0; i < 4; i++) {
326        scale_vals[i] = load_u32_at_src(block_byte_base + 192 + i * 4);
327    }
328
329    var dst_i = dst_base + offset * 256;
330    var qh_b_idx: u32 = 0;
331    var sc_b_idx: u32 = 0;
332    for (var ql_b_idx: u32 = 0; ql_b_idx < 128; ql_b_idx += 64) {
333        for (var l: u32 = 0; l < 32; l++) {
334            let ql13_b = get_byte(ql_vals[(ql_b_idx + l) / 4], (ql_b_idx + l) % 4);
335            let ql24_b = get_byte(ql_vals[(ql_b_idx + l + 32) / 4], (ql_b_idx + l + 32) % 4);
336            let qh_b = get_byte(qh_vals[(qh_b_idx + l) / 4], (qh_b_idx + l) % 4);
337
338            let q1 = f32((ql13_b & 0xF) | ((qh_b & 3) << 4)) - 32.0;
339            let q2 = f32((ql24_b & 0xF) | (((qh_b >> 2) & 3) << 4)) - 32.0;
340            let q3 = f32((ql13_b >> 4) | (((qh_b >> 4) & 3) << 4)) - 32.0;
341            let q4 = f32((ql24_b >> 4) | (((qh_b >> 6) & 3) << 4)) - 32.0;
342
343            let is = l/16;
344            let is1 = sc_b_idx + is;
345            let sc1 = get_byte_i32(scale_vals[is1 / 4], is1 % 4);
346            let is2 = sc_b_idx + is + 2;
347            let sc2 = get_byte_i32(scale_vals[is2 / 4], is2 % 4);
348            let is3 = sc_b_idx + is + 4;
349            let sc3 = get_byte_i32(scale_vals[is3 / 4], is3 % 4);
350            let is4 = sc_b_idx + is + 6;
351            let sc4 = get_byte_i32(scale_vals[is4 / 4], is4 % 4);
352
353            dst[dst_i + l] = (q1 * f32(sc1)) * d;
354            dst[dst_i + l + 32] = (q2 * f32(sc2)) * d;
355            dst[dst_i + l + 64] = (q3 * f32(sc3)) * d;
356            dst[dst_i + l + 96] = (q4 * f32(sc4)) * d;
357        }
358        dst_i += 128;
359        qh_b_idx += 32;
360        sc_b_idx += 8;
361    }
362}
363#endif
364
365#ifdef IQ2_XXS
366fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
367    let block_byte_base = (src_base + offset) * 66; // Block stride: 66 bytes
368    let d = load_f16_as_f32_at_src(block_byte_base);
369    var dst_i = dst_base + offset * 256;
370    for (var ib: u32 = 0; ib < 32; ib += 4) {
371        let aux0_offset = block_byte_base + 2 + ib * 2;
372        let aux1_offset = block_byte_base + 2 + (ib + 2) * 2;
373        let aux0 = load_u32_at_src(aux0_offset);
374        let aux1 = load_u32_at_src(aux1_offset);
375        let db = d * (0.5 + f32(aux1 >> 28)) * 0.25;
376        for (var l: u32 = 0; l < 4; l++) {
377            let ig = get_byte(aux0, l) * 8;
378            let is = (aux1 >> (7 * l)) & 127;
379            let signs = get_byte(ksigns_iq2xs[is / 4], is % 4);
380            for (var j: u32 = 0; j < 8; j++) {
381                let g = get_byte(iq2xxs_grid[(ig + j) / 4], (ig + j) % 4);
382                let m = select(1.0, -1.0, (get_byte(kmask_iq2xs[j / 4], j % 4) & signs) != 0);
383                dst[dst_i] = db * f32(g) * m;
384                dst_i++;
385            }
386        }
387    }
388}
389#endif
390
391
392
393#ifdef IQ2_XS
394fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
395    let block_byte_base = (src_base + offset) * 74; // Block stride: 74 bytes
396    let d = load_f16_as_f32_at_src(block_byte_base);
397    var dst_i = dst_base + offset * 256;
398
399    var scale_vals = array<u32, 2>(
400        load_u32_at_src(block_byte_base + 66),
401        load_u32_at_src(block_byte_base + 70)
402    );
403
404    for (var ib: u32 = 0; ib < 32; ib += 4) {
405        let s = get_byte(scale_vals[ib / 16], (ib % 16) / 4);
406        let db = array<f32, 2>(
407            d * (0.5 + f32(s & 0xF)) * 0.25,
408            d * (0.5 + f32(s >> 4)) * 0.25
409        );
410        for (var l: u32 = 0; l < 4; l++) {
411            let qs_offset = block_byte_base + 2 + (ib + l) * 2;
412            let qs_val = load_u32_at_src(qs_offset) & 0xFFFF;
413            let ig = (qs_val & 511) * 8;
414            let is = qs_val >> 9;
415            let signs = get_byte(ksigns_iq2xs[is / 4], is % 4);
416            let dl = db[l/2];
417            for (var j: u32 = 0; j < 8; j++) {
418                let g = get_byte(iq2xs_grid[(ig + j) / 4], (ig + j) % 4);
419                let m = select(1.0, -1.0, (get_byte(kmask_iq2xs[j / 4], j % 4) & signs) != 0);
420                dst[dst_i] = dl * f32(g) * m;
421                dst_i++;
422            }
423        }
424    }
425}
426#endif
427
428#ifdef IQ2_S
429fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
430    let block_byte_base = (src_base + offset) * 82; // Block stride: 82 bytes
431    let d = load_f16_as_f32_at_src(block_byte_base);
432    var dst_i = dst_base + offset * 256;
433
434    var qs_vals : array<u32, 16>;
435    for (var i: u32 = 0; i < 16; i++) {
436        qs_vals[i] = load_u32_at_src(block_byte_base + 2 + i * 4);
437    }
438
439    var qh_vals: array<u32, 2>;
440    qh_vals[0] = load_u32_at_src(block_byte_base + 66);
441    qh_vals[1] = load_u32_at_src(block_byte_base + 70);
442
443    var scale_vals: array<u32, 2>;
444    scale_vals[0] = load_u32_at_src(block_byte_base + 74);
445    scale_vals[1] = load_u32_at_src(block_byte_base + 78);
446
447    for (var ib: u32 = 0; ib < 8; ib ++) {
448        let s = get_byte(scale_vals[ib / 4], ib % 4);
449        let db = array<f32, 2>(
450            d * (0.5 + f32(s & 0xF)) * 0.25,
451            d * (0.5 + f32(s >> 4)) * 0.25
452        );
453        let qs_w = qs_vals[ib];
454        for (var l: u32 = 0; l < 4; l++) {
455            let qh_b = (get_byte(qh_vals[ib / 4], ib % 4) << (8 - 2 * l)) & 0x300;
456            let ig = (get_byte(qs_w, l) | qh_b) * 8;
457            let signs = get_byte(qs_vals[ib + 8], l);
458            let dl = db[l/2];
459            for (var j: u32 = 0; j < 8; j++) {
460                let g = get_byte(iq2s_grid[(ig + j) / 4], (ig + j) % 4);
461                let m = select(1.0, -1.0, (get_byte(kmask_iq2xs[j / 4], j % 4) & signs) != 0);
462                dst[dst_i] = dl * f32(g) * m;
463                dst_i++;
464            }
465        }
466    }
467}
468#endif
469
470#ifdef IQ3_XXS
471fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
472    let block_byte_base = (src_base + offset) * 98; // Block stride: 98 bytes
473    let d = load_f16_as_f32_at_src(block_byte_base);
474    var dst_i = dst_base + offset * 256;
475    for (var ib: u32 = 0; ib < 16; ib += 2) {
476        let sc_sign_offset = block_byte_base + 2 + (ib + 32) * 2;
477        let sc_sign = load_u32_at_src(sc_sign_offset);
478        let db = d * (0.5 + f32(sc_sign >> 28)) * 0.5;
479        for (var l: u32 = 0; l < 4; l++) {
480            let is = (sc_sign >> (7 * l)) & 127;
481            let signs = get_byte(ksigns_iq2xs[is / 4], is % 4);
482            let ig_val = load_u32_at_src(block_byte_base + 2 + (ib * 2 + l) * 2) & 0xFFFF;
483            let ig1 = get_byte(ig_val, 0);
484            let ig2 = get_byte(ig_val, 1);
485            for (var j: u32 = 0; j < 4; j++) {
486                let g1 = get_byte(iq3xxs_grid[ig1], j);
487                let g2 = get_byte(iq3xxs_grid[ig2], j);
488                let m1 = select(1.0, -1.0, (get_byte(kmask_iq2xs[0], j) & signs) != 0);
489                let m2 = select(1.0, -1.0, (get_byte(kmask_iq2xs[1], j) & signs) != 0);
490                dst[dst_i] = db * f32(g1) * m1;
491                dst[dst_i + 4] = db * f32(g2) * m2;
492                dst_i++;
493            }
494            dst_i += 4;
495        }
496    }
497}
498#endif
499
500#ifdef IQ3_S
501fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
502    let block_byte_base = (src_base + offset) * 110; // Block stride: 110 bytes
503    let d = load_f16_as_f32_at_src(block_byte_base);
504    var dst_i = dst_base + offset * 256;
505
506    var qh_vals = array<u32, 2>(
507        load_u32_at_src(block_byte_base + 66),
508        load_u32_at_src(block_byte_base + 70)
509    );
510
511    var sign_vals: array<u32, 8>;
512    for (var i: u32 = 0; i < 8; i++) {
513        sign_vals[i] = load_u32_at_src(block_byte_base + 74 + i * 4);
514    }
515
516    var scale_vals = load_u32_at_src(block_byte_base + 106);
517
518    for (var ib: u32 = 0; ib < 4; ib++) {
519        let s = get_byte(scale_vals, ib);
520        let db = array<f32, 2>(
521            d * (1.0 + 2.0 * f32(s & 0xF)),
522            d * (1.0 + 2.0 * f32(s >> 4))
523        );
524        for (var k: u32 = 0; k < 2; k++) {
525            let dl = db[k];
526            let qh_byte = get_byte(qh_vals[ib / 2], (ib % 2) * 2 + k);
527            let sign_w = sign_vals[ib * 2 + k];
528            for (var l: u32 = 0; l < 4; l++) {
529                let signs = get_byte(sign_w, l);
530                let ig_val = load_u32_at_src(block_byte_base + 2 + (ib * 8 + k * 4 + l) * 2) & 0xFFFF;
531                let ig1 = get_byte(ig_val, 0) | ((qh_byte << ((8 - (2 * l)))) & 256);
532                let ig2 = get_byte(ig_val, 1) | ((qh_byte << ((7 - (2 * l)))) & 256);
533                for (var j: u32 = 0; j < 4; j++) {
534                    let g1 = get_byte(iq3s_grid[ig1], j);
535                    let g2 = get_byte(iq3s_grid[ig2], j);
536                    let m1 = select(1.0, -1.0, (get_byte(kmask_iq2xs[0], j) & signs) != 0);
537                    let m2 = select(1.0, -1.0, (get_byte(kmask_iq2xs[1], j) & signs) != 0);
538                    dst[dst_i] = dl * f32(g1) * m1;
539                    dst[dst_i + 4] = dl * f32(g2) * m2;
540                    dst_i++;
541                }
542                dst_i += 4;
543            }
544        }
545    }
546}
547#endif
548
549#ifdef IQ1_S
550fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
551    let block_byte_base = (src_base + offset) * 50; // Block stride: 50 bytes
552    let d = load_f16_as_f32_at_src(block_byte_base);
553    var dst_i = dst_base + offset * 256;
554    for (var ib: u32 = 0; ib < 8; ib++) {
555        let qh = load_u32_at_src(block_byte_base + 34 + ib * 2) & 0xFFFF;
556        let dl = d * (2.0 * f32((qh >> 12) & 7) + 1.0);
557        let delta = select(IQ1_DELTA, -IQ1_DELTA, (qh & 0x8000) != 0);
558        let qs_w = load_u32_at_src(block_byte_base + 2 + ib * 4);
559        for (var l: u32 = 0; l < 4; l++) {
560            let ig = (get_byte(qs_w, l) | (((qh >> (3 * l)) & 7) << 8)) * 8;
561            for (var j: u32 = 0; j < 8; j++) {
562                let gw = iq1_grid[(ig + j) / 16];
563                let g = (gw >> (((ig + j) % 16) * 2)) & 3;
564                let gs = bitcast<i32>(g << 30) >> 30;
565                dst[dst_i] = dl * (f32(gs) + delta);
566                dst_i++;
567            }
568        }
569    }
570}
571#endif
572
573#ifdef IQ1_M
574fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
575    let block = src[src_base + offset];
576
577    let scale = ((block.scales[0] >> 12) & 0xF) | ((block.scales[0] >> 24) & 0x00F0) | ((block.scales[1] >> 4) & 0x0F00) | ((block.scales[1] >> 16) & 0xF000);
578    let d = f32(bitcast<vec2<f16>>(scale).x);
579    var dst_i = dst_base + offset * 256;
580    for (var ib: u32 = 0; ib < 8; ib++) {
581        let sw = (block.scales[ib / 4] >> (16 * ((ib / 2) % 2))) & 0xFFFF;
582        let s1 : u32 = (sw >> (6 * (ib % 2))) & 0x7;
583        let s2 : u32 = (sw >> (6 * (ib % 2) + 3)) & 0x7;
584        var dl = array<f32, 2>(
585            d * f32(2 * s1 + 1),
586            d * f32(2 * s2 + 1)
587        );
588
589        let qh = block.qh[ib / 2] >> (16 * (ib % 2));
590        var idx = array<u32, 4>(
591            get_byte(block.qs[ib], 0) | ((qh << 8) & 0x700),
592            get_byte(block.qs[ib], 1) | ((qh << 4) & 0x700),
593            get_byte(block.qs[ib], 2) | ((qh) & 0x700),
594            get_byte(block.qs[ib], 3) | ((qh >> 4) & 0x700)
595        );
596        var delta = array<f32, 4>(
597            select(IQ1_DELTA, -IQ1_DELTA, (qh & 0x08) != 0),
598            select(IQ1_DELTA, -IQ1_DELTA, (qh & 0x80) != 0),
599            select(IQ1_DELTA, -IQ1_DELTA, ((qh >> 8) & 0x08) != 0),
600            select(IQ1_DELTA, -IQ1_DELTA, ((qh >> 8) & 0x80) != 0)
601        );
602        for (var l: u32 = 0; l < 4; l++) {
603            let ig = idx[l] * 8;
604            for (var j: u32 = 0; j < 8; j++) {
605                let gw = iq1_grid[(ig + j) / 16];
606                let g = (gw >> (((ig + j) % 16) * 2)) & 3;
607                let gs = bitcast<i32>(g << 30) >> 30;
608                dst[dst_i] = dl[l/2] * (f32(gs) + delta[l]);
609                dst_i++;
610            }
611        }
612    }
613}
614#endif
615
616#ifdef IQ4_NL
617fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
618    let block_byte_base = (src_base + offset) * 18; // Block stride: 18 bytes
619    let d = load_f16_as_f32_at_src(block_byte_base);
620    var dst_i = dst_base + offset * 32;
621    var qs: array<u32, 4>;
622    for (var i: u32 = 0; i < 4; i++) {
623        qs[i] = load_u32_at_src(block_byte_base + 2 + i * 4);
624    }
625    for (var j: u32 = 0; j < 16; j++) {
626        let qsb = get_byte(qs[j / 4], j % 4);
627        dst[dst_i] = d * f32(kvalues_iq4nl[qsb & 0xF]);
628        dst[dst_i + 16] = d * f32(kvalues_iq4nl[qsb >> 4]);
629        dst_i++;
630    }
631}
632#endif
633
634#ifdef IQ4_XS
635fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
636    let block = src[src_base + offset];
637    let d = unpack2x16float(block.d_scales_h)[0];
638    let scales_h = block.d_scales_h >> 16;
639    var dst_i = dst_base + offset * 256;
640    for (var ib: u32 = 0; ib < 8; ib++) {
641        let ls = ((get_byte(block.scales_l, ib / 2) >> (4 * (ib % 2))) & 0xF) | (((scales_h >> (2 * ib)) & 3) << 4);
642        let dl = d * (f32(ls) - 32.0);
643        for (var j: u32 = 0; j < 16; j++) {
644            let iqs = ib * 16 + j;
645            let qsb = get_byte(block.qs[iqs / 4], iqs % 4);
646            dst[dst_i] = dl * f32(kvalues_iq4nl[qsb & 0xF]);
647            dst[dst_i + 16] = dl * f32(kvalues_iq4nl[qsb >> 4]);
648            dst_i++;
649        }
650        dst_i += 16;
651    }
652}
653#endif
654
655#ifdef MXFP4
656fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
657    let block_byte_base = (src_base + offset) * 17;
658    let eu8 = get_byte(load_u32_at_src(block_byte_base), 0);
659    let d = ldexp(1.0, i32(eu8) - 128);
660    for (var j: u32 = 0u; j < 4; j++) {
661        let q_byte_offset = block_byte_base + 1 + j * 4;
662        let q_packed = load_u32_at_src(q_byte_offset);
663        for (var k: u32 = 0; k < 4; k++) {
664            let q_byte = get_byte(q_packed, k);
665            let q_hi = f32(kvalues_mxfp4[(q_byte >> 4) & 0xF]) * d;
666            let q_lo = f32(kvalues_mxfp4[q_byte & 0xFu]) * d;
667            let dst_offset = dst_base + offset * 32 + j * 4 + k;
668            dst[dst_offset] = q_lo;
669            dst[dst_offset + 16u] = q_hi;
670        }
671    }
672}
673#endif
674
675#ifdef NVFP4
676fn copy_elements(src_base: u32, dst_base: u32, offset: u32) {
677    let block_byte_base = (src_base + offset) * 36;
678    let d_word = load_u32_at_src(block_byte_base);
679    for (var sub: u32 = 0u; sub < 4; sub++) {
680        let d = ue4m3_to_fp32(get_byte(d_word, sub)) * 0.5;
681        for (var j: u32 = 0u; j < 2; j++) {
682            let q_packed = load_u32_at_src(block_byte_base + 4 + sub * 8 + j * 4);
683            for (var k: u32 = 0; k < 4; k++) {
684                let q_byte = get_byte(q_packed, k);
685                let q_lo = f32(kvalues_mxfp4[q_byte & 0xFu]) * d;
686                let q_hi = f32(kvalues_mxfp4[(q_byte >> 4) & 0xF]) * d;
687                let dst_offset = dst_base + offset * 64 + sub * 16 + j * 4 + k;
688                dst[dst_offset] = q_lo;
689                dst[dst_offset + 8u] = q_hi;
690            }
691        }
692    }
693}
694#endif
695
696
697@group(0) @binding(0)
698var<storage, read_write> src: array<SRC_TYPE>;
699
700@group(0) @binding(1)
701var<storage, read_write> idx: array<i32>;
702
703@group(0) @binding(2)
704var<storage, read_write> dst: array<DST_TYPE>;
705
706struct Params {
707    offset_src: u32, // in elements
708    offset_idx: u32, // in elements
709    offset_dst: u32, // in elements
710
711    // Strides (in elements)
712    stride_src1: u32,
713    stride_src2: u32,
714    stride_src3: u32,
715
716    stride_idx0: u32,
717    stride_idx1: u32,
718    stride_idx2: u32,
719
720    stride_dst1: u32,
721    stride_dst2: u32,
722    stride_dst3: u32,
723
724    // Shape of dst
725    ne0: u32,
726    n_rows: u32,
727    ne2: u32,
728    ne3: u32,
729
730    // Shape of idx
731    idx1: u32,
732    idx2: u32,
733};
734
735@group(0) @binding(3)
736var<uniform> params: Params;
737
738@compute @workgroup_size(WG_SIZE)
739fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
740#ifdef FLOAT_PARALLEL
741    let blocks_per_row = params.ne0 / BLOCK_SIZE;
742    let row_count = params.n_rows * params.ne2 * params.ne3;
743
744    if (gid.x >= blocks_per_row * row_count) {
745        return;
746    }
747
748    let block_idx = gid.x % blocks_per_row;
749    var row_idx = gid.x / blocks_per_row;
750    let i_dst3 = row_idx / (params.ne2 * params.n_rows);
751
752    row_idx = row_idx % (params.ne2 * params.n_rows);
753    let i_dst2 = row_idx / params.n_rows;
754    let i_dst1 = row_idx % params.n_rows;
755
756    let i_idx2 = i_dst3 % params.idx2;
757    let i_idx1 = i_dst2 % params.idx1;
758    let i_idx0 = i_dst1;
759
760    let i_idx = params.offset_idx + i_idx0 * params.stride_idx0 + i_idx1 * params.stride_idx1 + i_idx2 * params.stride_idx2;
761
762    let idx_val = u32(idx[i_idx]);
763
764    let i_src_row = params.offset_src + idx_val * params.stride_src1 + i_dst2 * params.stride_src2 + i_dst3 * params.stride_src3;
765    let i_dst_row = params.offset_dst + i_dst1 * params.stride_dst1 + i_dst2 * params.stride_dst2 + i_dst3 * params.stride_dst3;
766
767    copy_elements(i_src_row, i_dst_row, block_idx);
768#else
769    if (gid.x >= params.n_rows * params.ne2 * params.ne3) {
770        return;
771    }
772    var i = gid.x;
773    let i_dst3 = i / (params.ne2 * params.n_rows);
774
775    i = i % (params.ne2 * params.n_rows);
776    let i_dst2 = i / params.n_rows;
777    let i_dst1 = i % params.n_rows;
778
779    let i_idx2 = i_dst3 % params.idx2;
780    let i_idx1 = i_dst2 % params.idx1;
781    let i_idx0 = i_dst1;
782
783    let i_idx = params.offset_idx + i_idx0 * params.stride_idx0 + i_idx1 * params.stride_idx1 + i_idx2 * params.stride_idx2;
784
785    let idx_val = u32(idx[i_idx]);
786
787    let i_src_row = params.offset_src + idx_val * params.stride_src1 + i_dst2 * params.stride_src2 + i_dst3 * params.stride_src3;
788    let i_dst_row = params.offset_dst + i_dst1 * params.stride_dst1 + i_dst2 * params.stride_dst2 + i_dst3 * params.stride_dst3;
789
790    for (var i: u32 = 0; i < params.ne0/BLOCK_SIZE; i++) {
791      copy_elements(i_src_row, i_dst_row, i);
792    }
793#endif
794}