char-fork/llama.cpp

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

Aman Guptaggml: add SWIGLU_CLAMP (#27930)0190529ec

char/aliceai-t5-moe
407.4 KiB12164 linesraw
1#include "ops.h"
2
3#include "ggml-cpu.h"
4#include "ggml-impl.h"
5#include "binary-ops.h"
6#include "simd-gemm.h"
7#include "ggml.h"
8#include "unary-ops.h"
9#include "vec.h"
10
11#include <algorithm>
12#include <cfloat>
13#include <cmath>
14
15// ggml_compute_forward_dup
16
17static void ggml_compute_forward_dup_same_cont(
18        const ggml_compute_params * params,
19        ggml_tensor * dst) {
20
21    const ggml_tensor * src0 = dst->src[0];
22
23    GGML_ASSERT(ggml_nelements(dst) == ggml_nelements(src0));
24    GGML_ASSERT(ggml_is_contiguous(dst) && ggml_is_contiguous(src0));
25    GGML_ASSERT(src0->type == dst->type);
26
27    const size_t nb0 = ggml_type_size(src0->type);
28
29    const int ith = params->ith; // thread index
30    const int nth = params->nth; // number of threads
31
32    // parallelize by blocks
33    const int nk = ggml_nelements(src0)/ggml_blck_size(src0->type);
34    const int dr = (nk + nth - 1) / nth;
35    const int k0 = dr * ith;
36    const int k1 = MIN(k0 + dr, nk);
37
38    if (k0 < k1) {
39        memcpy(
40            ((char *)  dst->data + k0*nb0),
41            ((char *) src0->data + k0*nb0),
42            (k1 - k0) * nb0);
43    }
44}
45
46template<typename src_t, typename dst_t>
47static void ggml_compute_forward_dup_flt(
48        const ggml_compute_params * params,
49        ggml_tensor * dst) {
50
51    const ggml_tensor * src0 = dst->src[0];
52
53    GGML_ASSERT(ggml_nelements(dst) == ggml_nelements(src0));
54    GGML_ASSERT(!ggml_is_quantized(src0->type) && !ggml_is_quantized(dst->type));
55
56    GGML_TENSOR_UNARY_OP_LOCALS
57
58    const int ith = params->ith; // thread index
59    const int nth = params->nth; // number of threads
60
61    // parallelize by rows
62    const int nr = ne01;
63    // number of rows per thread
64    const int dr = (nr + nth - 1) / nth;
65    // row range for this thread
66    const int ir0 = dr * ith;
67    const int ir1 = MIN(ir0 + dr, nr);
68
69    // case: type & row size equal
70    if (src0->type == dst->type &&
71        ne00 == ne0 &&
72        nb00 == ggml_type_size(src0->type) && nb0 == ggml_type_size(dst->type)) {
73        // copy by rows
74        const size_t rs = ne00*nb00;
75        for (int64_t i03 = 0; i03 < ne03; i03++) {
76            for (int64_t i02 = 0; i02 < ne02; i02++) {
77                for (int64_t i01 = ir0; i01 < ir1; i01++) {
78                    memcpy(
79                        ((char *)  dst->data + i01*nb1  + i02*nb2  + i03*nb3),
80                        ((char *) src0->data + i01*nb01 + i02*nb02 + i03*nb03),
81                        rs);
82                }
83            }
84        }
85        return;
86    }
87
88    // case: dst tensor is contiguous
89    if (ggml_is_contiguous(dst)) {
90        if (nb00 == sizeof(src_t)) {
91            if constexpr (std::is_same_v<dst_t, src_t>) {
92                // same type
93                size_t id = 0;
94                const size_t rs = ne00 * nb00;
95                char * dst_ptr = (char *) dst->data;
96
97                for (int i03 = 0; i03 < ne03; i03++) {
98                    for (int i02 = 0; i02 < ne02; i02++) {
99                        id += rs * ir0;
100                        for (int i01 = ir0; i01 < ir1; i01++) {
101                            const char * src0_ptr = (char *) src0->data + i01*nb01 + i02*nb02 + i03*nb03;
102                            memcpy(dst_ptr + id, src0_ptr, rs);
103                            id += rs;
104                        }
105                        id += rs * (ne01 - ir1);
106                    }
107                }
108            } else {
109                // casting between non-quantized types
110                size_t id = 0;
111                dst_t * dst_ptr = (dst_t *) dst->data;
112
113                for (int i03 = 0; i03 < ne03; i03++) {
114                    for (int i02 = 0; i02 < ne02; i02++) {
115                        id += ne00 * ir0;
116                        for (int i01 = ir0; i01 < ir1; i01++) {
117                            const src_t * src0_ptr = (src_t *) ((char *) src0->data + i01*nb01 + i02*nb02 + i03*nb03);
118                            for (int i00 = 0; i00 < ne00; i00++) {
119                                float tmp = type_conversion_table<src_t>::to_f32(src0_ptr[i00]);
120                                dst_ptr[id] = type_conversion_table<dst_t>::from_f32(tmp);
121                                id++;
122                            }
123                        }
124                        id += ne00 * (ne01 - ir1);
125                    }
126                }
127            }
128        } else {
129            //printf("%s: this is not optimal - fix me\n", __func__);
130
131            size_t id = 0;
132            dst_t * dst_ptr = (dst_t *) dst->data;
133
134            for (int i03 = 0; i03 < ne03; i03++) {
135                for (int i02 = 0; i02 < ne02; i02++) {
136                    id += ne00 * ir0;
137                    for (int i01 = ir0; i01 < ir1; i01++) {
138                        for (int i00 = 0; i00 < ne00; i00++) {
139                            const src_t * src0_ptr = (src_t *) ((char *) src0->data + i00*nb00 + i01*nb01 + i02*nb02 + i03*nb03);
140
141                            float tmp = type_conversion_table<src_t>::to_f32(*src0_ptr);
142                            dst_ptr[id] = type_conversion_table<dst_t>::from_f32(tmp);
143                            id++;
144                        }
145                    }
146                    id += ne00 * (ne01 - ir1);
147                }
148            }
149        }
150        return;
151    }
152
153    // dst counters
154    int64_t i10 = 0;
155    int64_t i11 = 0;
156    int64_t i12 = 0;
157    int64_t i13 = 0;
158
159    if constexpr (std::is_same_v<dst_t, src_t>) {
160        for (int64_t i03 = 0; i03 < ne03; i03++) {
161            for (int64_t i02 = 0; i02 < ne02; i02++) {
162                i10 += ne00 * ir0;
163                while (i10 >= ne0) {
164                    i10 -= ne0;
165                    if (++i11 == ne1) {
166                        i11 = 0;
167                        if (++i12 == ne2) {
168                            i12 = 0;
169                            if (++i13 == ne3) {
170                                i13 = 0;
171                            }
172                        }
173                    }
174                }
175                for (int64_t i01 = ir0; i01 < ir1; i01++) {
176                    for (int64_t i00 = 0; i00 < ne00; i00++) {
177                        const char * src0_ptr = ((char *) src0->data + i00*nb00 + i01*nb01 + i02*nb02 + i03*nb03);
178                              char * dst_ptr  = ((char *)  dst->data + i10*nb0  + i11*nb1  + i12*nb2  + i13*nb3);
179
180                        memcpy(dst_ptr, src0_ptr, sizeof(dst_t));
181
182                        if (++i10 == ne00) {
183                            i10 = 0;
184                            if (++i11 == ne01) {
185                                i11 = 0;
186                                if (++i12 == ne02) {
187                                    i12 = 0;
188                                    if (++i13 == ne03) {
189                                        i13 = 0;
190                                    }
191                                }
192                            }
193                        }
194                    }
195                }
196                i10 += ne00 * (ne01 - ir1);
197                while (i10 >= ne0) {
198                    i10 -= ne0;
199                    if (++i11 == ne1) {
200                        i11 = 0;
201                        if (++i12 == ne2) {
202                            i12 = 0;
203                            if (++i13 == ne3) {
204                                i13 = 0;
205                            }
206                        }
207                    }
208                }
209            }
210        }
211
212    } else {
213        for (int64_t i03 = 0; i03 < ne03; i03++) {
214            for (int64_t i02 = 0; i02 < ne02; i02++) {
215                i10 += ne00 * ir0;
216                while (i10 >= ne0) {
217                    i10 -= ne0;
218                    if (++i11 == ne1) {
219                        i11 = 0;
220                        if (++i12 == ne2) {
221                            i12 = 0;
222                            if (++i13 == ne3) {
223                                i13 = 0;
224                            }
225                        }
226                    }
227                }
228                for (int64_t i01 = ir0; i01 < ir1; i01++) {
229                    for (int64_t i00 = 0; i00 < ne00; i00++) {
230                        const char * src0_ptr = ((char *) src0->data + i00*nb00 + i01*nb01 + i02*nb02 + i03*nb03);
231                              char * dst_ptr  = ((char *)  dst->data + i10*nb0  + i11*nb1  + i12*nb2  + i13*nb3);
232
233                        float tmp = type_conversion_table<src_t>::to_f32(*(const src_t *) src0_ptr);
234                        *(dst_t *) dst_ptr = type_conversion_table<dst_t>::from_f32(tmp);
235
236                        if (++i10 == ne0) {
237                            i10 = 0;
238                            if (++i11 == ne1) {
239                                i11 = 0;
240                                if (++i12 == ne2) {
241                                    i12 = 0;
242                                    if (++i13 == ne3) {
243                                        i13 = 0;
244                                    }
245                                }
246                            }
247                        }
248                    }
249                }
250                i10 += ne00 * (ne01 - ir1);
251                while (i10 >= ne0) {
252                    i10 -= ne0;
253                    if (++i11 == ne1) {
254                        i11 = 0;
255                        if (++i12 == ne2) {
256                            i12 = 0;
257                            if (++i13 == ne3) {
258                                i13 = 0;
259                            }
260                        }
261                    }
262                }
263            }
264        }
265    }
266}
267
268
269template<typename src_t>
270static void ggml_compute_forward_dup_to_q(
271        const ggml_compute_params * params,
272        ggml_tensor * dst) {
273
274    const ggml_tensor * src0 = dst->src[0];
275
276    GGML_ASSERT(ggml_nelements(dst) == ggml_nelements(src0));
277    GGML_ASSERT(!ggml_is_quantized(src0->type));
278
279    GGML_TENSOR_UNARY_OP_LOCALS
280
281    const int ith = params->ith; // thread index
282    const int nth = params->nth; // number of threads
283
284    // parallelize by rows
285    const int nr = ne01;
286    // number of rows per thread
287    const int dr = (nr + nth - 1) / nth;
288    // row range for this thread
289    const int ir0 = dr * ith;
290    const int ir1 = MIN(ir0 + dr, nr);
291
292    if (ggml_is_contiguous(dst) &&
293            nb00 == sizeof(src_t) &&
294            ggml_get_type_traits_cpu(dst->type)->from_float) {
295        // casting non-quantized types --> intermediate f32 --> quantized
296        ggml_from_float_t const quantize_row_q = ggml_get_type_traits_cpu(dst->type)->from_float;
297        float * src0_f32 = (float *) params->wdata + (ne00 + CACHE_LINE_SIZE_F32) * ith;
298
299        size_t id = 0;
300        size_t rs = nb0 * (ne00 / ggml_blck_size(dst->type));
301        char * dst_ptr = (char *) dst->data;
302
303        for (int i03 = 0; i03 < ne03; i03++) {
304            for (int i02 = 0; i02 < ne02; i02++) {
305                id += rs * ir0;
306                for (int i01 = ir0; i01 < ir1; i01++) {
307                    const src_t * src0_ptr = (src_t *) ((char *) src0->data + i01*nb01 + i02*nb02 + i03*nb03);
308
309                    for (int i00 = 0; i00 < ne00; i00++) {
310                        src0_f32[i00] = type_conversion_table<src_t>::to_f32(src0_ptr[i00]);
311                    }
312
313                    quantize_row_q(src0_f32, dst_ptr + id, ne00);
314                    id += rs;
315                }
316                id += rs * (ne01 - ir1);
317            }
318        }
319    } else {
320        // printf("%s %s\n", ggml_type_name(src0->type), ggml_type_name(dst->type));
321        GGML_ABORT("not implemented");
322    }
323}
324
325// A simplified version of ggml_compute_forward_dup that doesn't do float upcasting, and just plain old memcpy.
326static void ggml_compute_forward_dup_bytes(
327        const ggml_compute_params * params,
328        ggml_tensor * dst) {
329    const ggml_tensor * src0 = dst->src[0];
330
331    GGML_ASSERT(ggml_nelements(dst) == ggml_nelements(src0));
332    GGML_ASSERT(src0->type == dst->type);
333
334    GGML_TENSOR_UNARY_OP_LOCALS;
335
336    if (ggml_is_contiguous(src0) && ggml_is_contiguous(dst)) {
337        ggml_compute_forward_dup_same_cont(params, dst);
338        return;
339    }
340
341    const size_t type_size = ggml_type_size(src0->type);
342
343    const int ith = params->ith; // thread index
344    const int nth = params->nth; // number of threads
345
346    // parallelize by rows
347    const int nr = ne01;
348    // number of rows per thread
349    const int dr = (nr + nth - 1) / nth;
350    // row range for this thread
351    const int ir0 = dr * ith;
352    const int ir1 = MIN(ir0 + dr, nr);
353
354    if (src0->type == dst->type &&
355        ggml_are_same_shape(src0, dst) &&
356        nb00 == type_size && nb0 == type_size) {
357        // copy by rows
358        const size_t rs = ggml_row_size(src0->type, ne00);
359        for (int64_t i03 = 0; i03 < ne03; i03++) {
360            for (int64_t i02 = 0; i02 < ne02; i02++) {
361                for (int64_t i01 = ir0; i01 < ir1; i01++) {
362                    memcpy(
363                        ((char *)  dst->data + i01*nb1  + i02*nb2  + i03*nb3),
364                        ((char *) src0->data + i01*nb01 + i02*nb02 + i03*nb03),
365                        rs);
366                }
367            }
368        }
369        return;
370    }
371
372    if (ggml_is_contiguous(dst)) {
373        size_t id = 0;
374        char * dst_ptr = (char *) dst->data;
375        const size_t rs = ne00 * type_size;
376
377        if (nb00 == type_size) {
378            // src0 is contiguous on first dimension, copy by rows
379            for (int64_t i03 = 0; i03 < ne03; i03++) {
380                for (int64_t i02 = 0; i02 < ne02; i02++) {
381                    id += rs * ir0;
382                    for (int64_t i01 = ir0; i01 < ir1; i01++) {
383                        const char * src0_ptr = (char *) src0->data + i01*nb01 + i02*nb02 + i03*nb03;
384                        memcpy(dst_ptr + id, src0_ptr, rs);
385                        id += rs;
386                    }
387                    id += rs * (ne01 - ir1);
388                }
389            }
390        } else {
391            //printf("%s: this is not optimal - fix me\n", __func__);
392
393            for (int64_t i03 = 0; i03 < ne03; i03++) {
394                for (int64_t i02 = 0; i02 < ne02; i02++) {
395                    id += rs * ir0;
396                    for (int64_t i01 = ir0; i01 < ir1; i01++) {
397                        for (int64_t i00 = 0; i00 < ne00; i00++) {
398                            const char * src0_ptr = (char *) src0->data + i00*nb00 + i01*nb01 + i02*nb02 + i03*nb03;
399                            memcpy(dst_ptr + id, src0_ptr, type_size);
400
401                            id += type_size;
402                        }
403                    }
404                    id += rs * (ne01 - ir1);
405                }
406            }
407        }
408
409        return;
410    }
411
412    // dst counters
413    int64_t k10 = 0;
414    int64_t i11 = 0;
415    int64_t i12 = 0;
416    int64_t i13 = 0;
417
418    // number of blocks in a row
419    const int64_t nk00 = ne00 / ggml_blck_size(src0->type);
420    const int64_t nk0  = ne0  / ggml_blck_size(dst->type);
421
422    for (int64_t i03 = 0; i03 < ne03; i03++) {
423        for (int64_t i02 = 0; i02 < ne02; i02++) {
424            k10 += nk00 * ir0;
425            while (k10 >= nk0) {
426                k10 -= nk0;
427                if (++i11 == ne1) {
428                    i11 = 0;
429                    if (++i12 == ne2) {
430                        i12 = 0;
431                        if (++i13 == ne3) {
432                            i13 = 0;
433                        }
434                    }
435                }
436            }
437            for (int64_t i01 = ir0; i01 < ir1; i01++) {
438                for (int64_t k00 = 0; k00 < nk00; k00++) {
439                    const char * src0_ptr = ((char *) src0->data + k00*nb00 + i01*nb01 + i02*nb02 + i03*nb03);
440                          char * dst_ptr  = ((char *)  dst->data + k10*nb0  + i11*nb1  + i12*nb2  + i13*nb3);
441
442                    memcpy(dst_ptr, src0_ptr, type_size);
443
444                    if (++k10 == nk0) {
445                        k10 = 0;
446                        if (++i11 == ne1) {
447                            i11 = 0;
448                            if (++i12 == ne2) {
449                                i12 = 0;
450                                if (++i13 == ne3) {
451                                    i13 = 0;
452                                }
453                            }
454                        }
455                    }
456                }
457            }
458            k10 += nk00 * (ne01 - ir1);
459            while (k10 >= nk0) {
460                k10 -= nk0;
461                if (++i11 == ne1) {
462                    i11 = 0;
463                    if (++i12 == ne2) {
464                        i12 = 0;
465                        if (++i13 == ne3) {
466                            i13 = 0;
467                        }
468                    }
469                }
470            }
471        }
472    }
473}
474
475static void ggml_compute_forward_dup_from_q(
476        const ggml_compute_params * params,
477              ggml_tensor * dst) {
478
479    const ggml_tensor * src0 = dst->src[0];
480    const ggml_tensor * src1 = dst->src[1];
481
482    GGML_TENSOR_BINARY_OP_LOCALS
483
484    const ggml_type type = src0->type;
485    ggml_to_float_t const dequantize_row_q = ggml_get_type_traits(type)->to_float;
486
487    size_t qk = ggml_blck_size(type);
488    const int64_t nr = ggml_nelements(src1) / qk;
489
490    // destination must be contiguous in the first dimension
491    GGML_ASSERT(nb10 == ggml_type_size(dst->type));
492    // must either have first dimension large enough to hold a row, or fully contiguous
493    GGML_ASSERT((ne10 % qk) == 0 || ggml_is_contiguous(dst));
494
495    const int ith = params->ith;
496    const int nth = params->nth;
497
498    const int dr = (nr + nth - 1)/nth;
499
500    // row range for this thread
501    const int ir0 = dr*ith;
502    const int ir1 = MIN(ir0 + dr, nr);
503
504    for (int64_t ir = ir0; ir < ir1; ++ir) {
505
506        uint32_t i = ir * qk;
507
508        const int64_t i03 = i/(ne00 * ne01 * ne02);
509        const int64_t i02 = (i - i03*ne00*ne01*ne02 )/ (ne00*ne01);
510        const int64_t i01 = (i - i03*ne00*ne01*ne02  -  i02*ne01*ne00) / ne00;
511        const int64_t i00 = i - i03*ne00*ne01*ne02 - i02*ne01*ne00 - i01*ne00;
512        const int64_t x_offset = (i00/qk)*nb00 + i01*nb01 + i02*nb02 + i03 * nb03;
513
514        const int64_t i13 = i/(ne10 * ne11 * ne12);
515        const int64_t i12 = (i - i13*ne10*ne11*ne12) / (ne10*ne11);
516        const int64_t i11 = (i - i13*ne10*ne11*ne12 - i12*ne10*ne11) / ne10;
517        const int64_t i10 = i - i13*ne10*ne11*ne12 - i12*ne10*ne11 - i11*ne10;
518        const int64_t dst_offset = i10*nb10 + i11*nb11 + i12*nb12 + i13*nb13;
519
520        dequantize_row_q(
521                (const void *) ((char *) src0->data + x_offset),
522                     (float *) ((char *)  dst->data + dst_offset), qk);
523    }
524}
525
526void ggml_compute_forward_dup(
527        const ggml_compute_params * params,
528        ggml_tensor * dst) {
529
530    const ggml_tensor * src0 = dst->src[0];
531
532    if (src0->type == dst->type) {
533        ggml_compute_forward_dup_bytes(params, dst);
534        return;
535    }
536
537    switch (src0->type) {
538        case GGML_TYPE_F16:
539            {
540                /**/ if (dst->type == GGML_TYPE_F16)  ggml_compute_forward_dup_flt<ggml_fp16_t, ggml_fp16_t>(params, dst);
541                else if (dst->type == GGML_TYPE_BF16) ggml_compute_forward_dup_flt<ggml_fp16_t, ggml_bf16_t>(params, dst);
542                else if (dst->type == GGML_TYPE_F32)  ggml_compute_forward_dup_flt<ggml_fp16_t, float      >(params, dst);
543                else ggml_compute_forward_dup_to_q<ggml_fp16_t>(params, dst);
544            } break;
545        case GGML_TYPE_BF16:
546            {
547                /**/ if (dst->type == GGML_TYPE_F16)  ggml_compute_forward_dup_flt<ggml_bf16_t, ggml_fp16_t>(params, dst);
548                else if (dst->type == GGML_TYPE_BF16) ggml_compute_forward_dup_flt<ggml_bf16_t, ggml_bf16_t>(params, dst);
549                else if (dst->type == GGML_TYPE_F32)  ggml_compute_forward_dup_flt<ggml_bf16_t, float      >(params, dst);
550                else ggml_compute_forward_dup_to_q<ggml_bf16_t>(params, dst);
551            } break;
552        case GGML_TYPE_F32:
553            {
554                /**/ if (dst->type == GGML_TYPE_F16)  ggml_compute_forward_dup_flt<float, ggml_fp16_t>(params, dst);
555                else if (dst->type == GGML_TYPE_BF16) ggml_compute_forward_dup_flt<float, ggml_bf16_t>(params, dst);
556                else if (dst->type == GGML_TYPE_F32)  ggml_compute_forward_dup_flt<float, float      >(params, dst);
557                else if (dst->type == GGML_TYPE_I32)  ggml_compute_forward_dup_flt<float, int32_t    >(params, dst);
558                else ggml_compute_forward_dup_to_q<float>(params, dst);
559            } break;
560        case GGML_TYPE_I32:
561            {
562                if (dst->type == GGML_TYPE_F32) ggml_compute_forward_dup_flt<int32_t, float>(params, dst);
563                else GGML_ABORT("not implemented");
564            } break;
565        default:
566            {
567                if (ggml_is_quantized(src0->type) && dst->type == GGML_TYPE_F32) {
568                    ggml_compute_forward_dup_from_q(params, dst);
569                    break;
570                }
571                GGML_ABORT("fatal error");
572            }
573    }
574}
575
576// ggml_compute_forward_add
577
578static void ggml_compute_forward_add_q_f32(
579        const ggml_compute_params * params,
580        ggml_tensor * dst) {
581
582    const ggml_tensor * src0 = dst->src[0];
583    const ggml_tensor * src1 = dst->src[1];
584
585    GGML_ASSERT(ggml_are_same_shape(src0, src1) && ggml_are_same_shape(src0, dst));
586
587    const int nr  = ggml_nrows(src0);
588
589    GGML_TENSOR_BINARY_OP_LOCALS
590
591    const int ith = params->ith;
592    const int nth = params->nth;
593
594    const ggml_type type = src0->type;
595    const ggml_type dtype = dst->type;
596    ggml_to_float_t const dequantize_row_q = ggml_get_type_traits(type)->to_float;
597    ggml_from_float_t const quantize_row_q = ggml_get_type_traits_cpu(dtype)->from_float;
598
599    // we don't support permuted src0 or src1
600    GGML_ASSERT(nb00 == ggml_type_size(type));
601    GGML_ASSERT(nb10 == sizeof(float));
602
603    // dst cannot be transposed or permuted
604    GGML_ASSERT(nb0 <= nb1);
605    GGML_ASSERT(nb1 <= nb2);
606    GGML_ASSERT(nb2 <= nb3);
607
608    GGML_ASSERT(ggml_is_quantized(src0->type));
609    GGML_ASSERT(src1->type == GGML_TYPE_F32);
610
611    // rows per thread
612    const int dr = (nr + nth - 1)/nth;
613
614    // row range for this thread
615    const int ir0 = dr*ith;
616    const int ir1 = MIN(ir0 + dr, nr);
617
618    float * wdata = (float *) params->wdata + (ne00 + CACHE_LINE_SIZE_F32) * ith;
619
620    for (int ir = ir0; ir < ir1; ++ir) {
621        // src0 indices
622        const int i03 = ir/(ne02*ne01);
623        const int i02 = (ir - i03*ne02*ne01)/ne01;
624        const int i01 = (ir - i03*ne02*ne01 - i02*ne01);
625
626        // src1 and dst are same shape as src0 => same indices
627        const int i13 = i03;
628        const int i12 = i02;
629        const int i11 = i01;
630
631        const int i3 = i03;
632        const int i2 = i02;
633        const int i1 = i01;
634
635        void  * src0_row = (void *) ((char *) src0->data + (i01*nb01 + i02*nb02 + i03*nb03));
636        float * src1_row = (float *)((char *) src1->data + (i11*nb11 + i12*nb12 + i13*nb13));
637        void  * dst_row  = (void *) ((char *)  dst->data + ( i1*nb1  +  i2*nb2  +  i3*nb3));
638
639        assert(ne00 % 32 == 0);
640
641        // unquantize row from src0 to temp buffer
642        dequantize_row_q(src0_row, wdata, ne00);
643        // add src1
644        ggml_vec_acc_f32(ne00, wdata, src1_row);
645        // quantize row to dst
646        if (quantize_row_q != NULL) {
647            quantize_row_q(wdata, dst_row, ne00);
648        } else {
649            memcpy(dst_row, wdata, ne0*nb0);
650        }
651    }
652}
653
654void ggml_compute_forward_add(
655        const ggml_compute_params * params,
656        ggml_tensor * dst) {
657
658    const ggml_tensor * src0 = dst->src[0];
659
660    switch (src0->type) {
661        case GGML_TYPE_F32:
662        case GGML_TYPE_F16:
663        case GGML_TYPE_BF16:
664            {
665                ggml_compute_forward_add_non_quantized(params, dst);
666            } break;
667        case GGML_TYPE_Q1_0:
668        case GGML_TYPE_Q2_0:
669        case GGML_TYPE_Q4_0:
670        case GGML_TYPE_Q4_1:
671        case GGML_TYPE_Q5_0:
672        case GGML_TYPE_Q5_1:
673        case GGML_TYPE_Q8_0:
674        case GGML_TYPE_MXFP4:
675        case GGML_TYPE_NVFP4:
676        case GGML_TYPE_Q2_K:
677        case GGML_TYPE_Q3_K:
678        case GGML_TYPE_Q4_K:
679        case GGML_TYPE_Q5_K:
680        case GGML_TYPE_Q6_K:
681        case GGML_TYPE_TQ1_0:
682        case GGML_TYPE_TQ2_0:
683        case GGML_TYPE_IQ2_XXS:
684        case GGML_TYPE_IQ2_XS:
685        case GGML_TYPE_IQ3_XXS:
686        case GGML_TYPE_IQ1_S:
687        case GGML_TYPE_IQ1_M:
688        case GGML_TYPE_IQ4_NL:
689        case GGML_TYPE_IQ4_XS:
690        case GGML_TYPE_IQ3_S:
691        case GGML_TYPE_IQ2_S:
692            {
693                ggml_compute_forward_add_q_f32(params, dst);
694            } break;
695        default:
696            {
697                GGML_ABORT("fatal error");
698            }
699    }
700}
701
702// ggml_compute_forward_add_id
703
704static void ggml_compute_forward_add_id_f32(
705        const ggml_compute_params * params,
706        ggml_tensor * dst) {
707
708    const ggml_tensor * src0 = dst->src[0];
709    const ggml_tensor * src1 = dst->src[1];
710    const ggml_tensor * src2 = dst->src[2];
711
712    GGML_ASSERT(dst->type  == GGML_TYPE_F32);
713    GGML_ASSERT(src0->type == GGML_TYPE_F32);
714    GGML_ASSERT(src1->type == GGML_TYPE_F32);
715    GGML_ASSERT(src2->type == GGML_TYPE_I32);
716
717    GGML_ASSERT(src0->nb[0] == sizeof(float));
718    GGML_ASSERT(src1->nb[0] == sizeof(float));
719
720    const int ith = params->ith;
721    const int nth = params->nth;
722
723    const int nr  = ggml_nrows(src0);
724
725    GGML_TENSOR_TERNARY_OP_LOCALS
726
727    GGML_ASSERT( nb0 == sizeof(float));
728    GGML_ASSERT(nb10 == sizeof(float));
729
730    // rows per thread
731    const int dr = (nr + nth - 1)/nth;
732
733    // row range for this thread
734    const int ir0 = dr*ith;
735    const int ir1 = MIN(ir0 + dr, nr);
736
737    for (int ir = ir0; ir < ir1; ++ir) {
738        // src0 indices
739        const int i3 = ir/(ne2*ne1);
740        const int i2 = (ir - i3*ne2*ne1)/ne1;
741        const int i1 = (ir - i3*ne2*ne1 - i2*ne1);
742
743        // src1 indices
744        const int i11 = *(int32_t *) ((char *) src2->data + i1*nb20 + i2*nb21);
745
746        GGML_ASSERT(i11 >= 0 && i11 < ne11);
747
748        ggml_vec_add_f32(ne0,
749                (float *) ((char *) dst->data  + i3*nb3  + i2*nb2  + i1*nb1 ),
750                (float *) ((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01),
751                (float *) ((char *) src1->data + i11*nb11));
752    }
753}
754
755void ggml_compute_forward_add_id(
756        const ggml_compute_params * params,
757        ggml_tensor * dst) {
758
759    const ggml_tensor * src0 = dst->src[0];
760
761    switch (src0->type) {
762        case GGML_TYPE_F32:
763            {
764                ggml_compute_forward_add_id_f32(params, dst);
765            } break;
766        default:
767            {
768                GGML_ABORT("unsupported type for ggml_compute_forward_add_id: %s", ggml_type_name(src0->type));
769            }
770    }
771}
772
773// ggml_compute_forward_add1
774
775static void ggml_compute_forward_add1_f32(
776        const ggml_compute_params * params,
777        ggml_tensor * dst) {
778
779    const ggml_tensor * src0 = dst->src[0];
780    const ggml_tensor * src1 = dst->src[1];
781
782    GGML_ASSERT(ggml_are_same_shape(src0, dst));
783    GGML_ASSERT(ggml_is_scalar(src1));
784
785    const int ith = params->ith;
786    const int nth = params->nth;
787
788    const int nr  = ggml_nrows(src0);
789
790    GGML_TENSOR_UNARY_OP_LOCALS
791
792    GGML_ASSERT( nb0 == sizeof(float));
793    GGML_ASSERT(nb00 == sizeof(float));
794
795    // rows per thread
796    const int dr = (nr + nth - 1)/nth;
797
798    // row range for this thread
799    const int ir0 = dr*ith;
800    const int ir1 = MIN(ir0 + dr, nr);
801
802    for (int ir = ir0; ir < ir1; ++ir) {
803        // src0 and dst are same shape => same indices
804        const int i3 = ir/(ne2*ne1);
805        const int i2 = (ir - i3*ne2*ne1)/ne1;
806        const int i1 = (ir - i3*ne2*ne1 - i2*ne1);
807
808#ifdef GGML_USE_ACCELERATE
809        GGML_UNUSED(ggml_vec_add1_f32);
810
811        vDSP_vadd(
812                (float *) ((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01), 1,
813                (float *) ((char *) src1->data), 0,
814                (float *) ((char *) dst->data  + i3*nb3  + i2*nb2  + i1*nb1 ), 1,
815                ne0);
816#else
817        ggml_vec_add1_f32(ne0,
818                (float *) ((char *) dst->data  + i3*nb3  + i2*nb2  + i1*nb1 ),
819                (float *) ((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01),
820               *(float *) src1->data);
821#endif
822    }
823}
824
825static void ggml_compute_forward_add1_f16_f32(
826        const ggml_compute_params * params,
827        ggml_tensor * dst) {
828
829    const ggml_tensor * src0 = dst->src[0];
830    const ggml_tensor * src1 = dst->src[1];
831
832    GGML_ASSERT(ggml_are_same_shape(src0, dst));
833    GGML_ASSERT(ggml_is_scalar(src1));
834
835    // scalar to add
836    const float v = *(float *) src1->data;
837
838    const int ith = params->ith;
839    const int nth = params->nth;
840
841    const int nr  = ggml_nrows(src0);
842
843    GGML_TENSOR_UNARY_OP_LOCALS
844
845    GGML_ASSERT(src0->type == GGML_TYPE_F16);
846    GGML_ASSERT(src1->type == GGML_TYPE_F32);
847    GGML_ASSERT(dst->type  == GGML_TYPE_F16);
848
849    GGML_ASSERT( nb0 == sizeof(ggml_fp16_t));
850    GGML_ASSERT(nb00 == sizeof(ggml_fp16_t));
851
852    // rows per thread
853    const int dr = (nr + nth - 1)/nth;
854
855    // row range for this thread
856    const int ir0 = dr*ith;
857    const int ir1 = MIN(ir0 + dr, nr);
858
859    for (int ir = ir0; ir < ir1; ++ir) {
860        // src0 and dst are same shape => same indices
861        const int i3 = ir/(ne2*ne1);
862        const int i2 = (ir - i3*ne2*ne1)/ne1;
863        const int i1 = (ir - i3*ne2*ne1 - i2*ne1);
864
865        ggml_fp16_t * dst_ptr  = (ggml_fp16_t *) ((char *) dst->data  + i3*nb3  + i2*nb2  + i1*nb1 );
866        ggml_fp16_t * src0_ptr = (ggml_fp16_t *) ((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01);
867        for (int i = 0; i < ne0; i++) {
868            dst_ptr[i] = GGML_CPU_FP32_TO_FP16(GGML_CPU_FP16_TO_FP32(src0_ptr[i]) + v);
869        }
870    }
871}
872
873static void ggml_compute_forward_add1_f16_f16(
874        const ggml_compute_params * params,
875        ggml_tensor * dst) {
876
877    const ggml_tensor * src0 = dst->src[0];
878    const ggml_tensor * src1 = dst->src[1];
879
880    GGML_ASSERT(ggml_are_same_shape(src0, dst));
881    GGML_ASSERT(ggml_is_scalar(src1));
882
883    // scalar to add
884    const float v = GGML_CPU_FP16_TO_FP32(*(ggml_fp16_t *) src1->data);
885
886    const int ith = params->ith;
887    const int nth = params->nth;
888
889    const int nr  = ggml_nrows(src0);
890
891    GGML_TENSOR_UNARY_OP_LOCALS
892
893    GGML_ASSERT(src0->type == GGML_TYPE_F16);
894    GGML_ASSERT(src1->type == GGML_TYPE_F16);
895    GGML_ASSERT(dst->type  == GGML_TYPE_F16);
896
897    GGML_ASSERT( nb0 == sizeof(ggml_fp16_t));
898    GGML_ASSERT(nb00 == sizeof(ggml_fp16_t));
899
900    // rows per thread
901    const int dr = (nr + nth - 1)/nth;
902
903    // row range for this thread
904    const int ir0 = dr*ith;
905    const int ir1 = MIN(ir0 + dr, nr);
906
907    for (int ir = ir0; ir < ir1; ++ir) {
908        // src0 and dst are same shape => same indices
909        const int i3 = ir/(ne2*ne1);
910        const int i2 = (ir - i3*ne2*ne1)/ne1;
911        const int i1 = (ir - i3*ne2*ne1 - i2*ne1);
912
913        ggml_fp16_t * dst_ptr  = (ggml_fp16_t *) ((char *) dst->data  + i3*nb3  + i2*nb2  + i1*nb1 );
914        ggml_fp16_t * src0_ptr = (ggml_fp16_t *) ((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01);
915        for (int i = 0; i < ne0; i++) {
916            dst_ptr[i] = GGML_CPU_FP32_TO_FP16(GGML_CPU_FP16_TO_FP32(src0_ptr[i]) + v);
917        }
918    }
919}
920
921static void ggml_compute_forward_add1_q_f32(
922        const ggml_compute_params * params,
923        ggml_tensor * dst) {
924
925    const ggml_tensor * src0 = dst->src[0];
926    const ggml_tensor * src1 = dst->src[1];
927
928    GGML_ASSERT(ggml_are_same_shape(src0, dst));
929    GGML_ASSERT(ggml_is_scalar(src1));
930
931    // scalar to add
932    const float v = *(float *) src1->data;
933
934    const int ith = params->ith;
935    const int nth = params->nth;
936
937    const int nr  = ggml_nrows(src0);
938
939    GGML_TENSOR_UNARY_OP_LOCALS
940
941    const ggml_type type = src0->type;
942    ggml_to_float_t const dequantize_row_q = ggml_get_type_traits(type)->to_float;
943    ggml_from_float_t const quantize_row_q = ggml_get_type_traits_cpu(type)->from_float;
944
945    // we don't support permuted src0
946    GGML_ASSERT(nb00 == ggml_type_size(type));
947
948    // dst cannot be transposed or permuted
949    GGML_ASSERT(nb0 <= nb1);
950    GGML_ASSERT(nb1 <= nb2);
951    GGML_ASSERT(nb2 <= nb3);
952
953    GGML_ASSERT(ggml_is_quantized(src0->type));
954    GGML_ASSERT(dst->type == src0->type);
955    GGML_ASSERT(src1->type == GGML_TYPE_F32);
956
957    // rows per thread
958    const int dr = (nr + nth - 1)/nth;
959
960    // row range for this thread
961    const int ir0 = dr*ith;
962    const int ir1 = MIN(ir0 + dr, nr);
963
964    float * wdata = (float *) params->wdata + (ne0 + CACHE_LINE_SIZE_F32) * ith;
965
966    for (int ir = ir0; ir < ir1; ++ir) {
967        // src0 and dst are same shape => same indices
968        const int i3 = ir/(ne2*ne1);
969        const int i2 = (ir - i3*ne2*ne1)/ne1;
970        const int i1 = (ir - i3*ne2*ne1 - i2*ne1);
971
972        void  * src0_row = (void *) ((char *) src0->data + (i1*nb01 + i2*nb02 + i3*nb03));
973        void  * dst_row  = (void *) ((char *)  dst->data + (i1*nb1  + i2*nb2  + i3*nb0 ));
974
975        assert(ne0 % 32 == 0);
976
977        // unquantize row from src0 to temp buffer
978        dequantize_row_q(src0_row, wdata, ne0);
979        // add src1
980        ggml_vec_acc1_f32(ne0, wdata, v);
981        // quantize row to dst
982        quantize_row_q(wdata, dst_row, ne0);
983    }
984}
985
986static void ggml_compute_forward_add1_bf16_f32(
987        const ggml_compute_params * params,
988        ggml_tensor * dst) {
989
990    const ggml_tensor * src0 = dst->src[0];
991    const ggml_tensor * src1 = dst->src[1];
992
993    GGML_ASSERT(ggml_are_same_shape(src0, dst));
994    GGML_ASSERT(ggml_is_scalar(src1));
995
996    // scalar to add
997    const float v = *(float *) src1->data;
998
999    const int ith = params->ith;
1000    const int nth = params->nth;
1001
1002    const int nr  = ggml_nrows(src0);
1003
1004    GGML_TENSOR_UNARY_OP_LOCALS
1005
1006    GGML_ASSERT(src0->type == GGML_TYPE_BF16);
1007    GGML_ASSERT(src1->type == GGML_TYPE_F32);
1008    GGML_ASSERT(dst->type  == GGML_TYPE_BF16);
1009
1010    GGML_ASSERT( nb0 == sizeof(ggml_bf16_t));
1011    GGML_ASSERT(nb00 == sizeof(ggml_bf16_t));
1012
1013    // rows per thread
1014    const int dr = (nr + nth - 1)/nth;
1015
1016    // row range for this thread
1017    const int ir0 = dr*ith;
1018    const int ir1 = MIN(ir0 + dr, nr);
1019
1020    for (int ir = ir0; ir < ir1; ++ir) {
1021        // src0 and dst are same shape => same indices
1022        const int i3 = ir/(ne2*ne1);
1023        const int i2 = (ir - i3*ne2*ne1)/ne1;
1024        const int i1 = (ir - i3*ne2*ne1 - i2*ne1);
1025
1026        ggml_bf16_t * dst_ptr  = (ggml_bf16_t *) ((char *) dst->data  + i3*nb3  + i2*nb2  + i1*nb1 );
1027        ggml_bf16_t * src0_ptr = (ggml_bf16_t *) ((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01);
1028        for (int i = 0; i < ne0; i++) {
1029            dst_ptr[i] = GGML_FP32_TO_BF16(GGML_BF16_TO_FP32(src0_ptr[i]) + v);
1030        }
1031    }
1032}
1033
1034static void ggml_compute_forward_add1_bf16_bf16(
1035        const ggml_compute_params * params,
1036        ggml_tensor * dst) {
1037
1038    const ggml_tensor * src0 = dst->src[0];
1039    const ggml_tensor * src1 = dst->src[1];
1040
1041    GGML_ASSERT(ggml_are_same_shape(src0, dst));
1042    GGML_ASSERT(ggml_is_scalar(src1));
1043
1044    // scalar to add
1045    const float v = GGML_BF16_TO_FP32(*(ggml_bf16_t *) src1->data);
1046
1047    const int ith = params->ith;
1048    const int nth = params->nth;
1049
1050    const int nr  = ggml_nrows(src0);
1051
1052    GGML_TENSOR_UNARY_OP_LOCALS
1053
1054    GGML_ASSERT(src0->type == GGML_TYPE_BF16);
1055    GGML_ASSERT(src1->type == GGML_TYPE_BF16);
1056    GGML_ASSERT(dst->type  == GGML_TYPE_BF16);
1057
1058    GGML_ASSERT( nb0 == sizeof(ggml_bf16_t));
1059    GGML_ASSERT(nb00 == sizeof(ggml_bf16_t));
1060
1061    // rows per thread
1062    const int dr = (nr + nth - 1)/nth;
1063
1064    // row range for this thread
1065    const int ir0 = dr*ith;
1066    const int ir1 = MIN(ir0 + dr, nr);
1067
1068    for (int ir = ir0; ir < ir1; ++ir) {
1069        // src0 and dst are same shape => same indices
1070        const int i3 = ir/(ne2*ne1);
1071        const int i2 = (ir - i3*ne2*ne1)/ne1;
1072        const int i1 = (ir - i3*ne2*ne1 - i2*ne1);
1073
1074        ggml_bf16_t * dst_ptr  = (ggml_bf16_t *) ((char *) dst->data  + i3*nb3  + i2*nb2  + i1*nb1 );
1075        ggml_bf16_t * src0_ptr = (ggml_bf16_t *) ((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01);
1076        for (int i = 0; i < ne0; i++) {
1077            dst_ptr[i] = GGML_FP32_TO_BF16(GGML_BF16_TO_FP32(src0_ptr[i]) + v);
1078        }
1079    }
1080}
1081
1082void ggml_compute_forward_add1(
1083        const ggml_compute_params * params,
1084        ggml_tensor * dst) {
1085
1086    const ggml_tensor * src0 = dst->src[0];
1087    const ggml_tensor * src1 = dst->src[1];
1088
1089    switch (src0->type) {
1090        case GGML_TYPE_F32:
1091            {
1092                ggml_compute_forward_add1_f32(params, dst);
1093            } break;
1094        case GGML_TYPE_F16:
1095            {
1096                if (src1->type == GGML_TYPE_F16) {
1097                    ggml_compute_forward_add1_f16_f16(params, dst);
1098                }
1099                else if (src1->type == GGML_TYPE_F32) {
1100                    ggml_compute_forward_add1_f16_f32(params, dst);
1101                }
1102                else {
1103                    GGML_ABORT("fatal error");
1104                }
1105            } break;
1106        case GGML_TYPE_BF16:
1107            {
1108                if (src1->type == GGML_TYPE_BF16) {
1109                    ggml_compute_forward_add1_bf16_bf16(params, dst);
1110                }
1111                else if (src1->type == GGML_TYPE_F32) {
1112                    ggml_compute_forward_add1_bf16_f32(params, dst);
1113                }
1114                else {
1115                    GGML_ABORT("fatal error");
1116                }
1117            } break;
1118        case GGML_TYPE_Q1_0:
1119        case GGML_TYPE_Q2_0:
1120        case GGML_TYPE_Q4_0:
1121        case GGML_TYPE_Q4_1:
1122        case GGML_TYPE_Q5_0:
1123        case GGML_TYPE_Q5_1:
1124        case GGML_TYPE_Q8_0:
1125        case GGML_TYPE_Q8_1:
1126        case GGML_TYPE_MXFP4:
1127        case GGML_TYPE_NVFP4:
1128        case GGML_TYPE_Q2_K:
1129        case GGML_TYPE_Q3_K:
1130        case GGML_TYPE_Q4_K:
1131        case GGML_TYPE_Q5_K:
1132        case GGML_TYPE_Q6_K:
1133        case GGML_TYPE_TQ1_0:
1134        case GGML_TYPE_TQ2_0:
1135        case GGML_TYPE_IQ2_XXS:
1136        case GGML_TYPE_IQ2_XS:
1137        case GGML_TYPE_IQ3_XXS:
1138        case GGML_TYPE_IQ1_S:
1139        case GGML_TYPE_IQ1_M:
1140        case GGML_TYPE_IQ4_NL:
1141        case GGML_TYPE_IQ4_XS:
1142        case GGML_TYPE_IQ3_S:
1143        case GGML_TYPE_IQ2_S:
1144            {
1145                ggml_compute_forward_add1_q_f32(params, dst);
1146            } break;
1147        default:
1148            {
1149                GGML_ABORT("fatal error");
1150            }
1151    }
1152}
1153
1154// ggml_compute_forward_acc
1155
1156static void ggml_compute_forward_acc_f32(
1157        const ggml_compute_params * params,
1158        ggml_tensor * dst) {
1159
1160    const ggml_tensor * src0 = dst->src[0];
1161    const ggml_tensor * src1 = dst->src[1];
1162
1163    GGML_ASSERT(ggml_are_same_shape(src0, dst));
1164    GGML_ASSERT(ggml_is_contiguous(dst) && ggml_is_contiguous(src0));
1165
1166    // view src0 and dst with these strides and data offset inbytes during acc
1167    // nb0 is implicitly element_size because src0 and dst are contiguous
1168    size_t nb1     = ((int32_t *) dst->op_params)[0];
1169    size_t nb2     = ((int32_t *) dst->op_params)[1];
1170    size_t nb3     = ((int32_t *) dst->op_params)[2];
1171    size_t offset  = ((int32_t *) dst->op_params)[3];
1172    bool   inplace = (bool) ((int32_t *) dst->op_params)[4];
1173
1174    if (!inplace) {
1175        if (params->ith == 0) {
1176            // memcpy needs to be synchronized across threads to avoid race conditions.
1177            // => do it in INIT phase
1178            memcpy(
1179                ((char *)  dst->data),
1180                ((char *) src0->data),
1181                ggml_nbytes(dst));
1182        }
1183        ggml_barrier(params->threadpool);
1184    }
1185
1186    const int ith = params->ith;
1187    const int nth = params->nth;
1188
1189    const int nr = ggml_nrows(src1);
1190    const int nc = src1->ne[0];
1191
1192    GGML_TENSOR_LOCALS(int64_t, ne1, src1, ne)
1193    GGML_TENSOR_LOCALS(size_t,  nb1, src1, nb)
1194
1195    // src0 and dst as viewed during acc
1196    const size_t nb0 = ggml_element_size(src0);
1197
1198    const size_t nb00 = nb0;
1199    const size_t nb01 = nb1;
1200    const size_t nb02 = nb2;
1201    const size_t nb03 = nb3;
1202
1203    GGML_ASSERT(offset + (ne10 == 0 ? 0 : ne10-1)*nb0  + (ne11 == 0 ? 0 : ne11-1)*nb1  + (ne12 == 0 ? 0 : ne12-1)*nb2  + (ne13 == 0 ? 0 : ne13-1)*nb3  < ggml_nbytes(dst));
1204    GGML_ASSERT(offset + (ne10 == 0 ? 0 : ne10-1)*nb00 + (ne11 == 0 ? 0 : ne11-1)*nb01 + (ne12 == 0 ? 0 : ne12-1)*nb02 + (ne13 == 0 ? 0 : ne13-1)*nb03 < ggml_nbytes(src0));
1205
1206    GGML_ASSERT(nb10 == sizeof(float));
1207
1208    // rows per thread
1209    const int dr = (nr + nth - 1)/nth;
1210
1211    // row range for this thread
1212    const int ir0 = dr*ith;
1213    const int ir1 = MIN(ir0 + dr, nr);
1214
1215    for (int ir = ir0; ir < ir1; ++ir) {
1216        // src0 and dst are viewed with shape of src1 and offset
1217        // => same indices
1218        const int i3 = ir/(ne12*ne11);
1219        const int i2 = (ir - i3*ne12*ne11)/ne11;
1220        const int i1 = (ir - i3*ne12*ne11 - i2*ne11);
1221
1222#ifdef GGML_USE_ACCELERATE
1223        vDSP_vadd(
1224                (float *) ((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01 + offset), 1,
1225                (float *) ((char *) src1->data + i3*nb13 + i2*nb12 + i1*nb11), 1,
1226                (float *) ((char *) dst->data  + i3*nb3  + i2*nb2  + i1*nb1  + offset), 1, nc);
1227#else
1228        ggml_vec_add_f32(nc,
1229                (float *) ((char *)  dst->data + i3*nb3  + i2*nb2  + i1*nb1  + offset),
1230                (float *) ((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01 + offset),
1231                (float *) ((char *) src1->data + i3*nb13 + i2*nb12 + i1*nb11));
1232#endif
1233    }
1234}
1235
1236void ggml_compute_forward_acc(
1237        const ggml_compute_params * params,
1238        ggml_tensor * dst) {
1239
1240    const ggml_tensor * src0 = dst->src[0];
1241
1242    switch (src0->type) {
1243        case GGML_TYPE_F32:
1244            {
1245                ggml_compute_forward_acc_f32(params, dst);
1246            } break;
1247        case GGML_TYPE_F16:
1248        case GGML_TYPE_BF16:
1249        case GGML_TYPE_Q1_0:
1250        case GGML_TYPE_Q2_0:
1251        case GGML_TYPE_Q4_0:
1252        case GGML_TYPE_Q4_1:
1253        case GGML_TYPE_Q5_0:
1254        case GGML_TYPE_Q5_1:
1255        case GGML_TYPE_Q8_0:
1256        case GGML_TYPE_Q8_1:
1257        case GGML_TYPE_MXFP4:
1258        case GGML_TYPE_NVFP4:
1259        case GGML_TYPE_Q2_K:
1260        case GGML_TYPE_Q3_K:
1261        case GGML_TYPE_Q4_K:
1262        case GGML_TYPE_Q5_K:
1263        case GGML_TYPE_Q6_K:
1264        case GGML_TYPE_TQ1_0:
1265        case GGML_TYPE_TQ2_0:
1266        case GGML_TYPE_IQ2_XXS:
1267        case GGML_TYPE_IQ2_XS:
1268        case GGML_TYPE_IQ3_XXS:
1269        case GGML_TYPE_IQ1_S:
1270        case GGML_TYPE_IQ1_M:
1271        case GGML_TYPE_IQ4_NL:
1272        case GGML_TYPE_IQ4_XS:
1273        case GGML_TYPE_IQ3_S:
1274        case GGML_TYPE_IQ2_S:
1275        default:
1276            {
1277                GGML_ABORT("fatal error");
1278            }
1279    }
1280}
1281
1282// ggml_compute_forward_sum
1283
1284static void ggml_compute_forward_sum_f32(
1285        const ggml_compute_params * params,
1286        ggml_tensor * dst) {
1287
1288    const ggml_tensor * src0 = dst->src[0];
1289
1290    if (params->ith != 0) {
1291        return;
1292    }
1293
1294    assert(ggml_is_scalar(dst));
1295    assert(src0->nb[0] == sizeof(float));
1296
1297    GGML_TENSOR_LOCALS(int64_t, ne0, src0, ne)
1298    GGML_TENSOR_LOCALS(size_t,  nb0, src0, nb)
1299
1300    ggml_float sum     = 0;
1301    ggml_float row_sum = 0;
1302
1303    for (int64_t i03 = 0; i03 < ne03; i03++) {
1304        for (int64_t i02 = 0; i02 < ne02; i02++) {
1305            for (int64_t i01 = 0; i01 < ne01; i01++) {
1306                ggml_vec_sum_f32_ggf(ne00,
1307                        &row_sum,
1308                        (float *) ((char *) src0->data + i01*nb01 + i02*nb02 + i03*nb03));
1309                sum += row_sum;
1310            }
1311        }
1312    }
1313    ((float *) dst->data)[0] = sum;
1314}
1315
1316static void ggml_compute_forward_sum_f16(
1317    const ggml_compute_params * params,
1318          ggml_tensor * dst) {
1319
1320    const ggml_tensor * src0 = dst->src[0];
1321
1322    if (params->ith != 0) {
1323        return;
1324    }
1325
1326    assert(ggml_is_scalar(dst));
1327
1328    assert(src0->nb[0] == sizeof(ggml_fp16_t));
1329
1330    GGML_TENSOR_LOCALS(int64_t, ne0, src0, ne)
1331    GGML_TENSOR_LOCALS(size_t,  nb0, src0, nb)
1332
1333    float sum = 0;
1334    float row_sum = 0;
1335
1336    for (int64_t i03 = 0; i03 < ne03; i03++) {
1337        for (int64_t i02 = 0; i02 < ne02; i02++) {
1338            for (int64_t i01 = 0; i01 < ne01; i01++) {
1339                ggml_vec_sum_f16_ggf(ne00,
1340                    &row_sum,
1341                    (ggml_fp16_t *) ((char *) src0->data + i01 * nb01 + i02 * nb02 + i03 * nb03));
1342                sum += row_sum;
1343            }
1344        }
1345    }
1346    ((ggml_fp16_t *) dst->data)[0] = GGML_CPU_FP32_TO_FP16(sum);
1347}
1348
1349static void ggml_compute_forward_sum_bf16(
1350    const ggml_compute_params * params,
1351          ggml_tensor * dst) {
1352
1353    const ggml_tensor * src0 = dst->src[0];
1354
1355    if (params->ith != 0) {
1356        return;
1357    }
1358
1359    assert(ggml_is_scalar(dst));
1360
1361    assert(src0->nb[0] == sizeof(ggml_bf16_t));
1362
1363    GGML_TENSOR_LOCALS(int64_t, ne0, src0, ne)
1364    GGML_TENSOR_LOCALS(size_t,  nb0, src0, nb)
1365
1366    float sum = 0;
1367    float row_sum = 0;
1368
1369    for (int64_t i03 = 0; i03 < ne03; i03++) {
1370        for (int64_t i02 = 0; i02 < ne02; i02++) {
1371            for (int64_t i01 = 0; i01 < ne01; i01++) {
1372                ggml_vec_sum_bf16_ggf(ne00,
1373                    &row_sum,
1374                    (ggml_bf16_t *) ((char *) src0->data + i01 * nb01 + i02 * nb02 + i03 * nb03));
1375                sum += row_sum;
1376            }
1377        }
1378    }
1379    ((ggml_bf16_t *) dst->data)[0] = GGML_FP32_TO_BF16(sum);
1380}
1381
1382void ggml_compute_forward_sum(
1383        const ggml_compute_params * params,
1384        ggml_tensor * dst) {
1385
1386    const ggml_tensor * src0 = dst->src[0];
1387
1388    switch (src0->type) {
1389        case GGML_TYPE_F32:
1390            {
1391                ggml_compute_forward_sum_f32(params, dst);
1392            } break;
1393        case GGML_TYPE_F16:
1394            {
1395                ggml_compute_forward_sum_f16(params, dst);
1396            } break;
1397        case GGML_TYPE_BF16:
1398            {
1399                ggml_compute_forward_sum_bf16(params, dst);
1400            } break;
1401        default:
1402            {
1403                GGML_ABORT("fatal error");
1404            }
1405    }
1406}
1407
1408// ggml_compute_forward_cumsum
1409
1410static void ggml_compute_forward_cumsum_f32(
1411        const ggml_compute_params * params,
1412        ggml_tensor * dst) {
1413
1414    const ggml_tensor * src0 = dst->src[0];
1415
1416    GGML_ASSERT(src0->nb[0] == sizeof(float));
1417    GGML_ASSERT(dst->nb[0] == sizeof(float));
1418
1419    GGML_TENSOR_UNARY_OP_LOCALS
1420
1421    GGML_ASSERT(ne0 == ne00);
1422    GGML_ASSERT(ne1 == ne01);
1423    GGML_ASSERT(ne2 == ne02);
1424    GGML_ASSERT(ne3 == ne03);
1425
1426    const auto [ir0, ir1] = get_thread_range(params, src0);
1427
1428    for (int64_t ir = ir0; ir < ir1; ++ir) {
1429        const int64_t i03 = ir/(ne02*ne01);
1430        const int64_t i02 = (ir - i03*ne02*ne01)/ne01;
1431        const int64_t i01 = (ir - i03*ne02*ne01 - i02*ne01);
1432
1433        float * src_row = (float *) ((char *) src0->data + i01*nb01 + i02*nb02 + i03*nb03);
1434        float * dst_row = (float *) ((char *) dst->data  + i01*nb1  + i02*nb2  + i03*nb3);
1435
1436        ggml_vec_cumsum_f32(ne00, dst_row, src_row);
1437    }
1438}
1439
1440void ggml_compute_forward_cumsum(
1441        const ggml_compute_params * params,
1442        ggml_tensor * dst) {
1443
1444    const ggml_tensor * src0 = dst->src[0];
1445
1446    switch (src0->type) {
1447        case GGML_TYPE_F32:
1448            {
1449                ggml_compute_forward_cumsum_f32(params, dst);
1450            } break;
1451        default:
1452            {
1453                GGML_ABORT("fatal error");
1454            }
1455    }
1456}
1457
1458// ggml_compute_forward_sum_rows
1459
1460static void ggml_compute_forward_sum_rows_f32(
1461        const ggml_compute_params * params,
1462        ggml_tensor * dst) {
1463
1464    const ggml_tensor * src0 = dst->src[0];
1465
1466    if (params->ith != 0) {
1467        return;
1468    }
1469
1470    GGML_ASSERT(src0->nb[0] == sizeof(float));
1471    GGML_ASSERT(dst->nb[0] == sizeof(float));
1472
1473    GGML_TENSOR_UNARY_OP_LOCALS
1474
1475    GGML_ASSERT(ne0 == 1);
1476    GGML_ASSERT(ne1 == ne01);
1477    GGML_ASSERT(ne2 == ne02);
1478    GGML_ASSERT(ne3 == ne03);
1479
1480    for (int64_t i3 = 0; i3 < ne03; i3++) {
1481        for (int64_t i2 = 0; i2 < ne02; i2++) {
1482            for (int64_t i1 = 0; i1 < ne01; i1++) {
1483                float * src_row = (float *) ((char *) src0->data + i1*nb01 + i2*nb02 + i3*nb03);
1484                float * dst_row = (float *) ((char *) dst->data  + i1*nb1  + i2*nb2  + i3*nb3);
1485                float row_sum = 0;
1486                ggml_vec_sum_f32(ne00, &row_sum, src_row);
1487                dst_row[0] = row_sum;
1488            }
1489        }
1490    }
1491}
1492
1493void ggml_compute_forward_sum_rows(
1494        const ggml_compute_params * params,
1495        ggml_tensor * dst) {
1496
1497    const ggml_tensor * src0 = dst->src[0];
1498
1499    switch (src0->type) {
1500        case GGML_TYPE_F32:
1501            {
1502                ggml_compute_forward_sum_rows_f32(params, dst);
1503            } break;
1504        default:
1505            {
1506                GGML_ABORT("fatal error");
1507            }
1508    }
1509}
1510
1511// ggml_compute_forward_mean
1512
1513static void ggml_compute_forward_mean_f32(
1514        const ggml_compute_params * params,
1515        ggml_tensor * dst) {
1516
1517    const ggml_tensor * src0 = dst->src[0];
1518
1519    if (params->ith != 0) {
1520        return;
1521    }
1522
1523    assert(src0->nb[0] == sizeof(float));
1524
1525    GGML_TENSOR_UNARY_OP_LOCALS
1526
1527    assert(ne0 == 1);
1528    assert(ne1 == ne01);
1529    assert(ne2 == ne02);
1530    assert(ne3 == ne03);
1531
1532    GGML_UNUSED(ne0);
1533    GGML_UNUSED(ne1);
1534    GGML_UNUSED(ne2);
1535    GGML_UNUSED(ne3);
1536
1537    for (int64_t i03 = 0; i03 < ne03; i03++) {
1538        for (int64_t i02 = 0; i02 < ne02; i02++) {
1539            for (int64_t i01 = 0; i01 < ne01; i01++) {
1540                ggml_vec_sum_f32(ne00,
1541                        (float *) ((char *)  dst->data + i01*nb1  + i02*nb2  + i03*nb3),
1542                        (float *) ((char *) src0->data + i01*nb01 + i02*nb02 + i03*nb03));
1543
1544                *(float *) ((char *) dst->data + i01*nb1 + i02*nb2 + i03*nb3) /= (float) ne00;
1545            }
1546        }
1547    }
1548}
1549
1550void ggml_compute_forward_mean(
1551        const ggml_compute_params * params,
1552        ggml_tensor * dst) {
1553
1554    const ggml_tensor * src0 = dst->src[0];
1555
1556    switch (src0->type) {
1557        case GGML_TYPE_F32:
1558            {
1559                ggml_compute_forward_mean_f32(params, dst);
1560            } break;
1561        default:
1562            {
1563                GGML_ABORT("fatal error");
1564            }
1565    }
1566}
1567
1568// ggml_compute_forward_argmax
1569
1570static void ggml_compute_forward_argmax_f32(
1571        const ggml_compute_params * params,
1572        ggml_tensor * dst) {
1573
1574    const ggml_tensor * src0 = dst->src[0];
1575
1576    if (params->ith != 0) {
1577        return;
1578    }
1579
1580    assert(src0->nb[0] == sizeof(float));
1581    assert(dst->nb[0] == sizeof(float));
1582
1583    const int64_t ne00 = src0->ne[0];
1584    const int64_t ne01 = src0->ne[1];
1585
1586    const size_t nb01 = src0->nb[1];
1587    const size_t nb0 = dst->nb[0];
1588
1589    for (int64_t i1 = 0; i1 < ne01; i1++) {
1590        float * src = (float *) ((char *) src0->data + i1*nb01);
1591        int32_t * dst_ = (int32_t *) ((char *)  dst->data + i1*nb0);
1592        int v = 0;
1593        ggml_vec_argmax_f32(ne00, &v, src);
1594        dst_[0] = v;
1595    }
1596}
1597
1598void ggml_compute_forward_argmax(
1599        const ggml_compute_params * params,
1600        ggml_tensor * dst) {
1601
1602    const ggml_tensor * src0 = dst->src[0];
1603
1604    switch (src0->type) {
1605        case GGML_TYPE_F32:
1606            {
1607                ggml_compute_forward_argmax_f32(params, dst);
1608            } break;
1609        default:
1610            {
1611                GGML_ABORT("fatal error");
1612            }
1613    }
1614}
1615
1616// ggml_compute_forward_count_equal
1617
1618static void ggml_compute_forward_count_equal_i32(
1619        const ggml_compute_params * params,
1620        ggml_tensor * dst) {
1621
1622    const ggml_tensor * src0 = dst->src[0];
1623    const ggml_tensor * src1 = dst->src[1];
1624
1625    GGML_TENSOR_BINARY_OP_LOCALS;
1626
1627    GGML_ASSERT(src0->type == GGML_TYPE_I32);
1628    GGML_ASSERT(src1->type == GGML_TYPE_I32);
1629    GGML_ASSERT(ggml_are_same_shape(src0, src1));
1630    GGML_ASSERT(ggml_is_scalar(dst));
1631    GGML_ASSERT(dst->type == GGML_TYPE_I64);
1632
1633    const int64_t nr = ggml_nrows(src0);
1634
1635    const int ith = params->ith;
1636    const int nth = params->nth;
1637
1638    int64_t * sums = (int64_t *) params->wdata;
1639    int64_t sum_thread = 0;
1640
1641    // rows per thread
1642    const int64_t dr = (nr + nth - 1)/nth;
1643
1644    // row range for this thread
1645    const int64_t ir0 = dr*ith;
1646    const int64_t ir1 = MIN(ir0 + dr, nr);
1647
1648    for (int64_t ir = ir0; ir < ir1; ++ir) {
1649        const int64_t i03 =  ir                        / (ne02*ne01);
1650        const int64_t i02 = (ir - i03*ne03)            /       ne01;
1651        const int64_t i01 =  ir - i03*ne03 - i02*ne02;
1652
1653        const char * data0 = (const char *) src0->data + i03*nb03 + i02*nb02 + i01*nb01;
1654        const char * data1 = (const char *) src1->data + i03*nb13 + i02*nb12 + i01*nb11;
1655
1656        for (int64_t i00 = 0; i00 < ne00; ++i00) {
1657            const int32_t val0 = *((const int32_t *) (data0 + i00*nb00));
1658            const int32_t val1 = *((const int32_t *) (data1 + i00*nb10));
1659
1660            sum_thread += val0 == val1;
1661        }
1662    }
1663    if (ith != 0) {
1664        sums[ith] = sum_thread;
1665    }
1666    ggml_barrier(params->threadpool);
1667
1668    if (ith != 0) {
1669        return;
1670    }
1671
1672    for (int ith_other = 1; ith_other < nth; ++ith_other) {
1673        sum_thread += sums[ith_other];
1674    }
1675    *((int64_t *) dst->data) = sum_thread;
1676}
1677
1678void ggml_compute_forward_count_equal(
1679        const ggml_compute_params * params,
1680        ggml_tensor * dst) {
1681
1682    const ggml_tensor * src0 = dst->src[0];
1683
1684    switch (src0->type) {
1685        case GGML_TYPE_I32:
1686            {
1687                ggml_compute_forward_count_equal_i32(params, dst);
1688            } break;
1689        default:
1690            {
1691                GGML_ABORT("fatal error");
1692            }
1693    }
1694}
1695
1696// ggml_compute_forward_repeat
1697
1698static void ggml_compute_forward_repeat_f32(
1699        const ggml_compute_params * params,
1700        ggml_tensor * dst) {
1701
1702    const ggml_tensor * src0 = dst->src[0];
1703
1704    if (params->ith != 0) {
1705        return;
1706    }
1707
1708    GGML_ASSERT(ggml_can_repeat(src0, dst));
1709
1710    GGML_TENSOR_UNARY_OP_LOCALS
1711
1712    // guaranteed to be an integer due to the check in ggml_can_repeat
1713    const int nr0 = (int)(ne0/ne00);
1714    const int nr1 = (int)(ne1/ne01);
1715    const int nr2 = (int)(ne2/ne02);
1716    const int nr3 = (int)(ne3/ne03);
1717
1718    // TODO: support for transposed / permuted tensors
1719    GGML_ASSERT(nb0  == sizeof(float));
1720    GGML_ASSERT(nb00 == sizeof(float));
1721
1722    // TODO: maybe this is not optimal?
1723    for                         (int i3 = 0; i3 < nr3;  i3++) {
1724        for                     (int k3 = 0; k3 < ne03; k3++) {
1725            for                 (int i2 = 0; i2 < nr2;  i2++) {
1726                for             (int k2 = 0; k2 < ne02; k2++) {
1727                    for         (int i1 = 0; i1 < nr1;  i1++) {
1728                        for     (int k1 = 0; k1 < ne01; k1++) {
1729                            for (int i0 = 0; i0 < nr0;  i0++) {
1730                                ggml_vec_cpy_f32(ne00,
1731                                        (float *) ((char *)  dst->data + (i3*ne03 + k3)*nb3  + (i2*ne02 + k2)*nb2  + (i1*ne01 + k1)*nb1  + (i0*ne00)*nb0),
1732                                        (float *) ((char *) src0->data + (          k3)*nb03 + (          k2)*nb02 + (          k1)*nb01));
1733                            }
1734                        }
1735                    }
1736                }
1737            }
1738        }
1739    }
1740}
1741
1742static void ggml_compute_forward_repeat_f16(
1743        const ggml_compute_params * params,
1744        ggml_tensor * dst) {
1745
1746    const ggml_tensor * src0 = dst->src[0];
1747
1748    if (params->ith != 0) {
1749        return;
1750    }
1751
1752    GGML_ASSERT(ggml_can_repeat(src0, dst));
1753
1754    GGML_TENSOR_UNARY_OP_LOCALS
1755
1756    // guaranteed to be an integer due to the check in ggml_can_repeat
1757    const int nr0 = (int)(ne0/ne00);
1758    const int nr1 = (int)(ne1/ne01);
1759    const int nr2 = (int)(ne2/ne02);
1760    const int nr3 = (int)(ne3/ne03);
1761
1762    // TODO: support for transposed / permuted tensors
1763    GGML_ASSERT(nb0  == sizeof(ggml_fp16_t));
1764    GGML_ASSERT(nb00 == sizeof(ggml_fp16_t));
1765
1766    // TODO: maybe this is not optimal?
1767    for                         (int i3 = 0; i3 < nr3;  i3++) {
1768        for                     (int k3 = 0; k3 < ne03; k3++) {
1769            for                 (int i2 = 0; i2 < nr2;  i2++) {
1770                for             (int k2 = 0; k2 < ne02; k2++) {
1771                    for         (int i1 = 0; i1 < nr1;  i1++) {
1772                        for     (int k1 = 0; k1 < ne01; k1++) {
1773                            for (int i0 = 0; i0 < nr0;  i0++) {
1774                                ggml_fp16_t * y = (ggml_fp16_t *) ((char *)  dst->data + (i3*ne03 + k3)*nb3  + (i2*ne02 + k2)*nb2  + (i1*ne01 + k1)*nb1  + (i0*ne00)*nb0);
1775                                ggml_fp16_t * x = (ggml_fp16_t *) ((char *) src0->data + (          k3)*nb03 + (          k2)*nb02 + (          k1)*nb01);
1776                                // ggml_vec_cpy_f16(ne00, y, x)
1777                                for (int i = 0; i < ne00; ++i) {
1778                                    y[i]  = x[i];
1779                                }
1780                            }
1781                        }
1782                    }
1783                }
1784            }
1785        }
1786    }
1787}
1788
1789void ggml_compute_forward_repeat(
1790        const ggml_compute_params * params,
1791        ggml_tensor * dst) {
1792
1793    const ggml_tensor * src0 = dst->src[0];
1794
1795    switch (src0->type) {
1796        case GGML_TYPE_F16:
1797        case GGML_TYPE_BF16:
1798        case GGML_TYPE_I16:
1799            {
1800                ggml_compute_forward_repeat_f16(params, dst);
1801            } break;
1802        case GGML_TYPE_F32:
1803        case GGML_TYPE_I32:
1804            {
1805                ggml_compute_forward_repeat_f32(params, dst);
1806            } break;
1807        // TODO: templateify the implementation and support for I64
1808        //       ref https://github.com/ggml-org/llama.cpp/pull/14274#discussion_r2169492225
1809        //case GGML_TYPE_I64:
1810        //    {
1811        //        ggml_compute_forward_repeat_i64(params, dst);
1812        //    } break;
1813        default:
1814            {
1815                GGML_ABORT("fatal error");
1816            }
1817    }
1818}
1819
1820// ggml_compute_forward_repeat_back
1821
1822static void ggml_compute_forward_repeat_back_f32(
1823        const ggml_compute_params * params,
1824        ggml_tensor * dst) {
1825
1826    const ggml_tensor * src0 = dst->src[0];
1827
1828    if (params->ith != 0) {
1829        return;
1830    }
1831
1832    GGML_ASSERT(ggml_can_repeat(dst, src0));
1833
1834    GGML_TENSOR_UNARY_OP_LOCALS
1835
1836    // guaranteed to be an integer due to the check in ggml_can_repeat
1837    const int nr0 = (int)(ne00/ne0);
1838    const int nr1 = (int)(ne01/ne1);
1839    const int nr2 = (int)(ne02/ne2);
1840    const int nr3 = (int)(ne03/ne3);
1841
1842    // TODO: support for transposed / permuted tensors
1843    GGML_ASSERT(nb0  == sizeof(float));
1844    GGML_ASSERT(nb00 == sizeof(float));
1845
1846    if (ggml_is_contiguous(dst)) {
1847        ggml_vec_set_f32(ne0*ne1*ne2*ne3, (float *)dst->data, 0);
1848    } else {
1849        for         (int k3 = 0; k3 < ne3; k3++) {
1850            for     (int k2 = 0; k2 < ne2; k2++) {
1851                for (int k1 = 0; k1 < ne1; k1++) {
1852                    ggml_vec_set_f32(ne0,
1853                        (float *) ((char *) dst->data + k1*nb1 + k2*nb2 + k3*nb3),
1854                        0);
1855                }
1856            }
1857        }
1858    }
1859
1860    // TODO: maybe this is not optimal?
1861    for                         (int i3 = 0; i3 < nr3; i3++) {
1862        for                     (int k3 = 0; k3 < ne3; k3++) {
1863            for                 (int i2 = 0; i2 < nr2; i2++) {
1864                for             (int k2 = 0; k2 < ne2; k2++) {
1865                    for         (int i1 = 0; i1 < nr1; i1++) {
1866                        for     (int k1 = 0; k1 < ne1; k1++) {
1867                            for (int i0 = 0; i0 < nr0; i0++) {
1868                                ggml_vec_acc_f32(ne0,
1869                                        (float *) ((char *)  dst->data + (         k3)*nb3  + (         k2)*nb2  + (         k1)*nb1),
1870                                        (float *) ((char *) src0->data + (i3*ne3 + k3)*nb03 + (i2*ne2 + k2)*nb02 + (i1*ne1 + k1)*nb01 + (i0*ne0)*nb00));
1871                            }
1872                        }
1873                    }
1874                }
1875            }
1876        }
1877    }
1878}
1879
1880void ggml_compute_forward_repeat_back(
1881        const ggml_compute_params * params,
1882        ggml_tensor * dst) {
1883
1884    const ggml_tensor * src0 = dst->src[0];
1885
1886    switch (src0->type) {
1887        case GGML_TYPE_F32:
1888            {
1889                ggml_compute_forward_repeat_back_f32(params, dst);
1890            } break;
1891        default:
1892            {
1893                GGML_ABORT("fatal error");
1894            }
1895    }
1896}
1897
1898// ggml_compute_forward_concat
1899static void ggml_compute_forward_concat_any(
1900    const ggml_compute_params * params,
1901    ggml_tensor * dst) {
1902
1903    const ggml_tensor * src0 = dst->src[0];
1904    const ggml_tensor * src1 = dst->src[1];
1905
1906    const int ith = params->ith;
1907    const int nth = params->nth;
1908
1909    GGML_TENSOR_BINARY_OP_LOCALS
1910
1911    const int32_t dim = ggml_get_op_params_i32(dst, 0);
1912
1913    GGML_ASSERT(dim >= 0 && dim < 4);
1914    GGML_ASSERT(ggml_is_contiguous_rows(src0));
1915    GGML_ASSERT(ggml_is_contiguous_rows(src1));
1916
1917    int64_t o[4] = {0, 0, 0, 0};
1918
1919    if (dim == 0) {
1920        GGML_ASSERT(src0->ne[0] % ggml_blck_size(src0->type) == 0);
1921        GGML_ASSERT(src1->ne[0] % ggml_blck_size(src1->type) == 0);
1922
1923        o[dim] = src0->ne[dim]/ggml_blck_size(src0->type);
1924    } else {
1925        o[dim] = src0->ne[dim];
1926    }
1927
1928    // Region 1: copy rows from src0
1929    for (int i3 = 0; i3 < ne03; i3++) {
1930        for (int i2 = ith; i2 < ne02; i2 += nth) {
1931            for (int i1 = 0; i1 < ne01; i1++) {
1932                const char * x = (const char *) src0->data + i1*nb01 + i2*nb02 + i3*nb03;
1933                      char * y = (      char *) dst->data  + i1*nb1  + i2*nb2  + i3*nb3;
1934                memcpy(y, x, ggml_row_size(src0->type, ne00));
1935            }
1936        }
1937    }
1938
1939    // Region 2: copy rows from src1, offset into dst by o[]
1940    for (int i3 = 0; i3 < ne13; i3++) {
1941        for (int i2 = ith; i2 < ne12; i2 += nth) {
1942            for (int i1 = 0; i1 < ne11; i1++) {
1943                const char * x = (const char *) src1->data + i1*nb11         + i2*nb12         + i3*nb13;
1944                      char * y = (      char *)  dst->data + (i1 + o[1])*nb1 + (i2 + o[2])*nb2 + (i3 + o[3])*nb3 + o[0]*nb0;
1945                memcpy(y, x, ggml_row_size(src1->type, ne10));
1946            }
1947        }
1948    }
1949}
1950
1951static void ggml_compute_forward_concat_i8(
1952    const ggml_compute_params * params,
1953    ggml_tensor * dst) {
1954
1955    const ggml_tensor * src0 = dst->src[0];
1956    const ggml_tensor * src1 = dst->src[1];
1957
1958    GGML_ASSERT(ggml_type_size(src0->type) == sizeof(int8_t));
1959
1960    const int ith = params->ith;
1961    const int nth = params->nth;
1962
1963    GGML_TENSOR_BINARY_OP_LOCALS
1964
1965    const int32_t dim = ggml_get_op_params_i32(dst, 0);
1966
1967    GGML_ASSERT(dim >= 0 && dim < 4);
1968
1969    int64_t o[4] = {0, 0, 0, 0};
1970    o[dim] = src0->ne[dim];
1971
1972    const int8_t * x;
1973
1974    // TODO: smarter multi-theading
1975    for (int i3 = 0; i3 < ne3; i3++) {
1976        for (int i2 = ith; i2 < ne2; i2 += nth) {
1977            for (int i1 = 0; i1 < ne1; i1++) {
1978                for (int i0 = 0; i0 < ne0; i0++) {
1979                    if (i0 < ne00 && i1 < ne01 && i2 < ne02 && i3 < ne03) {
1980                        x = (const int8_t *) ((const char *)src0->data + (i0       )*nb00 + (i1       )*nb01 + (i2       )*nb02 + (i3       )*nb03);
1981                    } else {
1982                        x = (const int8_t *) ((const char *)src1->data + (i0 - o[0])*nb10 + (i1 - o[1])*nb11 + (i2 - o[2])*nb12 + (i3 - o[3])*nb13);
1983                    }
1984
1985                    int8_t * y = (int8_t *)((char *)dst->data + i0*nb0 + i1*nb1 + i2*nb2 + i3*nb3);
1986
1987                    *y = *x;
1988                }
1989            }
1990        }
1991    }
1992}
1993
1994static void ggml_compute_forward_concat_f16(
1995    const ggml_compute_params * params,
1996    ggml_tensor * dst) {
1997
1998    const ggml_tensor * src0 = dst->src[0];
1999    const ggml_tensor * src1 = dst->src[1];
2000
2001    GGML_ASSERT(ggml_type_size(src0->type) == sizeof(ggml_fp16_t));
2002
2003    const int ith = params->ith;
2004    const int nth = params->nth;
2005
2006    GGML_TENSOR_BINARY_OP_LOCALS
2007
2008    const int32_t dim = ggml_get_op_params_i32(dst, 0);
2009
2010    GGML_ASSERT(dim >= 0 && dim < 4);
2011
2012    int64_t o[4] = {0, 0, 0, 0};
2013    o[dim] = src0->ne[dim];
2014
2015    const ggml_fp16_t * x;
2016
2017    // TODO: smarter multi-theading
2018    for (int i3 = 0; i3 < ne3; i3++) {
2019        for (int i2 = ith; i2 < ne2; i2 += nth) {
2020            for (int i1 = 0; i1 < ne1; i1++) {
2021                for (int i0 = 0; i0 < ne0; i0++) {
2022                    if (i0 < ne00 && i1 < ne01 && i2 < ne02 && i3 < ne03) {
2023                        x = (const ggml_fp16_t *) ((const char *)src0->data + (i0       )*nb00 + (i1       )*nb01 + (i2       )*nb02 + (i3       )*nb03);
2024                    } else {
2025                        x = (const ggml_fp16_t *) ((const char *)src1->data + (i0 - o[0])*nb10 + (i1 - o[1])*nb11 + (i2 - o[2])*nb12 + (i3 - o[3])*nb13);
2026                    }
2027
2028                    ggml_fp16_t * y = (ggml_fp16_t *)((char *)dst->data + i0*nb0 + i1*nb1 + i2*nb2 + i3*nb3);
2029
2030                    *y = *x;
2031                }
2032            }
2033        }
2034    }
2035}
2036
2037static void ggml_compute_forward_concat_f32(
2038    const ggml_compute_params * params,
2039    ggml_tensor * dst) {
2040
2041    const ggml_tensor * src0 = dst->src[0];
2042    const ggml_tensor * src1 = dst->src[1];
2043
2044    GGML_ASSERT(ggml_type_size(src0->type) == sizeof(float));
2045
2046    const int ith = params->ith;
2047    const int nth = params->nth;
2048
2049    GGML_TENSOR_BINARY_OP_LOCALS
2050
2051    const int32_t dim = ggml_get_op_params_i32(dst, 0);
2052
2053    GGML_ASSERT(dim >= 0 && dim < 4);
2054
2055    int64_t o[4] = {0, 0, 0, 0};
2056    o[dim] = src0->ne[dim];
2057
2058    const float * x;
2059
2060    // TODO: smarter multi-theading
2061    for (int i3 = 0; i3 < ne3; i3++) {
2062        for (int i2 = ith; i2 < ne2; i2 += nth) {
2063            for (int i1 = 0; i1 < ne1; i1++) {
2064                for (int i0 = 0; i0 < ne0; i0++) {
2065                    if (i0 < ne00 && i1 < ne01 && i2 < ne02 && i3 < ne03) {
2066                        x = (const float *) ((const char *)src0->data + (i0       )*nb00 + (i1       )*nb01 + (i2       )*nb02 + (i3       )*nb03);
2067                    } else {
2068                        x = (const float *) ((const char *)src1->data + (i0 - o[0])*nb10 + (i1 - o[1])*nb11 + (i2 - o[2])*nb12 + (i3 - o[3])*nb13);
2069                    }
2070
2071                    float * y = (float *)((char *)dst->data + i0*nb0 + i1*nb1 + i2*nb2 + i3*nb3);
2072
2073                    *y = *x;
2074                }
2075            }
2076        }
2077    }
2078}
2079
2080void ggml_compute_forward_concat(
2081    const ggml_compute_params * params,
2082    ggml_tensor * dst) {
2083
2084    const ggml_tensor * src0 = dst->src[0];
2085
2086    switch (src0->type) {
2087        case GGML_TYPE_F16:
2088        case GGML_TYPE_BF16:
2089        case GGML_TYPE_I16:
2090            {
2091                ggml_compute_forward_concat_f16(params, dst);
2092            } break;
2093        case GGML_TYPE_I8:
2094            {
2095                ggml_compute_forward_concat_i8(params, dst);
2096            } break;
2097        case GGML_TYPE_F32:
2098        case GGML_TYPE_I32:
2099            {
2100                ggml_compute_forward_concat_f32(params, dst);
2101            } break;
2102        default:
2103            {
2104                ggml_compute_forward_concat_any(params, dst);
2105            }
2106    }
2107}
2108
2109// ggml_compute_forward_gelu
2110
2111static void ggml_compute_forward_gelu_f32(
2112        const ggml_compute_params * params,
2113        ggml_tensor * dst) {
2114
2115    const ggml_tensor * src0 = dst->src[0];
2116
2117    assert(ggml_is_contiguous_rows(src0));
2118    assert(ggml_are_same_shape(src0, dst));
2119
2120    GGML_TENSOR_LOCALS(int64_t, ne0, src0, ne)
2121    GGML_TENSOR_LOCALS(size_t,  nb0, src0, nb)
2122    GGML_TENSOR_LOCALS(int64_t, ne,  dst,  ne)
2123    GGML_TENSOR_LOCALS(size_t,  nb,  dst,  nb)
2124
2125    const int ith = params->ith;
2126    const int nth = params->nth;
2127
2128    const int nc = src0->ne[0];
2129    const int nr = ggml_nrows(src0);
2130
2131    // rows per thread
2132    const int dr = (nr + nth - 1)/nth;
2133
2134    // row range for this thread
2135    const int ir0 = dr*ith;
2136    const int ir1 = MIN(ir0 + dr, nr);
2137
2138    for (int ir = ir0; ir < ir1; ++ir) {
2139        const int i3 = ir/(ne02*ne01);
2140        const int i2 = (ir - i3*ne02*ne01)/ne01;
2141        const int i1 = (ir - i3*ne02*ne01 - i2*ne01);
2142
2143        ggml_vec_gelu_f32(nc,
2144                (float *) ((char *) dst->data  + i3*nb3  + i2*nb2  + i1*nb1),
2145                (float *) ((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01));
2146
2147#ifndef NDEBUG
2148        for (int k = 0; k < nc; k++) {
2149            const float x = ((float *) ((char *) dst->data + i3*nb3 + i2*nb2 + i1*(dst->nb[1])))[k];
2150            GGML_UNUSED(x);
2151            assert(!isnan(x));
2152            assert(!isinf(x));
2153        }
2154#endif // NDEBUG
2155    }
2156}
2157
2158static void ggml_compute_forward_gelu_f16(
2159    const ggml_compute_params * params,
2160    ggml_tensor * dst) {
2161
2162    const ggml_tensor * src0 = dst->src[0];
2163
2164    assert(ggml_is_contiguous_rows(src0));
2165    assert(ggml_are_same_shape(src0, dst));
2166
2167    GGML_TENSOR_LOCALS(int64_t, ne0, src0, ne)
2168    GGML_TENSOR_LOCALS(size_t,  nb0, src0, nb)
2169    GGML_TENSOR_LOCALS(int64_t, ne,  dst,  ne)
2170    GGML_TENSOR_LOCALS(size_t,  nb,  dst,  nb)
2171
2172    const int ith = params->ith;
2173    const int nth = params->nth;
2174
2175    const int nc = src0->ne[0];
2176    const int nr = ggml_nrows(src0);
2177
2178    // rows per thread
2179    const int dr = (nr + nth - 1)/nth;
2180
2181    // row range for this thread
2182    const int ir0 = dr*ith;
2183    const int ir1 = MIN(ir0 + dr, nr);
2184
2185    for (int ir = ir0; ir < ir1; ++ir) {
2186        const int i3 = ir/(ne02*ne01);
2187        const int i2 = (ir - i3*ne02*ne01)/ne01;
2188        const int i1 = (ir - i3*ne02*ne01 - i2*ne01);
2189
2190        ggml_vec_gelu_f16(nc,
2191                (ggml_fp16_t *) ((char *) dst->data  + i3*nb3  + i2*nb2  + i1*nb1),
2192                (ggml_fp16_t *) ((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01));
2193
2194#ifndef NDEBUG
2195        for (int k = 0; k < nc; k++) {
2196            const ggml_fp16_t x = ((ggml_fp16_t *) ((char *) dst->data + i3*nb3 + i2*nb2 + i1*( dst->nb[1])))[k];
2197            const float v = GGML_CPU_FP16_TO_FP32(x);
2198            GGML_UNUSED(v);
2199            assert(!isnan(v));
2200            assert(!isinf(v));
2201        }
2202#endif // NDEBUG
2203    }
2204}
2205
2206static void ggml_compute_forward_gelu(
2207        const ggml_compute_params * params,
2208        ggml_tensor * dst) {
2209
2210    const ggml_tensor * src0 = dst->src[0];
2211
2212    switch (src0->type) {
2213        case GGML_TYPE_F32:
2214            {
2215                ggml_compute_forward_gelu_f32(params, dst);
2216            } break;
2217        case GGML_TYPE_F16:
2218            {
2219                ggml_compute_forward_gelu_f16(params, dst);
2220            } break;
2221        default:
2222            {
2223                GGML_ABORT("fatal error");
2224            }
2225    }
2226}
2227
2228// ggml_compute_fill
2229
2230static void ggml_compute_forward_fill_f32(const ggml_compute_params * params, ggml_tensor * dst) {
2231    const float c = ggml_get_op_params_f32(dst, 0);
2232
2233    GGML_TENSOR_LOCALS(int64_t, ne, dst, ne);
2234    GGML_TENSOR_LOCALS(size_t,  nb, dst, nb);
2235
2236    const auto [ir0, ir1] = get_thread_range(params, dst);
2237
2238    for (int64_t ir = ir0; ir < ir1; ++ir) {
2239        const int64_t i03 = ir/(ne2*ne1);
2240        const int64_t i02 = (ir - i03*ne2*ne1)/ne1;
2241        const int64_t i01 = (ir - i03*ne2*ne1 - i02*ne1);
2242
2243        float * dst_ptr  = (float *) ((char *) dst->data + i03*nb3 + i02*nb2 + i01*nb1);
2244
2245        ggml_vec_set_f32(ne0, dst_ptr, c);
2246    }
2247}
2248
2249static void ggml_compute_forward_fill_f16(const ggml_compute_params * params, ggml_tensor * dst) {
2250    const ggml_fp16_t c = GGML_CPU_FP32_TO_FP16(ggml_get_op_params_f32(dst, 0));
2251
2252    GGML_TENSOR_LOCALS(int64_t, ne, dst, ne);
2253    GGML_TENSOR_LOCALS(size_t,  nb, dst, nb);
2254
2255    const auto [ir0, ir1] = get_thread_range(params, dst);
2256
2257    for (int64_t ir = ir0; ir < ir1; ++ir) {
2258        const int64_t i03 = ir/(ne2*ne1);
2259        const int64_t i02 = (ir - i03*ne2*ne1)/ne1;
2260        const int64_t i01 = (ir - i03*ne2*ne1 - i02*ne1);
2261
2262        ggml_fp16_t * dst_ptr  = (ggml_fp16_t *) ((char *) dst->data + i03*nb3 + i02*nb2 + i01*nb1);
2263
2264        ggml_vec_set_f16(ne0, dst_ptr, c);
2265    }
2266}
2267
2268void ggml_compute_forward_fill(const ggml_compute_params * params, ggml_tensor * dst) {
2269    const ggml_tensor * src0 = dst->src[0];
2270
2271    switch (src0->type) {
2272        case GGML_TYPE_F32:
2273            {
2274                ggml_compute_forward_fill_f32(params, dst);
2275            } break;
2276        case GGML_TYPE_F16:
2277            {
2278                ggml_compute_forward_fill_f16(params, dst);
2279            } break;
2280        default:
2281            {
2282                GGML_ABORT("unsupported type for ggml_compute_forward_fill: %s", ggml_type_name(src0->type));
2283            }
2284    }
2285}
2286
2287// ggml_compute_tri
2288
2289static void ggml_compute_forward_tri_f32(const ggml_compute_params * params, ggml_tensor * dst) {
2290    const ggml_tensor * src0 = dst->src[0];
2291
2292    const ggml_tri_type ttype = (ggml_tri_type) ggml_get_op_params_i32(dst, 0);
2293
2294    GGML_ASSERT(ggml_is_contiguous(src0));
2295
2296    GGML_TENSOR_UNARY_OP_LOCALS
2297
2298    const auto [ir0, ir1] = get_thread_range(params, src0);
2299
2300    bool (*bipred)(int, int);
2301
2302    switch (ttype) {
2303        case GGML_TRI_TYPE_LOWER:      bipred = [](int i, int r) { return i <  r; }; break;
2304        case GGML_TRI_TYPE_LOWER_DIAG: bipred = [](int i, int r) { return i <= r; }; break;
2305        case GGML_TRI_TYPE_UPPER:      bipred = [](int i, int r) { return i >  r; }; break;
2306        case GGML_TRI_TYPE_UPPER_DIAG: bipred = [](int i, int r) { return i >= r; }; break;
2307        default: GGML_ABORT("invalid tri type");
2308    }
2309
2310    for (int64_t ir = ir0; ir < ir1; ++ir) {
2311        const int64_t i03 = ir/(ne02*ne01);
2312        const int64_t i02 = (ir - i03*ne02*ne01)/ne01;
2313        const int64_t i01 = (ir - i03*ne02*ne01 - i02*ne01);
2314
2315        const float * src_ptr = (const float  *) ((const char *) src0->data + i03*nb03 + i02*nb02 + i01*nb01);
2316              float * dst_ptr = (      float  *) ((      char *) dst->data  + i03*nb3  + i02*nb2  + i01*nb1);
2317
2318        for (int i0 = 0; i0 < ne0; ++i0) {
2319            dst_ptr[i0] = bipred(i0, i01) ? src_ptr[i0] : 0.0f;
2320        }
2321    }
2322}
2323
2324void ggml_compute_forward_tri(const ggml_compute_params * params, ggml_tensor * dst) {
2325    const ggml_tensor * src0 = dst->src[0];
2326
2327    switch (src0->type) {
2328        case GGML_TYPE_F32:
2329            {
2330                ggml_compute_forward_tri_f32(params, dst);
2331            } break;
2332        default:
2333            {
2334                GGML_ABORT("fatal error");
2335            }
2336    }
2337}
2338
2339// ggml_compute_forward_gelu_erf
2340
2341static void ggml_compute_forward_gelu_erf_f32(
2342        const ggml_compute_params * params,
2343        ggml_tensor * dst) {
2344
2345    const ggml_tensor * src0 = dst->src[0];
2346
2347    assert(ggml_is_contiguous_rows(src0));
2348    assert(ggml_are_same_shape(src0, dst));
2349
2350    GGML_TENSOR_LOCALS(int64_t, ne0, src0, ne)
2351    GGML_TENSOR_LOCALS(size_t,  nb0, src0, nb)
2352    GGML_TENSOR_LOCALS(int64_t, ne,  dst,  ne)
2353    GGML_TENSOR_LOCALS(size_t,  nb,  dst,  nb)
2354
2355    const int ith = params->ith;
2356    const int nth = params->nth;
2357
2358    const int nc = src0->ne[0];
2359    const int nr = ggml_nrows(src0);
2360
2361    // rows per thread
2362    const int dr = (nr + nth - 1)/nth;
2363
2364    // row range for this thread
2365    const int ir0 = dr*ith;
2366    const int ir1 = MIN(ir0 + dr, nr);
2367
2368    for (int ir = ir0; ir < ir1; ++ir) {
2369        const int i3 = ir/(ne02*ne01);
2370        const int i2 = (ir - i3*ne02*ne01)/ne01;
2371        const int i1 = (ir - i3*ne02*ne01 - i2*ne01);
2372
2373        ggml_vec_gelu_erf_f32(nc,
2374                (float *) ((char *) dst->data  + i3*nb3  + i2*nb2  + i1*nb1),
2375                (float *) ((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01));
2376
2377#ifndef NDEBUG
2378        for (int k = 0; k < nc; k++) {
2379            const float x = ((float *) ((char *) dst->data + i3*nb3 + i2*nb2 + i1*(dst->nb[1])))[k];
2380            GGML_UNUSED(x);
2381            assert(!isnan(x));
2382            assert(!isinf(x));
2383        }
2384#endif // NDEBUG
2385    }
2386}
2387
2388static void ggml_compute_forward_gelu_erf_f16(
2389    const ggml_compute_params * params,
2390    ggml_tensor * dst) {
2391
2392    const ggml_tensor * src0 = dst->src[0];
2393
2394    assert(ggml_is_contiguous_rows(src0));
2395    assert(ggml_are_same_shape(src0, dst));
2396
2397    GGML_TENSOR_LOCALS(int64_t, ne0, src0, ne)
2398    GGML_TENSOR_LOCALS(size_t,  nb0, src0, nb)
2399    GGML_TENSOR_LOCALS(int64_t, ne,  dst,  ne)
2400    GGML_TENSOR_LOCALS(size_t,  nb,  dst,  nb)
2401
2402    const int ith = params->ith;
2403    const int nth = params->nth;
2404
2405    const int nc = src0->ne[0];
2406    const int nr = ggml_nrows(src0);
2407
2408    // rows per thread
2409    const int dr = (nr + nth - 1)/nth;
2410
2411    // row range for this thread
2412    const int ir0 = dr*ith;
2413    const int ir1 = MIN(ir0 + dr, nr);
2414
2415    for (int ir = ir0; ir < ir1; ++ir) {
2416        const int i3 = ir/(ne02*ne01);
2417        const int i2 = (ir - i3*ne02*ne01)/ne01;
2418        const int i1 = (ir - i3*ne02*ne01 - i2*ne01);
2419
2420        ggml_vec_gelu_erf_f16(nc,
2421                (ggml_fp16_t *) ((char *) dst->data  + i3*nb3  + i2*nb2  + i1*nb1),
2422                (ggml_fp16_t *) ((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01));
2423
2424#ifndef NDEBUG
2425        for (int k = 0; k < nc; k++) {
2426            const ggml_fp16_t x = ((ggml_fp16_t *) ((char *) dst->data + i3*nb3 + i2*nb2 + i1*( dst->nb[1])))[k];
2427            const float v = GGML_CPU_FP16_TO_FP32(x);
2428            GGML_UNUSED(v);
2429            assert(!isnan(v));
2430            assert(!isinf(v));
2431        }
2432#endif // NDEBUG
2433    }
2434}
2435
2436static void ggml_compute_forward_gelu_erf(
2437        const ggml_compute_params * params,
2438        ggml_tensor * dst) {
2439
2440    const ggml_tensor * src0 = dst->src[0];
2441
2442    switch (src0->type) {
2443        case GGML_TYPE_F32:
2444            {
2445                ggml_compute_forward_gelu_erf_f32(params, dst);
2446            } break;
2447        case GGML_TYPE_F16:
2448            {
2449                ggml_compute_forward_gelu_erf_f16(params, dst);
2450            } break;
2451        default:
2452            {
2453                GGML_ABORT("fatal error");
2454            }
2455    }
2456}
2457
2458// ggml_compute_forward_gelu_quick
2459
2460static void ggml_compute_forward_gelu_quick_f32(
2461        const ggml_compute_params * params,
2462        ggml_tensor * dst) {
2463
2464    const ggml_tensor * src0 = dst->src[0];
2465
2466    assert(ggml_is_contiguous_rows(src0));
2467    assert(ggml_are_same_shape(src0, dst));
2468
2469    GGML_TENSOR_LOCALS(int64_t, ne0, src0, ne)
2470    GGML_TENSOR_LOCALS(size_t,  nb0, src0, nb)
2471    GGML_TENSOR_LOCALS(int64_t, ne,  dst,  ne)
2472    GGML_TENSOR_LOCALS(size_t,  nb,  dst,  nb)
2473
2474    const int ith = params->ith;
2475    const int nth = params->nth;
2476
2477    const int nc = src0->ne[0];
2478    const int nr = ggml_nrows(src0);
2479
2480    // rows per thread
2481    const int dr = (nr + nth - 1)/nth;
2482
2483    // row range for this thread
2484    const int ir0 = dr*ith;
2485    const int ir1 = MIN(ir0 + dr, nr);
2486
2487    for (int ir = ir0; ir < ir1; ++ir) {
2488        const int i3 = ir/(ne02*ne01);
2489        const int i2 = (ir - i3*ne02*ne01)/ne01;
2490        const int i1 = (ir - i3*ne02*ne01 - i2*ne01);
2491
2492        ggml_vec_gelu_quick_f32(nc,
2493                (float *) ((char *) dst->data  + i3*nb3  + i2*nb2  + i1*nb1),
2494                (float *) ((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01));
2495
2496#ifndef NDEBUG
2497        for (int k = 0; k < nc; k++) {
2498            const float x = ((float *) ((char *) dst->data + i3*nb3 + i2*nb2 + i1*(dst->nb[1])))[k];
2499            GGML_UNUSED(x);
2500            assert(!isnan(x));
2501            assert(!isinf(x));
2502        }
2503#endif // NDEBUG
2504    }
2505}
2506
2507static void ggml_compute_forward_gelu_quick_f16(
2508    const ggml_compute_params * params,
2509    ggml_tensor * dst) {
2510
2511    const ggml_tensor * src0 = dst->src[0];
2512
2513    assert(ggml_is_contiguous_rows(src0));
2514    assert(ggml_are_same_shape(src0, dst));
2515
2516    GGML_TENSOR_LOCALS(int64_t, ne0, src0, ne)
2517    GGML_TENSOR_LOCALS(size_t,  nb0, src0, nb)
2518    GGML_TENSOR_LOCALS(int64_t, ne,  dst,  ne)
2519    GGML_TENSOR_LOCALS(size_t,  nb,  dst,  nb)
2520
2521    const int ith = params->ith;
2522    const int nth = params->nth;
2523
2524    const int nc = src0->ne[0];
2525    const int nr = ggml_nrows(src0);
2526
2527    // rows per thread
2528    const int dr = (nr + nth - 1)/nth;
2529
2530    // row range for this thread
2531    const int ir0 = dr*ith;
2532    const int ir1 = MIN(ir0 + dr, nr);
2533
2534    for (int ir = ir0; ir < ir1; ++ir) {
2535        const int i3 = ir/(ne02*ne01);
2536        const int i2 = (ir - i3*ne02*ne01)/ne01;
2537        const int i1 = (ir - i3*ne02*ne01 - i2*ne01);
2538
2539        ggml_vec_gelu_quick_f16(nc,
2540                (ggml_fp16_t *) ((char *) dst->data  + i3*nb3  + i2*nb2  + i1*nb1),
2541                (ggml_fp16_t *) ((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01));
2542
2543#ifndef NDEBUG
2544        for (int k = 0; k < nc; k++) {
2545            const ggml_fp16_t x = ((ggml_fp16_t *) ((char *) dst->data + i3*nb3 + i2*nb2 + i1*( dst->nb[1])))[k];
2546            const float v = GGML_CPU_FP16_TO_FP32(x);
2547            GGML_UNUSED(v);
2548            assert(!isnan(v));
2549            assert(!isinf(v));
2550        }
2551#endif // NDEBUG
2552    }
2553}
2554
2555static void ggml_compute_forward_gelu_quick(
2556        const ggml_compute_params * params,
2557        ggml_tensor * dst) {
2558
2559    const ggml_tensor * src0 = dst->src[0];
2560
2561    switch (src0->type) {
2562        case GGML_TYPE_F32:
2563            {
2564                ggml_compute_forward_gelu_quick_f32(params, dst);
2565            } break;
2566        case GGML_TYPE_F16:
2567            {
2568                ggml_compute_forward_gelu_quick_f16(params, dst);
2569            } break;
2570        default:
2571            {
2572                GGML_ABORT("fatal error");
2573            }
2574    }
2575}
2576
2577// ggml_compute_forward_silu
2578
2579static void ggml_compute_forward_silu_f32(
2580        const ggml_compute_params * params,
2581        ggml_tensor * dst) {
2582
2583    const ggml_tensor * src0 = dst->src[0];
2584
2585    assert(ggml_is_contiguous_rows(src0));
2586    assert(ggml_are_same_shape(src0, dst));
2587
2588    GGML_TENSOR_LOCALS(int64_t, ne0, src0, ne)
2589    GGML_TENSOR_LOCALS(size_t,  nb0, src0, nb)
2590    GGML_TENSOR_LOCALS(int64_t, ne,  dst,  ne)
2591    GGML_TENSOR_LOCALS(size_t,  nb,  dst,  nb)
2592
2593    const int ith = params->ith;
2594    const int nth = params->nth;
2595
2596    const int nc = src0->ne[0];
2597    const int nr = ggml_nrows(src0);
2598
2599    // rows per thread
2600    const int dr = (nr + nth - 1)/nth;
2601
2602    // row range for this thread
2603    const int ir0 = dr*ith;
2604    const int ir1 = MIN(ir0 + dr, nr);
2605
2606    for (int ir = ir0; ir < ir1; ++ir) {
2607        const int i3 = ir/(ne02*ne01);
2608        const int i2 = (ir - i3*ne02*ne01)/ne01;
2609        const int i1 = (ir - i3*ne02*ne01 - i2*ne01);
2610
2611        ggml_vec_silu_f32(nc,
2612                (float *) ((char *) dst->data  + i3*nb3  + i2*nb2  + i1*nb1),
2613                (float *) ((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01));
2614
2615#ifndef NDEBUG
2616        for (int k = 0; k < nc; k++) {
2617            const float x = ((float *) ((char *) dst->data + i3*nb3 + i2*nb2 + i1*(dst->nb[1])))[k];
2618            GGML_UNUSED(x);
2619            assert(!isnan(x));
2620            assert(!isinf(x));
2621        }
2622#endif // NDEBUG
2623    }
2624}
2625
2626static void ggml_compute_forward_silu_f16(
2627    const ggml_compute_params * params,
2628    ggml_tensor * dst) {
2629
2630    const ggml_tensor * src0 = dst->src[0];
2631
2632    assert(ggml_is_contiguous_rows(src0));
2633    assert(ggml_are_same_shape(src0, dst));
2634
2635    GGML_TENSOR_LOCALS(int64_t, ne0, src0, ne)
2636    GGML_TENSOR_LOCALS(size_t,  nb0, src0, nb)
2637    GGML_TENSOR_LOCALS(int64_t, ne,  dst,  ne)
2638    GGML_TENSOR_LOCALS(size_t,  nb,  dst,  nb)
2639
2640    const int ith = params->ith;
2641    const int nth = params->nth;
2642
2643    const int nc = src0->ne[0];
2644    const int nr = ggml_nrows(src0);
2645
2646    // rows per thread
2647    const int dr = (nr + nth - 1)/nth;
2648
2649    // row range for this thread
2650    const int ir0 = dr*ith;
2651    const int ir1 = MIN(ir0 + dr, nr);
2652
2653    for (int ir = ir0; ir < ir1; ++ir) {
2654        const int i3 = ir/(ne02*ne01);
2655        const int i2 = (ir - i3*ne02*ne01)/ne01;
2656        const int i1 = (ir - i3*ne02*ne01 - i2*ne01);
2657
2658        ggml_vec_silu_f16(nc,
2659                (ggml_fp16_t *) ((char *) dst->data  + i3*nb3  + i2*nb2  + i1*nb1),
2660                (ggml_fp16_t *) ((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01));
2661
2662#ifndef NDEBUG
2663        for (int k = 0; k < nc; k++) {
2664            const ggml_fp16_t x = ((ggml_fp16_t *) ((char *) dst->data + i3*nb3 + i2*nb2 + i1*( dst->nb[1])))[k];
2665            const float v = GGML_CPU_FP16_TO_FP32(x);
2666            GGML_UNUSED(v);
2667            assert(!isnan(v));
2668            assert(!isinf(v));
2669        }
2670#endif // NDEBUG
2671    }
2672}
2673
2674static void ggml_compute_forward_silu(
2675        const ggml_compute_params * params,
2676        ggml_tensor * dst) {
2677
2678    const ggml_tensor * src0 = dst->src[0];
2679
2680    switch (src0->type) {
2681        case GGML_TYPE_F32:
2682            {
2683                ggml_compute_forward_silu_f32(params, dst);
2684            } break;
2685        case GGML_TYPE_F16:
2686            {
2687                ggml_compute_forward_silu_f16(params, dst);
2688            } break;
2689        default:
2690            {
2691                GGML_ABORT("fatal error");
2692            }
2693    }
2694}
2695// ggml_compute_forward_leaky_relu
2696
2697static void ggml_compute_forward_leaky_relu_f32(
2698        const ggml_compute_params * params,
2699        ggml_tensor * dst) {
2700
2701    const ggml_tensor * src0 = dst->src[0];
2702
2703    if (params->ith != 0) {
2704        return;
2705    }
2706
2707    assert(ggml_is_contiguous_1(src0));
2708    assert(ggml_is_contiguous_1(dst));
2709    assert(ggml_are_same_shape(src0, dst));
2710
2711    const int n  = ggml_nrows(src0);
2712    const int nc = src0->ne[0];
2713
2714    float negative_slope;
2715    memcpy(&negative_slope, dst->op_params, sizeof(float));
2716
2717    assert(dst->nb[0]  == sizeof(float));
2718    assert(src0->nb[0] == sizeof(float));
2719
2720    for (int i = 0; i < n; i++) {
2721        ggml_vec_leaky_relu_f32(nc,
2722                (float *) ((char *) dst->data  + i*( dst->nb[1])),
2723                (float *) ((char *) src0->data + i*(src0->nb[1])), negative_slope);
2724    }
2725}
2726
2727static void ggml_compute_forward_leaky_relu_f16(
2728    const ggml_compute_params * params,
2729    ggml_tensor * dst) {
2730
2731    const ggml_tensor * src0 = dst->src[0];
2732
2733    if (params->ith != 0) {
2734        return;
2735    }
2736
2737    assert(ggml_is_contiguous_1(src0));
2738    assert(ggml_is_contiguous_1(dst));
2739    assert(ggml_are_same_shape(src0, dst));
2740
2741    const int n  = ggml_nrows(src0);
2742    const int nc = src0->ne[0];
2743
2744    float negative_slope;
2745    memcpy(&negative_slope, dst->op_params, sizeof(float));
2746
2747    assert(dst->nb[0]  == sizeof(ggml_fp16_t));
2748    assert(src0->nb[0] == sizeof(ggml_fp16_t));
2749
2750    for (int i = 0; i < n; i++) {
2751        ggml_vec_leaky_relu_f16(nc,
2752                (ggml_fp16_t *) ((char *) dst->data  + i*( dst->nb[1])),
2753                (ggml_fp16_t *) ((char *) src0->data + i*(src0->nb[1])), negative_slope);
2754    }
2755}
2756
2757void ggml_compute_forward_leaky_relu(
2758        const ggml_compute_params * params,
2759        ggml_tensor * dst) {
2760
2761    const ggml_tensor * src0 = dst->src[0];
2762
2763    switch (src0->type) {
2764        case GGML_TYPE_F32:
2765            {
2766                ggml_compute_forward_leaky_relu_f32(params, dst);
2767            } break;
2768        case GGML_TYPE_F16:
2769            {
2770                ggml_compute_forward_leaky_relu_f16(params, dst);
2771            } break;
2772        default:
2773            {
2774                GGML_ABORT("fatal error");
2775            }
2776    }
2777}
2778
2779// ggml_compute_forward_silu_back
2780
2781static void ggml_compute_forward_silu_back_f32(
2782        const ggml_compute_params * params,
2783        ggml_tensor * dst) {
2784
2785    const ggml_tensor * grad = dst->src[0];
2786    const ggml_tensor * src1 = dst->src[1];
2787
2788    assert(ggml_is_contiguous_1(grad));
2789    assert(ggml_is_contiguous_1(src1));
2790    assert(ggml_is_contiguous_1(dst));
2791    assert(ggml_are_same_shape(src1, dst));
2792    assert(ggml_are_same_shape(src1, grad));
2793
2794    const int ith = params->ith;
2795    const int nth = params->nth;
2796
2797    const int nc = src1->ne[0];
2798    const int nr = ggml_nrows(src1);
2799
2800    // rows per thread
2801    const int dr = (nr + nth - 1)/nth;
2802
2803    // row range for this thread
2804    const int ir0 = dr*ith;
2805    const int ir1 = MIN(ir0 + dr, nr);
2806
2807    for (int i1 = ir0; i1 < ir1; i1++) {
2808        ggml_vec_silu_backward_f32(nc,
2809                (float *) ((char *) dst->data  + i1*( dst->nb[1])),
2810                (float *) ((char *) src1->data + i1*(src1->nb[1])),
2811                (float *) ((char *) grad->data + i1*(grad->nb[1])));
2812
2813#ifndef NDEBUG
2814        for (int k = 0; k < nc; k++) {
2815            const float x = ((float *) ((char *) dst->data + i1*( dst->nb[1])))[k];
2816            GGML_UNUSED(x);
2817            assert(!isnan(x));
2818            assert(!isinf(x));
2819        }
2820#endif // NDEBUG
2821    }
2822}
2823
2824static void ggml_compute_forward_silu_back_f16(
2825    const ggml_compute_params * params,
2826    ggml_tensor * dst) {
2827
2828    const ggml_tensor * grad = dst->src[0];
2829    const ggml_tensor * src1 = dst->src[1];
2830
2831    assert(ggml_is_contiguous_1(grad));
2832    assert(ggml_is_contiguous_1(src1));
2833    assert(ggml_is_contiguous_1(dst));
2834    assert(ggml_are_same_shape(src1, dst));
2835    assert(ggml_are_same_shape(src1, grad));
2836
2837    const int ith = params->ith;
2838    const int nth = params->nth;
2839
2840    const int nc = src1->ne[0];
2841    const int nr = ggml_nrows(src1);
2842
2843    // rows per thread
2844    const int dr = (nr + nth - 1)/nth;
2845
2846    // row range for this thread
2847    const int ir0 = dr*ith;
2848    const int ir1 = MIN(ir0 + dr, nr);
2849
2850    for (int i1 = ir0; i1 < ir1; i1++) {
2851        ggml_vec_silu_backward_f16(nc,
2852                (ggml_fp16_t *) ((char *) dst->data  + i1*( dst->nb[1])),
2853                (ggml_fp16_t *) ((char *) src1->data + i1*(src1->nb[1])),
2854                (ggml_fp16_t *) ((char *) grad->data + i1*(grad->nb[1])));
2855
2856#ifndef NDEBUG
2857        for (int k = 0; k < nc; k++) {
2858            const float x = ((ggml_fp16_t *) ((char *) dst->data + i1*( dst->nb[1])))[k];
2859            const float v = GGML_CPU_FP16_TO_FP32(x);
2860            GGML_UNUSED(v);
2861            assert(!isnan(v));
2862            assert(!isinf(v));
2863        }
2864#endif // NDEBUG
2865    }
2866}
2867
2868void ggml_compute_forward_silu_back(
2869        const ggml_compute_params * params,
2870        ggml_tensor * dst) {
2871
2872    const ggml_tensor * src0 = dst->src[0];
2873
2874    switch (src0->type) {
2875        case GGML_TYPE_F32:
2876            {
2877                ggml_compute_forward_silu_back_f32(params, dst);
2878            } break;
2879        case GGML_TYPE_F16:
2880            {
2881                ggml_compute_forward_silu_back_f16(params, dst);
2882            } break;
2883        default:
2884            {
2885                GGML_ABORT("fatal error");
2886            }
2887    }
2888}
2889
2890// ggml_compute_forward_reglu
2891
2892static void ggml_compute_forward_reglu_f32(
2893        const ggml_compute_params * params,
2894        ggml_tensor * dst) {
2895
2896    const ggml_tensor * src0 = dst->src[0];
2897    const ggml_tensor * src1 = dst->src[1];
2898    char * src0_d = (char *) src0->data;
2899    char * src1_d = (char *) (src1 ? src1->data : src0->data);
2900    const size_t src0_o = src0->nb[1];
2901    const size_t src1_o = src1 ? src1->nb[1] : src0->nb[1];
2902
2903    GGML_ASSERT(ggml_is_contiguous_1(src0));
2904    GGML_ASSERT(ggml_is_contiguous_1(dst));
2905
2906    if (src1) {
2907        GGML_ASSERT(ggml_is_contiguous_1(src1));
2908        GGML_ASSERT(src0->type == src1->type);
2909    }
2910
2911    const int ith = params->ith;
2912    const int nth = params->nth;
2913
2914    const int nc = src1 ? src0->ne[0] : src0->ne[0] / 2;
2915    const int nr = ggml_nrows(src0);
2916
2917    GGML_ASSERT(dst->ne[0] == nc);
2918    GGML_ASSERT(ggml_nrows(dst) == nr);
2919
2920    const int32_t swapped = ggml_get_op_params_i32(dst, 1);
2921
2922    // rows per thread
2923    const int dr = (nr + nth - 1)/nth;
2924
2925    // row range for this thread
2926    const int ir0 = dr*ith;
2927    const int ir1 = MIN(ir0 + dr, nr);
2928
2929    for (int i1 = ir0; i1 < ir1; i1++) {
2930        float * src0_p = (float *) (src0_d + i1*src0_o);
2931        float * src1_p = (float *) (src1_d + i1*src1_o);
2932
2933        if (!src1) {
2934            src0_p += swapped ? nc : 0;
2935            src1_p += swapped ? 0 : nc;
2936        }
2937
2938        ggml_vec_reglu_f32(nc, (float *) ((char *) dst->data + i1*(dst->nb[1])), src0_p, src1_p);
2939
2940#ifndef NDEBUG
2941        for (int k = 0; k < nc; k++) {
2942            const float x = ((float *) ((char *) dst->data + i1*( dst->nb[1])))[k];
2943            GGML_UNUSED(x);
2944            assert(!isnan(x));
2945            assert(!isinf(x));
2946        }
2947#endif // NDEBUG
2948    }
2949}
2950
2951static void ggml_compute_forward_reglu_f16(
2952    const ggml_compute_params * params,
2953    ggml_tensor * dst) {
2954
2955    const ggml_tensor * src0 = dst->src[0];
2956    const ggml_tensor * src1 = dst->src[1];
2957    char * src0_d = (char *) src0->data;
2958    char * src1_d = (char *) (src1 ? src1->data : src0->data);
2959    const size_t src0_o = src0->nb[1];
2960    const size_t src1_o = src1 ? src1->nb[1] : src0->nb[1];
2961
2962    GGML_ASSERT(ggml_is_contiguous_1(src0));
2963    GGML_ASSERT(ggml_is_contiguous_1(dst));
2964
2965    if (src1) {
2966        GGML_ASSERT(ggml_is_contiguous_1(src1));
2967        GGML_ASSERT(src0->type == src1->type);
2968    }
2969
2970    const int ith = params->ith;
2971    const int nth = params->nth;
2972
2973    const int nc = src1 ? src0->ne[0] : src0->ne[0] / 2;
2974    const int nr = ggml_nrows(src0);
2975
2976    GGML_ASSERT(dst->ne[0] == nc);
2977    GGML_ASSERT(ggml_nrows(dst) == nr);
2978
2979    const int32_t swapped = ggml_get_op_params_i32(dst, 1);
2980
2981    // rows per thread
2982    const int dr = (nr + nth - 1)/nth;
2983
2984    // row range for this thread
2985    const int ir0 = dr*ith;
2986    const int ir1 = MIN(ir0 + dr, nr);
2987
2988    for (int i1 = ir0; i1 < ir1; i1++) {
2989        ggml_fp16_t * src0_p = (ggml_fp16_t *) (src0_d + i1*src0_o);
2990        ggml_fp16_t * src1_p = (ggml_fp16_t *) (src1_d + i1*src1_o);
2991
2992        if (!src1) {
2993            src0_p += swapped ? nc : 0;
2994            src1_p += swapped ? 0 : nc;
2995        }
2996
2997        ggml_vec_reglu_f16(nc, (ggml_fp16_t *) ((char *) dst->data + i1*(dst->nb[1])), src0_p, src1_p);
2998
2999#ifndef NDEBUG
3000        for (int k = 0; k < nc; k++) {
3001            const ggml_fp16_t x = ((ggml_fp16_t *) ((char *) dst->data + i1*( dst->nb[1])))[k];
3002            const float v = GGML_FP16_TO_FP32(x);
3003            GGML_UNUSED(v);
3004            assert(!isnan(v));
3005            assert(!isinf(v));
3006        }
3007#endif // NDEBUG
3008    }
3009}
3010
3011static void ggml_compute_forward_reglu(
3012        const ggml_compute_params * params,
3013        ggml_tensor * dst) {
3014
3015    const ggml_tensor * src0 = dst->src[0];
3016
3017    switch (src0->type) {
3018        case GGML_TYPE_F32:
3019            {
3020                ggml_compute_forward_reglu_f32(params, dst);
3021            } break;
3022        case GGML_TYPE_F16:
3023            {
3024                ggml_compute_forward_reglu_f16(params, dst);
3025            } break;
3026        default:
3027            {
3028                GGML_ABORT("fatal error");
3029            }
3030    }
3031}
3032
3033// ggml_compute_forward_geglu
3034
3035static void ggml_compute_forward_geglu_f32(
3036        const ggml_compute_params * params,
3037        ggml_tensor * dst) {
3038
3039    const ggml_tensor * src0 = dst->src[0];
3040    const ggml_tensor * src1 = dst->src[1];
3041    char * src0_d = (char *) src0->data;
3042    char * src1_d = (char *) (src1 ? src1->data : src0->data);
3043    const size_t src0_o = src0->nb[1];
3044    const size_t src1_o = src1 ? src1->nb[1] : src0->nb[1];
3045
3046    GGML_ASSERT(ggml_is_contiguous_1(src0));
3047    GGML_ASSERT(ggml_is_contiguous_1(dst));
3048
3049    if (src1) {
3050        GGML_ASSERT(ggml_is_contiguous_1(src1));
3051        GGML_ASSERT(src0->type == src1->type);
3052    }
3053
3054    const int ith = params->ith;
3055    const int nth = params->nth;
3056
3057    const int nc = src1 ? src0->ne[0] : src0->ne[0] / 2;
3058    const int nr = ggml_nrows(src0);
3059
3060    GGML_ASSERT(dst->ne[0] == nc);
3061    GGML_ASSERT(ggml_nrows(dst) == nr);
3062
3063    const int32_t swapped = ggml_get_op_params_i32(dst, 1);
3064
3065    // rows per thread
3066    const int dr = (nr + nth - 1)/nth;
3067
3068    // row range for this thread
3069    const int ir0 = dr*ith;
3070    const int ir1 = MIN(ir0 + dr, nr);
3071
3072    for (int i1 = ir0; i1 < ir1; i1++) {
3073        float * src0_p = (float *) (src0_d + i1*src0_o);
3074        float * src1_p = (float *) (src1_d + i1*src1_o);
3075
3076        if (!src1) {
3077            src0_p += swapped ? nc : 0;
3078            src1_p += swapped ? 0 : nc;
3079        }
3080
3081        ggml_vec_geglu_f32(nc, (float *) ((char *) dst->data + i1*(dst->nb[1])), src0_p, src1_p);
3082
3083#ifndef NDEBUG
3084        for (int k = 0; k < nc; k++) {
3085            const float x = ((float *) ((char *) dst->data + i1*( dst->nb[1])))[k];
3086            GGML_UNUSED(x);
3087            assert(!isnan(x));
3088            assert(!isinf(x));
3089        }
3090#endif // NDEBUG
3091    }
3092}
3093
3094static void ggml_compute_forward_geglu_f16(
3095    const ggml_compute_params * params,
3096    ggml_tensor * dst) {
3097
3098    const ggml_tensor * src0 = dst->src[0];
3099    const ggml_tensor * src1 = dst->src[1];
3100    char * src0_d = (char *) src0->data;
3101    char * src1_d = (char *) (src1 ? src1->data : src0->data);
3102    const size_t src0_o = src0->nb[1];
3103    const size_t src1_o = src1 ? src1->nb[1] : src0->nb[1];
3104
3105    GGML_ASSERT(ggml_is_contiguous_1(src0));
3106    GGML_ASSERT(ggml_is_contiguous_1(dst));
3107
3108    if (src1) {
3109        GGML_ASSERT(ggml_is_contiguous_1(src1));
3110        GGML_ASSERT(src0->type == src1->type);
3111    }
3112
3113    const int ith = params->ith;
3114    const int nth = params->nth;
3115
3116    const int nc = src1 ? src0->ne[0] : src0->ne[0] / 2;
3117    const int nr = ggml_nrows(src0);
3118
3119    GGML_ASSERT(dst->ne[0] == nc);
3120    GGML_ASSERT(ggml_nrows(dst) == nr);
3121
3122    const int32_t swapped = ggml_get_op_params_i32(dst, 1);
3123
3124    // rows per thread
3125    const int dr = (nr + nth - 1)/nth;
3126
3127    // row range for this thread
3128    const int ir0 = dr*ith;
3129    const int ir1 = MIN(ir0 + dr, nr);
3130
3131    for (int i1 = ir0; i1 < ir1; i1++) {
3132        ggml_fp16_t * src0_p = (ggml_fp16_t *) (src0_d + i1*src0_o);
3133        ggml_fp16_t * src1_p = (ggml_fp16_t *) (src1_d + i1*src1_o);
3134
3135        if (!src1) {
3136            src0_p += swapped ? nc : 0;
3137            src1_p += swapped ? 0 : nc;
3138        }
3139
3140        ggml_vec_geglu_f16(nc, (ggml_fp16_t *) ((char *) dst->data + i1*(dst->nb[1])), src0_p, src1_p);
3141
3142#ifndef NDEBUG
3143        for (int k = 0; k < nc; k++) {
3144            const ggml_fp16_t x = ((ggml_fp16_t *) ((char *) dst->data + i1*( dst->nb[1])))[k];
3145            const float v = GGML_FP16_TO_FP32(x);
3146            GGML_UNUSED(v);
3147            assert(!isnan(v));
3148            assert(!isinf(v));
3149        }
3150#endif // NDEBUG
3151    }
3152}
3153
3154static void ggml_compute_forward_geglu(
3155        const ggml_compute_params * params,
3156        ggml_tensor * dst) {
3157
3158    const ggml_tensor * src0 = dst->src[0];
3159
3160    switch (src0->type) {
3161        case GGML_TYPE_F32:
3162            {
3163                ggml_compute_forward_geglu_f32(params, dst);
3164            } break;
3165        case GGML_TYPE_F16:
3166            {
3167                ggml_compute_forward_geglu_f16(params, dst);
3168            } break;
3169        default:
3170            {
3171                GGML_ABORT("fatal error");
3172            }
3173    }
3174}
3175
3176// ggml_compute_forward_swiglu
3177
3178static void ggml_compute_forward_swiglu_f32(
3179        const ggml_compute_params * params,
3180        ggml_tensor * dst) {
3181
3182    const ggml_tensor * src0 = dst->src[0];
3183    const ggml_tensor * src1 = dst->src[1];
3184    char * src0_d = (char *) src0->data;
3185    char * src1_d = (char *) (src1 ? src1->data : src0->data);
3186    const size_t src0_o = src0->nb[1];
3187    const size_t src1_o = src1 ? src1->nb[1] : src0->nb[1];
3188
3189    GGML_ASSERT(ggml_is_contiguous_1(src0));
3190    GGML_ASSERT(ggml_is_contiguous_1(dst));
3191
3192    if (src1) {
3193        GGML_ASSERT(ggml_is_contiguous_1(src1));
3194        GGML_ASSERT(src0->type == src1->type);
3195    }
3196
3197    const int ith = params->ith;
3198    const int nth = params->nth;
3199
3200    const int nc = src1 ? src0->ne[0] : src0->ne[0] / 2;
3201    const int nr = ggml_nrows(src0);
3202
3203    GGML_ASSERT(dst->ne[0] == nc);
3204    GGML_ASSERT(ggml_nrows(dst) == nr);
3205
3206    const int32_t swapped = ggml_get_op_params_i32(dst, 1);
3207
3208    // rows per thread
3209    const int dr = (nr + nth - 1)/nth;
3210
3211    // row range for this thread
3212    const int ir0 = dr*ith;
3213    const int ir1 = MIN(ir0 + dr, nr);
3214
3215    for (int i1 = ir0; i1 < ir1; i1++) {
3216        float * src0_p = (float *) (src0_d + i1*src0_o);
3217        float * src1_p = (float *) (src1_d + i1*src1_o);
3218
3219        if (!src1) {
3220            src0_p += swapped ? nc : 0;
3221            src1_p += swapped ? 0 : nc;
3222        }
3223
3224        ggml_vec_swiglu_f32(nc, (float *) ((char *) dst->data + i1*(dst->nb[1])), src0_p, src1_p);
3225
3226#ifndef NDEBUG
3227        for (int k = 0; k < nc; k++) {
3228            const float x = ((float *) ((char *) dst->data + i1*( dst->nb[1])))[k];
3229            GGML_UNUSED(x);
3230            assert(!isnan(x));
3231            assert(!isinf(x));
3232        }
3233#endif // NDEBUG
3234    }
3235}
3236
3237static void ggml_compute_forward_swiglu_f16(
3238    const ggml_compute_params * params,
3239    ggml_tensor * dst) {
3240
3241    const ggml_tensor * src0 = dst->src[0];
3242    const ggml_tensor * src1 = dst->src[1];
3243    char * src0_d = (char *) src0->data;
3244    char * src1_d = (char *) (src1 ? src1->data : src0->data);
3245    const size_t src0_o = src0->nb[1];
3246    const size_t src1_o = src1 ? src1->nb[1] : src0->nb[1];
3247
3248    GGML_ASSERT(ggml_is_contiguous_1(src0));
3249    GGML_ASSERT(ggml_is_contiguous_1(dst));
3250
3251    if (src1) {
3252        GGML_ASSERT(ggml_is_contiguous_1(src1));
3253        GGML_ASSERT(src0->type == src1->type);
3254    }
3255
3256    const int ith = params->ith;
3257    const int nth = params->nth;
3258
3259    const int nc = src1 ? src0->ne[0] : src0->ne[0] / 2;
3260    const int nr = ggml_nrows(src0);
3261
3262    GGML_ASSERT(dst->ne[0] == nc);
3263    GGML_ASSERT(ggml_nrows(dst) == nr);
3264
3265    const int32_t swapped = ggml_get_op_params_i32(dst, 1);
3266
3267    // rows per thread
3268    const int dr = (nr + nth - 1)/nth;
3269
3270    // row range for this thread
3271    const int ir0 = dr*ith;
3272    const int ir1 = MIN(ir0 + dr, nr);
3273
3274    for (int i1 = ir0; i1 < ir1; i1++) {
3275        ggml_fp16_t * src0_p = (ggml_fp16_t *) (src0_d + i1*src0_o);
3276        ggml_fp16_t * src1_p = (ggml_fp16_t *) (src1_d + i1*src1_o);
3277
3278        if (!src1) {
3279            src0_p += swapped ? nc : 0;
3280            src1_p += swapped ? 0 : nc;
3281        }
3282
3283        ggml_vec_swiglu_f16(nc, (ggml_fp16_t *) ((char *) dst->data + i1*(dst->nb[1])), src0_p, src1_p);
3284
3285#ifndef NDEBUG
3286        for (int k = 0; k < nc; k++) {
3287            const ggml_fp16_t x = ((ggml_fp16_t *) ((char *) dst->data + i1*( dst->nb[1])))[k];
3288            const float v = GGML_FP16_TO_FP32(x);
3289            GGML_UNUSED(v);
3290            assert(!isnan(v));
3291            assert(!isinf(v));
3292        }
3293#endif // NDEBUG
3294    }
3295}
3296
3297static void ggml_compute_forward_swiglu(
3298        const ggml_compute_params * params,
3299        ggml_tensor * dst) {
3300
3301    const ggml_tensor * src0 = dst->src[0];
3302
3303    switch (src0->type) {
3304        case GGML_TYPE_F32:
3305            {
3306                ggml_compute_forward_swiglu_f32(params, dst);
3307            } break;
3308        case GGML_TYPE_F16:
3309            {
3310                ggml_compute_forward_swiglu_f16(params, dst);
3311            } break;
3312        default:
3313            {
3314                GGML_ABORT("fatal error");
3315            }
3316    }
3317}
3318
3319// ggml_compute_forward_swiglu_oai
3320
3321static void ggml_compute_forward_swiglu_oai_f32(
3322        const ggml_compute_params * params,
3323        ggml_tensor * dst) {
3324
3325    const ggml_tensor * src0 = dst->src[0];
3326    const ggml_tensor * src1 = dst->src[1];
3327    char * src0_d = (char *) src0->data;
3328    char * src1_d = (char *) (src1 ? src1->data : src0->data);
3329    const size_t src0_o = src0->nb[1];
3330    const size_t src1_o = src1 ? src1->nb[1] : src0->nb[1];
3331
3332    GGML_ASSERT(ggml_is_contiguous_1(src0));
3333    GGML_ASSERT(ggml_is_contiguous_1(dst));
3334
3335    if (src1) {
3336        GGML_ASSERT(ggml_is_contiguous_1(src1));
3337        GGML_ASSERT(src0->type == src1->type);
3338    }
3339
3340    const int ith = params->ith;
3341    const int nth = params->nth;
3342
3343    const int nc = src1 ? src0->ne[0] : src0->ne[0] / 2;
3344    const int nr = ggml_nrows(src0);
3345
3346    GGML_ASSERT(dst->ne[0] == nc);
3347    GGML_ASSERT(ggml_nrows(dst) == nr);
3348
3349    const int32_t swapped = ggml_get_op_params_i32(dst, 1);
3350    const float alpha = ggml_get_op_params_f32(dst, 2);
3351    const float limit = ggml_get_op_params_f32(dst, 3);
3352
3353    // rows per thread
3354    const int dr = (nr + nth - 1)/nth;
3355
3356    // row range for this thread
3357    const int ir0 = dr*ith;
3358    const int ir1 = MIN(ir0 + dr, nr);
3359
3360    for (int i1 = ir0; i1 < ir1; i1++) {
3361        float * src0_p = (float *) (src0_d + i1*src0_o);
3362        float * src1_p = (float *) (src1_d + i1*src1_o);
3363        float * dst_p  = (float *) ((char *) dst->data + i1*(dst->nb[1]));
3364
3365        if (!src1) {
3366            src0_p += swapped ? nc : 0;
3367            src1_p += swapped ? 0 : nc;
3368        }
3369
3370        for (int k = 0; k < nc; k++) {
3371            const float x = std::min(src0_p[k], limit);
3372            const float y = std::clamp(src1_p[k], -limit, limit);
3373            const float out_glu = x / (1.f + expf(alpha * (-x)));
3374            dst_p[k] = out_glu * (y + 1.f);
3375        }
3376
3377#ifndef NDEBUG
3378        for (int k = 0; k < nc; k++) {
3379            const float x = dst_p[k];
3380            GGML_UNUSED(x);
3381            assert(!isnan(x));
3382            assert(!isinf(x));
3383        }
3384#endif // NDEBUG
3385    }
3386}
3387
3388static void ggml_compute_forward_swiglu_oai(
3389        const ggml_compute_params * params,
3390        ggml_tensor * dst) {
3391
3392    const ggml_tensor * src0 = dst->src[0];
3393
3394    switch (src0->type) {
3395        case GGML_TYPE_F32:
3396            {
3397                ggml_compute_forward_swiglu_oai_f32(params, dst);
3398            } break;
3399        default:
3400            {
3401                GGML_ABORT("fatal error");
3402            }
3403    }
3404}
3405
3406// ggml_compute_forward_swiglu_clamp
3407
3408static void ggml_compute_forward_swiglu_clamp_f32(const ggml_compute_params * params, ggml_tensor * dst) {
3409    const ggml_tensor * src0   = dst->src[0];
3410    const ggml_tensor * src1   = dst->src[1];
3411    char *              src0_d = (char *) src0->data;
3412    char *              src1_d = (char *) (src1 ? src1->data : src0->data);
3413    const size_t        src0_o = src0->nb[1];
3414    const size_t        src1_o = src1 ? src1->nb[1] : src0->nb[1];
3415
3416    GGML_ASSERT(ggml_is_contiguous_1(src0));
3417    GGML_ASSERT(ggml_is_contiguous_1(dst));
3418
3419    if (src1) {
3420        GGML_ASSERT(ggml_is_contiguous_1(src1));
3421        GGML_ASSERT(src0->type == src1->type);
3422    }
3423
3424    const int ith = params->ith;
3425    const int nth = params->nth;
3426
3427    const int nc = src1 ? src0->ne[0] : src0->ne[0] / 2;
3428    const int nr = ggml_nrows(src0);
3429
3430    GGML_ASSERT(dst->ne[0] == nc);
3431    GGML_ASSERT(ggml_nrows(dst) == nr);
3432
3433    const int32_t swapped = ggml_get_op_params_i32(dst, 1);
3434    const float   limit   = ggml_get_op_params_f32(dst, 3);
3435
3436    const int dr  = (nr + nth - 1) / nth;
3437    const int ir0 = dr * ith;
3438    const int ir1 = MIN(ir0 + dr, nr);
3439
3440    for (int i1 = ir0; i1 < ir1; i1++) {
3441        float * src0_p = (float *) (src0_d + i1 * src0_o);
3442        float * src1_p = (float *) (src1_d + i1 * src1_o);
3443        float * dst_p  = (float *) ((char *) dst->data + i1 * (dst->nb[1]));
3444
3445        if (!src1) {
3446            src0_p += swapped ? nc : 0;
3447            src1_p += swapped ? 0 : nc;
3448        }
3449
3450        for (int k = 0; k < nc; k++) {
3451            const float gate = std::min(src0_p[k], limit);
3452            const float up   = std::clamp(src1_p[k], -limit, limit);
3453            dst_p[k]         = gate / (1.f + expf(-gate)) * up;
3454        }
3455
3456#ifndef NDEBUG
3457        for (int k = 0; k < nc; k++) {
3458            const float x = dst_p[k];
3459            GGML_UNUSED(x);
3460            assert(!isnan(x));
3461            assert(!isinf(x));
3462        }
3463#endif  // NDEBUG
3464    }
3465}
3466
3467static void ggml_compute_forward_swiglu_clamp_f16(const ggml_compute_params * params, ggml_tensor * dst) {
3468    const ggml_tensor * src0   = dst->src[0];
3469    const ggml_tensor * src1   = dst->src[1];
3470    char *              src0_d = (char *) src0->data;
3471    char *              src1_d = (char *) (src1 ? src1->data : src0->data);
3472    const size_t        src0_o = src0->nb[1];
3473    const size_t        src1_o = src1 ? src1->nb[1] : src0->nb[1];
3474
3475    GGML_ASSERT(ggml_is_contiguous_1(src0));
3476    GGML_ASSERT(ggml_is_contiguous_1(dst));
3477
3478    if (src1) {
3479        GGML_ASSERT(ggml_is_contiguous_1(src1));
3480        GGML_ASSERT(src0->type == src1->type);
3481    }
3482
3483    const int ith = params->ith;
3484    const int nth = params->nth;
3485
3486    const int nc = src1 ? src0->ne[0] : src0->ne[0] / 2;
3487    const int nr = ggml_nrows(src0);
3488
3489    GGML_ASSERT(dst->ne[0] == nc);
3490    GGML_ASSERT(ggml_nrows(dst) == nr);
3491
3492    const int32_t swapped = ggml_get_op_params_i32(dst, 1);
3493    const float   limit   = ggml_get_op_params_f32(dst, 3);
3494
3495    const int dr  = (nr + nth - 1) / nth;
3496    const int ir0 = dr * ith;
3497    const int ir1 = MIN(ir0 + dr, nr);
3498
3499    for (int i1 = ir0; i1 < ir1; i1++) {
3500        ggml_fp16_t * src0_p = (ggml_fp16_t *) (src0_d + i1 * src0_o);
3501        ggml_fp16_t * src1_p = (ggml_fp16_t *) (src1_d + i1 * src1_o);
3502        ggml_fp16_t * dst_p  = (ggml_fp16_t *) ((char *) dst->data + i1 * (dst->nb[1]));
3503
3504        if (!src1) {
3505            src0_p += swapped ? nc : 0;
3506            src1_p += swapped ? 0 : nc;
3507        }
3508
3509        for (int k = 0; k < nc; k++) {
3510            const float gate = std::min(GGML_FP16_TO_FP32(src0_p[k]), limit);
3511            const float up   = std::clamp(GGML_FP16_TO_FP32(src1_p[k]), -limit, limit);
3512            dst_p[k]         = GGML_FP32_TO_FP16(gate / (1.f + expf(-gate)) * up);
3513        }
3514
3515#ifndef NDEBUG
3516        for (int k = 0; k < nc; k++) {
3517            const float x = GGML_FP16_TO_FP32(dst_p[k]);
3518            GGML_UNUSED(x);
3519            assert(!isnan(x));
3520            assert(!isinf(x));
3521        }
3522#endif  // NDEBUG
3523    }
3524}
3525
3526static void ggml_compute_forward_swiglu_clamp(const ggml_compute_params * params, ggml_tensor * dst) {
3527    switch (dst->src[0]->type) {
3528        case GGML_TYPE_F32:
3529            ggml_compute_forward_swiglu_clamp_f32(params, dst);
3530            break;
3531        case GGML_TYPE_F16:
3532            ggml_compute_forward_swiglu_clamp_f16(params, dst);
3533            break;
3534        default:
3535            GGML_ABORT("fatal error");
3536    }
3537}
3538
3539// ggml_compute_forward_geglu_erf
3540
3541static void ggml_compute_forward_geglu_erf_f32(
3542        const ggml_compute_params * params,
3543        ggml_tensor * dst) {
3544
3545    const ggml_tensor * src0 = dst->src[0];
3546    const ggml_tensor * src1 = dst->src[1];
3547    char * src0_d = (char *) src0->data;
3548    char * src1_d = (char *) (src1 ? src1->data : src0->data);
3549    const size_t src0_o = src0->nb[1];
3550    const size_t src1_o = src1 ? src1->nb[1] : src0->nb[1];
3551
3552    GGML_ASSERT(ggml_is_contiguous_1(src0));
3553    GGML_ASSERT(ggml_is_contiguous_1(dst));
3554
3555    if (src1) {
3556        GGML_ASSERT(ggml_is_contiguous_1(src1));
3557        GGML_ASSERT(src0->type == src1->type);
3558    }
3559
3560    const int ith = params->ith;
3561    const int nth = params->nth;
3562
3563    const int nc = src1 ? src0->ne[0] : src0->ne[0] / 2;
3564    const int nr = ggml_nrows(src0);
3565
3566    GGML_ASSERT(dst->ne[0] == nc);
3567    GGML_ASSERT(ggml_nrows(dst) == nr);
3568
3569    const int32_t swapped = ggml_get_op_params_i32(dst, 1);
3570
3571    // rows per thread
3572    const int dr = (nr + nth - 1)/nth;
3573
3574    // row range for this thread
3575    const int ir0 = dr*ith;
3576    const int ir1 = MIN(ir0 + dr, nr);
3577
3578    for (int i1 = ir0; i1 < ir1; i1++) {
3579        float * src0_p = (float *) (src0_d + i1*src0_o);
3580        float * src1_p = (float *) (src1_d + i1*src1_o);
3581
3582        if (!src1) {
3583            src0_p += swapped ? nc : 0;
3584            src1_p += swapped ? 0 : nc;
3585        }
3586
3587        ggml_vec_geglu_erf_f32(nc, (float *) ((char *) dst->data + i1*(dst->nb[1])), src0_p, src1_p);
3588
3589#ifndef NDEBUG
3590        for (int k = 0; k < nc; k++) {
3591            const float x = ((float *) ((char *) dst->data + i1*( dst->nb[1])))[k];
3592            GGML_UNUSED(x);
3593            assert(!isnan(x));
3594            assert(!isinf(x));
3595        }
3596#endif // NDEBUG
3597    }
3598}
3599
3600static void ggml_compute_forward_geglu_erf_f16(
3601    const ggml_compute_params * params,
3602    ggml_tensor * dst) {
3603
3604    const ggml_tensor * src0 = dst->src[0];
3605    const ggml_tensor * src1 = dst->src[1];
3606    char * src0_d = (char *) src0->data;
3607    char * src1_d = (char *) (src1 ? src1->data : src0->data);
3608    const size_t src0_o = src0->nb[1];
3609    const size_t src1_o = src1 ? src1->nb[1] : src0->nb[1];
3610
3611    GGML_ASSERT(ggml_is_contiguous_1(src0));
3612    GGML_ASSERT(ggml_is_contiguous_1(dst));
3613
3614    if (src1) {
3615        GGML_ASSERT(ggml_is_contiguous_1(src1));
3616        GGML_ASSERT(src0->type == src1->type);
3617    }
3618
3619    const int ith = params->ith;
3620    const int nth = params->nth;
3621
3622    const int nc = src1 ? src0->ne[0] : src0->ne[0] / 2;
3623    const int nr = ggml_nrows(src0);
3624
3625    GGML_ASSERT(dst->ne[0] == nc);
3626    GGML_ASSERT(ggml_nrows(dst) == nr);
3627
3628    const int32_t swapped = ggml_get_op_params_i32(dst, 1);
3629
3630    // rows per thread
3631    const int dr = (nr + nth - 1)/nth;
3632
3633    // row range for this thread
3634    const int ir0 = dr*ith;
3635    const int ir1 = MIN(ir0 + dr, nr);
3636
3637    for (int i1 = ir0; i1 < ir1; i1++) {
3638        ggml_fp16_t * src0_p = (ggml_fp16_t *) (src0_d + i1*src0_o);
3639        ggml_fp16_t * src1_p = (ggml_fp16_t *) (src1_d + i1*src1_o);
3640
3641        if (!src1) {
3642            src0_p += swapped ? nc : 0;
3643            src1_p += swapped ? 0 : nc;
3644        }
3645
3646        ggml_vec_geglu_erf_f16(nc, (ggml_fp16_t *) ((char *) dst->data + i1*(dst->nb[1])), src0_p, src1_p);
3647
3648#ifndef NDEBUG
3649        for (int k = 0; k < nc; k++) {
3650            const ggml_fp16_t x = ((ggml_fp16_t *) ((char *) dst->data + i1*( dst->nb[1])))[k];
3651            const float v = GGML_FP16_TO_FP32(x);
3652            GGML_UNUSED(v);
3653            assert(!isnan(v));
3654            assert(!isinf(v));
3655        }
3656#endif // NDEBUG
3657    }
3658}
3659
3660static void ggml_compute_forward_geglu_erf(
3661        const ggml_compute_params * params,
3662        ggml_tensor * dst) {
3663
3664    const ggml_tensor * src0 = dst->src[0];
3665
3666    switch (src0->type) {
3667        case GGML_TYPE_F32:
3668            {
3669                ggml_compute_forward_geglu_erf_f32(params, dst);
3670            } break;
3671        case GGML_TYPE_F16:
3672            {
3673                ggml_compute_forward_geglu_erf_f16(params, dst);
3674            } break;
3675        default:
3676            {
3677                GGML_ABORT("fatal error");
3678            }
3679    }
3680}
3681
3682// ggml_compute_forward_geglu_quick
3683
3684static void ggml_compute_forward_geglu_quick_f32(
3685        const ggml_compute_params * params,
3686        ggml_tensor * dst) {
3687
3688    const ggml_tensor * src0 = dst->src[0];
3689    const ggml_tensor * src1 = dst->src[1];
3690    char * src0_d = (char *) src0->data;
3691    char * src1_d = (char *) (src1 ? src1->data : src0->data);
3692    const size_t src0_o = src0->nb[1];
3693    const size_t src1_o = src1 ? src1->nb[1] : src0->nb[1];
3694
3695    GGML_ASSERT(ggml_is_contiguous_1(src0));
3696    GGML_ASSERT(ggml_is_contiguous_1(dst));
3697
3698    if (src1) {
3699        GGML_ASSERT(ggml_is_contiguous_1(src1));
3700        GGML_ASSERT(src0->type == src1->type);
3701    }
3702
3703    const int ith = params->ith;
3704    const int nth = params->nth;
3705
3706    const int nc = src1 ? src0->ne[0] : src0->ne[0] / 2;
3707    const int nr = ggml_nrows(src0);
3708
3709    GGML_ASSERT(dst->ne[0] == nc);
3710    GGML_ASSERT(ggml_nrows(dst) == nr);
3711
3712    const int32_t swapped = ggml_get_op_params_i32(dst, 1);
3713
3714    // rows per thread
3715    const int dr = (nr + nth - 1)/nth;
3716
3717    // row range for this thread
3718    const int ir0 = dr*ith;
3719    const int ir1 = MIN(ir0 + dr, nr);
3720
3721    for (int i1 = ir0; i1 < ir1; i1++) {
3722        float * src0_p = (float *) (src0_d + i1*src0_o);
3723        float * src1_p = (float *) (src1_d + i1*src1_o);
3724
3725        if (!src1) {
3726            src0_p += swapped ? nc : 0;
3727            src1_p += swapped ? 0 : nc;
3728        }
3729
3730        ggml_vec_geglu_quick_f32(nc, (float *) ((char *) dst->data + i1*(dst->nb[1])), src0_p, src1_p);
3731
3732#ifndef NDEBUG
3733        for (int k = 0; k < nc; k++) {
3734            const float x = ((float *) ((char *) dst->data + i1*( dst->nb[1])))[k];
3735            GGML_UNUSED(x);
3736            assert(!isnan(x));
3737            assert(!isinf(x));
3738        }
3739#endif // NDEBUG
3740    }
3741}
3742
3743static void ggml_compute_forward_geglu_quick_f16(
3744    const ggml_compute_params * params,
3745    ggml_tensor * dst) {
3746
3747    const ggml_tensor * src0 = dst->src[0];
3748    const ggml_tensor * src1 = dst->src[1];
3749    char * src0_d = (char *) src0->data;
3750    char * src1_d = (char *) (src1 ? src1->data : src0->data);
3751    const size_t src0_o = src0->nb[1];
3752    const size_t src1_o = src1 ? src1->nb[1] : src0->nb[1];
3753
3754    GGML_ASSERT(ggml_is_contiguous_1(src0));
3755    GGML_ASSERT(ggml_is_contiguous_1(dst));
3756
3757    if (src1) {
3758        GGML_ASSERT(ggml_is_contiguous_1(src1));
3759        GGML_ASSERT(src0->type == src1->type);
3760    }
3761
3762    const int ith = params->ith;
3763    const int nth = params->nth;
3764
3765    const int nc = src1 ? src0->ne[0] : src0->ne[0] / 2;
3766    const int nr = ggml_nrows(src0);
3767
3768    GGML_ASSERT(dst->ne[0] == nc);
3769    GGML_ASSERT(ggml_nrows(dst) == nr);
3770
3771    const int32_t swapped = ggml_get_op_params_i32(dst, 1);
3772
3773    // rows per thread
3774    const int dr = (nr + nth - 1)/nth;
3775
3776    // row range for this thread
3777    const int ir0 = dr*ith;
3778    const int ir1 = MIN(ir0 + dr, nr);
3779
3780    for (int i1 = ir0; i1 < ir1; i1++) {
3781        ggml_fp16_t * src0_p = (ggml_fp16_t *) (src0_d + i1*src0_o);
3782        ggml_fp16_t * src1_p = (ggml_fp16_t *) (src1_d + i1*src1_o);
3783
3784        if (!src1) {
3785            src0_p += swapped ? nc : 0;
3786            src1_p += swapped ? 0 : nc;
3787        }
3788
3789        ggml_vec_geglu_quick_f16(nc, (ggml_fp16_t *) ((char *) dst->data + i1*(dst->nb[1])), src0_p, src1_p);
3790
3791#ifndef NDEBUG
3792        for (int k = 0; k < nc; k++) {
3793            const ggml_fp16_t x = ((ggml_fp16_t *) ((char *) dst->data + i1*( dst->nb[1])))[k];
3794            const float v = GGML_FP16_TO_FP32(x);
3795            GGML_UNUSED(v);
3796            assert(!isnan(v));
3797            assert(!isinf(v));
3798        }
3799#endif // NDEBUG
3800    }
3801}
3802
3803static void ggml_compute_forward_geglu_quick(
3804        const ggml_compute_params * params,
3805        ggml_tensor * dst) {
3806
3807    const ggml_tensor * src0 = dst->src[0];
3808
3809    switch (src0->type) {
3810        case GGML_TYPE_F32:
3811            {
3812                ggml_compute_forward_geglu_quick_f32(params, dst);
3813            } break;
3814        case GGML_TYPE_F16:
3815            {
3816                ggml_compute_forward_geglu_quick_f16(params, dst);
3817            } break;
3818        default:
3819            {
3820                GGML_ABORT("fatal error");
3821            }
3822    }
3823}
3824
3825// ggml_compute_forward_norm
3826
3827static void ggml_compute_forward_norm_f32(
3828        const ggml_compute_params * params,
3829        ggml_tensor * dst) {
3830
3831    const ggml_tensor * src0 = dst->src[0];
3832
3833    GGML_ASSERT(ggml_are_same_shape(src0, dst));
3834
3835    const int ith = params->ith;
3836    const int nth = params->nth;
3837
3838    GGML_TENSOR_UNARY_OP_LOCALS
3839
3840    float eps;
3841    memcpy(&eps, dst->op_params, sizeof(float));
3842
3843    GGML_ASSERT(eps >= 0.0f);
3844
3845    for (int64_t i03 = 0; i03 < ne03; i03++) {
3846        for (int64_t i02 = 0; i02 < ne02; i02++) {
3847            for (int64_t i01 = ith; i01 < ne01; i01 += nth) {
3848                const char * x = (const char *) src0->data + i01*nb01 + i02*nb02 + i03*nb03;
3849                char * y = (char *) dst->data + i01*nb1 + i02*nb2 + i03*nb3;
3850
3851                if (nb00 == sizeof(float) && nb0 == sizeof(float)) {
3852                    const float * xf = (const float *) x;
3853
3854                    float sum = 0.0;
3855                    ggml_vec_sum_f32(ne00, &sum, xf);
3856                    float mean = sum/ne00;
3857
3858                    float * yf = (float *) y;
3859                    float variance = 0;
3860
3861#ifdef GGML_USE_ACCELERATE
3862                    mean = -mean;
3863                    vDSP_vsadd(xf, 1, &mean, yf, 1, ne00);
3864                    vDSP_measqv(yf, 1, &variance, ne00);
3865#else
3866                    variance = ggml_vec_cvar_f32(ne00, yf, xf, mean);
3867#endif //GGML_USE_ACCELERATE
3868
3869                    const float scale = 1.0f/sqrtf(variance + eps);
3870                    ggml_vec_scale_f32(ne00, yf, scale);
3871                } else {
3872                    float sum = 0.0;
3873                    for (int64_t i00 = 0; i00 < ne00; i00++) {
3874                        sum += *(const float *) (x + i00*nb00);
3875                    }
3876                    const float mean = sum/ne00;
3877
3878                    float variance = 0.0f;
3879                    for (int64_t i00 = 0; i00 < ne00; i00++) {
3880                        const float v = *(const float *) (x + i00*nb00) - mean;
3881                        *(float *) (y + i00*nb0) = v;
3882                        variance += v * v;
3883                    }
3884                    variance /= ne00;
3885
3886                    const float scale = 1.0f/sqrtf(variance + eps);
3887                    for (int64_t i00 = 0; i00 < ne00; i00++) {
3888                        *(float *) (y + i00*nb0) *= scale;
3889                    }
3890                }
3891            }
3892        }
3893    }
3894}
3895
3896void ggml_compute_forward_norm(
3897        const ggml_compute_params * params,
3898        ggml_tensor * dst) {
3899
3900    const ggml_tensor * src0 = dst->src[0];
3901
3902    switch (src0->type) {
3903        case GGML_TYPE_F32:
3904            {
3905                ggml_compute_forward_norm_f32(params, dst);
3906            } break;
3907        default:
3908            {
3909                GGML_ABORT("fatal error");
3910            }
3911    }
3912}
3913
3914// ggml_compute_forward_group_rms_norm
3915
3916// fusion kinds that can be combined with the rms_norm computation in a single pass.
3917// extend this enum when adding new fused variants (e.g. FUSE_ADD, FUSE_MUL_ADD, ...).
3918enum ggml_rms_norm_fuse_op {
3919    GGML_RMS_NORM_FUSE_OP_NONE,
3920    GGML_RMS_NORM_FUSE_OP_MUL,
3921};
3922
3923template <ggml_rms_norm_fuse_op FUSE_OP>
3924static void ggml_compute_forward_rms_norm_f32(
3925        const ggml_compute_params * params,
3926        ggml_tensor * dst_rms_norm,
3927        ggml_tensor * dst_fused = nullptr) {
3928
3929    const ggml_tensor * src0 = dst_rms_norm->src[0];
3930    const ggml_tensor * src1 = nullptr;
3931    ggml_tensor       * dst  = dst_rms_norm;
3932
3933    if constexpr (FUSE_OP == GGML_RMS_NORM_FUSE_OP_MUL) {
3934        src1 = (dst_fused->src[0] == dst_rms_norm) ? dst_fused->src[1] : dst_fused->src[0];
3935        dst  = dst_fused;
3936    }
3937
3938    GGML_ASSERT(ggml_are_same_shape(src0, dst));
3939
3940    GGML_ASSERT(src0->nb[0] == sizeof(float));
3941
3942    const int ith = params->ith;
3943    const int nth = params->nth;
3944
3945    GGML_TENSOR_BINARY_OP_LOCALS
3946
3947    float eps;
3948    memcpy(&eps, dst_rms_norm->op_params, sizeof(float));
3949    GGML_ASSERT(eps >= 0.0f);
3950
3951    // TODO: optimize
3952    for (int64_t i03 = 0; i03 < ne03; i03++) {
3953        for (int64_t i02 = 0; i02 < ne02; i02++) {
3954            for (int64_t i01 = ith; i01 < ne01; i01 += nth) {
3955                const float * x = (float *) ((char *) src0->data + i01*nb01 + i02*nb02 + i03*nb03);
3956
3957                ggml_float sum = 0.0;
3958                // worth switching to explicit SIMD?
3959                for (int64_t i00 = 0; i00 < ne00; i00++) {
3960                    sum += (ggml_float)(x[i00] * x[i00]);
3961                }
3962
3963                const float mean  = sum/ne00;
3964                const float scale = 1.0f/sqrtf(mean + eps);
3965
3966                // if you hit this, likely you got an inf somewhere earlier
3967                assert(scale > 0.0f);
3968
3969                float * y = (float *) ((char *) dst->data + i01*nb1 + i02*nb2 + i03*nb3);
3970
3971                if constexpr (FUSE_OP == GGML_RMS_NORM_FUSE_OP_MUL) {
3972                    const int64_t i11 = i01 % ne11;
3973                    const int64_t i12 = i02 % ne12;
3974                    const int64_t i13 = i03 % ne13;
3975                    const float * w = (float *) ((char *) src1->data + i11*nb11 + i12*nb12 + i13*nb13);
3976
3977                    for (int64_t i00 = 0; i00 < ne00; i00++) {
3978                        y[i00] = x[i00] * scale * w[i00];
3979                    }
3980                } else {
3981                    memcpy(y, x, ne00 * sizeof(float));
3982                    ggml_vec_scale_f32(ne00, y, scale);
3983                }
3984            }
3985        }
3986    }
3987}
3988
3989void ggml_compute_forward_rms_norm(
3990        const ggml_compute_params * params,
3991        ggml_tensor * dst) {
3992
3993    const ggml_tensor * src0 = dst->src[0];
3994
3995    switch (src0->type) {
3996        case GGML_TYPE_F32:
3997            {
3998                ggml_compute_forward_rms_norm_f32<GGML_RMS_NORM_FUSE_OP_NONE>(params, dst);
3999            } break;
4000        default:
4001            {
4002                GGML_ABORT("fatal error");
4003            }
4004    }
4005}
4006
4007// Fused RMS_NORM + MUL: computes dst = rms_norm(src0) * src1 in a single pass.
4008// This avoids materializing the intermediate rms_norm result in memory.
4009void ggml_compute_forward_rms_norm_mul_fused(
4010        const ggml_compute_params * params,
4011        ggml_tensor * dst_rms_norm,
4012        ggml_tensor * dst_mul) {
4013
4014    GGML_ASSERT(dst_mul != nullptr);
4015    GGML_ASSERT(dst_mul->src[0] == dst_rms_norm || dst_mul->src[1] == dst_rms_norm);
4016
4017    const ggml_tensor * src0 = dst_rms_norm->src[0];
4018
4019    switch (src0->type) {
4020        case GGML_TYPE_F32:
4021            {
4022                ggml_compute_forward_rms_norm_f32<GGML_RMS_NORM_FUSE_OP_MUL>(params, dst_rms_norm, dst_mul);
4023            } break;
4024        default:
4025            {
4026                GGML_ABORT("fatal error");
4027            }
4028    }
4029}
4030
4031static void ggml_compute_forward_rms_norm_back_f32(
4032        const ggml_compute_params * params,
4033        ggml_tensor * dst) {
4034
4035    const ggml_tensor * src0 = dst->src[0]; // gradients from forward pass output
4036    const ggml_tensor * src1 = dst->src[1]; // src1 from forward pass
4037
4038    GGML_ASSERT(ggml_are_same_shape(src0, dst) && ggml_are_same_shape(src0, src1));
4039
4040    GGML_ASSERT(src0->nb[0] == sizeof(float));
4041    GGML_ASSERT(src1->nb[0] == sizeof(float));
4042
4043    const int ith = params->ith;
4044    const int nth = params->nth;
4045
4046    GGML_TENSOR_BINARY_OP_LOCALS
4047
4048    float eps;
4049    memcpy(&eps, dst->op_params, sizeof(float));
4050
4051    // TODO: optimize
4052    for (int64_t i03 = 0; i03 < ne03; i03++) {
4053        for (int64_t i02 = 0; i02 < ne02; i02++) {
4054            for (int64_t i01 = ith; i01 < ne01; i01 += nth) {
4055                // src1 is same shape as src0 => same indices
4056                const int64_t i11 = i01;
4057                const int64_t i12 = i02;
4058                const int64_t i13 = i03;
4059
4060                const float * dz = (float *) ((char *) src0->data + i01*nb01 + i02*nb02 + i03*nb03);
4061                const float * x  = (float *) ((char *) src1->data + i11*nb11 + i12*nb12 + i13*nb13);
4062
4063                ggml_float sum_xx  = 0.0;
4064                ggml_float sum_xdz = 0.0;
4065
4066                for (int64_t i00 = 0; i00 < ne00; i00++) {
4067                    sum_xx  += (ggml_float)(x[i00] * x[i00]);
4068                    sum_xdz += (ggml_float)(x[i00] * dz[i00]);
4069                }
4070
4071                //const float mean     = (float)(sum_xx)/ne00;
4072                const float mean_eps = (float)(sum_xx)/ne00 + eps;
4073                const float sum_eps  = (float)(sum_xx) + eps*ne00;
4074                //const float mean_xdz = (float)(sum_xdz)/ne00;
4075                // we could cache rms from forward pass to improve performance.
4076                // to do this implement ggml_rms and compose ggml_rms_norm using ggml_rms.
4077                //const float rms      = sqrtf(mean_eps);
4078                const float rrms     = 1.0f / sqrtf(mean_eps);
4079                //const float scale    = -rrms/(ne00 * mean_eps); // -1/(n*rms**3)
4080
4081                {
4082                    // z = rms_norm(x)
4083                    //
4084                    // rms_norm(src1) =
4085                    //     scale(
4086                    //         src1,
4087                    //         div(
4088                    //             1,
4089                    //             sqrt(
4090                    //                 add(
4091                    //                     scale(
4092                    //                         sum(
4093                    //                             sqr(
4094                    //                                 src1)),
4095                    //                         (1.0/N)),
4096                    //                     eps))));
4097
4098                    // postorder:
4099                    // ## op    args         grad
4100                    // 00 param src1         grad[#00]
4101                    // 01 const 1
4102                    // 02 sqr   (#00)        grad[#02]
4103                    // 03 sum   (#02)        grad[#03]
4104                    // 04 const 1/N
4105                    // 05 scale (#03, #04)   grad[#05]
4106                    // 06 const eps
4107                    // 07 add   (#05, #06)   grad[#07]
4108                    // 08 sqrt  (#07)        grad[#08]
4109                    // 09 div   (#01,#08)    grad[#09]
4110                    // 10 scale (#00,#09)    grad[#10]
4111                    //
4112                    // backward pass, given grad[#10]
4113                    // #10: scale
4114                    // grad[#00] += scale(grad[#10],#09)
4115                    // grad[#09] += sum(mul(grad[#10],#00))
4116                    // #09: div
4117                    // grad[#08] += neg(mul(grad[#09], div(#09,#08)))
4118                    // #08: sqrt
4119                    // grad[#07] += mul(grad[#08], div(0.5, #08))
4120                    // #07: add
4121                    // grad[#05] += grad[#07]
4122                    // #05: scale
4123                    // grad[#03] += scale(grad[#05],#04)
4124                    // #03: sum
4125                    // grad[#02] += repeat(grad[#03], #02)
4126                    // #02:
4127                    // grad[#00] += scale(mul(#00, grad[#02]), 2.0)
4128                    //
4129                    // substitute and simplify:
4130                    // grad[#00] = scale(grad(#10), #09) + scale(mul(#00, grad[#02]), 2.0)
4131                    // grad[#02] = repeat(grad[#03], #02)
4132                    // grad[#02] = repeat(scale(grad[#05],#04), #02)
4133                    // grad[#02] = repeat(scale(grad[#07],#04), #02)
4134                    // grad[#02] = repeat(scale(mul(grad[#08], div(0.5, #08)),#04), #02)
4135                    // grad[#02] = repeat(scale(mul(neg(mul(grad[#09], div(#09,#08))), div(0.5, #08)),#04), #02)
4136                    // grad[#02] = repeat(scale(mul(neg(mul(sum(mul(grad[#10],#00)), div(#09,#08))), div(0.5, #08)),#04), #02)
4137                    // grad[#02] = repeat(-(sum(mul(grad[#10],#00)) * div(#09,#08) * div(0.5, #08) * (1/N)), #02)
4138                    // grad[#02] = repeat(-(sum(mul(grad[#10],#00)) * div(div(#01,#08),#08) * div(0.5, #08) * (1/N)), #02)
4139                    // grad[#02] = repeat(-(sum(mul(grad[#10],#00)) * div(1,#08*#08) * div(0.5, #08) * (1/N)), #02)
4140                    // grad[#02] = repeat(-(sum(mul(grad[#10],#00)) * div(1,#07) * div(0.5, #08) * (1/N)), #02)
4141                    // grad[#00] = scale(grad(#10), #09) + scale(mul(#00, grad[#02]), 2.0)
4142                    // grad[#00] = scale(grad(#10), #09) + scale(mul(#00, repeat(-(sum(mul(grad[#10],#00)) * div(1,#07) * div(0.5, #08) * (1/N)), #02)), 2.0)
4143                    // grad[#00] = scale(grad(#10), #09) + scale(scale(#00, -(sum(mul(grad[#10],#00)) * div(1,#07) * div(0.5, #08) * (1/N))), 2.0)
4144                    // grad[#00] = scale(grad(#10), #09) + scale(#00, -(sum(mul(grad[#10],#00)) * div(1,#07) * div(1,#08) * (1/N)))
4145                    // grad[#00] = scale(grad(#10), #09) + scale(#00, sum(mul(grad[#10],#00)) * div(1,#07*#08) * (-1/N))
4146                    // grad[#00] = scale(grad(#10), #09) + scale(#00, sum(mul(grad[#10],#00)) * div(1,#07*#08) * (-1/N))
4147                    // grad[#00] = scale(grad(#10), #09) + scale(#00, sum(mul(grad[#10],#00)) * div(1,mean_eps*rms) * (-1/N))
4148                    // grad[#00] = scale(grad(#10), #09) + scale(#00, sum(mul(grad[#10],#00)) * div(-1,rms*N*mean_eps))
4149                    // grad[#00] = scale(grad(#10), #09) + scale(#00, sum(mul(grad[#10],#00)) * div(-1,rms*N*(sum_xx/N+eps)))
4150                    // grad[#00] = scale(grad(#10), #09) + scale(#00, sum(mul(grad[#10],#00)) * div(-1,rms*N*sum_xx+rms*N*eps))
4151                    // grad[#00] = scale(dz, rrms) + scale(x, sum(mul(dz,x)) * div(-1,rms*N*mean_eps))
4152                    // grad[#00] = scale(dz, rrms) + scale(x, sum_xdz * div(-1,rms*N*mean_eps))
4153                    // a = b*c + d*e
4154                    // a = b*c*f/f + d*e*f/f
4155                    // a = (b*c*f + d*e*f)*(1/f)
4156                    // a = (b*c*(1/c) + d*e*(1/c))*(1/(1/c))
4157                    // a = (b + d*e/c)*c
4158                    // b = dz, c = rrms, d = x, e = sum_xdz * div(-1,rms*N*mean_eps)
4159                    // a = (dz + x*sum_xdz * div(-1,rms*N*mean_eps)/rrms)*rrms
4160                    // a = (dz + x*sum_xdz * div(-1,rms*N*mean_eps)*rms)*rrms
4161                    // a = (dz + x*sum_xdz * div(-rms,rms*N*mean_eps))*rrms
4162                    // a = (dz + x*sum_xdz * div(-1,N*mean_eps))*rrms
4163                    // a = (dz + x*div(-sum_xdz,N*mean_eps))*rrms
4164                    // a = (dz + x*div(-mean_xdz,mean_eps))*rrms
4165                    // grad[#00] = scale(dz + scale(x, div(-mean_xdz,mean_eps)),rrms)
4166                    // grad[#00] = scale(dz + scale(x, -mean_xdz/mean_eps),rrms)
4167                    // dx = scale(dz + scale(x, -mean_xdz/mean_eps),rrms)
4168                }
4169                // dx = scale(dz + scale(x, -mean_xdz/mean_eps),rrms)
4170                // post-order:
4171                // dx := x
4172                // dx := scale(dx,-mean_xdz/mean_eps)
4173                // dx := add(dx, dz)
4174                // dx := scale(dx, rrms)
4175                float * dx = (float *) ((char *) dst->data + i01*nb1 + i02*nb2 + i03*nb3);
4176
4177                // dx[i00] = (dz + x*(-sum_xdz/sum_eps)) * rrms
4178                // note: https://github.com/ggml-org/ggml/issues/1491
4179                const float scale_x = (float) (-sum_xdz) / sum_eps;
4180                for (int64_t i00 = 0; i00 < ne00; i00++) {
4181                    dx[i00] = (dz[i00] + x[i00] * scale_x) * rrms;
4182                }
4183            }
4184        }
4185    }
4186}
4187
4188void ggml_compute_forward_rms_norm_back(
4189        const ggml_compute_params * params,
4190        ggml_tensor * dst) {
4191
4192    const ggml_tensor * src0 = dst->src[0];
4193
4194    switch (src0->type) {
4195        case GGML_TYPE_F32:
4196            {
4197                ggml_compute_forward_rms_norm_back_f32(params, dst);
4198            } break;
4199        default:
4200            {
4201                GGML_ABORT("fatal error");
4202            }
4203    }
4204}
4205
4206// ggml_compute_forward_group_norm
4207
4208static void ggml_compute_forward_group_norm_f32(
4209    const ggml_compute_params * params,
4210    ggml_tensor * dst) {
4211
4212    const ggml_tensor * src0 = dst->src[0];
4213
4214    GGML_ASSERT(ggml_are_same_shape(src0, dst));
4215
4216    GGML_ASSERT(src0->nb[0] == sizeof(float));
4217
4218    const int ith = params->ith;
4219    const int nth = params->nth;
4220
4221    GGML_TENSOR_UNARY_OP_LOCALS
4222
4223    // TODO: optimize
4224
4225    float eps;
4226    memcpy(&eps, dst->op_params + 1, sizeof(float));
4227
4228    int n_channels = src0->ne[2];
4229    int n_groups = dst->op_params[0];
4230    int n_channels_per_group = (n_channels + n_groups - 1) / n_groups;
4231    for (int i = ith; i < n_groups; i += nth) {
4232        int start = i * n_channels_per_group;
4233        int end = start + n_channels_per_group;
4234        if (end > n_channels) {
4235            end = n_channels;
4236        }
4237        int step = end - start;
4238
4239        for (int64_t i03 = 0; i03 < ne03; i03++) {
4240            ggml_float sum = 0.0;
4241            for (int64_t i02 = start; i02 < end; i02++) {
4242                for (int64_t i01 = 0; i01 < ne01; i01++) {
4243                    const float * x = (float *)((char *) src0->data + i01 * nb01 + i02 * nb02 + i03 * nb03);
4244
4245                    ggml_float sumr = 0.0;
4246                    for (int64_t i00 = 0; i00 < ne00; i00++) {
4247                        sumr += (ggml_float)x[i00];
4248                    }
4249                    sum += sumr;
4250                }
4251            }
4252            const float mean = sum / (ne00 * ne01 * step);
4253
4254            ggml_float sum2 = 0.0;
4255            for (int64_t i02 = start; i02 < end; i02++) {
4256                for (int64_t i01 = 0; i01 < ne01; i01++) {
4257                    const float * x = (float *)((char *) src0->data + i01 * nb01 + i02 * nb02 + i03 * nb03);
4258
4259                    float * y = (float *)((char *) dst->data + i01 * nb1 + i02 * nb2 + i03 * nb3);
4260
4261                    ggml_float sumr = 0.0;
4262                    for (int64_t i00 = 0; i00 < ne00; i00++) {
4263                        float v = x[i00] - mean;
4264                        y[i00] = v;
4265                        sumr += (ggml_float)(v * v);
4266                    }
4267                    sum2 += sumr;
4268                }
4269            }
4270            const float variance = sum2 / (ne00 * ne01 * step);
4271            const float scale = 1.0f / sqrtf(variance + eps);
4272
4273            for (int64_t i02 = start; i02 < end; i02++) {
4274                for (int64_t i01 = 0; i01 < ne01; i01++) {
4275                    float * y = (float *)((char *) dst->data + i01 * nb1 + i02 * nb2 + i03 * nb3);
4276                    ggml_vec_scale_f32(ne00, y, scale);
4277                }
4278            }
4279        }
4280    }
4281}
4282
4283void ggml_compute_forward_group_norm(
4284    const ggml_compute_params * params,
4285    ggml_tensor * dst) {
4286
4287    const ggml_tensor * src0 = dst->src[0];
4288
4289    switch (src0->type) {
4290        case GGML_TYPE_F32:
4291            {
4292                ggml_compute_forward_group_norm_f32(params, dst);
4293            } break;
4294        default:
4295            {
4296                GGML_ABORT("fatal error");
4297            }
4298    }
4299}
4300
4301// ggml_compute_forward_l2_norm
4302
4303static void ggml_compute_forward_l2_norm_f32(
4304    const ggml_compute_params * params,
4305    ggml_tensor * dst) {
4306
4307    const ggml_tensor * src0 = dst->src[0];
4308
4309    GGML_ASSERT(ggml_are_same_shape(src0, dst));
4310
4311    const int ith = params->ith;
4312    const int nth = params->nth;
4313
4314    GGML_TENSOR_UNARY_OP_LOCALS
4315
4316    float eps;
4317    memcpy(&eps, dst->op_params, sizeof(float));
4318
4319    GGML_ASSERT(eps >= 0.0f);
4320
4321    // TODO: optimize
4322    for (int64_t i03 = 0; i03 < ne03; i03++) {
4323        for (int64_t i02 = 0; i02 < ne02; i02++) {
4324            for (int64_t i01 = ith; i01 < ne01; i01 += nth) {
4325                const char * x = (const char *) src0->data + i01*nb01 + i02*nb02 + i03*nb03;
4326
4327                ggml_float sum = 0.0;
4328                for (int64_t i00 = 0; i00 < ne00; i00++) {
4329                    const float xi = *(const float *) (x + i00*nb00);
4330                    sum += (ggml_float)(xi * xi);
4331                }
4332
4333                const float scale = 1.0f/fmaxf(sqrtf(sum), eps);
4334
4335                char * y = (char *) dst->data + i01*nb1 + i02*nb2 + i03*nb3;
4336
4337                if (nb00 == sizeof(float) && nb0 == sizeof(float)) {
4338                    memcpy(y, x, ne00 * sizeof(float));
4339                    ggml_vec_scale_f32(ne00, (float *) y, scale);
4340                } else {
4341                    for (int64_t i00 = 0; i00 < ne00; i00++) {
4342                        const float xi = *(const float *) (x + i00*nb00);
4343                        *(float *) (y + i00*nb0) = xi * scale;
4344                    }
4345                }
4346            }
4347        }
4348    }
4349}
4350
4351void ggml_compute_forward_l2_norm(
4352    const ggml_compute_params * params,
4353    ggml_tensor * dst) {
4354
4355    const ggml_tensor * src0 = dst->src[0];
4356
4357    switch (src0->type) {
4358        case GGML_TYPE_F32:
4359            {
4360                ggml_compute_forward_l2_norm_f32(params, dst);
4361            } break;
4362        default:
4363            {
4364                GGML_ABORT("fatal error");
4365            }
4366    }
4367}
4368
4369// ggml_compute_forward_out_prod
4370
4371static void ggml_compute_forward_out_prod_f32(
4372        const ggml_compute_params * params,
4373              ggml_tensor * dst) {
4374
4375    const ggml_tensor * src0 = dst->src[0];
4376    const ggml_tensor * src1 = dst->src[1];
4377
4378    GGML_TENSOR_BINARY_OP_LOCALS
4379
4380    GGML_ASSERT(dst->type == GGML_TYPE_F32);
4381    GGML_ASSERT(src0->type == GGML_TYPE_F32);
4382    GGML_ASSERT(src1->type == GGML_TYPE_F32);
4383
4384    const int ith = params->ith;
4385    const int nth = params->nth;
4386
4387    GGML_ASSERT(ne0 == ne00);
4388    GGML_ASSERT(ne1 == ne10);
4389    GGML_ASSERT(ne2 == ne12);
4390    GGML_ASSERT(ne3 == ne13);
4391
4392    GGML_ASSERT(ne2 % ne02 == 0);
4393    GGML_ASSERT(ne3 % ne03 == 0);
4394
4395    // we don't support permuted src0 or src1
4396    GGML_ASSERT(nb00 == sizeof(float));
4397
4398    // dst cannot be transposed or permuted
4399    GGML_ASSERT(nb0 == sizeof(float));
4400    // GGML_ASSERT(nb0 <= nb1);
4401    // GGML_ASSERT(nb1 <= nb2);
4402    // GGML_ASSERT(nb2 <= nb3);
4403
4404    // nb01 >= nb00 - src0 is not transposed
4405    //   compute by src0 rows
4406
4407    if (ith == 0) {
4408        ggml_vec_set_f32(ne0*ne1*ne2*ne3, (float *)dst->data, 0);
4409    }
4410    ggml_barrier(params->threadpool);
4411
4412    // dst[:,:,:,:] = 0
4413    // for i2,i3:
4414    //   for i1:
4415    //     for i01:
4416    //       for i0:
4417    //         dst[i0,i1,i2,i3] += src0[i0,i01,i2,i3] * src1[i1,i01,i2,i3]
4418
4419    // parallelize by last three dimensions
4420
4421    // total rows in dst
4422    const int64_t nr = ne1*ne2*ne3;
4423
4424    // rows per thread
4425    const int64_t dr = (nr + nth - 1)/nth;
4426
4427    // row range for this thread
4428    const int64_t ir0 = dr*ith;
4429    const int64_t ir1 = MIN(ir0 + dr, nr);
4430
4431    // block-tiling attempt
4432    const int64_t blck_0 = MAX(GGML_VEC_MAD_UNROLL, 32);
4433    const int64_t blck_1 = 16;
4434
4435    // dps == dst per src0, used for group query attention
4436    const int64_t dps2 = ne2 / ne02;
4437    const int64_t dps3 = ne3 / ne03;
4438
4439    for (int64_t bir = ir0; bir < ir1; bir += blck_1) {
4440        const int64_t bir1 = MIN(bir + blck_1, ir1);
4441        for (int64_t bi01 = 0; bi01 < ne01; bi01 += blck_0) {
4442            const int64_t bne01 = MIN(bi01 + blck_0, ne01);
4443            for (int64_t ir = bir; ir < bir1; ++ir) {
4444                // dst indices
4445                const int64_t i3 = ir/(ne2*ne1);
4446                const int64_t i2 = (ir - i3*ne2*ne1)/ne1;
4447                const int64_t i1 = (ir - i3*ne2*ne1 - i2*ne1);
4448
4449                const int64_t i02 = i2 / dps2;
4450                const int64_t i03 = i3 / dps3;
4451
4452                //const int64_t i10 = i1;
4453                const int64_t i12 = i2;
4454                const int64_t i13 = i3;
4455
4456#if GGML_VEC_MAD_UNROLL > 2
4457                const int64_t bne01_unroll = bne01 - (bne01 % GGML_VEC_MAD_UNROLL);
4458                for (int64_t i01 = bi01; i01 < bne01_unroll; i01 += GGML_VEC_MAD_UNROLL) {
4459                    const int64_t i11 = i01;
4460
4461                    float * s0 = (float *) ((char *) src0->data + (          i01*nb01 + i02*nb02 + i03*nb03));
4462                    float * s1 = (float *) ((char *) src1->data + (i1*nb10 + i11*nb11 + i12*nb12 + i13*nb13));
4463                    float * d  = (float *) ((char *)  dst->data + (          i1*nb1   + i2*nb2   + i3*nb3));
4464
4465                    ggml_vec_mad_f32_unroll(ne0, nb01, nb11, d, s0, s1);
4466                }
4467                for (int64_t i01 = bne01_unroll; i01 < bne01; ++i01) {
4468                    const int64_t i11 = i01;
4469
4470                    float * s0 = (float *) ((char *) src0->data + (          i01*nb01 + i02*nb02 + i03*nb03));
4471                    float * s1 = (float *) ((char *) src1->data + (i1*nb10 + i11*nb11 + i12*nb12 + i13*nb13));
4472                    float * d  = (float *) ((char *)  dst->data + (          i1*nb1   + i2*nb2   + i3*nb3));
4473
4474                    ggml_vec_mad_f32(ne0, d, s0, *s1);
4475                }
4476#else
4477                for (int64_t i01 = bi01; i01 < bne01; ++i01) {
4478                    const int64_t i11 = i01;
4479
4480                    float * s0 = (float *) ((char *) src0->data + (          i01*nb01 + i02*nb02 + i03*nb03));
4481                    float * s1 = (float *) ((char *) src1->data + (i1*nb10 + i11*nb11 + i12*nb12 + i13*nb13));
4482                    float * d  = (float *) ((char *)  dst->data + (          i1*nb1 + i2*nb2 + i3*nb3));
4483
4484                    ggml_vec_mad_f32(ne0, d, s0, *s1);
4485                }
4486#endif
4487            }
4488        }
4489    }
4490}
4491
4492static void ggml_compute_forward_out_prod_q_f32(
4493        const ggml_compute_params * params,
4494              ggml_tensor * dst) {
4495
4496    const ggml_tensor * src0 = dst->src[0];
4497    const ggml_tensor * src1 = dst->src[1];
4498
4499    GGML_TENSOR_BINARY_OP_LOCALS;
4500
4501    const int ith = params->ith;
4502    const int nth = params->nth;
4503
4504    const ggml_type type = src0->type;
4505    ggml_to_float_t const dequantize_row_q = ggml_get_type_traits(type)->to_float;
4506
4507    GGML_ASSERT(ne02 == ne12);
4508    GGML_ASSERT(ne03 == ne13);
4509    GGML_ASSERT(ne2  == ne12);
4510    GGML_ASSERT(ne3  == ne13);
4511
4512    // we don't support permuted src0 dim0
4513    GGML_ASSERT(nb00 == ggml_type_size(type));
4514
4515    // dst dim0 cannot be transposed or permuted
4516    GGML_ASSERT(nb0 == sizeof(float));
4517    // GGML_ASSERT(nb0 <= nb1);
4518    // GGML_ASSERT(nb1 <= nb2);
4519    // GGML_ASSERT(nb2 <= nb3);
4520
4521    GGML_ASSERT(ne0 == ne00);
4522    GGML_ASSERT(ne1 == ne10);
4523    GGML_ASSERT(ne2 == ne02);
4524    GGML_ASSERT(ne3 == ne03);
4525
4526    // nb01 >= nb00 - src0 is not transposed
4527    //   compute by src0 rows
4528
4529    if (ith == 0) {
4530        ggml_vec_set_f32(ne0*ne1*ne2*ne3, (float *)dst->data, 0);
4531    }
4532    ggml_barrier(params->threadpool);
4533
4534    // parallelize by last three dimensions
4535
4536    // total rows in dst
4537    const int64_t nr = ne1*ne2*ne3;
4538
4539    // rows per thread
4540    const int64_t dr = (nr + nth - 1)/nth;
4541
4542    // row range for this thread
4543    const int64_t ir0 = dr*ith;
4544    const int64_t ir1 = MIN(ir0 + dr, nr);
4545
4546    // dst[:,:,:,:] = 0
4547    // for i2,i3:
4548    //   for i1:
4549    //     for i01:
4550    //       for i0:
4551    //         dst[i0,i1,i2,i3] += src0[i0,i01,i2,i3] * src1[i1,i01,i2,i3]
4552
4553    float * wdata = (float *) params->wdata + (ne0 + CACHE_LINE_SIZE_F32) * ith;
4554
4555    for (int64_t ir = ir0; ir < ir1; ++ir) {
4556        // dst indices
4557        const int64_t i3 = ir/(ne2*ne1);
4558        const int64_t i2 = (ir - i3*ne2*ne1)/ne1;
4559        const int64_t i1 = (ir - i3*ne2*ne1 - i2*ne1);
4560
4561        const int64_t i02 = i2;
4562        const int64_t i03 = i3;
4563
4564        //const int64_t i10 = i1;
4565        const int64_t i12 = i2;
4566        const int64_t i13 = i3;
4567
4568        for (int64_t i01 = 0; i01 < ne01; ++i01) {
4569            const int64_t i11 = i01;
4570
4571            float * s0 = (float *) ((char *) src0->data + (          i01*nb01 + i02*nb02 + i03*nb03));
4572            float * s1 = (float *) ((char *) src1->data + (i1*nb10 + i11*nb11 + i12*nb12 + i13*nb13));
4573            float * d  = (float *) ((char *)  dst->data + (          i1*nb1 + i2*nb2 + i3*nb3));
4574
4575            dequantize_row_q(s0, wdata, ne0);
4576            ggml_vec_mad_f32(ne0, d, wdata, *s1);
4577        }
4578    }
4579}
4580
4581static void ggml_compute_forward_out_prod_f16_f32(
4582        const ggml_compute_params * params,
4583              ggml_tensor * dst) {
4584
4585    const ggml_tensor * src0 = dst->src[0];
4586    const ggml_tensor * src1 = dst->src[1];
4587
4588    GGML_TENSOR_BINARY_OP_LOCALS;
4589
4590    const int ith = params->ith;
4591    const int nth = params->nth;
4592
4593    GGML_ASSERT(src0->type == GGML_TYPE_F16);
4594    GGML_ASSERT(src1->type == GGML_TYPE_F32);
4595    GGML_ASSERT(dst->type == GGML_TYPE_F32);
4596
4597    GGML_ASSERT(ne02 == ne12);
4598    GGML_ASSERT(ne03 == ne13);
4599    GGML_ASSERT(ne2  == ne12);
4600    GGML_ASSERT(ne3  == ne13);
4601
4602    GGML_ASSERT(nb00 == sizeof(ggml_fp16_t));
4603    GGML_ASSERT(nb0  == sizeof(float));
4604
4605    GGML_ASSERT(ne0 == ne00);
4606    GGML_ASSERT(ne1 == ne10);
4607    GGML_ASSERT(ne2 == ne02);
4608    GGML_ASSERT(ne3 == ne03);
4609
4610    if (ith == 0) {
4611        ggml_vec_set_f32(ne0*ne1*ne2*ne3, (float *)dst->data, 0);
4612    }
4613    ggml_barrier(params->threadpool);
4614
4615    const int64_t nr = ne1*ne2*ne3;
4616    const int64_t dr = (nr + nth - 1)/nth;
4617    const int64_t ir0 = dr*ith;
4618    const int64_t ir1 = MIN(ir0 + dr, nr);
4619
4620    float * wdata = (float *) params->wdata + (ne0 + CACHE_LINE_SIZE_F32) * ith;
4621
4622    for (int64_t ir = ir0; ir < ir1; ++ir) {
4623        const int64_t i3 = ir/(ne2*ne1);
4624        const int64_t i2 = (ir - i3*ne2*ne1)/ne1;
4625        const int64_t i1 = (ir - i3*ne2*ne1 - i2*ne1);
4626
4627        const int64_t i02 = i2;
4628        const int64_t i03 = i3;
4629
4630        const int64_t i12 = i2;
4631        const int64_t i13 = i3;
4632
4633        float * d = (float *) ((char *) dst->data + (i1*nb1 + i2*nb2 + i3*nb3));
4634
4635        for (int64_t i01 = 0; i01 < ne01; ++i01) {
4636            const int64_t i11 = i01;
4637            ggml_fp16_t * s0 = (ggml_fp16_t *) ((char *) src0->data + (i01*nb01 + i02*nb02 + i03*nb03));
4638            float * s1 = (float *) ((char *) src1->data + (i1*nb10 + i11*nb11 + i12*nb12 + i13*nb13));
4639            ggml_fp16_to_fp32_row(s0, wdata, ne0);
4640            ggml_vec_mad_f32(ne0, d, wdata, *s1);
4641        }
4642    }
4643}
4644
4645void ggml_compute_forward_out_prod(
4646        const ggml_compute_params * params,
4647        ggml_tensor * dst) {
4648
4649    const ggml_tensor * src0 = dst->src[0];
4650
4651    switch (src0->type) {
4652        case GGML_TYPE_Q1_0:
4653        case GGML_TYPE_Q2_0:
4654        case GGML_TYPE_Q4_0:
4655        case GGML_TYPE_Q4_1:
4656        case GGML_TYPE_Q5_0:
4657        case GGML_TYPE_Q5_1:
4658        case GGML_TYPE_Q8_0:
4659        case GGML_TYPE_MXFP4:
4660        case GGML_TYPE_NVFP4:
4661        case GGML_TYPE_Q2_K:
4662        case GGML_TYPE_Q3_K:
4663        case GGML_TYPE_Q4_K:
4664        case GGML_TYPE_Q5_K:
4665        case GGML_TYPE_Q6_K:
4666        case GGML_TYPE_TQ1_0:
4667        case GGML_TYPE_TQ2_0:
4668        case GGML_TYPE_IQ2_XXS:
4669        case GGML_TYPE_IQ2_XS:
4670        case GGML_TYPE_IQ3_XXS:
4671        case GGML_TYPE_IQ1_S:
4672        case GGML_TYPE_IQ1_M:
4673        case GGML_TYPE_IQ4_NL:
4674        case GGML_TYPE_IQ4_XS:
4675        case GGML_TYPE_IQ3_S:
4676        case GGML_TYPE_IQ2_S:
4677            {
4678                ggml_compute_forward_out_prod_q_f32(params, dst);
4679            } break;
4680        case GGML_TYPE_F16:
4681            {
4682                ggml_compute_forward_out_prod_f16_f32(params, dst);
4683            } break;
4684        case GGML_TYPE_F32:
4685            {
4686                ggml_compute_forward_out_prod_f32(params, dst);
4687            } break;
4688        default:
4689            {
4690                GGML_ABORT("fatal error");
4691            }
4692    }
4693}
4694
4695// ggml_compute_forward_scale
4696
4697static void ggml_compute_forward_scale_f32(
4698        const ggml_compute_params * params,
4699        ggml_tensor * dst) {
4700
4701    const ggml_tensor * src0 = dst->src[0];
4702
4703    GGML_ASSERT(ggml_is_contiguous(src0));
4704    GGML_ASSERT(ggml_is_contiguous(dst));
4705    GGML_ASSERT(ggml_are_same_shape(src0, dst));
4706
4707    float s; // scale factor
4708    float b; // bias
4709
4710    memcpy(&s, (float *) dst->op_params + 0, sizeof(float));
4711    memcpy(&b, (float *) dst->op_params + 1, sizeof(float));
4712
4713    const int ith = params->ith;
4714    const int nth = params->nth;
4715
4716    const int nc = src0->ne[0];
4717    const int nr = ggml_nrows(src0);
4718
4719    // rows per thread
4720    const int dr = (nr + nth - 1)/nth;
4721
4722    // row range for this thread
4723    const int ir0 = dr*ith;
4724    const int ir1 = MIN(ir0 + dr, nr);
4725
4726    const size_t nb01 = src0->nb[1];
4727
4728    const size_t nb1 = dst->nb[1];
4729
4730    if (b == 0.0f) {
4731        for (int i1 = ir0; i1 < ir1; i1++) {
4732            if (dst->data != src0->data) {
4733                // src0 is same shape as dst => same indices
4734                // TODO: add x parameter to ggml_vec_scale_f32 and remove this memcpy
4735                memcpy((char *)dst->data + i1*nb1, (char *)src0->data + i1*nb01, nc * sizeof(float));
4736            }
4737            ggml_vec_scale_f32(nc, (float *) ((char *) dst->data + i1*nb1), s);
4738        }
4739    } else {
4740        for (int i1 = ir0; i1 < ir1; i1++) {
4741            ggml_vec_mad1_f32(nc,
4742                (float *) ((char *) dst->data  + i1*nb1),
4743                (float *) ((char *) src0->data + i1*nb1),
4744                s, b);
4745        }
4746    }
4747}
4748
4749void ggml_compute_forward_scale(
4750        const ggml_compute_params * params,
4751        ggml_tensor * dst) {
4752
4753    const ggml_tensor * src0 = dst->src[0];
4754
4755    switch (src0->type) {
4756        case GGML_TYPE_F32:
4757            {
4758                ggml_compute_forward_scale_f32(params, dst);
4759            } break;
4760        default:
4761            {
4762                GGML_ABORT("fatal error");
4763            }
4764    }
4765}
4766
4767// ggml_compute_forward_set
4768
4769static void ggml_compute_forward_set_f32(
4770        const ggml_compute_params * params,
4771        ggml_tensor * dst) {
4772
4773    const ggml_tensor * src0 = dst->src[0];
4774    const ggml_tensor * src1 = dst->src[1];
4775
4776    GGML_ASSERT(ggml_are_same_shape(src0, dst));
4777    GGML_ASSERT(ggml_is_contiguous(dst) && ggml_is_contiguous(src0));
4778
4779    // view src0 and dst with these strides and data offset inbytes during set
4780    // nb0 is implicitly element_size because src0 and dst are contiguous
4781    size_t nb1     = ((int32_t *) dst->op_params)[0];
4782    size_t nb2     = ((int32_t *) dst->op_params)[1];
4783    size_t nb3     = ((int32_t *) dst->op_params)[2];
4784    size_t offset  = ((int32_t *) dst->op_params)[3];
4785    bool   inplace = (bool) ((int32_t *) dst->op_params)[4];
4786
4787    if (!inplace) {
4788        if (params->ith == 0) {
4789            // memcpy needs to be synchronized across threads to avoid race conditions.
4790            // => do it in INIT phase
4791            memcpy(
4792                ((char *)  dst->data),
4793                ((char *) src0->data),
4794                ggml_nbytes(dst));
4795        }
4796        ggml_barrier(params->threadpool);
4797    }
4798
4799    const int ith = params->ith;
4800    const int nth = params->nth;
4801
4802    const int nr = ggml_nrows(src1);
4803    const int nc = src1->ne[0];
4804
4805    GGML_TENSOR_LOCALS(int64_t, ne1, src1, ne)
4806    GGML_TENSOR_LOCALS(size_t,  nb1, src1, nb)
4807
4808    // src0 and dst as viewed during set
4809    const size_t nb0 = ggml_element_size(src0);
4810
4811    const int im0 = (ne10 == 0 ? 0 : ne10-1);
4812    const int im1 = (ne11 == 0 ? 0 : ne11-1);
4813    const int im2 = (ne12 == 0 ? 0 : ne12-1);
4814    const int im3 = (ne13 == 0 ? 0 : ne13-1);
4815
4816    GGML_ASSERT(offset + im0*nb0  + im1*nb1  + im2*nb2  + im3*nb3  <= ggml_nbytes(dst));
4817
4818    GGML_ASSERT(nb10 == sizeof(float));
4819
4820    // rows per thread
4821    const int dr = (nr + nth - 1)/nth;
4822
4823    // row range for this thread
4824    const int ir0 = dr*ith;
4825    const int ir1 = MIN(ir0 + dr, nr);
4826
4827    for (int ir = ir0; ir < ir1; ++ir) {
4828        // src0 and dst are viewed with shape of src1 and offset
4829        // => same indices
4830        const int i3 = ir/(ne12*ne11);
4831        const int i2 = (ir - i3*ne12*ne11)/ne11;
4832        const int i1 = (ir - i3*ne12*ne11 - i2*ne11);
4833
4834        ggml_vec_cpy_f32(nc,
4835                (float *) ((char *)  dst->data + i3*nb3  + i2*nb2  + i1*nb1  + offset),
4836                (float *) ((char *) src1->data + i3*nb13 + i2*nb12 + i1*nb11));
4837    }
4838}
4839
4840static void ggml_compute_forward_set_i32(
4841        const ggml_compute_params * params,
4842        ggml_tensor * dst) {
4843
4844    const ggml_tensor * src0 = dst->src[0];
4845    const ggml_tensor * src1 = dst->src[1];
4846
4847    GGML_ASSERT(ggml_are_same_shape(src0, dst));
4848    GGML_ASSERT(ggml_is_contiguous(dst) && ggml_is_contiguous(src0));
4849
4850    // view src0 and dst with these strides and data offset inbytes during set
4851    // nb0 is implicitly element_size because src0 and dst are contiguous
4852    size_t nb1     = ((int32_t *) dst->op_params)[0];
4853    size_t nb2     = ((int32_t *) dst->op_params)[1];
4854    size_t nb3     = ((int32_t *) dst->op_params)[2];
4855    size_t offset  = ((int32_t *) dst->op_params)[3];
4856    bool   inplace = (bool) ((int32_t *) dst->op_params)[4];
4857
4858    if (!inplace) {
4859        if (params->ith == 0) {
4860            // memcpy needs to be synchronized across threads to avoid race conditions.
4861            // => do it in INIT phase
4862            memcpy(
4863                ((char *)  dst->data),
4864                ((char *) src0->data),
4865                ggml_nbytes(dst));
4866        }
4867        ggml_barrier(params->threadpool);
4868    }
4869
4870    const int ith = params->ith;
4871    const int nth = params->nth;
4872
4873    const int nr = ggml_nrows(src1);
4874    const int nc = src1->ne[0];
4875
4876    GGML_TENSOR_LOCALS(int64_t, ne1, src1, ne)
4877    GGML_TENSOR_LOCALS(size_t,  nb1, src1, nb)
4878
4879    // src0 and dst as viewed during set
4880    const size_t nb0 = ggml_element_size(src0);
4881
4882    const int im0 = (ne10 == 0 ? 0 : ne10-1);
4883    const int im1 = (ne11 == 0 ? 0 : ne11-1);
4884    const int im2 = (ne12 == 0 ? 0 : ne12-1);
4885    const int im3 = (ne13 == 0 ? 0 : ne13-1);
4886
4887    GGML_ASSERT(offset + im0*nb0  + im1*nb1  + im2*nb2  + im3*nb3  <= ggml_nbytes(dst));
4888
4889    GGML_ASSERT(nb10 == sizeof(int32_t));
4890
4891    // rows per thread
4892    const int dr = (nr + nth - 1)/nth;
4893
4894    // row range for this thread
4895    const int ir0 = dr*ith;
4896    const int ir1 = MIN(ir0 + dr, nr);
4897
4898    for (int ir = ir0; ir < ir1; ++ir) {
4899        // src0 and dst are viewed with shape of src1 and offset
4900        // => same indices
4901        const int i3 = ir/(ne12*ne11);
4902        const int i2 = (ir - i3*ne12*ne11)/ne11;
4903        const int i1 = (ir - i3*ne12*ne11 - i2*ne11);
4904
4905        ggml_vec_cpy_i32(nc,
4906                (int32_t *) ((char *)  dst->data + i3*nb3  + i2*nb2  + i1*nb1  + offset),
4907                (int32_t *) ((char *) src1->data + i3*nb13 + i2*nb12 + i1*nb11));
4908    }
4909}
4910
4911void ggml_compute_forward_set(
4912        const ggml_compute_params * params,
4913        ggml_tensor * dst) {
4914
4915    const ggml_tensor * src0 = dst->src[0];
4916
4917    switch (src0->type) {
4918        case GGML_TYPE_F32:
4919            {
4920                ggml_compute_forward_set_f32(params, dst);
4921            } break;
4922        case GGML_TYPE_I32:
4923            {
4924                ggml_compute_forward_set_i32(params, dst);
4925            } break;
4926        case GGML_TYPE_F16:
4927        case GGML_TYPE_BF16:
4928        case GGML_TYPE_Q1_0:
4929        case GGML_TYPE_Q2_0:
4930        case GGML_TYPE_Q4_0:
4931        case GGML_TYPE_Q4_1:
4932        case GGML_TYPE_Q5_0:
4933        case GGML_TYPE_Q5_1:
4934        case GGML_TYPE_Q8_0:
4935        case GGML_TYPE_Q8_1:
4936        case GGML_TYPE_MXFP4:
4937        case GGML_TYPE_NVFP4:
4938        case GGML_TYPE_Q2_K:
4939        case GGML_TYPE_Q3_K:
4940        case GGML_TYPE_Q4_K:
4941        case GGML_TYPE_Q5_K:
4942        case GGML_TYPE_Q6_K:
4943        case GGML_TYPE_TQ1_0:
4944        case GGML_TYPE_TQ2_0:
4945        case GGML_TYPE_IQ2_XXS:
4946        case GGML_TYPE_IQ2_XS:
4947        case GGML_TYPE_IQ3_XXS:
4948        case GGML_TYPE_IQ1_S:
4949        case GGML_TYPE_IQ1_M:
4950        case GGML_TYPE_IQ4_NL:
4951        case GGML_TYPE_IQ4_XS:
4952        case GGML_TYPE_IQ3_S:
4953        case GGML_TYPE_IQ2_S:
4954        default:
4955            {
4956                GGML_ABORT("fatal error");
4957            }
4958    }
4959}
4960
4961// ggml_compute_forward_cpy
4962
4963void ggml_compute_forward_cpy(
4964        const ggml_compute_params * params,
4965        ggml_tensor * dst) {
4966    ggml_compute_forward_dup(params, dst);
4967}
4968
4969// ggml_compute_forward_cont
4970
4971void ggml_compute_forward_cont(
4972        const ggml_compute_params * params,
4973        ggml_tensor * dst) {
4974    ggml_compute_forward_dup(params, dst);
4975}
4976
4977// ggml_compute_forward_get_rows
4978
4979static void ggml_compute_forward_get_rows_q(
4980        const ggml_compute_params * params,
4981              ggml_tensor * dst) {
4982
4983    const ggml_tensor * src0 = dst->src[0];
4984    const ggml_tensor * src1 = dst->src[1];
4985
4986    GGML_TENSOR_BINARY_OP_LOCALS
4987
4988    const int64_t nc = ne00;
4989    const int64_t nr = ggml_nelements(src1);
4990
4991    const ggml_type type = src0->type;
4992    ggml_to_float_t const dequantize_row_q = ggml_get_type_traits(type)->to_float;
4993
4994    assert(ne0  == nc);
4995    assert(ne02 == ne11);
4996    assert(nb00 == ggml_type_size(type));
4997    assert(ggml_nrows(dst) == nr);
4998
4999    const int ith = params->ith;
5000    const int nth = params->nth;
5001
5002    // rows per thread
5003    const int dr = (nr + nth - 1)/nth;
5004
5005    // row range for this thread
5006    const int ir0 = dr*ith;
5007    const int ir1 = MIN(ir0 + dr, nr);
5008
5009    for (int64_t i = ir0; i < ir1; ++i) {
5010        const int64_t i12 = i/(ne11*ne10);
5011        const int64_t i11 = (i - i12*ne11*ne10)/ne10;
5012        const int64_t i10 = (i - i12*ne11*ne10 - i11*ne10);
5013        const int64_t i01 = *(int32_t *) ((char *) src1->data + i10*nb10 + i11*nb11 + i12*nb12);
5014
5015        GGML_ASSERT(i01 >= 0 && i01 < ne01);
5016
5017        dequantize_row_q(
5018                (const void *) ((char *) src0->data + i01*nb01 + i11*nb02 + i12*nb03),
5019                     (float *) ((char *)  dst->data + i10*nb1  + i11*nb2  + i12*nb3), nc);
5020    }
5021}
5022
5023static void ggml_compute_forward_get_rows_f16(
5024        const ggml_compute_params * params,
5025              ggml_tensor * dst) {
5026
5027    const ggml_tensor * src0 = dst->src[0];
5028    const ggml_tensor * src1 = dst->src[1];
5029
5030    GGML_TENSOR_BINARY_OP_LOCALS
5031
5032    const int64_t nc = ne00;
5033    const int64_t nr = ggml_nelements(src1);
5034
5035    assert(ne0  == nc);
5036    assert(ne02 == ne11);
5037    assert(nb00 == sizeof(ggml_fp16_t));
5038    assert(ggml_nrows(dst) == nr);
5039
5040    const int ith = params->ith;
5041    const int nth = params->nth;
5042
5043    // rows per thread
5044    const int dr = (nr + nth - 1)/nth;
5045
5046    // row range for this thread
5047    const int ir0 = dr*ith;
5048    const int ir1 = MIN(ir0 + dr, nr);
5049
5050    for (int64_t i = ir0; i < ir1; ++i) {
5051        const int64_t i12 = i/(ne11*ne10);
5052        const int64_t i11 = (i - i12*ne11*ne10)/ne10;
5053        const int64_t i10 = (i - i12*ne11*ne10 - i11*ne10);
5054        const int64_t i01 = *(int32_t *) ((char *) src1->data + i10*nb10 + i11*nb11 + i12*nb12);
5055
5056        GGML_ASSERT(i01 >= 0 && i01 < ne01);
5057
5058        ggml_cpu_fp16_to_fp32(
5059            (const ggml_fp16_t*) ((char *) src0->data + i01*nb01 + i11*nb02 + i12*nb03),
5060                       (float *) ((char *)  dst->data + i10*nb1  + i11*nb2  + i12*nb3), nc);
5061    }
5062}
5063
5064static void ggml_compute_forward_get_rows_bf16(
5065        const ggml_compute_params * params,
5066              ggml_tensor * dst) {
5067
5068    const ggml_tensor * src0 = dst->src[0];
5069    const ggml_tensor * src1 = dst->src[1];
5070
5071    GGML_TENSOR_BINARY_OP_LOCALS
5072
5073    const int64_t nc = ne00;
5074    const int64_t nr = ggml_nelements(src1);
5075
5076    assert(ne0  == nc);
5077    assert(ne02 == ne11);
5078    assert(nb00 == sizeof(ggml_bf16_t));
5079    assert(ggml_nrows(dst) == nr);
5080
5081    const int ith = params->ith;
5082    const int nth = params->nth;
5083
5084    // rows per thread
5085    const int dr = (nr + nth - 1)/nth;
5086
5087    // row range for this thread
5088    const int ir0 = dr*ith;
5089    const int ir1 = MIN(ir0 + dr, nr);
5090
5091    for (int64_t i = ir0; i < ir1; ++i) {
5092        const int64_t i12 = i/(ne11*ne10);
5093        const int64_t i11 = (i - i12*ne11*ne10)/ne10;
5094        const int64_t i10 = (i - i12*ne11*ne10 - i11*ne10);
5095        const int64_t i01 = *(int32_t *) ((char *) src1->data + i10*nb10 + i11*nb11 + i12*nb12);
5096
5097        GGML_ASSERT(i01 >= 0 && i01 < ne01);
5098
5099        ggml_cpu_bf16_to_fp32(
5100            (const ggml_bf16_t *) ((char *) src0->data + i01*nb01 + i11*nb02 + i12*nb03),
5101                        (float *) ((char *)  dst->data + i10*nb1  + i11*nb2  + i12*nb3), nc);
5102    }
5103}
5104
5105static void ggml_compute_forward_get_rows_f32(
5106        const ggml_compute_params * params,
5107              ggml_tensor * dst) {
5108
5109    const ggml_tensor * src0 = dst->src[0];
5110    const ggml_tensor * src1 = dst->src[1];
5111
5112    GGML_TENSOR_BINARY_OP_LOCALS
5113
5114    const int64_t nc = ne00;
5115    const int64_t nr = ggml_nelements(src1);
5116
5117    assert(ne0  == nc);
5118    assert(ne02 == ne11);
5119    assert(nb00 == sizeof(float));
5120    assert(ggml_nrows(dst) == nr);
5121
5122    const int ith = params->ith;
5123    const int nth = params->nth;
5124
5125    // rows per thread
5126    const int dr = (nr + nth - 1)/nth;
5127
5128    // row range for this thread
5129    const int ir0 = dr*ith;
5130    const int ir1 = MIN(ir0 + dr, nr);
5131
5132    for (int64_t i = ir0; i < ir1; ++i) {
5133        const int64_t i12 = i/(ne11*ne10);
5134        const int64_t i11 = (i - i12*ne11*ne10)/ne10;
5135        const int64_t i10 = (i - i12*ne11*ne10 - i11*ne10);
5136        const int64_t i01 = *(int32_t *) ((char *) src1->data + i10*nb10 + i11*nb11 + i12*nb12);
5137
5138        GGML_ASSERT(i01 >= 0 && i01 < ne01);
5139
5140        ggml_vec_cpy_f32(nc,
5141                (float *) ((char *)  dst->data + i10*nb1  + i11*nb2  + i12*nb3),
5142                (float *) ((char *) src0->data + i01*nb01 + i11*nb02 + i12*nb03));
5143    }
5144}
5145
5146void ggml_compute_forward_get_rows(
5147        const ggml_compute_params * params,
5148        ggml_tensor * dst) {
5149
5150    const ggml_tensor * src0 = dst->src[0];
5151
5152    switch (src0->type) {
5153        case GGML_TYPE_Q1_0:
5154        case GGML_TYPE_Q2_0:
5155        case GGML_TYPE_Q4_0:
5156        case GGML_TYPE_Q4_1:
5157        case GGML_TYPE_Q5_0:
5158        case GGML_TYPE_Q5_1:
5159        case GGML_TYPE_Q8_0:
5160        case GGML_TYPE_Q8_1:
5161        case GGML_TYPE_MXFP4:
5162        case GGML_TYPE_NVFP4:
5163        case GGML_TYPE_Q2_K:
5164        case GGML_TYPE_Q3_K:
5165        case GGML_TYPE_Q4_K:
5166        case GGML_TYPE_Q5_K:
5167        case GGML_TYPE_Q6_K:
5168        case GGML_TYPE_TQ1_0:
5169        case GGML_TYPE_TQ2_0:
5170        case GGML_TYPE_IQ2_XXS:
5171        case GGML_TYPE_IQ2_XS:
5172        case GGML_TYPE_IQ3_XXS:
5173        case GGML_TYPE_IQ1_S:
5174        case GGML_TYPE_IQ1_M:
5175        case GGML_TYPE_IQ4_NL:
5176        case GGML_TYPE_IQ4_XS:
5177        case GGML_TYPE_IQ3_S:
5178        case GGML_TYPE_IQ2_S:
5179            {
5180                ggml_compute_forward_get_rows_q(params, dst);
5181            } break;
5182        case GGML_TYPE_F16:
5183            {
5184                ggml_compute_forward_get_rows_f16(params, dst);
5185            } break;
5186        case GGML_TYPE_BF16:
5187            {
5188                ggml_compute_forward_get_rows_bf16(params, dst);
5189            } break;
5190        case GGML_TYPE_F32:
5191        case GGML_TYPE_I32:
5192            {
5193                ggml_compute_forward_get_rows_f32(params, dst);
5194            } break;
5195        default:
5196            {
5197                GGML_ABORT("fatal error");
5198            }
5199    }
5200
5201    //static bool first = true;
5202    //printf("ne0 = %d, ne1 = %d, ne2 = %d\n", dst->ne[0], dst->ne[1], dst->ne[2]);
5203    //if (first) {
5204    //    first = false;
5205    //} else {
5206    //    for (int k = 0; k < dst->ne[1]; ++k) {
5207    //        for (int j = 0; j < dst->ne[0]/16; ++j) {
5208    //            for (int i = 0; i < 16; ++i) {
5209    //                printf("%8.4f ", ((float *) dst->data)[k*dst->ne[0] + j*16 + i]);
5210    //            }
5211    //            printf("\n");
5212    //        }
5213    //        printf("\n");
5214    //    }
5215    //    printf("\n");
5216    //    exit(0);
5217    //}
5218}
5219
5220template<typename src_t, typename idx_t>
5221static void ggml_compute_forward_set_rows_impl(
5222        const ggml_compute_params * params,
5223              ggml_tensor * dst) {
5224
5225    const ggml_tensor * src0 = dst->src[0];
5226    const ggml_tensor * src1 = dst->src[1];
5227
5228    GGML_TENSOR_BINARY_OP_LOCALS
5229
5230    const int64_t nc = ne00;
5231    const int64_t nr = ne01;
5232
5233    assert(ne0  == nc);
5234    assert(ne2  == ne02);
5235    assert(ne3  == ne03);
5236    GGML_ASSERT(src0->type == GGML_TYPE_F32 || src0->type == GGML_TYPE_F16);
5237    assert(ne02 % ne11 == 0);
5238    assert(ne03 % ne12 == 0);
5239
5240    const int ith = params->ith;
5241    const int nth = params->nth;
5242
5243    // rows per thread
5244    const int64_t dr = (nr + nth - 1)/nth;
5245
5246    // row range for this thread
5247    const int64_t ir0 = dr*ith;
5248    const int64_t ir1 = std::min(ir0 + dr, nr);
5249
5250    const size_t rs = ggml_row_size(src0->type, nc);
5251
5252    ggml_from_float_t const from_float = ggml_get_type_traits_cpu(dst->type)->from_float;
5253
5254    for (int64_t i03 = 0; i03 < ne03; ++i03) {
5255        for (int64_t i02 = 0; i02 < ne02; ++i02) {
5256            for (int64_t i = ir0; i < ir1; ++i) {
5257                const int64_t i12 = i03%ne12;
5258                const int64_t i11 = i02%ne11;
5259                const int64_t i10 = i;
5260
5261                const int64_t i1 = *(idx_t *) ((char *) src1->data + i10*nb10 + i11*nb11 + i12*nb12);
5262
5263                GGML_ASSERT(i1 >= 0 && i1 < ne1);
5264
5265                if constexpr (std::is_same_v<src_t, float>) {
5266                    from_float(
5267                            (const float *) ((char *) src0->data +  i*nb01 + i02*nb02 + i03*nb03),
5268                                            ((char *)  dst->data + i1*nb1  + i02*nb2  + i03*nb3), nc);
5269                } else if constexpr (std::is_same_v<src_t, ggml_fp16_t>) {
5270                    if (dst->type == GGML_TYPE_F16) {
5271                        memcpy(
5272                                            ((char *)  dst->data + i1*nb1  + i02*nb2  + i03*nb3),
5273                                            ((char *) src0->data +  i*nb01 + i02*nb02 + i03*nb03),
5274                                            rs);
5275                    } else {
5276                        float * wdata = (float *) params->wdata + (nc + CACHE_LINE_SIZE_F32) * ith;
5277                        ggml_fp16_to_fp32_row(
5278                                (const ggml_fp16_t *) ((char *) src0->data + i*nb01 + i02*nb02 + i03*nb03),
5279                                wdata, nc);
5280                        from_float(wdata,
5281                                ((char *) dst->data + i1*nb1 + i02*nb2 + i03*nb3), nc);
5282                    }
5283                } else {
5284                    GGML_ABORT("src0->type = %d (%s) not supported", src0->type, ggml_type_name(src0->type));
5285                }
5286            }
5287        }
5288    }
5289}
5290
5291void ggml_compute_forward_set_rows(
5292        const ggml_compute_params * params,
5293        ggml_tensor * dst) {
5294
5295    const ggml_tensor * src0 = dst->src[0];
5296    const ggml_tensor * src1 = dst->src[1];
5297
5298    switch (src0->type) {
5299        case GGML_TYPE_F32:
5300            {
5301                if (src1->type == GGML_TYPE_I64) {
5302                    ggml_compute_forward_set_rows_impl<float, int64_t>(params, dst);
5303                } else if (src1->type == GGML_TYPE_I32) {
5304                    ggml_compute_forward_set_rows_impl<float, int32_t>(params, dst);
5305                } else {
5306                    GGML_ABORT("src1->type = %d (%s) not supported", src1->type, ggml_type_name(src1->type));
5307                }
5308            } break;
5309        case GGML_TYPE_F16:
5310            {
5311                if (src1->type == GGML_TYPE_I64) {
5312                    ggml_compute_forward_set_rows_impl<ggml_fp16_t, int64_t>(params, dst);
5313                } else if (src1->type == GGML_TYPE_I32) {
5314                    ggml_compute_forward_set_rows_impl<ggml_fp16_t, int32_t>(params, dst);
5315                } else {
5316                    GGML_ABORT("src1->type = %d (%s) not supported", src1->type, ggml_type_name(src1->type));
5317                }
5318            } break;
5319        default:
5320            {
5321                GGML_ABORT("src0->type = %d (%s) not supported", src0->type, ggml_type_name(src0->type));
5322            }
5323    }
5324}
5325
5326// ggml_compute_forward_get_rows_back
5327
5328static void ggml_compute_forward_get_rows_back_f32_f16(
5329        const ggml_compute_params * params,
5330              ggml_tensor * dst) {
5331
5332    const ggml_tensor * src0 = dst->src[0];
5333    const ggml_tensor * src1 = dst->src[1];
5334
5335    if (params->ith != 0) {
5336        return;
5337    }
5338
5339    GGML_ASSERT(ggml_is_contiguous(dst));
5340
5341    // ggml_compute_forward_dup_same_cont(params, opt0, dst);
5342
5343    memset(dst->data, 0, ggml_nbytes(dst));
5344
5345    const int nc = src0->ne[0];
5346    const int nr = ggml_nelements(src1);
5347
5348    GGML_ASSERT( dst->ne[0] == nc);
5349    GGML_ASSERT(src0->nb[0] == sizeof(ggml_fp16_t));
5350
5351    for (int i = 0; i < nr; ++i) {
5352        const int r = ((int32_t *) src1->data)[i];
5353
5354        for (int j = 0; j < nc; ++j) {
5355            ggml_fp16_t v = ((ggml_fp16_t *) ((char *) src0->data + i*src0->nb[1]))[j];
5356            ((float *) ((char *) dst->data + r*dst->nb[1]))[j] += GGML_CPU_FP16_TO_FP32(v);
5357        }
5358    }
5359}
5360
5361static void ggml_compute_forward_get_rows_back_f32(
5362        const ggml_compute_params * params,
5363              ggml_tensor * dst) {
5364
5365    const ggml_tensor * src0 = dst->src[0];
5366    const ggml_tensor * src1 = dst->src[1];
5367
5368    if (params->ith != 0) {
5369        return;
5370    }
5371
5372    GGML_ASSERT(ggml_is_contiguous(dst));
5373
5374    // ggml_compute_forward_dup_same_cont(params, opt0, dst);
5375
5376    memset(dst->data, 0, ggml_nbytes(dst));
5377
5378    const int nc = src0->ne[0];
5379    const int nr = ggml_nelements(src1);
5380
5381    GGML_ASSERT( dst->ne[0] == nc);
5382    GGML_ASSERT(src0->nb[0] == sizeof(float));
5383
5384    for (int i = 0; i < nr; ++i) {
5385        const int r = ((int32_t *) src1->data)[i];
5386
5387        ggml_vec_add_f32(nc,
5388                (float *) ((char *)  dst->data + r*dst->nb[1]),
5389                (float *) ((char *)  dst->data + r*dst->nb[1]),
5390                (float *) ((char *) src0->data + i*src0->nb[1]));
5391    }
5392}
5393
5394void ggml_compute_forward_get_rows_back(
5395        const ggml_compute_params * params,
5396        ggml_tensor * dst) {
5397
5398    const ggml_tensor * src0 = dst->src[0];
5399
5400    switch (src0->type) {
5401        case GGML_TYPE_F16:
5402            {
5403                ggml_compute_forward_get_rows_back_f32_f16(params, dst);
5404            } break;
5405        case GGML_TYPE_F32:
5406            {
5407                ggml_compute_forward_get_rows_back_f32(params, dst);
5408            } break;
5409        default:
5410            {
5411                GGML_ABORT("fatal error");
5412            }
5413    }
5414
5415    //static bool first = true;
5416    //printf("ne0 = %d, ne1 = %d, ne2 = %d\n", dst->ne[0], dst->ne[1], dst->ne[2]);
5417    //if (first) {
5418    //    first = false;
5419    //} else {
5420    //    for (int k = 0; k < dst->ne[1]; ++k) {
5421    //        for (int j = 0; j < dst->ne[0]/16; ++j) {
5422    //            for (int i = 0; i < 16; ++i) {
5423    //                printf("%8.4f ", ((float *) dst->data)[k*dst->ne[0] + j*16 + i]);
5424    //            }
5425    //            printf("\n");
5426    //        }
5427    //        printf("\n");
5428    //    }
5429    //    printf("\n");
5430    //    exit(0);
5431    //}
5432}
5433
5434// ggml_compute_forward_diag
5435
5436static void ggml_compute_forward_diag_f32(
5437        const ggml_compute_params * params,
5438        ggml_tensor * dst) {
5439
5440    const ggml_tensor * src0 = dst->src[0];
5441
5442    if (params->ith != 0) {
5443        return;
5444    }
5445
5446    // TODO: handle transposed/permuted matrices
5447
5448    GGML_TENSOR_UNARY_OP_LOCALS
5449
5450    GGML_ASSERT(ne00 == ne0);
5451    GGML_ASSERT(ne00 == ne1);
5452    GGML_ASSERT(ne01 == 1);
5453    GGML_ASSERT(ne02 == ne2);
5454    GGML_ASSERT(ne03 == ne3);
5455
5456    GGML_ASSERT(nb00 == sizeof(float));
5457    GGML_ASSERT(nb0  == sizeof(float));
5458
5459    for (int i3 = 0; i3 < ne3; i3++) {
5460        for (int i2 = 0; i2 < ne2; i2++) {
5461            for (int i1 = 0; i1 < ne1; i1++) {
5462                float * d = (float *)((char *)  dst->data + i3*nb3  + i2*nb2 + i1*nb1);
5463                float * s = (float *)((char *) src0->data + i3*nb03 + i2*nb02);
5464                for (int i0 = 0; i0 < i1; i0++) {
5465                    d[i0] = 0;
5466                }
5467                d[i1] = s[i1];
5468                for (int i0 = i1+1; i0 < ne0; i0++) {
5469                    d[i0] = 0;
5470                }
5471            }
5472        }
5473    }
5474}
5475
5476void ggml_compute_forward_diag(
5477        const ggml_compute_params * params,
5478        ggml_tensor * dst) {
5479
5480    const ggml_tensor * src0 = dst->src[0];
5481
5482    switch (src0->type) {
5483        case GGML_TYPE_F32:
5484            {
5485                ggml_compute_forward_diag_f32(params, dst);
5486            } break;
5487        default:
5488            {
5489                GGML_ABORT("fatal error");
5490            }
5491    }
5492}
5493
5494// ggml_compute_forward_diag_mask_inf
5495
5496static void ggml_compute_forward_diag_mask_f32(
5497        const ggml_compute_params * params,
5498        ggml_tensor * dst,
5499        const float value) {
5500
5501    const ggml_tensor * src0 = dst->src[0];
5502
5503    const int ith = params->ith;
5504    const int nth = params->nth;
5505
5506    const int  n_past  = ((int32_t *) dst->op_params)[0];
5507    const bool inplace = src0->data == dst->data;
5508
5509    GGML_ASSERT(n_past >= 0);
5510
5511    if (!inplace) {
5512        if (ith == 0) {
5513            // memcpy needs to be synchronized across threads to avoid race conditions.
5514            // => do it in INIT phase
5515            GGML_ASSERT(ggml_nelements(dst) == ggml_nelements(src0));
5516            GGML_ASSERT(ggml_is_contiguous(dst) && ggml_is_contiguous(src0));
5517            memcpy(
5518                ((char *)  dst->data),
5519                ((char *) src0->data),
5520                ggml_nbytes(dst));
5521        }
5522        ggml_barrier(params->threadpool);
5523    }
5524
5525    // TODO: handle transposed/permuted matrices
5526
5527    const int n  = ggml_nrows(src0);
5528    const int nc = src0->ne[0];
5529    const int nr = src0->ne[1];
5530    const int nz = n/nr;
5531
5532    GGML_ASSERT( dst->nb[0] == sizeof(float));
5533    GGML_ASSERT(src0->nb[0] == sizeof(float));
5534
5535    for (int k = 0; k < nz; k++) {
5536        for (int j = ith; j < nr; j += nth) {
5537            for (int i = n_past; i < nc; i++) {
5538                if (i > n_past + j) {
5539                    *(float *)((char *) dst->data + k*dst->nb[2] + j*dst->nb[1] + i*dst->nb[0]) = value;
5540                }
5541            }
5542        }
5543    }
5544}
5545
5546void ggml_compute_forward_diag_mask_inf(
5547        const ggml_compute_params * params,
5548        ggml_tensor * dst) {
5549
5550    const ggml_tensor * src0 = dst->src[0];
5551
5552    switch (src0->type) {
5553        case GGML_TYPE_F32:
5554            {
5555                ggml_compute_forward_diag_mask_f32(params, dst, -INFINITY);
5556            } break;
5557        default:
5558            {
5559                GGML_ABORT("fatal error");
5560            }
5561    }
5562}
5563
5564void ggml_compute_forward_diag_mask_zero(
5565        const ggml_compute_params * params,
5566        ggml_tensor * dst) {
5567
5568    const ggml_tensor * src0 = dst->src[0];
5569
5570    switch (src0->type) {
5571        case GGML_TYPE_F32:
5572            {
5573                ggml_compute_forward_diag_mask_f32(params, dst, 0);
5574            } break;
5575        default:
5576            {
5577                GGML_ABORT("fatal error");
5578            }
5579    }
5580}
5581
5582// ggml_compute_forward_soft_max
5583
5584static void ggml_compute_forward_soft_max_f32(
5585        const ggml_compute_params * params,
5586              ggml_tensor * dst) {
5587
5588    const ggml_tensor * src0 = dst->src[0];
5589    const ggml_tensor * src1 = dst->src[1];
5590    const ggml_tensor * src2 = dst->src[2];
5591
5592    assert(ggml_is_contiguous(dst));
5593    assert(ggml_are_same_shape(src0, dst));
5594
5595    float scale    = 1.0f;
5596    float max_bias = 0.0f;
5597
5598    memcpy(&scale,    (float *) dst->op_params + 0, sizeof(float));
5599    memcpy(&max_bias, (float *) dst->op_params + 1, sizeof(float));
5600
5601    const int ith = params->ith;
5602    const int nth = params->nth;
5603
5604    GGML_TENSOR_UNARY_OP_LOCALS
5605
5606    const int64_t nb11 = src1 ? src1->nb[1] : 1;
5607    const int64_t nb12 = src1 ? src1->nb[2] : 1;
5608    const int64_t nb13 = src1 ? src1->nb[3] : 1;
5609
5610    const int64_t ne12 = src1 ? src1->ne[2] : 1;
5611    const int64_t ne13 = src1 ? src1->ne[3] : 1;
5612
5613    // TODO: is this supposed to be ceil instead of floor?
5614    //       https://huggingface.co/mosaicml/mpt-7b/blob/main/attention.py#L370
5615    const uint32_t n_head      = ne02;
5616    const uint32_t n_head_log2 = 1u << (uint32_t) floor(log2(n_head));
5617
5618    const float m0 = powf(2.0f, -(max_bias       ) / n_head_log2);
5619    const float m1 = powf(2.0f, -(max_bias / 2.0f) / n_head_log2);
5620
5621    float * wp = (float *) params->wdata + (ne00 + CACHE_LINE_SIZE_F32) * ith;
5622
5623    const bool use_f16 = (src1 && src1->type == GGML_TYPE_F16);
5624
5625    // sinks
5626    const float * sk = src2 ? (float *)((char *) src2->data) : nullptr;
5627
5628    for (int64_t i03 = 0; i03 < ne03; i03++) {
5629        for (int64_t i02 = 0; i02 < ne02; i02++) {
5630            for (int64_t i01 = ith; i01 < ne01; i01 += nth) {
5631                const int64_t i11 = i01;
5632                const int64_t i12 = i02%ne12;
5633                const int64_t i13 = i03%ne13;
5634
5635                // ALiBi
5636                const uint32_t h = i02; // head
5637                const float slope = (max_bias > 0.0f) ? h < n_head_log2 ? powf(m0, h + 1) : powf(m1, 2*(h - n_head_log2) + 1) : 1.0f;
5638
5639                float * sp = (float *)((char *) src0->data + i01*nb01 + i02*nb02 + i03*nb03);
5640                float * dp = (float *)((char *)  dst->data + i01*nb1  + i02*nb2  + i03*nb3);
5641
5642                // broadcast the mask across rows
5643                ggml_fp16_t * mp_f16 = src1 ? (ggml_fp16_t *)((char *) src1->data + i11*nb11 + i12*nb12 + i13*nb13) : NULL;
5644                float       * mp_f32 = src1 ? (float       *)((char *) src1->data + i11*nb11 + i12*nb12 + i13*nb13) : NULL;
5645
5646                ggml_vec_cpy_f32  (ne00, wp, sp);
5647                ggml_vec_scale_f32(ne00, wp, scale);
5648                if (mp_f32) {
5649                    if (use_f16) {
5650                        for (int i = 0; i < ne00; ++i) {
5651                            wp[i] += slope*GGML_CPU_FP16_TO_FP32(mp_f16[i]);
5652                        }
5653                    } else {
5654                        for (int i = 0; i < ne00; ++i) {
5655                            wp[i] += slope*mp_f32[i];
5656                        }
5657                    }
5658                }
5659
5660#ifndef NDEBUG
5661                for (int i = 0; i < ne00; ++i) {
5662                    //printf("p[%d] = %f\n", i, p[i]);
5663                    assert(!isnan(wp[i]));
5664                }
5665#endif // NDEBUG
5666
5667                float max = -INFINITY;
5668                ggml_vec_max_f32(ne00, &max, wp);
5669
5670                // if we have sinks, make a correction as if they were included in the softmax
5671                if (sk) {
5672                    max = MAX(max, sk[i02]);
5673                }
5674
5675                ggml_float sum = ggml_vec_soft_max_f32(ne00, dp, wp, max);
5676                assert(sum > 0.0);
5677
5678                if (sk) {
5679                    sum += (ggml_float) expf(sk[i02] - max);
5680                }
5681
5682                sum = 1.0/sum;
5683                ggml_vec_scale_f32(ne00, dp, sum);
5684
5685#ifndef NDEBUG
5686                for (int i = 0; i < ne00; ++i) {
5687                    assert(!isnan(dp[i]));
5688                    assert(!isinf(dp[i]));
5689                }
5690#endif // NDEBUG
5691            }
5692        }
5693    }
5694}
5695
5696void ggml_compute_forward_soft_max(
5697        const ggml_compute_params * params,
5698              ggml_tensor * dst) {
5699
5700    const ggml_tensor * src0 = dst->src[0];
5701
5702    switch (src0->type) {
5703        case GGML_TYPE_F32:
5704            {
5705                ggml_compute_forward_soft_max_f32(params, dst);
5706            } break;
5707        default:
5708            {
5709                GGML_ABORT("fatal error");
5710            }
5711    }
5712}
5713
5714
5715// ggml_compute_forward_soft_max_ext_back
5716
5717static void ggml_compute_forward_soft_max_ext_back_f32(
5718        const ggml_compute_params * params,
5719        ggml_tensor * dst) {
5720
5721    const ggml_tensor * src0 = dst->src[0];
5722    const ggml_tensor * src1 = dst->src[1];
5723
5724    GGML_ASSERT(ggml_is_contiguous(src0));
5725    GGML_ASSERT(ggml_is_contiguous(src1));
5726    GGML_ASSERT(ggml_is_contiguous(dst));
5727    GGML_ASSERT(ggml_are_same_shape(src0, dst));
5728    GGML_ASSERT(ggml_are_same_shape(src1, dst));
5729
5730    float scale    = 1.0f;
5731    float max_bias = 0.0f;
5732
5733    memcpy(&scale,    (const float *) dst->op_params + 0, sizeof(float));
5734    memcpy(&max_bias, (const float *) dst->op_params + 1, sizeof(float));
5735
5736    GGML_ASSERT(max_bias == 0.0f);
5737
5738    // TODO: handle transposed/permuted matrices
5739
5740    const int ith = params->ith;
5741    const int nth = params->nth;
5742
5743    const int nc = src0->ne[0];
5744    const int nr = ggml_nrows(src0);
5745
5746    // rows per thread
5747    const int dr = (nr + nth - 1)/nth;
5748
5749    // row range for this thread
5750    const int ir0 = dr*ith;
5751    const int ir1 = MIN(ir0 + dr, nr);
5752
5753    for (int i1 = ir0; i1 < ir1; i1++) {
5754        float *dy = (float *)((char *) src0->data + i1*src0->nb[1]);
5755        float *y  = (float *)((char *) src1->data + i1*src1->nb[1]);
5756        float *dx = (float *)((char *) dst->data  + i1*dst->nb[1]);
5757
5758#ifndef NDEBUG
5759        for (int i = 0; i < nc; ++i) {
5760            //printf("p[%d] = %f\n", i, p[i]);
5761            assert(!isnan(dy[i]));
5762            assert(!isnan(y[i]));
5763        }
5764#endif // NDEBUG
5765        // Jii = yi - yi*yi
5766        // Jij = -yi*yj
5767        // J = diag(y)-y.T*y
5768        // dx = J * dy
5769        // dxk = sum_i(Jki * dyi)
5770        // dxk = sum_i(-yk*yi * dyi) - (-yk*yk)*dyk + (yk - yk*yk)*dyk
5771        // dxk = sum_i(-yk*yi * dyi) + yk*yk*dyk + yk*dyk - yk*yk*dyk
5772        // dxk = sum_i(-yk*yi * dyi) + yk*dyk
5773        // dxk = -yk * sum_i(yi * dyi) + yk*dyk
5774        // dxk = -yk * dot(y, dy) + yk*dyk
5775        // dxk = yk * (- dot(y, dy) + dyk)
5776        // dxk = yk * (dyk - dot(y, dy))
5777        //
5778        // post-order:
5779        // dot_y_dy := dot(y, dy)
5780        // dx := dy
5781        // dx := dx - dot_y_dy
5782        // dx := dx * y
5783
5784        // linear runtime, no additional memory
5785        float dot_y_dy = 0;
5786        ggml_vec_dot_f32  (nc, &dot_y_dy, 0, y, 0, dy, 0, 1);
5787        ggml_vec_cpy_f32  (nc, dx, dy);
5788        ggml_vec_acc1_f32 (nc, dx, -dot_y_dy);
5789        ggml_vec_mul_f32  (nc, dx, dx, y);
5790        ggml_vec_scale_f32(nc, dx, scale);
5791
5792#ifndef NDEBUG
5793        for (int i = 0; i < nc; ++i) {
5794            assert(!isnan(dx[i]));
5795            assert(!isinf(dx[i]));
5796        }
5797#endif // NDEBUG
5798    }
5799}
5800
5801void ggml_compute_forward_soft_max_ext_back(
5802        const ggml_compute_params * params,
5803        ggml_tensor * dst) {
5804
5805    const ggml_tensor * src0 = dst->src[0];
5806
5807    switch (src0->type) {
5808        case GGML_TYPE_F32:
5809            {
5810                ggml_compute_forward_soft_max_ext_back_f32(params, dst);
5811            } break;
5812        default:
5813            {
5814                GGML_ABORT("fatal error");
5815            }
5816    }
5817}
5818
5819// ggml_compute_forward_clamp
5820
5821static void ggml_compute_forward_clamp_f32(
5822        const ggml_compute_params * params,
5823        ggml_tensor * dst) {
5824
5825    const ggml_tensor * src0 = dst->src[0];
5826
5827    float min;
5828    float max;
5829    memcpy(&min, (float *) dst->op_params + 0, sizeof(float));
5830    memcpy(&max, (float *) dst->op_params + 1, sizeof(float));
5831
5832    const int ith = params->ith;
5833    const int nth = params->nth;
5834
5835    const int n  = ggml_nrows(src0);
5836    const int nc = src0->ne[0];
5837
5838    const size_t nb00 = src0->nb[0];
5839    const size_t nb01 = src0->nb[1];
5840
5841    const size_t nb0 = dst->nb[0];
5842    const size_t nb1 = dst->nb[1];
5843
5844    GGML_ASSERT( nb0 == sizeof(float));
5845    GGML_ASSERT(nb00 == sizeof(float));
5846
5847    for (int j = ith; j < n; j += nth) {
5848        float * dst_ptr  = (float *) ((char *)  dst->data + j*nb1);
5849        float * src0_ptr = (float *) ((char *) src0->data + j*nb01);
5850
5851        for (int i = 0; i < nc; i++) {
5852            dst_ptr[i] = MAX(MIN(src0_ptr[i], max), min);
5853        }
5854    }
5855}
5856
5857static void ggml_compute_forward_clamp_f16(
5858    const ggml_compute_params * params,
5859    ggml_tensor * dst) {
5860
5861    const ggml_tensor * src0 = dst->src[0];
5862
5863    float min;
5864    float max;
5865    memcpy(&min, (float *) dst->op_params + 0, sizeof(float));
5866    memcpy(&max, (float *) dst->op_params + 1, sizeof(float));
5867
5868    const int ith = params->ith;
5869    const int nth = params->nth;
5870
5871    const int n  = ggml_nrows(src0);
5872    const int nc = src0->ne[0];
5873
5874    const size_t nb00 = src0->nb[0];
5875    const size_t nb01 = src0->nb[1];
5876
5877    const size_t nb0 = dst->nb[0];
5878    const size_t nb1 = dst->nb[1];
5879
5880    GGML_ASSERT( nb0 == sizeof(ggml_fp16_t));
5881    GGML_ASSERT(nb00 == sizeof(ggml_fp16_t));
5882
5883    for (int j = ith; j < n; j += nth) {
5884        ggml_fp16_t * dst_ptr  = (ggml_fp16_t *) ((char *)  dst->data + j*nb1);
5885        ggml_fp16_t * src0_ptr = (ggml_fp16_t *) ((char *) src0->data + j*nb01);
5886
5887        for (int i = 0; i < nc; i++) {
5888            float v = GGML_CPU_FP16_TO_FP32(src0_ptr[i]);
5889            dst_ptr[i] = GGML_CPU_FP32_TO_FP16(MAX(MIN(v, max), min));
5890        }
5891    }
5892}
5893
5894void ggml_compute_forward_clamp(
5895        const ggml_compute_params * params,
5896        ggml_tensor * dst) {
5897
5898    const ggml_tensor * src0 = dst->src[0];
5899
5900    switch (src0->type) {
5901        case GGML_TYPE_F32:
5902            {
5903                ggml_compute_forward_clamp_f32(params, dst);
5904            } break;
5905        case GGML_TYPE_F16:
5906            {
5907                ggml_compute_forward_clamp_f16(params, dst);
5908            } break;
5909        case GGML_TYPE_BF16:
5910        case GGML_TYPE_Q1_0:
5911        case GGML_TYPE_Q2_0:
5912        case GGML_TYPE_Q4_0:
5913        case GGML_TYPE_Q4_1:
5914        case GGML_TYPE_Q5_0:
5915        case GGML_TYPE_Q5_1:
5916        case GGML_TYPE_Q8_0:
5917        case GGML_TYPE_Q8_1:
5918        case GGML_TYPE_MXFP4:
5919        case GGML_TYPE_NVFP4:
5920        case GGML_TYPE_Q2_K:
5921        case GGML_TYPE_Q3_K:
5922        case GGML_TYPE_Q4_K:
5923        case GGML_TYPE_Q5_K:
5924        case GGML_TYPE_Q6_K:
5925        case GGML_TYPE_TQ1_0:
5926        case GGML_TYPE_TQ2_0:
5927        case GGML_TYPE_IQ2_XXS:
5928        case GGML_TYPE_IQ2_XS:
5929        case GGML_TYPE_IQ3_XXS:
5930        case GGML_TYPE_IQ1_S:
5931        case GGML_TYPE_IQ1_M:
5932        case GGML_TYPE_IQ4_NL:
5933        case GGML_TYPE_IQ4_XS:
5934        case GGML_TYPE_IQ3_S:
5935        case GGML_TYPE_IQ2_S:
5936        case GGML_TYPE_Q8_K:
5937        case GGML_TYPE_I8:
5938        case GGML_TYPE_I16:
5939        case GGML_TYPE_I32:
5940        case GGML_TYPE_I64:
5941        case GGML_TYPE_F64:
5942        case GGML_TYPE_COUNT:
5943            {
5944                GGML_ABORT("fatal error");
5945            }
5946    }
5947}
5948
5949// ggml_compute_forward_rope
5950
5951static float rope_yarn_ramp(const float low, const float high, const int i0) {
5952    const float y = (i0 / 2 - low) / MAX(0.001f, high - low);
5953    return 1 - MIN(1, MAX(0, y));
5954}
5955
5956// YaRN algorithm based on LlamaYaRNScaledRotaryEmbedding.py from https://github.com/jquesnelle/yarn
5957// MIT licensed. Copyright (c) 2023 Jeffrey Quesnelle and Bowen Peng.
5958static void rope_yarn(
5959    float theta_extrap, float freq_scale, float corr_dims[2], int64_t i0, float ext_factor, float mscale,
5960    float * cos_theta, float * sin_theta) {
5961    // Get n-d rotational scaling corrected for extrapolation
5962    float theta_interp = freq_scale * theta_extrap;
5963    float theta = theta_interp;
5964    if (ext_factor != 0.0f) {
5965        float ramp_mix = rope_yarn_ramp(corr_dims[0], corr_dims[1], i0) * ext_factor;
5966        theta = theta_interp * (1 - ramp_mix) + theta_extrap * ramp_mix;
5967
5968        // Get n-d magnitude scaling corrected for interpolation
5969        mscale *= 1.0f + 0.1f * logf(1.0f / freq_scale);
5970    }
5971    *cos_theta = cosf(theta) * mscale;
5972    *sin_theta = sinf(theta) * mscale;
5973}
5974
5975static void ggml_rope_cache_init(
5976     float theta_base, float freq_scale, const float * freq_factors, float corr_dims[2], int64_t ne0, float ext_factor, float mscale,
5977     float * cache, float sin_sign, float theta_scale) {
5978    // ref: https://github.com/jquesnelle/yarn/blob/master/scaled_rope/LlamaYaRNScaledRotaryEmbedding.py
5979    float theta = theta_base;
5980    for (int64_t i0 = 0; i0 < ne0; i0 += 2) {
5981        const float ff = freq_factors ? freq_factors[i0/2] : 1.0f;
5982        rope_yarn(
5983            theta/ff, freq_scale, corr_dims, i0, ext_factor, mscale, &cache[i0 + 0], &cache[i0 + 1]
5984        );
5985        cache[i0 + 1] *= sin_sign;
5986
5987        theta *= theta_scale;
5988    }
5989}
5990
5991static void ggml_mrope_cache_init(
5992     float theta_base_t, float theta_base_h, float theta_base_w, float theta_base_e, int sections[4], bool is_imrope, bool indep_sects,
5993     float freq_scale, const float * freq_factors, float corr_dims[2], int64_t ne0, float ext_factor, float mscale,
5994     float * cache, float sin_sign, float theta_scale) {
5995    // ref: https://github.com/jquesnelle/yarn/blob/master/scaled_rope/LlamaYaRNScaledRotaryEmbedding.py
5996    float theta_t = theta_base_t;
5997    float theta_h = theta_base_h;
5998    float theta_w = theta_base_w;
5999    float theta_e = theta_base_e;  // extra position id for vision encoder
6000    int sect_dims = sections[0] + sections[1] + sections[2] + sections[3];
6001    int sec_w = sections[1] + sections[0];
6002    int sec_e = sections[2] + sec_w;
6003    GGML_ASSERT(sect_dims <= ne0);
6004
6005    for (int64_t i0 = 0; i0 < ne0; i0 += 2) {
6006        const float ff = freq_factors ? freq_factors[i0/2] : 1.0f;
6007
6008        int sector = (i0 / 2) % sect_dims;
6009        if (indep_sects) {
6010            // compute theta independently for each dim sections
6011            // (i.e. reset corresponding theta when `i0` go from one section to another)
6012            if (sector == 0) {
6013                theta_t = theta_base_t;
6014            }
6015            else if (sector == sections[0]) {
6016                theta_h = theta_base_h;;
6017            }
6018            else if (sector == sec_w) {
6019                theta_w = theta_base_w;
6020            }
6021            else if (sector == sec_e) {
6022                theta_e = theta_base_e;
6023            }
6024        }
6025
6026        float theta = theta_t;
6027        if (is_imrope) { // qwen3vl apply interleaved mrope
6028            if (sector % 3 == 1 && sector < 3 * sections[1]) {
6029                theta = theta_h;
6030            } else if (sector % 3 == 2 && sector < 3 * sections[2]) {
6031                theta = theta_w;
6032            } else if (sector % 3 == 0 && sector < 3 * sections[0]) {
6033                theta = theta_t;
6034            } else {
6035                theta = theta_e;
6036            }
6037        } else {
6038            if (sector >= sections[0] && sector < sec_w) {
6039                theta = theta_h;
6040            }
6041            else if (sector >= sec_w && sector < sec_w + sections[2]) {
6042                theta = theta_w;
6043            }
6044            else if (sector >= sec_w + sections[2]) {
6045                theta = theta_e;
6046            }
6047        }
6048
6049        rope_yarn(
6050            theta/ff, freq_scale, corr_dims, i0, ext_factor, mscale, &cache[i0 + 0], &cache[i0 + 1]
6051        );
6052        cache[i0 + 1] *= sin_sign;
6053
6054        theta_t *= theta_scale;
6055        theta_w *= theta_scale;
6056        theta_h *= theta_scale;
6057        theta_e *= theta_scale;
6058    }
6059}
6060
6061
6062template<typename T>
6063static void rotate_pairs(const int64_t n, const int64_t n_offset, const float * cache, const T * src_data, T * dst_data, const int scale = 2) {
6064  for (int64_t i0 = 0; i0 < n; i0 += 2) {
6065    const int64_t ic = i0/scale; // hack for GGML_ROPE_TYPE_NORMAL, where we need ic = i0; for all other cases, ic = i0/2
6066
6067    const float cos_theta = cache[i0 + 0];
6068    const float sin_theta = cache[i0 + 1];
6069
6070    const T * const src = src_data + ic;
6071    T * dst             = dst_data + ic;
6072
6073    const float x0 = type_conversion_table<T>::to_f32(src[0]);
6074    const float x1 = type_conversion_table<T>::to_f32(src[n_offset]);
6075
6076    dst[0]        = type_conversion_table<T>::from_f32(x0*cos_theta - x1*sin_theta);
6077    dst[n_offset] = type_conversion_table<T>::from_f32(x0*sin_theta + x1*cos_theta);
6078  }
6079}
6080
6081template<typename T> //float or ggml_fp16_t
6082static void ggml_compute_forward_rope_flt(
6083        const ggml_compute_params * params,
6084        ggml_tensor * dst,
6085        const bool forward) {
6086
6087    const ggml_tensor * src0 = dst->src[0];
6088    const ggml_tensor * src1 = dst->src[1];
6089    const ggml_tensor * src2 = dst->src[2];
6090
6091    GGML_ASSERT(src0->type == GGML_TYPE_F32 || src0->type == GGML_TYPE_F16);
6092    GGML_ASSERT(src1->type == GGML_TYPE_I32);
6093
6094    float freq_base, freq_scale, ext_factor, attn_factor, beta_fast, beta_slow;
6095    int sections[4];
6096
6097    //const int n_past     = ((int32_t *) dst->op_params)[0];
6098    const int n_dims     = ((int32_t *) dst->op_params)[1];
6099    const int mode       = ((int32_t *) dst->op_params)[2];
6100    //const int n_ctx      = ((int32_t *) dst->op_params)[3];
6101    const int n_ctx_orig = ((int32_t *) dst->op_params)[4];
6102
6103    memcpy(&freq_base,   (int32_t *) dst->op_params +  5, sizeof(float));
6104    memcpy(&freq_scale,  (int32_t *) dst->op_params +  6, sizeof(float));
6105    memcpy(&ext_factor,  (int32_t *) dst->op_params +  7, sizeof(float));
6106    memcpy(&attn_factor, (int32_t *) dst->op_params +  8, sizeof(float));
6107    memcpy(&beta_fast,   (int32_t *) dst->op_params +  9, sizeof(float));
6108    memcpy(&beta_slow,   (int32_t *) dst->op_params + 10, sizeof(float));
6109    memcpy(&sections,    (int32_t *) dst->op_params + 11, sizeof(int)*4);
6110
6111    const int n_offs = ((int32_t *) dst->op_params)[15];
6112
6113    GGML_TENSOR_UNARY_OP_LOCALS
6114
6115    //printf("ne0: %d, ne1: %d, ne2: %d, ne3: %d\n", ne0, ne1, ne2, ne3);
6116    //printf("n_past = %d, ne2 = %d\n", n_past, ne2);
6117
6118    GGML_ASSERT(nb0 == nb00);
6119    GGML_ASSERT(nb0 == sizeof(T));
6120
6121    const int ith = params->ith;
6122    const int nth = params->nth;
6123
6124    const int nr = ggml_nrows(dst);
6125
6126    GGML_ASSERT(n_dims <= ne0);
6127    GGML_ASSERT(n_dims % 2 == 0);
6128
6129    GGML_ASSERT(n_offs >= 0);
6130    GGML_ASSERT(n_offs % 2 == 0);
6131    GGML_ASSERT(n_offs + n_dims <= ne0);
6132
6133    // rows per thread
6134    const int dr = (nr + nth - 1)/nth;
6135
6136    // row range for this thread
6137    const int ir0 = dr*ith;
6138    const int ir1 = MIN(ir0 + dr, nr);
6139
6140    // row index used to determine which thread to use
6141    int ir = 0;
6142
6143    const float theta_scale = powf(freq_base, -2.0f/n_dims);
6144
6145    float corr_dims[2];
6146    ggml_rope_yarn_corr_dims(n_dims, n_ctx_orig, freq_base, beta_fast, beta_slow, corr_dims);
6147
6148    const bool is_imrope = mode == GGML_ROPE_TYPE_IMROPE; // qwen3vl apply interleaved mrope
6149    const bool mrope_used = mode & GGML_ROPE_TYPE_MROPE;  // ggml_rope_multi, note: also true for vision (24 & 8 == true) and for imrope
6150    const bool is_vision = mode == GGML_ROPE_TYPE_VISION;
6151
6152    if (mrope_used) {
6153        GGML_ASSERT(sections[0] > 0 || sections[1] > 0 || sections[2] > 0);
6154    }
6155
6156    if (is_vision) {
6157        GGML_ASSERT(n_dims == ne0/2);
6158        GGML_ASSERT(n_offs == 0);
6159    }
6160
6161    const float * freq_factors = NULL;
6162    if (src2 != NULL) {
6163        GGML_ASSERT(src2->type == GGML_TYPE_F32);
6164        GGML_ASSERT(src2->ne[0] >= n_dims / 2);
6165        freq_factors = (const float *) src2->data;
6166    }
6167
6168    // backward process uses inverse rotation by cos and sin.
6169    // cos and sin build a rotation matrix, where the inverse is the transpose.
6170    // this essentially just switches the sign of sin.
6171    const float sin_sign = forward ? 1.0f : -1.0f;
6172
6173    const int32_t * pos = (const int32_t *) src1->data;
6174
6175    int64_t last_i2 = -1;
6176
6177    for (int64_t i3 = 0; i3 < ne3; i3++) { // batch
6178        for (int64_t i2 = 0; i2 < ne2; i2++) { // seq-len
6179            for (int64_t i1 = 0; i1 < ne1; i1++) { // attn-heads
6180                if (ir++ < ir0) continue; // skip rows mapped to other threads
6181                if (ir   > ir1) break;
6182
6183                float * cache = (float *) params->wdata + (ne0 + CACHE_LINE_SIZE_F32)*ith;
6184                if (last_i2 != i2) {
6185                    if (!mrope_used) {
6186                        const int64_t p = pos[i2];
6187                        ggml_rope_cache_init(p, freq_scale, freq_factors, corr_dims, ne0, ext_factor, attn_factor, cache, sin_sign, theta_scale);
6188                    }
6189                    else {
6190                        const int64_t p_t = pos[i2];
6191                        const int64_t p_h = pos[i2 + ne2];
6192                        const int64_t p_w = pos[i2 + ne2 * 2];
6193                        const int64_t p_e = pos[i2 + ne2 * 3];
6194                        ggml_mrope_cache_init(
6195                            p_t, p_h, p_w, p_e, sections, is_imrope, is_vision,
6196                            freq_scale, freq_factors, corr_dims, ne0, ext_factor, attn_factor, cache, sin_sign, theta_scale);
6197                    }
6198
6199                    last_i2 = i2;
6200                }
6201
6202                T * src = (T *)((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01);
6203                T * dst_data  = (T *)((char *)  dst->data + i3*nb3  + i2*nb2  + i1*nb1);
6204
6205                switch (mode) {
6206                    case GGML_ROPE_TYPE_NORMAL:
6207                        rotate_pairs<T>(n_dims, 1, cache, src + n_offs, dst_data + n_offs, 1);
6208                        break;
6209                    case GGML_ROPE_TYPE_NEOX:
6210                    case GGML_ROPE_TYPE_MROPE:
6211                    case GGML_ROPE_TYPE_IMROPE:
6212                        rotate_pairs<T>(n_dims, n_dims/2, cache, src + n_offs, dst_data + n_offs);
6213                        break;
6214                    case GGML_ROPE_TYPE_VISION:
6215                        rotate_pairs<T>(ne0, n_dims, cache, src, dst_data);
6216                        break;
6217                    default:
6218                        GGML_ABORT("rope type not supported");
6219                }
6220
6221                if (!is_vision) {
6222                    // fill the remain channels with data from src tensor
6223                    for (int64_t i0 = 0; i0 < ne0; i0 += 2) {
6224                        if (i0 == n_offs) {
6225                            i0 += n_dims - 2; // skip the rotated channels
6226                            continue;
6227                        }
6228                        const T * const src = (T *)((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01 + i0*nb00);
6229                        T * dst_data  = (T *)((char *)  dst->data + i3*nb3  + i2*nb2  + i1*nb1  + i0*nb0);
6230
6231                        dst_data[0] = src[0];
6232                        dst_data[1] = src[1];
6233                    }
6234                }
6235            } //attn-heads
6236        }
6237    }
6238}
6239
6240void ggml_compute_forward_rope(
6241        const ggml_compute_params * params,
6242        ggml_tensor * dst) {
6243
6244    const ggml_tensor * src0 = dst->src[0];
6245
6246    switch (src0->type) {
6247        case GGML_TYPE_F16:
6248            {
6249                ggml_compute_forward_rope_flt<ggml_fp16_t>(params, dst, true);
6250            } break;
6251        case GGML_TYPE_F32:
6252            {
6253                ggml_compute_forward_rope_flt<float>(params, dst, true);
6254            } break;
6255        default:
6256            {
6257                GGML_ABORT("fatal error");
6258            }
6259    }
6260}
6261
6262// ggml_compute_forward_rope_back
6263
6264void ggml_compute_forward_rope_back(
6265        const ggml_compute_params * params,
6266        ggml_tensor * dst) {
6267
6268    const ggml_tensor * src0 = dst->src[0];
6269
6270    switch (src0->type) {
6271        case GGML_TYPE_F16:
6272            {
6273                ggml_compute_forward_rope_flt<ggml_fp16_t>(params, dst, false);
6274            } break;
6275        case GGML_TYPE_F32:
6276            {
6277                ggml_compute_forward_rope_flt<float>(params, dst, false);
6278            } break;
6279        default:
6280            {
6281                GGML_ABORT("fatal error");
6282            }
6283    }
6284}
6285
6286// ggml_compute_forward_conv_transpose_1d
6287
6288static void ggml_compute_forward_conv_transpose_1d_f16_f32(
6289        const ggml_compute_params * params,
6290              ggml_tensor * dst) {
6291
6292    const ggml_tensor * src0 = dst->src[0];
6293    const ggml_tensor * src1 = dst->src[1];
6294
6295    GGML_ASSERT(src0->type == GGML_TYPE_F16);
6296    GGML_ASSERT(src1->type == GGML_TYPE_F32);
6297    GGML_ASSERT( dst->type == GGML_TYPE_F32);
6298
6299    GGML_TENSOR_BINARY_OP_LOCALS
6300
6301    const int ith = params->ith;
6302    const int nth = params->nth;
6303
6304    const int nk = ne00*ne01*ne02;
6305
6306    GGML_ASSERT(nb00 == sizeof(ggml_fp16_t));
6307    GGML_ASSERT(nb10 == sizeof(float));
6308
6309    if (ith == 0) {
6310        memset(params->wdata, 0, params->wsize);
6311
6312        // permute kernel data (src0) from (K x Cout x Cin) to (Cin x K x Cout)
6313        {
6314            ggml_fp16_t * const wdata = (ggml_fp16_t *) params->wdata + 0;
6315
6316            for (int64_t i02 = 0; i02 < ne02; i02++) {
6317                for (int64_t i01 = 0; i01 < ne01; i01++) {
6318                    const ggml_fp16_t * const src = (ggml_fp16_t *)((char *) src0->data + i02*nb02 + i01*nb01);
6319                    ggml_fp16_t * dst_data = wdata + i01*ne00*ne02;
6320                    for (int64_t i00 = 0; i00 < ne00; i00++) {
6321                        dst_data[i00*ne02 + i02] = src[i00];
6322                    }
6323                }
6324            }
6325        }
6326
6327        // permute source data (src1) from (L x Cin) to (Cin x L)
6328        {
6329            ggml_fp16_t * const wdata = (ggml_fp16_t *) params->wdata + nk;
6330            ggml_fp16_t * dst_data = wdata;
6331
6332            for (int64_t i11 = 0; i11 < ne11; i11++) {
6333                const float * const src = (float *)((char *) src1->data + i11*nb11);
6334                for (int64_t i10 = 0; i10 < ne10; i10++) {
6335                    dst_data[i10*ne11 + i11] = GGML_CPU_FP32_TO_FP16(src[i10]);
6336                }
6337            }
6338        }
6339
6340        // need to zero dst since we are accumulating into it
6341        memset(dst->data, 0, ggml_nbytes(dst));
6342    }
6343    ggml_barrier(params->threadpool);
6344
6345    const int32_t s0 = ((const int32_t*)(dst->op_params))[0];
6346
6347    // total rows in dst
6348    const int nr = ne1;
6349
6350    // rows per thread
6351    const int dr = (nr + nth - 1)/nth;
6352
6353    // row range for this thread
6354    const int ir0 = dr*ith;
6355    const int ir1 = MIN(ir0 + dr, nr);
6356
6357    ggml_fp16_t * const wdata     = (ggml_fp16_t *) params->wdata + 0;
6358    ggml_fp16_t * const wdata_src = wdata + nk;
6359
6360    for (int i1 = ir0; i1 < ir1; i1++) {
6361        float * dst_data = (float *)((char *) dst->data + i1*nb1);
6362        ggml_fp16_t * wdata_kernel = wdata + i1*ne02*ne00;
6363        for (int i10 = 0; i10 < ne10; i10++) {
6364            const int i1n = i10*ne11;
6365            for (int i00 = 0; i00 < ne00; i00++) {
6366                float v = 0;
6367                ggml_vec_dot_f16(ne02, &v, 0,
6368                        (ggml_fp16_t *)    wdata_src + i1n, 0,
6369                        (ggml_fp16_t *) wdata_kernel + i00*ne02, 0, 1);
6370                dst_data[i10*s0 + i00] += v;
6371            }
6372        }
6373    }
6374}
6375
6376static void ggml_compute_forward_conv_transpose_1d_f32(
6377        const ggml_compute_params * params,
6378              ggml_tensor * dst) {
6379
6380    const ggml_tensor * src0 = dst->src[0];
6381    const ggml_tensor * src1 = dst->src[1];
6382
6383    GGML_ASSERT(src0->type == GGML_TYPE_F32);
6384    GGML_ASSERT(src1->type == GGML_TYPE_F32);
6385    GGML_ASSERT( dst->type == GGML_TYPE_F32);
6386
6387    GGML_TENSOR_BINARY_OP_LOCALS
6388
6389    const int ith = params->ith;
6390    const int nth = params->nth;
6391
6392    const int nk = ne00*ne01*ne02;
6393
6394    GGML_ASSERT(nb00 == sizeof(float));
6395    GGML_ASSERT(nb10 == sizeof(float));
6396
6397    if (ith == 0) {
6398        memset(params->wdata, 0, params->wsize);
6399
6400        // prepare kernel data (src0) from (K x Cout x Cin) to (Cin x K x Cout)
6401        {
6402            float * const wdata = (float *) params->wdata + 0;
6403
6404            for (int64_t i02 = 0; i02 < ne02; i02++) {
6405                for (int64_t i01 = 0; i01 < ne01; i01++) {
6406                    const float * const src = (float *)((char *) src0->data + i02*nb02 + i01*nb01);
6407                    float * dst_data = wdata + i01*ne00*ne02;
6408                    for (int64_t i00 = 0; i00 < ne00; i00++) {
6409                        dst_data[i00*ne02 + i02] = src[i00];
6410                    }
6411                }
6412            }
6413        }
6414
6415        // prepare source data (src1)
6416        {
6417            float * const wdata = (float *) params->wdata + nk;
6418            float * dst_data = wdata;
6419
6420            for (int64_t i11 = 0; i11 < ne11; i11++) {
6421                const float * const src = (float *)((char *) src1->data + i11*nb11);
6422                for (int64_t i10 = 0; i10 < ne10; i10++) {
6423                    dst_data[i10*ne11 + i11] = src[i10];
6424                }
6425            }
6426        }
6427
6428        // need to zero dst since we are accumulating into it
6429        memset(dst->data, 0, ggml_nbytes(dst));
6430    }
6431    ggml_barrier(params->threadpool);
6432
6433    const int32_t s0 = ((const int32_t*)(dst->op_params))[0];
6434
6435    // total rows in dst
6436    const int nr = ne1;
6437
6438    // rows per thread
6439    const int dr = (nr + nth - 1)/nth;
6440
6441    // row range for this thread
6442    const int ir0 = dr*ith;
6443    const int ir1 = MIN(ir0 + dr, nr);
6444
6445    float * const wdata     = (float *) params->wdata + 0;
6446    float * const wdata_src = wdata + nk;
6447
6448    for (int i1 = ir0; i1 < ir1; i1++) {
6449        float * dst_data = (float *)((char *) dst->data + i1*nb1);
6450        float * wdata_kernel = wdata + i1*ne02*ne00;
6451        for (int i10 = 0; i10 < ne10; i10++) {
6452            const int i1n = i10*ne11;
6453            for (int i00 = 0; i00 < ne00; i00++) {
6454                float v = 0;
6455                ggml_vec_dot_f32(ne02, &v, 0,
6456                        wdata_src + i1n, 0,
6457                        wdata_kernel + i00*ne02, 0, 1);
6458                dst_data[i10*s0 + i00] += v;
6459            }
6460        }
6461    }
6462}
6463
6464void ggml_compute_forward_conv_transpose_1d(
6465        const ggml_compute_params * params,
6466              ggml_tensor * dst) {
6467
6468    const ggml_tensor * src0 = dst->src[0];
6469
6470    switch (src0->type) {
6471        case GGML_TYPE_F16:
6472            {
6473                ggml_compute_forward_conv_transpose_1d_f16_f32(params, dst);
6474            } break;
6475        case GGML_TYPE_F32:
6476            {
6477                ggml_compute_forward_conv_transpose_1d_f32(params, dst);
6478            } break;
6479        default:
6480            {
6481                GGML_ABORT("fatal error");
6482            }
6483    }
6484}
6485
6486// ggml_compute_forward_im2col_f32
6487// src0: kernel [OC, IC, KH, KW]
6488// src1: image [N, IC, IH, IW]
6489// dst:  result [N, OH, OW, IC*KH*KW]
6490static void ggml_compute_forward_im2col_f32(
6491        const ggml_compute_params * params,
6492              ggml_tensor * dst) {
6493
6494    const ggml_tensor * src0 = dst->src[0];
6495    const ggml_tensor * src1 = dst->src[1];
6496
6497    GGML_ASSERT(src1->type == GGML_TYPE_F32);
6498    GGML_ASSERT( dst->type == GGML_TYPE_F32);
6499
6500    GGML_TENSOR_BINARY_OP_LOCALS;
6501
6502    const int32_t s0 = ((const int32_t *)(dst->op_params))[0];
6503    const int32_t s1 = ((const int32_t *)(dst->op_params))[1];
6504    const int32_t p0 = ((const int32_t *)(dst->op_params))[2];
6505    const int32_t p1 = ((const int32_t *)(dst->op_params))[3];
6506    const int32_t d0 = ((const int32_t *)(dst->op_params))[4];
6507    const int32_t d1 = ((const int32_t *)(dst->op_params))[5];
6508    const bool is_2D = ((const int32_t *)(dst->op_params))[6] == 1;
6509
6510    const int ith = params->ith;
6511    const int nth = params->nth;
6512
6513    const int64_t N  = is_2D ? ne13 : ne12;
6514    const int64_t IC = is_2D ? ne12 : ne11;
6515    const int64_t IH = is_2D ? ne11 : 1;
6516    const int64_t IW = ne10;
6517
6518    const int64_t KH = is_2D ? ne01 : 1;
6519    const int64_t KW = ne00;
6520
6521    const int64_t OH = is_2D ? ne2 : 1;
6522    const int64_t OW = ne1;
6523
6524    int ofs0 = is_2D ? nb13 : nb12;
6525    int ofs1 = is_2D ? nb12 : nb11;
6526
6527    GGML_ASSERT(nb10 == sizeof(float));
6528
6529    // im2col: [N, IC, IH, IW] => [N, OH, OW, IC*KH*KW]
6530    {
6531        float * const wdata = (float *) dst->data;
6532
6533        for (int64_t in = 0; in < N; in++) {
6534            for (int64_t ioh = 0; ioh < OH; ioh++) { // 1
6535                for (int64_t iow = 0; iow < OW; iow++) {
6536                    for (int64_t iic = ith; iic < IC; iic += nth) {
6537
6538                        // micro kernel
6539                        float * dst_data = wdata + (in*OH*OW + ioh*OW + iow)*(IC*KH*KW); // [IC, KH, KW]
6540                        const float * const src_data = (float *)((char *) src1->data + in*ofs0 + iic*ofs1); // [IH, IW]
6541
6542                        for (int64_t ikh = 0; ikh < KH; ikh++) {  // 1
6543                            for (int64_t ikw = 0; ikw < KW; ikw++) {
6544                                const int64_t iiw = iow*s0 + ikw*d0 - p0;
6545                                const int64_t iih = ioh*s1 + ikh*d1 - p1;
6546
6547                                if (iih < 0 || iih >= IH || iiw < 0 || iiw >= IW) {
6548                                    dst_data[iic*(KH*KW) + ikh*KW + ikw] = 0;
6549                                } else {
6550                                    dst_data[iic*(KH*KW) + ikh*KW + ikw] = (src_data[iih*IW + iiw]);
6551                                }
6552                            }
6553                        }
6554                    }
6555                }
6556            }
6557        }
6558    }
6559}
6560
6561
6562// ggml_compute_forward_im2col_f16
6563// src0: kernel [OC, IC, KH, KW]
6564// src1: image [N, IC, IH, IW]
6565// dst:  result [N, OH, OW, IC*KH*KW]
6566static void ggml_compute_forward_im2col_f16(
6567        const ggml_compute_params * params,
6568              ggml_tensor * dst) {
6569
6570    const ggml_tensor * src0 = dst->src[0];
6571    const ggml_tensor * src1 = dst->src[1];
6572
6573    GGML_ASSERT(src1->type == GGML_TYPE_F16 || src1->type == GGML_TYPE_F32);
6574    GGML_ASSERT( dst->type == GGML_TYPE_F16);
6575
6576    GGML_TENSOR_BINARY_OP_LOCALS;
6577
6578    const int32_t s0 = ((const int32_t *)(dst->op_params))[0];
6579    const int32_t s1 = ((const int32_t *)(dst->op_params))[1];
6580    const int32_t p0 = ((const int32_t *)(dst->op_params))[2];
6581    const int32_t p1 = ((const int32_t *)(dst->op_params))[3];
6582    const int32_t d0 = ((const int32_t *)(dst->op_params))[4];
6583    const int32_t d1 = ((const int32_t *)(dst->op_params))[5];
6584    const bool is_2D = ((const int32_t *)(dst->op_params))[6] == 1;
6585
6586    const int ith = params->ith;
6587    const int nth = params->nth;
6588
6589    const int64_t N  = is_2D ? ne13 : ne12;
6590    const int64_t IC = is_2D ? ne12 : ne11;
6591    const int64_t IH = is_2D ? ne11 : 1;
6592    const int64_t IW = ne10;
6593
6594    const int64_t KH = is_2D ? ne01 : 1;
6595    const int64_t KW = ne00;
6596
6597    const int64_t OH = is_2D ? ne2 : 1;
6598    const int64_t OW = ne1;
6599
6600    int ofs0 = is_2D ? nb13 : nb12;
6601    int ofs1 = is_2D ? nb12 : nb11;
6602
6603    GGML_ASSERT(nb10 == ggml_type_size(src1->type));
6604
6605    // im2col: [N, IC, IH, IW] => [N, OH, OW, IC*KH*KW]
6606    {
6607        ggml_fp16_t * const wdata = (ggml_fp16_t *) dst->data;
6608
6609        for (int64_t in = 0; in < N; in++) {
6610            for (int64_t ioh = 0; ioh < OH; ioh++) { // 1
6611                for (int64_t iow = 0; iow < OW; iow++) {
6612                    for (int64_t iic = ith; iic < IC; iic += nth) {
6613
6614                        // micro kernel
6615                        ggml_fp16_t * dst_data = wdata + (in*OH*OW + ioh*OW + iow)*(IC*KH*KW); // [IC, KH, KW]
6616                        const float * const src_data_f32 = src1->type == GGML_TYPE_F32
6617                            ? (const float *)((const char *) src1->data + in*ofs0 + iic*ofs1)
6618                            : nullptr; // [IH, IW]
6619                        const ggml_fp16_t * const src_data_f16 = src1->type == GGML_TYPE_F16
6620                            ? (const ggml_fp16_t *)((const char *) src1->data + in*ofs0 + iic*ofs1)
6621                            : nullptr; // [IH, IW]
6622
6623                        for (int64_t ikh = 0; ikh < KH; ikh++) {  // 1
6624                            for (int64_t ikw = 0; ikw < KW; ikw++) {
6625                                const int64_t iiw = iow*s0 + ikw*d0 - p0;
6626                                const int64_t iih = ioh*s1 + ikh*d1 - p1;
6627
6628                                if (iih < 0 || iih >= IH || iiw < 0 || iiw >= IW) {
6629                                    dst_data[iic*(KH*KW) + ikh*KW + ikw] = 0;
6630                                } else {
6631                                    if (src_data_f32 != nullptr) {
6632                                        dst_data[iic*(KH*KW) + ikh*KW + ikw] = GGML_CPU_FP32_TO_FP16(src_data_f32[iih*IW + iiw]);
6633                                    } else {
6634                                        dst_data[iic*(KH*KW) + ikh*KW + ikw] = src_data_f16[iih*IW + iiw];
6635                                    }
6636                                }
6637                            }
6638                        }
6639                    }
6640                }
6641            }
6642        }
6643    }
6644}
6645
6646void ggml_compute_forward_im2col(
6647        const ggml_compute_params * params,
6648              ggml_tensor * dst) {
6649    switch (dst->type) {
6650        case GGML_TYPE_F16:
6651            {
6652                ggml_compute_forward_im2col_f16(params, dst);
6653            } break;
6654        case GGML_TYPE_F32:
6655            {
6656                ggml_compute_forward_im2col_f32(params, dst);
6657            } break;
6658        default:
6659            {
6660                GGML_ABORT("fatal error");
6661            }
6662    }
6663}
6664
6665// ggml_compute_forward_im2col_back_f32
6666
6667void ggml_compute_forward_im2col_back_f32(
6668        const ggml_compute_params * params,
6669              ggml_tensor * dst) {
6670
6671    const ggml_tensor * src0 = dst->src[0]; // gradients of forward pass output
6672    const ggml_tensor * src1 = dst->src[1]; // convolution kernel
6673
6674    GGML_ASSERT(src0->type == GGML_TYPE_F32);
6675    GGML_ASSERT(src1->type == GGML_TYPE_F32 || src1->type == GGML_TYPE_F16);
6676    GGML_ASSERT( dst->type == GGML_TYPE_F32);
6677
6678    GGML_TENSOR_BINARY_OP_LOCALS;
6679
6680    const int32_t s0 = ((const int32_t *)(dst->op_params))[0];
6681    const int32_t s1 = ((const int32_t *)(dst->op_params))[1];
6682    const int32_t p0 = ((const int32_t *)(dst->op_params))[2];
6683    const int32_t p1 = ((const int32_t *)(dst->op_params))[3];
6684    const int32_t d0 = ((const int32_t *)(dst->op_params))[4];
6685    const int32_t d1 = ((const int32_t *)(dst->op_params))[5];
6686    const bool is_2D = ((const int32_t *)(dst->op_params))[6] == 1;
6687
6688    const int ith = params->ith;
6689    const int nth = params->nth;
6690
6691    const int64_t N  = is_2D ? ne3 : ne2;
6692    const int64_t IC = is_2D ? ne2 : ne1;
6693    const int64_t IH = is_2D ? ne1 : 1;
6694    const int64_t IW = ne0;
6695
6696    const int64_t KH = is_2D ? ne11 : 1;
6697    const int64_t KW = ne10;
6698
6699    const int64_t OH = is_2D ? ne02 : 1;
6700    const int64_t OW = ne01;
6701
6702    int ofs0 = is_2D ? nb3 : nb2;
6703    int ofs1 = is_2D ? nb2 : nb1;
6704
6705    GGML_ASSERT(nb0  == sizeof(float));
6706
6707    // im2col: [N, IC, IH, IW] => [N, OH, OW, IC*KH*KW]
6708    {
6709        float * const wdata = (float *) dst->data;
6710
6711        for (int64_t in = 0; in < N; in++) {
6712            for (int64_t iic = ith; iic < IC; iic += nth) {
6713                for (int64_t iih = 0; iih < IH; iih++) {
6714                    for (int64_t iiw = 0; iiw < IW; iiw++) {
6715
6716                        // micro kernel
6717                        float grad = 0.0f;
6718                        for (int64_t ikh = 0; ikh < KH; ikh++) {
6719                            for (int64_t ikw = 0; ikw < KW; ikw++) {
6720                                // For s0 > 1 some values were skipped over in the forward pass.
6721                                // These values have tmpw % s0 != 0 and need to be skipped in the backwards pass as well.
6722                                const int64_t tmpw = (iiw + p0 - ikw*d0);
6723                                if (tmpw % s0 != 0) {
6724                                    continue;
6725                                }
6726                                const int64_t iow = tmpw / s0;
6727
6728                                // Equivalent logic as above except for s1.
6729                                int64_t ioh;
6730                                if (is_2D) {
6731                                    const int64_t tmph = iih + p1 - ikh*d1;
6732
6733                                    if (tmph % s1 != 0) {
6734                                        continue;
6735                                    }
6736
6737                                    ioh = tmph / s1;
6738                                } else {
6739                                    ioh = 0;
6740                                }
6741
6742                                if (iow < 0 || iow >= OW || ioh < 0 || ioh >= OH) {
6743                                    continue;
6744                                }
6745
6746                                const float * const grad_in = (const float *) src0->data
6747                                    + (in*OH*OW + ioh*OW + iow)*(IC*KH*KW); // [IC, KH, KW]
6748                                grad += grad_in[iic*(KH*KW) + ikh*KW + ikw];
6749                            }
6750                        }
6751                        float * dst_data = (float *)((char *) wdata + (in*ofs0 + iic*ofs1)); // [IH, IW]
6752                        dst_data[iih*IW + iiw] = grad;
6753                    }
6754                }
6755            }
6756        }
6757    }
6758}
6759
6760
6761// ggml_compute_forward_im2col_3d_f16
6762// src0: kernel [OC*IC, KD, KH, KW]
6763// src1: image [N*IC, ID, IH, IW]
6764// dst:  result [N*OD, OH, OW, IC * KD * KH * KW]
6765static void ggml_compute_forward_im2col_3d_f16(
6766        const ggml_compute_params * params,
6767              ggml_tensor * dst) {
6768
6769    const ggml_tensor * src0 = dst->src[0];
6770    const ggml_tensor * src1 = dst->src[1];
6771
6772    GGML_ASSERT(src1->type == GGML_TYPE_F32);
6773    GGML_ASSERT( dst->type == GGML_TYPE_F16);
6774
6775    GGML_TENSOR_BINARY_OP_LOCALS;
6776
6777    const int32_t s0 = ((const int32_t *)(dst->op_params))[0];
6778    const int32_t s1 = ((const int32_t *)(dst->op_params))[1];
6779    const int32_t s2 = ((const int32_t *)(dst->op_params))[2];
6780    const int32_t p0 = ((const int32_t *)(dst->op_params))[3];
6781    const int32_t p1 = ((const int32_t *)(dst->op_params))[4];
6782    const int32_t p2 = ((const int32_t *)(dst->op_params))[5];
6783    const int32_t d0 = ((const int32_t *)(dst->op_params))[6];
6784    const int32_t d1 = ((const int32_t *)(dst->op_params))[7];
6785    const int32_t d2 = ((const int32_t *)(dst->op_params))[8];
6786    const int32_t IC = ((const int32_t *)(dst->op_params))[9];
6787
6788
6789    const int ith = params->ith;
6790    const int nth = params->nth;
6791
6792    const int64_t N  = ne13 / IC;
6793    const int64_t ID = ne12;
6794    const int64_t IH = ne11;
6795    const int64_t IW = ne10;
6796
6797    const int64_t OC = ne03 / IC;
6798    GGML_UNUSED(OC);
6799    const int64_t KD = ne02;
6800    const int64_t KH = ne01;
6801    const int64_t KW = ne00;
6802
6803    const int64_t OD = ne3 / N;
6804    const int64_t OH = ne2;
6805    const int64_t OW = ne1;
6806    const int64_t OH_OW = OH*OW;
6807    const int64_t KD_KH_KW = KD*KH*KW;
6808    const int64_t KH_KW = KH*KW;
6809    const int64_t IC_KD_KH_KW = IC*KD*KH*KW;
6810
6811    GGML_ASSERT(nb10 == sizeof(float));
6812
6813    // im2col: [N*IC, ID, IH, IW] => [N*OD, OH, OW, IC * KD * KH * KW]
6814    {
6815        ggml_fp16_t * const wdata = (ggml_fp16_t *) dst->data;
6816
6817        for (int64_t in = 0; in < N; in++) {
6818            for (int64_t iod = 0; iod < OD; iod++) {
6819                for (int64_t ioh = 0; ioh < OH; ioh++) {
6820                    for (int64_t iow = 0; iow < OW; iow++) {
6821                        for (int64_t iic = ith; iic < IC; iic += nth) {
6822
6823                            // micro kernel
6824                            ggml_fp16_t * dst_data = wdata + (in*OD*OH_OW + iod*OH_OW + ioh*OW + iow)*IC_KD_KH_KW; // [IC, KD, KH, KW]
6825                            const float * const src_data = (const float *) ((const char *)src1->data + (in*IC + iic)*nb13); // [ID, IH, IW]
6826
6827                            for (int64_t ikd = 0; ikd < KD; ikd++) {
6828                                for (int64_t ikh = 0; ikh < KH; ikh++) {
6829                                    for (int64_t ikw = 0; ikw < KW; ikw++) {
6830                                        const int64_t iiw = iow*s0 + ikw*d0 - p0;
6831                                        const int64_t iih = ioh*s1 + ikh*d1 - p1;
6832                                        const int64_t iid = iod*s2 + ikd*d2 - p2;
6833
6834                                        if (iid < 0 || iid >= ID || iih < 0 || iih >= IH || iiw < 0 || iiw >= IW) {
6835                                            dst_data[iic*KD_KH_KW + ikd * KH_KW + ikh*KW + ikw] = 0;
6836                                        } else {
6837                                            const float * const s = (const float *) ((const char *)src_data + iid*nb12 + iih*nb11 + iiw*nb10); // [ID, IH, IW]
6838                                            dst_data[iic*KD_KH_KW + ikd * KH_KW + ikh*KW + ikw] = GGML_CPU_FP32_TO_FP16(*s);
6839                                        }
6840                                    }
6841                                }
6842                            }
6843                        }
6844                    }
6845                }
6846            }
6847        }
6848    }
6849}
6850
6851// ggml_compute_forward_im2col_3d_f32
6852// src0: kernel [OC*IC, KD, KH, KW]
6853// src1: image [N*IC, ID, IH, IW]
6854// dst:  result [N*OD, OH, OW, IC * KD * KH * KW]
6855static void ggml_compute_forward_im2col_3d_f32(
6856        const ggml_compute_params * params,
6857              ggml_tensor * dst) {
6858
6859    const ggml_tensor * src0 = dst->src[0];
6860    const ggml_tensor * src1 = dst->src[1];
6861
6862    GGML_ASSERT(src1->type == GGML_TYPE_F32);
6863    GGML_ASSERT( dst->type == GGML_TYPE_F32);
6864
6865    GGML_TENSOR_BINARY_OP_LOCALS;
6866
6867    const int32_t s0 = ((const int32_t *)(dst->op_params))[0];
6868    const int32_t s1 = ((const int32_t *)(dst->op_params))[1];
6869    const int32_t s2 = ((const int32_t *)(dst->op_params))[2];
6870    const int32_t p0 = ((const int32_t *)(dst->op_params))[3];
6871    const int32_t p1 = ((const int32_t *)(dst->op_params))[4];
6872    const int32_t p2 = ((const int32_t *)(dst->op_params))[5];
6873    const int32_t d0 = ((const int32_t *)(dst->op_params))[6];
6874    const int32_t d1 = ((const int32_t *)(dst->op_params))[7];
6875    const int32_t d2 = ((const int32_t *)(dst->op_params))[8];
6876    const int32_t IC = ((const int32_t *)(dst->op_params))[9];
6877
6878
6879    const int ith = params->ith;
6880    const int nth = params->nth;
6881
6882    const int64_t N  = ne13 / IC;
6883    const int64_t ID = ne12;
6884    const int64_t IH = ne11;
6885    const int64_t IW = ne10;
6886
6887    const int64_t OC = ne03 / IC;
6888    GGML_UNUSED(OC);
6889    const int64_t KD = ne02;
6890    const int64_t KH = ne01;
6891    const int64_t KW = ne00;
6892
6893    const int64_t OD = ne3 / N;
6894    const int64_t OH = ne2;
6895    const int64_t OW = ne1;
6896
6897    const int64_t OH_OW = OH*OW;
6898    const int64_t KD_KH_KW = KD*KH*KW;
6899    const int64_t KH_KW = KH*KW;
6900    const int64_t IC_KD_KH_KW = IC*KD*KH*KW;
6901
6902    GGML_ASSERT(nb10 == sizeof(float));
6903
6904    // im2col: [N*IC, ID, IH, IW] => [N*OD, OH, OW, IC * KD * KH * KW]
6905    {
6906        float * const wdata = (float *) dst->data;
6907
6908        for (int64_t in = 0; in < N; in++) {
6909            for (int64_t iod = 0; iod < OD; iod++) {
6910                for (int64_t ioh = 0; ioh < OH; ioh++) {
6911                    for (int64_t iow = 0; iow < OW; iow++) {
6912                        for (int64_t iic = ith; iic < IC; iic += nth) {
6913
6914                            // micro kernel
6915                            float * dst_data = wdata + (in*OD*OH_OW + iod*OH_OW + ioh*OW + iow)*IC_KD_KH_KW; // [IC, KD, KH, KW]
6916                            const float * const src_data = (const float *) ((const char *)src1->data + (in*IC + iic)*nb13); // [ID, IH, IW]
6917
6918                            for (int64_t ikd = 0; ikd < KD; ikd++) {
6919                                for (int64_t ikh = 0; ikh < KH; ikh++) {
6920                                    for (int64_t ikw = 0; ikw < KW; ikw++) {
6921                                        const int64_t iiw = iow*s0 + ikw*d0 - p0;
6922                                        const int64_t iih = ioh*s1 + ikh*d1 - p1;
6923                                        const int64_t iid = iod*s2 + ikd*d2 - p2;
6924
6925                                        if (iid < 0 || iid >= ID || iih < 0 || iih >= IH || iiw < 0 || iiw >= IW || iid < 0 || iid >= ID) {
6926                                            dst_data[iic*KD_KH_KW + ikd * KH_KW + ikh*KW + ikw] = 0;
6927                                        } else {
6928                                            const float * const s = (const float *) ((const char *)src_data + iid*nb12 + iih*nb11 + iiw*nb10); // [ID, IH, IW]
6929                                            dst_data[iic*KD_KH_KW + ikd * KH_KW + ikh*KW + ikw] = *s;
6930                                        }
6931                                    }
6932                                }
6933                            }
6934                        }
6935                    }
6936                }
6937            }
6938        }
6939    }
6940}
6941
6942
6943void ggml_compute_forward_im2col_3d(
6944        const ggml_compute_params * params,
6945              ggml_tensor * dst) {
6946    switch (dst->type) {
6947        case GGML_TYPE_F16:
6948            {
6949                ggml_compute_forward_im2col_3d_f16(params, dst);
6950            } break;
6951        case GGML_TYPE_F32:
6952            {
6953                ggml_compute_forward_im2col_3d_f32(params, dst);
6954            } break;
6955        default:
6956            {
6957                GGML_ABORT("fatal error");
6958            }
6959    }
6960}
6961
6962static void ggml_call_mul_mat(ggml_type type, const ggml_compute_params * params, int64_t m, int64_t n, int64_t k,
6963                              void * a, void * b, float * c) {
6964    const ggml_type_traits * traits = ggml_get_type_traits(type);
6965    struct ggml_tensor src1 = {};
6966    src1.type  = type;
6967    src1.ne[0] = k;
6968    src1.ne[1] = m;
6969    src1.ne[2] = 1;
6970    src1.ne[3] = 1;
6971    src1.nb[0] = traits->type_size;
6972    src1.nb[1] = k * traits->type_size;
6973    src1.nb[2] = src1.nb[1];
6974    src1.nb[3] = src1.nb[2];
6975    src1.data  = a;
6976
6977    struct ggml_tensor src0 = {};
6978    src0.type  = type;
6979    src0.ne[0] = k;
6980    src0.ne[1] = n;
6981    src0.ne[2] = 1;
6982    src0.ne[3] = 1;
6983    src0.nb[0] = traits->type_size;
6984    src0.nb[1] = k * traits->type_size;
6985    src0.nb[2] = src0.nb[1];
6986    src0.nb[3] = src0.nb[2];
6987    src0.data  = b;
6988
6989    struct ggml_tensor dst = {};
6990    dst.ne[0] = n;
6991    dst.ne[1] = m;
6992    dst.ne[2] = 1;
6993    dst.ne[3] = 1;
6994    dst.nb[0] = sizeof(float);
6995    dst.nb[1] = n * sizeof(float);
6996    dst.nb[2] = dst.nb[1];
6997    dst.nb[3] = dst.nb[2];
6998    dst.data  = c;
6999    dst.src[0] = &src0;
7000    dst.src[1] = &src1;
7001
7002    ggml_compute_forward_mul_mat(params, &dst);
7003}
7004
7005static inline int64_t ggml_wrap_around(int64_t coord, int64_t size) {
7006    return (coord  + size) % size; // adding size avoids negative number weirdness
7007}
7008
7009// ggml_compute_forward_col2im_1d
7010//
7011// Scatter-add columns [K*OC, T_in] -> signal [T_out, OC]
7012// where T_out = (T_in - 1)*s + K - 2*p.  Gather approach: each output reads ceil(K/s) inputs.
7013// Parallelized over the time axis so the split stays balanced whatever OC is.
7014// Supports F32, F16, BF16 input/output (same type), F32 accumulator.
7015
7016template <typename elem_t>
7017static void ggml_compute_forward_col2im_1d_impl(
7018        const ggml_compute_params * params,
7019        ggml_tensor * dst) {
7020
7021    const ggml_tensor * src = dst->src[0];  // [K*OC, T_in]
7022
7023    GGML_ASSERT(ggml_is_contiguous(src));
7024    GGML_ASSERT(ggml_is_contiguous(dst));
7025
7026    const int32_t s0 = ((const int32_t *)(dst->op_params))[0];
7027    const int32_t OC = ((const int32_t *)(dst->op_params))[1];
7028    const int32_t p0 = ((const int32_t *)(dst->op_params))[2];
7029
7030    const int64_t K_OC = src->ne[0];
7031    const int64_t T_in = src->ne[1];
7032    const int64_t K    = K_OC / OC;
7033    const int64_t T_out = dst->ne[0];
7034
7035    const elem_t * col_data = (const elem_t *) src->data;
7036    elem_t       * dst_data = (elem_t *) dst->data;
7037
7038    const int ith = params->ith;
7039    const int nth = params->nth;
7040
7041    // Parallelize over the time axis: the split stays balanced whatever OC is,
7042    // down to OC = 1 for mono audio, and threads read disjoint column bands
7043    const int64_t dr = (T_out + nth - 1) / nth;
7044    const int64_t it0 = dr * ith;
7045    const int64_t it1 = it0 + dr < T_out ? it0 + dr : T_out;
7046
7047    for (int64_t oc = 0; oc < OC; oc++) {
7048        for (int64_t t_out = it0; t_out < it1; t_out++) {
7049            const int64_t t_abs = t_out + p0;  // absolute position in uncropped signal
7050            // Gather: find all (t_in, k) where t_in * s + k == t_abs, 0 <= k < K
7051            int64_t t_in_min = (t_abs - K + 1 + s0 - 1) / s0;  // ceil((t_abs-K+1)/s)
7052            if (t_in_min < 0) t_in_min = 0;
7053            int64_t t_in_max = t_abs / s0;
7054            if (t_in_max >= T_in) t_in_max = T_in - 1;
7055
7056            float sum = 0.0f;
7057            for (int64_t t_in = t_in_min; t_in <= t_in_max; t_in++) {
7058                int64_t k = t_abs - t_in * s0;
7059                if (k >= 0 && k < K) {
7060                    // col layout: [K*OC, T_in], element (oc*K+k, t_in)
7061                    sum += type_conversion_table<elem_t>::to_f32(col_data[(oc * K + k) + t_in * K_OC]);
7062                }
7063            }
7064            // dst layout: [T_out, OC], element (t_out, oc)
7065            dst_data[t_out + oc * T_out] = type_conversion_table<elem_t>::from_f32(sum);
7066        }
7067    }
7068}
7069
7070void ggml_compute_forward_col2im_1d(
7071        const ggml_compute_params * params,
7072        ggml_tensor * dst) {
7073    switch (dst->src[0]->type) {
7074        case GGML_TYPE_F32:  ggml_compute_forward_col2im_1d_impl<float>      (params, dst); break;
7075        case GGML_TYPE_F16:  ggml_compute_forward_col2im_1d_impl<ggml_fp16_t>(params, dst); break;
7076        case GGML_TYPE_BF16: ggml_compute_forward_col2im_1d_impl<ggml_bf16_t>(params, dst); break;
7077        default: GGML_ABORT("col2im_1d: unsupported type %d", dst->src[0]->type);
7078    }
7079}
7080
7081// ggml_compute_forward_conv_2d
7082
7083
7084static void ggml_compute_forward_conv_2d_impl(const ggml_compute_params * params,
7085                                              const ggml_tensor *         kernel,  // [KW, KH, IC, OC]
7086                                              const ggml_tensor *         src,     // [W, H, C, N]
7087                                              ggml_tensor *               dst,     // [OW, OH, OC, N]
7088                                              ggml_type                   kernel_type) {
7089
7090    GGML_ASSERT(ggml_is_contiguous(kernel));
7091    GGML_ASSERT(kernel_type == GGML_TYPE_F16 || kernel_type == GGML_TYPE_F32);
7092    GGML_ASSERT(kernel->type == kernel_type);
7093
7094    const ggml_type_traits * traits = ggml_get_type_traits(kernel_type);
7095
7096    const int32_t stride_x   = dst->op_params[0];
7097    const int32_t stride_y   = dst->op_params[1];
7098    const int32_t pad_x      = dst->op_params[2];
7099    const int32_t pad_y      = dst->op_params[3];
7100    const int32_t dilation_x = dst->op_params[4];
7101    const int32_t dilation_y = dst->op_params[5];
7102
7103    const int64_t c_in  = src->ne[2];
7104    const int64_t c_out = kernel->ne[3];
7105    GGML_ASSERT(c_in == kernel->ne[2]);
7106
7107    const int64_t src_w = src->ne[0];
7108    const int64_t src_h = src->ne[1];
7109    const int64_t knl_w = kernel->ne[0];
7110    const int64_t knl_h = kernel->ne[1];
7111    const int64_t dst_w = dst->ne[0];
7112    const int64_t dst_h = dst->ne[1];
7113
7114    const float * src_data = (float *) src->data;
7115    void  * knl_data       = kernel->data;
7116    float * dst_data       = (float *) dst->data;
7117
7118    const int64_t knl_n           = knl_w * knl_h * c_in;
7119    const int64_t patch_total     = dst->ne[3] * dst_w * dst_h;
7120
7121    const int64_t space_per_patch   = knl_n * traits->type_size + c_out * sizeof(float);
7122    const int64_t batch_size        = params->wsize / space_per_patch;
7123    const int64_t patches_per_batch = batch_size > 8 ? (batch_size / 8) * 8 : batch_size;
7124    const int64_t batch_n           = (patch_total + patches_per_batch - 1) / patches_per_batch;
7125
7126    GGML_ASSERT(patches_per_batch > 0 && batch_size >= 1);
7127
7128    void * tmp = params->wdata;
7129
7130    for (int64_t batch_i = 0; batch_i < batch_n; ++batch_i) {
7131
7132        const int64_t patch_start_batch = batch_i * patches_per_batch;
7133        const int64_t patch_end_batch   = std::min(patch_start_batch + patches_per_batch,
7134                                              patch_total);
7135        const int64_t patch_n           = patch_end_batch - patch_start_batch;
7136
7137        const int64_t patch_per_thread  = (patch_n + params->nth - 1) / params->nth;
7138        const int64_t patch_start       = patch_start_batch + params->ith * patch_per_thread;
7139        const int64_t patch_end         = std::min(patch_start + patch_per_thread, patch_end_batch);
7140
7141        //im2col for a patch
7142        for (int64_t p = patch_start; p < patch_end; ++p) {
7143            const int64_t  batch_n     =  p / (dst_w * dst_h);
7144            const int64_t  src_x       = (p / dst_w) % dst_h;
7145            const int64_t  src_y       =  p % dst_w;
7146
7147            const float * src_base = (const float *)((const char *)src_data + batch_n * src->nb[3]);
7148            char *        dst_row  = (char *) tmp + (p % patches_per_batch) * knl_n * traits->type_size;
7149
7150            for (int64_t ic = 0; ic < c_in; ++ic) {
7151                for (int64_t ky = 0; ky < knl_h; ++ky) {
7152                    for (int64_t kx = 0; kx < knl_w; ++kx) {
7153                        const int64_t sy = src_x * stride_y + ky * dilation_y - pad_y;
7154                        const int64_t sx = src_y * stride_x + kx * dilation_x - pad_x;
7155
7156                        int64_t dst_idx = ic * (knl_h * knl_w) + ky * knl_w + kx;
7157
7158                        float src_val;
7159                        if (sy < 0 || sy >= src_h || sx < 0 || sx >= src_w) {
7160                            src_val = 0.0f;
7161                        } else {
7162                            const float * src_ptr = (const float *)((const char *)src_base + sx * src->nb[0] + sy * src->nb[1] + ic * src->nb[2]);
7163                            src_val               = *src_ptr;
7164                        }
7165
7166                        char * element_ptr = dst_row + dst_idx * traits->type_size;
7167                        if (kernel_type == GGML_TYPE_F32) {
7168                            *(float *) element_ptr = src_val;
7169                        } else if (kernel_type == GGML_TYPE_F16) {
7170                            *(ggml_fp16_t *) element_ptr = GGML_CPU_FP32_TO_FP16(src_val);
7171                        }
7172                    }
7173                }
7174            }
7175        }   // patches handled by this thread
7176
7177        ggml_barrier(params->threadpool);
7178
7179        float * gemm_output = (float *) ((char *) tmp + patches_per_batch * knl_n * traits->type_size);
7180
7181        GGML_ASSERT(gemm_output + patch_n * c_out <= (float*)tmp + params->wsize);
7182
7183        // GEMM: patches[patch_n, knl_n] × kernel[knl_n, c_out] = output[patch_n, c_out]
7184        ggml_call_mul_mat(kernel_type, params, patch_n, c_out, knl_n, tmp, knl_data, gemm_output);
7185
7186        ggml_barrier(params->threadpool);
7187
7188
7189        //permute back [OC, N, OH, OW] to [N, OC, OH, OW]
7190        const int64_t permute_per_thread = (patch_n + params->nth - 1) / params->nth;
7191        const int64_t permute_start = params->ith * permute_per_thread;
7192        const int64_t permute_end = std::min(permute_start + permute_per_thread, patch_n);
7193
7194        for (int64_t i = permute_start; i < permute_end; ++i) {
7195            const int64_t p       = patch_start_batch + i;
7196            const int64_t batch_n = p / (dst_w * dst_h);
7197            const int64_t dst_y   = (p / dst_w) % dst_h;
7198            const int64_t dst_x   = p % dst_w;
7199
7200            for (int64_t oc = 0; oc < c_out; ++oc) {
7201                const float value = gemm_output[i * c_out + oc];
7202                float * dst_ptr = (float *)((char *)dst_data + dst_x * dst->nb[0] + dst_y * dst->nb[1] + oc * dst->nb[2] + batch_n * dst->nb[3]);
7203                *dst_ptr = value;
7204            }
7205        }
7206    }
7207}
7208
7209void ggml_compute_forward_conv_2d(
7210        const ggml_compute_params * params,
7211        ggml_tensor * dst) {
7212
7213    const ggml_tensor * src0 = dst->src[0];
7214    const ggml_tensor * src1 = dst->src[1];
7215
7216    ggml_compute_forward_conv_2d_impl(params, src0, src1, dst, src0->type);
7217}
7218
7219// ggml_compute_forward_conv_3d
7220
7221static void ggml_compute_forward_conv_3d_impl(const ggml_compute_params * params,
7222                                              const ggml_tensor *         kernel,
7223                                              const ggml_tensor *         src,
7224                                              ggml_tensor *               dst,
7225                                              ggml_type                   kernel_type) {
7226
7227    GGML_ASSERT(ggml_is_contiguous(kernel));
7228    GGML_ASSERT(kernel_type == GGML_TYPE_F16 || kernel_type == GGML_TYPE_F32);
7229    GGML_ASSERT(kernel->type == kernel_type);
7230
7231    const ggml_type_traits * traits = ggml_get_type_traits(kernel_type);
7232
7233    const int32_t s0 = dst->op_params[0];
7234    const int32_t s1 = dst->op_params[1];
7235    const int32_t s2 = dst->op_params[2];
7236    const int32_t p0 = dst->op_params[3];
7237    const int32_t p1 = dst->op_params[4];
7238    const int32_t p2 = dst->op_params[5];
7239    const int32_t d0 = dst->op_params[6];
7240    const int32_t d1 = dst->op_params[7];
7241    const int32_t d2 = dst->op_params[8];
7242    const int32_t c  = dst->op_params[9];
7243    const int32_t n  = dst->op_params[10];
7244    const int32_t oc = dst->op_params[11];
7245
7246    const int64_t src_w = src->ne[0];
7247    const int64_t src_h = src->ne[1];
7248    const int64_t src_d = src->ne[2];
7249    const int64_t knl_w = kernel->ne[0];
7250    const int64_t knl_h = kernel->ne[1];
7251    const int64_t knl_d = kernel->ne[2];
7252    const int64_t dst_w = dst->ne[0];
7253    const int64_t dst_h = dst->ne[1];
7254    const int64_t dst_d = dst->ne[2];
7255
7256    const float * src_data = (float *) src->data;
7257    void  * knl_data       = kernel->data;
7258    float * dst_data       = (float *) dst->data;
7259
7260    const int64_t knl_n_per_channel = knl_w * knl_h * knl_d;
7261    const int64_t knl_n_total       = knl_n_per_channel * c;
7262    const int64_t patch_total       = n * dst_w * dst_h * dst_d;
7263
7264    const int64_t space_per_patch   = knl_n_total * traits->type_size + oc * sizeof(float);
7265    const int64_t batch_size        = params->wsize / space_per_patch;
7266    const int64_t patches_per_batch = batch_size > 8 ? (batch_size / 8) * 8 : batch_size;
7267    const int64_t batch_n           = (patch_total + patches_per_batch - 1) / patches_per_batch;
7268
7269    GGML_ASSERT(patches_per_batch > 0 && batch_size >= 1);
7270
7271    void * tmp = params->wdata;
7272
7273    for (int64_t batch_i = 0; batch_i < batch_n; ++batch_i) {
7274        const int64_t patch_start_batch = batch_i * patches_per_batch;
7275        const int64_t patch_end_batch   = std::min(patch_start_batch + patches_per_batch, patch_total);
7276        const int64_t patch_n_in_batch  = patch_end_batch - patch_start_batch;
7277
7278        const int64_t patch_per_thread  = (patch_n_in_batch + params->nth - 1) / params->nth;
7279        const int64_t patch_start       = patch_start_batch + params->ith * patch_per_thread;
7280        const int64_t patch_end         = std::min(patch_start + patch_per_thread, patch_end_batch);
7281
7282        for (int64_t p = patch_start; p < patch_end; ++p) {
7283            const int64_t p_in_batch = p % (dst_w * dst_h * dst_d);
7284            const int64_t p_in_depth = p_in_batch % (dst_w * dst_h);
7285            const int64_t batch_idx  = p / (dst_w * dst_h * dst_d);
7286            const int64_t dst_z      = p_in_batch / (dst_w * dst_h);
7287            const int64_t dst_y      = p_in_depth / dst_w;
7288            const int64_t dst_x      = p_in_depth % dst_w;
7289
7290            char * dst_row = (char *) tmp + (p % patches_per_batch) * knl_n_total * traits->type_size;
7291
7292            for (int64_t ic = 0; ic < c; ++ic) {
7293                for (int64_t kz = 0; kz < knl_d; ++kz) {
7294                    for (int64_t ky = 0; ky < knl_h; ++ky) {
7295                        for (int64_t kx = 0; kx < knl_w; ++kx) {
7296                            const int64_t sz = dst_z * s2 + kz * d2 - p2;
7297                            const int64_t sy = dst_y * s1 + ky * d1 - p1;
7298                            const int64_t sx = dst_x * s0 + kx * d0 - p0;
7299
7300                            int64_t dst_idx = ic * knl_n_per_channel + kz * (knl_h * knl_w) + ky * knl_w + kx;
7301
7302                            float src_val;
7303                            if (sz < 0 || sz >= src_d || sy < 0 || sy >= src_h || sx < 0 || sx >= src_w) {
7304                                src_val = 0.0f;
7305                            } else {
7306                                const int64_t cn_idx = batch_idx * c + ic;
7307                                const float * src_ptr = (const float *)((const char *)src_data + sx*src->nb[0] + sy*src->nb[1] + sz*src->nb[2] + cn_idx*src->nb[3]);
7308                                src_val = *src_ptr;
7309                            }
7310
7311                            char * element_ptr = dst_row + dst_idx * traits->type_size;
7312                            if (kernel_type == GGML_TYPE_F32) {
7313                                *(float *)element_ptr = src_val;
7314                            } else if (kernel_type == GGML_TYPE_F16) {
7315                                *(ggml_fp16_t *)element_ptr = GGML_CPU_FP32_TO_FP16(src_val);
7316                            }
7317                        }
7318                    }
7319                }
7320            }
7321        }
7322
7323        ggml_barrier(params->threadpool);
7324
7325        float * gemm_output = (float *) ((char *) tmp + patches_per_batch * knl_n_total * traits->type_size);
7326        ggml_call_mul_mat(kernel_type, params, patch_n_in_batch, oc, knl_n_total, tmp, knl_data, gemm_output);
7327
7328        ggml_barrier(params->threadpool);
7329
7330        const int64_t permute_per_thread = (patch_n_in_batch + params->nth - 1) / params->nth;
7331        const int64_t permute_start = params->ith * permute_per_thread;
7332        const int64_t permute_end = std::min(permute_start + permute_per_thread, patch_n_in_batch);
7333
7334        for (int64_t i = permute_start; i < permute_end; ++i) {
7335            const int64_t p = patch_start_batch + i;
7336            const int64_t p_in_batch = p % (dst_w * dst_h * dst_d);
7337            const int64_t p_in_depth = p_in_batch % (dst_w * dst_h);
7338            const int64_t batch_idx  = p / (dst_w * dst_h * dst_d);
7339            const int64_t dst_z      = p_in_batch / (dst_w * dst_h);
7340            const int64_t dst_y      = p_in_depth / dst_w;
7341            const int64_t dst_x      = p_in_depth % dst_w;
7342
7343            for (int64_t ioc = 0; ioc < oc; ++ioc) {
7344                const float value = gemm_output[i * oc + ioc];
7345                const int64_t ocn_idx = batch_idx * oc + ioc;
7346                float * dst_ptr = (float *)((char *)dst_data + dst_x*dst->nb[0] + dst_y*dst->nb[1] + dst_z*dst->nb[2] + ocn_idx*dst->nb[3]);
7347                *dst_ptr = value;
7348            }
7349        }
7350    }
7351}
7352
7353void ggml_compute_forward_conv_3d(
7354        const ggml_compute_params * params,
7355        ggml_tensor * dst) {
7356    const ggml_tensor * src0 = dst->src[0];
7357    const ggml_tensor * src1 = dst->src[1];
7358    ggml_compute_forward_conv_3d_impl(params, src0, src1, dst, src0->type);
7359}
7360
7361template <typename kernel_t>
7362static void ggml_compute_forward_conv_transpose_2d_impl(
7363    const ggml_compute_params * params,
7364          ggml_tensor * dst) {
7365
7366    const ggml_tensor * src0 = dst->src[0];
7367    const ggml_tensor * src1 = dst->src[1];
7368
7369    GGML_ASSERT(src0->type == GGML_TYPE_F16 || src0->type == GGML_TYPE_F32);
7370    GGML_ASSERT(src1->type == GGML_TYPE_F32);
7371    GGML_ASSERT( dst->type == GGML_TYPE_F32);
7372
7373    GGML_TENSOR_BINARY_OP_LOCALS
7374
7375    const int ith = params->ith;
7376    const int nth = params->nth;
7377
7378    const int nk = ne00*ne01*ne02*ne03;
7379
7380    GGML_ASSERT(nb00 == ggml_type_size(src0->type));
7381    GGML_ASSERT(nb10 == sizeof(float));
7382
7383    if (ith == 0) {
7384        memset(params->wdata, 0, params->wsize);
7385
7386        // permute kernel data (src0) from (Kw x Kh x Cout x Cin) to (Cin x Kw x Kh x Cout)
7387        {
7388            kernel_t * const wdata = (kernel_t *) params->wdata + 0;
7389
7390            for (int64_t i03 = 0; i03 < ne03; i03++) {
7391                for (int64_t i02 = 0; i02 < ne02; i02++) {
7392                    const kernel_t * const src = (kernel_t *)((char *) src0->data + i03*nb03 + i02*nb02);
7393                    kernel_t * dst_data = wdata + i02*ne01*ne00*ne03;
7394                    for (int64_t i01 = 0; i01 < ne01; i01++) {
7395                        for (int64_t i00 = 0; i00 < ne00; i00++) {
7396                            dst_data[i01*ne00*ne03 + i00*ne03 + i03] = src[i01 * ne00 + i00];
7397                        }
7398                    }
7399                }
7400            }
7401        }
7402
7403        // permute source data (src1) from (Sw x Sh x Cin) to (Cin x Sw x Sh), for all batches
7404        {
7405            kernel_t * const wdata = (kernel_t *) params->wdata + nk;
7406            for (int i13 = 0; i13 < ne13; i13++) {
7407                kernel_t * const wdata_b = wdata + i13*ne10*ne11*ne12;
7408                for (int i12 = 0; i12 < ne12; i12++) {
7409                    for (int i11 = 0; i11 < ne11; i11++) {
7410                        const float * const src = (float *)((char *) src1->data + i13*nb13 + i12*nb12 + i11*nb11);
7411                        kernel_t * dst_data = wdata_b + i11*ne10*ne12;
7412                        for (int i10 = 0; i10 < ne10; i10++) {
7413                            if constexpr (std::is_same_v<kernel_t, ggml_fp16_t>) {
7414                                dst_data[i10*ne12 + i12] = GGML_CPU_FP32_TO_FP16(src[i10]);
7415                            } else {
7416                                dst_data[i10*ne12 + i12] = src[i10];
7417                            }
7418                        }
7419                    }
7420                }
7421            }
7422        }
7423
7424        memset(dst->data, 0, ggml_nbytes(dst));
7425    }
7426    ggml_barrier(params->threadpool);
7427
7428    const int32_t stride = ggml_get_op_params_i32(dst, 0);
7429
7430    // total patches in dst
7431    const int np = ne2;
7432
7433    // patches per thread
7434    const int dp = (np + nth - 1)/nth;
7435
7436    // patch range for this thread
7437    const int ip0 = dp*ith;
7438    const int ip1 = MIN(ip0 + dp, np);
7439
7440    kernel_t * const wdata = (kernel_t *) params->wdata + 0;
7441    kernel_t * const wdata_src = wdata + nk;
7442
7443    for (int i2 = ip0; i2 < ip1; i2++) { // Cout
7444        kernel_t * wdata_kernel = wdata + i2*ne01*ne00*ne03;
7445        for (int i3 = 0; i3 < ne3; i3++) { // batch
7446            float * dst_data = (float *)((char *) dst->data + i3*nb3 + i2*nb2);
7447            kernel_t * wdata_src_b = wdata_src + i3*ne10*ne11*ne12;
7448            for (int i11 = 0; i11 < ne11; i11++) {
7449                for (int i10 = 0; i10 < ne10; i10++) {
7450                    const int i1n = i11*ne10*ne12 + i10*ne12;
7451                    for (int i01 = 0; i01 < ne01; i01++) {
7452                        for (int i00 = 0; i00 < ne00; i00++) {
7453                            float v = 0;
7454                            if constexpr (std::is_same_v<kernel_t, ggml_fp16_t>) {
7455                                ggml_vec_dot_f16(ne03, &v, 0,
7456                                        wdata_src_b + i1n, 0,
7457                                        wdata_kernel + i01*ne00*ne03 + i00*ne03, 0, 1);
7458                            } else {
7459                                ggml_vec_dot_f32(ne03, &v, 0,
7460                                        wdata_src_b + i1n, 0,
7461                                        wdata_kernel + i01*ne00*ne03 + i00*ne03, 0, 1);
7462                            }
7463                            dst_data[(i11*stride + i01)*ne0 + i10*stride + i00] += v;
7464                        }
7465                    }
7466                }
7467            }
7468        }
7469    }
7470}
7471
7472void ggml_compute_forward_conv_transpose_2d(
7473        const ggml_compute_params * params,
7474              ggml_tensor * dst) {
7475
7476    const ggml_tensor * src0 = dst->src[0];
7477
7478    switch (src0->type) {
7479        case GGML_TYPE_F16:
7480            {
7481                ggml_compute_forward_conv_transpose_2d_impl<ggml_fp16_t>(params, dst);
7482            } break;
7483        case GGML_TYPE_F32:
7484            {
7485                ggml_compute_forward_conv_transpose_2d_impl<float>(params, dst);
7486            } break;
7487        default:
7488            {
7489                GGML_ABORT("fatal error");
7490            }
7491    }
7492}
7493
7494// ggml_compute_forward_conv_2d_dw
7495
7496struct ggml_conv_2d_dw_params {
7497    int64_t channels;
7498    int64_t batch;
7499    int64_t src_w;
7500    int64_t src_h;
7501    int64_t dst_w;
7502    int64_t dst_h;
7503    int64_t knl_w;
7504    int64_t knl_h;
7505    int stride_x;
7506    int stride_y;
7507    int pad_x;
7508    int pad_y;
7509    int dilation_x;
7510    int dilation_y;
7511};
7512
7513static inline float ggml_conv_2d_dw_knl_f32(const char * data, int64_t i, ggml_type type) {
7514    if (type == GGML_TYPE_F16) {
7515        return GGML_FP16_TO_FP32(((const ggml_fp16_t *)data)[i]);
7516    }
7517    return ((const float *)data)[i];
7518}
7519
7520static void ggml_compute_forward_conv_2d_dw_cwhn(
7521        const ggml_compute_params * params,
7522        const ggml_tensor * src,
7523        const ggml_tensor * kernel,
7524        ggml_tensor * dst,
7525        const ggml_conv_2d_dw_params & p) {
7526
7527    const int64_t c = p.channels;
7528    const char * knl_data = (const char *)kernel->data;
7529    const ggml_type knl_type = kernel->type;
7530
7531    const int64_t rows_total = p.dst_h * p.batch;
7532    const int64_t rows_per_thread = (rows_total + params->nth - 1) / params->nth;
7533    const int64_t row_start = params->ith * rows_per_thread;
7534    const int64_t row_end = MIN(row_start + rows_per_thread, rows_total);
7535
7536#ifdef GGML_SIMD
7537    int64_t c_pkg_end = 0;
7538    int64_t pkg_size = GGML_F32_EPR;
7539    if (knl_type == GGML_TYPE_F32) {
7540    #if defined(__ARM_FEATURE_SVE)
7541        pkg_size = svcntw();
7542    #else
7543        pkg_size = GGML_F32_EPR;
7544    #endif
7545        c_pkg_end = (c / pkg_size) * pkg_size;
7546    }
7547#else
7548    const int64_t c_pkg_end = 0;
7549#endif
7550
7551    for (int64_t row = row_start; row < row_end; ++row) {
7552        const int64_t dst_y = row % p.dst_h;
7553        const float * src_data = (const float *)src->data + (row / p.dst_h) * p.src_w * p.src_h * c;
7554        for (int64_t dst_x = 0; dst_x < p.dst_w; ++dst_x) {
7555            float * dst_data = (float *)dst->data + (row * p.dst_w + dst_x) * c;
7556            const int64_t src_y_base = dst_y * p.stride_y - p.pad_y;
7557            const int64_t src_x_base = dst_x * p.stride_x - p.pad_x;
7558
7559#ifdef GGML_SIMD
7560            for (int64_t c_i = 0; c_i < c_pkg_end; c_i += pkg_size) {
7561                GGML_F32_VEC sum = GGML_F32_VEC_ZERO;
7562                for (int64_t knl_y = 0; knl_y < p.knl_h; ++knl_y) {
7563                    const int64_t src_y = src_y_base + knl_y * p.dilation_y;
7564                    if (src_y < 0 || src_y >= p.src_h) {
7565                        continue;
7566                    }
7567                    for (int64_t knl_x = 0; knl_x < p.knl_w; ++knl_x) {
7568                        const int64_t src_x = src_x_base + knl_x * p.dilation_x;
7569                        if (src_x < 0 || src_x >= p.src_w) {
7570                            continue;
7571                        }
7572                        const float * kp = (const float *)knl_data + (knl_y * p.knl_w + knl_x) * c + c_i;
7573                        GGML_F32_VEC k = GGML_F32_VEC_LOAD(kp);
7574                        GGML_F32_VEC s = GGML_F32_VEC_LOAD(src_data + (src_y * p.src_w + src_x) * c + c_i);
7575                        sum = GGML_F32_VEC_FMA(sum, k, s);
7576                    }
7577                }
7578                GGML_F32_VEC_STORE(dst_data + c_i, sum);
7579            }
7580#endif
7581            for (int64_t c_i = c_pkg_end; c_i < c; ++c_i) {
7582                float sum = 0.0f;
7583                for (int64_t knl_y = 0; knl_y < p.knl_h; ++knl_y) {
7584                    const int64_t src_y = src_y_base + knl_y * p.dilation_y;
7585                    if (src_y < 0 || src_y >= p.src_h) {
7586                        continue;
7587                    }
7588                    for (int64_t knl_x = 0; knl_x < p.knl_w; ++knl_x) {
7589                        const int64_t src_x = src_x_base + knl_x * p.dilation_x;
7590                        if (src_x < 0 || src_x >= p.src_w) {
7591                            continue;
7592                        }
7593                        sum += ggml_conv_2d_dw_knl_f32(knl_data, (knl_y * p.knl_w + knl_x) * c + c_i, knl_type)
7594                             * src_data[(src_y * p.src_w + src_x) * c + c_i];
7595                    }
7596                }
7597                dst_data[c_i] = sum;
7598            }
7599        }
7600    }
7601}
7602
7603static void ggml_compute_forward_conv_2d_dw_whcn(
7604        const ggml_compute_params * params,
7605        const ggml_tensor * src,
7606        const ggml_tensor * kernel,
7607        ggml_tensor * dst,
7608        const ggml_conv_2d_dw_params & p) {
7609
7610    const int64_t n = p.channels * p.batch;
7611    const int64_t per_thread = (n + params->nth - 1) / params->nth;
7612    const int64_t start = params->ith * per_thread;
7613    const int64_t end = MIN(start + per_thread, n);
7614    const char * knl_base = (const char *)kernel->data;
7615    const ggml_type knl_type = kernel->type;
7616
7617    for (int64_t i = start; i < end; ++i) {
7618        const int64_t knl_offset = (i % p.channels) * p.knl_w * p.knl_h;
7619        const float * src_data = (const float *)src->data + i * p.src_w * p.src_h;
7620        float * dst_data = (float *)dst->data + i * p.dst_w * p.dst_h;
7621
7622        for (int64_t dst_y = 0; dst_y < p.dst_h; ++dst_y) {
7623            for (int64_t dst_x = 0; dst_x < p.dst_w; ++dst_x) {
7624
7625                float sum = 0.0f;
7626                for (int64_t knl_y = 0; knl_y < p.knl_h; ++knl_y) {
7627                    const int64_t src_y = dst_y * p.stride_y + knl_y * p.dilation_y - p.pad_y;
7628                    if (src_y < 0 || src_y >= p.src_h) {
7629                        continue;
7630                    }
7631                    for (int64_t knl_x = 0; knl_x < p.knl_w; ++knl_x) {
7632                        const int64_t src_x = dst_x * p.stride_x + knl_x * p.dilation_x - p.pad_x;
7633                        if (src_x < 0 || src_x >= p.src_w) {
7634                            continue;
7635                        }
7636                        sum += ggml_conv_2d_dw_knl_f32(knl_base, knl_offset + knl_y * p.knl_w + knl_x, knl_type)
7637                             * src_data[src_y * p.src_w + src_x];
7638                    }
7639                }
7640                dst_data[dst_y * p.dst_w + dst_x] = sum;
7641            }
7642        }
7643    }
7644}
7645
7646void ggml_compute_forward_conv_2d_dw(
7647        const ggml_compute_params * params,
7648        ggml_tensor * dst) {
7649
7650    const ggml_tensor * kernel = dst->src[0];
7651    const ggml_tensor * src = dst->src[1];
7652    ggml_conv_2d_dw_params p;
7653    p.channels = src->ne[2];
7654    p.batch = src->ne[3];
7655    p.src_w = src->ne[0];
7656    p.src_h = src->ne[1];
7657    p.dst_w = dst->ne[0];
7658    p.dst_h = dst->ne[1];
7659    p.knl_w = kernel->ne[0];
7660    p.knl_h = kernel->ne[1];
7661    p.stride_x = dst->op_params[0];
7662    p.stride_y = dst->op_params[1];
7663    p.pad_x = dst->op_params[2];
7664    p.pad_y = dst->op_params[3];
7665    p.dilation_x = dst->op_params[4];
7666    p.dilation_y = dst->op_params[5];
7667
7668    GGML_ASSERT(kernel->type == GGML_TYPE_F32 || kernel->type == GGML_TYPE_F16);
7669    GGML_ASSERT(kernel->ne[3] == p.channels);
7670    GGML_ASSERT(dst->ne[3] == p.batch);
7671
7672    if (ggml_is_contiguous(src)) {
7673        ggml_compute_forward_conv_2d_dw_whcn(params, src, kernel, dst, p);
7674    } else if (ggml_is_contiguous_channels(src)) {
7675        GGML_ASSERT(kernel->nb[0] >= kernel->nb[2] && kernel->nb[1] >= kernel->nb[0]);
7676        ggml_compute_forward_conv_2d_dw_cwhn(params, src, kernel, dst, p);
7677    } else {
7678        GGML_ABORT("non-contiguous memory layout not supported");
7679    }
7680}
7681
7682// ggml_compute_forward_pool_1d_ksp
7683static void ggml_compute_forward_pool_1d_ksp(
7684        const ggml_compute_params * params,
7685        const ggml_op_pool op,
7686        const int k,
7687        const int s,
7688        const int p,
7689        ggml_tensor * dst) {
7690
7691    const ggml_tensor * src = dst->src[0];
7692
7693    assert(src->type == GGML_TYPE_F32 || src->type == GGML_TYPE_F16);
7694
7695    if (params->ith != 0) {
7696        return;
7697    }
7698
7699    const int64_t IW = src->ne[0];
7700    const int64_t OW = dst->ne[0];
7701
7702    const int64_t nr = ggml_nrows(src);
7703
7704    for (int64_t ir = 0; ir < nr; ++ir) {
7705        const char * srow_bytes =            (const char *) src->data + ir * src->nb[1];
7706        float      * drow       = (float *) ((      char *) dst->data + ir * dst->nb[1]);
7707
7708        for (int64_t ow = 0; ow < OW; ++ow) {
7709            float res = 0;
7710            switch (op) {
7711                case GGML_OP_POOL_AVG: res = 0.0f;     break;
7712                case GGML_OP_POOL_MAX: res = -FLT_MAX; break;
7713                case GGML_OP_POOL_COUNT: GGML_ABORT("fatal error");
7714            }
7715
7716            int count = 0;
7717            const int base = (int) ow * s - p;
7718
7719            for (int ki = 0; ki < k; ++ki) {
7720                const int j = base + ki;
7721                if (j < 0 || j >= (int) IW) {
7722                    continue;
7723                }
7724
7725                float v;
7726                if (src->type == GGML_TYPE_F32) {
7727                    v = ((const float *) srow_bytes)[j];
7728                } else {
7729                    v = GGML_CPU_FP16_TO_FP32(((const ggml_fp16_t *) srow_bytes)[j]);
7730                }
7731
7732                switch (op) {
7733                    case GGML_OP_POOL_AVG: res += v;                break;
7734                    case GGML_OP_POOL_MAX: res =  std::max(v, res); break;
7735                    case GGML_OP_POOL_COUNT: GGML_ABORT("fatal error");
7736                }
7737
7738                ++count;
7739            }
7740
7741            switch (op) {
7742                case GGML_OP_POOL_AVG: res = (count > 0) ? (res / count) : 0.0f; break;
7743                case GGML_OP_POOL_MAX:                                           break;
7744                case GGML_OP_POOL_COUNT: GGML_ABORT("fatal error");
7745            }
7746
7747            drow[ow] = res;
7748        }
7749    }
7750}
7751
7752// ggml_compute_forward_pool_1d
7753
7754void ggml_compute_forward_pool_1d(
7755        const ggml_compute_params * params,
7756              ggml_tensor * dst) {
7757
7758    const int32_t * opts = (const int32_t *)dst->op_params;
7759    ggml_op_pool op = static_cast<ggml_op_pool>(opts[0]);
7760    const int k0 = opts[1];
7761    const int s0 = opts[2];
7762    const int p0 = opts[3];
7763
7764    ggml_compute_forward_pool_1d_ksp(params, op, k0, s0, p0, dst);
7765}
7766
7767// ggml_compute_forward_pool_2d
7768
7769void ggml_compute_forward_pool_2d(
7770        const ggml_compute_params * params,
7771        ggml_tensor * dst) {
7772
7773    const ggml_tensor * src = dst->src[0];
7774
7775    assert(src->type == GGML_TYPE_F32 || src->type == GGML_TYPE_F16);
7776
7777    if (params->ith != 0) {
7778        return;
7779    }
7780
7781    const int32_t * opts = (const int32_t *)dst->op_params;
7782
7783    ggml_op_pool op = static_cast<ggml_op_pool>(opts[0]);
7784    const int k0 = opts[1];
7785    const int k1 = opts[2];
7786    const int s0 = opts[3];
7787    const int s1 = opts[4];
7788    const int p0 = opts[5];
7789    const int p1 = opts[6];
7790    const char * cdata = (const char*)src->data;
7791    const char * const data_end = cdata + ggml_nbytes(src);
7792
7793    const int64_t px = dst->ne[0];
7794    const int64_t py = dst->ne[1];
7795    const int64_t pa = px * py;
7796
7797    float * dplane = (float *)dst->data;
7798
7799    const int ka = k0 * k1;
7800    const int offset0 = -p0;
7801    const int offset1 = -p1;
7802
7803    while (cdata < data_end) {
7804        for (int oy = 0; oy < py; ++oy) {
7805            float * const drow = dplane + oy * px;
7806            float * const out  = drow;
7807
7808            for (int ox = 0; ox < px; ++ox) {
7809                float res = 0;
7810                switch (op) {
7811                    case GGML_OP_POOL_AVG: res = 0;        break;
7812                    case GGML_OP_POOL_MAX: res = -FLT_MAX; break;
7813                    case GGML_OP_POOL_COUNT: GGML_ABORT("fatal error");
7814                }
7815
7816                const int ix = offset0 + ox * s0;
7817                const int iy = offset1 + oy * s1;
7818
7819                for (int ky = 0; ky < k1; ++ky) {
7820                    if (iy + ky < 0 || iy + ky >= src->ne[1]) {
7821                        continue;
7822                    }
7823
7824                    const void * srow = (const void *)(cdata + src->nb[1] * (iy + ky));
7825                    for (int kx = 0; kx < k0; ++kx) {
7826                        int j = ix + kx;
7827                        if (j < 0 || j >= src->ne[0]) {
7828                            continue;
7829                        }
7830
7831                        const float srow_j = (src->type == GGML_TYPE_F32) ? ((const float*)srow)[j] : GGML_CPU_FP16_TO_FP32(((const ggml_fp16_t*)srow)[j]);
7832                        switch (op) {
7833                            case GGML_OP_POOL_AVG: res += srow_j;                break;
7834                            case GGML_OP_POOL_MAX: res =  std::max(srow_j, res); break;
7835                            case GGML_OP_POOL_COUNT:               GGML_ABORT("fatal error");
7836                        }
7837                    }
7838                }
7839                switch (op) {
7840                    case GGML_OP_POOL_AVG:           res /= ka; break;
7841                    case GGML_OP_POOL_MAX:                      break;
7842                    case GGML_OP_POOL_COUNT: GGML_ABORT("fatal error");
7843                }
7844
7845                out[ox] = res;
7846            }
7847        }
7848
7849        cdata  += src->nb[2];
7850        dplane += pa;
7851    }
7852}
7853
7854// ggml_compute_forward_pool_2d_back
7855
7856void ggml_compute_forward_pool_2d_back(
7857        const ggml_compute_params * params,
7858        ggml_tensor * dst) {
7859
7860    const ggml_tensor * src  = dst->src[0];
7861    const ggml_tensor * dstf = dst->src[1]; // forward tensor of dst
7862
7863    assert(dst->type == GGML_TYPE_F32 || dst->type == GGML_TYPE_F16);
7864
7865    if (params->ith != 0) {
7866        return;
7867    }
7868
7869    const int32_t * opts = (const int32_t *)dst->op_params;
7870    ggml_op_pool op = static_cast<ggml_op_pool>(opts[0]);
7871    const int k0 = opts[1];
7872    const int k1 = opts[2];
7873    const int s0 = opts[3];
7874    const int s1 = opts[4];
7875    const int p0 = opts[5];
7876    const int p1 = opts[6];
7877
7878    char       * cdata  = (char       *) dst->data;
7879    const char * cdataf = (const char *) dstf->data;
7880    const char * const data_end = cdata + ggml_nbytes(dst);
7881
7882    GGML_ASSERT(params->ith == 0);
7883    memset(cdata, 0, ggml_nbytes(dst));
7884
7885    const int64_t px = src->ne[0];
7886    const int64_t py = src->ne[1];
7887    const int64_t pa = px * py;
7888
7889    const float * splane = (const float *) src->data;
7890
7891    const int ka = k0 * k1;
7892    const int offset0 = -p0;
7893    const int offset1 = -p1;
7894
7895    while (cdata < data_end) {
7896        for (int oy = 0; oy < py; ++oy) {
7897            const float * const srow = splane + oy * px;
7898            for (int ox = 0; ox < px; ++ox) {
7899                const float grad0 = srow[ox];
7900
7901                const int ix = offset0 + ox * s0;
7902                const int iy = offset1 + oy * s1;
7903
7904                if (op == GGML_OP_POOL_MAX) {
7905                    float maxval = -FLT_MAX;
7906                    int kxmax = -1;
7907                    int kymax = -1;
7908
7909                    for (int ky = 0; ky < k1; ++ky) {
7910                        if (iy + ky < 0 || iy + ky >= dst->ne[1]) {
7911                            continue;
7912                        }
7913                        const void * drowf = (const void *)(cdataf + dst->nb[1] * (iy + ky));
7914                        for (int kx = 0; kx < k0; ++kx) {
7915                            int j = ix + kx;
7916                            if (j < 0 || j >= dst->ne[0]) {
7917                                continue;
7918                            }
7919
7920                            const float val = dst->type == GGML_TYPE_F32 ?
7921                                ((const float *) drowf)[j] : GGML_CPU_FP16_TO_FP32(((const ggml_fp16_t *) drowf)[j]);
7922                            if (val <= maxval) {
7923                                continue;
7924                            }
7925
7926                            maxval = val;
7927                            kxmax = kx;
7928                            kymax = ky;
7929                        }
7930                    }
7931
7932                    if (kxmax == -1 || kymax == -1) {
7933                        continue;
7934                    }
7935
7936                    void * drow = (void *)(cdata + dst->nb[1] * (iy + kymax));
7937                    const int j = ix + kxmax;
7938                    if (dst->type == GGML_TYPE_F32) {
7939                        ((float *) drow)[j] += grad0;
7940                    } else {
7941                        ((ggml_fp16_t *) drow)[j] = GGML_CPU_FP32_TO_FP16(grad0 + GGML_CPU_FP16_TO_FP32(((const ggml_fp16_t *) drow)[j]));
7942                    }
7943                } else if (op == GGML_OP_POOL_AVG) {
7944                    const float grad = grad0 / ka;
7945
7946                    for (int ky = 0; ky < k1; ++ky) {
7947                        if (iy + ky < 0 || iy + ky >= dst->ne[1]) {
7948                            continue;
7949                        }
7950                        void * drow = (void *)(cdata + dst->nb[1] * (iy + ky));
7951                        for (int kx = 0; kx < k0; ++kx) {
7952                            int j = ix + kx;
7953                            if (j < 0 || j >= dst->ne[0]) {
7954                                continue;
7955                            }
7956
7957                            if (dst->type == GGML_TYPE_F32) {
7958                                ((float *) drow)[j] += grad;
7959                            } else {
7960                                ((ggml_fp16_t *) drow)[j] += GGML_CPU_FP32_TO_FP16(grad);
7961                            }
7962                        }
7963                    }
7964                } else {
7965                    GGML_ASSERT(false);
7966                }
7967            }
7968        }
7969
7970        cdata  += dst->nb[2];
7971        cdataf += dst->nb[2];
7972        splane += pa;
7973    }
7974}
7975
7976// ggml_compute_forward_upscale
7977
7978static void ggml_compute_forward_upscale_f32(
7979    const ggml_compute_params * params,
7980    ggml_tensor * dst) {
7981
7982    const ggml_tensor * src0 = dst->src[0];
7983
7984    GGML_ASSERT(src0->type == GGML_TYPE_F32);
7985
7986    const int ith = params->ith;
7987    const int nth = params->nth;
7988
7989    GGML_TENSOR_UNARY_OP_LOCALS
7990
7991    float sf0 = (float)ne0/src0->ne[0];
7992    float sf1 = (float)ne1/src0->ne[1];
7993    float sf2 = (float)ne2/src0->ne[2];
7994    float sf3 = (float)ne3/src0->ne[3];
7995    float pixel_offset = 0.5f;
7996
7997    const int32_t mode_flags = ggml_get_op_params_i32(dst, 0);
7998    const ggml_scale_mode mode = (ggml_scale_mode) (mode_flags & 0xFF);
7999
8000    if (mode_flags & GGML_SCALE_FLAG_ALIGN_CORNERS) {
8001        pixel_offset = 0.0f;
8002        sf0 = ne0 > 1 && ne00 > 1 ? (float)(ne0 - 1) / (ne00 - 1) : sf0;
8003        sf1 = ne1 > 1 && ne01 > 1 ? (float)(ne1 - 1) / (ne01 - 1) : sf1;
8004    }
8005
8006    if (mode == GGML_SCALE_MODE_NEAREST) {
8007        for (int64_t i3 = 0; i3 < ne3; i3++) {
8008            const int64_t i03 = i3 / sf3;
8009            for (int64_t i2 = ith; i2 < ne2; i2 += nth) {
8010                const int64_t i02 = i2 / sf2;
8011                for (int64_t i1 = 0; i1 < ne1; i1++) {
8012                    const int64_t i01 = i1 / sf1;
8013                    for (int64_t i0 = 0; i0 < ne0; i0++) {
8014                        const int64_t i00 = i0 / sf0;
8015
8016                        const float * x = (float *)((char *) src0->data + i00*nb00 + i01*nb01 + i02*nb02 + i03*nb03);
8017                              float * y = (float *)((char *)  dst->data +  i0*nb0  +  i1*nb1  +  i2*nb2  +  i3*nb3);
8018
8019                        *y = *x;
8020                    }
8021                }
8022            }
8023        }
8024    } else if (mode == GGML_SCALE_MODE_BILINEAR && (mode_flags & GGML_SCALE_FLAG_ANTIALIAS)) {
8025        // Similar to F.interpolate(..., mode="bilinear", align_corners=False, antialias=True)
8026        // https://github.com/pytorch/pytorch/blob/8871ff29b743948d1225389d5b7068f37b22750b/aten/src/ATen/native/cpu/UpSampleKernel.cpp
8027        auto triangle_filter = [](float x) -> float {
8028            return std::max(1.0f - fabsf(x), 0.0f);
8029        };
8030
8031        // support and invscale, minimum 1 pixel for bilinear
8032        const float support1  = std::max(1.0f, 1.0f / sf1);
8033        const float invscale1 = 1.0f / support1;
8034        const float support0  = std::max(1.0f, 1.0f / sf0);
8035        const float invscale0 = 1.0f / support0;
8036
8037        for (int64_t i3 = 0; i3 < ne3; i3++) {
8038            const int64_t i03 = i3 / sf3;
8039            for (int64_t i2 = ith; i2 < ne2; i2 += nth) {
8040                const int64_t i02 = i2 / sf2;
8041                for (int64_t i1 = 0; i1 < ne1; i1++) {
8042                    const float y = ((float) i1 + pixel_offset) / sf1;
8043                    for (int64_t i0 = 0; i0 < ne0; i0++) {
8044                        const float x = ((float) i0 + pixel_offset) / sf0;
8045
8046                        // the range of source pixels that contribute
8047                        const int64_t x_min = std::max<int64_t>(x - support0 + pixel_offset, 0);
8048                        const int64_t x_max = std::min<int64_t>(x + support0 + pixel_offset, ne00);
8049                        const int64_t y_min = std::max<int64_t>(y - support1 + pixel_offset, 0);
8050                        const int64_t y_max = std::min<int64_t>(y + support1 + pixel_offset, ne01);
8051
8052                        // bilinear filter with antialiasing
8053                        float val = 0.0f;
8054                        float total_weight = 0.0f;
8055
8056                        for (int64_t sy = y_min; sy < y_max; sy++) {
8057                            const float weight_y = triangle_filter((sy - y + pixel_offset) * invscale1);
8058
8059                            for (int64_t sx = x_min; sx < x_max; sx++) {
8060                                const float weight_x = triangle_filter((sx - x + pixel_offset) * invscale0);
8061                                const float weight = weight_x * weight_y;
8062
8063                                if (weight <= 0.0f) {
8064                                    continue;
8065                                }
8066
8067                                const float pixel = *(const float *)((const char *)src0->data + sx*nb00 + sy*nb01 + i02*nb02 + i03*nb03);
8068                                val += pixel * weight;
8069                                total_weight += weight;
8070                            }
8071                        }
8072
8073                        if (total_weight > 0.0f) {
8074                            val /= total_weight;
8075                        }
8076
8077                        float * dst_ptr = (float *)((char *)dst->data + i0*nb0 + i1*nb1 + i2*nb2 + i3*nb3);
8078                        *dst_ptr = val;
8079                    }
8080                }
8081            }
8082        }
8083    } else if (mode == GGML_SCALE_MODE_BILINEAR) {
8084        for (int64_t i3 = 0; i3 < ne3; i3++) {
8085            const int64_t i03 = i3 / sf3;
8086            for (int64_t i2 = ith; i2 < ne2; i2 += nth) {
8087                const int64_t i02 = i2 / sf2;
8088                for (int64_t i1 = 0; i1 < ne1; i1++) {
8089                    const float y = ((float)i1 + pixel_offset) / sf1 - pixel_offset;
8090                    int64_t y0 = (int64_t)floorf(y);
8091                    int64_t y1 = y0 + 1;
8092
8093                    y0 = std::max(int64_t(0), std::min(y0, ne01 - 1));
8094                    y1 = std::max(int64_t(0), std::min(y1, ne01 - 1));
8095
8096                    float dy = y - (float)y0;
8097                    dy = std::max(0.0f, std::min(dy, 1.0f));
8098
8099                    for (int64_t i0 = 0; i0 < ne0; i0++) {
8100                        const float x = ((float)i0 + pixel_offset) / sf0 - pixel_offset;
8101                        int64_t x0 = (int64_t)floorf(x);
8102                        int64_t x1 = x0 + 1;
8103
8104                        x0 = std::max(int64_t(0), std::min(x0, ne00 - 1));
8105                        x1 = std::max(int64_t(0), std::min(x1, ne00 - 1));
8106
8107                        float dx = x - (float)x0;
8108                        dx = std::max(0.0f, std::min(dx, 1.0f));
8109
8110                        // fetch the four surrounding pixel values and interpolate
8111                        const float a = *(const float *)((const char *)src0->data + x0*nb00 + y0*nb01 + i02*nb02 + i03*nb03);
8112                        const float b = *(const float *)((const char *)src0->data + x1*nb00 + y0*nb01 + i02*nb02 + i03*nb03);
8113                        const float c = *(const float *)((const char *)src0->data + x0*nb00 + y1*nb01 + i02*nb02 + i03*nb03);
8114                        const float d = *(const float *)((const char *)src0->data + x1*nb00 + y1*nb01 + i02*nb02 + i03*nb03);
8115
8116                        const float val = a*(1 - dx)*(1 - dy) + b*dx*(1 - dy) + c*(1 - dx)*dy + d*dx*dy;
8117
8118                        float * y_dst = (float *)((char *)dst->data + i0*nb0 + i1*nb1 + i2*nb2 + i3*nb3);
8119                        *y_dst = val;
8120                    }
8121                }
8122            }
8123        }
8124    } else if (mode == GGML_SCALE_MODE_BICUBIC) {
8125        // https://en.wikipedia.org/wiki/Bicubic_interpolation#Bicubic_convolution_algorithm
8126        const float a = -0.75f; // use alpha = -0.75 (same as PyTorch)
8127        auto weight1 = [a](float x) { return ((a + 2) * x - (a + 3)) * x * x + 1; };
8128        auto weight2 = [a](float x) { return ((a * x - 5 * a) * x + 8 * a) * x - 4 * a; };
8129        auto bicubic = [=](float p0, float p1, float p2, float p3, float x) {
8130            const float w0 = weight2(x + 1);
8131            const float w1 = weight1(x + 0);
8132            const float w2 = weight1(1 - x);
8133            const float w3 = weight2(2 - x);
8134            return p0*w0 + p1*w1 + p2*w2 + p3*w3;
8135        };
8136
8137        for (int64_t i3 = 0; i3 < ne3; i3++) {
8138            const int64_t i03 = i3 / sf3;
8139            for (int64_t i2 = ith; i2 < ne2; i2 += nth) {
8140                const int64_t i02 = i2 / sf2;
8141                for (int64_t i1 = 0; i1 < ne1; i1++) {
8142                    const float y = ((float)i1 + pixel_offset) / sf1 - pixel_offset;
8143                    const int64_t y0 = (int64_t)floorf(y);
8144                    const float dy = y - (float)y0;
8145
8146                    for (int64_t i0 = 0; i0 < ne0; i0++) {
8147                        const float x = ((float)i0 + pixel_offset) / sf0 - pixel_offset;
8148                        const int64_t x0 = (int64_t)floorf(x);
8149                        const float dx = x - (float)x0;
8150
8151                        auto p = [=](int64_t x_off, int64_t y_off) -> float {
8152                            int64_t i00 = std::max(int64_t(0), std::min(x0 + x_off, ne00 - 1));
8153                            int64_t i01 = std::max(int64_t(0), std::min(y0 + y_off, ne01 - 1));
8154                            return *(const float *)((const char *)src0->data + i00*nb00 + i01*nb01 + i02*nb02 + i03*nb03);
8155                        };
8156
8157                        const float val = bicubic(
8158                            bicubic(p(-1,-1), p(0,-1), p(1,-1), p(2,-1), dx),
8159                            bicubic(p(-1, 0), p(0, 0), p(1, 0), p(2, 0), dx),
8160                            bicubic(p(-1, 1), p(0, 1), p(1, 1), p(2, 1), dx),
8161                            bicubic(p(-1, 2), p(0, 2), p(1, 2), p(2, 2), dx), dy);
8162
8163                        float * y_dst = (float *)((char *)dst->data + i0*nb0 + i1*nb1 + i2*nb2 + i3*nb3);
8164                        *y_dst = val;
8165                    }
8166                }
8167            }
8168        }
8169    } else {
8170        GGML_ABORT("unsupported upscale mode");
8171    }
8172}
8173
8174void ggml_compute_forward_upscale(
8175    const ggml_compute_params * params,
8176    ggml_tensor * dst) {
8177
8178    const ggml_tensor * src0 = dst->src[0];
8179
8180    switch (src0->type) {
8181        case GGML_TYPE_F32:
8182            {
8183                ggml_compute_forward_upscale_f32(params, dst);
8184            } break;
8185        default:
8186            {
8187                GGML_ABORT("fatal error");
8188            }
8189    }
8190}
8191
8192
8193// ggml_compute_forward_pad
8194
8195template<bool circular_t>
8196static void ggml_compute_forward_pad_f32(
8197    const ggml_compute_params * params,
8198          ggml_tensor * dst) {
8199
8200    const ggml_tensor * src0 = dst->src[0];
8201
8202    assert(dst->nb[0] == sizeof(float));
8203
8204    const int ith = params->ith;
8205    const int nth = params->nth;
8206
8207    GGML_TENSOR_UNARY_OP_LOCALS
8208
8209    float * dst_ptr = (float *) dst->data;
8210    const int32_t lp0 = ggml_get_op_params_i32(dst, 0);
8211    const int32_t rp0 = ggml_get_op_params_i32(dst, 1);
8212    const int32_t lp1 = ggml_get_op_params_i32(dst, 2);
8213    const int32_t rp1 = ggml_get_op_params_i32(dst, 3);
8214    const int32_t lp2 = ggml_get_op_params_i32(dst, 4);
8215    const int32_t rp2 = ggml_get_op_params_i32(dst, 5);
8216    const int32_t lp3 = ggml_get_op_params_i32(dst, 6);
8217    const int32_t rp3 = ggml_get_op_params_i32(dst, 7);
8218
8219    // TODO: optimize
8220
8221    for (int64_t i2 = 0; i2 < ne2; ++i2) {
8222        for (int64_t i1 = ith; i1 < ne1; i1 += nth) {
8223            for (int64_t i0 = 0; i0 < ne0; ++i0) {
8224                for (int64_t i3 = 0; i3 < ne3; ++i3) {
8225                    // circular means wrap around on a torus, so x and y loop around
8226                    if constexpr (circular_t) {
8227                        const int64_t dst_idx = i3*(ne0*ne1*ne2) + i2*(ne0*ne1) + i1*ne0 + i0;
8228                        const int64_t src_i0 = ggml_wrap_around(i0 - lp0, ne00);
8229                        const int64_t src_i1 = ggml_wrap_around(i1 - lp1, ne01);
8230                        const int64_t src_i2 = ggml_wrap_around(i2 - lp2, ne02);
8231                        const int64_t src_i3 = ggml_wrap_around(i3 - lp3, ne03);
8232
8233                        const int64_t src_idx =
8234                            src_i3*nb03 +
8235                            src_i2*nb02 +
8236                            src_i1*nb01 +
8237                            src_i0*nb00;
8238
8239                        const float * src_ptr = (const float *)((char *) src0->data + src_idx);
8240                        dst_ptr[dst_idx] = *src_ptr;
8241                    } else {
8242                        const int64_t dst_idx = i3*(ne0*ne1*ne2) + i2*(ne0*ne1) + i1*ne0 + i0;
8243                        if ((i0 >= lp0 && i0 < ne0 - rp0) \
8244                            && (i1 >= lp1 && i1 < ne1 - rp1) \
8245                            && (i2 >= lp2 && i2 < ne2 - rp2) \
8246                            && (i3 >= lp3 && i3 < ne3 - rp3)) {
8247                            const int64_t src_idx = (i3 - lp3)*nb03 + (i2 - lp2)*nb02 + (i1 - lp1)*nb01 + (i0 - lp0)*nb00;
8248                            const float * src_ptr = (const float *)((char *) src0->data + src_idx);
8249                            dst_ptr[dst_idx] = *src_ptr;
8250                        } else {
8251                            dst_ptr[dst_idx] = 0;
8252                        }
8253                    }
8254                }
8255            }
8256        }
8257    }
8258}
8259
8260
8261void ggml_compute_forward_pad(
8262    const ggml_compute_params * params,
8263    ggml_tensor * dst) {
8264    const ggml_tensor * src0 = dst->src[0];
8265    const bool circular = (bool) ggml_get_op_params_i32(dst, 8);
8266    switch (src0->type) {
8267        case GGML_TYPE_F32:
8268            {
8269                if (circular) {
8270                    ggml_compute_forward_pad_f32<true>(params, dst);
8271                } else {
8272                    ggml_compute_forward_pad_f32<false>(params, dst);
8273                }
8274            } break;
8275        default:
8276            {
8277                GGML_ABORT("fatal error");
8278            }
8279    }
8280}
8281
8282// ggml_compute_forward_pad_reflect_1d
8283
8284void ggml_compute_forward_pad_reflect_1d(
8285        const ggml_compute_params * params,
8286              ggml_tensor * dst) {
8287
8288    const ggml_tensor * src0 = dst->src[0];
8289
8290    GGML_ASSERT(src0->type == GGML_TYPE_F32);
8291    GGML_ASSERT( dst->type == GGML_TYPE_F32);
8292
8293    const int ith = params->ith;
8294    const int nth = params->nth;
8295
8296    const int32_t * opts = (const int32_t *) dst->op_params;
8297    const int p0 = opts[0];
8298    const int p1 = opts[1];
8299
8300    GGML_TENSOR_UNARY_OP_LOCALS
8301
8302    for (int64_t i3 = 0; i3 < ne3; i3++) {
8303        for (int64_t i2 = 0; i2 < ne2; i2++) {
8304            for (int64_t i1 = ith; i1 < ne1; i1 += nth) {
8305                float * left  = (float *) ((char *) dst->data + i3*nb3 + i2*nb2 + i1*nb1 +         p0*nb0);
8306                float * right = (float *) ((char *) dst->data + i3*nb3 + i2*nb2 + i1*nb1 + (ne0-p1-1)*nb0);
8307
8308                ggml_vec_cpy_f32(ne00, left, (float *) ((char *) src0->data + i3*nb03 + i2*nb02 + i1*nb01));
8309
8310                for (int i0 = 1; i0 <= p0; i0++) { left[-i0] = left[i0];   }
8311                for (int i0 = 1; i0 <= p1; i0++) { right[i0] = right[-i0]; }
8312            }
8313        }
8314    }
8315}
8316
8317// ggml_compute_forward_roll
8318
8319static int64_t ggml_wrap_index(int64_t i, int64_t ne) {
8320    if (i < 0) {
8321        return i + ne;
8322    } else if (i >= ne) {
8323        return i - ne;
8324    }
8325    return i;
8326}
8327
8328static void ggml_compute_forward_roll_f32(
8329        const ggml_compute_params * params,
8330        ggml_tensor * dst) {
8331
8332    const ggml_tensor * src0 = dst->src[0];
8333    const float * src_data = (const float *) src0->data;
8334    float * dst_data = (float *) dst->data;
8335
8336    GGML_TENSOR_UNARY_OP_LOCALS
8337
8338    const int s0 = ggml_get_op_params_i32(dst, 0);
8339    const int s1 = ggml_get_op_params_i32(dst, 1);
8340    const int s2 = ggml_get_op_params_i32(dst, 2);
8341    const int s3 = ggml_get_op_params_i32(dst, 3);
8342
8343    const int64_t total = ne1 * ne2 * ne3;
8344    const int64_t per_thread = (total + params->nth) / params->nth;
8345    const int64_t start = params->ith * per_thread;
8346    const int64_t end   = std::min(start + per_thread, total);
8347
8348    for (int64_t i = start; i < end; ++i) {
8349        const int64_t i1 = i % ne1;
8350        const int64_t i2 = (i / ne1) % ne2;
8351        const int64_t i3 = i / (ne2 * ne1);
8352        float * dst_row = dst_data + (i3*nb3 + i2*nb2 + i1*nb1) / sizeof(float);
8353
8354        const int64_t i01 = ggml_wrap_index(i1 - s1, ne01);
8355        const int64_t i02 = ggml_wrap_index(i2 - s2, ne02);
8356        const int64_t i03 = ggml_wrap_index(i3 - s3, ne03);
8357        const float * src_row = src_data + (i03*nb03 + i02*nb02 + i01*nb01) / sizeof(float);
8358
8359        const int64_t s = ggml_wrap_index(-s0, ne00);
8360        const int64_t n = ne00 - s;
8361        ggml_vec_cpy_f32(n, dst_row,     src_row + s);
8362        ggml_vec_cpy_f32(s, dst_row + n, src_row);
8363    }
8364}
8365
8366void ggml_compute_forward_roll(
8367        const ggml_compute_params * params,
8368        ggml_tensor * dst) {
8369
8370    const ggml_tensor * src0 = dst->src[0];
8371
8372    switch (src0->type) {
8373        case GGML_TYPE_F32:
8374            {
8375                ggml_compute_forward_roll_f32(params, dst);
8376            } break;
8377        default:
8378            {
8379                GGML_ABORT("fatal error");
8380            }
8381    }
8382}
8383
8384// ggml_compute_forward_arange
8385
8386static void ggml_compute_forward_arange_f32(
8387    const ggml_compute_params * params,
8388    ggml_tensor * dst) {
8389
8390    GGML_ASSERT(dst->nb[0] == sizeof(float));
8391
8392    const int ith = params->ith;
8393    const int nth = params->nth;
8394
8395    const float start = ggml_get_op_params_f32(dst, 0);
8396    const float stop  = ggml_get_op_params_f32(dst, 1);
8397    const float step  = ggml_get_op_params_f32(dst, 2);
8398
8399    const int64_t steps = (int64_t) ceilf((stop - start) / step);
8400
8401    GGML_ASSERT(ggml_nelements(dst) == steps);
8402
8403    for (int64_t i = ith; i < steps; i+= nth) {
8404        float value = start + step * i;
8405        ((float *)dst->data)[i] = value;
8406    }
8407}
8408
8409void ggml_compute_forward_arange(
8410    const ggml_compute_params * params,
8411    ggml_tensor * dst) {
8412    switch (dst->type) {
8413        case GGML_TYPE_F32:
8414            {
8415                ggml_compute_forward_arange_f32(params, dst);
8416            } break;
8417        default:
8418            {
8419                GGML_ABORT("fatal error");
8420            }
8421    }
8422}
8423
8424static void ggml_compute_forward_timestep_embedding_f32(
8425    const ggml_compute_params * params,
8426    ggml_tensor * dst) {
8427
8428    const ggml_tensor * src0 = dst->src[0];
8429
8430    GGML_ASSERT(src0->nb[0] == sizeof(float));
8431
8432    const int ith = params->ith;
8433    const int nth = params->nth;
8434
8435    GGML_TENSOR_UNARY_OP_LOCALS
8436
8437    const int dim = ggml_get_op_params_i32(dst, 0);
8438    const int max_period = ggml_get_op_params_i32(dst, 1);
8439
8440    int half = dim / 2;
8441
8442    for (int64_t i = 0; i < ne00; i++) {
8443        float * embed_data = (float *)((char *)  dst->data +  i*nb1);
8444        for (int64_t j = ith; j < half; j += nth) {
8445            float timestep = ((float *)src0->data)[i];
8446            float freq = (float)expf(-logf(max_period) * j / half);
8447            float arg = timestep * freq;
8448            embed_data[j] = cosf(arg);
8449            embed_data[j + half] = sinf(arg);
8450        }
8451        if (dim % 2 != 0 && ith == 0) {
8452            embed_data[2 * half] = 0.f;
8453        }
8454    }
8455}
8456
8457void ggml_compute_forward_timestep_embedding(
8458    const ggml_compute_params * params,
8459    ggml_tensor * dst) {
8460
8461    const ggml_tensor * src0 = dst->src[0];
8462
8463    switch (src0->type) {
8464        case GGML_TYPE_F32:
8465            {
8466                ggml_compute_forward_timestep_embedding_f32(params, dst);
8467            } break;
8468        default:
8469            {
8470                GGML_ABORT("fatal error");
8471            }
8472    }
8473}
8474
8475// ggml_compute_forward_argsort
8476
8477template<enum ggml_sort_order order>
8478struct cmp_argsort {
8479    const float * data;
8480    bool operator()(int32_t a, int32_t b) const {
8481        if constexpr (order == GGML_SORT_ORDER_ASC) {
8482            return data[a] < data[b];
8483        } else {
8484            return data[a] > data[b];
8485        }
8486    }
8487};
8488
8489static void ggml_compute_forward_argsort_f32(
8490    const ggml_compute_params * params,
8491    ggml_tensor * dst) {
8492
8493    const ggml_tensor * src0 = dst->src[0];
8494
8495    GGML_TENSOR_UNARY_OP_LOCALS
8496
8497    GGML_ASSERT(nb0 == sizeof(float));
8498
8499    const int ith = params->ith;
8500    const int nth = params->nth;
8501
8502    const int64_t nr = ggml_nrows(src0);
8503
8504    ggml_sort_order order = (ggml_sort_order) ggml_get_op_params_i32(dst, 0);
8505
8506    for (int64_t i = ith; i < nr; i += nth) {
8507        const float * src_data = (float *)((char *) src0->data + i*nb01);
8508
8509        int32_t * dst_data = (int32_t *)((char *) dst->data + i*nb1);
8510
8511        for (int64_t j = 0; j < ne0; j++) {
8512            dst_data[j] = j;
8513        }
8514
8515        switch (order) {
8516            case GGML_SORT_ORDER_ASC:
8517                std::sort(dst_data, dst_data + ne0, cmp_argsort<GGML_SORT_ORDER_ASC>{src_data});
8518                break;
8519
8520            case GGML_SORT_ORDER_DESC:
8521                std::sort(dst_data, dst_data + ne0, cmp_argsort<GGML_SORT_ORDER_DESC>{src_data});
8522                break;
8523
8524            default:
8525                GGML_ABORT("invalid sort order");
8526        }
8527    }
8528}
8529
8530void ggml_compute_forward_argsort(
8531    const ggml_compute_params * params,
8532    ggml_tensor * dst) {
8533
8534    const ggml_tensor * src0 = dst->src[0];
8535
8536    switch (src0->type) {
8537        case GGML_TYPE_F32:
8538            {
8539                ggml_compute_forward_argsort_f32(params, dst);
8540            } break;
8541        default:
8542            {
8543                GGML_ABORT("fatal error");
8544            }
8545    }
8546}
8547
8548// ggml_compute_forward_top_k
8549
8550struct cmp_top_k {
8551    const float * data;
8552    bool operator()(int32_t a, int32_t b) const {
8553        return data[a] > data[b];
8554    }
8555};
8556
8557static void ggml_compute_forward_top_k_f32(
8558    const ggml_compute_params * params,
8559    ggml_tensor * dst) {
8560
8561    const ggml_tensor * src0 = dst->src[0];
8562
8563    GGML_TENSOR_UNARY_OP_LOCALS
8564
8565    GGML_ASSERT(nb0 == sizeof(float));
8566
8567    const int ith = params->ith;
8568    const int nth = params->nth;
8569
8570    const int64_t nr = ggml_nrows(src0);
8571
8572    const int top_k = ne0;
8573
8574    int32_t * tmp = (int32_t *) params->wdata + (ne00 + CACHE_LINE_SIZE_F32) * ith;
8575
8576    for (int64_t i = ith; i < nr; i += nth) {
8577        const float * src_data = (float *)((char *) src0->data + i*nb01);
8578
8579        for (int64_t j = 0; j < ne00; j++) {
8580            tmp[j] = j;
8581        }
8582
8583        std::partial_sort(tmp, tmp + top_k, tmp + ne00, cmp_top_k{src_data});
8584
8585        int32_t * dst_data = (int32_t *)((char *) dst->data + i*nb1);
8586
8587        std::copy(tmp, tmp + top_k, dst_data);
8588
8589        // emphasize that the order is not important
8590        if (top_k > 1) {
8591            std::swap(dst_data[0], dst_data[1]);
8592        }
8593    }
8594}
8595
8596void ggml_compute_forward_top_k(
8597    const ggml_compute_params * params,
8598    ggml_tensor * dst) {
8599
8600    const ggml_tensor * src0 = dst->src[0];
8601
8602    switch (src0->type) {
8603        case GGML_TYPE_F32:
8604            {
8605                ggml_compute_forward_top_k_f32(params, dst);
8606            } break;
8607        default:
8608            {
8609                GGML_ABORT("fatal error");
8610            }
8611    }
8612}
8613
8614static void ggml_compute_forward_flash_attn_ext_f16_one_chunk(
8615        const ggml_compute_params * params,
8616        ggml_tensor * dst,
8617        int ir0, int ir1,
8618        int64_t ic_start, int64_t ic_end,
8619        float * partials, int64_t partial_stride) {
8620
8621    const bool write_partials = (partials != nullptr);
8622    const ggml_tensor * q     = dst->src[0];
8623    const ggml_tensor * k     = dst->src[1];
8624    const ggml_tensor * v     = dst->src[2];
8625    const ggml_tensor * mask  = dst->src[3];
8626    const ggml_tensor * sinks = dst->src[4];
8627
8628    GGML_TENSOR_LOCALS(int64_t, neq, q,   ne)
8629    GGML_TENSOR_LOCALS(size_t,  nbq, q,   nb)
8630    GGML_TENSOR_LOCALS(int64_t, nek, k,   ne)
8631    GGML_TENSOR_LOCALS(size_t,  nbk, k,   nb)
8632    GGML_TENSOR_LOCALS(int64_t, nev, v,   ne)
8633    GGML_TENSOR_LOCALS(size_t,  nbv, v,   nb)
8634    GGML_TENSOR_LOCALS(int64_t, ne,  dst, ne)
8635    GGML_TENSOR_LOCALS(size_t,  nb,  dst, nb)
8636
8637    const int64_t DK = nek0;
8638    const int64_t DV = nev0;
8639    const int64_t N  = neq1;
8640
8641    GGML_ASSERT(ne0 == DV);
8642    GGML_ASSERT(ne2 == N);
8643
8644    // input tensor rows must be contiguous
8645    GGML_ASSERT(nbq0 == ggml_type_size(q->type));
8646    GGML_ASSERT(nbk0 == ggml_type_size(k->type));
8647    GGML_ASSERT(nbv0 == ggml_type_size(v->type));
8648
8649    GGML_ASSERT(neq0 == DK);
8650    GGML_ASSERT(nek0 == DK);
8651    GGML_ASSERT(nev0 == DV);
8652
8653    GGML_ASSERT(neq1 == N);
8654
8655    // dst cannot be transposed or permuted
8656    GGML_ASSERT(nb0 == sizeof(float));
8657    GGML_ASSERT(nb0 <= nb1);
8658    GGML_ASSERT(nb1 <= nb2);
8659    GGML_ASSERT(nb2 <= nb3);
8660
8661    // broadcast factors
8662    const int64_t rk2 = neq2/nek2;
8663    const int64_t rk3 = neq3/nek3;
8664
8665    const int64_t rv2 = neq2/nev2;
8666    const int64_t rv3 = neq3/nev3;
8667
8668    // parallelize by q rows using ggml_vec_dot_f32
8669
8670    float scale         = 1.0f;
8671    float max_bias      = 0.0f;
8672    float logit_softcap = 0.0f;
8673
8674    memcpy(&scale,         (float *) dst->op_params + 0, sizeof(float));
8675    memcpy(&max_bias,      (float *) dst->op_params + 1, sizeof(float));
8676    memcpy(&logit_softcap, (float *) dst->op_params + 2, sizeof(float));
8677
8678    if (logit_softcap != 0) {
8679        scale /= logit_softcap;
8680    }
8681
8682    const uint32_t n_head      = neq2;
8683    const uint32_t n_head_log2 = 1u << (uint32_t) floor(log2(n_head));
8684
8685    const float m0 = powf(2.0f, -(max_bias       ) / n_head_log2);
8686    const float m1 = powf(2.0f, -(max_bias / 2.0f) / n_head_log2);
8687
8688    ggml_type         const k_vec_dot_type = ggml_get_type_traits_cpu(k->type)->vec_dot_type;
8689    ggml_from_float_t const q_to_vec_dot   = ggml_get_type_traits_cpu(k_vec_dot_type)->from_float;
8690    ggml_vec_dot_t    const kq_vec_dot     = ggml_get_type_traits_cpu(k->type)->vec_dot;
8691    ggml_to_float_t   const v_to_float     = ggml_get_type_traits(v->type)->to_float;
8692
8693    GGML_ASSERT((                            q_to_vec_dot) && "fattn: unsupported K-type");
8694    GGML_ASSERT((v->type == GGML_TYPE_F32 || v_to_float  ) && "fattn: unsupported V-type");
8695
8696    int ith = params->ith;
8697
8698    for (int ir = ir0; ir < ir1; ++ir) {
8699        // q indices
8700        const int iq3 = ir/(neq2*neq1);
8701        const int iq2 = (ir - iq3*neq2*neq1)/neq1;
8702        const int iq1 = (ir - iq3*neq2*neq1 - iq2*neq1);
8703
8704        const uint32_t h = iq2; // head index
8705        const float slope = (max_bias > 0.0f) ? h < n_head_log2 ? powf(m0, h + 1) : powf(m1, 2*(h - n_head_log2) + 1) : 1.0f;
8706
8707        float S = 0.0f;      // sum
8708        float M = -INFINITY; // maximum KQ value
8709
8710        float       * VKQ32 = (float       *) params->wdata + ith*(1*DK + 2*DV + CACHE_LINE_SIZE_F32); // FP32 VKQ accumulator
8711        float       * V32   =                 (VKQ32 + 1*DV); // (temporary) FP32 V buffer
8712        ggml_fp16_t * VKQ16 = (ggml_fp16_t *) (VKQ32 + 1*DV); // (temporary) FP16 VKQ accumulator
8713        ggml_fp16_t * Q_q   = (ggml_fp16_t *) (VKQ32 + 2*DV); // (temporary) buffer for Q converted to quantized/FP16
8714
8715        if (v->type == GGML_TYPE_F16) {
8716            memset(VKQ16, 0, DV*sizeof(ggml_fp16_t));
8717        } else {
8718            memset(VKQ32, 0, DV*sizeof(float));
8719        }
8720
8721        const ggml_fp16_t * mp = mask ? (ggml_fp16_t *)((char *) mask->data + iq1*mask->nb[1] + (iq2%mask->ne[2])*mask->nb[2] + (iq3%mask->ne[3])*mask->nb[3]) : NULL;
8722
8723        // k indices
8724        const int ik3 = iq3 / rk3;
8725        const int ik2 = iq2 / rk2;
8726
8727        // v indices
8728        const int iv3 = iq3 / rv3;
8729        const int iv2 = iq2 / rv2;
8730
8731        const float * pq = (const float *) ((char *) q->data + (iq1*nbq1 + iq2*nbq2 + iq3*nbq3));
8732        q_to_vec_dot(pq, Q_q, DK);
8733
8734        // online softmax / attention
8735        // loop over n_kv and n_head_kv
8736        // ref: https://arxiv.org/pdf/2112.05682.pdf
8737
8738        for (int64_t ic = ic_start; ic < ic_end; ++ic) {
8739            const float mv = mp ? slope*GGML_CPU_FP16_TO_FP32(mp[ic]) : 0.0f;
8740            if (mv == -INFINITY) {
8741                continue;
8742            }
8743
8744            float s; // KQ value
8745
8746            const char * k_data = (const char *) k->data + ( ic*nbk1 + ik2*nbk2 + ik3*nbk3);
8747            kq_vec_dot(DK, &s, 0, k_data, 0, Q_q, 0, 1);
8748
8749            s = s*scale; // scale KQ value
8750
8751            if (logit_softcap != 0.0f) {
8752                s = logit_softcap*tanhf(s);
8753            }
8754
8755            s += mv; // apply mask
8756
8757            const float Mold = M;
8758
8759            float ms = 1.0f; // upon new higher max val, scale VKQ and KQ sum with this value
8760            float vs = 1.0f; // post-softmax KQ value, expf(s - M)
8761
8762            const char * v_data = ((const char *) v->data + (ic*nbv1 + iv2*nbv2 + iv3*nbv3));
8763
8764            if (v->type == GGML_TYPE_F16) {
8765                if (s > M) {
8766                    // s is new maximum, ms < 1.0f, vs == expf(s - s) == 1.0f
8767                    M = s;
8768                    ms = expf(Mold - M);
8769
8770                    // V = V*expf(Mold - M)
8771                    ggml_vec_scale_f16(DV, VKQ16, ms);
8772                } else {
8773                    // no new maximum, ms == 1.0f, vs != 1.0f
8774                    vs = expf(s - M);
8775                }
8776
8777                // V += v*expf(s - M)
8778                ggml_vec_mad_f16(DV, VKQ16, (const ggml_fp16_t *) v_data, vs);
8779            } else {
8780                if (s > M) {
8781                    // s is new maximum, ms < 1.0f, vs == expf(s - s) == 1.0f
8782                    M = s;
8783                    ms = expf(Mold - M);
8784
8785                    // V = V*expf(Mold - M)
8786                    ggml_vec_scale_f32(DV, VKQ32, ms);
8787                } else {
8788                    // no new maximum, ms == 1.0f, vs != 1.0f
8789                    vs = expf(s - M);
8790                }
8791
8792                // V += v*expf(s - M)
8793                if (v_to_float) {
8794                    v_to_float(v_data, V32, DV);
8795                    ggml_vec_mad_f32(DV, VKQ32, V32, vs);
8796                } else {
8797                    // V is F32
8798                    ggml_vec_mad_f32(DV, VKQ32, (const float *) v_data, vs);
8799                }
8800            }
8801
8802            S = S*ms + vs; // scale and increment sum with partial sum
8803        }
8804
8805        if (v->type == GGML_TYPE_F16) {
8806            for (int64_t d = 0; d < DV; ++d) {
8807                VKQ32[d] = GGML_CPU_FP16_TO_FP32(VKQ16[d]);
8808            }
8809        }
8810
8811        // sinks - apply only on the first kv-chunk
8812        if (sinks && ic_start == 0) {
8813            const float s = ((float *)((char *) sinks->data))[h];
8814
8815            float ms = 1.0f;
8816            float vs = 1.0f;
8817
8818            if (s > M) {
8819                ms = expf(M - s);
8820                M = s;
8821                ggml_vec_scale_f32(DV, VKQ32, ms);
8822            } else {
8823                vs = expf(s - M);
8824            }
8825
8826            S = S*ms + vs;
8827        }
8828
8829        if (write_partials) {
8830            // Write M, S, VKQ to partials for later reduction
8831            // partials layout: [M, S, VKQ[DV]] per query head
8832            float * partial = partials + ir * partial_stride;
8833            partial[0] = M;
8834            partial[1] = S;
8835            memcpy(partial + 2, VKQ32, DV * sizeof(float));
8836        } else {
8837            // V /= S
8838            const float S_inv = S == 0.0f ? 0.0f : 1.0f/S;
8839            ggml_vec_scale_f32(DV, VKQ32, S_inv);
8840
8841            // dst indices
8842            const int i1 = iq1;
8843            const int i2 = iq2;
8844            const int i3 = iq3;
8845
8846            // permute(0, 2, 1, 3)
8847            memcpy((char *) dst->data + (i3*ne2*ne1 + i2 + i1*ne1)*nb1, VKQ32, nb1);
8848        }
8849    }
8850}
8851
8852static void ggml_compute_forward_flash_attn_ext_tiled(
8853        const ggml_compute_params * params,
8854        ggml_tensor * dst,
8855        int ir0, int ir1) {
8856    const ggml_tensor * q     = dst->src[0];
8857    const ggml_tensor * k     = dst->src[1];
8858    const ggml_tensor * v     = dst->src[2];
8859    const ggml_tensor * mask  = dst->src[3];
8860    const ggml_tensor * sinks = dst->src[4];
8861
8862    GGML_TENSOR_LOCALS(int64_t, neq, q,   ne)
8863    GGML_TENSOR_LOCALS(size_t,  nbq, q,   nb)
8864    GGML_TENSOR_LOCALS(int64_t, nek, k,   ne)
8865    GGML_TENSOR_LOCALS(size_t,  nbk, k,   nb)
8866    GGML_TENSOR_LOCALS(int64_t, nev, v,   ne)
8867    GGML_TENSOR_LOCALS(size_t,  nbv, v,   nb)
8868    GGML_TENSOR_LOCALS(int64_t, ne,  dst, ne)
8869    GGML_TENSOR_LOCALS(size_t,  nb,  dst, nb)
8870
8871    const int64_t DK = nek0;
8872    const int64_t DV = nev0;
8873    const int64_t N  = neq1;
8874
8875    GGML_ASSERT(ne0 == DV);
8876    GGML_ASSERT(ne2 == N);
8877
8878    // input tensor rows must be contiguous
8879    GGML_ASSERT(nbq0 == ggml_type_size(q->type));
8880    GGML_ASSERT(nbk0 == ggml_type_size(k->type));
8881    GGML_ASSERT(nbv0 == ggml_type_size(v->type));
8882
8883    GGML_ASSERT(neq0 == DK);
8884    GGML_ASSERT(nek0 == DK);
8885    GGML_ASSERT(nev0 == DV);
8886
8887    GGML_ASSERT(neq1 == N);
8888
8889    // dst cannot be transposed or permuted
8890    GGML_ASSERT(nb0 == sizeof(float));
8891    GGML_ASSERT(nb0 <= nb1);
8892    GGML_ASSERT(nb1 <= nb2);
8893    GGML_ASSERT(nb2 <= nb3);
8894
8895    GGML_ASSERT(k->type == v->type);
8896    const ggml_type kv_type = k->type;
8897
8898
8899    // broadcast factors
8900    const int64_t rk2 = neq2/nek2;
8901    const int64_t rk3 = neq3/nek3;
8902
8903    const int64_t rv2 = neq2/nev2;
8904    const int64_t rv3 = neq3/nev3;
8905
8906    float scale         = 1.0f;
8907    float max_bias      = 0.0f;
8908    float logit_softcap = 0.0f;
8909
8910    memcpy(&scale,         (float *) dst->op_params + 0, sizeof(float));
8911    memcpy(&max_bias,      (float *) dst->op_params + 1, sizeof(float));
8912    memcpy(&logit_softcap, (float *) dst->op_params + 2, sizeof(float));
8913
8914    if (logit_softcap != 0) {
8915        scale /= logit_softcap;
8916    }
8917
8918    const uint32_t n_head      = neq2;
8919    const uint32_t n_head_log2 = 1u << (uint32_t) floor(log2(n_head));
8920
8921    const float m0 = powf(2.0f, -(max_bias       ) / n_head_log2);
8922    const float m1 = powf(2.0f, -(max_bias / 2.0f) / n_head_log2);
8923
8924    int ith = params->ith;
8925
8926    static constexpr int Q_TILE_SZ  = ggml_fa_tile_config::Q;
8927    static constexpr int KV_TILE_SZ = ggml_fa_tile_config::KV;
8928
8929    int ir = ir0;
8930    while (ir < ir1) {
8931        // q indices for the start of this tile
8932        const int iq3 = ir/(neq2*neq1);
8933        const int iq2 = (ir - iq3*neq2*neq1)/neq1;
8934        const int iq1 = (ir - iq3*neq2*neq1 - iq2*neq1);
8935
8936        // Number of valid rows in this tile:
8937        // - limited by tile size (Q_TILE_SZ)
8938        // - limited by chunk boundary (ir1 - ir)
8939        // - limited by head boundary (neq1 - iq1) to avoid crossing into next head
8940        const int tile_rows = MIN(Q_TILE_SZ, MIN((int)(ir1 - ir), (int)(neq1 - iq1)));
8941        GGML_ASSERT(tile_rows > 0);
8942
8943        const uint32_t h = iq2; // head index
8944        const float slope = (max_bias > 0.0f) ? h < n_head_log2 ? powf(m0, h + 1) : powf(m1, 2*(h - n_head_log2) + 1) : 1.0f;
8945
8946        float S[Q_TILE_SZ];
8947        float M[Q_TILE_SZ];
8948
8949        for (int i = 0 ; i < Q_TILE_SZ; ++i) {
8950            S[i] = 0.;
8951            M[i] = -INFINITY;
8952        }
8953
8954        // Per-thread scratch layout:
8955        // Q_q:    Q_TILE_SZ * DK (converted Q tile — F32 for GEMM, KV type for scalar)
8956        // KQ:     Q_TILE_SZ * KV_TILE_SZ (attention scores in float)
8957        // mask:   Q_TILE_SZ * KV_TILE_SZ (mask in float)
8958        // VKQ32:  Q_TILE_SZ * DV (FP32 output accumulator)
8959        // V32:    KV_TILE_SZ * DV (F32 buffer for V tile)
8960        // K_f32:  KV_TILE_SZ * DK (F32 buffer for K tile — GEMM path)
8961        float * base  = (float *) params->wdata + ith*(Q_TILE_SZ*DK + 2*Q_TILE_SZ*KV_TILE_SZ + Q_TILE_SZ*DV + KV_TILE_SZ*DV + KV_TILE_SZ*DK + CACHE_LINE_SIZE_F32);
8962
8963        void  * Q_q    = base;
8964        float * KQ     = (float *)((char *)base + Q_TILE_SZ * DK * sizeof(float));
8965        float * mask32 = KQ + Q_TILE_SZ * KV_TILE_SZ;
8966        float * VKQ32  = mask32 + Q_TILE_SZ * KV_TILE_SZ;
8967        float * V32    = VKQ32 + Q_TILE_SZ * DV;
8968        float * K_f32  = V32 + KV_TILE_SZ * DV;
8969
8970        memset(VKQ32, 0, Q_TILE_SZ * DV * sizeof(float));
8971        memset(mask32, 0, Q_TILE_SZ * KV_TILE_SZ * sizeof(float));
8972
8973        // k indices
8974        const int ik3 = iq3 / rk3;
8975        const int ik2 = iq2 / rk2;
8976
8977        // v indices
8978        const int iv3 = iq3 / rv3;
8979        const int iv2 = iq2 / rv2;
8980
8981        {
8982            float * Q_f32 = (float *)Q_q;
8983            for (int tq = 0; tq < tile_rows; tq++) {
8984                const float * pq = (const float *) ((char *) q->data + ((iq1 + tq)*nbq1 + iq2*nbq2 + iq3*nbq3));
8985                memcpy(Q_f32 + tq * DK, pq, DK * sizeof(float));
8986            }
8987            for (int tq = tile_rows; tq < Q_TILE_SZ; tq++) {
8988                memset(Q_f32 + tq * DK, 0, DK * sizeof(float));
8989            }
8990        }
8991
8992        memset(K_f32, 0, DK * KV_TILE_SZ * sizeof(float));
8993        memset(V32,   0, KV_TILE_SZ * DV * sizeof(float));
8994
8995        for (int64_t ic = 0; ic < nek1; ic += KV_TILE_SZ) {
8996            const int kv_tile = (int)std::min((int64_t)KV_TILE_SZ, nek1 - ic);
8997
8998            // skip the tile entirely if all the masks are -inf
8999            if (mask) {
9000                bool can_skip = true;
9001                for (int tq = 0; tq < tile_rows; tq++) {
9002                    const ggml_fp16_t * mp_row = (const ggml_fp16_t *)((const char *) mask->data + (iq1 + tq)*mask->nb[1] + (iq2%mask->ne[2])*mask->nb[2] + (iq3%mask->ne[3])*mask->nb[3]);
9003                    for (int tk = 0; tk < kv_tile; tk++) {
9004                        mask32[tq * KV_TILE_SZ + tk] = slope * GGML_CPU_FP16_TO_FP32(mp_row[ic + tk]);
9005                        if (mask32[tq * KV_TILE_SZ + tk] != -INFINITY) {
9006                            can_skip = false;
9007                        }
9008                    }
9009                    // Pad remaining mask entries with -inf
9010                    for (int tk = kv_tile; tk < KV_TILE_SZ; tk++) {
9011                        mask32[tq * KV_TILE_SZ + tk] = -INFINITY;
9012                    }
9013                }
9014
9015                if (can_skip) {
9016                    continue;
9017                }
9018            }
9019
9020            // Pack K tile transposed: K_f32[dk][kv] so KV_TILE is contiguous (SIMD dim)
9021            // Zero-pad the last tile so the GEMM always operates on KV_TILE_SZ columns
9022            for (int tk = 0; tk < kv_tile; tk++) {
9023                const char * k_data = (const char *)k->data + (ic + tk)*nbk1 + ik2*nbk2 + ik3*nbk3;
9024                if (kv_type == GGML_TYPE_F16) {
9025                    const ggml_fp16_t * k_f16 = (const ggml_fp16_t *)k_data;
9026                    for (int64_t dk = 0; dk < DK; dk++) {
9027                        K_f32[dk * KV_TILE_SZ + tk] = GGML_CPU_FP16_TO_FP32(k_f16[dk]);
9028                    }
9029                } else {
9030                    const float * k_f32_src = (const float *)k_data;
9031                    for (int64_t dk = 0; dk < DK; dk++) {
9032                        K_f32[dk * KV_TILE_SZ + tk] = k_f32_src[dk];
9033                    }
9034                }
9035            }
9036            memset(KQ, 0, Q_TILE_SZ * KV_TILE_SZ * sizeof(float));
9037            simd_gemm(KQ, (const float *)Q_q, K_f32, Q_TILE_SZ, DK, KV_TILE_SZ);
9038            ggml_vec_scale_f32(Q_TILE_SZ * KV_TILE_SZ, KQ, scale);
9039
9040            // Set padded KQ entries to -inf so softmax gives them zero weight
9041            if (kv_tile < KV_TILE_SZ) {
9042                for (int tq = 0; tq < Q_TILE_SZ; tq++) {
9043                    for (int tk = kv_tile; tk < KV_TILE_SZ; tk++) {
9044                        KQ[tq * KV_TILE_SZ + tk] = -INFINITY;
9045                    }
9046                }
9047            }
9048
9049            if (logit_softcap != 0.0f) {
9050                ggml_vec_tanh_f32(Q_TILE_SZ * KV_TILE_SZ, KQ, KQ);
9051                ggml_vec_scale_f32(Q_TILE_SZ * KV_TILE_SZ, KQ, logit_softcap);
9052            }
9053
9054            if (mask) {
9055                ggml_vec_add_f32(tile_rows * KV_TILE_SZ, KQ, KQ, mask32);
9056            }
9057
9058            bool skip[Q_TILE_SZ] = {};
9059
9060            for (int tq = 0; tq < Q_TILE_SZ; tq++) {
9061                float * kq_row = KQ + tq * KV_TILE_SZ;
9062
9063                float tile_max;
9064                ggml_vec_max_f32(KV_TILE_SZ, &tile_max, kq_row);
9065
9066                if (tile_max == -INFINITY) {
9067                    skip[tq] = true;
9068                    continue;
9069                }
9070
9071                const float Mold = M[tq];
9072                const float Mnew = fmaxf(Mold, tile_max);
9073
9074                if (Mnew > Mold) {
9075                    const float ms = expf(Mold - Mnew);
9076                    ggml_vec_scale_f32(DV, VKQ32 + tq * DV, ms);
9077                    S[tq] *= ms;
9078                }
9079                M[tq] = Mnew;
9080
9081
9082                S[tq] += ggml_vec_soft_max_f32(KV_TILE_SZ, kq_row, kq_row, Mnew);
9083            }
9084
9085            // V accumulation: VKQ32 += softmax(KQ) * V
9086            // Pack V tile to contiguous F32, zero-padded
9087            for (int tk = 0; tk < kv_tile; tk++) {
9088                const char * v_data = (const char *)v->data + (ic + tk)*nbv1 + iv2*nbv2 + iv3*nbv3;
9089                if (kv_type == GGML_TYPE_F16) {
9090                    ggml_cpu_fp16_to_fp32((const ggml_fp16_t *)v_data, V32 + tk * DV, DV);
9091                } else {
9092                    memcpy(V32 + tk * DV, v_data, DV * sizeof(float));
9093                }
9094            }
9095            for (int tq = 0; tq < Q_TILE_SZ; tq++) {
9096                if (skip[tq]) {
9097                    memset(KQ + tq * KV_TILE_SZ, 0, KV_TILE_SZ * sizeof(float));
9098                }
9099            }
9100            simd_gemm(VKQ32, KQ, V32, Q_TILE_SZ, KV_TILE_SZ, DV);
9101        }
9102
9103        // sinks (apply only to valid rows in the tile)
9104        if (sinks) {
9105            const float s = ((float *)((char *) sinks->data))[h];
9106
9107            for (int tq = 0; tq < tile_rows; tq++) {
9108                float ms = 1.0f;
9109                float vs = 1.0f;
9110
9111                if (s > M[tq]) {
9112                    ms = expf(M[tq] - s);
9113                    ggml_vec_scale_f32(DV, VKQ32 + tq * DV, ms);
9114                } else {
9115                    vs = expf(s - M[tq]);
9116                }
9117
9118                S[tq] = S[tq] * ms + vs;
9119            }
9120        }
9121
9122        for (int tq = 0; tq < tile_rows; tq++) {
9123            // V /= S
9124            const float S_inv = S[tq] == 0.0f ? 0.0f : 1.0f / S[tq];
9125            ggml_vec_scale_f32(DV, VKQ32 + tq * DV, S_inv);
9126
9127            // dst indices
9128            const int i1 = iq1 + tq;
9129            const int i2 = iq2;
9130            const int i3 = iq3;
9131
9132            // permute(0, 2, 1, 3)
9133            memcpy((char *) dst->data + (i3*ne2*ne1 + i2 + i1*ne1)*nb1, VKQ32 + tq * DV, nb1);
9134        }
9135
9136        ir += tile_rows;
9137    }
9138}
9139
9140// Reduction function: combines partial results across KV chunks
9141// Partials layout in wdata: [n_q_heads][n_chunks][2 + DV]
9142static void ggml_flash_attn_ext_reduce_partials(
9143        const ggml_compute_params * params,
9144        ggml_tensor * dst,
9145        const int64_t n_chunks,
9146        const int64_t chunk_size) {
9147
9148    const ggml_tensor * q = dst->src[0];
9149    const ggml_tensor * k = dst->src[1];
9150    const ggml_tensor * v = dst->src[2];
9151
9152    const int64_t DK        = k->ne[0];
9153    const int64_t DV        = v->ne[0];
9154    const int64_t nek1      = k->ne[1];
9155    const int64_t n_q_heads = q->ne[2];
9156
9157    const int ith = params->ith;
9158    const int nth = params->nth;
9159
9160    const int64_t wdata_per_thread = DK + 2*DV + CACHE_LINE_SIZE_F32;
9161    float *       thread_wdata     = (float *) params->wdata + ith * wdata_per_thread;
9162
9163    const int64_t partials_offset  = nth * (DK + 2*DV + CACHE_LINE_SIZE_F32);
9164    const int64_t partial_size     = 2 + DV;
9165    const float * partials_base    = (const float *) params->wdata + partials_offset;
9166
9167    // Output layout
9168    const int64_t ne1 = dst->ne[1];
9169    const int64_t ne2 = dst->ne[2];
9170    const size_t  nb1 = dst->nb[1];
9171
9172    // Each thread reduces a subset of query heads
9173    for (int64_t q_head = ith; q_head < n_q_heads; q_head += nth) {
9174        float   M_final   = -INFINITY;
9175        float   S_final   = 0.0f;
9176        float * VKQ_final = thread_wdata;
9177        memset(VKQ_final, 0, DV * sizeof(float));
9178
9179        // Combine partials from all chunks
9180        for (int64_t chunk_idx = 0; chunk_idx < n_chunks; ++chunk_idx) {
9181            const int64_t ic_start = chunk_idx * chunk_size;
9182            if (ic_start >= nek1) continue;
9183
9184            const float * partial   = partials_base + (q_head * n_chunks + chunk_idx) * partial_size;
9185            const float   M_chunk   = partial[0];
9186            const float   S_chunk   = partial[1];
9187            const float * VKQ_chunk = partial + 2;
9188
9189            if (S_chunk == 0.0f) continue;
9190
9191            const float M_new     = fmaxf(M_final, M_chunk);
9192            const float scale_old = expf(M_final - M_new);
9193            const float scale_new = expf(M_chunk - M_new);
9194
9195            for (int64_t d = 0; d < DV; ++d) {
9196                VKQ_final[d] = VKQ_final[d] * scale_old + VKQ_chunk[d] * scale_new;
9197            }
9198            S_final = S_final * scale_old + S_chunk * scale_new;
9199            M_final = M_new;
9200        }
9201
9202        // Normalize and write to output
9203        if (S_final != 0.0f) {
9204            const float S_inv = 1.0f / S_final;
9205            ggml_vec_scale_f32(DV, VKQ_final, S_inv);
9206        }
9207        // iq1=0, iq3=0 for decode
9208        memcpy((char *) dst->data + (0*ne2*ne1 + q_head + 0*ne1)*nb1, VKQ_final, nb1);
9209    }
9210}
9211
9212static void ggml_compute_forward_flash_attn_ext_f16(
9213        const ggml_compute_params * params,
9214        ggml_tensor * dst) {
9215
9216    const ggml_tensor * q     = dst->src[0];
9217    const ggml_tensor * k     = dst->src[1];
9218    const ggml_tensor * v     = dst->src[2];
9219
9220    GGML_TENSOR_LOCALS(int64_t, neq, q,   ne)
9221    GGML_TENSOR_LOCALS(size_t,  nbq, q,   nb)
9222    GGML_TENSOR_LOCALS(int64_t, nek, k,   ne)
9223    GGML_TENSOR_LOCALS(size_t,  nbk, k,   nb)
9224    GGML_TENSOR_LOCALS(int64_t, nev, v,   ne)
9225    GGML_TENSOR_LOCALS(size_t,  nbv, v,   nb)
9226    GGML_TENSOR_LOCALS(int64_t, ne,  dst, ne)
9227    GGML_TENSOR_LOCALS(size_t,  nb,  dst, nb)
9228
9229    const int64_t DK = nek0;
9230    const int64_t DV = nev0;
9231    const int64_t N  = neq1;
9232
9233
9234    GGML_ASSERT(ne0 == DV);
9235    GGML_ASSERT(ne2 == N);
9236
9237    // input tensor rows must be contiguous
9238    GGML_ASSERT(nbq0 == ggml_type_size(q->type));
9239    GGML_ASSERT(nbk0 == ggml_type_size(k->type));
9240    GGML_ASSERT(nbv0 == ggml_type_size(v->type));
9241
9242    GGML_ASSERT(neq0 == DK);
9243    GGML_ASSERT(nek0 == DK);
9244    GGML_ASSERT(nev0 == DV);
9245
9246    GGML_ASSERT(neq1 == N);
9247
9248    // dst cannot be transposed or permuted
9249    GGML_ASSERT(nb0 == sizeof(float));
9250    GGML_ASSERT(nb0 <= nb1);
9251    GGML_ASSERT(nb1 <= nb2);
9252    GGML_ASSERT(nb2 <= nb3);
9253
9254    const int ith = params->ith;
9255    const int nth = params->nth;
9256
9257    // When use_ref is set, force the vec-only reference implementation (no tiling, no KV-chunking)
9258    const bool use_ref = params->use_ref;
9259
9260    const bool kv_is_f32_or_f16 = (k->type == GGML_TYPE_F32 || k->type == GGML_TYPE_F16);
9261    const bool use_split_kv_path = !use_ref && (neq1 == 1 && neq3 == 1) && kv_is_f32_or_f16 && (k->type == v->type) && q->type == GGML_TYPE_F32 && nek1 >= 512;
9262
9263    if (use_split_kv_path) {
9264        const int64_t chunk_size = (nek1 + nth - 1) / nth;
9265
9266        // Partials buffer layout: [q_head][kv_chunk][M, S, VKQ]
9267        const int64_t partial_size  = 2 + DV;
9268        float *       partials_base = (float *) params->wdata + nth * (DK + 2*DV + CACHE_LINE_SIZE_F32);
9269
9270        const int64_t ic_start = ith * chunk_size;
9271        const int64_t ic_end   = std::min(ic_start + chunk_size, nek1);
9272
9273        const int64_t partial_stride = nth * partial_size;
9274        float *       chunk_partials = partials_base + ith * partial_size;
9275
9276        if (ic_start < nek1) {
9277            for (int64_t q_head = 0; q_head < neq2; q_head++) {
9278                ggml_compute_forward_flash_attn_ext_f16_one_chunk(
9279                    params, dst, q_head, q_head + 1, ic_start, ic_end,
9280                    chunk_partials, partial_stride);
9281            }
9282        } else {
9283            for (int64_t q_head = 0; q_head < neq2; q_head++) {
9284                float * q_partials = chunk_partials + q_head * partial_stride;
9285                q_partials[0] = -INFINITY;  // M
9286                q_partials[1] = 0.0f;       // S
9287            }
9288        }
9289
9290        ggml_barrier(params->threadpool);
9291        ggml_flash_attn_ext_reduce_partials(params, dst, nth, chunk_size);
9292    } else {
9293
9294        // total rows in q
9295        const int64_t nr = neq1*neq2*neq3;
9296
9297        // disable for NUMA
9298        const bool disable_chunking = ggml_is_numa();
9299
9300        // 4x chunks per thread
9301        int nth_scaled = nth * 4;
9302        int64_t chunk_size = (nr + nth_scaled - 1) / nth_scaled;
9303        int64_t nchunk     = (nr + chunk_size - 1) / chunk_size;
9304
9305        if (nth == 1 || nchunk < nth || disable_chunking) {
9306            nchunk = nth;
9307        }
9308
9309        if (ith == 0) {
9310            ggml_threadpool_chunk_set(params->threadpool, nth);
9311        }
9312
9313        ggml_barrier(params->threadpool);
9314
9315        const int64_t dr = (nr + nchunk - 1) / nchunk;
9316
9317        static constexpr int64_t Q_TILE_SZ  = ggml_fa_tile_config::Q;
9318        bool use_tiled = !use_ref &&
9319                               (q->type == GGML_TYPE_F32 &&
9320                                kv_is_f32_or_f16 &&
9321                                k->type == v->type &&
9322                                neq1 >= Q_TILE_SZ);
9323#ifdef GGML_SIMD
9324#if defined(__ARM_FEATURE_SVE)
9325        const int64_t f32_epr = svcntw();
9326#else
9327        const int64_t f32_epr = GGML_F32_EPR;
9328#endif
9329        use_tiled &= (DV % f32_epr == 0);
9330#endif
9331        int current_chunk = ith;
9332
9333        while (current_chunk < nchunk) {
9334            const int64_t ir0 = dr * current_chunk;
9335            const int64_t ir1 = MIN(ir0 + dr, nr);
9336
9337            if (use_tiled) {
9338                ggml_compute_forward_flash_attn_ext_tiled(params, dst, ir0, ir1);
9339            } else {
9340                ggml_compute_forward_flash_attn_ext_f16_one_chunk(params, dst, ir0, ir1, 0, nek1, nullptr, 0);
9341            }
9342
9343            current_chunk = ggml_threadpool_chunk_add(params->threadpool, 1);
9344        }
9345    }
9346}
9347
9348void ggml_compute_forward_flash_attn_ext(
9349        const ggml_compute_params * params,
9350        ggml_tensor * dst) {
9351    switch (dst->op_params[3]) {
9352        case GGML_PREC_DEFAULT:
9353        case GGML_PREC_F32:
9354            {
9355                // uses F32 accumulators
9356                ggml_compute_forward_flash_attn_ext_f16(params, dst);
9357            } break;
9358        default:
9359            {
9360                GGML_ABORT("fatal error");
9361            }
9362    }
9363}
9364
9365// ggml_compute_forward_flash_attn_back
9366
9367static void ggml_compute_forward_flash_attn_back_f32(
9368        const ggml_compute_params * params,
9369        const bool masked,
9370              ggml_tensor * dst) {
9371
9372    const ggml_tensor * q = dst->src[0];
9373    const ggml_tensor * k = dst->src[1];
9374    const ggml_tensor * v = dst->src[2];
9375    const ggml_tensor * d = dst->src[3];
9376
9377    GGML_TENSOR_LOCALS(int64_t, neq, q,   ne)
9378    GGML_TENSOR_LOCALS(size_t,  nbq, q,   nb)
9379    GGML_TENSOR_LOCALS(int64_t, nek, k,   ne)
9380    GGML_TENSOR_LOCALS(size_t,  nbk, k,   nb)
9381    GGML_TENSOR_LOCALS(int64_t, nev, v,   ne)
9382    GGML_TENSOR_LOCALS(size_t,  nbv, v,   nb)
9383    GGML_TENSOR_LOCALS(int64_t, ned, d,   ne)
9384    GGML_TENSOR_LOCALS(size_t,  nbd, d,   nb)
9385    GGML_TENSOR_LOCALS(int64_t, ne,  dst, ne)
9386    GGML_TENSOR_LOCALS(size_t,  nb,  dst, nb)
9387
9388    const int ith = params->ith;
9389    const int nth = params->nth;
9390
9391    const int64_t D = neq0;
9392    const int64_t N = neq1;
9393    const int64_t P = nek1 - N;
9394    const int64_t M = P + N;
9395
9396    const int Mup  = ggml_up(M, GGML_SOFT_MAX_UNROLL);
9397    const int mxDM = MAX(D, Mup);
9398
9399    // GGML_ASSERT(ne0 == D);
9400    // GGML_ASSERT(ne1 == N);
9401    GGML_ASSERT(P >= 0);
9402
9403    GGML_ASSERT(nbq0 == sizeof(float));
9404    GGML_ASSERT(nbk0 == sizeof(float));
9405    GGML_ASSERT(nbv0 == sizeof(float));
9406
9407    GGML_ASSERT(neq0 == D);
9408    GGML_ASSERT(nek0 == D);
9409    GGML_ASSERT(nev1 == D);
9410    GGML_ASSERT(ned0 == D);
9411
9412    GGML_ASSERT(neq1 == N);
9413    GGML_ASSERT(nek1 == N + P);
9414    GGML_ASSERT(nev1 == D);
9415    GGML_ASSERT(ned1 == N);
9416
9417    // dst cannot be transposed or permuted
9418    GGML_ASSERT(nb0 == sizeof(float));
9419    GGML_ASSERT(nb0 <= nb1);
9420    GGML_ASSERT(nb1 <= nb2);
9421    GGML_ASSERT(nb2 <= nb3);
9422
9423    if (ith == 0) {
9424        memset(dst->data, 0, nb0*ne0*ne1*ne2*ne3);
9425    }
9426    ggml_barrier(params->threadpool);
9427
9428    const int64_t elem_q = ggml_nelements(q);
9429    const int64_t elem_k = ggml_nelements(k);
9430
9431    ggml_type result_type = dst->type;
9432    GGML_ASSERT(ggml_blck_size(result_type) == 1);
9433    const size_t tsize = ggml_type_size(result_type);
9434
9435    const size_t offs_q = 0;
9436    const size_t offs_k = offs_q + GGML_PAD(elem_q * tsize, GGML_MEM_ALIGN);
9437    const size_t offs_v = offs_k + GGML_PAD(elem_k * tsize, GGML_MEM_ALIGN);
9438
9439    void * grad_q = (char *) dst->data;
9440    void * grad_k = (char *) dst->data + offs_k;
9441    void * grad_v = (char *) dst->data + offs_v;
9442
9443    const size_t nbgq1 = nb0*neq0;
9444    const size_t nbgq2 = nb0*neq0*neq1;
9445    const size_t nbgq3 = nb0*neq0*neq1*neq2;
9446
9447    const size_t nbgk1 = nb0*nek0;
9448    const size_t nbgk2 = nb0*nek0*nek1;
9449    const size_t nbgk3 = nb0*nek0*nek1*neq2;
9450
9451    const size_t nbgv1 = nb0*nev0;
9452    const size_t nbgv2 = nb0*nev0*nev1;
9453    const size_t nbgv3 = nb0*nev0*nev1*neq2;
9454
9455    // parallelize by k rows using ggml_vec_dot_f32
9456
9457    // total rows in k
9458    const int nr = nek2*nek3;
9459
9460    // rows per thread
9461    const int dr = (nr + nth - 1)/nth;
9462
9463    // row range for this thread
9464    const int ir0 = dr*ith;
9465    const int ir1 = MIN(ir0 + dr, nr);
9466
9467    const float scale = 1.0f/sqrtf(D);
9468
9469    //printf("P=%d N=%d D=%d ir0=%d ir1=%d scale = %f\n", P, N, D, ir0, ir1, scale);
9470
9471    // how often k2 (and v2) is repeated in q2
9472    int nrep = neq2/nek2;
9473
9474    for (int ir = ir0; ir < ir1; ++ir) {
9475        // q indices
9476        const int ik3 = ir/(nek2);
9477        const int ik2 = ir - ik3*nek2;
9478
9479        const int iq3 = ik3;
9480        const int id3 = ik3;
9481        const int iv3 = ik3;
9482        const int iv2 = ik2;
9483
9484        for (int irep = 0; irep < nrep; ++irep) {
9485            const int iq2 = ik2 + irep*nek2;
9486            const int id2 = iq2;
9487
9488            // (ik2 + irep*nek2) % nek2 == ik2
9489            for (int iq1 = 0; iq1 < neq1; ++iq1) {
9490                const int id1 = iq1;
9491
9492                // not sure about CACHE_LINE_SIZE_F32..
9493                // - maybe it must not be multiplied by 2 and excluded from .. in SM 1*(..) offset?
9494                float * S  = (float *) params->wdata + ith*2*(mxDM + CACHE_LINE_SIZE_F32) + 0*(mxDM+CACHE_LINE_SIZE_F32);
9495                float * SM = (float *) params->wdata + ith*2*(mxDM + CACHE_LINE_SIZE_F32) + 1*(mxDM+CACHE_LINE_SIZE_F32);
9496
9497                for (int i = M; i < Mup; ++i) {
9498                    S[i] = -INFINITY;
9499                }
9500
9501                const int64_t masked_begin = masked ? (P + iq1 + 1) : M;
9502                for (int64_t ic = 0; ic < masked_begin; ++ic) {
9503                    // k indices
9504                    const int ik1 = ic;
9505
9506                    // S indices
9507                    const int i1 = ik1;
9508
9509                    ggml_vec_dot_f32(neq0,
9510                            S + i1, 0,
9511                            (float *) ((char *) k->data + (ik1*nbk1 + ik2*nbk2 + ik3*nbk3)), 0,
9512                            (float *) ((char *) q->data + (iq1*nbq1 + iq2*nbq2 + iq3*nbq3)), 0, 1);
9513                }
9514
9515                // scale
9516                ggml_vec_scale_f32(masked_begin, S, scale);
9517
9518                for (int64_t i = masked_begin; i < M; i++) {
9519                    S[i] = -INFINITY;
9520                }
9521
9522                // softmax
9523                // exclude known -INF S[..] values from max and loop
9524                // dont forget to set their SM values to zero
9525                {
9526                    float max = -INFINITY;
9527                    ggml_vec_max_f32(masked_begin, &max, S);
9528
9529                    ggml_float sum = 0.0;
9530                    {
9531#ifdef GGML_SOFT_MAX_ACCELERATE
9532                        max = -max;
9533                        vDSP_vsadd(SM, 1, &max, SM, 1, Mup);
9534                        vvexpf(SM, SM, &Mup);
9535                        ggml_vec_sum_f32(Mup, &sum, SM);
9536#else
9537                        sum = ggml_vec_soft_max_f32(Mup, SM, S, max);
9538#endif
9539                    }
9540
9541                    assert(sum > 0.0);
9542
9543                    sum = 1.0/sum;
9544                    ggml_vec_scale_f32(masked_begin, SM, sum);
9545
9546                }
9547
9548                // step-by-step explanation
9549                {
9550                    // forward-process                    shape      grads from backward process
9551                    // parallel_for ik2,ik3:
9552                    //  for irep:
9553                    //   iq2 = ik2 + irep*nek2
9554                    //   k[:D,:M,:,:]                     [D,M,:,:]  grad[k][:D,:M,ik2,ik3]  += grad[kcur]
9555                    //   q[:D,:N,:,:]                     [D,N,:,:]  grad[q][:D,iq1,iq2,iq3] += grad[qcur]
9556                    //   v[:M,:D,:,:]                     [M,D,:,:]  grad[v][:M,:D,iv2,iv3]  += grad[vcur]
9557                    //   for iq1:
9558                    //    kcur   = k[:D,:M,ik2,ik3]       [D,M,1,1]  grad[kcur] = grad[S1].T @ qcur
9559                    //    qcur   = q[:D,iq1,iq2,iq3]      [D,1,1,1]  grad[qcur] = grad[S1]   @ kcur
9560                    //    vcur   = v[:M,:D,iv2,iv3]       [M,D,1,1]  grad[vcur] = grad[S5].T @ S4
9561                    //    S0     = -Inf                   [D,1,1,1]
9562                    //   ~S1[i]  = dot(kcur[:D,i], qcur)
9563                    //    S1     = qcur @ kcur.T          [M,1,1,1]  grad[S1]   = grad[S2] * scale
9564                    //    S2     = S1 * scale             [M,1,1,1]  grad[S2]   = diag_mask_zero(grad[S3], P)
9565                    //    S3     = diag_mask_inf(S2, P)   [M,1,1,1]  grad[S3]   = S4 * (grad[S4] - dot(S4, grad[S4]))
9566                    //    S4     = softmax(S3)            [M,1,1,1]  grad[S4]   = grad[S5] @ vcur
9567                    //   ~S5[i]  = dot(vcur[:,i], S4)
9568                    //    S5     = S4 @ vcur.T            [D,1,1,1]  grad[S5]   = d[:D,id1,id2,id3]
9569                    //   ~dst[i,iq1,iq2,iq3]  = S5[i]              ^
9570                    //    dst[:D,iq1,iq2,iq3] = S5                 | grad[dst[:D,iq1,iq2,iq3]] = d[:D,id1,id2,id3]
9571                    // dst                               backward-/ grad[dst]                 = d
9572                    //
9573                    // output gradients with their dependencies:
9574                    //
9575                    // grad[kcur] = grad[S1].T @ qcur
9576                    // grad[S1]   = diag_mask_zero(grad[S3], P) * scale
9577                    // grad[S3]   = S4 * (grad[S4] - dot(S4, grad[S4]))
9578                    // grad[S4]   = grad[S5] @ vcur
9579                    // grad[S4]   = d[:D,id1,id2,id3] @ vcur
9580                    // grad[qcur] = grad[S1]   @ kcur
9581                    // grad[vcur] = grad[S5].T @ S4
9582                    // grad[vcur] = d[:D,id1,id2,id3].T @ S4
9583                    //
9584                    // in post-order:
9585                    //
9586                    // S1         = qcur @ kcur.T
9587                    // S2         = S1 * scale
9588                    // S3         = diag_mask_inf(S2, P)
9589                    // S4         = softmax(S3)
9590                    // grad[S4]   = d[:D,id1,id2,id3] @ vcur
9591                    // grad[S3]   = S4 * (grad[S4] - dot(S4, grad[S4]))
9592                    // grad[S1]   = diag_mask_zero(grad[S3], P) * scale
9593                    // grad[qcur] = grad[S1]   @ kcur
9594                    // grad[kcur] = grad[S1].T @ qcur
9595                    // grad[vcur] = d[:D,id1,id2,id3].T @ S4
9596                    //
9597                    // using less variables (SM=S4):
9598                    //
9599                    // S             = diag_mask_inf(qcur @ kcur.T * scale, P)
9600                    // SM            = softmax(S)
9601                    // S             = d[:D,iq1,iq2,iq3] @ vcur
9602                    // dot_SM_gradSM = dot(SM, S)
9603                    // S             = SM * (S - dot(SM, S))
9604                    // S             = diag_mask_zero(S, P) * scale
9605                    //
9606                    // grad[q][:D,iq1,iq2,iq3] += S   @ kcur
9607                    // grad[k][:D,:M,ik2,ik3]  += S.T @ qcur
9608                    // grad[v][:M,:D,iv2,iv3]  += d[:D,id1,id2,id3].T @ SM
9609                }
9610
9611                // S = gradSM = d[:D,id1,id2,id3] @ vcur[:,:,iv2,iv3]
9612                // S = d[:D,id1,id2,id3] @ vcur[:,:,iv2,iv3]
9613                // for ic:
9614                //   S[:M] += vcur[:M,ic,iv2,iv3] * d[ic,id1,id2,id3]
9615                // exclude known future zero S[..] values from operation
9616                ggml_vec_set_f32(masked_begin, S, 0);
9617                for (int64_t ic = 0; ic < D; ++ic) {
9618                    ggml_vec_mad_f32(masked_begin,
9619                            S,
9620                             (float *) ((char *) v->data + (          ic*nbv1  + iv2*nbv2 + iv3*nbv3)),
9621                            *(float *) ((char *) d->data + (ic*nbd0 + id1*nbd1 + id2*nbd2 + id3*nbd3)));
9622                }
9623
9624                // S = SM * (S - dot(SM, S))
9625                float dot_SM_gradSM = 0;
9626                ggml_vec_dot_f32 (masked_begin, &dot_SM_gradSM, 0, SM, 0, S, 0, 1);
9627                ggml_vec_acc1_f32(M, S, -dot_SM_gradSM);
9628                ggml_vec_mul_f32 (masked_begin, S, S, SM);
9629
9630                // S = diag_mask_zero(S, P) * scale
9631                // already done by above ggml_vec_set_f32
9632
9633                // exclude known zero S[..] values from operation
9634                ggml_vec_scale_f32(masked_begin, S, scale);
9635
9636                // S    shape [M,1]
9637                // SM   shape [M,1]
9638                // kcur shape [D,M]
9639                // qcur shape [D,1]
9640                // vcur shape [M,D]
9641
9642                // grad[q][:D,iq1,iq2,iq3] += S @ kcur
9643                // grad[q][:D,iq1,iq2,iq3] += shape[M,1] @ shape[D,M]
9644                // for ic:
9645                //  grad[q][:D,iq1,iq2,iq3] += S[ic] * kcur[:D,ic,ik2,ik3]
9646                // exclude known zero S[..] values from loop
9647                for (int64_t ic = 0; ic < masked_begin; ++ic) {
9648                    ggml_vec_mad_f32(D,
9649                            (float *) ((char *) grad_q  + (iq1*nbgq1 + iq2*nbgq2  + iq3*nbgq3)),
9650                            (float *) ((char *) k->data + (ic*nbk1   + ik2*nbk2   + ik3*nbk3)),
9651                            S[ic]);
9652                }
9653
9654                // grad[k][:D,:M,iq2,iq3] += S.T @ qcur
9655                // for ic:
9656                //  grad[k][:D,ic,iq2,iq3] += S.T[0,ic] * qcur[:D,0]
9657                //  grad[k][:D,ic,iq2,iq3] += S[ic]     * qcur[:D,0]
9658                // exclude known zero S[..] values from loop
9659                for (int64_t ic = 0; ic < masked_begin; ++ic) {
9660                    ggml_vec_mad_f32(D,
9661                            (float *) ((char *) grad_k  + (ic*nbgk1  + ik2*nbgk2  + ik3*nbgk3)),
9662                            (float *) ((char *) q->data + (iq1*nbq1  + iq2*nbq2   + iq3*nbq3)),
9663                            S[ic]);
9664                }
9665
9666                // grad[v][:M,:D,iv2,iv3] += d[:D,id1,id2,id3].T       @ SM
9667                // for ic:
9668                //  grad[v][:M,ic,iv2,iv3] += d[:D,id1,id2,id3].T[0,ic] * SM[:M]
9669                //  grad[v][:M,ic,iv2,iv3] += d[ic,id1,id2,id3]         * SM[:M]
9670                // exclude known zero SM[..] values from mad
9671                for (int64_t ic = 0; ic < D; ++ic) {
9672                    ggml_vec_mad_f32(masked_begin,
9673                            (float *) ((char *) grad_v   + (          ic*nbgv1 + iv2*nbgv2 + iv3*nbgv3)),
9674                            SM,
9675                            *(float *) ((char *) d->data + (ic*nbd0 + id1*nbd1 + id2*nbd2  + id3*nbd3)));
9676                }
9677            }
9678        }
9679    }
9680}
9681
9682void ggml_compute_forward_flash_attn_back(
9683        const ggml_compute_params * params,
9684        const bool masked,
9685        ggml_tensor * dst) {
9686
9687    const ggml_tensor * q = dst->src[0];
9688
9689    switch (q->type) {
9690        case GGML_TYPE_F32:
9691            {
9692                ggml_compute_forward_flash_attn_back_f32(params, masked, dst);
9693            } break;
9694        default:
9695            {
9696                GGML_ABORT("fatal error");
9697            }
9698    }
9699}
9700
9701// ggml_compute_forward_ssm_conv
9702
9703static void ggml_compute_forward_ssm_conv_f32(
9704        const ggml_compute_params * params,
9705        ggml_tensor * dst) {
9706    const ggml_tensor * src0 = dst->src[0]; // conv_x
9707    const ggml_tensor * src1 = dst->src[1]; // conv1d.weight
9708
9709    const int ith = params->ith;
9710    const int nth = params->nth;
9711
9712    const int nc  = src1->ne[0]; // d_conv
9713    const int ncs = src0->ne[0]; // d_conv - 1 + n_t
9714    const int nr  = src0->ne[1]; // d_inner
9715    const int n_t =  dst->ne[1]; // tokens per sequence
9716    const int n_s =  dst->ne[2]; // number of sequences in the batch
9717
9718    GGML_ASSERT( dst->ne[0] == nr);
9719    GGML_ASSERT(src0->nb[0] == sizeof(float));
9720    GGML_ASSERT(src1->nb[0] == sizeof(float));
9721    GGML_ASSERT(src0->nb[1] == src0->ne[0]*sizeof(float));
9722
9723    // rows per thread
9724    const int dr = (nr + nth - 1)/nth;
9725
9726    // row range for this thread
9727    const int ir0 = dr*ith;
9728    const int ir1 = MIN(ir0 + dr, nr);
9729    const int ir  = ir1 - ir0;
9730
9731    for (int i3 = 0; i3 < n_s; ++i3) {
9732        for (int i2 = 0; i2 < n_t; ++i2) {
9733            // {d_conv - 1 + n_t, d_inner, n_seqs}
9734            // sliding window
9735            const float * s = (const float *) ((const char *) src0->data + ir0*(src0->nb[1]) + i2*(src0->nb[0]) + i3*(src0->nb[2])); // {d_conv, d_inner, n_s}
9736            const float * c = (const float *) ((const char *) src1->data + ir0*(src1->nb[1])); // {d_conv, d_inner}
9737            float * x = (float *) ((char *) dst->data + ir0*(dst->nb[0]) + i2*(dst->nb[1]) + i3*(dst->nb[2])); // {d_inner, n_t, n_s}
9738
9739            // TODO: transpose the output for smaller strides for big batches?
9740            // d_inner
9741            for (int i1 = 0; i1 < ir; ++i1) {
9742                // rowwise dot product
9743                // NOTE: not using ggml_vec_dot_f32, because its sum is in double precision
9744                float sumf = 0.0f;
9745
9746                // d_conv
9747                for (int i0 = 0; i0 < nc; ++i0) {
9748                    sumf += s[i0 + i1*ncs] * c[i0 + i1*nc];
9749                }
9750                x[i1] = sumf;
9751            }
9752        }
9753    }
9754}
9755
9756void ggml_compute_forward_ssm_conv(
9757        const ggml_compute_params * params,
9758        ggml_tensor * dst) {
9759    switch (dst->src[0]->type) {
9760        case GGML_TYPE_F32:
9761            {
9762                ggml_compute_forward_ssm_conv_f32(params, dst);
9763            } break;
9764        default:
9765            {
9766                GGML_ABORT("fatal error");
9767            }
9768    }
9769}
9770
9771// ggml_compute_forward_ssm_scan
9772
9773static void ggml_compute_forward_ssm_scan_f32(
9774        const ggml_compute_params * params,
9775        ggml_tensor * dst) {
9776    const ggml_tensor * src0 = dst->src[0]; // s  {d_state, dim, n_head, n_seqs+}
9777    const ggml_tensor * src1 = dst->src[1]; // x  {dim, n_head, n_seq_tokens, n_seqs}
9778    const ggml_tensor * src2 = dst->src[2]; // dt {n_head, n_seq_tokens, n_seqs}
9779    const ggml_tensor * src3 = dst->src[3]; // A  {d_state, n_head} or {1, n_head}
9780    const ggml_tensor * src4 = dst->src[4]; // B  {d_state, n_group, n_seq_tokens, n_seqs}
9781    const ggml_tensor * src5 = dst->src[5]; // C  {d_state, n_group, n_seq_tokens, n_seqs}
9782    const ggml_tensor * src6 = dst->src[6]; // ids {n_seqs}
9783
9784    const int ith = params->ith;
9785    const int nth = params->nth;
9786
9787    const int64_t nc = src0->ne[0]; // d_state
9788    const int64_t nr = src0->ne[1]; // dim
9789    const int64_t nh = src1->ne[1]; // n_head
9790    const int64_t ng = src4->ne[1];
9791    const int64_t nt = src1->ne[2]; // number of tokens per sequence
9792    const int64_t ns = src1->ne[3]; // number of sequences in the batch
9793    const int64_t K  = ggml_get_op_params_i32(dst, 0);
9794
9795    // can't use ggml_nbytes because src1 is not necessarily contiguous
9796    const int64_t s_off = ggml_nelements(src1) * ggml_element_size(src1);
9797
9798    GGML_ASSERT(K >= 1);
9799    GGML_ASSERT(ggml_nelements(src1) + K*nc*nr*nh*ns == ggml_nelements(dst));
9800    GGML_ASSERT(src0->nb[0] == sizeof(float));
9801    GGML_ASSERT(src1->nb[0] == sizeof(float));
9802    GGML_ASSERT(src2->nb[0] == sizeof(float));
9803    GGML_ASSERT(src3->nb[0] == sizeof(float));
9804    GGML_ASSERT(src4->nb[0] == sizeof(float));
9805    GGML_ASSERT(src5->nb[0] == sizeof(float));
9806    GGML_ASSERT(src6->nb[0] == sizeof(int32_t));
9807    GGML_ASSERT(nh % ng == 0);
9808    GGML_ASSERT(src3->ne[0] == 1 || K == 1);
9809
9810    // heads per thread
9811    const int dh = (nh + nth - 1)/nth;
9812
9813    // head range for this thread
9814    const int ih0 = dh*ith;
9815    const int ih1 = MIN(ih0 + dh, nh);
9816
9817    const int32_t * ids = (const int32_t *) src6->data;
9818
9819    for (int i3 = 0; i3 < ns; ++i3) {
9820        const float * s0 = (const float *) ((const char *) src0->data + ids[i3]*(src0->nb[3])); // {d_state, dim, nh, ns}
9821              float * s  = (      float *) ((      char *) dst->data  + i3*(src0->nb[3]) + s_off); // {d_state, dim, nh, ns}
9822
9823        for (int i2 = 0; i2 < nt; ++i2) {
9824            const float * x  = (const float *) ((const char *) src1->data + i2*(src1->nb[2]) + i3*(src1->nb[3])); // {dim, nh, nt, ns}
9825            const float * dt = (const float *) ((const char *) src2->data + i2*(src2->nb[1]) + i3*(src2->nb[2])); // {nh, nt, ns}
9826            const float * A  = (const float *) ((const char *) src3->data); // {d_state, nh} or {1, nh}
9827            const float * B  = (const float *) ((const char *) src4->data + i2*(src4->nb[2]) + i3*(src4->nb[3])); // {d_state, ng, nt, ns}
9828            const float * C  = (const float *) ((const char *) src5->data + i2*(src5->nb[2]) + i3*(src5->nb[3])); // {d_state, ng, nt, ns}
9829                  float * y  = (      float *) ((      char *) dst->data + i2*(nh*nr*sizeof(float)) + i3*(nt*nh*nr*sizeof(float))); // {dim, nh, nt, ns}
9830
9831            if (src3->ne[0] == 1) {
9832                // Mamba-2 has a scalar decay factor per head; dA can be outside the state-wise loop
9833
9834                // n_head
9835                for (int h = ih0; h < ih1; ++h) {
9836                    // ref: https://github.com/state-spaces/mamba/blob/62db608da60f6fc790b8ed9f4b3225e95ca15fde/mamba_ssm/ops/triton/softplus.py#L16
9837                    const float dt_soft_plus = ggml_compute_softplus_f32(dt[h]);
9838                    const float dA = expf(dt_soft_plus * A[h]);
9839                    const int g = h / (nh / ng); // repeat_interleave
9840
9841                    // dim
9842                    for (int i1 = 0; i1 < nr; ++i1) {
9843                        const int ii = i1 + h*nr;
9844                        const float x_dt = x[ii] * dt_soft_plus;
9845                        float sumf = 0.0f;
9846#if defined(GGML_SIMD)
9847    #if defined(__ARM_FEATURE_SVE)
9848                        const int ggml_f32_epr = svcntw();
9849                        const int ggml_f32_step = 1 * ggml_f32_epr;
9850
9851                        const int np = (nc & ~(ggml_f32_step - 1));
9852
9853                        GGML_F32_VEC sum = GGML_F32_VEC_ZERO;
9854
9855                        GGML_F32_VEC adA = GGML_F32_VEC_SET1(dA);
9856                        GGML_F32_VEC axdt = GGML_F32_VEC_SET1(x_dt);
9857
9858                        for (int i = 0; i < np; i += ggml_f32_step) {
9859                            // TODO: maybe unroll more?
9860                            for (int j = 0; j < 1; j++) {
9861                                GGML_F32_VEC t0 = GGML_F32_VEC_LOAD(s0 + i + j*ggml_f32_epr + ii*nc);
9862                                GGML_F32_VEC t1 = GGML_F32_VEC_LOAD(B + i + j*ggml_f32_epr + g*nc);
9863                                GGML_F32_VEC t2 = GGML_F32_VEC_LOAD(C + i + j*ggml_f32_epr + g*nc);
9864
9865                                t0 = GGML_F32_VEC_MUL(t0, adA);
9866                                t1 = GGML_F32_VEC_MUL(t1, axdt);
9867
9868                                t0 = GGML_F32_VEC_ADD(t0, t1);
9869
9870                                sum = GGML_F32_VEC_FMA(sum, t0, t2);
9871
9872                                GGML_F32_VEC_STORE(s + i + j*ggml_f32_epr + ii*nc, t0);
9873                            }
9874                        }
9875
9876                        sumf = GGML_F32xt_REDUCE_ONE(sum);
9877    #elif defined(__riscv_v_intrinsic)
9878                        // todo: RVV implementation
9879                        const int np = 0;
9880    #else
9881                        const int np = (nc & ~(GGML_F32_STEP - 1));
9882
9883                        GGML_F32_VEC sum[GGML_F32_ARR] = { GGML_F32_VEC_ZERO };
9884
9885                        GGML_F32_VEC adA = GGML_F32_VEC_SET1(dA);
9886                        GGML_F32_VEC axdt = GGML_F32_VEC_SET1(x_dt);
9887
9888                        GGML_F32_VEC ax[GGML_F32_ARR];
9889                        GGML_F32_VEC ay[GGML_F32_ARR];
9890                        GGML_F32_VEC az[GGML_F32_ARR];
9891
9892                        for (int i = 0; i < np; i += GGML_F32_STEP) {
9893                            for (int j = 0; j < GGML_F32_ARR; j++) {
9894                                ax[j] = GGML_F32_VEC_LOAD(s0 + i + j*GGML_F32_EPR + ii*nc);
9895                                ay[j] = GGML_F32_VEC_LOAD(B + i + j*GGML_F32_EPR + g*nc);
9896                                az[j] = GGML_F32_VEC_LOAD(C + i + j*GGML_F32_EPR + g*nc);
9897
9898                                ax[j] = GGML_F32_VEC_MUL(ax[j], adA);
9899                                ay[j] = GGML_F32_VEC_MUL(ay[j], axdt);
9900
9901                                ax[j] = GGML_F32_VEC_ADD(ax[j], ay[j]);
9902
9903                                sum[j] = GGML_F32_VEC_FMA(sum[j], ax[j], az[j]);
9904
9905                                GGML_F32_VEC_STORE(s + i + j*GGML_F32_EPR + ii*nc, ax[j]);
9906                            }
9907                        }
9908
9909                        // reduce sum0..sum3 to sum0
9910                        GGML_F32_VEC_REDUCE(sumf, sum);
9911    #endif
9912#else
9913                        const int np = 0;
9914#endif
9915                        // d_state
9916                        for (int i0 = np; i0 < nc; ++i0) {
9917                            const int i = i0 + ii*nc;
9918                            const int ig = i0 + g*nc;
9919                            // state = prev_state * dA + dB * x
9920                            const float state = (s0[i] * dA) + (B[ig] * x_dt);
9921                            // y = rowwise_dotprod(state, C)
9922                            sumf += state * C[ig];
9923                            s[i] = state;
9924                        }
9925                        y[ii] = sumf;
9926                    }
9927                }
9928            } else {
9929                // Mamba-1 has an element-wise decay factor for the states
9930
9931                // n_head
9932                for (int h = ih0; h < ih1; ++h) {
9933                    // ref: https://github.com/state-spaces/mamba/blob/62db608da60f6fc790b8ed9f4b3225e95ca15fde/mamba_ssm/ops/triton/softplus.py#L16
9934                    const float dt_soft_plus = ggml_compute_softplus_f32(dt[h]);
9935                    const int g = h / (nh / ng); // repeat_interleave
9936
9937                    // dim
9938                    for (int i1 = 0; i1 < nr; ++i1) {
9939                        const int ii = i1 + h*nr;
9940                        const float x_dt = x[ii] * dt_soft_plus;
9941#if defined(__ARM_FEATURE_SVE)
9942                        svfloat32_t vx_dt = GGML_F32_VEC_SET1(x_dt);
9943                        svfloat32_t vdt_soft_plus = GGML_F32_VEC_SET1(dt_soft_plus);
9944                        svfloat32_t r1_vector = GGML_F32_VEC_ZERO;
9945
9946                        // d_state
9947                        // TODO: what happens when (d_state % svcntw()) != 0?
9948                        for (int64_t k = 0; k < nc; k += svcntw()) {
9949                            svfloat32_t vA = GGML_F32_VEC_LOAD(&A[h*nc + k]);
9950                            svfloat32_t vB = GGML_F32_VEC_LOAD(&B[k + g*nc]);
9951                            svfloat32_t vC = GGML_F32_VEC_LOAD(&C[k + g*nc]);
9952                            svfloat32_t vs0 = GGML_F32_VEC_LOAD(&s0[ii*nc + k]);
9953
9954                            svfloat32_t t1 = GGML_F32_VEC_MUL(vdt_soft_plus, vA);
9955                            t1 = exp_ps_sve(svptrue_b32(), t1);
9956                            svfloat32_t t2 = GGML_F32_VEC_MUL(vx_dt, vB);
9957
9958                            vs0 = GGML_F32_VEC_FMA(t2, vs0, t1);
9959                            r1_vector = GGML_F32_VEC_ADD(GGML_F32_VEC_MUL(vs0, vC), r1_vector);
9960
9961                            GGML_F32_VEC_STORE(&s[ii*nc + k], vs0);
9962                        }
9963                        y[ii] = GGML_F32xt_REDUCE_ONE(r1_vector);
9964#else
9965                        float sumf = 0.0f;
9966                        // NOTE: can't really use GGML_SIMD here because d_state is usually 16
9967                        //       and also because expf is used within the loop.
9968                        // d_state
9969                        for (int i0 = 0; i0 < nc; ++i0) {
9970                            const int i = i0 + ii*nc;
9971                            const int ig = i0 + g*nc;
9972                            // state = prev_state * dA + dB * x
9973                            const float state = (s0[i] * expf(dt_soft_plus * A[i0 + h*nc])) + (B[ig] * x_dt);
9974                            // y = rowwise_dotprod(state, C)
9975                            sumf += state * C[ig];
9976                            s[i] = state;
9977                        }
9978                        y[ii] = sumf;
9979#endif
9980                    }
9981                }
9982            }
9983            const int64_t slot = nt - 1 - i2;
9984            if (K > 1 && slot > 0 && slot < K) {
9985                float * s_snapshot = (float *) ((char *) dst->data + s_off + (slot*ns + i3)*(src0->nb[3]));
9986                for (int h = ih0; h < ih1; ++h) {
9987                    memcpy((char *) s_snapshot + h*src0->nb[2], (char *) s + h*src0->nb[2], src0->nb[2]);
9988                }
9989            }
9990            // use the output as the source when it's not the first token-wise iteration
9991            s0 = s;
9992        }
9993    }
9994}
9995
9996void ggml_compute_forward_ssm_scan(
9997        const ggml_compute_params * params,
9998        ggml_tensor * dst) {
9999    switch (dst->src[0]->type) {
10000        case GGML_TYPE_F32:
10001            {
10002                ggml_compute_forward_ssm_scan_f32(params, dst);
10003            } break;
10004        default:
10005            {
10006                GGML_ABORT("fatal error");
10007            }
10008    }
10009}
10010
10011// ggml_compute_forward_win_part
10012
10013static void ggml_compute_forward_win_part_f32(
10014        const ggml_compute_params * params,
10015        ggml_tensor * dst) {
10016    GGML_UNUSED(params);
10017
10018    const ggml_tensor * src0 = dst->src[0];
10019
10020    GGML_TENSOR_LOCALS(int64_t, ne0, src0, ne)
10021    GGML_TENSOR_LOCALS(int64_t, ne,  dst,  ne)
10022
10023    const int32_t nep0 = ((const int32_t *)(dst->op_params))[0];
10024    const int32_t nep1 = ((const int32_t *)(dst->op_params))[1];
10025    const int32_t w    = ((const int32_t *)(dst->op_params))[2];
10026
10027    assert(ne00 == ne0);
10028    assert(ne3  == nep0*nep1);
10029
10030    // TODO: optimize / multi-thread
10031    for (int py = 0; py < nep1; ++py) {
10032        for (int px = 0; px < nep0; ++px) {
10033            const int64_t i3 = py*nep0 + px;
10034            for (int64_t i2 = 0; i2 < ne2; ++i2) {
10035                for (int64_t i1 = 0; i1 < ne1; ++i1) {
10036                    for (int64_t i0 = 0; i0 < ne0; ++i0) {
10037                        const int64_t i02 = py*w + i2;
10038                        const int64_t i01 = px*w + i1;
10039                        const int64_t i00 = i0;
10040
10041                        const int64_t i = i3*ne2*ne1*ne0 + i2*ne1*ne0    + i1*ne0   + i0;
10042                        const int64_t j =                  i02*ne01*ne00 + i01*ne00 + i00;
10043
10044                        if (py*w + i2 >= ne02 || px*w + i1 >= ne01) {
10045                            ((float *) dst->data)[i] = 0.0f;
10046                        } else {
10047                            ((float *) dst->data)[i] = ((float *) src0->data)[j];
10048                        }
10049                    }
10050                }
10051            }
10052        }
10053    }
10054}
10055
10056void ggml_compute_forward_win_part(
10057        const ggml_compute_params * params,
10058        ggml_tensor * dst) {
10059
10060    const ggml_tensor * src0 = dst->src[0];
10061
10062    switch (src0->type) {
10063        case GGML_TYPE_F32:
10064            {
10065                ggml_compute_forward_win_part_f32(params, dst);
10066            } break;
10067        default:
10068            {
10069                GGML_ABORT("fatal error");
10070            }
10071    }
10072}
10073
10074// ggml_compute_forward_win_unpart
10075
10076static void ggml_compute_forward_win_unpart_f32(
10077        const ggml_compute_params * params,
10078        ggml_tensor * dst) {
10079    GGML_UNUSED(params);
10080
10081    const ggml_tensor * src0 = dst->src[0];
10082
10083    GGML_TENSOR_LOCALS(int64_t, ne0, src0, ne)
10084    GGML_TENSOR_LOCALS(int64_t, ne,  dst,  ne)
10085
10086    const int32_t w = ((const int32_t *)(dst->op_params))[0];
10087
10088    // padding
10089    const int px = (w - ne1%w)%w;
10090    //const int py = (w - ne2%w)%w;
10091
10092    const int npx = (px + ne1)/w;
10093    //const int npy = (py + ne2)/w;
10094
10095    assert(ne0 == ne00);
10096
10097    // TODO: optimize / multi-thread
10098    for (int64_t i2 = 0; i2 < ne2; ++i2) {
10099        for (int64_t i1 = 0; i1 < ne1; ++i1) {
10100            for (int64_t i0 = 0; i0 < ne0; ++i0) {
10101                const int ip2 = i2/w;
10102                const int ip1 = i1/w;
10103
10104                const int64_t i02 = i2%w;
10105                const int64_t i01 = i1%w;
10106                const int64_t i00 = i0;
10107
10108                const int64_t i = (ip2*npx + ip1)*ne02*ne01*ne00 + i02*ne01*ne00 + i01*ne00 + i00;
10109                const int64_t j =                                  i2*ne1*ne0    + i1*ne0   + i0;
10110
10111                ((float *) dst->data)[j] = ((float *) src0->data)[i];
10112            }
10113        }
10114    }
10115}
10116
10117void ggml_compute_forward_win_unpart(
10118        const ggml_compute_params * params,
10119        ggml_tensor * dst) {
10120
10121    const ggml_tensor * src0 = dst->src[0];
10122
10123    switch (src0->type) {
10124        case GGML_TYPE_F32:
10125            {
10126                ggml_compute_forward_win_unpart_f32(params, dst);
10127            } break;
10128        default:
10129            {
10130                GGML_ABORT("fatal error");
10131            }
10132    }
10133}
10134
10135//ggml_compute_forward_unary
10136
10137void ggml_compute_forward_unary(
10138        const ggml_compute_params * params,
10139        ggml_tensor * dst) {
10140
10141    const ggml_unary_op op = ggml_get_unary_op(dst);
10142
10143    switch (op) {
10144        case GGML_UNARY_OP_ABS:
10145            {
10146                ggml_compute_forward_abs(params, dst);
10147            } break;
10148        case GGML_UNARY_OP_SGN:
10149            {
10150                ggml_compute_forward_sgn(params, dst);
10151            } break;
10152        case GGML_UNARY_OP_NEG:
10153            {
10154                ggml_compute_forward_neg(params, dst);
10155            } break;
10156        case GGML_UNARY_OP_STEP:
10157            {
10158                ggml_compute_forward_step(params, dst);
10159            } break;
10160        case GGML_UNARY_OP_TANH:
10161            {
10162                ggml_compute_forward_tanh(params, dst);
10163            } break;
10164        case GGML_UNARY_OP_ELU:
10165            {
10166                ggml_compute_forward_elu(params, dst);
10167            } break;
10168        case GGML_UNARY_OP_RELU:
10169            {
10170                ggml_compute_forward_relu(params, dst);
10171            } break;
10172        case GGML_UNARY_OP_SIGMOID:
10173            {
10174                ggml_compute_forward_sigmoid(params, dst);
10175            } break;
10176        case GGML_UNARY_OP_GELU:
10177            {
10178                ggml_compute_forward_gelu(params, dst);
10179            } break;
10180        case GGML_UNARY_OP_GELU_ERF:
10181            {
10182                ggml_compute_forward_gelu_erf(params, dst);
10183            } break;
10184        case GGML_UNARY_OP_GELU_QUICK:
10185            {
10186                ggml_compute_forward_gelu_quick(params, dst);
10187            } break;
10188        case GGML_UNARY_OP_SILU:
10189            {
10190                ggml_compute_forward_silu(params, dst);
10191            } break;
10192        case GGML_UNARY_OP_HARDSWISH:
10193            {
10194                ggml_compute_forward_hardswish(params, dst);
10195            } break;
10196        case GGML_UNARY_OP_HARDSIGMOID:
10197            {
10198                ggml_compute_forward_hardsigmoid(params, dst);
10199            } break;
10200        case GGML_UNARY_OP_EXP:
10201            {
10202                ggml_compute_forward_exp(params, dst);
10203            } break;
10204        case GGML_UNARY_OP_FLOOR:
10205            {
10206                ggml_compute_forward_floor(params, dst);
10207            } break;
10208        case GGML_UNARY_OP_CEIL:
10209            {
10210                ggml_compute_forward_ceil(params, dst);
10211            } break;
10212        case GGML_UNARY_OP_ROUND:
10213            {
10214                ggml_compute_forward_round(params, dst);
10215            } break;
10216        case GGML_UNARY_OP_TRUNC:
10217            {
10218                ggml_compute_forward_trunc(params, dst);
10219            } break;
10220        case GGML_UNARY_OP_XIELU:
10221            {
10222                ggml_compute_forward_xielu(params, dst);
10223            } break;
10224        case GGML_UNARY_OP_EXPM1:
10225            {
10226                ggml_compute_forward_expm1(params, dst);
10227            } break;
10228        case GGML_UNARY_OP_SOFTPLUS:
10229            {
10230                ggml_compute_forward_softplus(params, dst);
10231            } break;
10232        default:
10233            {
10234                GGML_ABORT("fatal error");
10235            }
10236    }
10237}
10238
10239//ggml_compute_forward_glu
10240
10241void ggml_compute_forward_glu(
10242        const ggml_compute_params * params,
10243        ggml_tensor * dst) {
10244
10245    const ggml_glu_op op = ggml_get_glu_op(dst);
10246
10247    switch (op) {
10248        case GGML_GLU_OP_REGLU:
10249            {
10250                ggml_compute_forward_reglu(params, dst);
10251            } break;
10252        case GGML_GLU_OP_GEGLU:
10253            {
10254                ggml_compute_forward_geglu(params, dst);
10255            } break;
10256        case GGML_GLU_OP_SWIGLU:
10257            {
10258                ggml_compute_forward_swiglu(params, dst);
10259            } break;
10260        case GGML_GLU_OP_SWIGLU_OAI:
10261            {
10262                ggml_compute_forward_swiglu_oai(params, dst);
10263            } break;
10264        case GGML_GLU_OP_GEGLU_ERF:
10265            {
10266                ggml_compute_forward_geglu_erf(params, dst);
10267            } break;
10268        case GGML_GLU_OP_GEGLU_QUICK:
10269            {
10270                ggml_compute_forward_geglu_quick(params, dst);
10271            } break;
10272        case GGML_GLU_OP_SWIGLU_CLAMP:
10273            {
10274                ggml_compute_forward_swiglu_clamp(params, dst);
10275            } break;
10276        default:
10277            {
10278                GGML_ABORT("fatal error");
10279            }
10280    }
10281}
10282
10283// ggml_compute_forward_get_rel_pos
10284
10285static void ggml_compute_forward_get_rel_pos_f16(
10286        const ggml_compute_params * params,
10287        ggml_tensor * dst) {
10288    GGML_UNUSED(params);
10289
10290    const ggml_tensor * src0 = dst->src[0];
10291
10292    // ref: https://github.com/facebookresearch/segment-anything/blob/main/segment_anything/modeling/image_encoder.py#L292-L322
10293
10294    GGML_TENSOR_UNARY_OP_LOCALS
10295
10296    const int64_t w = ne1;
10297
10298    ggml_fp16_t * src0_data = (ggml_fp16_t *) src0->data;
10299    ggml_fp16_t * dst_data  = (ggml_fp16_t *) dst->data;
10300
10301    for (int64_t i2 = 0; i2 < ne2; ++i2) {
10302        for (int64_t i1 = 0; i1 < ne1; ++i1) {
10303            const int64_t pos = (w - i1 - 1) + i2;
10304            for (int64_t i0 = 0; i0 < ne0; ++i0) {
10305                dst_data[i2*ne1*ne0 + i1*ne0 + i0] = src0_data[pos*ne00 + i0];
10306            }
10307        }
10308    }
10309}
10310
10311void ggml_compute_forward_get_rel_pos(
10312        const ggml_compute_params * params,
10313        ggml_tensor * dst) {
10314
10315    const ggml_tensor * src0 = dst->src[0];
10316
10317    switch (src0->type) {
10318        case GGML_TYPE_F16:
10319        case GGML_TYPE_BF16:
10320            {
10321                ggml_compute_forward_get_rel_pos_f16(params, dst);
10322            } break;
10323        default:
10324            {
10325                GGML_ABORT("fatal error");
10326            }
10327    }
10328}
10329
10330// ggml_compute_forward_add_rel_pos
10331
10332static void ggml_compute_forward_add_rel_pos_f32(
10333        const ggml_compute_params * params,
10334        ggml_tensor * dst) {
10335
10336    const ggml_tensor * src0 = dst->src[0];
10337    const ggml_tensor * src1 = dst->src[1];
10338    const ggml_tensor * src2 = dst->src[2];
10339
10340    const bool inplace = (bool) ((int32_t *) dst->op_params)[0];
10341    if (!inplace) {
10342        if (params->ith == 0) {
10343            memcpy((char *) dst->data, (char *) src0->data, ggml_nbytes(dst));
10344        }
10345        ggml_barrier(params->threadpool);
10346    }
10347    // ref: https://github.com/facebookresearch/segment-anything/blob/main/segment_anything/modeling/image_encoder.py#L357-L359
10348
10349    float * src1_data = (float *) src1->data;
10350    float * src2_data = (float *) src2->data;
10351    float * dst_data  = (float *) dst->data;
10352
10353    const int64_t ne10 = src1->ne[0];
10354    const int64_t ne11 = src1->ne[1];
10355    const int64_t ne12 = src1->ne[2];
10356    const int64_t ne13 = src1->ne[3];
10357
10358    const int ith = params->ith;
10359    const int nth = params->nth;
10360
10361    // total patches in dst
10362    const int np = ne13;
10363
10364    // patches per thread
10365    const int dp = (np + nth - 1)/nth;
10366
10367    // patch range for this thread
10368    const int ip0 = dp*ith;
10369    const int ip1 = MIN(ip0 + dp, np);
10370
10371    for (int64_t i13 = ip0; i13 < ip1; ++i13) {
10372        for (int64_t i12 = 0; i12 < ne12; ++i12) {
10373            for (int64_t i11 = 0; i11 < ne11; ++i11) {
10374                const int64_t jp1 = i13*ne12*ne11*ne10 + i12*ne11*ne10 + i11*ne10;
10375                for (int64_t i10 = 0; i10 < ne10; ++i10) {
10376                    const int64_t jp0  = jp1 + i10;
10377                    const float src1_e = src1_data[jp0];
10378                    const float src2_e = src2_data[jp0];
10379
10380                    const int64_t jdh = jp0 * ne10;
10381                    const int64_t jdw = jdh - (ne10 - 1) * i10;
10382
10383                    for (int64_t j = 0; j < ne10; ++j) {
10384                        dst_data[jdh + j     ] += src2_e;
10385                        dst_data[jdw + j*ne10] += src1_e;
10386                    }
10387                }
10388            }
10389        }
10390    }
10391}
10392
10393void ggml_compute_forward_add_rel_pos(
10394        const ggml_compute_params * params,
10395        ggml_tensor * dst) {
10396
10397    const ggml_tensor * src0 = dst->src[0];
10398
10399    switch (src0->type) {
10400        case GGML_TYPE_F32:
10401            {
10402                ggml_compute_forward_add_rel_pos_f32(params, dst);
10403            } break;
10404        default:
10405            {
10406                GGML_ABORT("fatal error");
10407            }
10408    }
10409}
10410
10411// ggml_compute_forward_rwkv_wkv6
10412
10413static void ggml_compute_forward_rwkv_wkv6_f32(
10414        const ggml_compute_params * params,
10415        ggml_tensor * dst) {
10416    const int64_t T = dst->src[1]->ne[2];
10417    const int64_t C = dst->ne[0];
10418    const int64_t HEADS = dst->src[1]->ne[1];
10419    const int64_t n_seqs = dst->src[5]->ne[1];
10420    const int64_t head_size = C / HEADS;
10421
10422    float * dst_data = (float *) dst->data;
10423    float * state = ((float *) dst->data) + C * T;
10424
10425    const int ith = params->ith;
10426    const int nth = params->nth;
10427
10428    const int h_start =  (HEADS * (ith    )) / nth;
10429    const int h_end   = ((HEADS * (ith + 1)) / nth < HEADS) ?
10430                         (HEADS * (ith + 1)) / nth : HEADS;
10431
10432    float * k =          (float *) dst->src[0]->data;
10433    float * v =          (float *) dst->src[1]->data;
10434    float * r =          (float *) dst->src[2]->data;
10435    float * time_faaaa = (float *) dst->src[3]->data;
10436    float * time_decay = (float *) dst->src[4]->data;
10437
10438    size_t t_stride = HEADS * head_size; // Same to C
10439
10440    size_t h_stride = C / HEADS;
10441    GGML_ASSERT(C % HEADS == 0); // C must be divisible by HEADS
10442    size_t h_stride_2d = head_size * head_size;
10443
10444    if (ith == 0) {
10445        memset(dst_data, 0, T * C * sizeof(float));
10446    }
10447    ggml_barrier(params->threadpool);
10448
10449
10450    #if defined(__AVX__) && !defined(__AVX512F__)
10451        #define GGML_F32X GGML_F32x8
10452        #define GGML_F32X_SET1 GGML_F32x8_SET1
10453        #define GGML_F32X_LOAD GGML_F32x8_LOAD
10454        #define GGML_F32X_STORE GGML_F32x8_STORE
10455        #define GGML_F32X_MUL GGML_F32x8_MUL
10456        #define GGML_F32X_FMA GGML_F32x8_FMA
10457        #define WKV_VECTOR_SIZE 8
10458    #elif defined(__AVX512F__)
10459        #define GGML_F32X GGML_F32x16
10460        #define GGML_F32X_SET1 GGML_F32x16_SET1
10461        #define GGML_F32X_LOAD GGML_F32x16_LOAD
10462        #define GGML_F32X_STORE GGML_F32x16_STORE
10463        #define GGML_F32X_MUL GGML_F32x16_MUL
10464        #define GGML_F32X_FMA GGML_F32x16_FMA
10465        #define WKV_VECTOR_SIZE 16
10466    #elif defined(__ARM_FEATURE_SVE) && defined(__aarch64__)
10467        #define GGML_F32X GGML_F32xt
10468        #define GGML_F32X_SET1 GGML_F32xt_SET1
10469        #define GGML_F32X_LOAD GGML_F32xt_LOAD
10470        #define GGML_F32X_STORE GGML_F32xt_STORE
10471        #define GGML_F32X_MUL GGML_F32xt_MUL
10472        #define GGML_F32X_FMA GGML_F32xt_FMA
10473        #define WKV_VECTOR_SIZE 8
10474    #elif defined(__ARM_NEON) && defined(__aarch64__)
10475        #define GGML_F32X GGML_F32x4
10476        #define GGML_F32X_SET1 GGML_F32x4_SET1
10477        #define GGML_F32X_LOAD GGML_F32x4_LOAD
10478        #define GGML_F32X_STORE GGML_F32x4_STORE
10479        #define GGML_F32X_MUL GGML_F32x4_MUL
10480        #define GGML_F32X_FMA GGML_F32x4_FMA
10481        #define WKV_VECTOR_SIZE 4
10482    #endif
10483
10484    #ifdef WKV_VECTOR_SIZE
10485        int wkv_vector_size;
10486        #if defined(__ARM_FEATURE_SVE)
10487            wkv_vector_size = svcntw();
10488        #else
10489            wkv_vector_size = WKV_VECTOR_SIZE;
10490        #endif
10491        const int64_t vec_count = head_size / wkv_vector_size;
10492
10493        for (int64_t t = 0; t < T; t++) {
10494            size_t t_offset = t * t_stride;
10495            size_t state_offset = head_size * C * (t / (T / n_seqs));
10496            float * state_cur = state + state_offset;
10497            float * state_prev = t % (T / n_seqs) ? state_cur : (float*)dst->src[5]->data + state_offset;
10498
10499            for (int64_t h = h_start; h < h_end; h++) {
10500                size_t h_offset = h * h_stride;
10501                size_t t_h_offset = t_offset + h_offset;
10502                size_t h_2d_offset = h * h_stride_2d;
10503
10504                for (int64_t i = 0; i < head_size; i++) {
10505                    size_t t_h_i_offset = t_h_offset + i;
10506                    size_t h_i_offset = h_offset + i;
10507                    size_t h_2d_i_offset = h_2d_offset + i * h_stride;
10508
10509                    float k_val = k[t_h_i_offset];
10510                    float r_val = r[t_h_i_offset];
10511                    float time_faaaa_val = time_faaaa[h_i_offset];
10512                    float time_decay_val = time_decay[t_h_i_offset];
10513
10514                    // Broadcast scalar values to vectors
10515                    GGML_F32X k_vec = GGML_F32X_SET1(k_val);
10516                    GGML_F32X r_vec = GGML_F32X_SET1(r_val);
10517                    GGML_F32X time_faaaa_vec = GGML_F32X_SET1(time_faaaa_val);
10518                    GGML_F32X time_decay_vec = GGML_F32X_SET1(time_decay_val);
10519
10520                    for (int64_t j = 0; j < vec_count; j++) {
10521                        size_t base_j = j * wkv_vector_size;
10522                        size_t t_h_j_offset = t_h_offset + base_j;
10523                        size_t h_2d_i_j_offset = h_2d_i_offset + base_j;
10524
10525                        // Load x elements at once
10526                        GGML_F32X v_vec = GGML_F32X_LOAD(&v[t_h_j_offset]);
10527                        GGML_F32X prev_state_vec = GGML_F32X_LOAD(&state_prev[h_2d_i_j_offset]);
10528                        GGML_F32X dst_vec = GGML_F32X_LOAD(&dst_data[t_h_j_offset]);
10529
10530                        // Compute kv = v * k
10531                        GGML_F32X kv_vec = GGML_F32X_MUL(v_vec, k_vec);
10532
10533                        // Compute temp = kv * time_faaaa + prev_state
10534                        GGML_F32X temp_vec = GGML_F32X_FMA(prev_state_vec, kv_vec, time_faaaa_vec);
10535
10536                        // Update dst: dst += temp * r
10537                        dst_vec = GGML_F32X_FMA(dst_vec, temp_vec, r_vec);
10538                        GGML_F32X_STORE(&dst_data[t_h_j_offset], dst_vec);
10539
10540                        // Update state: state = prev_state * time_decay + kv
10541                        GGML_F32X new_state_vec = GGML_F32X_FMA(kv_vec, prev_state_vec, time_decay_vec);
10542                        GGML_F32X_STORE(&state_cur[h_2d_i_j_offset], new_state_vec);
10543                    }
10544
10545                    // Handle remaining elements, this will not be used.
10546                    for (int64_t j = vec_count * wkv_vector_size; j < head_size; j++) {
10547                        size_t t_h_j_offset = t_h_offset + j;
10548                        size_t h_2d_i_j_offset = h_2d_i_offset + j;
10549                        float v_val = v[t_h_j_offset];
10550                        float kv_val = v_val * k_val;
10551                        float prev_state_val = state_prev[h_2d_i_j_offset];
10552                        float temp_val = kv_val * time_faaaa_val + prev_state_val;
10553                        dst_data[t_h_j_offset] += temp_val * r_val;
10554                        state_cur[h_2d_i_j_offset] = prev_state_val * time_decay_val + kv_val;
10555                    }
10556                }
10557            }
10558        }
10559
10560    #else
10561        // basically fused operations:
10562        // dst = r @ (time_faaaa * (k @ v) + state),
10563        // state = time_decay * state + (k @ v),
10564        // recursive through each token
10565        for (int64_t t = 0; t < T; t++) {
10566            size_t t_offset = t * t_stride;
10567            size_t state_offset = head_size * C * (t / (T / n_seqs));
10568            float * state_cur = state + state_offset;
10569            float * state_prev = t % (T / n_seqs) ? state_cur : (float*)dst->src[5]->data + state_offset;
10570
10571            for (int64_t h = h_start; h < h_end; h++) {
10572                size_t h_offset = h * h_stride;
10573                size_t t_h_offset = t_offset + h_offset;
10574                size_t h_2d_offset = h * h_stride_2d;
10575
10576                for (int64_t i = 0; i < head_size; i++) {
10577                    size_t t_h_i_offset = t_h_offset + i;
10578                    size_t h_i_offset = h_offset + i;
10579                    size_t h_2d_i_offset = h_2d_offset + i * h_stride;
10580
10581                    float k_val = k[t_h_i_offset];
10582                    float r_val = r[t_h_i_offset];
10583                    float time_faaaa_val = time_faaaa[h_i_offset];
10584                    // RWKV v6: different time_decay for each token.
10585                    float time_decay_val = time_decay[t_h_i_offset];
10586
10587                    for (int64_t j = 0; j < head_size; j++) {
10588                        size_t t_h_j_offset = t_h_offset + j;
10589                        size_t h_2d_i_j_offset = h_2d_i_offset + j;
10590
10591                        float v_val = v[t_h_j_offset];
10592                        float kv_val = v_val * k_val;
10593                        float prev_state_val = state_prev[h_2d_i_j_offset];
10594                        float temp_val = kv_val * time_faaaa_val + prev_state_val;
10595                        dst_data[t_h_j_offset] += temp_val * r_val;
10596                        state_cur[h_2d_i_j_offset] = prev_state_val * time_decay_val + kv_val;
10597                    }
10598                }
10599            }
10600        }
10601    #endif
10602}
10603
10604
10605void ggml_compute_forward_rwkv_wkv6(
10606        const ggml_compute_params * params,
10607        ggml_tensor * dst) {
10608
10609    const ggml_tensor * src0 = dst->src[0];
10610
10611    switch (src0->type) {
10612        case GGML_TYPE_F32:
10613            {
10614                ggml_compute_forward_rwkv_wkv6_f32(params, dst);
10615            } break;
10616        default:
10617            {
10618                GGML_ABORT("fatal error");
10619            }
10620    }
10621}
10622
10623// ggml_compute_forward_gla
10624
10625static void ggml_compute_forward_gla_f32(
10626        const ggml_compute_params * params,
10627        ggml_tensor * dst) {
10628    const int64_t T = dst->src[1]->ne[2];
10629    const int64_t C = dst->ne[0];
10630    const int64_t HEADS = dst->src[1]->ne[1];
10631    const int64_t n_seqs = dst->src[4]->ne[1];
10632    const int64_t head_size = C / HEADS;
10633    const float scale = ggml_get_op_params_f32(dst, 0);
10634
10635    float * dst_data = (float *) dst->data;
10636    float * state = ((float *) dst->data) + C * T;
10637
10638    const int ith = params->ith;
10639    const int nth = params->nth;
10640
10641    const int h_start =  (HEADS * (ith    )) / nth;
10642    const int h_end   = ((HEADS * (ith + 1)) / nth < HEADS) ?
10643                         (HEADS * (ith + 1)) / nth : HEADS;
10644
10645    float * k = (float *) dst->src[0]->data;
10646    float * v = (float *) dst->src[1]->data;
10647    float * q = (float *) dst->src[2]->data;
10648    float * g = (float *) dst->src[3]->data;
10649
10650    size_t t_stride = HEADS * head_size; // Same to C
10651
10652    size_t h_stride = C / HEADS;
10653    GGML_ASSERT(C % HEADS == 0); // C must be divisible by HEADS
10654    size_t h_stride_2d = head_size * head_size;
10655
10656    if (ith == 0) {
10657        memset(dst_data, 0, T * C * sizeof(float));
10658    }
10659    ggml_barrier(params->threadpool);
10660
10661
10662    #if defined(__AVX__) && !defined(__AVX512F__)
10663        #define GGML_F32X GGML_F32x8
10664        #define GGML_F32X_SET1 GGML_F32x8_SET1
10665        #define GGML_F32X_LOAD GGML_F32x8_LOAD
10666        #define GGML_F32X_STORE GGML_F32x8_STORE
10667        #define GGML_F32X_MUL GGML_F32x8_MUL
10668        #define GGML_F32X_FMA GGML_F32x8_FMA
10669        #define GLA_VECTOR_SIZE 8
10670    #elif defined(__AVX512F__)
10671        #define GGML_F32X GGML_F32x16
10672        #define GGML_F32X_SET1 GGML_F32x16_SET1
10673        #define GGML_F32X_LOAD GGML_F32x16_LOAD
10674        #define GGML_F32X_STORE GGML_F32x16_STORE
10675        #define GGML_F32X_MUL GGML_F32x16_MUL
10676        #define GGML_F32X_FMA GGML_F32x16_FMA
10677        #define GLA_VECTOR_SIZE 16
10678    #elif defined(__ARM_FEATURE_SVE) && defined(__aarch64__)
10679        #define GGML_F32X GGML_F32xt
10680        #define GGML_F32X_SET1 GGML_F32xt_SET1
10681        #define GGML_F32X_LOAD GGML_F32xt_LOAD
10682        #define GGML_F32X_STORE GGML_F32xt_STORE
10683        #define GGML_F32X_MUL GGML_F32xt_MUL
10684        #define GGML_F32X_FMA GGML_F32xt_FMA
10685        #define GLA_VECTOR_SIZE 8
10686    #elif defined(__ARM_NEON) && defined(__aarch64__)
10687        #define GGML_F32X GGML_F32x4
10688        #define GGML_F32X_SET1 GGML_F32x4_SET1
10689        #define GGML_F32X_LOAD GGML_F32x4_LOAD
10690        #define GGML_F32X_STORE GGML_F32x4_STORE
10691        #define GGML_F32X_MUL GGML_F32x4_MUL
10692        #define GGML_F32X_FMA GGML_F32x4_FMA
10693        #define GLA_VECTOR_SIZE 4
10694    #endif
10695
10696    #ifdef GLA_VECTOR_SIZE
10697        int gla_vector_size;
10698        #if defined(__ARM_FEATURE_SVE)
10699            gla_vector_size = svcntw();
10700        #else
10701            gla_vector_size = GLA_VECTOR_SIZE;
10702        #endif
10703        const int64_t vec_count = head_size / gla_vector_size;
10704
10705        for (int64_t t = 0; t < T; t++) {
10706            size_t t_offset = t * t_stride;
10707            size_t state_offset = head_size * C * (t / (T / n_seqs));
10708            float * state_cur = state + state_offset;
10709            float * state_prev = t % (T / n_seqs) ? state_cur : (float*)dst->src[4]->data + state_offset;
10710
10711            for (int64_t h = h_start; h < h_end; h++) {
10712                size_t h_offset = h * h_stride;
10713                size_t t_h_offset = t_offset + h_offset;
10714                size_t h_2d_offset = h * h_stride_2d;
10715
10716                for (int64_t i = 0; i < head_size; i++) {
10717                    size_t t_h_i_offset = t_h_offset + i;
10718                    size_t h_2d_i_offset = h_2d_offset + i * h_stride;
10719
10720                    float k_val = k[t_h_i_offset];
10721                    float q_val = q[t_h_i_offset] * scale;
10722                    float g_val = g[t_h_i_offset];
10723
10724                    // Broadcast scalar values to vectors
10725                    GGML_F32X k_vec = GGML_F32X_SET1(k_val);
10726                    GGML_F32X q_vec = GGML_F32X_SET1(q_val);
10727                    GGML_F32X g_vec = GGML_F32X_SET1(g_val);
10728
10729                    for (int64_t j = 0; j < vec_count; j++) {
10730                        size_t base_j = j * gla_vector_size;
10731                        size_t t_h_j_offset = t_h_offset + base_j;
10732                        size_t h_2d_i_j_offset = h_2d_i_offset + base_j;
10733
10734                        // Load x elements at once
10735                        GGML_F32X v_vec = GGML_F32X_LOAD(&v[t_h_j_offset]);
10736                        GGML_F32X prev_state_vec = GGML_F32X_LOAD(&state_prev[h_2d_i_j_offset]);
10737                        GGML_F32X dst_vec = GGML_F32X_LOAD(&dst_data[t_h_j_offset]);
10738
10739                        // Compute kv = v * k
10740                        GGML_F32X kv_vec = GGML_F32X_MUL(v_vec, k_vec);
10741
10742                        // Compute temp = prev_state * g + kv
10743                        GGML_F32X temp_vec = GGML_F32X_FMA(kv_vec, prev_state_vec, g_vec);
10744
10745                        // Update dst: dst += temp * q
10746                        dst_vec = GGML_F32X_FMA(dst_vec, temp_vec, q_vec);
10747                        GGML_F32X_STORE(&dst_data[t_h_j_offset], dst_vec);
10748
10749                        // Update state
10750                        GGML_F32X_STORE(&state_cur[h_2d_i_j_offset], temp_vec);
10751                    }
10752
10753                    // Handle remaining elements, this will not be used.
10754                    for (int64_t j = vec_count * gla_vector_size; j < head_size; j++) {
10755                        size_t t_h_j_offset = t_h_offset + j;
10756                        size_t h_2d_i_j_offset = h_2d_i_offset + j;
10757                        float v_val = v[t_h_j_offset];
10758                        float kv_val = v_val * k_val;
10759                        float prev_state_val = state_prev[h_2d_i_j_offset];
10760                        float temp_val = kv_val + prev_state_val * g_val;
10761                        dst_data[t_h_j_offset] += temp_val * q_val;
10762                        state_cur[h_2d_i_j_offset] = temp_val;
10763                    }
10764                }
10765            }
10766        }
10767
10768    #else
10769        for (int64_t t = 0; t < T; t++) {
10770            size_t t_offset = t * t_stride;
10771            size_t state_offset = head_size * C * (t / (T / n_seqs));
10772            float * state_cur = state + state_offset;
10773            float * state_prev = t % (T / n_seqs) ? state_cur : (float*)dst->src[4]->data + state_offset;
10774
10775            for (int64_t h = h_start; h < h_end; h++) {
10776                size_t h_offset = h * h_stride;
10777                size_t t_h_offset = t_offset + h_offset;
10778                size_t h_2d_offset = h * h_stride_2d;
10779
10780                for (int64_t i = 0; i < head_size; i++) {
10781                    size_t t_h_i_offset = t_h_offset + i;
10782                    size_t h_2d_i_offset = h_2d_offset + i * h_stride;
10783
10784                    float k_val = k[t_h_i_offset];
10785                    float q_val = q[t_h_i_offset] * scale;
10786                    float g_val = g[t_h_i_offset];
10787
10788                    for (int64_t j = 0; j < head_size; j++) {
10789                        size_t t_h_j_offset = t_h_offset + j;
10790                        size_t h_2d_i_j_offset = h_2d_i_offset + j;
10791
10792                        float v_val = v[t_h_j_offset];
10793                        float kv_val = v_val * k_val;
10794                        float prev_state_val = state_prev[h_2d_i_j_offset];
10795                        float temp_val = prev_state_val * g_val + kv_val;
10796                        dst_data[t_h_j_offset] += temp_val * q_val;
10797                        state_cur[h_2d_i_j_offset] = temp_val;
10798                    }
10799                }
10800            }
10801        }
10802    #endif
10803}
10804
10805
10806void ggml_compute_forward_gla(
10807        const ggml_compute_params * params,
10808        ggml_tensor * dst) {
10809
10810    const ggml_tensor * src0 = dst->src[0];
10811
10812    switch (src0->type) {
10813        case GGML_TYPE_F32:
10814            {
10815                ggml_compute_forward_gla_f32(params, dst);
10816            } break;
10817        default:
10818            {
10819                GGML_ABORT("fatal error");
10820            }
10821    }
10822}
10823
10824static void ggml_compute_forward_solve_tri_f32(const struct ggml_compute_params * params, struct ggml_tensor * dst) {
10825    const struct ggml_tensor * src0 = dst->src[0];  // A (lower triangular)
10826    const struct ggml_tensor * src1 = dst->src[1];  // B (RHS)
10827
10828    GGML_TENSOR_BINARY_OP_LOCALS;
10829
10830    GGML_ASSERT(src0->type == GGML_TYPE_F32);
10831    GGML_ASSERT(src1->type == GGML_TYPE_F32);
10832    GGML_ASSERT(dst->type  == GGML_TYPE_F32);
10833
10834    GGML_ASSERT(ne00 == ne01); // A must be square
10835    GGML_ASSERT(ne0  == ne10); // solution cols == B cols
10836    GGML_ASSERT(ne1  == ne11); // solution rows == B rows
10837
10838    GGML_ASSERT(ne02 == ne12 && ne12 == ne2);
10839    GGML_ASSERT(ne03 == ne13 && ne13 == ne3);
10840
10841    const int ith = params->ith;
10842    const int nth = params->nth;
10843
10844    const int64_t k = ne10;   // number of RHS columns
10845    const int64_t n = ne11;   // A is n×n
10846    const int64_t nr = ne02 * ne03 * k; // we're parallelizing on columns here, so seq x token x column will be the unit
10847
10848    // chunks per thread
10849    const int64_t dr = (nr + nth - 1)/nth;
10850
10851    // chunk range for this thread
10852    const int64_t ir0 = dr*ith;
10853    const int64_t ir1 = MIN(ir0 + dr, nr);
10854
10855    const float * A = (const float *) src0->data;  // [n, n, B1, B2]
10856    const float * B = (const float *) src1->data;  // [n, k, B1, B2]
10857          float * X = (      float *) dst->data;   // [n, k, B1, B2]
10858
10859    for (int64_t ir = ir0; ir < ir1; ++ir) {
10860        const int64_t i03 = ir/(ne02*k);
10861        const int64_t i02 = (ir - i03*ne02*k)/k;
10862        const int64_t i01 = (ir - i03*ne02*k - i02*k);
10863
10864        const float * A_batch = A + i02 * nb02 / sizeof(float) + i03 * nb03 / sizeof(float);
10865        const float * B_batch = B + i02 * nb12 / sizeof(float) + i03 * nb13 / sizeof(float);
10866
10867        float * X_batch = X + i02 * nb2 / sizeof(float) + i03 * nb3 / sizeof(float);
10868
10869        for (int64_t i00 = 0; i00 < n; ++i00) {
10870            float sum = 0.0f;
10871            for (int64_t t = 0; t < i00; ++t) {
10872                sum += A_batch[i00 * n + t] * X_batch[t * k + i01];
10873            }
10874
10875            const float diag = A_batch[i00 * n + i00];
10876            assert(diag != 0.0f && "Zero diagonal in triangular matrix");
10877
10878            X_batch[i00 * k + i01] = (B_batch[i00 * k + i01] - sum) / diag;
10879        }
10880    }
10881}
10882
10883void ggml_compute_forward_solve_tri(const struct ggml_compute_params * params, struct ggml_tensor * dst) {
10884    const ggml_tensor * src0 = dst->src[0];
10885    const ggml_tensor * src1 = dst->src[1];
10886
10887    if (src0->type == GGML_TYPE_F32 && src1->type == GGML_TYPE_F32) {
10888        ggml_compute_forward_solve_tri_f32(params, dst);
10889    } else {
10890        GGML_ABORT("fatal error");
10891    }
10892}
10893
10894// ggml_compute_forward_gated_delta_net
10895static void ggml_compute_forward_gated_delta_net_one_chunk(
10896    const ggml_compute_params * params,
10897    ggml_tensor * dst,
10898    int64_t ir0,
10899    int64_t ir1) {
10900
10901    ggml_tensor * src_q     = dst->src[0];
10902    ggml_tensor * src_k     = dst->src[1];
10903    ggml_tensor * src_v     = dst->src[2];
10904    ggml_tensor * src_g     = dst->src[3];
10905    ggml_tensor * src_beta  = dst->src[4];
10906    ggml_tensor * src_state = dst->src[5];
10907
10908    const int64_t S_v      = src_v->ne[0];
10909    const int64_t H        = src_v->ne[1];
10910    const int64_t n_tokens = src_v->ne[2];
10911    const int64_t n_seqs   = src_v->ne[3];
10912
10913    GGML_ASSERT(ggml_is_contiguous_rows(src_q));
10914    GGML_ASSERT(ggml_is_contiguous_rows(src_k));
10915    GGML_ASSERT(ggml_is_contiguous_rows(src_v));
10916    GGML_ASSERT(ggml_is_contiguous(src_g));
10917    GGML_ASSERT(ggml_is_contiguous(src_beta));
10918    GGML_ASSERT(ggml_is_contiguous(src_state));
10919
10920    GGML_ASSERT(src_g->ne[0] == 1 || src_g->ne[0] == S_v);
10921    GGML_ASSERT(src_beta->ne[0] == 1);
10922
10923    GGML_TENSOR_LOCALS(int64_t, neq, src_q, ne);
10924    GGML_TENSOR_LOCALS(size_t,  nbq, src_q, nb);
10925    GGML_TENSOR_LOCALS(int64_t, nek, src_k, ne);
10926    GGML_TENSOR_LOCALS(size_t,  nbk, src_k, nb);
10927    GGML_TENSOR_LOCALS(int64_t, nev, src_v, ne);
10928    GGML_TENSOR_LOCALS(size_t,  nbv, src_v, nb);
10929    GGML_TENSOR_LOCALS(int64_t, neg, src_g, ne);
10930    GGML_TENSOR_LOCALS(size_t,  nbg, src_g, nb);
10931    GGML_TENSOR_LOCALS(size_t,  nbb, src_beta, nb);
10932
10933    const bool kda = (neg0 == S_v);
10934
10935    // K (snapshot slot count) is an op param; state holds s0 only [S_v, S_v, H, n_seqs].
10936    const int64_t K = ggml_get_op_params_i32(dst, 0);
10937    GGML_ASSERT(K >= 1);
10938    // per-seq stride in floats (seq s starts at state + s * seq_stride)
10939    const int64_t state_seq_stride = src_state->nb[3] / sizeof(float);
10940
10941    const int64_t per_thread = S_v + (K > 1 ? S_v * S_v : 0);
10942    const int ith = params->ith;
10943
10944    float * delta       = (float *)params->wdata + ith * per_thread + CACHE_LINE_SIZE_F32;
10945    float * state_work  = K > 1 ? (delta + S_v) : nullptr;
10946
10947    // output layout: [attn_scores | new_states]
10948    // attn_scores: S_v * H * n_tokens * n_seqs    floats
10949    // new_states:  S_v * S_v * H * n_seqs * K     floats  (K snapshot slots; last min(n_tokens, K))
10950    const int64_t attn_score_elems    = S_v * H * n_tokens * n_seqs;
10951    const int64_t state_size_per_snap = S_v * S_v * H * n_seqs;
10952    float * attn_out_base  = (float *)dst->data;
10953    float * state_out_base = (float *)dst->data + attn_score_elems;
10954
10955    // snapshot slot mapping: slot 0 = most recent state, slot s = s tokens back.
10956    // When n_tokens < K only slots 0..n_tokens-1 are written; older slots are caller-owned.
10957
10958    const float * state_in_base = (const float *)src_state->data;
10959
10960  //const int64_t rq1 = nev1 / neq1;
10961  //const int64_t rk1 = nev1 / nek1;
10962    const int64_t rq3 = nev3 / neq3;
10963    const int64_t rk3 = nev3 / nek3;
10964
10965    const float scale = 1.0f / sqrtf((float) S_v);
10966
10967    for (int64_t ir = ir0; ir < ir1; ++ir) {
10968        const int64_t iv1 = ir % H; // head_index
10969        const int64_t iv3 = ir / H; // sequence
10970
10971        const int64_t iq1 = iv1 % neq1;
10972        const int64_t ik1 = iv1 % nek1;
10973
10974        const int64_t iq3 = iv3 / rq3;
10975        const int64_t ik3 = iv3 / rk3;
10976
10977        // For K=1, write directly to the single output slot to avoid an extra memcpy at the end.
10978        // For K>1, work in scratch and copy out per-token when the slot is in range.
10979        float * s_out = (K > 1)
10980            ? state_work
10981            : state_out_base + (iv3 * H + iv1) * S_v * S_v;
10982
10983        // copy input state into the working buffer and operate in-place
10984        // state layout [S_v, S_v, H, n_seqs]: seq iv3 starts at iv3 * state_seq_stride.
10985        const float * s_in = state_in_base + iv3 * state_seq_stride + iv1 * S_v * S_v;
10986        memcpy(s_out, s_in, S_v * S_v * sizeof(float));
10987
10988        // attn output pointer for first token of this (head, seq)
10989        float * attn_data = attn_out_base + (iv3 * n_tokens * H + iv1) * S_v;
10990
10991        for (int64_t t = 0; t < n_tokens; t++) {
10992            const float * q_d = (const float *)((const char *)src_q->data + iq3 * nbq3 + t * nbq2 + iq1 * nbq1);
10993            const float * k_d = (const float *)((const char *)src_k->data + ik3 * nbk3 + t * nbk2 + ik1 * nbk1);
10994            const float * v_d = (const float *)((const char *)src_v->data + iv3 * nbv3 + t * nbv2 + iv1 * nbv1);
10995
10996            const float beta_val = *(const float *)((const char *)src_beta->data + iv3 * nbb3 + t * nbb2 + iv1 * nbb1);
10997            const float * g_d    =  (const float *)((const char *)src_g->data    + iv3 * nbg3 + t * nbg2 + iv1 * nbg1);
10998
10999            // state is stored transposed: s_out[j*S_v + i] = S[i][j]
11000            // so row j of s_out = column j of S (contiguous access)
11001
11002            if (kda) {
11003                // precompute exp(g) into delta scratch (reused below)
11004                for (int64_t i = 0; i < S_v; ++i) {
11005                    delta[i] = expf(g_d[i]);
11006                }
11007                // S[i][:] *= exp(g[i]) => for each row j of M: M[j][i] *= exp(g[i])
11008                for (int64_t j = 0; j < S_v; ++j) {
11009                    ggml_vec_mul_f32(S_v, &s_out[j * S_v], &s_out[j * S_v], delta);
11010                }
11011            } else {
11012                ggml_vec_scale_f32(S_v * S_v, s_out, expf(g_d[0]));
11013            }
11014
11015            // delta[j] = sum_i S[i][j] * k[i] = dot(row j of M, k)
11016            for (int64_t j = 0; j < S_v; ++j) {
11017                float sum = 0.0f;
11018                ggml_vec_dot_f32(S_v, &sum, 0, &s_out[j * S_v], 0, k_d, 0, 1);
11019                delta[j] = (v_d[j] - sum) * beta_val;
11020            }
11021
11022            // outer product: S[i][j] += k[i] * delta[j] => M[j][i] += delta[j] * k[i]
11023            for (int64_t j = 0; j < S_v; ++j) {
11024                ggml_vec_mad_f32(S_v, &s_out[j * S_v], k_d, delta[j]);
11025            }
11026
11027            // attn_out[j] = sum_i S[i][j] * q[i] = dot(row j of M, q)
11028            for (int64_t j = 0; j < S_v; ++j) {
11029                float sum = 0.0f;
11030                ggml_vec_dot_f32(S_v, &sum, 0, &s_out[j * S_v], 0, q_d, 0, 1);
11031                attn_data[j] = sum * scale;
11032            }
11033
11034            attn_data += S_v * H; // advance to next token
11035
11036            if (K > 1) {
11037                const int64_t target_slot = n_tokens - 1 - t;
11038                if (target_slot >= 0 && target_slot < K) {
11039                    float * curr_state_o = state_out_base + target_slot * state_size_per_snap +
11040                                     (iv3 * H + iv1) * S_v * S_v;
11041                    memcpy(curr_state_o, s_out, S_v * S_v * sizeof(float));
11042                }
11043            }
11044        }
11045    }
11046}
11047
11048
11049static void ggml_compute_forward_gated_delta_net_f32(
11050        const ggml_compute_params * params,
11051        ggml_tensor * dst) {
11052
11053    ggml_tensor * V = dst->src[2];
11054    int64_t nr = V->ne[1] * V->ne[3];
11055
11056    // disable for NUMA
11057    const bool disable_chunking = ggml_is_numa();
11058
11059    int nth = params->nth;
11060    int ith = params->ith;
11061
11062    // 4x chunks per thread
11063    int nth_scaled = nth * 4;
11064    int64_t chunk_size = (nr + nth_scaled - 1) / nth_scaled;
11065    int64_t nchunk     = (nr + chunk_size - 1) / chunk_size;
11066
11067    if (nth == 1 || nchunk < nth || disable_chunking) {
11068      nchunk = nth;
11069    }
11070
11071    if (ith == 0) {
11072      ggml_threadpool_chunk_set(params->threadpool, nth);
11073    }
11074
11075    ggml_barrier(params->threadpool);
11076
11077    const int64_t dr = (nr + nchunk - 1) / nchunk;
11078
11079    int current_chunk = ith;
11080
11081    while (current_chunk < nchunk) {
11082        const int64_t ir0 = dr * current_chunk;
11083        const int64_t ir1 = MIN(ir0 + dr, nr);
11084
11085        ggml_compute_forward_gated_delta_net_one_chunk(params, dst, ir0, ir1);
11086        current_chunk = ggml_threadpool_chunk_add(params->threadpool, 1);
11087    }
11088}
11089
11090void ggml_compute_forward_gated_delta_net(
11091        const ggml_compute_params * params,
11092        ggml_tensor * dst) {
11093    const ggml_tensor * src0 = dst->src[0];
11094
11095    switch (src0->type) {
11096        case GGML_TYPE_F32:
11097            {
11098                ggml_compute_forward_gated_delta_net_f32(params, dst);
11099            } break;
11100        default:
11101            {
11102                GGML_ABORT("fatal error");
11103            }
11104    }
11105}
11106
11107
11108// ggml_compute_forward_dsv4_hc_comb
11109
11110static void ggml_dsv4_hc_comb_norm_cols(float * comb, float eps) {
11111    constexpr int64_t hc = 4;
11112
11113    for (int64_t idst = 0; idst < hc; ++idst) {
11114        float sum = eps;
11115        for (int64_t isrc = 0; isrc < hc; ++isrc) {
11116            sum += comb[idst + hc*isrc];
11117        }
11118
11119        const float inv_sum = 1.0f / sum;
11120        for (int64_t isrc = 0; isrc < hc; ++isrc) {
11121            comb[idst + hc*isrc] *= inv_sum;
11122        }
11123    }
11124}
11125
11126static void ggml_dsv4_hc_comb_norm_rows(float * comb, float eps) {
11127    constexpr int64_t hc = 4;
11128
11129    for (int64_t isrc = 0; isrc < hc; ++isrc) {
11130        float sum = eps;
11131        for (int64_t idst = 0; idst < hc; ++idst) {
11132            sum += comb[idst + hc*isrc];
11133        }
11134
11135        const float inv_sum = 1.0f / sum;
11136        for (int64_t idst = 0; idst < hc; ++idst) {
11137            comb[idst + hc*isrc] *= inv_sum;
11138        }
11139    }
11140}
11141
11142static void ggml_compute_forward_dsv4_hc_comb_f32(
11143        const ggml_compute_params * params,
11144        ggml_tensor * dst) {
11145    const ggml_tensor * mixes = dst->src[0];
11146    const ggml_tensor * scale = dst->src[1];
11147    const ggml_tensor * base  = dst->src[2];
11148
11149    GGML_ASSERT(mixes->type == GGML_TYPE_F32);
11150    GGML_ASSERT(scale->type == GGML_TYPE_F32);
11151    GGML_ASSERT(base->type == GGML_TYPE_F32);
11152    GGML_ASSERT(dst->type == GGML_TYPE_F32);
11153
11154    constexpr int64_t hc = 4;
11155    constexpr int64_t comb_offset = 2*hc;
11156    constexpr int64_t hc_mix_dim = (2 + hc)*hc;
11157
11158    const int64_t n_tokens = mixes->ne[1];
11159
11160    GGML_ASSERT(mixes->ne[0] == hc_mix_dim);
11161    GGML_ASSERT(dst->ne[0] == hc);
11162    GGML_ASSERT(dst->ne[1] == hc);
11163    GGML_ASSERT(dst->ne[2] == n_tokens);
11164    GGML_ASSERT(scale->ne[0] >= 3);
11165    GGML_ASSERT(base->ne[0] == hc_mix_dim);
11166
11167    GGML_TENSOR_LOCALS(size_t, nbm, mixes, nb);
11168    GGML_TENSOR_LOCALS(size_t, nbs, scale, nb);
11169    GGML_TENSOR_LOCALS(size_t, nbb, base,  nb);
11170    GGML_TENSOR_LOCALS(size_t, nbd, dst,   nb);
11171
11172    const float eps = ggml_get_op_params_f32(dst, 0);
11173    const int32_t n_iter = ggml_get_op_params_i32(dst, 1);
11174    GGML_ASSERT(n_iter > 0);
11175
11176    const int ith = params->ith;
11177    const int nth = params->nth;
11178
11179    const int64_t dr  = (n_tokens + nth - 1) / nth;
11180    const int64_t it0 = dr * ith;
11181    const int64_t it1 = MIN(it0 + dr, n_tokens);
11182
11183    const float scale_comb = *(const float *) ((const char *) scale->data + 2*nbs0);
11184
11185    for (int64_t it = it0; it < it1; ++it) {
11186        float comb[hc*hc];
11187
11188        for (int64_t isrc = 0; isrc < hc; ++isrc) {
11189            float max = -INFINITY;
11190            for (int64_t idst = 0; idst < hc; ++idst) {
11191                const int64_t idx = idst + hc*isrc;
11192                const float xv = *(const float *) ((const char *) mixes->data + (comb_offset + idx)*nbm0 + it*nbm1);
11193                const float bv = *(const float *) ((const char *) base->data  + (comb_offset + idx)*nbb0);
11194                const float v = xv * scale_comb + bv;
11195                comb[idx] = v;
11196                max = MAX(max, v);
11197            }
11198
11199            float sum = 0.0f;
11200            for (int64_t idst = 0; idst < hc; ++idst) {
11201                const int64_t idx = idst + hc*isrc;
11202                const float v = expf(comb[idx] - max);
11203                comb[idx] = v;
11204                sum += v;
11205            }
11206
11207            const float inv_sum = 1.0f / sum;
11208            for (int64_t idst = 0; idst < hc; ++idst) {
11209                const int64_t idx = idst + hc*isrc;
11210                comb[idx] = comb[idx] * inv_sum + eps;
11211            }
11212        }
11213
11214        ggml_dsv4_hc_comb_norm_cols(comb, eps);
11215        for (int32_t i = 1; i < n_iter; ++i) {
11216            ggml_dsv4_hc_comb_norm_rows(comb, eps);
11217            ggml_dsv4_hc_comb_norm_cols(comb, eps);
11218        }
11219
11220        for (int64_t isrc = 0; isrc < hc; ++isrc) {
11221            for (int64_t idst = 0; idst < hc; ++idst) {
11222                const int64_t idx = idst + hc*isrc;
11223                *(float *) ((char *) dst->data + idst*nbd0 + isrc*nbd1 + it*nbd2) = comb[idx];
11224            }
11225        }
11226    }
11227}
11228
11229void ggml_compute_forward_dsv4_hc_comb(
11230        const ggml_compute_params * params,
11231        ggml_tensor * dst) {
11232    const ggml_tensor * src0 = dst->src[0];
11233
11234    switch (src0->type) {
11235        case GGML_TYPE_F32:
11236            {
11237                ggml_compute_forward_dsv4_hc_comb_f32(params, dst);
11238            } break;
11239        default:
11240            {
11241                GGML_ABORT("fatal error");
11242            }
11243    }
11244}
11245
11246// ggml_compute_forward_dsv4_hc_pre
11247
11248static void ggml_compute_forward_dsv4_hc_pre_f32(
11249        const ggml_compute_params * params,
11250        ggml_tensor * dst) {
11251    const ggml_tensor * x       = dst->src[0];
11252    const ggml_tensor * weights = dst->src[1];
11253
11254    GGML_ASSERT(x->type == GGML_TYPE_F32);
11255    GGML_ASSERT(weights->type == GGML_TYPE_F32);
11256    GGML_ASSERT(dst->type == GGML_TYPE_F32);
11257
11258    const int64_t n_embd   = x->ne[0];
11259    const int64_t hc       = x->ne[1];
11260    const int64_t n_tokens = x->ne[2];
11261
11262    GGML_ASSERT(dst->ne[0] == n_embd);
11263    GGML_ASSERT(dst->ne[1] == n_tokens);
11264    GGML_ASSERT(weights->ne[0] == hc);
11265    GGML_ASSERT(weights->ne[1] == n_tokens);
11266
11267    GGML_TENSOR_LOCALS(size_t, nbx, x,       nb);
11268    GGML_TENSOR_LOCALS(size_t, nbw, weights, nb);
11269    GGML_TENSOR_LOCALS(size_t, nbd, dst,     nb);
11270
11271    const int ith = params->ith;
11272    const int nth = params->nth;
11273
11274    const int64_t nr  = n_embd * n_tokens;
11275    const int64_t dr  = (nr + nth - 1) / nth;
11276    const int64_t ir0 = dr * ith;
11277    const int64_t ir1 = MIN(ir0 + dr, nr);
11278
11279    for (int64_t ir = ir0; ir < ir1; ++ir) {
11280        const int64_t i0 = ir % n_embd;
11281        const int64_t it = ir / n_embd;
11282
11283        float sum = 0.0f;
11284        for (int64_t ih = 0; ih < hc; ++ih) {
11285            const float xv = *(const float *) ((const char *) x->data       + i0*nbx0 + ih*nbx1 + it*nbx2);
11286            const float wv = *(const float *) ((const char *) weights->data + ih*nbw0 + it*nbw1);
11287            sum += xv * wv;
11288        }
11289
11290        *(float *) ((char *) dst->data + i0*nbd0 + it*nbd1) = sum;
11291    }
11292}
11293
11294void ggml_compute_forward_dsv4_hc_pre(
11295        const ggml_compute_params * params,
11296        ggml_tensor * dst) {
11297    const ggml_tensor * src0 = dst->src[0];
11298
11299    switch (src0->type) {
11300        case GGML_TYPE_F32:
11301            {
11302                ggml_compute_forward_dsv4_hc_pre_f32(params, dst);
11303            } break;
11304        default:
11305            {
11306                GGML_ABORT("fatal error");
11307            }
11308    }
11309}
11310
11311// ggml_compute_forward_dsv4_hc_post
11312
11313static void ggml_compute_forward_dsv4_hc_post_f32(
11314        const ggml_compute_params * params,
11315        ggml_tensor * dst) {
11316    const ggml_tensor * x        = dst->src[0];
11317    const ggml_tensor * residual = dst->src[1];
11318    const ggml_tensor * post     = dst->src[2];
11319    const ggml_tensor * comb     = dst->src[3];
11320
11321    GGML_ASSERT(x->type == GGML_TYPE_F32);
11322    GGML_ASSERT(residual->type == GGML_TYPE_F32);
11323    GGML_ASSERT(post->type == GGML_TYPE_F32);
11324    GGML_ASSERT(comb->type == GGML_TYPE_F32);
11325    GGML_ASSERT(dst->type == GGML_TYPE_F32);
11326
11327    const int64_t n_embd   = x->ne[0];
11328    const int64_t n_tokens = x->ne[1];
11329    const int64_t hc       = residual->ne[1];
11330
11331    GGML_ASSERT(dst->ne[0] == n_embd);
11332    GGML_ASSERT(dst->ne[1] == hc);
11333    GGML_ASSERT(dst->ne[2] == n_tokens);
11334    GGML_ASSERT(residual->ne[0] == n_embd);
11335    GGML_ASSERT(residual->ne[2] == n_tokens);
11336    GGML_ASSERT(post->ne[0] == hc);
11337    GGML_ASSERT(post->ne[1] == n_tokens);
11338    GGML_ASSERT(comb->ne[0] == hc);
11339    GGML_ASSERT(comb->ne[1] == hc);
11340    GGML_ASSERT(comb->ne[2] == n_tokens);
11341
11342    GGML_TENSOR_LOCALS(size_t, nbx, x,        nb);
11343    GGML_TENSOR_LOCALS(size_t, nbr, residual, nb);
11344    GGML_TENSOR_LOCALS(size_t, nbp, post,     nb);
11345    GGML_TENSOR_LOCALS(size_t, nbc, comb,     nb);
11346    GGML_TENSOR_LOCALS(size_t, nbd, dst,      nb);
11347
11348    const int ith = params->ith;
11349    const int nth = params->nth;
11350
11351    const int64_t nr  = n_embd * hc * n_tokens;
11352    const int64_t dr  = (nr + nth - 1) / nth;
11353    const int64_t ir0 = dr * ith;
11354    const int64_t ir1 = MIN(ir0 + dr, nr);
11355
11356    for (int64_t ir = ir0; ir < ir1; ++ir) {
11357        const int64_t i0     = ir % n_embd;
11358        const int64_t idst   = (ir / n_embd) % hc;
11359        const int64_t it     = ir / (n_embd * hc);
11360
11361        const float xv = *(const float *) ((const char *) x->data    + i0*nbx0 + it*nbx1);
11362        const float pv = *(const float *) ((const char *) post->data + idst*nbp0 + it*nbp1);
11363
11364        float sum = xv * pv;
11365        for (int64_t isrc = 0; isrc < hc; ++isrc) {
11366            const float rv = *(const float *) ((const char *) residual->data + i0*nbr0 + isrc*nbr1 + it*nbr2);
11367            const float cv = *(const float *) ((const char *) comb->data     + idst*nbc0 + isrc*nbc1 + it*nbc2);
11368            sum += rv * cv;
11369        }
11370
11371        *(float *) ((char *) dst->data + i0*nbd0 + idst*nbd1 + it*nbd2) = sum;
11372    }
11373}
11374
11375void ggml_compute_forward_dsv4_hc_post(
11376        const ggml_compute_params * params,
11377        ggml_tensor * dst) {
11378    const ggml_tensor * src0 = dst->src[0];
11379
11380    switch (src0->type) {
11381        case GGML_TYPE_F32:
11382            {
11383                ggml_compute_forward_dsv4_hc_post_f32(params, dst);
11384            } break;
11385        default:
11386            {
11387                GGML_ABORT("fatal error");
11388            }
11389    }
11390}
11391
11392// ggml_compute_forward_rwkv_wkv7
11393
11394static void ggml_compute_forward_rwkv_wkv7_f32(
11395        const ggml_compute_params * params,
11396        ggml_tensor * dst) {
11397    const int64_t T = dst->src[1]->ne[2];
11398    const int64_t C = dst->ne[0];
11399    const int64_t HEADS = dst->src[1]->ne[1];
11400    const int64_t n_seqs = dst->src[6]->ne[1];
11401    const int64_t head_size = C / HEADS;
11402
11403    float * dst_data = (float *) dst->data;
11404    float * state = ((float *) dst->data) + C * T;
11405
11406    const int ith = params->ith;
11407    const int nth = params->nth;
11408
11409    const int h_start =  (HEADS * (ith    )) / nth;
11410    const int h_end   = ((HEADS * (ith + 1)) / nth < HEADS) ?
11411                         (HEADS * (ith + 1)) / nth : HEADS;
11412
11413    float * r = (float *) dst->src[0]->data;
11414    float * w = (float *) dst->src[1]->data;
11415    float * k = (float *) dst->src[2]->data;
11416    float * v = (float *) dst->src[3]->data;
11417    float * a = (float *) dst->src[4]->data;
11418    float * b = (float *) dst->src[5]->data;
11419
11420    int64_t t_stride = HEADS * head_size; // Same to C
11421
11422    int64_t h_stride = C / HEADS;
11423    GGML_ASSERT(C % HEADS == 0); // C must be divisible by HEADS
11424    int64_t h_stride_2d = head_size * head_size;
11425
11426    #if defined(GGML_SIMD)
11427        #if defined(__ARM_FEATURE_SVE) || defined(__riscv_v_intrinsic)
11428            // scalar Route to scalar implementation       //TODO: Write SVE code and RVV code
11429            for (int64_t t = 0; t < T; t++) {
11430                int64_t t_offset = t * t_stride;
11431                int64_t state_offset = head_size * C * (t / (T / n_seqs));
11432                float * state_cur = state + state_offset;
11433                float * state_prev = t % (T / n_seqs) ? state_cur : (float*)dst->src[6]->data + state_offset;
11434
11435                for (int64_t h = h_start; h < h_end; h++) {
11436                    int64_t h_offset = h * h_stride;
11437                    int64_t t_h_offset = t_offset + h_offset;
11438                    int64_t h_2d_offset = h * h_stride_2d;
11439
11440                    for (int64_t i = 0; i < head_size; i++) {
11441                        int64_t t_h_i_offset = t_h_offset + i;
11442                        int64_t h_2d_i_offset = h_2d_offset + i * h_stride;
11443
11444                        float v_val = v[t_h_i_offset];
11445
11446                        float sa = 0, result = 0;
11447                        for (int64_t j = 0; j < head_size; j++) {
11448                            sa += a[t_h_offset + j] * state_prev[h_2d_i_offset + j];
11449                        }
11450
11451                        for (int64_t j = 0; j < head_size; j++) {
11452                            int64_t t_h_j_offset = t_h_offset + j;
11453                            int64_t h_2d_i_j_offset = h_2d_i_offset + j;
11454
11455                            float r_val = r[t_h_j_offset];
11456                            float w_val = w[t_h_j_offset];
11457                            float k_val = k[t_h_j_offset];
11458                            float b_val = b[t_h_j_offset];
11459                            float kv_val = v_val * k_val;
11460                            float prev_state_val = state_prev[h_2d_i_j_offset];
11461                            state_cur[h_2d_i_j_offset] = prev_state_val * w_val + kv_val + sa * b_val;
11462                            result += state_cur[h_2d_i_j_offset] * r_val;
11463                        }
11464                        dst_data[t_h_i_offset] = result;
11465                    }
11466                }
11467            }
11468        #else
11469            for (int64_t t = 0; t < T; t++) {
11470                int64_t t_offset = t * t_stride;
11471                int64_t state_offset = head_size * C * (t / (T / n_seqs));
11472                float * state_cur = state + state_offset;
11473                float * state_prev = t % (T / n_seqs) ? state_cur : (float*)dst->src[6]->data + state_offset;
11474
11475                for (int64_t h = h_start; h < h_end; h++) {
11476                    int64_t h_offset = h * h_stride;
11477                    int64_t t_h_offset = t_offset + h_offset;
11478                    int64_t h_2d_offset = h * h_stride_2d;
11479
11480                    for (int64_t ii = 0; ii < head_size; ii++) {
11481                        int64_t t_h_i_offset = t_h_offset + ii;
11482                        int64_t h_2d_i_offset = h_2d_offset + ii * h_stride;
11483
11484                        GGML_F32_VEC v_vec = GGML_F32_VEC_SET1(v[t_h_i_offset]);
11485
11486                        float sa = 0;
11487                        {
11488                            GGML_F32_VEC sum[GGML_F32_ARR] = { GGML_F32_VEC_ZERO };
11489                            GGML_F32_VEC ax[GGML_F32_ARR];
11490                            GGML_F32_VEC ay[GGML_F32_ARR];
11491                            for (int64_t j = 0; j < head_size; j += GGML_F32_STEP) {
11492                                for (int64_t kk = 0; kk < GGML_F32_ARR; kk++) {
11493                                    ax[kk] = GGML_F32_VEC_LOAD(&a[t_h_offset + j + kk * GGML_F32_EPR]);
11494                                    ay[kk] = GGML_F32_VEC_LOAD(&state_prev[h_2d_i_offset + j + kk * GGML_F32_EPR]);
11495                                    sum[kk] = GGML_F32_VEC_FMA(sum[kk], ax[kk], ay[kk]);
11496                                }
11497                            }
11498                            GGML_F32_VEC_REDUCE(sa, sum);
11499                        }
11500
11501                        GGML_F32_VEC sa_vec = GGML_F32_VEC_SET1(sa);
11502
11503                        int64_t j = 0;
11504                        GGML_F32_VEC result_vec[GGML_F32_ARR] = { GGML_F32_VEC_ZERO };
11505                        for (; j < head_size; j += GGML_F32_STEP) {
11506                            for (int64_t kk = 0; kk < GGML_F32_ARR; kk++) {
11507                                int64_t t_h_j_offset = t_h_offset + j + kk * GGML_F32_EPR;
11508                                int64_t h_2d_i_j_offset = h_2d_i_offset + j + kk * GGML_F32_EPR;
11509
11510                                GGML_F32_VEC r_vec = GGML_F32_VEC_LOAD(&r[t_h_j_offset]);
11511                                GGML_F32_VEC w_vec = GGML_F32_VEC_LOAD(&w[t_h_j_offset]);
11512                                GGML_F32_VEC k_vec = GGML_F32_VEC_LOAD(&k[t_h_j_offset]);
11513                                GGML_F32_VEC b_vec = GGML_F32_VEC_LOAD(&b[t_h_j_offset]);
11514
11515                                k_vec = GGML_F32_VEC_MUL(v_vec, k_vec);
11516
11517                                GGML_F32_VEC state_vec = GGML_F32_VEC_LOAD(&state_prev[h_2d_i_j_offset]);
11518                                // kv + s * decay + sa * b
11519                                state_vec = GGML_F32_VEC_FMA(k_vec, state_vec, w_vec);
11520                                state_vec = GGML_F32_VEC_FMA(state_vec, sa_vec, b_vec);
11521                                GGML_F32_VEC_STORE(&state_cur[h_2d_i_j_offset], state_vec);
11522
11523                                result_vec[kk] = GGML_F32_VEC_FMA(result_vec[kk], state_vec, r_vec);
11524                            }
11525                        }
11526                        GGML_F32_VEC_REDUCE(dst_data[t_h_i_offset], result_vec);
11527
11528                        // There shouldn't be left-overs though.
11529                        for (; j < head_size; j++) {
11530                            int64_t t_h_j_offset = t_h_offset + j;
11531                            int64_t h_2d_i_j_offset = h_2d_i_offset + j;
11532
11533                            float r_val = r[t_h_j_offset];
11534                            float w_val = w[t_h_j_offset];
11535                            float k_val = k[t_h_j_offset];
11536                            float b_val = b[t_h_j_offset];
11537                            float kv_val = v[t_h_i_offset] * k_val;
11538
11539                            float prev_state_val = state_prev[h_2d_i_j_offset];
11540                            state_cur[h_2d_i_j_offset] = prev_state_val * w_val + kv_val + sa * b_val;
11541                            dst_data[t_h_i_offset] += state_cur[h_2d_i_j_offset] * r_val;
11542                        }
11543                    }
11544                }
11545            }
11546        #endif
11547    #else
11548        for (int64_t t = 0; t < T; t++) {
11549            int64_t t_offset = t * t_stride;
11550            int64_t state_offset = head_size * C * (t / (T / n_seqs));
11551            float * state_cur = state + state_offset;
11552            float * state_prev = t % (T / n_seqs) ? state_cur : (float*)dst->src[6]->data + state_offset;
11553
11554            for (int64_t h = h_start; h < h_end; h++) {
11555                int64_t h_offset = h * h_stride;
11556                int64_t t_h_offset = t_offset + h_offset;
11557                int64_t h_2d_offset = h * h_stride_2d;
11558
11559                for (int64_t i = 0; i < head_size; i++) {
11560                    int64_t t_h_i_offset = t_h_offset + i;
11561                    int64_t h_2d_i_offset = h_2d_offset + i * h_stride;
11562
11563                    float v_val = v[t_h_i_offset];
11564
11565                    float sa = 0, result = 0;
11566                    for (int64_t j = 0; j < head_size; j++) {
11567                        sa += a[t_h_offset + j] * state_prev[h_2d_i_offset + j];
11568                    }
11569
11570                    for (int64_t j = 0; j < head_size; j++) {
11571                        int64_t t_h_j_offset = t_h_offset + j;
11572                        int64_t h_2d_i_j_offset = h_2d_i_offset + j;
11573
11574                        float r_val = r[t_h_j_offset];
11575                        float w_val = w[t_h_j_offset];
11576                        float k_val = k[t_h_j_offset];
11577                        float b_val = b[t_h_j_offset];
11578                        float kv_val = v_val * k_val;
11579                        float prev_state_val = state_prev[h_2d_i_j_offset];
11580                        state_cur[h_2d_i_j_offset] = prev_state_val * w_val + kv_val + sa * b_val;
11581                        result += state_cur[h_2d_i_j_offset] * r_val;
11582                    }
11583                    dst_data[t_h_i_offset] = result;
11584                }
11585            }
11586        }
11587    #endif
11588}
11589
11590
11591void ggml_compute_forward_rwkv_wkv7(
11592        const ggml_compute_params * params,
11593        ggml_tensor * dst) {
11594
11595    const ggml_tensor * src0 = dst->src[0];
11596
11597    switch (src0->type) {
11598        case GGML_TYPE_F32:
11599            {
11600                ggml_compute_forward_rwkv_wkv7_f32(params, dst);
11601            } break;
11602        default:
11603            {
11604                GGML_ABORT("fatal error");
11605            }
11606    }
11607}
11608
11609// ggml_compute_forward_map_custom1
11610
11611void ggml_compute_forward_map_custom1(
11612        const ggml_compute_params * params,
11613              ggml_tensor * dst) {
11614
11615    const ggml_tensor * a = dst->src[0];
11616
11617    struct ggml_map_custom1_op_params p;
11618    memcpy(&p, dst->op_params, sizeof(p));
11619
11620    p.fun(dst, a, params->ith, params->nth, p.userdata);
11621}
11622
11623// ggml_compute_forward_map_custom2
11624
11625void ggml_compute_forward_map_custom2(
11626        const ggml_compute_params * params,
11627              ggml_tensor * dst) {
11628
11629    const ggml_tensor * a = dst->src[0];
11630    const ggml_tensor * b = dst->src[1];
11631
11632    struct ggml_map_custom2_op_params p;
11633    memcpy(&p, dst->op_params, sizeof(p));
11634
11635    p.fun(dst, a, b, params->ith, params->nth, p.userdata);
11636}
11637
11638// ggml_compute_forward_map_custom3
11639
11640void ggml_compute_forward_map_custom3(
11641        const ggml_compute_params * params,
11642              ggml_tensor * dst) {
11643
11644    const ggml_tensor * a = dst->src[0];
11645    const ggml_tensor * b = dst->src[1];
11646    const ggml_tensor * c = dst->src[2];
11647
11648    struct ggml_map_custom3_op_params p;
11649    memcpy(&p, dst->op_params, sizeof(p));
11650
11651    p.fun(dst, a, b, c, params->ith, params->nth, p.userdata);
11652}
11653
11654// ggml_compute_forward_custom
11655
11656void ggml_compute_forward_custom(
11657    const struct ggml_compute_params * params,
11658          struct ggml_tensor * dst) {
11659
11660    struct ggml_custom_op_params p;
11661    memcpy(&p, dst->op_params, sizeof(p));
11662
11663    p.fun(dst, params->ith, params->nth, p.userdata);
11664}
11665
11666// ggml_compute_forward_cross_entropy_loss
11667
11668static void ggml_compute_forward_cross_entropy_loss_f32(
11669        const ggml_compute_params * params,
11670        ggml_tensor * dst) {
11671
11672    const ggml_tensor * src0 = dst->src[0];
11673    const ggml_tensor * src1 = dst->src[1];
11674
11675    GGML_ASSERT(src0->type == GGML_TYPE_F32);
11676    GGML_ASSERT(src1->type == GGML_TYPE_F32);
11677    GGML_ASSERT(src0->nb[0] == ggml_type_size(src0->type));
11678    GGML_ASSERT(src1->nb[0] == ggml_type_size(src1->type));
11679    GGML_ASSERT(ggml_are_same_shape(src0, src1));
11680    GGML_ASSERT(ggml_is_scalar(dst));
11681    GGML_ASSERT(dst->type == GGML_TYPE_F32);
11682
11683    // TODO: handle transposed/permuted matrices
11684    const int64_t nc = src0->ne[0];
11685    const int64_t nr = ggml_nrows(src0);
11686
11687    const int ith = params->ith;
11688    const int nth = params->nth;
11689
11690    float * sums =  (float *) params->wdata;
11691    float * st   = ((float *) params->wdata) + nth + ith*nc;
11692    float sum_thread = 0.0f;
11693
11694    GGML_ASSERT(params->wsize >= sizeof(float) * (nth + nth * nc));
11695
11696    // rows per thread
11697    const int64_t dr = (nr + nth - 1)/nth;
11698
11699    // row range for this thread
11700    const int64_t ir0 = dr*ith;
11701    const int64_t ir1 = MIN(ir0 + dr, nr);
11702
11703    for (int64_t i1 = ir0; i1 < ir1; ++i1) {
11704        const float * s0 = (const float *)((const char *) src0->data + i1*src0->nb[1]);
11705        const float * s1 = (const float *)((const char *) src1->data + i1*src1->nb[1]);
11706
11707#ifndef NDEBUG
11708        for (int64_t i = 0; i < nc; ++i) {
11709            //printf("p[%d] = %f\n", i, p[i]);
11710            assert(!isnan(s0[i]));
11711            assert(!isnan(s1[i]));
11712        }
11713#endif // NDEBUG
11714
11715        float max = -INFINITY;
11716        ggml_vec_max_f32(nc, &max, s0);
11717        const ggml_float sum_softmax = ggml_vec_log_soft_max_f32(nc, st, s0, max);
11718        assert(sum_softmax >= 0.0);
11719
11720        ggml_vec_add1_f32(nc, st, st, -sum_softmax);
11721        ggml_vec_mul_f32(nc, st, st, s1);
11722
11723        float sum_st = 0.0f;
11724        ggml_vec_sum_f32(nc, &sum_st, st);
11725        sum_thread += sum_st;
11726
11727#ifndef NDEBUG
11728        for (int64_t i = 0; i < nc; ++i) {
11729            assert(!isnan(st[i]));
11730            assert(!isinf(st[i]));
11731        }
11732#endif // NDEBUG
11733    }
11734    sums[ith] = sum_thread;
11735    ggml_barrier(params->threadpool);
11736
11737    if (ith == 0) {
11738        float * dp = (float *) dst->data;
11739        ggml_vec_sum_f32(nth, dp, sums);
11740        dp[0] *= -1.0f / (float) nr;
11741    }
11742}
11743
11744void ggml_compute_forward_cross_entropy_loss(
11745        const ggml_compute_params * params,
11746        ggml_tensor * dst) {
11747
11748    const ggml_tensor * src0 = dst->src[0];
11749
11750    switch (src0->type) {
11751        case GGML_TYPE_F32:
11752            {
11753                ggml_compute_forward_cross_entropy_loss_f32(params, dst);
11754            } break;
11755        default:
11756            {
11757                GGML_ABORT("fatal error");
11758            }
11759    }
11760}
11761
11762// ggml_compute_forward_cross_entropy_loss_back
11763
11764static void ggml_compute_forward_cross_entropy_loss_back_f32(
11765        const ggml_compute_params * params,
11766        ggml_tensor * dst) {
11767
11768    const ggml_tensor * grad  = dst->src[0]; // gradient of forward pass output
11769    const ggml_tensor * src0f = dst->src[1]; // src0 of forward pass
11770    const ggml_tensor * src1f = dst->src[2]; // src1 of forward pass
11771
11772    GGML_ASSERT(ggml_is_contiguous(dst));
11773    GGML_ASSERT(ggml_is_contiguous(src0f));
11774    GGML_ASSERT(ggml_is_contiguous(src1f));
11775    GGML_ASSERT(ggml_is_contiguous(grad));
11776    GGML_ASSERT(ggml_are_same_shape(src0f, src1f) && ggml_are_same_shape(src0f, dst));
11777
11778    const int64_t ith = params->ith;
11779    const int64_t nth = params->nth;
11780
11781    // TODO: handle transposed/permuted matrices
11782    const int64_t nc = src0f->ne[0];
11783    const int64_t nr = ggml_nrows(src0f);
11784
11785    // rows per thread
11786    const int64_t dr = (nr + nth - 1)/nth;
11787
11788    // row range for this thread
11789    const int64_t ir0 = dr*ith;
11790    const int64_t ir1 = MIN(ir0 + dr, nr);
11791
11792    const float d_by_nr = ((const float *) grad->data)[0] / (float) nr;
11793
11794    for (int64_t i1 = ir0; i1 < ir1; i1++) {
11795        float       * ds0 = (float       *)((char       *) dst->data   + i1*dst->nb[1]);
11796        const float * s0  = (const float *)((const char *) src0f->data + i1*src0f->nb[1]);
11797        const float * s1  = (const float *)((const char *) src1f->data + i1*src1f->nb[1]);
11798
11799#ifndef NDEBUG
11800        for (int64_t i = 0; i < nc; ++i) {
11801            //printf("p[%d] = %f\n", i, p[i]);
11802            assert(!isnan(s0[i]));
11803            assert(!isnan(s1[i]));
11804        }
11805#endif // NDEBUG
11806
11807        // soft_max
11808        float max = -INFINITY;
11809        ggml_vec_max_f32(nc, &max, s0);
11810        const ggml_float sum = ggml_vec_soft_max_f32(nc, ds0, s0, max);
11811        assert(sum > 0.0);
11812        ggml_vec_scale_f32(nc, ds0, 1.0/sum);
11813
11814        // grad(src0f) = (softmax(src0f) - src1f) * grad(cross_entropy_loss(src0f, src1f)) / nr
11815        ggml_vec_sub_f32(nc, ds0, ds0, s1);
11816        ggml_vec_scale_f32(nc, ds0, d_by_nr);
11817
11818#ifndef NDEBUG
11819        for (int64_t i = 0; i < nc; ++i) {
11820            assert(!isnan(ds0[i]));
11821            assert(!isinf(ds0[i]));
11822        }
11823#endif // NDEBUG
11824    }
11825}
11826
11827void ggml_compute_forward_cross_entropy_loss_back(
11828        const ggml_compute_params * params,
11829        ggml_tensor * dst) {
11830
11831    const ggml_tensor * src0 = dst->src[0];
11832
11833    switch (src0->type) {
11834        case GGML_TYPE_F32:
11835            {
11836                ggml_compute_forward_cross_entropy_loss_back_f32(params, dst);
11837            } break;
11838        default:
11839            {
11840                GGML_ABORT("fatal error");
11841            }
11842    }
11843}
11844
11845static void ggml_compute_forward_opt_step_adamw_f32(
11846        const ggml_compute_params * params,
11847        ggml_tensor * dst) {
11848
11849    const ggml_tensor * src0         = dst->src[0];
11850    const ggml_tensor * src0_grad    = dst->src[1];
11851    const ggml_tensor * src0_grad_m  = dst->src[2];
11852    const ggml_tensor * src0_grad_v  = dst->src[3];
11853    const ggml_tensor * adamw_params = dst->src[4];
11854
11855    GGML_ASSERT(ggml_are_same_shape(src0, src0_grad));
11856    GGML_ASSERT(ggml_are_same_shape(src0, src0_grad_m));
11857    GGML_ASSERT(ggml_are_same_shape(src0, src0_grad_v));
11858    GGML_ASSERT(ggml_nelements(adamw_params) == 7);
11859
11860    const int ith = params->ith;
11861    const int nth = params->nth;
11862
11863    const int nr  = ggml_nrows(src0);
11864
11865    GGML_TENSOR_UNARY_OP_LOCALS
11866    GGML_ASSERT(nb00 == sizeof(float));
11867
11868    // rows per thread
11869    const int dr = (nr + nth - 1)/nth;
11870
11871    // row range for this thread
11872    const int ir0 = dr*ith;
11873    const int ir1 = MIN(ir0 + dr, nr);
11874
11875    const float * adamw_params_ptr = ggml_get_data_f32(adamw_params);
11876
11877    const float alpha  = adamw_params_ptr[0];
11878    const float beta1  = adamw_params_ptr[1];
11879    const float beta2  = adamw_params_ptr[2];
11880    const float eps    = adamw_params_ptr[3];
11881    const float wd     = adamw_params_ptr[4];
11882    const float beta1h = adamw_params_ptr[5];
11883    const float beta2h = adamw_params_ptr[6];
11884    const float keep   = 1.f - alpha * wd;
11885    for (int ir = ir0; ir < ir1; ++ir) {
11886        const int64_t i03 = ir/(ne02*ne01);
11887        const int64_t i02 = (ir - i03*ne02*ne01)/ne01;
11888        const int64_t i01 = (ir - i03*ne02*ne01 - i02*ne01);
11889
11890        const size_t offset = i03*nb03 + i02*nb02 + i01*nb01;
11891
11892        float       * w = (float       *) ((char       *) src0->data        + offset); // weight
11893        const float * g = (const float *) ((const char *) src0_grad->data   + offset); // grad
11894        float       * m = (float       *) ((char       *) src0_grad_m->data + offset);
11895        float       * v = (float       *) ((char       *) src0_grad_v->data + offset);
11896
11897        for (int i00 = 0; i00 < ne00; ++i00) {
11898            m[i00] = m[i00]*beta1 +        g[i00]*(1.0f - beta1);
11899            v[i00] = v[i00]*beta2 + g[i00]*g[i00]*(1.0f - beta2);
11900
11901            const float mh =       m[i00]*beta1h;
11902            const float vh = sqrtf(v[i00]*beta2h) + eps;
11903
11904            // The weight decay is applied independently of the Adam momenta m and v.
11905            // This is NOT equivalent to l2 regularization that adds w[i00]*w[i00] to the loss.
11906            // See: https://arxiv.org/pdf/1711.05101v3.pdf
11907            w[i00] = w[i00] * keep - alpha * mh / vh;
11908        }
11909    }
11910}
11911
11912void ggml_compute_forward_opt_step_adamw(
11913        const ggml_compute_params * params,
11914        ggml_tensor * dst) {
11915
11916    const ggml_tensor * src0 = dst->src[0];
11917
11918    switch (src0->type) {
11919        case GGML_TYPE_F32:
11920            {
11921                ggml_compute_forward_opt_step_adamw_f32(params, dst);
11922            } break;
11923        default:
11924            {
11925                GGML_ABORT("fatal error");
11926            }
11927    }
11928}
11929
11930static void ggml_compute_forward_opt_step_sgd_f32(const ggml_compute_params * params, ggml_tensor * dst) {
11931    const ggml_tensor * src0       = dst->src[0];
11932    const ggml_tensor * src0_grad  = dst->src[1];
11933    const ggml_tensor * sgd_params = dst->src[2];
11934
11935    GGML_ASSERT(ggml_are_same_shape(src0, src0_grad));
11936    GGML_ASSERT(ggml_nelements(sgd_params) == 2);
11937
11938    const int ith = params->ith;
11939    const int nth = params->nth;
11940
11941    const int nr = ggml_nrows(src0);
11942
11943    GGML_TENSOR_UNARY_OP_LOCALS
11944    GGML_ASSERT(nb00 == sizeof(float));
11945
11946    // rows per thread
11947    const int dr = (nr + nth - 1) / nth;
11948
11949    // row range for this thread
11950    const int ir0 = dr * ith;
11951    const int ir1 = MIN(ir0 + dr, nr);
11952
11953    // using adamw param subset we care about - alpha, wd - could have a separate struct
11954    const float * sgd_params_ptr   = ggml_get_data_f32(sgd_params);
11955    const float   alpha            = sgd_params_ptr[0];
11956    const float   keep             = 1.f - alpha * sgd_params_ptr[1];
11957
11958    for (int ir = ir0; ir < ir1; ++ir) {
11959        const int64_t i03 = ir / (ne02 * ne01);
11960        const int64_t i02 = (ir - i03 * ne02 * ne01) / ne01;
11961        const int64_t i01 = (ir - i03 * ne02 * ne01 - i02 * ne01);
11962
11963        const size_t offset = i03 * nb03 + i02 * nb02 + i01 * nb01;
11964
11965        float *       w = (float *) ((char *) src0->data + offset);                   // weight
11966        const float * g = (const float *) ((const char *) src0_grad->data + offset);  // grad
11967
11968        for (int i00 = 0; i00 < ne00; ++i00) {
11969            w[i00] = w[i00] * keep - alpha * g[i00];
11970        }
11971    }
11972}
11973
11974void ggml_compute_forward_opt_step_sgd(const ggml_compute_params * params, ggml_tensor * dst) {
11975    const ggml_tensor * src0 = dst->src[0];
11976
11977    switch (src0->type) {
11978        case GGML_TYPE_F32:
11979            {
11980                ggml_compute_forward_opt_step_sgd_f32(params, dst);
11981            }
11982            break;
11983        default:
11984            {
11985                GGML_ABORT("fatal error - sgd is F32 only");
11986            }
11987    }
11988}
11989
11990static void ggml_compute_forward_fwht_f32(const ggml_compute_params * params, ggml_tensor * dst) {
11991    const ggml_tensor * src0 = dst->src[0];
11992    const ggml_tensor * src1 = dst->src[1];
11993
11994    GGML_ASSERT(src1->type == GGML_TYPE_F32);
11995    GGML_ASSERT(dst->type == GGML_TYPE_F32);
11996
11997    GGML_TENSOR_BINARY_OP_LOCALS
11998
11999    const int ith = params->ith;
12000    const int nth = params->nth;
12001
12002    const int64_t n = ne10;
12003    GGML_ASSERT((n & (n - 1)) == 0); // must be power of 2
12004
12005    const int64_t nr = ne11 * ne12 * ne13;
12006    const int64_t rows_per_thread = (nr + nth - 1) / nth;
12007    const int64_t start_row = ith * rows_per_thread;
12008    const int64_t end_row = MIN(start_row + rows_per_thread, nr);
12009
12010    const float scale = 1.0f / sqrtf((float)n);
12011
12012#if defined(GGML_SIMD)
12013    const GGML_F32_VEC v_minus_one = GGML_F32_VEC_SET1(-1.0f);
12014#endif
12015
12016    for (int64_t r = start_row; r < end_row; r++) {
12017        const int64_t i13 = r / (ne11 * ne12);
12018        const int64_t i12 = (r - i13 * ne11 * ne12) / ne11;
12019        const int64_t i11 = r - i13 * ne11 * ne12 - i12 * ne11;
12020
12021        const float * src_row = (const float *) ((const char *) src1->data + i11 * nb11 + i12 * nb12 + i13 * nb13);
12022        float * dst_row = (float *) ((char *) dst->data + i11 * nb1 + i12 * nb2 + i13 * nb3);
12023
12024        for (int64_t j = 0; j < n; j++) {
12025            dst_row[j] = src_row[j] * scale;
12026        }
12027
12028        // Scalar passes
12029#if defined(GGML_SIMD)
12030#if defined(__ARM_FEATURE_SVE)
12031        const int step = svcntw();
12032#else
12033        const int step = GGML_F32_EPR;
12034#endif
12035#else
12036        const int step = n;
12037#endif
12038        for (int64_t len = 1; len < step && len < n; len <<= 1) {
12039            for (int64_t i = 0; i < n; i += 2 * len) {
12040                for (int64_t j = 0; j < len; j++) {
12041                    float u = dst_row[i + j];
12042                    float v = dst_row[i + len + j];
12043                    dst_row[i + j] = u + v;
12044                    dst_row[i + len + j] = u - v;
12045                }
12046            }
12047        }
12048
12049        // SIMD passes using GGML_F32_VEC_* macros for multi-architecture support
12050#if defined(GGML_SIMD)
12051        for (int64_t len = step; len < n; len <<= 1) {
12052            for (int64_t i = 0; i < n; i += 2 * len) {
12053                for (int64_t j = 0; j < len; j += step) {
12054                    GGML_F32_VEC u = GGML_F32_VEC_LOAD(dst_row + i + j);
12055                    GGML_F32_VEC v = GGML_F32_VEC_LOAD(dst_row + i + len + j);
12056
12057                    GGML_F32_VEC_STORE(dst_row + i + j,       GGML_F32_VEC_ADD(u, v));
12058                    GGML_F32_VEC_STORE(dst_row + i + len + j, GGML_F32_VEC_FMA(u, v, v_minus_one));
12059                }
12060            }
12061        }
12062#endif
12063    }
12064}
12065
12066void ggml_compute_forward_fwht(const ggml_compute_params * params, ggml_tensor * dst) {
12067    const ggml_tensor * src1 = dst->src[1];
12068
12069    switch (src1->type) {
12070        case GGML_TYPE_F32:
12071            {
12072                ggml_compute_forward_fwht_f32(params, dst);
12073            }
12074            break;
12075        default:
12076            {
12077                GGML_ABORT("fatal error - fwht is F32 only");
12078            }
12079    }
12080}
12081
12082// ggml_compute_forward_lightning_indexer
12083
12084void ggml_compute_forward_lightning_indexer(
12085        const ggml_compute_params * params,
12086        ggml_tensor * dst) {
12087
12088    const ggml_tensor * q = dst->src[0];
12089    const ggml_tensor * k = dst->src[1];
12090    const ggml_tensor * w = dst->src[2]; // weights
12091    const ggml_tensor * m = dst->src[3]; // mask
12092
12093    GGML_ASSERT(dst->type  == GGML_TYPE_F32);
12094    GGML_ASSERT(   q->type == GGML_TYPE_F32);
12095    GGML_ASSERT(   w->type == GGML_TYPE_F32);
12096    GGML_ASSERT(   m->type == GGML_TYPE_F16);
12097
12098    GGML_TENSOR_LOCALS(int64_t, neq,  q, ne)
12099    GGML_TENSOR_LOCALS(size_t,  nbq,  q, nb)
12100    GGML_TENSOR_LOCALS(int64_t, nek,  k, ne)
12101    GGML_TENSOR_LOCALS(size_t,  nbk,  k, nb)
12102    GGML_TENSOR_LOCALS(int64_t, new,  w, ne)
12103    GGML_TENSOR_LOCALS(size_t,  nbw,  w, nb)
12104    GGML_TENSOR_LOCALS(int64_t, nem,  m, ne)
12105    GGML_TENSOR_LOCALS(size_t,  nbm,  m, nb)
12106    GGML_TENSOR_LOCALS(int64_t, ne, dst, ne)
12107    GGML_TENSOR_LOCALS(size_t,  nb, dst, nb)
12108
12109    GGML_ASSERT( nb0 == ggml_type_size(dst->type));
12110    GGML_ASSERT(nbq0 == ggml_type_size(  q->type));
12111    GGML_ASSERT(nbk0 == ggml_type_size(  k->type));
12112    GGML_ASSERT(nbw0 == ggml_type_size(  w->type));
12113    GGML_ASSERT(nbm0 == ggml_type_size(  m->type));
12114
12115    const int n_embd    = q->ne[0];
12116    const int n_head    = q->ne[1];
12117    const int n_tokens  = q->ne[2];
12118    const int n_stream  = q->ne[3];
12119    const int n_kv      = k->ne[2];
12120
12121    ggml_to_float_t const k_to_float = ggml_get_type_traits(k->type)->to_float;
12122    GGML_ASSERT((k->type == GGML_TYPE_F32 || k_to_float) && "lightning indexer: unsupported K-type");
12123
12124    const int nr  = n_kv;
12125    const int ith = params->ith;
12126    const int nth = params->nth;
12127
12128    // (temporary) buffer for K converted to float
12129    float * k_row_f32 = (float *) params->wdata + ith*(1*n_embd + CACHE_LINE_SIZE_F32);
12130
12131    // rows per thread
12132    const int dr = (nr + nth - 1)/nth;
12133
12134    // row range for this thread
12135    const int ir0 = dr*ith;
12136    const int ir1 = MIN(ir0 + dr, nr);
12137
12138    for (int s = 0; s < n_stream; ++s) {
12139        for (int t = 0; t < n_tokens; ++t) {
12140            const float       *   w_row =       (float *) ((char *)   w->data + t*nbw1 +        s*nbw3);
12141            const ggml_fp16_t *   m_row = (ggml_fp16_t *) ((char *)   m->data + t*nbm1 + (s%nem3)*nbm3);
12142            float             * dst_row =       (float *) ((char *) dst->data + t*nb1  +        s*nb3 );
12143            for (int ik = ir0; ik < ir1; ++ik) {
12144                char * k_row = (char *) k->data + ik*nbk2 + s*nbk3;
12145                if (k_to_float) {
12146                    k_to_float(k_row, k_row_f32, n_embd);
12147                } else {
12148                    k_row_f32 = (float *) k_row;
12149                }
12150                float score = 0.0f;
12151                for (int h = 0; h < n_head; ++h) {
12152                    // dot product of q and k for head h
12153                    float qk = 0.0f;
12154                    const float * q_row = (float *) ((char *) q->data + h*nbq1 + t*nbq2 + s*nbq3);
12155                    ggml_vec_dot_f32(n_embd, &qk, 0, q_row, 0, k_row_f32, 0, 1);
12156                    // ReLU and weights (prescaled)
12157                    score += MAX(qk, 0.0f) * w_row[h];
12158                }
12159                // apply mask
12160                dst_row[ik] = score + GGML_CPU_FP16_TO_FP32(m_row[ik]);
12161            }
12162        }
12163    }
12164}