char-fork/llama.cpp

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

Xuan-Son Nguyenggml: add ggml_rope_set_offset (+ metal support) (#27120)fe8156f78

char/aliceai-t5-moe
43.5 KiB941 linesraw
1#include "convert.cuh"
2#include "ggml-cuda/common.cuh"
3#include "ggml.h"
4#include "rope.cuh"
5
6struct rope_corr_dims {
7    float v[2];
8};
9
10
11struct mrope_sections {
12    int v[4];
13};
14
15static __device__ float rope_yarn_ramp(const float low, const float high, const int i0) {
16    const float y = (i0 / 2 - low) / max(0.001f, high - low);
17    return 1.0f - min(1.0f, max(0.0f, y));
18}
19
20// YaRN algorithm based on LlamaYaRNScaledRotaryEmbedding.py from https://github.com/jquesnelle/yarn
21// MIT licensed. Copyright (c) 2023 Jeffrey Quesnelle and Bowen Peng.
22template<bool forward>
23static __device__ void rope_yarn(
24        const float theta_extrap, const float freq_scale, const rope_corr_dims corr_dims, const int64_t i0, const float ext_factor,
25        float mscale, float & cos_theta, float & sin_theta) {
26    // Get n-d rotational scaling corrected for extrapolation
27    float theta_interp = freq_scale * theta_extrap;
28    float theta = theta_interp;
29    if (ext_factor != 0.0f) {
30        float ramp_mix = rope_yarn_ramp(corr_dims.v[0], corr_dims.v[1], i0) * ext_factor;
31        theta = theta_interp * (1 - ramp_mix) + theta_extrap * ramp_mix;
32
33        // Get n-d magnitude scaling corrected for interpolation
34        mscale *= 1.0f + 0.1f * logf(1.0f / freq_scale);
35    }
36    cos_theta = cosf(theta) * mscale;
37    sin_theta = sinf(theta) * mscale;
38    if (!forward) {
39        sin_theta *= -1.0f;
40    }
41}
42
43template <bool forward, bool has_ff, typename T, typename D>
44static __global__ void rope_norm(const T *            x,
45                                 D *                  dst,
46                                 const int            ne00,
47                                 const int            ne01,
48                                 const int            ne02,
49                                 const int            s01,
50                                 const int            s02,
51                                 const int            s03,
52                                 const int            s1,
53                                 const int            s2,
54                                 const int            s3,
55                                 const int            n_dims,
56                                 const int            n_offs,
57                                 const int32_t *      pos,
58                                 const float          freq_scale,
59                                 const float          ext_factor,
60                                 const float          attn_factor,
61                                 const rope_corr_dims corr_dims,
62                                 const float          theta_scale,
63                                 const float *        freq_factors,
64                                 const int64_t *      row_indices,
65                                 const int            set_rows_stride,
66                                 const bool           inplace) {
67    const int i0 = 2*(blockDim.y*blockIdx.y + threadIdx.y);
68
69    if (i0 >= ne00) {
70        return;
71    }
72
73    const int row_dst = blockDim.x*blockIdx.x + threadIdx.x;
74
75    const uint32_t i3 = row_dst / (ne01 * ne02);
76    const uint32_t i2 = (row_dst - i3 * ne01 * ne02) / ne01;
77    const uint32_t i1 = row_dst - i3 * ne01 * ne02 - i2 * ne01;
78
79    int       idst = i0 + i1 * s1  + i2 * s2  + i3 * s3;
80    const int ix   = i0 + i1 * s01 + i2 * s02 + i3 * s03;
81    // Fusion optimization: ROPE + VIEW + SET_ROWS.
82    // The rope output is viewed as a 1D tensor and offset based on a row index in row_indices.
83    if (set_rows_stride != 0) {
84        idst = i1 * s1 + i0;
85        idst += row_indices[i2] * set_rows_stride;
86    }
87
88    const auto & store_coaelsced = [&](float x0, float x1) {
89        if constexpr (std::is_same_v<float, D>) {
90            float2 v = make_float2(x0, x1);
91            ggml_cuda_memcpy_1<8>(dst + idst, &v);
92        } else if constexpr (std::is_same_v<half, D>) {
93            half2 v = make_half2(x0, x1);
94            ggml_cuda_memcpy_1<4>(dst + idst, &v);
95        }
96    };
97    if (i0 < n_offs || i0 >= n_offs + n_dims) {
98        if (inplace) {
99            return;
100        }
101        store_coaelsced(x[ix + 0], x[ix + 1]);
102        return;
103    }
104
105    const int iw = i0 - n_offs; // relative idx
106
107    const float theta_base = pos[i2]*powf(theta_scale, iw/2.0f);
108
109    const float freq_factor = has_ff ? freq_factors[iw/2] : 1.0f;
110
111    float cos_theta;
112    float sin_theta;
113
114    rope_yarn<forward>(theta_base/freq_factor, freq_scale, corr_dims, iw, ext_factor, attn_factor, cos_theta, sin_theta);
115
116    const float x0 = x[ix + 0];
117    const float x1 = x[ix + 1];
118
119    store_coaelsced(x0 * cos_theta - x1 * sin_theta, x0 * sin_theta + x1 * cos_theta);
120}
121
122template <bool forward, bool has_ff, typename T, typename D>
123static __global__ void rope_neox(const T *            x,
124                                 D *                  dst,
125                                 const int            ne00,
126                                 const int            ne01,
127                                 const int            ne02,
128                                 const int            s01,
129                                 const int            s02,
130                                 const int            s03,
131                                 const int            s1,
132                                 const int            s2,
133                                 const int            s3,
134                                 const int            n_dims,
135                                 const int            n_offs,
136                                 const int32_t *      pos,
137                                 const float          freq_scale,
138                                 const float          ext_factor,
139                                 const float          attn_factor,
140                                 const rope_corr_dims corr_dims,
141                                 const float          theta_scale,
142                                 const float *        freq_factors,
143                                 const int64_t *      row_indices,
144                                 const int            set_rows_stride,
145                                 const bool           inplace) {
146    ggml_cuda_pdl_lc();
147    const int i0 = 2*(blockDim.y*blockIdx.y + threadIdx.y);
148
149    if (i0 >= ne00) {
150        return;
151    }
152
153    const int row_dst = blockDim.x*blockIdx.x + threadIdx.x;
154
155    const uint32_t i3 = row_dst / (ne01 * ne02);
156    const uint32_t i2 = (row_dst - i3 * ne01 * ne02) / ne01;
157    const uint32_t i1 = row_dst - i3 * ne01 * ne02 - i2 * ne01;
158
159    int       idst = i0 / 2 + i1 * s1  + i2 * s2  + i3 * s3;
160    const int ix   = i0 / 2 + i1 * s01 + i2 * s02 + i3 * s03;
161    ggml_cuda_pdl_sync();
162
163    // Fusion optimization: ROPE + VIEW + SET_ROWS.
164    // The rope output is viewed as a 1D tensor and offset based on a row index in row_indices.
165    if (set_rows_stride != 0) {
166        idst = i1 * s1 + i0 / 2;
167        idst += row_indices[i2] * set_rows_stride;
168    }
169
170    if (i0 < n_offs || i0 >= n_offs + n_dims) {
171        if (inplace) {
172            return;
173        }
174        dst[idst + i0 / 2 + 0] = ggml_cuda_cast<D>(x[ix + i0 / 2 + 0]);
175        dst[idst + i0 / 2 + 1] = ggml_cuda_cast<D>(x[ix + i0 / 2 + 1]);
176
177        return;
178    }
179
180    const int iw = i0 - n_offs; // relative idx
181
182    const float theta_base = pos[i2]*powf(theta_scale, iw/2.0f);
183
184    const float freq_factor = has_ff ? freq_factors[iw/2] : 1.0f;
185
186    float cos_theta;
187    float sin_theta;
188
189    rope_yarn<forward>(theta_base/freq_factor, freq_scale, corr_dims, iw, ext_factor, attn_factor, cos_theta, sin_theta);
190
191    // idst/ix point at channel i0/2; the first channel of the rotated pair is n_offs + iw/2 = i0/2 + n_offs/2
192    const float x0 = x[ix + n_offs/2 + 0];
193    const float x1 = x[ix + n_offs/2 + n_dims/2];
194
195    dst[idst + n_offs/2 + 0]          = ggml_cuda_cast<D>(x0 * cos_theta - x1 * sin_theta);
196    dst[idst + n_offs/2 + n_dims / 2] = ggml_cuda_cast<D>(x0 * sin_theta + x1 * cos_theta);
197}
198
199template <bool forward, bool has_ff, typename T>
200static __global__ void rope_multi(const T *            x,
201                                  T *                  dst,
202                                  const int            ne00,
203                                  const int            ne01,
204                                  const int            ne02,
205                                  const int            s01,
206                                  const int            s02,
207                                  const int            s03,
208                                  const int            s1,
209                                  const int            s2,
210                                  const int            s3,
211                                  const int            n_dims,
212                                  const int            n_offs,
213                                  const int32_t *      pos,
214                                  const float          freq_scale,
215                                  const float          ext_factor,
216                                  const float          attn_factor,
217                                  const rope_corr_dims corr_dims,
218                                  const float          theta_scale,
219                                  const float *        freq_factors,
220                                  const mrope_sections sections,
221                                  const bool           is_imrope,
222                                  const bool           inplace) {
223    const int i0 = 2 * (blockDim.y * blockIdx.y + threadIdx.y);
224
225    if (i0 >= ne00) {
226        return;
227    }
228
229    const int row_dst = blockDim.x*blockIdx.x + threadIdx.x;
230
231    const uint32_t i3 = row_dst / (ne01 * ne02);
232    const uint32_t i2 = (row_dst - i3 * ne01 * ne02) / ne01;
233    const uint32_t i1 = row_dst - i3 * ne01 * ne02 - i2 * ne01;
234
235    int       idst = i0 / 2 + i1 * s1  + i2 * s2  + i3 * s3;
236    const int ix   = i0 / 2 + i1 * s01 + i2 * s02 + i3 * s03;
237
238    ggml_cuda_pdl_sync();
239    if (i0 < n_offs || i0 >= n_offs + n_dims) {
240        if (inplace) {
241            return;
242        }
243        dst[idst + i0/2 + 0] = x[ix + i0/2 + 0];
244        dst[idst + i0/2 + 1] = x[ix + i0/2 + 1];
245
246        return;
247    }
248
249    const int iw = i0 - n_offs; // relative idx
250
251    const int sect_dims = sections.v[0] + sections.v[1] + sections.v[2] + sections.v[3];
252    const int sec_w = sections.v[1] + sections.v[0];
253    const int sector = (iw / 2) % sect_dims;
254
255    float theta_base = 0.0;
256    if (is_imrope) {
257        if (sector % 3 == 1 && sector < 3 * sections.v[1]) {         // h
258            theta_base = pos[i2 + ne02 * 1] * powf(theta_scale, iw / 2.0f);
259        } else if (sector % 3 == 2 && sector < 3 * sections.v[2]) {  // w
260            theta_base = pos[i2 + ne02 * 2] * powf(theta_scale, iw / 2.0f);
261        } else if (sector % 3 == 0 && sector < 3 * sections.v[0]) {  // t
262            theta_base = pos[i2] * powf(theta_scale, iw / 2.0f);
263        } else {
264            theta_base = pos[i2 + ne02 * 3] * powf(theta_scale, iw / 2.0f);
265        }
266    } else {
267        if (sector < sections.v[0]) {
268            theta_base = pos[i2] * powf(theta_scale, iw / 2.0f);
269        } else if (sector >= sections.v[0] && sector < sec_w) {
270            theta_base = pos[i2 + ne02 * 1] * powf(theta_scale, iw / 2.0f);
271        } else if (sector >= sec_w && sector < sec_w + sections.v[2]) {
272            theta_base = pos[i2 + ne02 * 2] * powf(theta_scale, iw / 2.0f);
273        } else if (sector >= sec_w + sections.v[2]) {
274            theta_base = pos[i2 + ne02 * 3] * powf(theta_scale, iw / 2.0f);
275        }
276    }
277
278    const float freq_factor = has_ff ? freq_factors[iw/2] : 1.0f;
279
280    float cos_theta;
281    float sin_theta;
282
283    rope_yarn<forward>(theta_base/freq_factor, freq_scale, corr_dims, iw, ext_factor, attn_factor, cos_theta, sin_theta);
284
285    // idst/ix point at channel i0/2; the first channel of the rotated pair is n_offs + iw/2 = i0/2 + n_offs/2
286    const float x0 = x[ix + n_offs/2 + 0];
287    const float x1 = x[ix + n_offs/2 + n_dims/2];
288
289    dst[idst + n_offs/2 + 0]        = x0*cos_theta - x1*sin_theta;
290    dst[idst + n_offs/2 + n_dims/2] = x0*sin_theta + x1*cos_theta;
291}
292
293template <bool forward, bool has_ff, typename T>
294static __global__ void rope_vision(const T *            x,
295                                   T *                  dst,
296                                   const int            ne00,
297                                   const int            ne01,
298                                   const int            ne02,
299                                   const int            s01,
300                                   const int            s02,
301                                   const int            s03,
302                                   const int            s1,
303                                   const int            s2,
304                                   const int            s3,
305                                   const int            n_dims,
306                                   const int32_t *      pos,
307                                   const float          freq_scale,
308                                   const float          ext_factor,
309                                   const float          attn_factor,
310                                   const rope_corr_dims corr_dims,
311                                   const float          theta_scale,
312                                   const float *        freq_factors,
313                                   const mrope_sections sections) {
314    const int i0 = 2*(blockDim.y*blockIdx.y + threadIdx.y);
315
316    if (i0 >= ne00) {
317        return;
318    }
319
320    const int row_dst = blockDim.x*blockIdx.x + threadIdx.x;
321
322    const uint32_t i3 = row_dst / (ne01 * ne02);
323    const uint32_t i2 = (row_dst - i3 * ne01 * ne02) / ne01;
324    const uint32_t i1 = row_dst - i3 * ne01 * ne02 - i2 * ne01;
325
326    int       idst = i0 / 2 + i1 * s1  + i2 * s2  + i3 * s3;
327    const int ix   = i0 / 2 + i1 * s01 + i2 * s02 + i3 * s03;
328
329    ggml_cuda_pdl_sync();
330    const int sect_dims = sections.v[0] + sections.v[1];
331    const int sec_w     = sections.v[1] + sections.v[0];
332    const int sector    = (i0 / 2) % sect_dims;
333
334    float theta_base = 0.0;
335    if (sector < sections.v[0]) {
336        const int p = sector;
337        theta_base  = pos[i2] * powf(theta_scale, p);
338    } else if (sector >= sections.v[0] && sector < sec_w) {
339        const int p = sector - sections.v[0];
340        theta_base  = pos[i2 + ne02] * powf(theta_scale, p);
341    }
342
343    const float freq_factor = has_ff ? freq_factors[i0/2] : 1.0f;
344
345    float cos_theta;
346    float sin_theta;
347
348    rope_yarn<forward>(theta_base/freq_factor, freq_scale, corr_dims, i0, ext_factor, attn_factor, cos_theta, sin_theta);
349
350    const float x0 = x[ix + 0];
351    const float x1 = x[ix + n_dims];
352
353    dst[idst + 0]      = x0*cos_theta - x1*sin_theta;
354    dst[idst + n_dims] = x0*sin_theta + x1*cos_theta;
355}
356
357template <bool forward, typename T, typename D>
358static void rope_norm_cuda(const T *            x,
359                           D *                  dst,
360                           const int            ne00,
361                           const int            ne01,
362                           const int            ne02,
363                           const int            s01,
364                           const int            s02,
365                           const int            s03,
366                           const int            s1,
367                           const int            s2,
368                           const int            s3,
369                           const int            n_dims,
370                           const int            n_offs,
371                           const int            nr,
372                           const int32_t *      pos,
373                           const float          freq_scale,
374                           const float          freq_base,
375                           const float          ext_factor,
376                           const float          attn_factor,
377                           const rope_corr_dims corr_dims,
378                           const float *        freq_factors,
379                           const int64_t *      row_indices,
380                           const int            set_rows_stride,
381                           const bool           inplace,
382                           cudaStream_t         stream) {
383    GGML_ASSERT(ne00 % 2 == 0);
384    const dim3 block_dims(1, CUDA_ROPE_BLOCK_SIZE, 1);
385    const int  n_blocks_x = (ne00 + 2 * CUDA_ROPE_BLOCK_SIZE - 1) / (2 * CUDA_ROPE_BLOCK_SIZE);
386    const dim3 block_nums(nr, n_blocks_x, 1);
387
388    const float theta_scale = powf(freq_base, -2.0f / n_dims);
389
390    if (freq_factors == nullptr) {
391        rope_norm<forward, false><<<block_nums, block_dims, 0, stream>>>(
392            x, dst, ne00, ne01, ne02, s01, s02, s03, s1, s2, s3, n_dims, n_offs, pos, freq_scale, ext_factor,
393            attn_factor, corr_dims, theta_scale, freq_factors, row_indices, set_rows_stride, inplace);
394    } else {
395        rope_norm<forward, true><<<block_nums, block_dims, 0, stream>>>(
396            x, dst, ne00, ne01, ne02, s01, s02, s03, s1, s2, s3, n_dims, n_offs, pos, freq_scale, ext_factor,
397            attn_factor, corr_dims, theta_scale, freq_factors, row_indices, set_rows_stride, inplace);
398    }
399}
400
401template <bool forward, typename T, typename D>
402static void rope_neox_cuda(const T *            x,
403                           D *                  dst,
404                           const int            ne00,
405                           const int            ne01,
406                           const int            ne02,
407                           const int            s01,
408                           const int            s02,
409                           const int            s03,
410                           const int            s1,
411                           const int            s2,
412                           const int            s3,
413                           const int            n_dims,
414                           const int            n_offs,
415                           const int            nr,
416                           const int32_t *      pos,
417                           const float          freq_scale,
418                           const float          freq_base,
419                           const float          ext_factor,
420                           const float          attn_factor,
421                           const rope_corr_dims corr_dims,
422                           const float *        freq_factors,
423                           const int64_t *      row_indices,
424                           const int            set_rows_stride,
425                           const bool           inplace,
426                           cudaStream_t         stream) {
427    GGML_ASSERT(ne00 % 2 == 0);
428    const dim3 block_dims(1, CUDA_ROPE_BLOCK_SIZE, 1);
429    const int  n_blocks_x = (ne00 + 2 * CUDA_ROPE_BLOCK_SIZE - 1) / (2 * CUDA_ROPE_BLOCK_SIZE);
430    const dim3 block_nums(nr, n_blocks_x, 1);
431
432    const float theta_scale = powf(freq_base, -2.0f / n_dims);
433    const ggml_cuda_kernel_launch_params launch_params = {block_nums, block_dims, 0, stream};
434
435    if (freq_factors == nullptr) {
436        ggml_cuda_kernel_launch(rope_neox<forward, false, T, D>, launch_params,
437            x, dst, ne00, ne01, ne02, s01, s02, s03, s1, s2, s3, n_dims, n_offs, pos, freq_scale, ext_factor,
438            attn_factor, corr_dims, theta_scale, freq_factors, row_indices, set_rows_stride, inplace);
439    } else {
440        ggml_cuda_kernel_launch(rope_neox<forward, true, T, D>, launch_params,
441            x, dst, ne00, ne01, ne02, s01, s02, s03, s1, s2, s3, n_dims, n_offs, pos, freq_scale, ext_factor,
442            attn_factor, corr_dims, theta_scale, freq_factors, row_indices, set_rows_stride, inplace);
443    }
444}
445
446template <bool forward, typename T>
447static void rope_multi_cuda(const T *            x,
448                            T *                  dst,
449                            const int            ne00,
450                            const int            ne01,
451                            const int            ne02,
452                            const int            s01,
453                            const int            s02,
454                            const int            s03,
455                            const int            s1,
456                            const int            s2,
457                            const int            s3,
458                            const int            n_dims,
459                            const int            n_offs,
460                            const int            nr,
461                            const int32_t *      pos,
462                            const float          freq_scale,
463                            const float          freq_base,
464                            const float          ext_factor,
465                            const float          attn_factor,
466                            const rope_corr_dims corr_dims,
467                            const float *        freq_factors,
468                            const mrope_sections sections,
469                            const bool           is_imrope,
470                            const bool           inplace,
471                            cudaStream_t         stream) {
472    GGML_ASSERT(ne00 % 2 == 0);
473    const dim3 block_dims(1, CUDA_ROPE_BLOCK_SIZE, 1);
474    const int  n_blocks_x = (ne00 + 2 * CUDA_ROPE_BLOCK_SIZE - 1) / (2 * CUDA_ROPE_BLOCK_SIZE);
475    const dim3 block_nums(nr, n_blocks_x, 1);
476
477    const float theta_scale = powf(freq_base, -2.0f / n_dims);
478
479    if (freq_factors == nullptr) {
480        const ggml_cuda_kernel_launch_params launch_params = ggml_cuda_kernel_launch_params(block_nums, block_dims, 0, stream);
481        ggml_cuda_kernel_launch(rope_multi<forward, false, T>, launch_params,
482            x, dst, ne00, ne01, ne02, s01, s02, s03, s1, s2, s3, n_dims, n_offs, pos, freq_scale, ext_factor,
483            attn_factor, corr_dims, theta_scale, freq_factors, sections, is_imrope, inplace);
484    } else {
485        const ggml_cuda_kernel_launch_params launch_params = ggml_cuda_kernel_launch_params(block_nums, block_dims, 0, stream);
486        ggml_cuda_kernel_launch(rope_multi<forward, true, T>, launch_params,
487            x, dst, ne00, ne01, ne02, s01, s02, s03, s1, s2, s3, n_dims, n_offs, pos, freq_scale, ext_factor,
488            attn_factor, corr_dims, theta_scale, freq_factors, sections, is_imrope, inplace);
489    }
490}
491
492template <bool forward, typename T>
493static void rope_vision_cuda(const T *            x,
494                             T *                  dst,
495                             const int            ne00,
496                             const int            ne01,
497                             const int            ne02,
498                             const int            s01,
499                             const int            s02,
500                             const int            s03,
501                             const int            s1,
502                             const int            s2,
503                             const int            s3,
504                             const int            n_dims,
505                             const int            nr,
506                             const int32_t *      pos,
507                             const float          freq_scale,
508                             const float          freq_base,
509                             const float          ext_factor,
510                             const float          attn_factor,
511                             const rope_corr_dims corr_dims,
512                             const float *        freq_factors,
513                             const mrope_sections sections,
514                             cudaStream_t         stream) {
515    GGML_ASSERT(ne00 % 2 == 0);
516    const dim3 block_dims(1, CUDA_ROPE_BLOCK_SIZE, 1);
517    const int  n_blocks_x = (ne00 + 2 * CUDA_ROPE_BLOCK_SIZE - 1) / (2 * CUDA_ROPE_BLOCK_SIZE);
518    const dim3 block_nums(nr, n_blocks_x, 1);
519    // break down (head_dim, heads, seq) into (CUDA_ROPE_BLOCK_SIZE, x, heads * seq)
520    // where x ~= ceil(head_dim / CUDA_ROPE_BLOCK_SIZE);
521
522    const float theta_scale = powf(freq_base, -2.0f/n_dims);
523
524    if (freq_factors == nullptr) {
525        rope_vision<forward, false, T><<<block_nums, block_dims, 0, stream>>>(
526            x, dst, ne00, ne01, ne02, s01, s02, s03, s1, s2, s3, n_dims, pos, freq_scale, ext_factor,
527            attn_factor, corr_dims, theta_scale, freq_factors, sections);
528    } else {
529        rope_vision<forward, true, T><<<block_nums, block_dims, 0, stream>>>(
530            x, dst, ne00, ne01, ne02, s01, s02, s03, s1, s2, s3, n_dims, pos, freq_scale, ext_factor,
531            attn_factor, corr_dims, theta_scale, freq_factors, sections);
532    }
533}
534
535template <bool forward>
536void ggml_cuda_op_rope_impl(ggml_backend_cuda_context & ctx,
537                            ggml_tensor *               dst,
538                            const ggml_tensor *         set_rows = nullptr) {
539    const ggml_tensor * src0 = dst->src[0];
540    const ggml_tensor * src1 = dst->src[1];
541    const ggml_tensor * src2 = dst->src[2];
542
543    const float * src0_d = (const float *)src0->data;
544    const float * src1_d = (const float *)src1->data;
545
546    void *          dst_d           = dst->data;
547    const int64_t * row_indices     = nullptr;
548    ggml_type       dst_type        = dst->type;
549    int             set_rows_stride = 0;
550
551    if (set_rows != nullptr) {
552        GGML_ASSERT(forward);
553        dst_d           = set_rows->data;
554        row_indices     = (const int64_t *) set_rows->src[1]->data;
555        dst_type        = set_rows->type;
556        set_rows_stride = set_rows->nb[1] / ggml_type_size(set_rows->type);
557    }
558    cudaStream_t stream = ctx.stream();
559
560    GGML_ASSERT(src0->type == GGML_TYPE_F32 || src0->type == GGML_TYPE_F16);
561    GGML_ASSERT( dst->type == GGML_TYPE_F32 ||  dst->type == GGML_TYPE_F16);
562    // When not fused, src0 and dst types must match
563    // When fused (ROPE+VIEW+SET_ROWS), src0 may be F32 and dst may be F16
564    GGML_ASSERT(src0->type == dst->type || (src0->type == GGML_TYPE_F32 && dst->type == GGML_TYPE_F16));
565
566    const int64_t ne00 = src0->ne[0]; // head dims
567    const int64_t ne01 = src0->ne[1]; // num heads
568    const int64_t ne02 = src0->ne[2]; // num heads
569    const int64_t nr = ggml_nrows(src0);
570
571    const size_t s01 = src0->nb[1] / ggml_type_size(src0->type);
572    const size_t s02 = src0->nb[2] / ggml_type_size(src0->type);
573    const size_t s03 = src0->nb[3] / ggml_type_size(src0->type);
574
575    const size_t s1 = dst->nb[1] / ggml_type_size(dst->type);
576    const size_t s2 = dst->nb[2] / ggml_type_size(dst->type);
577    const size_t s3 = dst->nb[3] / ggml_type_size(dst->type);
578
579    //const int n_past     = ((int32_t *) dst->op_params)[0];
580    const int n_dims     = ((int32_t *) dst->op_params)[1];
581    const int mode       = ((int32_t *) dst->op_params)[2];
582    //const int n_ctx      = ((int32_t *) dst->op_params)[3];
583    const int n_ctx_orig = ((int32_t *) dst->op_params)[4];
584    const int n_offs     = ((int32_t *) dst->op_params)[15];
585    mrope_sections sections;
586
587    // when dst aliases src0, the channels outside the rotated window already hold the correct data
588    const bool inplace = dst_d == src0->data;
589
590    // RoPE alteration for extended context
591    float freq_base;
592    float freq_scale;
593    float ext_factor;
594    float attn_factor;
595    float beta_fast;
596    float beta_slow;
597
598    memcpy(&freq_base,   (int32_t *) dst->op_params +  5, sizeof(float));
599    memcpy(&freq_scale,  (int32_t *) dst->op_params +  6, sizeof(float));
600    memcpy(&ext_factor,  (int32_t *) dst->op_params +  7, sizeof(float));
601    memcpy(&attn_factor, (int32_t *) dst->op_params +  8, sizeof(float));
602    memcpy(&beta_fast,   (int32_t *) dst->op_params +  9, sizeof(float));
603    memcpy(&beta_slow,   (int32_t *) dst->op_params + 10, sizeof(float));
604    memcpy(&sections.v,  (int32_t *) dst->op_params + 11, sizeof(int)*4);
605
606    const bool is_neox = mode & GGML_ROPE_TYPE_NEOX;
607    const bool is_mrope = mode & GGML_ROPE_TYPE_MROPE;
608    const bool is_imrope = mode == GGML_ROPE_TYPE_IMROPE;
609    const bool is_vision = mode == GGML_ROPE_TYPE_VISION;
610
611    if (is_mrope) {
612        GGML_ASSERT(sections.v[0] > 0 || sections.v[1] > 0 || sections.v[2] > 0);
613    }
614
615    if (is_vision) {
616        GGML_ASSERT(n_dims == ne00/2);
617        GGML_ASSERT(n_offs == 0); // offset not supported for vision, as the rotated pairs span the whole row
618    }
619
620    const int32_t * pos = (const int32_t *) src1_d;
621
622    const float * freq_factors = nullptr;
623    if (src2 != nullptr) {
624        freq_factors = (const float *) src2->data;
625    }
626
627    rope_corr_dims corr_dims;
628    ggml_rope_yarn_corr_dims(n_dims, n_ctx_orig, freq_base, beta_fast, beta_slow, corr_dims.v);
629
630    // compute
631    if (is_neox) {
632        if (src0->type == GGML_TYPE_F32 && dst_type == GGML_TYPE_F32) {
633            rope_neox_cuda<forward, float, float>((const float *) src0_d, (float *) dst_d, ne00, ne01, ne02, s01, s02,
634                                                  s03, s1, s2, s3, n_dims, n_offs, nr, pos, freq_scale, freq_base,
635                                                  ext_factor, attn_factor, corr_dims, freq_factors, row_indices,
636                                                  set_rows_stride, inplace, stream);
637        } else if (src0->type == GGML_TYPE_F32 && dst_type == GGML_TYPE_F16) {
638            rope_neox_cuda<forward, float, half>((const float *) src0_d, (half *) dst_d, ne00, ne01, ne02, s01, s02,
639                                                 s03, s1, s2, s3, n_dims, n_offs, nr, pos, freq_scale, freq_base,
640                                                 ext_factor, attn_factor, corr_dims, freq_factors, row_indices,
641                                                 set_rows_stride, inplace, stream);
642        } else if (src0->type == GGML_TYPE_F16 && dst_type == GGML_TYPE_F16) {
643            rope_neox_cuda<forward, half, half>((const half *) src0_d, (half *) dst_d, ne00, ne01, ne02, s01, s02,
644                                                s03, s1, s2, s3, n_dims, n_offs, nr, pos, freq_scale, freq_base,
645                                                ext_factor, attn_factor, corr_dims, freq_factors, row_indices,
646                                                set_rows_stride, inplace, stream);
647        } else {
648            GGML_ABORT("fatal error");
649        }
650    } else if (is_mrope && !is_vision) {
651        if (src0->type == GGML_TYPE_F32) {
652            rope_multi_cuda<forward>((const float *) src0_d, (float *) dst_d, ne00, ne01, ne02, s01, s02, s03, s1,
653                                     s2, s3, n_dims, n_offs, nr, pos, freq_scale, freq_base, ext_factor, attn_factor,
654                                     corr_dims, freq_factors, sections, is_imrope, inplace, stream);
655        } else if (src0->type == GGML_TYPE_F16) {
656            rope_multi_cuda<forward>((const half *) src0_d, (half *) dst_d, ne00, ne01, ne02, s01, s02, s03, s1,
657                                     s2, s3, n_dims, n_offs, nr, pos, freq_scale, freq_base, ext_factor, attn_factor,
658                                     corr_dims, freq_factors, sections, is_imrope, inplace, stream);
659        } else {
660            GGML_ABORT("fatal error");
661        }
662    } else if (is_vision) {
663        if (src0->type == GGML_TYPE_F32) {
664            rope_vision_cuda<forward>((const float *) src0_d, (float *) dst_d, ne00, ne01, ne02, s01, s02, s03, s1,
665                                      s2, s3, n_dims, nr, pos, freq_scale, freq_base, ext_factor, attn_factor,
666                                      corr_dims, freq_factors, sections, stream);
667        } else if (src0->type == GGML_TYPE_F16) {
668            rope_vision_cuda<forward>((const half *) src0_d, (half *) dst_d, ne00, ne01, ne02, s01, s02, s03, s1,
669                                      s2, s3, n_dims, nr, pos, freq_scale, freq_base, ext_factor, attn_factor,
670                                      corr_dims, freq_factors, sections, stream);
671        } else {
672            GGML_ABORT("fatal error");
673        }
674    } else {
675        if (src0->type == GGML_TYPE_F32 && dst_type == GGML_TYPE_F32) {
676            rope_norm_cuda<forward, float, float>((const float *) src0_d, (float *) dst_d, ne00, ne01, ne02, s01, s02,
677                                                  s03, s1, s2, s3, n_dims, n_offs, nr, pos, freq_scale, freq_base,
678                                                  ext_factor, attn_factor, corr_dims, freq_factors, row_indices,
679                                                  set_rows_stride, inplace, stream);
680        } else if (src0->type == GGML_TYPE_F32 && dst_type == GGML_TYPE_F16) {
681            rope_norm_cuda<forward, float, half>((const float *) src0_d, (half *) dst_d, ne00, ne01, ne02, s01, s02,
682                                                 s03, s1, s2, s3, n_dims, n_offs, nr, pos, freq_scale, freq_base,
683                                                 ext_factor, attn_factor, corr_dims, freq_factors, row_indices,
684                                                 set_rows_stride, inplace, stream);
685        } else if (src0->type == GGML_TYPE_F16 && dst_type == GGML_TYPE_F16) {
686            rope_norm_cuda<forward, half, half>((const half *) src0_d, (half *) dst_d, ne00, ne01, ne02, s01, s02,
687                                                s03, s1, s2, s3, n_dims, n_offs, nr, pos, freq_scale, freq_base,
688                                                ext_factor, attn_factor, corr_dims, freq_factors, row_indices,
689                                                set_rows_stride, inplace, stream);
690        } else {
691            GGML_ABORT("fatal error");
692        }
693    }
694}
695
696void ggml_cuda_op_rope(ggml_backend_cuda_context & ctx, ggml_tensor * dst) {
697    ggml_cuda_op_rope_impl<true>(ctx, dst);
698}
699
700void ggml_cuda_op_rope_back(ggml_backend_cuda_context & ctx, ggml_tensor * dst) {
701    ggml_cuda_op_rope_impl<false>(ctx, dst);
702}
703
704void ggml_cuda_op_rope_fused(ggml_backend_cuda_context & ctx, ggml_tensor * rope, ggml_tensor * set_rows) {
705    ggml_cuda_op_rope_impl<true>(ctx, rope, set_rows);
706}
707
708// fused RMS_NORM + MUL + ROPE (+ VIEW + SET_ROWS)
709// one block per row: block_reduce gives the norm scale, then each thread applies mul and rope to the elements it owns
710template <int block_size, bool has_ff, typename D>
711static __global__ void rms_norm_mul_rope_f32(
712        const float * x, D * dst, const int ncols,
713        const int64_t s01, const int64_t s02, const int64_t s03,
714        const int64_t s1, const int64_t s2, const int64_t s3,
715        const float eps,
716        const float * mul,
717        const int64_t mul_s01, const int64_t mul_s02, const int64_t mul_s03,
718        const uint3 mul_ncols_packed, const uint3 mul_nrows_packed,
719        const uint3 mul_nchannels_packed, const uint3 mul_nsamples_packed,
720        const int n_dims, const int32_t * pos,
721        const float freq_scale, const float ext_factor, const float attn_factor,
722        const rope_corr_dims corr_dims, const float theta_scale,
723        const float * freq_factors,
724        const int64_t * row_indices, const int set_rows_stride,
725        const bool is_neox) {
726    ggml_cuda_pdl_lc();
727    const int row     = blockIdx.x;
728    const int channel = blockIdx.y;
729    const int sample  = blockIdx.z;
730    const int tid     = threadIdx.x;
731
732    x += sample*s03 + channel*s02 + row*s01;
733
734    const uint32_t mul_row     = fastmodulo(row,     mul_nrows_packed);
735    const uint32_t mul_channel = fastmodulo(channel, mul_nchannels_packed);
736    const uint32_t mul_sample  = fastmodulo(sample,  mul_nsamples_packed);
737    mul += mul_sample*mul_s03 + mul_channel*mul_s02 + mul_row*mul_s01;
738
739    float tmp = 0.0f;
740
741    ggml_cuda_pdl_sync();
742    for (int col = tid; col < ncols; col += block_size) {
743        const float xi = x[col];
744        tmp += xi * xi;
745    }
746
747    extern __shared__ float s_sum[];
748    tmp = block_reduce<block_reduce_method::SUM, block_size>(tmp, s_sum);
749
750    const float scale = rsqrtf(tmp/ncols + eps);
751
752    int64_t idst = sample*s3 + channel*s2 + row*s1;
753    if (set_rows_stride != 0) {
754        idst = row*s1 + row_indices[channel]*set_rows_stride;
755    }
756    dst += idst;
757
758    for (int i0 = 2*tid; i0 < ncols; i0 += 2*block_size) {
759        int ix0;
760        int ix1;
761        if (is_neox && i0 < n_dims) {
762            ix0 = i0/2;
763            ix1 = i0/2 + n_dims/2;
764        } else {
765            ix0 = i0 + 0;
766            ix1 = i0 + 1;
767        }
768
769        const float x0 = scale * x[ix0] * mul[fastmodulo(ix0, mul_ncols_packed)];
770        const float x1 = scale * x[ix1] * mul[fastmodulo(ix1, mul_ncols_packed)];
771
772        if (i0 >= n_dims) {
773            dst[ix0] = ggml_cuda_cast<D>(x0);
774            dst[ix1] = ggml_cuda_cast<D>(x1);
775            continue;
776        }
777
778        const float theta_base  = pos[channel]*powf(theta_scale, i0/2.0f);
779        const float freq_factor = has_ff ? freq_factors[i0/2] : 1.0f;
780
781        float cos_theta;
782        float sin_theta;
783        rope_yarn<true>(theta_base/freq_factor, freq_scale, corr_dims, i0, ext_factor, attn_factor, cos_theta, sin_theta);
784
785        dst[ix0] = ggml_cuda_cast<D>(x0*cos_theta - x1*sin_theta);
786        dst[ix1] = ggml_cuda_cast<D>(x0*sin_theta + x1*cos_theta);
787    }
788}
789
790template <typename D>
791static void rms_norm_mul_rope_cuda(
792        const float * x, D * dst,
793        const int ncols, const int nrows, const int nchannels, const int nsamples,
794        const int64_t s01, const int64_t s02, const int64_t s03,
795        const int64_t s1, const int64_t s2, const int64_t s3,
796        const float eps,
797        const float * mul,
798        const int64_t mul_s01, const int64_t mul_s02, const int64_t mul_s03,
799        const uint32_t mul_ncols, const uint32_t mul_nrows,
800        const uint32_t mul_nchannels, const uint32_t mul_nsamples,
801        const int n_dims, const int32_t * pos,
802        const float freq_scale, const float freq_base, const float ext_factor, const float attn_factor,
803        const rope_corr_dims corr_dims,
804        const float * freq_factors,
805        const int64_t * row_indices, const int set_rows_stride,
806        const bool is_neox, cudaStream_t stream) {
807    GGML_ASSERT(ncols % 2 == 0);
808
809    const dim3 blocks_num(nrows, nchannels, nsamples);
810
811    const float theta_scale = powf(freq_base, -2.0f/n_dims);
812
813    const uint3 mul_ncols_packed     = init_fastdiv_values(mul_ncols);
814    const uint3 mul_nrows_packed     = init_fastdiv_values(mul_nrows);
815    const uint3 mul_nchannels_packed = init_fastdiv_values(mul_nchannels);
816    const uint3 mul_nsamples_packed  = init_fastdiv_values(mul_nsamples);
817
818    if (ncols < 1024) {
819        const dim3 block_dims(256, 1, 1);
820        const ggml_cuda_kernel_launch_params launch_params = {blocks_num, block_dims, 32*sizeof(float), stream};
821        if (freq_factors == nullptr) {
822            ggml_cuda_kernel_launch(rms_norm_mul_rope_f32<256, false, D>, launch_params,
823                x, dst, ncols, s01, s02, s03, s1, s2, s3, eps, mul, mul_s01, mul_s02, mul_s03,
824                mul_ncols_packed, mul_nrows_packed, mul_nchannels_packed, mul_nsamples_packed,
825                n_dims, pos, freq_scale, ext_factor, attn_factor, corr_dims, theta_scale,
826                freq_factors, row_indices, set_rows_stride, is_neox);
827        } else {
828            ggml_cuda_kernel_launch(rms_norm_mul_rope_f32<256, true, D>, launch_params,
829                x, dst, ncols, s01, s02, s03, s1, s2, s3, eps, mul, mul_s01, mul_s02, mul_s03,
830                mul_ncols_packed, mul_nrows_packed, mul_nchannels_packed, mul_nsamples_packed,
831                n_dims, pos, freq_scale, ext_factor, attn_factor, corr_dims, theta_scale,
832                freq_factors, row_indices, set_rows_stride, is_neox);
833        }
834    } else {
835        const dim3 block_dims(1024, 1, 1);
836        const ggml_cuda_kernel_launch_params launch_params = {blocks_num, block_dims, 32*sizeof(float), stream};
837        if (freq_factors == nullptr) {
838            ggml_cuda_kernel_launch(rms_norm_mul_rope_f32<1024, false, D>, launch_params,
839                x, dst, ncols, s01, s02, s03, s1, s2, s3, eps, mul, mul_s01, mul_s02, mul_s03,
840                mul_ncols_packed, mul_nrows_packed, mul_nchannels_packed, mul_nsamples_packed,
841                n_dims, pos, freq_scale, ext_factor, attn_factor, corr_dims, theta_scale,
842                freq_factors, row_indices, set_rows_stride, is_neox);
843        } else {
844            ggml_cuda_kernel_launch(rms_norm_mul_rope_f32<1024, true, D>, launch_params,
845                x, dst, ncols, s01, s02, s03, s1, s2, s3, eps, mul, mul_s01, mul_s02, mul_s03,
846                mul_ncols_packed, mul_nrows_packed, mul_nchannels_packed, mul_nsamples_packed,
847                n_dims, pos, freq_scale, ext_factor, attn_factor, corr_dims, theta_scale,
848                freq_factors, row_indices, set_rows_stride, is_neox);
849        }
850    }
851}
852
853void ggml_cuda_op_rms_norm_mul_rope_fused(ggml_backend_cuda_context & ctx,
854        ggml_tensor * rms_norm, ggml_tensor * mul, ggml_tensor * rope, ggml_tensor * set_rows) {
855    const ggml_tensor * x = rms_norm->src[0];
856    const ggml_tensor * mul_src = mul->src[0] == rms_norm ? mul->src[1] : mul->src[0];
857
858    float eps = 0.0f;
859    memcpy(&eps, rms_norm->op_params, sizeof(float));
860    GGML_ASSERT(eps >= 0.0f);
861
862    GGML_ASSERT(x->type == GGML_TYPE_F32);
863    GGML_ASSERT(mul_src->type == GGML_TYPE_F32);
864    GGML_ASSERT(rope->type == GGML_TYPE_F32);
865
866    void *          dst_d           = rope->data;
867    ggml_type       dst_type        = rope->type;
868    const int64_t * row_indices     = nullptr;
869    int             set_rows_stride = 0;
870
871    if (set_rows != nullptr) {
872        dst_d           = set_rows->data;
873        dst_type        = set_rows->type;
874        row_indices     = (const int64_t *) set_rows->src[1]->data;
875        set_rows_stride = set_rows->nb[1] / ggml_type_size(set_rows->type);
876    }
877
878    const int n_dims     = ((const int32_t *) rope->op_params)[1];
879    const int mode       = ((const int32_t *) rope->op_params)[2];
880    const int n_ctx_orig = ((const int32_t *) rope->op_params)[4];
881
882    float freq_base;
883    float freq_scale;
884    float ext_factor;
885    float attn_factor;
886    float beta_fast;
887    float beta_slow;
888
889    memcpy(&freq_base,   (const int32_t *) rope->op_params +  5, sizeof(float));
890    memcpy(&freq_scale,  (const int32_t *) rope->op_params +  6, sizeof(float));
891    memcpy(&ext_factor,  (const int32_t *) rope->op_params +  7, sizeof(float));
892    memcpy(&attn_factor, (const int32_t *) rope->op_params +  8, sizeof(float));
893    memcpy(&beta_fast,   (const int32_t *) rope->op_params +  9, sizeof(float));
894    memcpy(&beta_slow,   (const int32_t *) rope->op_params + 10, sizeof(float));
895
896    const bool is_neox = mode & GGML_ROPE_TYPE_NEOX;
897
898    const int32_t * pos = (const int32_t *) rope->src[1]->data;
899
900    const float * freq_factors = rope->src[2] != nullptr ? (const float *) rope->src[2]->data : nullptr;
901
902    rope_corr_dims corr_dims;
903    ggml_rope_yarn_corr_dims(n_dims, n_ctx_orig, freq_base, beta_fast, beta_slow, corr_dims.v);
904
905    const size_t ts0 = ggml_type_size(x->type);
906    GGML_ASSERT(x->nb[0] == ts0);
907    const int64_t s01 = x->nb[1] / ts0;
908    const int64_t s02 = x->nb[2] / ts0;
909    const int64_t s03 = x->nb[3] / ts0;
910
911    const size_t ts_mul = ggml_type_size(mul_src->type);
912    GGML_ASSERT(mul_src->nb[0] == ts_mul);
913    const int64_t mul_s01 = mul_src->nb[1] / ts_mul;
914    const int64_t mul_s02 = mul_src->nb[2] / ts_mul;
915    const int64_t mul_s03 = mul_src->nb[3] / ts_mul;
916
917    const size_t ts_dst = ggml_type_size(rope->type);
918    const int64_t s1 = rope->nb[1] / ts_dst;
919    const int64_t s2 = rope->nb[2] / ts_dst;
920    const int64_t s3 = rope->nb[3] / ts_dst;
921
922    cudaStream_t stream = ctx.stream();
923
924    if (dst_type == GGML_TYPE_F32) {
925        rms_norm_mul_rope_cuda((const float *) x->data, (float *) dst_d,
926            x->ne[0], x->ne[1], x->ne[2], x->ne[3], s01, s02, s03, s1, s2, s3, eps,
927            (const float *) mul_src->data, mul_s01, mul_s02, mul_s03,
928            mul_src->ne[0], mul_src->ne[1], mul_src->ne[2], mul_src->ne[3],
929            n_dims, pos, freq_scale, freq_base, ext_factor, attn_factor, corr_dims,
930            freq_factors, row_indices, set_rows_stride, is_neox, stream);
931    } else if (dst_type == GGML_TYPE_F16) {
932        rms_norm_mul_rope_cuda((const float *) x->data, (half *) dst_d,
933            x->ne[0], x->ne[1], x->ne[2], x->ne[3], s01, s02, s03, s1, s2, s3, eps,
934            (const float *) mul_src->data, mul_s01, mul_s02, mul_s03,
935            mul_src->ne[0], mul_src->ne[1], mul_src->ne[2], mul_src->ne[3],
936            n_dims, pos, freq_scale, freq_base, ext_factor, attn_factor, corr_dims,
937            freq_factors, row_indices, set_rows_stride, is_neox, stream);
938    } else {
939        GGML_ABORT("fatal error");
940    }
941}