Kernels
kernels-bot commited on
Commit
91fae15
·
verified ·
1 Parent(s): 4fce497

Uploaded using `kernel-builder`.

Browse files
build/torch-rocm/__init__.py ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """AITER RoPE kernels for AMD ROCm (Triton).
2
+
3
+ Triton-based RoPE (Rotary Position Embedding) kernels repackaged from the
4
+ [ROCm/aiter](https://github.com/ROCm/aiter) project. Exposes
5
+ ``apply_rotary_transformers`` — drop-in replacement for the same-named
6
+ function in ``kernels-community/rotary`` — so transformers can use this as
7
+ the ROCm entry of ``_KERNEL_MAPPING["rotary_pos_emb"]`` with zero model-side
8
+ changes.
9
+ """
10
+
11
+ import torch
12
+
13
+ from .rope import (
14
+ RotateStyle,
15
+ rope_cached_fwd,
16
+ rope_cached_fwd_inplace,
17
+ )
18
+
19
+
20
+ __kernel_metadata__ = {
21
+ "license": "mit",
22
+ }
23
+
24
+
25
+ def _to_sbhd(t: torch.Tensor) -> torch.Tensor:
26
+ # transformers passes attention tensors as (batch, heads, seq, head_dim);
27
+ # AITER's kernels operate in (seq, batch, heads, head_dim).
28
+ return t.permute(2, 0, 1, 3).contiguous()
29
+
30
+
31
+ def _to_bhsd(t: torch.Tensor) -> torch.Tensor:
32
+ return t.permute(1, 2, 0, 3)
33
+
34
+
35
+ def apply_rotary_transformers(q, k, cos, sin, position_ids=None, unsqueeze_dim=1):
36
+ """Apply NEOX-style RoPE to ``q`` and ``k``.
37
+
38
+ Signature mirrors ``kernels-community/rotary``'s ``apply_rotary_transformers``
39
+ so this kernel can be a drop-in replacement under the ``"rocm"`` entry of
40
+ transformers' ``_KERNEL_MAPPING["rotary_pos_emb"]``.
41
+
42
+ Args:
43
+ q, k: ``(batch, heads, seq, head_dim)``.
44
+ cos, sin: ``(batch, seq, head_dim // 2)`` — pre-``unsqueeze`` form.
45
+ position_ids, unsqueeze_dim: accepted for API parity; the kernel reads
46
+ positions from the already-computed ``cos`` / ``sin``.
47
+
48
+ Returns:
49
+ ``(q_embed, k_embed)`` in the same shape as ``q``, ``k``.
50
+ """
51
+ q_sbhd = _to_sbhd(q)
52
+ k_sbhd = _to_sbhd(k)
53
+
54
+ # Cached path expects (seq, 1, 1, head_dim/2). Take batch index 0 — for the
55
+ # standard (unpadded, equal-length) inference case all batch rows share the
56
+ # same cos/sin since they come from the same position_ids.
57
+ cos_freqs = cos[0].unsqueeze(1).unsqueeze(1).contiguous()
58
+ sin_freqs = sin[0].unsqueeze(1).unsqueeze(1).contiguous()
59
+
60
+ common = dict(
61
+ rotate_style=int(RotateStyle.NEOX),
62
+ reuse_freqs_front_part=True,
63
+ nope_first=False,
64
+ )
65
+ q_out_sbhd = rope_cached_fwd(q_sbhd, cos_freqs, sin_freqs, **common)
66
+ k_out_sbhd = rope_cached_fwd(k_sbhd, cos_freqs, sin_freqs, **common)
67
+
68
+ return _to_bhsd(q_out_sbhd), _to_bhsd(k_out_sbhd)
69
+
70
+
71
+ __all__ = [
72
+ "__kernel_metadata__",
73
+ "RotateStyle",
74
+ "apply_rotary_transformers",
75
+ "rope_cached_fwd",
76
+ "rope_cached_fwd_inplace",
77
+ ]
build/torch-rocm/_kernels/__init__.py ADDED
File without changes
build/torch-rocm/_kernels/rope.py ADDED
@@ -0,0 +1,2040 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (C) 2024-2026, Advanced Micro Devices, Inc. All rights reserved.
3
+
4
+ import triton
5
+ import triton.language as tl
6
+
7
+
8
+ @triton.jit
9
+ def _get_neox_rotated_x_1D(
10
+ x,
11
+ x_rotated_mask,
12
+ BLOCK_D: tl.constexpr,
13
+ BLOCK_D_HALF: tl.constexpr,
14
+ ):
15
+ x_rotated = tl.where(x_rotated_mask, x, -x)
16
+ x_rotated = tl.reshape(x_rotated, (2, BLOCK_D_HALF))
17
+ x_rotated = tl.flip(x_rotated, 1)
18
+ x_rotated = tl.reshape(x_rotated, (BLOCK_D,))
19
+ x_rotated = tl.flip(x_rotated, 0)
20
+ return x_rotated
21
+
22
+
23
+ @triton.jit
24
+ def _get_gptj_rotated_x_1D(
25
+ x,
26
+ x_rotated_mask,
27
+ BLOCK_D: tl.constexpr,
28
+ BLOCK_D_HALF: tl.constexpr,
29
+ ):
30
+ x_rotated = tl.where(x_rotated_mask, x, -x)
31
+ x_rotated = tl.reshape(x_rotated, (BLOCK_D_HALF, 2))
32
+ x_rotated = tl.flip(x_rotated, 1)
33
+ x_rotated = tl.reshape(x_rotated, (BLOCK_D,))
34
+ return x_rotated
35
+
36
+
37
+ @triton.jit
38
+ def _get_neox_rotated_x(
39
+ x,
40
+ x_rotated_mask,
41
+ BLOCK_T: tl.constexpr,
42
+ BLOCK_D: tl.constexpr,
43
+ BLOCK_D_HALF: tl.constexpr,
44
+ IS_BWD: tl.constexpr = False,
45
+ ):
46
+ if IS_BWD:
47
+ x_rotated = tl.where(x_rotated_mask, -x, x)
48
+ else:
49
+ x_rotated = tl.where(x_rotated_mask, x, -x)
50
+
51
+ x_rotated = tl.reshape(x_rotated, (BLOCK_T, 2, BLOCK_D_HALF))
52
+ x_rotated = tl.flip(x_rotated, 2)
53
+ x_rotated = tl.reshape(
54
+ x_rotated,
55
+ (
56
+ BLOCK_T,
57
+ BLOCK_D,
58
+ ),
59
+ )
60
+ x_rotated = tl.flip(x_rotated, 1)
61
+ return x_rotated
62
+
63
+
64
+ @triton.jit
65
+ def _get_gptj_rotated_x(
66
+ x,
67
+ x_rotated_mask,
68
+ BLOCK_T: tl.constexpr,
69
+ BLOCK_D: tl.constexpr,
70
+ BLOCK_D_HALF: tl.constexpr,
71
+ IS_BWD: tl.constexpr = False,
72
+ ):
73
+ if IS_BWD:
74
+ x_rotated = tl.where(x_rotated_mask, -x, x)
75
+ else:
76
+ x_rotated = tl.where(x_rotated_mask, x, -x)
77
+
78
+ x_rotated = tl.reshape(x_rotated, (BLOCK_T, BLOCK_D_HALF, 2))
79
+ x_rotated = tl.flip(x_rotated, 2)
80
+ x_rotated = tl.reshape(
81
+ x_rotated,
82
+ (
83
+ BLOCK_T,
84
+ BLOCK_D,
85
+ ),
86
+ )
87
+ return x_rotated
88
+
89
+
90
+ @triton.jit
91
+ def _rope_kernel_sbhd_fwd(
92
+ x_ptr,
93
+ freqs_ptr,
94
+ out_ptr,
95
+ stride_x_s,
96
+ stride_x_b,
97
+ stride_x_h,
98
+ stride_x_d,
99
+ stride_freqs_s,
100
+ stride_freqs_b,
101
+ stride_freqs_h,
102
+ stride_freqs_d,
103
+ stride_out_s,
104
+ stride_out_b,
105
+ stride_out_h,
106
+ stride_out_d,
107
+ S,
108
+ HAVE_NOPE: tl.constexpr,
109
+ NOPE_FIRST: tl.constexpr,
110
+ INPLACE: tl.constexpr,
111
+ REUSE_FREQS_FRONT_PART: tl.constexpr,
112
+ IS_NEOX: tl.constexpr,
113
+ BLOCK_S: tl.constexpr,
114
+ BLOCK_D: tl.constexpr,
115
+ BLOCK_D_HALF: tl.constexpr,
116
+ ):
117
+ # Parallelize over batch and head. Handle 1 sequence per program
118
+ b = tl.program_id(0)
119
+ h = tl.program_id(1)
120
+ pid_s = tl.program_id(2)
121
+
122
+ s_offs = pid_s * BLOCK_S + tl.arange(0, BLOCK_S)
123
+ d_offs = tl.arange(0, BLOCK_D)
124
+ s_mask = s_offs < S
125
+
126
+ if REUSE_FREQS_FRONT_PART:
127
+ if IS_NEOX:
128
+ d_freqs_offs = tl.where(
129
+ (d_offs >= BLOCK_D_HALF) & (d_offs < BLOCK_D),
130
+ d_offs - BLOCK_D_HALF,
131
+ d_offs,
132
+ ).to(d_offs.dtype)
133
+ d_freqs_mask = d_freqs_offs < BLOCK_D
134
+ else:
135
+ d_freqs_offs = d_offs // 2
136
+ d_freqs_mask = d_freqs_offs < BLOCK_D_HALF
137
+ else:
138
+ d_freqs_offs = d_offs
139
+ d_freqs_mask = d_freqs_offs < BLOCK_D
140
+
141
+ freqs_mask = s_mask[:, None] & d_freqs_mask[None, :]
142
+ freqs_offs = (
143
+ s_offs[:, None] * stride_freqs_s + d_freqs_offs[None, :] * stride_freqs_d
144
+ )
145
+
146
+ freqs = tl.load(freqs_ptr + freqs_offs, mask=freqs_mask)
147
+ cos = tl.cos(freqs.to(tl.float32))
148
+ sin = tl.sin(freqs.to(tl.float32))
149
+
150
+ nope_offs = 0
151
+ if HAVE_NOPE and NOPE_FIRST:
152
+ nope_offs = BLOCK_D
153
+
154
+ x_offs = (
155
+ b * stride_x_b
156
+ + s_offs[:, None] * stride_x_s
157
+ + h * stride_x_h
158
+ + (d_offs + nope_offs)[None, :] * stride_x_d
159
+ )
160
+ x_mask = s_mask[:, None] & (d_offs < BLOCK_D)[None, :]
161
+ x = tl.load(x_ptr + x_offs, mask=x_mask)
162
+
163
+ if IS_NEOX:
164
+ x_rotated_mask = (d_offs < BLOCK_D_HALF)[None, :]
165
+ x_rotated = _get_neox_rotated_x(
166
+ x, x_rotated_mask, BLOCK_S, BLOCK_D, BLOCK_D_HALF
167
+ )
168
+ else:
169
+ x_rotated_mask = (d_offs % 2 == 0)[None, :]
170
+ x_rotated = _get_gptj_rotated_x(
171
+ x, x_rotated_mask, BLOCK_S, BLOCK_D, BLOCK_D_HALF
172
+ )
173
+
174
+ out_x = x * cos + x_rotated * sin
175
+ out_x = out_x.to(x_ptr.dtype.element_ty)
176
+ x_out_offs = (
177
+ b * stride_out_b
178
+ + s_offs[:, None] * stride_out_s
179
+ + h * stride_out_h
180
+ + (d_offs + nope_offs)[None, :] * stride_out_d
181
+ )
182
+
183
+ tl.store(out_ptr + x_out_offs, out_x, mask=x_mask)
184
+
185
+ if HAVE_NOPE and not INPLACE:
186
+ if NOPE_FIRST:
187
+ x = tl.load(x_ptr + x_offs - BLOCK_D * stride_x_d, mask=x_mask)
188
+ tl.store(out_ptr + x_out_offs - BLOCK_D * stride_out_d, x, mask=x_mask)
189
+ else:
190
+ x = tl.load(x_ptr + x_offs + BLOCK_D * stride_x_d, mask=x_mask)
191
+ tl.store(out_ptr + x_out_offs + BLOCK_D * stride_out_d, x, mask=x_mask)
192
+
193
+
194
+ @triton.jit
195
+ def _rope_kernel_sbhd_bwd(
196
+ x_ptr,
197
+ freqs_ptr,
198
+ out_ptr,
199
+ stride_x_s,
200
+ stride_x_b,
201
+ stride_x_h,
202
+ stride_x_d,
203
+ stride_freqs_s,
204
+ stride_freqs_b,
205
+ stride_freqs_h,
206
+ stride_freqs_d,
207
+ stride_out_s,
208
+ stride_out_b,
209
+ stride_out_h,
210
+ stride_out_d,
211
+ S,
212
+ HAVE_NOPE: tl.constexpr,
213
+ NOPE_FIRST: tl.constexpr,
214
+ INPLACE: tl.constexpr,
215
+ REUSE_FREQS_FRONT_PART: tl.constexpr,
216
+ IS_NEOX: tl.constexpr,
217
+ BLOCK_S: tl.constexpr,
218
+ BLOCK_D: tl.constexpr,
219
+ BLOCK_D_HALF: tl.constexpr,
220
+ ):
221
+ # Parallelize over batch and head. Handle 1 sequence per program
222
+ b = tl.program_id(0)
223
+ h = tl.program_id(1)
224
+ pid_s = tl.program_id(2)
225
+
226
+ s_offs = pid_s * BLOCK_S + tl.arange(0, BLOCK_S)
227
+ d_offs = tl.arange(0, BLOCK_D)
228
+ s_mask = s_offs < S
229
+
230
+ if REUSE_FREQS_FRONT_PART:
231
+ if IS_NEOX:
232
+ d_freqs_offs = tl.where(
233
+ (d_offs >= BLOCK_D_HALF) & (d_offs < BLOCK_D),
234
+ d_offs - BLOCK_D_HALF,
235
+ d_offs,
236
+ ).to(d_offs.dtype)
237
+ d_freqs_mask = d_freqs_offs < BLOCK_D
238
+ else:
239
+ d_freqs_offs = d_offs // 2
240
+ d_freqs_mask = d_freqs_offs < BLOCK_D_HALF
241
+ else:
242
+ d_freqs_offs = d_offs
243
+ d_freqs_mask = d_freqs_offs < BLOCK_D
244
+
245
+ freqs_mask = s_mask[:, None] & d_freqs_mask[None, :]
246
+ freqs_offs = (
247
+ s_offs[:, None] * stride_freqs_s + d_freqs_offs[None, :] * stride_freqs_d
248
+ )
249
+
250
+ freqs = tl.load(freqs_ptr + freqs_offs, mask=freqs_mask)
251
+ cos = tl.cos(freqs.to(tl.float32))
252
+ sin = tl.sin(freqs.to(tl.float32))
253
+
254
+ nope_offs = 0
255
+ if HAVE_NOPE and NOPE_FIRST:
256
+ nope_offs = BLOCK_D
257
+
258
+ x_mask = s_mask[:, None] & (d_offs < BLOCK_D)[None, :]
259
+
260
+ if IS_NEOX:
261
+ x_rotated_mask = (d_offs < BLOCK_D_HALF)[None, :]
262
+ else:
263
+ x_rotated_mask = (d_offs % 2 == 0)[None, :]
264
+
265
+ d_offs += nope_offs
266
+ x_offs = (
267
+ b * stride_x_b
268
+ + s_offs[:, None] * stride_x_s
269
+ + h * stride_x_h
270
+ + d_offs[None, :] * stride_x_d
271
+ )
272
+ x = tl.load(x_ptr + x_offs, mask=x_mask)
273
+
274
+ if IS_NEOX:
275
+ x_rotated = _get_neox_rotated_x(
276
+ x * sin, x_rotated_mask, BLOCK_S, BLOCK_D, BLOCK_D_HALF, True
277
+ )
278
+ else:
279
+ x_rotated = _get_gptj_rotated_x(
280
+ x * sin, x_rotated_mask, BLOCK_S, BLOCK_D, BLOCK_D_HALF, True
281
+ )
282
+
283
+ out_x = x * cos + x_rotated
284
+ out_x = out_x.to(x_ptr.dtype.element_ty)
285
+ x_out_offs = (
286
+ b * stride_out_b
287
+ + s_offs[:, None] * stride_out_s
288
+ + h * stride_out_h
289
+ + d_offs[None, :] * stride_out_d
290
+ )
291
+
292
+ tl.store(out_ptr + x_out_offs, out_x, mask=x_mask)
293
+
294
+ if HAVE_NOPE and not INPLACE:
295
+ if NOPE_FIRST:
296
+ x = tl.load(x_ptr + x_offs - BLOCK_D * stride_x_d, mask=x_mask)
297
+ tl.store(out_ptr + x_out_offs - BLOCK_D * stride_out_d, x, mask=x_mask)
298
+ else:
299
+ x = tl.load(x_ptr + x_offs + BLOCK_D * stride_x_d, mask=x_mask)
300
+ tl.store(out_ptr + x_out_offs + BLOCK_D * stride_out_d, x, mask=x_mask)
301
+
302
+
303
+ @triton.jit
304
+ def _rope_kernel_thd_fwd(
305
+ x_ptr,
306
+ cu_seqlens_ptr,
307
+ freqs_ptr,
308
+ out_ptr,
309
+ stride_x_t,
310
+ stride_x_h,
311
+ stride_x_d,
312
+ stride_freqs_t,
313
+ stride_freqs_b,
314
+ stride_freqs_h,
315
+ stride_freqs_d,
316
+ stride_out_t,
317
+ stride_out_h,
318
+ stride_out_d,
319
+ HAVE_NOPE: tl.constexpr,
320
+ NOPE_FIRST: tl.constexpr,
321
+ INPLACE: tl.constexpr,
322
+ REUSE_FREQS_FRONT_PART: tl.constexpr,
323
+ IS_NEOX: tl.constexpr,
324
+ BLOCK_T: tl.constexpr,
325
+ BLOCK_D: tl.constexpr,
326
+ BLOCK_D_HALF: tl.constexpr,
327
+ ):
328
+ b = tl.program_id(0)
329
+ h = tl.program_id(1)
330
+ pid_t = tl.program_id(2)
331
+
332
+ t_start = tl.load(cu_seqlens_ptr + b)
333
+ t_end = tl.load(cu_seqlens_ptr + b + 1)
334
+ T = t_end - t_start
335
+ if pid_t * BLOCK_T >= T:
336
+ return
337
+
338
+ t_offs = pid_t * BLOCK_T + tl.arange(0, BLOCK_T)
339
+ d_offs = tl.arange(0, BLOCK_D)
340
+ t_mask = t_offs < T
341
+
342
+ if REUSE_FREQS_FRONT_PART:
343
+ if IS_NEOX:
344
+ d_freqs_offs = tl.where(
345
+ (d_offs >= BLOCK_D_HALF) & (d_offs < BLOCK_D),
346
+ d_offs - BLOCK_D_HALF,
347
+ d_offs,
348
+ ).to(d_offs.dtype)
349
+ d_freqs_mask = d_freqs_offs < BLOCK_D
350
+ else:
351
+ d_freqs_offs = d_offs // 2
352
+ d_freqs_mask = d_freqs_offs < BLOCK_D_HALF
353
+ else:
354
+ d_freqs_offs = d_offs
355
+ d_freqs_mask = d_freqs_offs < BLOCK_D
356
+
357
+ freqs_mask = t_mask[:, None] & d_freqs_mask[None, :]
358
+ freqs_offs = (
359
+ t_offs[:, None] * stride_freqs_t + d_freqs_offs[None, :] * stride_freqs_d
360
+ )
361
+ freqs = tl.load(freqs_ptr + freqs_offs, mask=freqs_mask)
362
+ cos = tl.cos(freqs.to(tl.float32))
363
+ sin = tl.sin(freqs.to(tl.float32))
364
+
365
+ nope_offs = 0
366
+ if HAVE_NOPE and NOPE_FIRST:
367
+ nope_offs = BLOCK_D
368
+
369
+ x_mask = t_mask[:, None] & (d_offs < BLOCK_D)[None, :]
370
+
371
+ if IS_NEOX:
372
+ x_rotated_mask = (d_offs < BLOCK_D_HALF)[None, :]
373
+ else:
374
+ x_rotated_mask = (d_offs % 2 == 0)[None, :]
375
+
376
+ d_offs += nope_offs
377
+ x_offs = (
378
+ (t_start + t_offs)[:, None] * stride_x_t
379
+ + h * stride_x_h
380
+ + d_offs[None, :] * stride_x_d
381
+ )
382
+ x = tl.load(x_ptr + x_offs, mask=x_mask)
383
+
384
+ if IS_NEOX:
385
+ x_rotated = _get_neox_rotated_x(
386
+ x, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF
387
+ )
388
+ else:
389
+ x_rotated = _get_gptj_rotated_x(
390
+ x, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF
391
+ )
392
+
393
+ out_x = x * cos + x_rotated * sin
394
+ out_x = out_x.to(x_ptr.dtype.element_ty)
395
+ x_out_offs = (
396
+ (t_start + t_offs)[:, None] * stride_out_t
397
+ + h * stride_out_h
398
+ + d_offs[None, :] * stride_out_d
399
+ )
400
+
401
+ tl.store(out_ptr + x_out_offs, out_x, mask=x_mask)
402
+
403
+ if HAVE_NOPE and not INPLACE:
404
+ if NOPE_FIRST:
405
+ x = tl.load(x_ptr + x_offs - BLOCK_D * stride_x_d, mask=x_mask)
406
+ tl.store(out_ptr + x_out_offs - BLOCK_D * stride_out_d, x, mask=x_mask)
407
+ else:
408
+ x = tl.load(x_ptr + x_offs + BLOCK_D * stride_x_d, mask=x_mask)
409
+ tl.store(out_ptr + x_out_offs + BLOCK_D * stride_out_d, x, mask=x_mask)
410
+
411
+
412
+ @triton.jit
413
+ def _rope_kernel_thd_bwd(
414
+ x_ptr,
415
+ cu_seqlens_ptr,
416
+ freqs_ptr,
417
+ out_ptr,
418
+ stride_x_t,
419
+ stride_x_h,
420
+ stride_x_d,
421
+ stride_freqs_t,
422
+ stride_freqs_b,
423
+ stride_freqs_h,
424
+ stride_freqs_d,
425
+ stride_out_t,
426
+ stride_out_h,
427
+ stride_out_d,
428
+ HAVE_NOPE: tl.constexpr,
429
+ NOPE_FIRST: tl.constexpr,
430
+ INPLACE: tl.constexpr,
431
+ REUSE_FREQS_FRONT_PART: tl.constexpr,
432
+ IS_NEOX: tl.constexpr,
433
+ BLOCK_T: tl.constexpr,
434
+ BLOCK_D: tl.constexpr,
435
+ BLOCK_D_HALF: tl.constexpr,
436
+ ):
437
+ b = tl.program_id(0)
438
+ h = tl.program_id(1)
439
+ pid_t = tl.program_id(2)
440
+
441
+ t_start = tl.load(cu_seqlens_ptr + b)
442
+ t_end = tl.load(cu_seqlens_ptr + b + 1)
443
+ T = t_end - t_start
444
+ if pid_t * BLOCK_T >= T:
445
+ return
446
+
447
+ t_offs = pid_t * BLOCK_T + tl.arange(0, BLOCK_T)
448
+ d_offs = tl.arange(0, BLOCK_D)
449
+ t_mask = t_offs < T
450
+
451
+ if REUSE_FREQS_FRONT_PART:
452
+ if IS_NEOX:
453
+ d_freqs_offs = tl.where(
454
+ (d_offs >= BLOCK_D_HALF) & (d_offs < BLOCK_D),
455
+ d_offs - BLOCK_D_HALF,
456
+ d_offs,
457
+ ).to(d_offs.dtype)
458
+ d_freqs_mask = d_freqs_offs < BLOCK_D
459
+ else:
460
+ d_freqs_offs = d_offs // 2
461
+ d_freqs_mask = d_freqs_offs < BLOCK_D_HALF
462
+ else:
463
+ d_freqs_offs = d_offs
464
+ d_freqs_mask = d_freqs_offs < BLOCK_D
465
+
466
+ freqs_mask = t_mask[:, None] & d_freqs_mask[None, :]
467
+ freqs_offs = (
468
+ t_offs[:, None] * stride_freqs_t + d_freqs_offs[None, :] * stride_freqs_d
469
+ )
470
+ freqs = tl.load(freqs_ptr + freqs_offs, mask=freqs_mask)
471
+ cos = tl.cos(freqs.to(tl.float32))
472
+ sin = tl.sin(freqs.to(tl.float32))
473
+
474
+ nope_offs = 0
475
+ if HAVE_NOPE and NOPE_FIRST:
476
+ nope_offs = BLOCK_D
477
+
478
+ x_mask = t_mask[:, None] & (d_offs < BLOCK_D)[None, :]
479
+
480
+ if IS_NEOX:
481
+ x_rotated_mask = (d_offs < BLOCK_D_HALF)[None, :]
482
+ else:
483
+ x_rotated_mask = (d_offs % 2 == 0)[None, :]
484
+
485
+ d_offs += nope_offs
486
+ x_offs = (
487
+ (t_start + t_offs)[:, None] * stride_x_t
488
+ + h * stride_x_h
489
+ + d_offs[None, :] * stride_x_d
490
+ )
491
+ x = tl.load(x_ptr + x_offs, mask=x_mask)
492
+
493
+ if IS_NEOX:
494
+ x_rotated = _get_neox_rotated_x(
495
+ x * sin, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF, True
496
+ )
497
+ else:
498
+ x_rotated = _get_gptj_rotated_x(
499
+ x * sin, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF, True
500
+ )
501
+
502
+ out_x = x * cos + x_rotated
503
+ out_x = out_x.to(x_ptr.dtype.element_ty)
504
+ x_out_offs = (
505
+ (t_start + t_offs)[:, None] * stride_out_t
506
+ + h * stride_out_h
507
+ + d_offs[None, :] * stride_out_d
508
+ )
509
+
510
+ tl.store(out_ptr + x_out_offs, out_x, mask=x_mask)
511
+
512
+ if HAVE_NOPE and not INPLACE:
513
+ if NOPE_FIRST:
514
+ x = tl.load(x_ptr + x_offs - BLOCK_D * stride_x_d, mask=x_mask)
515
+ tl.store(out_ptr + x_out_offs - BLOCK_D * stride_out_d, x, mask=x_mask)
516
+ else:
517
+ x = tl.load(x_ptr + x_offs + BLOCK_D * stride_x_d, mask=x_mask)
518
+ tl.store(out_ptr + x_out_offs + BLOCK_D * stride_out_d, x, mask=x_mask)
519
+
520
+
521
+ @triton.jit
522
+ def _rope_kernel_sbhd_cached_fwd(
523
+ x_ptr,
524
+ cos_ptr,
525
+ sin_ptr,
526
+ pos_ptr,
527
+ off_ptr,
528
+ out_ptr,
529
+ stride_x_s,
530
+ stride_x_b,
531
+ stride_x_h,
532
+ stride_x_d,
533
+ stride_cos_s,
534
+ stride_cos_b,
535
+ stride_cos_h,
536
+ stride_cos_d,
537
+ stride_pos_s,
538
+ stride_pos_b,
539
+ stride_out_s,
540
+ stride_out_b,
541
+ stride_out_h,
542
+ stride_out_d,
543
+ S,
544
+ HAVE_NOPE: tl.constexpr,
545
+ NOPE_FIRST: tl.constexpr,
546
+ INPLACE: tl.constexpr,
547
+ REUSE_FREQS_FRONT_PART: tl.constexpr,
548
+ IS_NEOX: tl.constexpr,
549
+ HAVE_POS: tl.constexpr,
550
+ HAVE_OFFS: tl.constexpr,
551
+ BLOCK_S: tl.constexpr,
552
+ BLOCK_D: tl.constexpr,
553
+ BLOCK_D_HALF: tl.constexpr,
554
+ ):
555
+ b = tl.program_id(0)
556
+ h = tl.program_id(1)
557
+ pid_s = tl.program_id(2)
558
+
559
+ s_offs = pid_s * BLOCK_S + tl.arange(0, BLOCK_S)
560
+ d_offs = tl.arange(0, BLOCK_D)
561
+ s_mask = s_offs < S
562
+
563
+ if HAVE_POS:
564
+ pos_offs = s_offs * stride_pos_s + b * stride_pos_b
565
+ pos = tl.load(pos_ptr + pos_offs, mask=s_mask)
566
+ if HAVE_OFFS:
567
+ offset = tl.load(off_ptr + pos_offs, mask=s_mask)
568
+ s_cos_offs = pos + offset
569
+ else:
570
+ s_cos_offs = pos
571
+ else:
572
+ s_cos_offs = s_offs
573
+
574
+ if REUSE_FREQS_FRONT_PART:
575
+ if IS_NEOX:
576
+ d_cos_offs = d_offs
577
+ d_cos_offs = tl.where(
578
+ (d_cos_offs >= BLOCK_D_HALF) & (d_cos_offs < BLOCK_D),
579
+ d_cos_offs - BLOCK_D_HALF,
580
+ d_cos_offs,
581
+ ).to(d_cos_offs.dtype)
582
+ d_cos_mask = d_cos_offs < BLOCK_D
583
+ else:
584
+ d_cos_offs = d_offs // 2
585
+ d_cos_mask = d_cos_offs < BLOCK_D_HALF
586
+ else:
587
+ d_cos_offs = d_offs
588
+ d_cos_mask = d_cos_offs < BLOCK_D
589
+
590
+ cos_mask = s_mask[:, None] & d_cos_mask[None, :]
591
+ cos_offs = s_cos_offs[:, None] * stride_cos_s + d_cos_offs[None, :] * stride_cos_d
592
+ cos = tl.load(cos_ptr + cos_offs, mask=cos_mask)
593
+ sin = tl.load(sin_ptr + cos_offs, mask=cos_mask)
594
+
595
+ nope_offs = 0
596
+ if HAVE_NOPE and NOPE_FIRST:
597
+ nope_offs = BLOCK_D
598
+
599
+ x_mask = s_mask[:, None] & (d_offs < BLOCK_D)[None, :]
600
+
601
+ if IS_NEOX:
602
+ x_rotated_mask = (d_offs < BLOCK_D_HALF)[None, :]
603
+ else:
604
+ x_rotated_mask = (d_offs % 2 == 0)[None, :]
605
+
606
+ d_offs += nope_offs
607
+ x_offs = (
608
+ b * stride_x_b
609
+ + s_offs[:, None] * stride_x_s
610
+ + h * stride_x_h
611
+ + d_offs[None, :] * stride_x_d
612
+ )
613
+ x = tl.load(x_ptr + x_offs, mask=x_mask)
614
+
615
+ if IS_NEOX:
616
+ x_rotated = _get_neox_rotated_x(
617
+ x, x_rotated_mask, BLOCK_S, BLOCK_D, BLOCK_D_HALF
618
+ )
619
+ else:
620
+ x_rotated = _get_gptj_rotated_x(
621
+ x, x_rotated_mask, BLOCK_S, BLOCK_D, BLOCK_D_HALF
622
+ )
623
+
624
+ out_x = x * cos + x_rotated * sin
625
+ out_x = out_x.to(x_ptr.dtype.element_ty)
626
+ x_out_offs = (
627
+ b * stride_out_b
628
+ + s_offs[:, None] * stride_out_s
629
+ + h * stride_out_h
630
+ + d_offs[None, :] * stride_out_d
631
+ )
632
+
633
+ tl.store(out_ptr + x_out_offs, out_x, mask=x_mask)
634
+
635
+ if HAVE_NOPE and not INPLACE:
636
+ if NOPE_FIRST:
637
+ x = tl.load(x_ptr + x_offs - BLOCK_D * stride_x_d, mask=x_mask)
638
+ tl.store(out_ptr + x_out_offs - BLOCK_D * stride_out_d, x, mask=x_mask)
639
+ else:
640
+ x = tl.load(x_ptr + x_offs + BLOCK_D * stride_x_d, mask=x_mask)
641
+ tl.store(out_ptr + x_out_offs + BLOCK_D * stride_out_d, x, mask=x_mask)
642
+
643
+
644
+ @triton.jit
645
+ def _rope_kernel_sbhd_cached_bwd(
646
+ x_ptr,
647
+ cos_ptr,
648
+ sin_ptr,
649
+ pos_ptr,
650
+ off_ptr,
651
+ out_ptr,
652
+ stride_x_s,
653
+ stride_x_b,
654
+ stride_x_h,
655
+ stride_x_d,
656
+ stride_cos_s,
657
+ stride_cos_b,
658
+ stride_cos_h,
659
+ stride_cos_d,
660
+ stride_pos_s,
661
+ stride_pos_b,
662
+ stride_out_s,
663
+ stride_out_b,
664
+ stride_out_h,
665
+ stride_out_d,
666
+ S,
667
+ HAVE_NOPE: tl.constexpr,
668
+ NOPE_FIRST: tl.constexpr,
669
+ INPLACE: tl.constexpr,
670
+ REUSE_FREQS_FRONT_PART: tl.constexpr,
671
+ IS_NEOX: tl.constexpr,
672
+ HAVE_POS: tl.constexpr,
673
+ HAVE_OFFS: tl.constexpr,
674
+ BLOCK_S: tl.constexpr,
675
+ BLOCK_D: tl.constexpr,
676
+ BLOCK_D_HALF: tl.constexpr,
677
+ ):
678
+ b = tl.program_id(0)
679
+ h = tl.program_id(1)
680
+ pid_s = tl.program_id(2)
681
+
682
+ s_offs = pid_s * BLOCK_S + tl.arange(0, BLOCK_S)
683
+ d_offs = tl.arange(0, BLOCK_D)
684
+ s_mask = s_offs < S
685
+
686
+ if HAVE_POS:
687
+ pos_offs = s_offs * stride_pos_s + b * stride_pos_b
688
+ pos = tl.load(pos_ptr + pos_offs, mask=s_mask)
689
+ if HAVE_OFFS:
690
+ offset = tl.load(off_ptr + pos_offs, mask=s_mask)
691
+ s_cos_offs = pos + offset
692
+ else:
693
+ s_cos_offs = pos
694
+ else:
695
+ s_cos_offs = s_offs
696
+
697
+ if REUSE_FREQS_FRONT_PART:
698
+ if IS_NEOX:
699
+ d_cos_offs = d_offs
700
+ d_cos_offs = tl.where(
701
+ (d_cos_offs >= BLOCK_D_HALF) & (d_cos_offs < BLOCK_D),
702
+ d_cos_offs - BLOCK_D_HALF,
703
+ d_cos_offs,
704
+ ).to(d_cos_offs.dtype)
705
+ d_cos_mask = d_cos_offs < BLOCK_D
706
+ else:
707
+ d_cos_offs = d_offs // 2
708
+ d_cos_mask = d_cos_offs < BLOCK_D_HALF
709
+ else:
710
+ d_cos_offs = d_offs
711
+ d_cos_mask = d_cos_offs < BLOCK_D
712
+
713
+ cos_mask = s_mask[:, None] & d_cos_mask[None, :]
714
+ cos_offs = s_cos_offs[:, None] * stride_cos_s + d_cos_offs[None, :] * stride_cos_d
715
+ cos = tl.load(cos_ptr + cos_offs, mask=cos_mask)
716
+ sin = tl.load(sin_ptr + cos_offs, mask=cos_mask)
717
+
718
+ nope_offs = 0
719
+ if HAVE_NOPE and NOPE_FIRST:
720
+ nope_offs = BLOCK_D
721
+
722
+ x_mask = s_mask[:, None] & (d_offs < BLOCK_D)[None, :]
723
+
724
+ if IS_NEOX:
725
+ x_rotated_mask = (d_offs < BLOCK_D_HALF)[None, :]
726
+ else:
727
+ x_rotated_mask = (d_offs % 2 == 0)[None, :]
728
+
729
+ d_offs += nope_offs
730
+ x_offs = (
731
+ b * stride_x_b
732
+ + s_offs[:, None] * stride_x_s
733
+ + h * stride_x_h
734
+ + d_offs[None, :] * stride_x_d
735
+ )
736
+ x = tl.load(x_ptr + x_offs, mask=x_mask)
737
+
738
+ if IS_NEOX:
739
+ x_rotated = _get_neox_rotated_x(
740
+ x * sin, x_rotated_mask, BLOCK_S, BLOCK_D, BLOCK_D_HALF, True
741
+ )
742
+ else:
743
+ x_rotated = _get_gptj_rotated_x(
744
+ x * sin, x_rotated_mask, BLOCK_S, BLOCK_D, BLOCK_D_HALF, True
745
+ )
746
+
747
+ out_x = x * cos + x_rotated
748
+ out_x = out_x.to(x_ptr.dtype.element_ty)
749
+ x_out_offs = (
750
+ b * stride_out_b
751
+ + s_offs[:, None] * stride_out_s
752
+ + h * stride_out_h
753
+ + d_offs[None, :] * stride_out_d
754
+ )
755
+
756
+ tl.store(out_ptr + x_out_offs, out_x, mask=x_mask)
757
+
758
+ if HAVE_NOPE and not INPLACE:
759
+ if NOPE_FIRST:
760
+ x = tl.load(x_ptr + x_offs - BLOCK_D * stride_x_d, mask=x_mask)
761
+ tl.store(out_ptr + x_out_offs - BLOCK_D * stride_out_d, x, mask=x_mask)
762
+ else:
763
+ x = tl.load(x_ptr + x_offs + BLOCK_D * stride_x_d, mask=x_mask)
764
+ tl.store(out_ptr + x_out_offs + BLOCK_D * stride_out_d, x, mask=x_mask)
765
+
766
+
767
+ @triton.jit
768
+ def _rope_kernel_thd_cached_2c_fwd(
769
+ x_ptr,
770
+ y_ptr,
771
+ cos_ptr,
772
+ sin_ptr,
773
+ pos_ptr,
774
+ off_ptr,
775
+ out_x_ptr,
776
+ out_y_ptr,
777
+ stride_x_t,
778
+ stride_x_h,
779
+ stride_x_d,
780
+ stride_y_t,
781
+ stride_y_h,
782
+ stride_y_d,
783
+ stride_cos_t,
784
+ stride_cos_d,
785
+ stride_pos_t,
786
+ stride_out_x_t,
787
+ stride_out_x_h,
788
+ stride_out_x_d,
789
+ stride_out_y_t,
790
+ stride_out_y_h,
791
+ stride_out_y_d,
792
+ T,
793
+ HAVE_NOPE: tl.constexpr,
794
+ NOPE_FIRST: tl.constexpr,
795
+ INPLACE: tl.constexpr,
796
+ REUSE_FREQS_FRONT_PART: tl.constexpr,
797
+ IS_NEOX: tl.constexpr,
798
+ HAVE_POS: tl.constexpr,
799
+ HAVE_OFFS: tl.constexpr,
800
+ BLOCK_T: tl.constexpr,
801
+ SPLIT_H_SIZE: tl.constexpr,
802
+ BLOCK_D: tl.constexpr,
803
+ BLOCK_D_HALF: tl.constexpr,
804
+ num_stages: tl.constexpr,
805
+ ):
806
+ h_s = tl.program_id(0)
807
+ pid_t = tl.program_id(1)
808
+
809
+ tl.assume(stride_x_t > 0)
810
+ tl.assume(stride_x_h > 0)
811
+ tl.assume(stride_x_d > 0)
812
+ tl.assume(stride_y_t > 0)
813
+ tl.assume(stride_y_h > 0)
814
+ tl.assume(stride_y_d > 0)
815
+ tl.assume(stride_cos_t > 0)
816
+ tl.assume(stride_cos_d > 0)
817
+ tl.assume(stride_pos_t > 0)
818
+ tl.assume(stride_out_x_t > 0)
819
+ tl.assume(stride_out_x_h > 0)
820
+ tl.assume(stride_out_x_d > 0)
821
+ tl.assume(stride_out_y_t > 0)
822
+ tl.assume(stride_out_y_h > 0)
823
+ tl.assume(stride_out_y_d > 0)
824
+
825
+ t_offs = pid_t * BLOCK_T + tl.arange(0, BLOCK_T)
826
+ d_offs = tl.arange(0, BLOCK_D)
827
+ t_mask = t_offs < T
828
+
829
+ if HAVE_POS:
830
+ pos_offs = t_offs * stride_pos_t
831
+ pos = tl.load(pos_ptr + pos_offs, mask=t_mask)
832
+ if HAVE_OFFS:
833
+ offset = tl.load(off_ptr + pos_offs, mask=t_mask)
834
+ t_cos_offs = pos + offset
835
+ else:
836
+ t_cos_offs = pos
837
+ else:
838
+ t_cos_offs = t_offs
839
+
840
+ if REUSE_FREQS_FRONT_PART:
841
+ if IS_NEOX:
842
+ d_cos_offs = d_offs
843
+ d_cos_offs = tl.where(
844
+ (d_cos_offs < BLOCK_D_HALF),
845
+ d_cos_offs,
846
+ d_cos_offs - BLOCK_D_HALF,
847
+ ).to(d_cos_offs.dtype)
848
+ d_cos_mask = d_cos_offs < BLOCK_D_HALF
849
+ else:
850
+ d_cos_offs = tl.arange(0, BLOCK_D) // 2
851
+ d_cos_mask = d_cos_offs < BLOCK_D_HALF
852
+ else:
853
+ d_cos_offs = d_offs
854
+ d_cos_mask = d_cos_offs < BLOCK_D
855
+
856
+ cos_mask = t_mask[:, None] & d_cos_mask[None, :]
857
+ cos_offs = t_cos_offs[:, None] * stride_cos_t + d_cos_offs[None, :] * stride_cos_d
858
+ cos = tl.load(cos_ptr + cos_offs, mask=cos_mask)
859
+ sin = tl.load(sin_ptr + cos_offs, mask=cos_mask)
860
+
861
+ nope_offs = 0
862
+ if HAVE_NOPE and NOPE_FIRST:
863
+ nope_offs = BLOCK_D
864
+
865
+ h_start_idx = h_s * SPLIT_H_SIZE
866
+
867
+ x_mask = t_mask[:, None] & (d_offs < BLOCK_D)[None, :]
868
+
869
+ if IS_NEOX:
870
+ x_rotated_mask = (d_offs < BLOCK_D_HALF)[None, :]
871
+ else:
872
+ x_rotated_mask = (d_offs % 2 == 0)[None, :]
873
+
874
+ d_offs += nope_offs
875
+ for h in tl.range(0, SPLIT_H_SIZE, 1, num_stages=num_stages):
876
+ x_offs = (
877
+ t_offs[:, None] * stride_x_t
878
+ + d_offs[None, :] * stride_x_d
879
+ + (h_start_idx + h) * stride_x_h
880
+ )
881
+ y_offs = (
882
+ t_offs[:, None] * stride_y_t
883
+ + d_offs[None, :] * stride_y_d
884
+ + (h_start_idx + h) * stride_y_h
885
+ )
886
+
887
+ x = tl.load(x_ptr + x_offs, mask=x_mask)
888
+ y = tl.load(y_ptr + y_offs, mask=x_mask)
889
+
890
+ if IS_NEOX:
891
+ x_rotated = _get_neox_rotated_x(
892
+ x, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF
893
+ )
894
+ y_rotated = _get_neox_rotated_x(
895
+ y, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF
896
+ )
897
+ else:
898
+ x_rotated = _get_gptj_rotated_x(
899
+ x, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF
900
+ )
901
+ y_rotated = _get_gptj_rotated_x(
902
+ y, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF
903
+ )
904
+
905
+ out_x = x * cos + x_rotated * sin
906
+ out_x = out_x.to(x_ptr.dtype.element_ty)
907
+ out_y = y * cos + y_rotated * sin
908
+ out_y = out_y.to(y_ptr.dtype.element_ty)
909
+
910
+ out_x_offs = (
911
+ t_offs[:, None] * stride_out_x_t
912
+ + d_offs[None, :] * stride_out_x_d
913
+ + (h_start_idx + h) * stride_out_x_h
914
+ )
915
+ out_y_offs = (
916
+ t_offs[:, None] * stride_out_y_t
917
+ + d_offs[None, :] * stride_out_y_d
918
+ + (h_start_idx + h) * stride_out_y_h
919
+ )
920
+ tl.store(out_x_ptr + out_x_offs, out_x, mask=x_mask)
921
+ tl.store(out_y_ptr + out_y_offs, out_y, mask=x_mask)
922
+
923
+ if HAVE_NOPE and not INPLACE:
924
+ if NOPE_FIRST:
925
+ x = tl.load(x_ptr + x_offs - BLOCK_D * stride_x_d, mask=x_mask)
926
+ tl.store(
927
+ out_x_ptr + out_x_offs - BLOCK_D * stride_out_x_d, x, mask=x_mask
928
+ )
929
+ y = tl.load(y_ptr + y_offs - BLOCK_D * stride_y_d, mask=x_mask)
930
+ tl.store(
931
+ out_y_ptr + out_y_offs - BLOCK_D * stride_out_y_d, y, mask=x_mask
932
+ )
933
+ else:
934
+ x = tl.load(x_ptr + x_offs + BLOCK_D * stride_x_d, mask=x_mask)
935
+ tl.store(
936
+ out_x_ptr + out_x_offs + BLOCK_D * stride_out_x_d, x, mask=x_mask
937
+ )
938
+ y = tl.load(y_ptr + y_offs + BLOCK_D * stride_y_d, mask=x_mask)
939
+ tl.store(
940
+ out_y_ptr + out_y_offs + BLOCK_D * stride_out_y_d, y, mask=x_mask
941
+ )
942
+
943
+
944
+ @triton.jit
945
+ def _rope_kernel_thd_cached_2c_bwd(
946
+ x_ptr,
947
+ y_ptr,
948
+ cos_ptr,
949
+ sin_ptr,
950
+ pos_ptr,
951
+ off_ptr,
952
+ out_x_ptr,
953
+ out_y_ptr,
954
+ stride_x_t,
955
+ stride_x_h,
956
+ stride_x_d,
957
+ stride_y_t,
958
+ stride_y_h,
959
+ stride_y_d,
960
+ stride_cos_t,
961
+ stride_cos_d,
962
+ stride_pos_t,
963
+ stride_out_x_t,
964
+ stride_out_x_h,
965
+ stride_out_x_d,
966
+ stride_out_y_t,
967
+ stride_out_y_h,
968
+ stride_out_y_d,
969
+ T,
970
+ HAVE_NOPE: tl.constexpr,
971
+ NOPE_FIRST: tl.constexpr,
972
+ INPLACE: tl.constexpr,
973
+ REUSE_FREQS_FRONT_PART: tl.constexpr,
974
+ IS_NEOX: tl.constexpr,
975
+ HAVE_POS: tl.constexpr,
976
+ HAVE_OFFS: tl.constexpr,
977
+ BLOCK_T: tl.constexpr,
978
+ SPLIT_H_SIZE: tl.constexpr,
979
+ BLOCK_D: tl.constexpr,
980
+ BLOCK_D_HALF: tl.constexpr,
981
+ num_stages: tl.constexpr,
982
+ ):
983
+ h_s = tl.program_id(0)
984
+ pid_t = tl.program_id(1)
985
+
986
+ tl.assume(stride_x_t > 0)
987
+ tl.assume(stride_x_h > 0)
988
+ tl.assume(stride_x_d > 0)
989
+ tl.assume(stride_y_t > 0)
990
+ tl.assume(stride_y_h > 0)
991
+ tl.assume(stride_y_d > 0)
992
+ tl.assume(stride_cos_t > 0)
993
+ tl.assume(stride_cos_d > 0)
994
+ tl.assume(stride_pos_t > 0)
995
+ tl.assume(stride_out_x_t > 0)
996
+ tl.assume(stride_out_x_h > 0)
997
+ tl.assume(stride_out_x_d > 0)
998
+ tl.assume(stride_out_y_t > 0)
999
+ tl.assume(stride_out_y_h > 0)
1000
+ tl.assume(stride_out_y_d > 0)
1001
+
1002
+ t_offs = pid_t * BLOCK_T + tl.arange(0, BLOCK_T)
1003
+ d_offs = tl.arange(0, BLOCK_D)
1004
+ t_mask = t_offs < T
1005
+
1006
+ if HAVE_POS:
1007
+ pos_offs = t_offs * stride_pos_t
1008
+ pos = tl.load(pos_ptr + pos_offs, mask=t_mask)
1009
+ if HAVE_OFFS:
1010
+ offset = tl.load(off_ptr + pos_offs, mask=t_mask)
1011
+ t_cos_offs = pos + offset
1012
+ else:
1013
+ t_cos_offs = pos
1014
+ else:
1015
+ t_cos_offs = t_offs
1016
+
1017
+ if REUSE_FREQS_FRONT_PART:
1018
+ if IS_NEOX:
1019
+ d_cos_offs = d_offs
1020
+ d_cos_offs = tl.where(
1021
+ (d_cos_offs < BLOCK_D_HALF),
1022
+ d_cos_offs,
1023
+ d_cos_offs - BLOCK_D_HALF,
1024
+ ).to(d_cos_offs.dtype)
1025
+ d_cos_mask = d_cos_offs < BLOCK_D_HALF
1026
+ else:
1027
+ d_cos_offs = tl.arange(0, BLOCK_D) // 2
1028
+ d_cos_mask = d_cos_offs < BLOCK_D_HALF
1029
+ else:
1030
+ d_cos_offs = d_offs
1031
+ d_cos_mask = d_cos_offs < BLOCK_D
1032
+
1033
+ cos_mask = t_mask[:, None] & d_cos_mask[None, :]
1034
+ cos_offs = t_cos_offs[:, None] * stride_cos_t + d_cos_offs[None, :] * stride_cos_d
1035
+ cos = tl.load(cos_ptr + cos_offs, mask=cos_mask)
1036
+ sin = tl.load(sin_ptr + cos_offs, mask=cos_mask)
1037
+
1038
+ nope_offs = 0
1039
+ if HAVE_NOPE and NOPE_FIRST:
1040
+ nope_offs = BLOCK_D
1041
+
1042
+ h_start_idx = h_s * SPLIT_H_SIZE
1043
+
1044
+ x_mask = t_mask[:, None] & (d_offs < BLOCK_D)[None, :]
1045
+
1046
+ if IS_NEOX:
1047
+ x_rotated_mask = (d_offs < BLOCK_D_HALF)[None, :]
1048
+ else:
1049
+ x_rotated_mask = (d_offs % 2 == 0)[None, :]
1050
+
1051
+ d_offs += nope_offs
1052
+ for h in tl.range(0, SPLIT_H_SIZE, 1, num_stages=num_stages):
1053
+ x_offs = (
1054
+ t_offs[:, None] * stride_x_t
1055
+ + d_offs[None, :] * stride_x_d
1056
+ + (h_start_idx + h) * stride_x_h
1057
+ )
1058
+ y_offs = (
1059
+ t_offs[:, None] * stride_y_t
1060
+ + d_offs[None, :] * stride_y_d
1061
+ + (h_start_idx + h) * stride_y_h
1062
+ )
1063
+
1064
+ x = tl.load(x_ptr + x_offs, mask=x_mask)
1065
+ y = tl.load(y_ptr + y_offs, mask=x_mask)
1066
+
1067
+ if IS_NEOX:
1068
+ x_rotated = _get_neox_rotated_x(
1069
+ x * sin, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF, True
1070
+ )
1071
+ y_rotated = _get_neox_rotated_x(
1072
+ y * sin, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF, True
1073
+ )
1074
+ else:
1075
+ x_rotated = _get_gptj_rotated_x(
1076
+ x * sin, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF, True
1077
+ )
1078
+ y_rotated = _get_gptj_rotated_x(
1079
+ y * sin, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF, True
1080
+ )
1081
+
1082
+ out_x = x * cos + x_rotated
1083
+ out_x = out_x.to(x_ptr.dtype.element_ty)
1084
+ out_y = y * cos + y_rotated
1085
+ out_y = out_y.to(y_ptr.dtype.element_ty)
1086
+
1087
+ out_x_offs = (
1088
+ t_offs[:, None] * stride_out_x_t
1089
+ + d_offs[None, :] * stride_out_x_d
1090
+ + (h_start_idx + h) * stride_out_x_h
1091
+ )
1092
+ out_y_offs = (
1093
+ t_offs[:, None] * stride_out_y_t
1094
+ + d_offs[None, :] * stride_out_y_d
1095
+ + (h_start_idx + h) * stride_out_y_h
1096
+ )
1097
+ tl.store(out_x_ptr + out_x_offs, out_x, mask=x_mask)
1098
+ tl.store(out_y_ptr + out_y_offs, out_y, mask=x_mask)
1099
+
1100
+ if HAVE_NOPE and not INPLACE:
1101
+ # TODO check
1102
+ if NOPE_FIRST:
1103
+ x = tl.load(x_ptr + x_offs - BLOCK_D * stride_x_d, mask=x_mask)
1104
+ tl.store(
1105
+ out_x_ptr + out_x_offs - BLOCK_D * stride_out_x_d, x, mask=x_mask
1106
+ )
1107
+ y = tl.load(y_ptr + y_offs - BLOCK_D * stride_y_d, mask=x_mask)
1108
+ tl.store(
1109
+ out_y_ptr + out_y_offs - BLOCK_D * stride_out_y_d, y, mask=x_mask
1110
+ )
1111
+ else:
1112
+ x = tl.load(x_ptr + x_offs + BLOCK_D * stride_x_d, mask=x_mask)
1113
+ tl.store(
1114
+ out_x_ptr + out_x_offs + BLOCK_D * stride_out_x_d, x, mask=x_mask
1115
+ )
1116
+ y = tl.load(y_ptr + y_offs + BLOCK_D * stride_y_d, mask=x_mask)
1117
+ tl.store(
1118
+ out_y_ptr + out_y_offs + BLOCK_D * stride_out_y_d, y, mask=x_mask
1119
+ )
1120
+
1121
+
1122
+ @triton.jit
1123
+ def _rope_kernel_cached_thd_2c_gqa_fwd(
1124
+ x_ptr,
1125
+ y_ptr,
1126
+ cos_ptr,
1127
+ sin_ptr,
1128
+ pos_ptr,
1129
+ off_ptr,
1130
+ out_x_ptr,
1131
+ out_y_ptr,
1132
+ stride_x_t,
1133
+ stride_x_h,
1134
+ stride_x_d,
1135
+ stride_y_t,
1136
+ stride_y_h,
1137
+ stride_y_d,
1138
+ stride_cos_t,
1139
+ stride_cos_d,
1140
+ stride_pos_t,
1141
+ stride_out_x_t,
1142
+ stride_out_x_h,
1143
+ stride_out_x_d,
1144
+ stride_out_y_t,
1145
+ stride_out_y_h,
1146
+ stride_out_y_d,
1147
+ T,
1148
+ HAVE_NOPE: tl.constexpr,
1149
+ NOPE_FIRST: tl.constexpr,
1150
+ INPLACE: tl.constexpr,
1151
+ REUSE_FREQS_FRONT_PART: tl.constexpr,
1152
+ IS_NEOX: tl.constexpr,
1153
+ HAVE_POS: tl.constexpr,
1154
+ HAVE_OFFS: tl.constexpr,
1155
+ BLOCK_T: tl.constexpr,
1156
+ QH_per_G: tl.constexpr,
1157
+ BLOCK_D: tl.constexpr,
1158
+ BLOCK_D_HALF: tl.constexpr,
1159
+ num_stages: tl.constexpr,
1160
+ ):
1161
+ h_s = tl.program_id(0)
1162
+ pid_t = tl.program_id(1)
1163
+
1164
+ tl.assume(stride_x_t > 0)
1165
+ tl.assume(stride_x_h > 0)
1166
+ tl.assume(stride_x_d > 0)
1167
+ tl.assume(stride_y_t > 0)
1168
+ tl.assume(stride_y_h > 0)
1169
+ tl.assume(stride_y_d > 0)
1170
+ tl.assume(stride_cos_t > 0)
1171
+ tl.assume(stride_cos_d > 0)
1172
+ tl.assume(stride_pos_t > 0)
1173
+ tl.assume(stride_out_x_t > 0)
1174
+ tl.assume(stride_out_x_h > 0)
1175
+ tl.assume(stride_out_x_d > 0)
1176
+ tl.assume(stride_out_y_t > 0)
1177
+ tl.assume(stride_out_y_h > 0)
1178
+ tl.assume(stride_out_y_d > 0)
1179
+
1180
+ t_offs = pid_t * BLOCK_T + tl.arange(0, BLOCK_T)
1181
+ d_offs = tl.arange(0, BLOCK_D)
1182
+ t_mask = t_offs < T
1183
+
1184
+ if HAVE_POS:
1185
+ pos_offs = t_offs * stride_pos_t
1186
+ pos = tl.load(pos_ptr + pos_offs, mask=t_mask)
1187
+ if HAVE_OFFS:
1188
+ offset = tl.load(off_ptr + pos_offs, mask=t_mask)
1189
+ t_cos_offs = pos + offset
1190
+ else:
1191
+ t_cos_offs = pos
1192
+ else:
1193
+ t_cos_offs = t_offs
1194
+
1195
+ if REUSE_FREQS_FRONT_PART:
1196
+ if IS_NEOX:
1197
+ d_cos_offs = d_offs
1198
+ d_cos_offs = tl.where(
1199
+ (d_cos_offs < BLOCK_D_HALF),
1200
+ d_cos_offs,
1201
+ d_cos_offs - BLOCK_D_HALF,
1202
+ ).to(d_cos_offs.dtype)
1203
+ d_cos_mask = d_cos_offs < BLOCK_D_HALF
1204
+ else:
1205
+ d_cos_offs = tl.arange(0, BLOCK_D) // 2
1206
+ d_cos_mask = d_cos_offs < BLOCK_D_HALF
1207
+ else:
1208
+ d_cos_offs = d_offs
1209
+ d_cos_mask = d_cos_offs < BLOCK_D
1210
+
1211
+ cos_mask = t_mask[:, None] & d_cos_mask[None, :]
1212
+ cos_offs = t_cos_offs[:, None] * stride_cos_t + d_cos_offs[None, :] * stride_cos_d
1213
+ cos = tl.load(cos_ptr + cos_offs, mask=cos_mask)
1214
+ sin = tl.load(sin_ptr + cos_offs, mask=cos_mask)
1215
+
1216
+ nope_offs = 0
1217
+ if HAVE_NOPE and NOPE_FIRST:
1218
+ nope_offs = BLOCK_D
1219
+
1220
+ h_start_idx = h_s * QH_per_G
1221
+
1222
+ x_mask = t_mask[:, None] & (d_offs < BLOCK_D)[None, :]
1223
+
1224
+ if IS_NEOX:
1225
+ x_rotated_mask = (d_offs < BLOCK_D_HALF)[None, :]
1226
+ else:
1227
+ x_rotated_mask = (d_offs % 2 == 0)[None, :]
1228
+
1229
+ d_offs += nope_offs
1230
+ y_offs = (
1231
+ t_offs[:, None] * stride_y_t + d_offs[None, :] * stride_y_d + h_s * stride_y_h
1232
+ )
1233
+ y = tl.load(y_ptr + y_offs, mask=x_mask)
1234
+
1235
+ if IS_NEOX:
1236
+ y_rotated = _get_neox_rotated_x(
1237
+ y, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF
1238
+ )
1239
+ else:
1240
+ y_rotated = _get_gptj_rotated_x(
1241
+ y, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF
1242
+ )
1243
+
1244
+ out_y_offs = (
1245
+ t_offs[:, None] * stride_out_y_t
1246
+ + d_offs[None, :] * stride_out_y_d
1247
+ + h_s * stride_out_y_h
1248
+ )
1249
+ out_y = y * cos + y_rotated * sin
1250
+ out_y = out_y.to(y_ptr.dtype.element_ty)
1251
+ tl.store(out_y_ptr + out_y_offs, out_y, mask=x_mask)
1252
+
1253
+ if HAVE_NOPE and not INPLACE:
1254
+ if NOPE_FIRST:
1255
+ y = tl.load(y_ptr + y_offs - BLOCK_D * stride_y_d, mask=x_mask)
1256
+ tl.store(out_y_ptr + out_y_offs - BLOCK_D * stride_out_y_d, y, mask=x_mask)
1257
+ else:
1258
+ y = tl.load(y_ptr + y_offs + BLOCK_D * stride_y_d, mask=x_mask)
1259
+ tl.store(out_y_ptr + out_y_offs + BLOCK_D * stride_out_y_d, y, mask=x_mask)
1260
+
1261
+ for h in tl.range(0, QH_per_G, 1, num_stages=num_stages):
1262
+ x_offs = (
1263
+ t_offs[:, None] * stride_x_t
1264
+ + d_offs[None, :] * stride_x_d
1265
+ + (h_start_idx + h) * stride_x_h
1266
+ )
1267
+
1268
+ x = tl.load(x_ptr + x_offs, mask=x_mask)
1269
+
1270
+ if IS_NEOX:
1271
+ x_rotated = _get_neox_rotated_x(
1272
+ x, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF
1273
+ )
1274
+ else:
1275
+ x_rotated = _get_gptj_rotated_x(
1276
+ x, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF
1277
+ )
1278
+
1279
+ out_x_offs = (
1280
+ t_offs[:, None] * stride_out_x_t
1281
+ + d_offs[None, :] * stride_out_x_d
1282
+ + (h_start_idx + h) * stride_out_x_h
1283
+ )
1284
+ out_x = x * cos + x_rotated * sin
1285
+ out_x = out_x.to(x_ptr.dtype.element_ty)
1286
+
1287
+ tl.store(out_x_ptr + out_x_offs, out_x, mask=x_mask)
1288
+
1289
+ if HAVE_NOPE and not INPLACE:
1290
+ if NOPE_FIRST:
1291
+ x = tl.load(x_ptr + x_offs - BLOCK_D * stride_x_d, mask=x_mask)
1292
+ tl.store(
1293
+ out_x_ptr + out_x_offs - BLOCK_D * stride_out_x_d, x, mask=x_mask
1294
+ )
1295
+ else:
1296
+ x = tl.load(x_ptr + x_offs + BLOCK_D * stride_x_d, mask=x_mask)
1297
+ tl.store(
1298
+ out_x_ptr + out_x_offs + BLOCK_D * stride_out_x_d, x, mask=x_mask
1299
+ )
1300
+
1301
+
1302
+ @triton.jit
1303
+ def _rope_kernel_cached_thd_2c_gqa_onehead_fwd(
1304
+ x_ptr,
1305
+ y_ptr,
1306
+ cos_ptr,
1307
+ sin_ptr,
1308
+ pos_ptr,
1309
+ off_ptr,
1310
+ out_x_ptr,
1311
+ out_y_ptr,
1312
+ stride_x_t,
1313
+ stride_x_h,
1314
+ stride_x_d,
1315
+ stride_y_t,
1316
+ stride_y_h,
1317
+ stride_y_d,
1318
+ stride_cos_t,
1319
+ stride_cos_d,
1320
+ stride_pos_t,
1321
+ stride_out_x_t,
1322
+ stride_out_x_h,
1323
+ stride_out_x_d,
1324
+ stride_out_y_t,
1325
+ stride_out_y_h,
1326
+ stride_out_y_d,
1327
+ T,
1328
+ HAVE_NOPE: tl.constexpr,
1329
+ NOPE_FIRST: tl.constexpr,
1330
+ INPLACE: tl.constexpr,
1331
+ REUSE_FREQS_FRONT_PART: tl.constexpr,
1332
+ IS_NEOX: tl.constexpr,
1333
+ HAVE_POS: tl.constexpr,
1334
+ HAVE_OFFS: tl.constexpr,
1335
+ BLOCK_T: tl.constexpr,
1336
+ G: tl.constexpr,
1337
+ BLOCK_D: tl.constexpr,
1338
+ BLOCK_D_HALF: tl.constexpr,
1339
+ ):
1340
+ pid_t = tl.program_id(0)
1341
+ hq = tl.program_id(1)
1342
+
1343
+ tl.assume(stride_x_t > 0)
1344
+ tl.assume(stride_x_h > 0)
1345
+ tl.assume(stride_x_d > 0)
1346
+ tl.assume(stride_y_t > 0)
1347
+ tl.assume(stride_y_h > 0)
1348
+ tl.assume(stride_y_d > 0)
1349
+ tl.assume(stride_cos_t > 0)
1350
+ tl.assume(stride_cos_d > 0)
1351
+ tl.assume(stride_pos_t > 0)
1352
+ tl.assume(stride_out_x_t > 0)
1353
+ tl.assume(stride_out_x_h > 0)
1354
+ tl.assume(stride_out_x_d > 0)
1355
+ tl.assume(stride_out_y_t > 0)
1356
+ tl.assume(stride_out_y_h > 0)
1357
+ tl.assume(stride_out_y_d > 0)
1358
+
1359
+ t_offs = pid_t * BLOCK_T + tl.arange(0, BLOCK_T)
1360
+ d_offs = tl.arange(0, BLOCK_D)
1361
+ t_mask = t_offs < T
1362
+
1363
+ if HAVE_POS:
1364
+ pos_offs = t_offs * stride_pos_t
1365
+ pos = tl.load(pos_ptr + pos_offs, mask=t_mask)
1366
+ if HAVE_OFFS:
1367
+ offset = tl.load(off_ptr + pos_offs, mask=t_mask)
1368
+ t_cos_offs = pos + offset
1369
+ else:
1370
+ t_cos_offs = pos
1371
+ else:
1372
+ t_cos_offs = t_offs
1373
+
1374
+ if REUSE_FREQS_FRONT_PART:
1375
+ if IS_NEOX:
1376
+ d_cos_offs = d_offs
1377
+ d_cos_offs = tl.where(
1378
+ (d_cos_offs < BLOCK_D_HALF),
1379
+ d_cos_offs,
1380
+ d_cos_offs - BLOCK_D_HALF,
1381
+ ).to(d_cos_offs.dtype)
1382
+ d_cos_mask = d_cos_offs < BLOCK_D_HALF
1383
+ else:
1384
+ d_cos_offs = tl.arange(0, BLOCK_D) // 2
1385
+ d_cos_mask = d_cos_offs < BLOCK_D_HALF
1386
+ else:
1387
+ d_cos_offs = d_offs
1388
+ d_cos_mask = d_cos_offs < BLOCK_D
1389
+
1390
+ cos_mask = t_mask[:, None] & d_cos_mask[None, :]
1391
+ cos_offs = t_cos_offs[:, None] * stride_cos_t + d_cos_offs[None, :] * stride_cos_d
1392
+ cos = tl.load(cos_ptr + cos_offs, mask=cos_mask)
1393
+ sin = tl.load(sin_ptr + cos_offs, mask=cos_mask)
1394
+
1395
+ nope_offs = 0
1396
+ if HAVE_NOPE and NOPE_FIRST:
1397
+ nope_offs = BLOCK_D
1398
+
1399
+ x_mask = t_mask[:, None] & (d_offs < BLOCK_D)[None, :]
1400
+
1401
+ if IS_NEOX:
1402
+ x_rotated_mask = (d_offs < BLOCK_D_HALF)[None, :]
1403
+ else:
1404
+ x_rotated_mask = (d_offs % 2 == 0)[None, :]
1405
+
1406
+ d_offs += nope_offs
1407
+ x_offs = (
1408
+ t_offs[:, None] * stride_x_t + d_offs[None, :] * stride_x_d + hq * stride_x_h
1409
+ )
1410
+ x = tl.load(x_ptr + x_offs, mask=x_mask)
1411
+
1412
+ if IS_NEOX:
1413
+ x_rotated = _get_neox_rotated_x(
1414
+ x, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF
1415
+ )
1416
+ else:
1417
+ x_rotated = _get_gptj_rotated_x(
1418
+ x, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF
1419
+ )
1420
+
1421
+ out_x_offs = (
1422
+ t_offs[:, None] * stride_out_x_t
1423
+ + d_offs[None, :] * stride_out_x_d
1424
+ + hq * stride_out_x_h
1425
+ )
1426
+ out_x = x * cos + x_rotated * sin
1427
+ out_x = out_x.to(x_ptr.dtype.element_ty)
1428
+ tl.store(out_x_ptr + out_x_offs, out_x, mask=x_mask)
1429
+
1430
+ if HAVE_NOPE and not INPLACE:
1431
+ if NOPE_FIRST:
1432
+ x = tl.load(x_ptr + x_offs - BLOCK_D * stride_x_d, mask=x_mask)
1433
+ tl.store(out_x_ptr + out_x_offs - BLOCK_D * stride_out_x_d, x, mask=x_mask)
1434
+ else:
1435
+ x = tl.load(x_ptr + x_offs + BLOCK_D * stride_x_d, mask=x_mask)
1436
+ tl.store(out_x_ptr + out_x_offs + BLOCK_D * stride_out_x_d, x, mask=x_mask)
1437
+
1438
+ if hq < G:
1439
+ y_offs = (
1440
+ t_offs[:, None] * stride_y_t
1441
+ + d_offs[None, :] * stride_x_d
1442
+ + hq * stride_y_h
1443
+ )
1444
+ y = tl.load(y_ptr + y_offs, mask=x_mask)
1445
+
1446
+ if IS_NEOX:
1447
+ y_rotated = _get_neox_rotated_x(
1448
+ y, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF
1449
+ )
1450
+ else:
1451
+ y_rotated = _get_gptj_rotated_x(
1452
+ y, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF
1453
+ )
1454
+
1455
+ out_y_offs = (
1456
+ t_offs[:, None] * stride_out_y_t
1457
+ + d_offs[None, :] * stride_out_y_d
1458
+ + hq * stride_out_y_h
1459
+ )
1460
+ out_y = y * cos + y_rotated * sin
1461
+ out_y = out_y.to(y_ptr.dtype.element_ty)
1462
+ tl.store(out_y_ptr + out_y_offs, out_y, mask=x_mask)
1463
+
1464
+ if HAVE_NOPE and not INPLACE:
1465
+ if NOPE_FIRST:
1466
+ y = tl.load(y_ptr + y_offs - BLOCK_D * stride_y_d, mask=x_mask)
1467
+ tl.store(
1468
+ out_y_ptr + out_y_offs - BLOCK_D * stride_out_y_d, y, mask=x_mask
1469
+ )
1470
+ else:
1471
+ y = tl.load(y_ptr + y_offs + BLOCK_D * stride_y_d, mask=x_mask)
1472
+ tl.store(
1473
+ out_y_ptr + out_y_offs + BLOCK_D * stride_out_y_d, y, mask=x_mask
1474
+ )
1475
+
1476
+
1477
+ @triton.jit
1478
+ def _rope_kernel_cached_thd_2c_gqa_bwd(
1479
+ x_ptr,
1480
+ y_ptr,
1481
+ cos_ptr,
1482
+ sin_ptr,
1483
+ pos_ptr,
1484
+ off_ptr,
1485
+ out_x_ptr,
1486
+ out_y_ptr,
1487
+ stride_x_t,
1488
+ stride_x_h,
1489
+ stride_x_d,
1490
+ stride_y_t,
1491
+ stride_y_h,
1492
+ stride_y_d,
1493
+ stride_cos_t,
1494
+ stride_cos_d,
1495
+ stride_pos_t,
1496
+ stride_out_x_t,
1497
+ stride_out_x_h,
1498
+ stride_out_x_d,
1499
+ stride_out_y_t,
1500
+ stride_out_y_h,
1501
+ stride_out_y_d,
1502
+ T,
1503
+ HAVE_NOPE: tl.constexpr,
1504
+ NOPE_FIRST: tl.constexpr,
1505
+ INPLACE: tl.constexpr,
1506
+ REUSE_FREQS_FRONT_PART: tl.constexpr,
1507
+ IS_NEOX: tl.constexpr,
1508
+ HAVE_POS: tl.constexpr,
1509
+ HAVE_OFFS: tl.constexpr,
1510
+ BLOCK_T: tl.constexpr,
1511
+ QH_per_G: tl.constexpr,
1512
+ BLOCK_D: tl.constexpr,
1513
+ BLOCK_D_HALF: tl.constexpr,
1514
+ num_stages: tl.constexpr,
1515
+ ):
1516
+ h_s = tl.program_id(0)
1517
+ pid_t = tl.program_id(1)
1518
+
1519
+ tl.assume(stride_x_t > 0)
1520
+ tl.assume(stride_x_h > 0)
1521
+ tl.assume(stride_x_d > 0)
1522
+ tl.assume(stride_y_t > 0)
1523
+ tl.assume(stride_y_h > 0)
1524
+ tl.assume(stride_y_d > 0)
1525
+ tl.assume(stride_cos_t > 0)
1526
+ tl.assume(stride_cos_d > 0)
1527
+ tl.assume(stride_pos_t > 0)
1528
+ tl.assume(stride_out_x_t > 0)
1529
+ tl.assume(stride_out_x_h > 0)
1530
+ tl.assume(stride_out_x_d > 0)
1531
+ tl.assume(stride_out_y_t > 0)
1532
+ tl.assume(stride_out_y_h > 0)
1533
+ tl.assume(stride_out_y_d > 0)
1534
+
1535
+ t_offs = pid_t * BLOCK_T + tl.arange(0, BLOCK_T)
1536
+ d_offs = tl.arange(0, BLOCK_D)
1537
+ t_mask = t_offs < T
1538
+
1539
+ if HAVE_POS:
1540
+ pos_offs = t_offs * stride_pos_t
1541
+ pos = tl.load(pos_ptr + pos_offs, mask=t_mask)
1542
+ if HAVE_OFFS:
1543
+ offset = tl.load(off_ptr + pos_offs, mask=t_mask)
1544
+ t_cos_offs = pos + offset
1545
+ else:
1546
+ t_cos_offs = pos
1547
+ else:
1548
+ t_cos_offs = t_offs
1549
+
1550
+ if REUSE_FREQS_FRONT_PART:
1551
+ if IS_NEOX:
1552
+ d_cos_offs = d_offs
1553
+ d_cos_offs = tl.where(
1554
+ (d_cos_offs < BLOCK_D_HALF),
1555
+ d_cos_offs,
1556
+ d_cos_offs - BLOCK_D_HALF,
1557
+ ).to(d_cos_offs.dtype)
1558
+ d_cos_mask = d_cos_offs < BLOCK_D_HALF
1559
+ else:
1560
+ d_cos_offs = tl.arange(0, BLOCK_D) // 2
1561
+ d_cos_mask = d_cos_offs < BLOCK_D_HALF
1562
+ else:
1563
+ d_cos_offs = d_offs
1564
+ d_cos_mask = d_cos_offs < BLOCK_D
1565
+
1566
+ cos_mask = t_mask[:, None] & d_cos_mask[None, :]
1567
+ cos_offs = t_cos_offs[:, None] * stride_cos_t + d_cos_offs[None, :] * stride_cos_d
1568
+ cos = tl.load(cos_ptr + cos_offs, mask=cos_mask)
1569
+ sin = tl.load(sin_ptr + cos_offs, mask=cos_mask)
1570
+
1571
+ nope_offs = 0
1572
+ if HAVE_NOPE and NOPE_FIRST:
1573
+ nope_offs = BLOCK_D
1574
+
1575
+ h_start_idx = h_s * QH_per_G
1576
+
1577
+ x_mask = t_mask[:, None] & (d_offs < BLOCK_D)[None, :]
1578
+
1579
+ if IS_NEOX:
1580
+ x_rotated_mask = (d_offs < BLOCK_D_HALF)[None, :]
1581
+ else:
1582
+ x_rotated_mask = (d_offs % 2 == 0)[None, :]
1583
+
1584
+ d_offs += nope_offs
1585
+ y_offs = (
1586
+ t_offs[:, None] * stride_y_t + d_offs[None, :] * stride_y_d + h_s * stride_y_h
1587
+ )
1588
+ y = tl.load(y_ptr + y_offs, mask=x_mask)
1589
+
1590
+ if IS_NEOX:
1591
+ y_rotated = _get_neox_rotated_x(
1592
+ y * sin, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF, True
1593
+ )
1594
+ else:
1595
+ y_rotated = _get_gptj_rotated_x(
1596
+ y * sin, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF, True
1597
+ )
1598
+
1599
+ out_y_offs = (
1600
+ t_offs[:, None] * stride_out_y_t
1601
+ + d_offs[None, :] * stride_out_y_d
1602
+ + h_s * stride_out_y_h
1603
+ )
1604
+ out_y = y * cos + y_rotated
1605
+ out_y = out_y.to(y_ptr.dtype.element_ty)
1606
+ tl.store(out_y_ptr + out_y_offs, out_y, mask=x_mask)
1607
+
1608
+ if HAVE_NOPE and not INPLACE:
1609
+ if NOPE_FIRST:
1610
+ y = tl.load(y_ptr + y_offs - BLOCK_D * stride_y_d, mask=x_mask)
1611
+ tl.store(out_y_ptr + out_y_offs - BLOCK_D * stride_out_y_d, y, mask=x_mask)
1612
+ else:
1613
+ y = tl.load(y_ptr + y_offs + BLOCK_D * stride_y_d, mask=x_mask)
1614
+ tl.store(out_y_ptr + out_y_offs + BLOCK_D * stride_out_y_d, y, mask=x_mask)
1615
+
1616
+ for h in tl.range(0, QH_per_G, 1, num_stages=num_stages):
1617
+ x_offs = (
1618
+ t_offs[:, None] * stride_x_t
1619
+ + d_offs[None, :] * stride_x_d
1620
+ + (h_start_idx + h) * stride_x_h
1621
+ )
1622
+
1623
+ x = tl.load(x_ptr + x_offs, mask=x_mask)
1624
+
1625
+ if IS_NEOX:
1626
+ x_rotated = _get_neox_rotated_x(
1627
+ x * sin, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF, True
1628
+ )
1629
+ else:
1630
+ x_rotated = _get_gptj_rotated_x(
1631
+ x * sin, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF, True
1632
+ )
1633
+
1634
+ out_x_offs = (
1635
+ t_offs[:, None] * stride_out_x_t
1636
+ + d_offs[None, :] * stride_out_x_d
1637
+ + (h_start_idx + h) * stride_out_x_h
1638
+ )
1639
+ out_x = x * cos + x_rotated
1640
+ out_x = out_x.to(x_ptr.dtype.element_ty)
1641
+
1642
+ tl.store(out_x_ptr + out_x_offs, out_x, mask=x_mask)
1643
+
1644
+ if HAVE_NOPE and not INPLACE:
1645
+ if NOPE_FIRST:
1646
+ x = tl.load(x_ptr + x_offs - BLOCK_D * stride_x_d, mask=x_mask)
1647
+ tl.store(
1648
+ out_x_ptr + out_x_offs - BLOCK_D * stride_out_x_d, x, mask=x_mask
1649
+ )
1650
+ else:
1651
+ x = tl.load(x_ptr + x_offs + BLOCK_D * stride_x_d, mask=x_mask)
1652
+ tl.store(
1653
+ out_x_ptr + out_x_offs + BLOCK_D * stride_out_x_d, x, mask=x_mask
1654
+ )
1655
+
1656
+
1657
+ @triton.jit
1658
+ def _rope_kernel_cached_thd_2c_gqa_onehead_bwd(
1659
+ x_ptr,
1660
+ y_ptr,
1661
+ cos_ptr,
1662
+ sin_ptr,
1663
+ pos_ptr,
1664
+ off_ptr,
1665
+ out_x_ptr,
1666
+ out_y_ptr,
1667
+ stride_x_t,
1668
+ stride_x_h,
1669
+ stride_x_d,
1670
+ stride_y_t,
1671
+ stride_y_h,
1672
+ stride_y_d,
1673
+ stride_cos_t,
1674
+ stride_cos_d,
1675
+ stride_pos_t,
1676
+ stride_out_x_t,
1677
+ stride_out_x_h,
1678
+ stride_out_x_d,
1679
+ stride_out_y_t,
1680
+ stride_out_y_h,
1681
+ stride_out_y_d,
1682
+ T,
1683
+ HAVE_NOPE: tl.constexpr,
1684
+ NOPE_FIRST: tl.constexpr,
1685
+ INPLACE: tl.constexpr,
1686
+ REUSE_FREQS_FRONT_PART: tl.constexpr,
1687
+ IS_NEOX: tl.constexpr,
1688
+ HAVE_POS: tl.constexpr,
1689
+ HAVE_OFFS: tl.constexpr,
1690
+ BLOCK_T: tl.constexpr,
1691
+ G: tl.constexpr,
1692
+ BLOCK_D: tl.constexpr,
1693
+ BLOCK_D_HALF: tl.constexpr,
1694
+ ):
1695
+ pid_t = tl.program_id(0)
1696
+ hq = tl.program_id(1)
1697
+
1698
+ tl.assume(stride_x_t > 0)
1699
+ tl.assume(stride_x_h > 0)
1700
+ tl.assume(stride_x_d > 0)
1701
+ tl.assume(stride_y_t > 0)
1702
+ tl.assume(stride_y_h > 0)
1703
+ tl.assume(stride_y_d > 0)
1704
+ tl.assume(stride_cos_t > 0)
1705
+ tl.assume(stride_cos_d > 0)
1706
+ tl.assume(stride_pos_t > 0)
1707
+ tl.assume(stride_out_x_t > 0)
1708
+ tl.assume(stride_out_x_h > 0)
1709
+ tl.assume(stride_out_x_d > 0)
1710
+ tl.assume(stride_out_y_t > 0)
1711
+ tl.assume(stride_out_y_h > 0)
1712
+ tl.assume(stride_out_y_d > 0)
1713
+
1714
+ t_offs = pid_t * BLOCK_T + tl.arange(0, BLOCK_T)
1715
+ d_offs = tl.arange(0, BLOCK_D)
1716
+ t_mask = t_offs < T
1717
+
1718
+ if HAVE_POS:
1719
+ pos_offs = t_offs * stride_pos_t
1720
+ pos = tl.load(pos_ptr + pos_offs, mask=t_mask)
1721
+ if HAVE_OFFS:
1722
+ offset = tl.load(off_ptr + pos_offs, mask=t_mask)
1723
+ t_cos_offs = pos + offset
1724
+ else:
1725
+ t_cos_offs = pos
1726
+ else:
1727
+ t_cos_offs = t_offs
1728
+
1729
+ if REUSE_FREQS_FRONT_PART:
1730
+ if IS_NEOX:
1731
+ d_cos_offs = d_offs
1732
+ d_cos_offs = tl.where(
1733
+ (d_cos_offs < BLOCK_D_HALF),
1734
+ d_cos_offs,
1735
+ d_cos_offs - BLOCK_D_HALF,
1736
+ ).to(d_cos_offs.dtype)
1737
+ d_cos_mask = d_cos_offs < BLOCK_D_HALF
1738
+ else:
1739
+ d_cos_offs = tl.arange(0, BLOCK_D) // 2
1740
+ d_cos_mask = d_cos_offs < BLOCK_D_HALF
1741
+ else:
1742
+ d_cos_offs = d_offs
1743
+ d_cos_mask = d_cos_offs < BLOCK_D
1744
+
1745
+ cos_mask = t_mask[:, None] & d_cos_mask[None, :]
1746
+ cos_offs = t_cos_offs[:, None] * stride_cos_t + d_cos_offs[None, :] * stride_cos_d
1747
+ cos = tl.load(cos_ptr + cos_offs, mask=cos_mask)
1748
+ sin = tl.load(sin_ptr + cos_offs, mask=cos_mask)
1749
+
1750
+ nope_offs = 0
1751
+ if HAVE_NOPE and NOPE_FIRST:
1752
+ nope_offs = BLOCK_D
1753
+
1754
+ x_mask = t_mask[:, None] & (d_offs < BLOCK_D)[None, :]
1755
+
1756
+ if IS_NEOX:
1757
+ x_rotated_mask = (d_offs < BLOCK_D_HALF)[None, :]
1758
+ else:
1759
+ x_rotated_mask = (d_offs % 2 == 0)[None, :]
1760
+
1761
+ d_offs += nope_offs
1762
+ x_offs = (
1763
+ t_offs[:, None] * stride_x_t + d_offs[None, :] * stride_x_d + hq * stride_x_h
1764
+ )
1765
+ x = tl.load(x_ptr + x_offs, mask=x_mask)
1766
+
1767
+ if IS_NEOX:
1768
+ x_rotated = _get_neox_rotated_x(
1769
+ x * sin, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF, True
1770
+ )
1771
+ else:
1772
+ x_rotated = _get_gptj_rotated_x(
1773
+ x * sin, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF, True
1774
+ )
1775
+
1776
+ out_x_offs = (
1777
+ t_offs[:, None] * stride_out_x_t
1778
+ + d_offs[None, :] * stride_out_x_d
1779
+ + hq * stride_out_x_h
1780
+ )
1781
+ out_x = x * cos + x_rotated
1782
+ out_x = out_x.to(x_ptr.dtype.element_ty)
1783
+ tl.store(out_x_ptr + out_x_offs, out_x, mask=x_mask)
1784
+
1785
+ if HAVE_NOPE and not INPLACE:
1786
+ if NOPE_FIRST:
1787
+ x = tl.load(x_ptr + x_offs - BLOCK_D * stride_x_d, mask=x_mask)
1788
+ tl.store(out_x_ptr + out_x_offs - BLOCK_D * stride_out_x_d, x, mask=x_mask)
1789
+ else:
1790
+ x = tl.load(x_ptr + x_offs + BLOCK_D * stride_x_d, mask=x_mask)
1791
+ tl.store(out_x_ptr + out_x_offs + BLOCK_D * stride_out_x_d, x, mask=x_mask)
1792
+
1793
+ if hq < G:
1794
+ y_offs = (
1795
+ t_offs[:, None] * stride_y_t
1796
+ + d_offs[None, :] * stride_x_d
1797
+ + hq * stride_y_h
1798
+ )
1799
+ y = tl.load(y_ptr + y_offs, mask=x_mask)
1800
+
1801
+ if IS_NEOX:
1802
+ y_rotated = _get_neox_rotated_x(
1803
+ y * sin, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF, True
1804
+ )
1805
+ else:
1806
+ y_rotated = _get_gptj_rotated_x(
1807
+ y * sin, x_rotated_mask, BLOCK_T, BLOCK_D, BLOCK_D_HALF, True
1808
+ )
1809
+
1810
+ out_y_offs = (
1811
+ t_offs[:, None] * stride_out_y_t
1812
+ + d_offs[None, :] * stride_out_y_d
1813
+ + hq * stride_out_y_h
1814
+ )
1815
+ out_y = y * cos + y_rotated
1816
+ out_y = out_y.to(y_ptr.dtype.element_ty)
1817
+ tl.store(out_y_ptr + out_y_offs, out_y, mask=x_mask)
1818
+
1819
+ if HAVE_NOPE and not INPLACE:
1820
+ if NOPE_FIRST:
1821
+ y = tl.load(y_ptr + y_offs - BLOCK_D * stride_y_d, mask=x_mask)
1822
+ tl.store(
1823
+ out_y_ptr + out_y_offs - BLOCK_D * stride_out_y_d, y, mask=x_mask
1824
+ )
1825
+ else:
1826
+ y = tl.load(y_ptr + y_offs + BLOCK_D * stride_y_d, mask=x_mask)
1827
+ tl.store(
1828
+ out_y_ptr + out_y_offs + BLOCK_D * stride_out_y_d, y, mask=x_mask
1829
+ )
1830
+
1831
+
1832
+ @triton.jit
1833
+ def _rope_fwd_2d_kernel_neox(
1834
+ x_ptr,
1835
+ cos_h_ptr,
1836
+ sin_h_ptr,
1837
+ cos_w_ptr,
1838
+ sin_w_ptr,
1839
+ out_ptr,
1840
+ stride_x_b,
1841
+ stride_x_wh,
1842
+ stride_x_h,
1843
+ stride_x_d,
1844
+ stride_cos_h_b,
1845
+ stride_cos_h_ht,
1846
+ stride_cos_h_h,
1847
+ stride_cos_h_d,
1848
+ stride_cos_w_b,
1849
+ stride_cos_w_w,
1850
+ stride_cos_w_h,
1851
+ stride_cos_w_d,
1852
+ WH: tl.constexpr,
1853
+ HEIGHT: tl.constexpr,
1854
+ WEIGHT: tl.constexpr,
1855
+ BLOCK_D: tl.constexpr,
1856
+ ):
1857
+ b = tl.program_id(0)
1858
+ h = tl.program_id(1)
1859
+
1860
+ # load cos_h [HT, BLOCK_D]
1861
+ offs_wh = tl.arange(0, WH)
1862
+ offs_cos_h_h = offs_wh // WEIGHT
1863
+ offs_d = tl.arange(0, BLOCK_D)
1864
+ offs_cos_h = (
1865
+ stride_cos_h_h * offs_cos_h_h[:, None] + stride_cos_h_d * offs_d[None, :]
1866
+ )
1867
+ mask_cos_h = offs_d < BLOCK_D // 2
1868
+ cos_h = tl.load(cos_h_ptr + offs_cos_h, mask=mask_cos_h[None, :])
1869
+
1870
+ # load sin_h
1871
+ sin_h = tl.load(sin_h_ptr + offs_cos_h, mask=mask_cos_h[None, :])
1872
+
1873
+ # load cos_w
1874
+ offs_cos_w_w = offs_wh % WEIGHT
1875
+ offs_cos_w_d = offs_d - BLOCK_D // 2
1876
+ offs_cos_w = (
1877
+ stride_cos_w_w * offs_cos_w_w[:, None] + stride_cos_w_d * offs_cos_w_d[None, :]
1878
+ )
1879
+ mask_cos_w = (offs_cos_w_d >= 0) & (offs_cos_w_d < BLOCK_D // 2)
1880
+ cos_w = tl.load(cos_w_ptr + offs_cos_w, mask=mask_cos_w[None, :])
1881
+
1882
+ # load sin_w
1883
+ sin_w = tl.load(sin_w_ptr + offs_cos_w, mask=mask_cos_w[None, :])
1884
+
1885
+ # load x
1886
+ offs_wh = tl.arange(0, WH)
1887
+ offs_x = (
1888
+ stride_x_b * b
1889
+ + stride_x_wh * offs_wh[:, None]
1890
+ + stride_x_h * h
1891
+ + stride_x_d * offs_d[None, :]
1892
+ )
1893
+ x = tl.load(x_ptr + offs_x)
1894
+
1895
+ # load x_rotated
1896
+ offs_wh = tl.arange(0, WH)
1897
+ offs_d_rotated = tl.where(offs_d < BLOCK_D // 4, offs_d + BLOCK_D // 4, offs_d)
1898
+ offs_d_rotated = tl.where(
1899
+ (offs_d >= BLOCK_D // 4) & (offs_d < BLOCK_D // 2),
1900
+ offs_d_rotated - BLOCK_D // 4,
1901
+ offs_d_rotated,
1902
+ )
1903
+ offs_d_rotated = tl.where(
1904
+ (offs_d >= BLOCK_D // 2) & (offs_d < 3 * BLOCK_D // 4),
1905
+ offs_d_rotated + BLOCK_D // 4,
1906
+ offs_d_rotated,
1907
+ )
1908
+ offs_d_rotated = tl.where(
1909
+ (offs_d >= 3 * BLOCK_D // 4) & (offs_d < BLOCK_D),
1910
+ offs_d_rotated - BLOCK_D // 4,
1911
+ offs_d_rotated,
1912
+ )
1913
+ offs_x_rotated = (
1914
+ stride_x_b * b
1915
+ + stride_x_wh * offs_wh[:, None]
1916
+ + stride_x_h * h
1917
+ + stride_x_d * offs_d_rotated[None, :]
1918
+ )
1919
+ x_rotated = tl.load(x_ptr + offs_x_rotated)
1920
+ neg_x_rotated = tl.where((offs_d >= BLOCK_D // 4) & (offs_d < BLOCK_D // 2), 1, 0)
1921
+ neg_x_rotated = tl.where(
1922
+ (offs_d >= 3 * BLOCK_D // 4) & (offs_d < BLOCK_D), 1, neg_x_rotated
1923
+ )
1924
+ x_rotated = tl.where(neg_x_rotated, x_rotated, -x_rotated)
1925
+
1926
+ # compute x1
1927
+ x1 = x * cos_h + x_rotated * sin_h
1928
+
1929
+ # compute x2
1930
+ x2 = x * cos_w + x_rotated * sin_w
1931
+
1932
+ # compute output
1933
+ out = x1 + x2
1934
+
1935
+ # store output
1936
+ tl.store(out_ptr + offs_x, out)
1937
+
1938
+
1939
+ @triton.jit
1940
+ def _rope_fwd_3d(
1941
+ x_ptr,
1942
+ freqs_real_ptr,
1943
+ freqs_imag_ptr,
1944
+ grid_sizes_ptr,
1945
+ out_ptr,
1946
+ stride_x_b,
1947
+ stride_x_l,
1948
+ stride_x_n,
1949
+ stride_x_c,
1950
+ stride_freqs_s,
1951
+ stride_freqs_c,
1952
+ stride_grid_b,
1953
+ stride_grid_d,
1954
+ stride_out_b,
1955
+ stride_out_l,
1956
+ stride_out_n,
1957
+ stride_out_c,
1958
+ L: tl.constexpr,
1959
+ N_HEADS: tl.constexpr,
1960
+ C: tl.constexpr,
1961
+ c_total: tl.constexpr,
1962
+ sp_size: tl.constexpr,
1963
+ sp_rank: tl.constexpr,
1964
+ max_freq_seq_len: tl.constexpr,
1965
+ s_per_rank: tl.constexpr,
1966
+ pad_freq_val_r: tl.constexpr,
1967
+ pad_freq_val_i: tl.constexpr,
1968
+ BLOCK_L: tl.constexpr,
1969
+ BLOCK_N: tl.constexpr,
1970
+ BLOCK_C: tl.constexpr,
1971
+ C1: tl.constexpr,
1972
+ C2: tl.constexpr,
1973
+ ):
1974
+ pid_b = tl.program_id(0)
1975
+ pid_n = tl.program_id(1)
1976
+ pid_l = tl.program_id(2)
1977
+
1978
+ l_start = pid_l * BLOCK_L
1979
+ l_off = l_start + tl.arange(0, BLOCK_L)
1980
+ s_mask = l_off < L
1981
+
1982
+ c_off = tl.arange(0, BLOCK_C)
1983
+ c_mask = c_off < c_total
1984
+
1985
+ # head mask
1986
+ n_mask = pid_n < N_HEADS
1987
+
1988
+ # broadcast to (BLOCK_L, 1, BLOCK_C)
1989
+ l_b = tl.broadcast_to(l_off[:, None], (BLOCK_L, BLOCK_C))
1990
+ c_b = tl.broadcast_to(c_off[None, :], (BLOCK_L, BLOCK_C))
1991
+
1992
+ # read grid_sizes
1993
+ f_grid = tl.load(
1994
+ grid_sizes_ptr + pid_b * stride_grid_b + 0 * stride_grid_d, mask=n_mask, other=0
1995
+ )
1996
+ h_grid = tl.load(
1997
+ grid_sizes_ptr + pid_b * stride_grid_b + 1 * stride_grid_d, mask=n_mask, other=0
1998
+ )
1999
+ w_grid = tl.load(
2000
+ grid_sizes_ptr + pid_b * stride_grid_b + 2 * stride_grid_d, mask=n_mask, other=0
2001
+ )
2002
+ h_w = h_grid * w_grid
2003
+
2004
+ global_tid = sp_rank * s_per_rank + l_b
2005
+ valid_global_tid = global_tid < f_grid * h_w
2006
+
2007
+ # caculate f h w
2008
+ f_idx = tl.where(valid_global_tid, global_tid // h_w, 0)
2009
+ rem = tl.where(valid_global_tid, global_tid % h_w, 0)
2010
+ h_idx = tl.where(valid_global_tid, rem // w_grid, 0)
2011
+ w_idx = tl.where(valid_global_tid, rem % w_grid, 0)
2012
+
2013
+ freq_row = tl.where(c_b < C1, f_idx, tl.where(c_b < C1 + C2, h_idx, w_idx))
2014
+ freq_row = tl.where(freq_row >= max_freq_seq_len, max_freq_seq_len - 1, freq_row)
2015
+
2016
+ mask_rope = s_mask[:, None] & c_mask[None, :] & n_mask & valid_global_tid[:, :]
2017
+
2018
+ # load freqs_real and freqs_imag
2019
+ off_freq = freq_row * stride_freqs_s + c_b * stride_freqs_c
2020
+ freq_r = tl.load(freqs_real_ptr + off_freq, mask=mask_rope, other=pad_freq_val_r)
2021
+ freq_i = tl.load(freqs_imag_ptr + off_freq, mask=mask_rope, other=pad_freq_val_i)
2022
+
2023
+ off_x_base = pid_b * stride_x_b + pid_n * stride_x_n
2024
+ off_x_r = off_x_base + l_b * stride_x_l + (2 * c_b) * stride_x_c
2025
+ off_x_i = off_x_base + l_b * stride_x_l + (2 * c_b + 1) * stride_x_c
2026
+
2027
+ x_r = tl.load(x_ptr + off_x_r, mask=mask_rope, other=0.0)
2028
+ x_i = tl.load(x_ptr + off_x_i, mask=mask_rope, other=0.0)
2029
+
2030
+ # complex number multiplication
2031
+ out_r = x_r * freq_r - x_i * freq_i
2032
+ out_i = x_r * freq_i + x_i * freq_r
2033
+
2034
+ # write result
2035
+ off_out_base = pid_b * stride_out_b + pid_n * stride_out_n
2036
+ off_out_r = off_out_base + l_b * stride_out_l + (2 * c_b) * stride_out_c
2037
+ off_out_i = off_out_base + l_b * stride_out_l + (2 * c_b + 1) * stride_out_c
2038
+
2039
+ tl.store(out_ptr + off_out_r, out_r, mask=mask_rope)
2040
+ tl.store(out_ptr + off_out_i, out_i, mask=mask_rope)
build/torch-rocm/_ops.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+
3
+ def get_backend() -> str:
4
+ """Detect the backend by inspecting torch."""
5
+ import torch
6
+
7
+ if hasattr(torch, "neuron"):
8
+ # Needs to be sorted before specific Torch builds, since Neuron
9
+ # extension can be loaded into e.g. CUDA Torch builds.
10
+ return "neuron"
11
+ elif torch.version.cuda is not None:
12
+ return "cuda"
13
+ elif torch.version.hip is not None:
14
+ return "rocm"
15
+ elif torch.backends.mps.is_available():
16
+ return "metal"
17
+ elif hasattr(torch.version, "xpu") and torch.version.xpu is not None:
18
+ return "xpu"
19
+ else:
20
+ return "cpu"
21
+
22
+
23
+ def _find_ops_name() -> str:
24
+ kernel_name = "aiter_rope"
25
+ unique_id = "6c454e0"
26
+ backend = get_backend()
27
+ return f"_{kernel_name}_{backend}_{unique_id}"
28
+
29
+
30
+ _OPS_NAME = _find_ops_name()
31
+
32
+ ops = getattr(torch.ops, _OPS_NAME)
33
+
34
+ def add_op_namespace_prefix(op_name: str) -> str:
35
+ """
36
+ Prefix op by namespace.
37
+ """
38
+ return f"{_OPS_NAME}::{op_name}"
build/torch-rocm/aiter_rope/__init__.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ctypes
2
+ import importlib.util
3
+ import sys
4
+ from pathlib import Path
5
+ from types import ModuleType
6
+
7
+
8
+ def _import_from_path(file_path: Path) -> ModuleType:
9
+ # We cannot use the module name as-is, after adding it to `sys.modules`,
10
+ # it would also be used for other imports. So, we make a module name that
11
+ # depends on the path for it to be unique using the hex-encoded hash of
12
+ # the path.
13
+ path_hash = "{:x}".format(ctypes.c_size_t(hash(file_path.absolute())).value)
14
+ module_name = path_hash
15
+ spec = importlib.util.spec_from_file_location(module_name, file_path)
16
+ if spec is None:
17
+ raise ImportError(f"Cannot load spec for {module_name} from {file_path}")
18
+ module = importlib.util.module_from_spec(spec)
19
+ if module is None:
20
+ raise ImportError(f"Cannot load module {module_name} from spec")
21
+ sys.modules[module_name] = module
22
+ spec.loader.exec_module(module) # type: ignore
23
+ return module
24
+
25
+
26
+ globals().update(vars(_import_from_path(Path(__file__).parent.parent / "__init__.py")))
build/torch-rocm/metadata.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "aiter-rope",
3
+ "id": "_aiter_rope_rocm_6c454e0",
4
+ "version": 1,
5
+ "license": "MIT",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "rocm"
9
+ }
10
+ }
build/torch-rocm/rope.py ADDED
@@ -0,0 +1,1728 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (C) 2024-2026, Advanced Micro Devices, Inc. All rights reserved.
3
+
4
+ import torch
5
+ import triton
6
+ import triton.language as tl
7
+ from torch import autograd
8
+ from enum import IntEnum
9
+ from typing import Tuple, Union
10
+ from ._kernels.rope import (
11
+ _rope_kernel_sbhd_fwd,
12
+ _rope_kernel_sbhd_bwd,
13
+ _rope_kernel_thd_fwd,
14
+ _rope_kernel_thd_bwd,
15
+ _rope_kernel_sbhd_cached_fwd,
16
+ _rope_kernel_sbhd_cached_bwd,
17
+ _rope_kernel_thd_cached_2c_fwd,
18
+ _rope_kernel_thd_cached_2c_bwd,
19
+ _rope_kernel_cached_thd_2c_gqa_fwd,
20
+ _rope_kernel_cached_thd_2c_gqa_onehead_fwd,
21
+ _rope_kernel_cached_thd_2c_gqa_bwd,
22
+ _rope_kernel_cached_thd_2c_gqa_onehead_bwd,
23
+ _rope_fwd_2d_kernel_neox,
24
+ _rope_fwd_3d,
25
+ _get_neox_rotated_x_1D,
26
+ _get_gptj_rotated_x_1D,
27
+ _get_neox_rotated_x,
28
+ _get_gptj_rotated_x,
29
+ )
30
+ from .utils.logger import AiterTritonLogger
31
+
32
+ __all__ = [
33
+ "_get_neox_rotated_x_1D",
34
+ "_get_gptj_rotated_x_1D",
35
+ "_get_neox_rotated_x",
36
+ "_get_gptj_rotated_x",
37
+ ]
38
+
39
+ _LOGGER = AiterTritonLogger()
40
+
41
+
42
+ class RotateStyle(IntEnum):
43
+ NEOX = (0,)
44
+ GPTJ = 1
45
+
46
+
47
+ # TODO: For now BLOCK_D is assumed to be power of 2. Expand to handle other value of D.
48
+ def _rope_fwd(
49
+ x: torch.Tensor,
50
+ out: torch.Tensor,
51
+ freqs: torch.Tensor,
52
+ rotate_style: int,
53
+ reuse_freqs_front_part: bool,
54
+ nope_first: bool,
55
+ inplace: bool,
56
+ transpose_output: bool = False,
57
+ ) -> torch.Tensor:
58
+ s, b, h, d = x.shape
59
+
60
+ if freqs.shape[-1] == d // 2:
61
+ if reuse_freqs_front_part:
62
+ have_nope = False
63
+ else:
64
+ have_nope = True
65
+ elif freqs.shape[-1] == d // 4:
66
+ have_nope = True
67
+ else:
68
+ have_nope = False
69
+
70
+ if have_nope:
71
+ BLOCK_D = d // 2
72
+ BLOCK_D_HALF = d // 4
73
+ else:
74
+ BLOCK_D = d
75
+ BLOCK_D_HALF = d // 2
76
+
77
+ # TODO: performance optimization
78
+ BLOCK_S = 32
79
+ num_warps = 4
80
+ waves_per_eu = 0
81
+ grid = (b, h, triton.cdiv(s, BLOCK_S))
82
+
83
+ _rope_kernel_sbhd_fwd[grid](
84
+ x,
85
+ freqs,
86
+ out,
87
+ *x.stride(),
88
+ *freqs.stride(),
89
+ *out.stride(),
90
+ s,
91
+ HAVE_NOPE=have_nope,
92
+ NOPE_FIRST=nope_first,
93
+ INPLACE=inplace,
94
+ REUSE_FREQS_FRONT_PART=reuse_freqs_front_part,
95
+ IS_NEOX=(rotate_style == RotateStyle.NEOX),
96
+ BLOCK_S=BLOCK_S,
97
+ BLOCK_D=BLOCK_D,
98
+ BLOCK_D_HALF=BLOCK_D_HALF,
99
+ num_warps=num_warps,
100
+ waves_per_eu=waves_per_eu,
101
+ )
102
+
103
+ return out
104
+
105
+
106
+ def rope_fwd(
107
+ x: torch.Tensor,
108
+ freqs: torch.Tensor,
109
+ rotate_style: int,
110
+ reuse_freqs_front_part: bool,
111
+ nope_first: bool,
112
+ transpose_output: bool = False,
113
+ ) -> torch.Tensor:
114
+ s, b, h, d = x.shape
115
+ out = torch.empty((s, b, h, d), dtype=x.dtype, device=x.device, requires_grad=False)
116
+
117
+ _rope_fwd(
118
+ x,
119
+ out,
120
+ freqs,
121
+ rotate_style,
122
+ reuse_freqs_front_part,
123
+ nope_first,
124
+ False,
125
+ transpose_output,
126
+ )
127
+
128
+ return out
129
+
130
+
131
+ def rope_fwd_inplace(
132
+ x: torch.Tensor,
133
+ freqs: torch.Tensor,
134
+ rotate_style: int,
135
+ reuse_freqs_front_part: bool,
136
+ nope_first: bool,
137
+ transpose_output: bool = False,
138
+ ) -> torch.Tensor:
139
+ out = x
140
+
141
+ _rope_fwd(
142
+ x,
143
+ out,
144
+ freqs,
145
+ rotate_style,
146
+ reuse_freqs_front_part,
147
+ nope_first,
148
+ True,
149
+ transpose_output,
150
+ )
151
+
152
+ return out
153
+
154
+
155
+ def _rope_bwd(
156
+ x: torch.Tensor,
157
+ out: torch.Tensor,
158
+ freqs: torch.Tensor,
159
+ rotate_style: int,
160
+ reuse_freqs_front_part: bool,
161
+ nope_first: bool,
162
+ inplace: bool,
163
+ transpose_output: bool = False,
164
+ ) -> torch.Tensor:
165
+ s, b, h, d = x.shape
166
+
167
+ if freqs.shape[-1] == d // 2:
168
+ if reuse_freqs_front_part:
169
+ have_nope = False
170
+ else:
171
+ have_nope = True
172
+ elif freqs.shape[-1] == d // 4:
173
+ have_nope = True
174
+ else:
175
+ have_nope = False
176
+
177
+ if have_nope:
178
+ BLOCK_D = d // 2
179
+ BLOCK_D_HALF = d // 4
180
+ else:
181
+ BLOCK_D = d
182
+ BLOCK_D_HALF = d // 2
183
+
184
+ # TODO: performance optimization
185
+ BLOCK_S = 32
186
+ num_warps = 4
187
+ waves_per_eu = 0
188
+ grid = (b, h, triton.cdiv(s, BLOCK_S))
189
+
190
+ _rope_kernel_sbhd_bwd[grid](
191
+ x,
192
+ freqs,
193
+ out,
194
+ *x.stride(),
195
+ *freqs.stride(),
196
+ *out.stride(),
197
+ s,
198
+ HAVE_NOPE=have_nope,
199
+ NOPE_FIRST=nope_first,
200
+ INPLACE=inplace,
201
+ REUSE_FREQS_FRONT_PART=reuse_freqs_front_part,
202
+ IS_NEOX=(rotate_style == RotateStyle.NEOX),
203
+ BLOCK_S=BLOCK_S,
204
+ BLOCK_D=BLOCK_D,
205
+ BLOCK_D_HALF=BLOCK_D_HALF,
206
+ num_warps=num_warps,
207
+ waves_per_eu=waves_per_eu,
208
+ )
209
+
210
+ return out
211
+
212
+
213
+ def rope_bwd(
214
+ x: torch.Tensor,
215
+ freqs: torch.Tensor,
216
+ rotate_style: int,
217
+ reuse_freqs_front_part: bool,
218
+ nope_first: bool,
219
+ transpose_output: bool = False,
220
+ ) -> torch.Tensor:
221
+ s, b, h, d = x.shape
222
+ out = torch.empty((s, b, h, d), dtype=x.dtype, device=x.device, requires_grad=False)
223
+
224
+ _rope_bwd(
225
+ x,
226
+ out,
227
+ freqs,
228
+ rotate_style,
229
+ reuse_freqs_front_part,
230
+ nope_first,
231
+ False,
232
+ transpose_output,
233
+ )
234
+
235
+ return out
236
+
237
+
238
+ def _rope_thd_fwd(
239
+ x: torch.Tensor,
240
+ out: torch.Tensor,
241
+ cu_seqlens: torch.Tensor,
242
+ freqs: torch.Tensor,
243
+ rotate_style: int,
244
+ reuse_freqs_front_part: bool,
245
+ nope_first: bool,
246
+ inplace: bool,
247
+ transpose_output: bool = False,
248
+ ) -> torch.Tensor:
249
+ b = torch.numel(cu_seqlens) - 1
250
+ t, h, d = x.shape
251
+
252
+ if freqs.shape[-1] == d // 2:
253
+ if reuse_freqs_front_part:
254
+ have_nope = False
255
+ else:
256
+ have_nope = True
257
+ elif freqs.shape[-1] == d // 4:
258
+ have_nope = True
259
+ else:
260
+ have_nope = False
261
+
262
+ if have_nope:
263
+ BLOCK_D = d // 2
264
+ BLOCK_D_HALF = d // 4
265
+ else:
266
+ BLOCK_D = d
267
+ BLOCK_D_HALF = d // 2
268
+
269
+ # TODO: performance optimization
270
+ BLOCK_T = 32
271
+ num_warps = 4
272
+ waves_per_eu = 0
273
+ grid = (b, h, triton.cdiv(t, BLOCK_T))
274
+
275
+ _rope_kernel_thd_fwd[grid](
276
+ x,
277
+ cu_seqlens,
278
+ freqs,
279
+ out,
280
+ *x.stride(),
281
+ *freqs.stride(),
282
+ *out.stride(),
283
+ HAVE_NOPE=have_nope,
284
+ NOPE_FIRST=nope_first,
285
+ INPLACE=inplace,
286
+ REUSE_FREQS_FRONT_PART=reuse_freqs_front_part,
287
+ IS_NEOX=(rotate_style == RotateStyle.NEOX),
288
+ BLOCK_T=BLOCK_T,
289
+ BLOCK_D=BLOCK_D,
290
+ BLOCK_D_HALF=BLOCK_D_HALF,
291
+ num_warps=num_warps,
292
+ waves_per_eu=waves_per_eu,
293
+ )
294
+
295
+ return out
296
+
297
+
298
+ def rope_thd_fwd(
299
+ x: torch.Tensor,
300
+ cu_seqlens: torch.Tensor,
301
+ freqs: torch.Tensor,
302
+ rotate_style: int,
303
+ reuse_freqs_front_part: bool,
304
+ nope_first: bool,
305
+ transpose_output: bool = False,
306
+ ) -> torch.Tensor:
307
+ t, h, d = x.shape
308
+ out = torch.empty((t, h, d), dtype=x.dtype, device=x.device, requires_grad=False)
309
+
310
+ _rope_thd_fwd(
311
+ x,
312
+ out,
313
+ cu_seqlens,
314
+ freqs,
315
+ rotate_style,
316
+ reuse_freqs_front_part,
317
+ nope_first,
318
+ False,
319
+ transpose_output,
320
+ )
321
+
322
+ return out
323
+
324
+
325
+ def rope_thd_fwd_inplace(
326
+ x: torch.Tensor,
327
+ cu_seqlens: torch.Tensor,
328
+ freqs: torch.Tensor,
329
+ rotate_style: int,
330
+ reuse_freqs_front_part: bool,
331
+ nope_first: bool,
332
+ transpose_output: bool = False,
333
+ ) -> torch.Tensor:
334
+ out = x
335
+
336
+ _rope_thd_fwd(
337
+ x,
338
+ out,
339
+ cu_seqlens,
340
+ freqs,
341
+ rotate_style,
342
+ reuse_freqs_front_part,
343
+ nope_first,
344
+ True,
345
+ transpose_output,
346
+ )
347
+
348
+ return out
349
+
350
+
351
+ def _rope_thd_bwd(
352
+ x: torch.Tensor,
353
+ out: torch.Tensor,
354
+ cu_seqlens: torch.Tensor,
355
+ freqs: torch.Tensor,
356
+ rotate_style: int,
357
+ reuse_freqs_front_part: bool,
358
+ nope_first: bool,
359
+ inplace: bool,
360
+ transpose_output: bool = False,
361
+ ) -> torch.Tensor:
362
+ b = torch.numel(cu_seqlens) - 1
363
+ t, h, d = x.shape
364
+
365
+ if freqs.shape[-1] == d // 2:
366
+ if reuse_freqs_front_part:
367
+ have_nope = False
368
+ else:
369
+ have_nope = True
370
+ elif freqs.shape[-1] == d // 4:
371
+ have_nope = True
372
+ else:
373
+ have_nope = False
374
+
375
+ if have_nope:
376
+ BLOCK_D = d // 2
377
+ BLOCK_D_HALF = d // 4
378
+ else:
379
+ BLOCK_D = d
380
+ BLOCK_D_HALF = d // 2
381
+
382
+ # TODO: performance optimization
383
+ BLOCK_T = 32
384
+ num_warps = 4
385
+ waves_per_eu = 0
386
+ grid = (b, h, triton.cdiv(t, BLOCK_T))
387
+
388
+ _rope_kernel_thd_bwd[grid](
389
+ x,
390
+ cu_seqlens,
391
+ freqs,
392
+ out,
393
+ *x.stride(),
394
+ *freqs.stride(),
395
+ *out.stride(),
396
+ HAVE_NOPE=have_nope,
397
+ NOPE_FIRST=nope_first,
398
+ INPLACE=inplace,
399
+ REUSE_FREQS_FRONT_PART=reuse_freqs_front_part,
400
+ IS_NEOX=(rotate_style == RotateStyle.NEOX),
401
+ BLOCK_T=BLOCK_T,
402
+ BLOCK_D=BLOCK_D,
403
+ BLOCK_D_HALF=BLOCK_D_HALF,
404
+ num_warps=num_warps,
405
+ waves_per_eu=waves_per_eu,
406
+ )
407
+
408
+ return out
409
+
410
+
411
+ def rope_thd_bwd(
412
+ x: torch.Tensor,
413
+ cu_seqlens: torch.Tensor,
414
+ freqs: torch.Tensor,
415
+ rotate_style: int,
416
+ reuse_freqs_front_part: bool,
417
+ nope_first: bool,
418
+ transpose_output: bool = False,
419
+ ) -> torch.Tensor:
420
+ t, h, d = x.shape
421
+ out = torch.empty((t, h, d), dtype=x.dtype, device=x.device, requires_grad=False)
422
+
423
+ _rope_thd_bwd(
424
+ x,
425
+ out,
426
+ cu_seqlens,
427
+ freqs,
428
+ rotate_style,
429
+ reuse_freqs_front_part,
430
+ nope_first,
431
+ False,
432
+ transpose_output,
433
+ )
434
+
435
+ return out
436
+
437
+
438
+ # TODO: For now BLOCK_D is assumed to be power of 2. Expand to handle other value of D.
439
+ def _rope_cached_fwd(
440
+ x: torch.Tensor,
441
+ out: torch.Tensor,
442
+ cos: torch.Tensor,
443
+ sin: torch.Tensor,
444
+ positions: torch.Tensor,
445
+ offsets: torch.Tensor,
446
+ rotate_style: int,
447
+ reuse_freqs_front_part: bool,
448
+ nope_first: bool,
449
+ inplace: bool,
450
+ transpose_output: bool = False,
451
+ ) -> torch.Tensor:
452
+ s, b, h, d = x.shape
453
+
454
+ if cos.shape[-1] == d // 2:
455
+ if reuse_freqs_front_part:
456
+ have_nope = False
457
+ else:
458
+ have_nope = True
459
+ elif cos.shape[-1] == d // 4:
460
+ have_nope = True
461
+ else:
462
+ have_nope = False
463
+
464
+ if have_nope:
465
+ BLOCK_D = d // 2
466
+ BLOCK_D_HALF = d // 4
467
+ else:
468
+ BLOCK_D = d
469
+ BLOCK_D_HALF = d // 2
470
+
471
+ # TODO: performance optimization
472
+ BLOCK_S = 32
473
+ num_warps = 4
474
+ waves_per_eu = 0
475
+ grid = (b, h, triton.cdiv(s, BLOCK_S))
476
+
477
+ pos_stride = positions.stride() if positions is not None else (1, 1)
478
+ _rope_kernel_sbhd_cached_fwd[grid](
479
+ x,
480
+ cos,
481
+ sin,
482
+ positions,
483
+ offsets,
484
+ out,
485
+ *x.stride(),
486
+ *cos.stride(),
487
+ *pos_stride,
488
+ *out.stride(),
489
+ s,
490
+ HAVE_NOPE=have_nope,
491
+ NOPE_FIRST=nope_first,
492
+ INPLACE=inplace,
493
+ REUSE_FREQS_FRONT_PART=reuse_freqs_front_part,
494
+ IS_NEOX=(rotate_style == RotateStyle.NEOX),
495
+ HAVE_POS=(positions is not None),
496
+ HAVE_OFFS=(offsets is not None),
497
+ BLOCK_S=BLOCK_S,
498
+ BLOCK_D=BLOCK_D,
499
+ BLOCK_D_HALF=BLOCK_D_HALF,
500
+ num_warps=num_warps,
501
+ waves_per_eu=waves_per_eu,
502
+ )
503
+
504
+ return out
505
+
506
+
507
+ def rope_cached_fwd(
508
+ x: torch.Tensor,
509
+ cos: torch.Tensor,
510
+ sin: torch.Tensor,
511
+ rotate_style: int,
512
+ reuse_freqs_front_part: bool,
513
+ nope_first: bool,
514
+ transpose_output: bool = False,
515
+ ):
516
+ s, b, h, d = x.shape
517
+ out = torch.empty((s, b, h, d), dtype=x.dtype, device=x.device, requires_grad=False)
518
+
519
+ _rope_cached_fwd(
520
+ x,
521
+ out,
522
+ cos,
523
+ sin,
524
+ None,
525
+ None,
526
+ rotate_style,
527
+ reuse_freqs_front_part,
528
+ nope_first,
529
+ False,
530
+ transpose_output,
531
+ )
532
+
533
+ return out
534
+
535
+
536
+ def rope_cached_fwd_inplace(
537
+ x: torch.Tensor,
538
+ cos: torch.Tensor,
539
+ sin: torch.Tensor,
540
+ rotate_style: int,
541
+ reuse_freqs_front_part: bool,
542
+ nope_first: bool,
543
+ transpose_output: bool = False,
544
+ ):
545
+ out = x
546
+
547
+ _rope_cached_fwd(
548
+ x,
549
+ out,
550
+ cos,
551
+ sin,
552
+ None,
553
+ None,
554
+ rotate_style,
555
+ reuse_freqs_front_part,
556
+ nope_first,
557
+ True,
558
+ transpose_output,
559
+ )
560
+
561
+ return out
562
+
563
+
564
+ def rope_cached_positions_fwd(
565
+ x: torch.Tensor,
566
+ cos: torch.Tensor,
567
+ sin: torch.Tensor,
568
+ positions: torch.Tensor,
569
+ rotate_style: int,
570
+ reuse_freqs_front_part: bool,
571
+ nope_first: bool,
572
+ transpose_output: bool = False,
573
+ ) -> torch.Tensor:
574
+ s, b, h, d = x.shape
575
+ out = torch.empty((s, b, h, d), dtype=x.dtype, device=x.device, requires_grad=False)
576
+
577
+ _rope_cached_fwd(
578
+ x,
579
+ out,
580
+ cos,
581
+ sin,
582
+ positions,
583
+ None,
584
+ rotate_style,
585
+ reuse_freqs_front_part,
586
+ nope_first,
587
+ False,
588
+ transpose_output,
589
+ )
590
+
591
+ return out
592
+
593
+
594
+ def rope_cached_positions_fwd_inplace(
595
+ x: torch.Tensor,
596
+ cos: torch.Tensor,
597
+ sin: torch.Tensor,
598
+ positions: torch.Tensor,
599
+ rotate_style: int,
600
+ reuse_freqs_front_part: bool,
601
+ nope_first: bool,
602
+ transpose_output: bool = False,
603
+ ) -> torch.Tensor:
604
+ out = x
605
+
606
+ _rope_cached_fwd(
607
+ x,
608
+ out,
609
+ cos,
610
+ sin,
611
+ positions,
612
+ None,
613
+ rotate_style,
614
+ reuse_freqs_front_part,
615
+ nope_first,
616
+ True,
617
+ transpose_output,
618
+ )
619
+
620
+ return out
621
+
622
+
623
+ def rope_cached_positions_offsets_fwd(
624
+ x: torch.Tensor,
625
+ cos: torch.Tensor,
626
+ sin: torch.Tensor,
627
+ positions: torch.Tensor,
628
+ offsets: torch.Tensor,
629
+ rotate_style: int,
630
+ reuse_freqs_front_part: bool,
631
+ nope_first: bool,
632
+ transpose_output: bool = False,
633
+ ) -> torch.Tensor:
634
+ s, b, h, d = x.shape
635
+ out = torch.empty((s, b, h, d), dtype=x.dtype, device=x.device, requires_grad=False)
636
+
637
+ _rope_cached_fwd(
638
+ x,
639
+ out,
640
+ cos,
641
+ sin,
642
+ positions,
643
+ offsets,
644
+ rotate_style,
645
+ reuse_freqs_front_part,
646
+ nope_first,
647
+ False,
648
+ transpose_output,
649
+ )
650
+
651
+ return out
652
+
653
+
654
+ def rope_cached_positions_offsets_fwd_inplace(
655
+ x: torch.Tensor,
656
+ cos: torch.Tensor,
657
+ sin: torch.Tensor,
658
+ positions: torch.Tensor,
659
+ offsets: torch.Tensor,
660
+ rotate_style: int,
661
+ reuse_freqs_front_part: bool,
662
+ nope_first: bool,
663
+ transpose_output: bool = False,
664
+ ) -> torch.Tensor:
665
+ out = x
666
+
667
+ _rope_cached_fwd(
668
+ x,
669
+ out,
670
+ cos,
671
+ sin,
672
+ positions,
673
+ offsets,
674
+ rotate_style,
675
+ reuse_freqs_front_part,
676
+ nope_first,
677
+ True,
678
+ transpose_output,
679
+ )
680
+
681
+ return out
682
+
683
+
684
+ def _rope_cached_bwd(
685
+ x: torch.Tensor,
686
+ out: torch.Tensor,
687
+ cos: torch.Tensor,
688
+ sin: torch.Tensor,
689
+ positions: torch.Tensor,
690
+ offsets: torch.Tensor,
691
+ rotate_style: int,
692
+ reuse_freqs_front_part: bool,
693
+ nope_first: bool,
694
+ inplace: bool,
695
+ transpose_output: bool = False,
696
+ ) -> torch.Tensor:
697
+ s, b, h, d = x.shape
698
+
699
+ if cos.shape[-1] == d // 2:
700
+ if reuse_freqs_front_part:
701
+ have_nope = False
702
+ else:
703
+ have_nope = True
704
+ elif cos.shape[-1] == d // 4:
705
+ have_nope = True
706
+ else:
707
+ have_nope = False
708
+
709
+ if have_nope:
710
+ BLOCK_D = d // 2
711
+ BLOCK_D_HALF = d // 4
712
+ else:
713
+ BLOCK_D = d
714
+ BLOCK_D_HALF = d // 2
715
+
716
+ # TODO: performance optimization
717
+ BLOCK_S = 32
718
+ num_warps = 4
719
+ waves_per_eu = 0
720
+ grid = (b, h, triton.cdiv(s, BLOCK_S))
721
+
722
+ pos_stride = positions.stride() if positions is not None else (1, 1)
723
+ _rope_kernel_sbhd_cached_bwd[grid](
724
+ x,
725
+ cos,
726
+ sin,
727
+ positions,
728
+ offsets,
729
+ out,
730
+ *x.stride(),
731
+ *cos.stride(),
732
+ *pos_stride,
733
+ *out.stride(),
734
+ s,
735
+ HAVE_NOPE=have_nope,
736
+ NOPE_FIRST=nope_first,
737
+ INPLACE=inplace,
738
+ REUSE_FREQS_FRONT_PART=reuse_freqs_front_part,
739
+ IS_NEOX=(rotate_style == RotateStyle.NEOX),
740
+ HAVE_POS=(positions is not None),
741
+ HAVE_OFFS=(offsets is not None),
742
+ BLOCK_S=BLOCK_S,
743
+ BLOCK_D=BLOCK_D,
744
+ BLOCK_D_HALF=BLOCK_D_HALF,
745
+ num_warps=num_warps,
746
+ waves_per_eu=waves_per_eu,
747
+ )
748
+
749
+ return out
750
+
751
+
752
+ def rope_cached_bwd(
753
+ x: torch.Tensor,
754
+ cos: torch.Tensor,
755
+ sin: torch.Tensor,
756
+ rotate_style: int,
757
+ reuse_freqs_front_part: bool,
758
+ nope_first: bool,
759
+ transpose_output: bool = False,
760
+ ):
761
+ s, b, h, d = x.shape
762
+ out = torch.empty((s, b, h, d), dtype=x.dtype, device=x.device, requires_grad=False)
763
+
764
+ _rope_cached_bwd(
765
+ x,
766
+ out,
767
+ cos,
768
+ sin,
769
+ None,
770
+ None,
771
+ rotate_style,
772
+ reuse_freqs_front_part,
773
+ nope_first,
774
+ False,
775
+ transpose_output,
776
+ )
777
+
778
+ return out
779
+
780
+
781
+ def rope_cached_positions_bwd(
782
+ x: torch.Tensor,
783
+ cos: torch.Tensor,
784
+ sin: torch.Tensor,
785
+ positions: torch.Tensor,
786
+ rotate_style: int,
787
+ reuse_freqs_front_part: bool,
788
+ nope_first: bool,
789
+ transpose_output: bool = False,
790
+ ) -> torch.Tensor:
791
+ s, b, h, d = x.shape
792
+ out = torch.empty((s, b, h, d), dtype=x.dtype, device=x.device, requires_grad=False)
793
+
794
+ _rope_cached_bwd(
795
+ x,
796
+ out,
797
+ cos,
798
+ sin,
799
+ positions,
800
+ None,
801
+ rotate_style,
802
+ reuse_freqs_front_part,
803
+ nope_first,
804
+ False,
805
+ transpose_output,
806
+ )
807
+
808
+ return out
809
+
810
+
811
+ def rope_cached_positions_offsets_bwd(
812
+ x: torch.Tensor,
813
+ cos: torch.Tensor,
814
+ sin: torch.Tensor,
815
+ positions: torch.Tensor,
816
+ offsets: torch.Tensor,
817
+ rotate_style: int,
818
+ reuse_freqs_front_part: bool,
819
+ nope_first: bool,
820
+ transpose_output: bool = False,
821
+ ) -> torch.Tensor:
822
+ s, b, h, d = x.shape
823
+ out = torch.empty((s, b, h, d), dtype=x.dtype, device=x.device, requires_grad=False)
824
+
825
+ _rope_cached_bwd(
826
+ x,
827
+ out,
828
+ cos,
829
+ sin,
830
+ positions,
831
+ offsets,
832
+ rotate_style,
833
+ reuse_freqs_front_part,
834
+ nope_first,
835
+ False,
836
+ transpose_output,
837
+ )
838
+
839
+ return out
840
+
841
+
842
+ def _rope_cached_thd_2c_fwd(
843
+ x: torch.Tensor,
844
+ y: torch.Tensor,
845
+ out_x: torch.Tensor,
846
+ out_y: torch.Tensor,
847
+ cos: torch.Tensor,
848
+ sin: torch.Tensor,
849
+ positions: torch.Tensor,
850
+ offsets: torch.Tensor,
851
+ rotate_style: int,
852
+ reuse_freqs_front_part: bool,
853
+ nope_first: bool,
854
+ inplace: bool,
855
+ transpose_output: bool = False,
856
+ ):
857
+ t, h, d = x.shape
858
+ ty, kh, dy = y.shape
859
+
860
+ assert (
861
+ t == ty
862
+ ), f"The number of tokens should be the same for the two inputs, but got {t} and {ty}"
863
+ assert (
864
+ d == dy
865
+ ), f"The head dimension should be the same for the two inputs, but got {d} and {dy}"
866
+ assert h % kh == 0, f"QH should be multiple of KH, but got QH={h} and KH={kh}"
867
+
868
+ if cos.shape[-1] == d // 2:
869
+ if reuse_freqs_front_part:
870
+ have_nope = False
871
+ else:
872
+ have_nope = True
873
+ elif cos.shape[-1] == d // 4:
874
+ have_nope = True
875
+ else:
876
+ have_nope = False
877
+
878
+ if have_nope:
879
+ BLOCK_D = d // 2
880
+ BLOCK_D_HALF = d // 4
881
+ else:
882
+ BLOCK_D = d
883
+ BLOCK_D_HALF = d // 2
884
+
885
+ if h == kh:
886
+ BLOCK_T = 32
887
+ SPLIT_T = (triton.next_power_of_2(t) + BLOCK_T - 1) // BLOCK_T
888
+
889
+ if t >= 8192:
890
+ MIN_NUM_WG = 4096
891
+ elif t >= 1024:
892
+ MIN_NUM_WG = 1024
893
+ else:
894
+ MIN_NUM_WG = 512
895
+
896
+ if SPLIT_T < MIN_NUM_WG:
897
+ SPLIT_H_SIZE = h
898
+ SPLIT_H = (triton.next_power_of_2(h) + SPLIT_H_SIZE - 1) // SPLIT_H_SIZE
899
+ while SPLIT_H * SPLIT_T < MIN_NUM_WG and SPLIT_H_SIZE > 1:
900
+ SPLIT_H_SIZE = SPLIT_H_SIZE // 2
901
+ SPLIT_H = (triton.next_power_of_2(h) + SPLIT_H_SIZE - 1) // SPLIT_H_SIZE
902
+ else:
903
+ SPLIT_H_SIZE = h
904
+
905
+ SPLIT_H = (triton.next_power_of_2(h) + SPLIT_H_SIZE - 1) // SPLIT_H_SIZE
906
+ grid = (SPLIT_H, SPLIT_T, 1)
907
+ num_warps = 4
908
+ waves_per_eu = 0
909
+ num_stages = 2 if SPLIT_H_SIZE > 1 else 1
910
+
911
+ _rope_kernel_thd_cached_2c_fwd[grid](
912
+ x,
913
+ y,
914
+ cos,
915
+ sin,
916
+ positions,
917
+ offsets,
918
+ out_x,
919
+ out_y,
920
+ *x.stride(),
921
+ *y.stride(),
922
+ *cos.stride(),
923
+ *positions.stride(),
924
+ *out_x.stride(),
925
+ *out_y.stride(),
926
+ t,
927
+ HAVE_NOPE=have_nope,
928
+ NOPE_FIRST=nope_first,
929
+ INPLACE=inplace,
930
+ REUSE_FREQS_FRONT_PART=reuse_freqs_front_part,
931
+ IS_NEOX=(rotate_style == RotateStyle.NEOX),
932
+ HAVE_POS=(positions is not None),
933
+ HAVE_OFFS=(offsets is not None),
934
+ BLOCK_T=BLOCK_T,
935
+ SPLIT_H_SIZE=SPLIT_H_SIZE,
936
+ BLOCK_D=BLOCK_D,
937
+ BLOCK_D_HALF=BLOCK_D_HALF,
938
+ num_warps=num_warps,
939
+ waves_per_eu=waves_per_eu,
940
+ num_stages=num_stages,
941
+ )
942
+ else:
943
+ # TODO check boundary
944
+ if rotate_style == RotateStyle.GPTJ and t >= 1024:
945
+ BLOCK_T = 32
946
+ SPLIT_T = (triton.next_power_of_2(t) + BLOCK_T - 1) // BLOCK_T
947
+ QH_per_G = h // kh
948
+ grid = (kh, SPLIT_T, 1)
949
+ num_warps = 4
950
+ waves_per_eu = 0
951
+ num_stages = 2 if QH_per_G > 1 else 1
952
+
953
+ _rope_kernel_cached_thd_2c_gqa_fwd[grid](
954
+ x,
955
+ y,
956
+ cos,
957
+ sin,
958
+ positions,
959
+ offsets,
960
+ out_x,
961
+ out_y,
962
+ *x.stride(),
963
+ *y.stride(),
964
+ *cos.stride(),
965
+ *positions.stride(),
966
+ *out_x.stride(),
967
+ *out_y.stride(),
968
+ t,
969
+ HAVE_NOPE=have_nope,
970
+ NOPE_FIRST=nope_first,
971
+ INPLACE=inplace,
972
+ REUSE_FREQS_FRONT_PART=reuse_freqs_front_part,
973
+ IS_NEOX=(rotate_style == RotateStyle.NEOX),
974
+ HAVE_POS=(positions is not None),
975
+ HAVE_OFFS=(offsets is not None),
976
+ BLOCK_T=BLOCK_T,
977
+ QH_per_G=QH_per_G,
978
+ BLOCK_D=BLOCK_D,
979
+ BLOCK_D_HALF=BLOCK_D_HALF,
980
+ num_warps=num_warps,
981
+ waves_per_eu=waves_per_eu,
982
+ num_stages=num_stages,
983
+ )
984
+ else:
985
+ BLOCK_T = min(max(triton.next_power_of_2(t), 16), 32)
986
+ SPLIT_T = (triton.next_power_of_2(t) + BLOCK_T - 1) // BLOCK_T
987
+ grid = (SPLIT_T, h, 1)
988
+ num_warps = 4
989
+ waves_per_eu = 0
990
+ _rope_kernel_cached_thd_2c_gqa_onehead_fwd[grid](
991
+ x,
992
+ y,
993
+ cos,
994
+ sin,
995
+ positions,
996
+ offsets,
997
+ out_x,
998
+ out_y,
999
+ *x.stride(),
1000
+ *y.stride(),
1001
+ *cos.stride(),
1002
+ *positions.stride(),
1003
+ *out_x.stride(),
1004
+ *out_y.stride(),
1005
+ t,
1006
+ HAVE_NOPE=have_nope,
1007
+ NOPE_FIRST=nope_first,
1008
+ INPLACE=inplace,
1009
+ REUSE_FREQS_FRONT_PART=reuse_freqs_front_part,
1010
+ IS_NEOX=(rotate_style == RotateStyle.NEOX),
1011
+ HAVE_POS=(positions is not None),
1012
+ HAVE_OFFS=(offsets is not None),
1013
+ BLOCK_T=BLOCK_T,
1014
+ G=kh,
1015
+ BLOCK_D=BLOCK_D,
1016
+ BLOCK_D_HALF=BLOCK_D_HALF,
1017
+ num_warps=num_warps,
1018
+ waves_per_eu=waves_per_eu,
1019
+ )
1020
+
1021
+ return out_x, out_y
1022
+
1023
+
1024
+ def rope_cached_thd_positions_2c_fwd(
1025
+ x: torch.Tensor,
1026
+ y: torch.Tensor,
1027
+ cos: torch.Tensor,
1028
+ sin: torch.Tensor,
1029
+ positions: torch.Tensor,
1030
+ rotate_style: int,
1031
+ reuse_freqs_front_part: bool,
1032
+ nope_first: bool,
1033
+ transpose_output: bool = False,
1034
+ ):
1035
+ out_x = torch.empty(*x.shape, dtype=x.dtype, device=x.device, requires_grad=False)
1036
+ out_y = torch.empty(*y.shape, dtype=x.dtype, device=x.device, requires_grad=False)
1037
+
1038
+ _rope_cached_thd_2c_fwd(
1039
+ x,
1040
+ y,
1041
+ out_x,
1042
+ out_y,
1043
+ cos,
1044
+ sin,
1045
+ positions,
1046
+ None,
1047
+ rotate_style,
1048
+ reuse_freqs_front_part,
1049
+ nope_first,
1050
+ False,
1051
+ transpose_output,
1052
+ )
1053
+
1054
+ return out_x, out_y
1055
+
1056
+
1057
+ def rope_cached_thd_positions_2c_fwd_inplace(
1058
+ x: torch.Tensor,
1059
+ y: torch.Tensor,
1060
+ cos: torch.Tensor,
1061
+ sin: torch.Tensor,
1062
+ positions: torch.Tensor,
1063
+ rotate_style: int,
1064
+ reuse_freqs_front_part: bool,
1065
+ nope_first: bool,
1066
+ transpose_output: bool = False,
1067
+ ):
1068
+ out_x = x
1069
+ out_y = y
1070
+
1071
+ _rope_cached_thd_2c_fwd(
1072
+ x,
1073
+ y,
1074
+ out_x,
1075
+ out_y,
1076
+ cos,
1077
+ sin,
1078
+ positions,
1079
+ None,
1080
+ rotate_style,
1081
+ reuse_freqs_front_part,
1082
+ nope_first,
1083
+ True,
1084
+ transpose_output,
1085
+ )
1086
+
1087
+ return out_x, out_y
1088
+
1089
+
1090
+ def rope_cached_thd_positions_offsets_2c_fwd(
1091
+ x: torch.Tensor,
1092
+ y: torch.Tensor,
1093
+ cos: torch.Tensor,
1094
+ sin: torch.Tensor,
1095
+ positions: torch.Tensor,
1096
+ offsets: torch.Tensor,
1097
+ rotate_style: int,
1098
+ reuse_freqs_front_part: bool,
1099
+ nope_first: bool,
1100
+ transpose_output: bool = False,
1101
+ ):
1102
+ out_x = torch.empty(*x.shape, dtype=x.dtype, device=x.device, requires_grad=False)
1103
+ out_y = torch.empty(*y.shape, dtype=x.dtype, device=x.device, requires_grad=False)
1104
+
1105
+ _rope_cached_thd_2c_fwd(
1106
+ x,
1107
+ y,
1108
+ out_x,
1109
+ out_y,
1110
+ cos,
1111
+ sin,
1112
+ positions,
1113
+ offsets,
1114
+ rotate_style,
1115
+ reuse_freqs_front_part,
1116
+ nope_first,
1117
+ False,
1118
+ transpose_output,
1119
+ )
1120
+
1121
+ return out_x, out_y
1122
+
1123
+
1124
+ def rope_cached_thd_positions_offsets_2c_fwd_inplace(
1125
+ x: torch.Tensor,
1126
+ y: torch.Tensor,
1127
+ cos: torch.Tensor,
1128
+ sin: torch.Tensor,
1129
+ positions: torch.Tensor,
1130
+ offsets: torch.Tensor,
1131
+ rotate_style: int,
1132
+ reuse_freqs_front_part: bool,
1133
+ nope_first: bool,
1134
+ transpose_output: bool = False,
1135
+ ):
1136
+ out_x = x
1137
+ out_y = y
1138
+
1139
+ _rope_cached_thd_2c_fwd(
1140
+ x,
1141
+ y,
1142
+ out_x,
1143
+ out_y,
1144
+ cos,
1145
+ sin,
1146
+ positions,
1147
+ offsets,
1148
+ rotate_style,
1149
+ reuse_freqs_front_part,
1150
+ nope_first,
1151
+ True,
1152
+ transpose_output,
1153
+ )
1154
+
1155
+ return out_x, out_y
1156
+
1157
+
1158
+ def _rope_cached_thd_positions_offsets_2c_bwd(
1159
+ x: torch.Tensor,
1160
+ y: torch.Tensor,
1161
+ out_x: torch.Tensor,
1162
+ out_y: torch.Tensor,
1163
+ cos: torch.Tensor,
1164
+ sin: torch.Tensor,
1165
+ positions: torch.Tensor,
1166
+ offsets: torch.Tensor,
1167
+ rotate_style: int,
1168
+ reuse_freqs_front_part: bool,
1169
+ nope_first: bool,
1170
+ inplace: bool,
1171
+ transpose_output: bool = False,
1172
+ ):
1173
+ t, h, d = x.shape
1174
+ ty, kh, dy = y.shape
1175
+
1176
+ assert (
1177
+ t == ty
1178
+ ), f"The number of tokens should be the same for the two inputs, but got {t} and {ty}"
1179
+ assert (
1180
+ d == dy
1181
+ ), f"The head dimension should be the same for the two inputs, but got {d} and {dy}"
1182
+ assert h % kh == 0, f"QH should be multiple of KH, but got QH={h} and KH={kh}"
1183
+
1184
+ if cos.shape[-1] == d // 2:
1185
+ if reuse_freqs_front_part:
1186
+ have_nope = False
1187
+ else:
1188
+ have_nope = True
1189
+ elif cos.shape[-1] == d // 4:
1190
+ have_nope = True
1191
+ else:
1192
+ have_nope = False
1193
+
1194
+ if have_nope:
1195
+ BLOCK_D = d // 2
1196
+ BLOCK_D_HALF = d // 4
1197
+ else:
1198
+ BLOCK_D = d
1199
+ BLOCK_D_HALF = d // 2
1200
+
1201
+ if h == kh:
1202
+ BLOCK_T = 32
1203
+ SPLIT_T = (triton.next_power_of_2(t) + BLOCK_T - 1) // BLOCK_T
1204
+
1205
+ if t >= 8192:
1206
+ MIN_NUM_WG = 4096
1207
+ elif t >= 1024:
1208
+ MIN_NUM_WG = 1024
1209
+ else:
1210
+ MIN_NUM_WG = 512
1211
+
1212
+ if SPLIT_T < MIN_NUM_WG:
1213
+ SPLIT_H_SIZE = h
1214
+ SPLIT_H = (triton.next_power_of_2(h) + SPLIT_H_SIZE - 1) // SPLIT_H_SIZE
1215
+ while SPLIT_H * SPLIT_T < MIN_NUM_WG and SPLIT_H_SIZE > 1:
1216
+ SPLIT_H_SIZE = SPLIT_H_SIZE // 2
1217
+ SPLIT_H = (triton.next_power_of_2(h) + SPLIT_H_SIZE - 1) // SPLIT_H_SIZE
1218
+ else:
1219
+ SPLIT_H_SIZE = h
1220
+
1221
+ SPLIT_H = (triton.next_power_of_2(h) + SPLIT_H_SIZE - 1) // SPLIT_H_SIZE
1222
+ grid = (SPLIT_H, SPLIT_T, 1)
1223
+ num_warps = 4
1224
+ waves_per_eu = 0
1225
+ num_stages = 2 if SPLIT_H_SIZE > 1 else 1
1226
+
1227
+ _rope_kernel_thd_cached_2c_bwd[grid](
1228
+ x,
1229
+ y,
1230
+ cos,
1231
+ sin,
1232
+ positions,
1233
+ offsets,
1234
+ out_x,
1235
+ out_y,
1236
+ *x.stride(),
1237
+ *y.stride(),
1238
+ *cos.stride(),
1239
+ *positions.stride(),
1240
+ *out_x.stride(),
1241
+ *out_y.stride(),
1242
+ t,
1243
+ HAVE_NOPE=have_nope,
1244
+ NOPE_FIRST=nope_first,
1245
+ INPLACE=inplace,
1246
+ REUSE_FREQS_FRONT_PART=reuse_freqs_front_part,
1247
+ IS_NEOX=(rotate_style == RotateStyle.NEOX),
1248
+ HAVE_POS=(positions is not None),
1249
+ HAVE_OFFS=(offsets is not None),
1250
+ BLOCK_T=BLOCK_T,
1251
+ SPLIT_H_SIZE=SPLIT_H_SIZE,
1252
+ BLOCK_D=BLOCK_D,
1253
+ BLOCK_D_HALF=BLOCK_D_HALF,
1254
+ num_warps=num_warps,
1255
+ waves_per_eu=waves_per_eu,
1256
+ num_stages=num_stages,
1257
+ )
1258
+ else:
1259
+ # TODO check boundary
1260
+ if rotate_style == RotateStyle.GPTJ and t >= 1024:
1261
+ BLOCK_T = 32
1262
+ SPLIT_T = (triton.next_power_of_2(t) + BLOCK_T - 1) // BLOCK_T
1263
+ QH_per_G = h // kh
1264
+ grid = (kh, SPLIT_T, 1)
1265
+ num_warps = 4
1266
+ waves_per_eu = 0
1267
+ num_stages = 2 if QH_per_G > 1 else 1
1268
+
1269
+ _rope_kernel_cached_thd_2c_gqa_bwd[grid](
1270
+ x,
1271
+ y,
1272
+ cos,
1273
+ sin,
1274
+ positions,
1275
+ offsets,
1276
+ out_x,
1277
+ out_y,
1278
+ *x.stride(),
1279
+ *y.stride(),
1280
+ *cos.stride(),
1281
+ *positions.stride(),
1282
+ *out_x.stride(),
1283
+ *out_y.stride(),
1284
+ t,
1285
+ HAVE_NOPE=have_nope,
1286
+ NOPE_FIRST=nope_first,
1287
+ INPLACE=inplace,
1288
+ REUSE_FREQS_FRONT_PART=reuse_freqs_front_part,
1289
+ IS_NEOX=(rotate_style == RotateStyle.NEOX),
1290
+ HAVE_POS=(positions is not None),
1291
+ HAVE_OFFS=(offsets is not None),
1292
+ BLOCK_T=BLOCK_T,
1293
+ QH_per_G=QH_per_G,
1294
+ BLOCK_D=BLOCK_D,
1295
+ BLOCK_D_HALF=BLOCK_D_HALF,
1296
+ num_warps=num_warps,
1297
+ waves_per_eu=waves_per_eu,
1298
+ num_stages=num_stages,
1299
+ )
1300
+ else:
1301
+ BLOCK_T = min(max(triton.next_power_of_2(t), 16), 32)
1302
+ SPLIT_T = (triton.next_power_of_2(t) + BLOCK_T - 1) // BLOCK_T
1303
+ grid = (SPLIT_T, h, 1)
1304
+ num_warps = 4
1305
+ waves_per_eu = 0
1306
+ _rope_kernel_cached_thd_2c_gqa_onehead_bwd[grid](
1307
+ x,
1308
+ y,
1309
+ cos,
1310
+ sin,
1311
+ positions,
1312
+ offsets,
1313
+ out_x,
1314
+ out_y,
1315
+ *x.stride(),
1316
+ *y.stride(),
1317
+ *cos.stride(),
1318
+ *positions.stride(),
1319
+ *out_x.stride(),
1320
+ *out_y.stride(),
1321
+ t,
1322
+ HAVE_NOPE=have_nope,
1323
+ NOPE_FIRST=nope_first,
1324
+ INPLACE=inplace,
1325
+ REUSE_FREQS_FRONT_PART=reuse_freqs_front_part,
1326
+ IS_NEOX=(rotate_style == RotateStyle.NEOX),
1327
+ HAVE_POS=(positions is not None),
1328
+ HAVE_OFFS=(offsets is not None),
1329
+ BLOCK_T=BLOCK_T,
1330
+ G=kh,
1331
+ BLOCK_D=BLOCK_D,
1332
+ BLOCK_D_HALF=BLOCK_D_HALF,
1333
+ num_warps=num_warps,
1334
+ waves_per_eu=waves_per_eu,
1335
+ )
1336
+
1337
+ return out_x, out_y
1338
+
1339
+
1340
+ def rope_cached_thd_positions_2c_bwd(
1341
+ x: torch.Tensor,
1342
+ y: torch.Tensor,
1343
+ cos: torch.Tensor,
1344
+ sin: torch.Tensor,
1345
+ positions: torch.Tensor,
1346
+ rotate_style: int,
1347
+ reuse_freqs_front_part: bool,
1348
+ nope_first: bool,
1349
+ transpose_output: bool = False,
1350
+ ):
1351
+ out_x = torch.empty(*x.shape, dtype=x.dtype, device=x.device, requires_grad=False)
1352
+ out_y = torch.empty(*y.shape, dtype=x.dtype, device=x.device, requires_grad=False)
1353
+
1354
+ _rope_cached_thd_positions_offsets_2c_bwd(
1355
+ x,
1356
+ y,
1357
+ out_x,
1358
+ out_y,
1359
+ cos,
1360
+ sin,
1361
+ positions,
1362
+ None,
1363
+ rotate_style,
1364
+ reuse_freqs_front_part,
1365
+ nope_first,
1366
+ False,
1367
+ transpose_output,
1368
+ )
1369
+
1370
+ return out_x, out_y
1371
+
1372
+
1373
+ def rope_cached_thd_positions_offsets_2c_bwd(
1374
+ x: torch.Tensor,
1375
+ y: torch.Tensor,
1376
+ cos: torch.Tensor,
1377
+ sin: torch.Tensor,
1378
+ positions: torch.Tensor,
1379
+ offsets: torch.Tensor,
1380
+ rotate_style: int,
1381
+ reuse_freqs_front_part: bool,
1382
+ nope_first: bool,
1383
+ transpose_output: bool = False,
1384
+ ):
1385
+ out_x = torch.empty(*x.shape, dtype=x.dtype, device=x.device, requires_grad=False)
1386
+ out_y = torch.empty(*y.shape, dtype=x.dtype, device=x.device, requires_grad=False)
1387
+
1388
+ _rope_cached_thd_positions_offsets_2c_bwd(
1389
+ x,
1390
+ y,
1391
+ out_x,
1392
+ out_y,
1393
+ cos,
1394
+ sin,
1395
+ positions,
1396
+ offsets,
1397
+ rotate_style,
1398
+ reuse_freqs_front_part,
1399
+ nope_first,
1400
+ False,
1401
+ transpose_output,
1402
+ )
1403
+
1404
+ return out_x, out_y
1405
+
1406
+
1407
+ def _rope_fwd_2d(
1408
+ x: torch.Tensor,
1409
+ out: torch.Tensor,
1410
+ cos_h: torch.Tensor,
1411
+ sin_h: torch.Tensor,
1412
+ cos_w: torch.Tensor,
1413
+ sin_w: torch.Tensor,
1414
+ img_height: torch.Tensor,
1415
+ img_width: torch.Tensor,
1416
+ rotate_style: int,
1417
+ reuse_freqs_front_part: bool,
1418
+ nope_first: bool,
1419
+ transpose_output: bool = False,
1420
+ ):
1421
+ b, wh, h, d = x.shape
1422
+ # out = torch.empty((b,wh,h,d), dtype=x.dtype, device=x.device, requires_grad=False)
1423
+
1424
+ grid = (b, h, 1)
1425
+ _rope_fwd_2d_kernel_neox[grid](
1426
+ x,
1427
+ cos_h,
1428
+ sin_h,
1429
+ cos_w,
1430
+ sin_w,
1431
+ out,
1432
+ *x.stride(),
1433
+ *cos_h.stride(),
1434
+ *cos_w.stride(),
1435
+ wh,
1436
+ img_height,
1437
+ img_width,
1438
+ BLOCK_D=d,
1439
+ )
1440
+
1441
+ return out
1442
+
1443
+
1444
+ def rope_fwd_2d(
1445
+ x: torch.Tensor,
1446
+ cos_h: torch.Tensor,
1447
+ sin_h: torch.Tensor,
1448
+ cos_w: torch.Tensor,
1449
+ sin_w: torch.Tensor,
1450
+ img_height: torch.Tensor,
1451
+ img_width: torch.Tensor,
1452
+ rotate_style: int,
1453
+ reuse_freqs_front_part: bool,
1454
+ nope_first: bool,
1455
+ transpose_output: bool = False,
1456
+ ):
1457
+ b, wh, h, d = x.shape
1458
+ out = torch.empty(
1459
+ (b, wh, h, d), dtype=x.dtype, device=x.device, requires_grad=False
1460
+ )
1461
+
1462
+ # grid = (b,h,1)
1463
+ # _rope_fwd_2d_kernel_neox[grid](x, cos_h, sin_h, cos_w, sin_w, out, *x.stride(), *cos_h.stride(), *cos_w.stride(), wh, img_height, img_width, BLOCK_D=d)
1464
+
1465
+ _rope_fwd_2d(
1466
+ x,
1467
+ out,
1468
+ cos_h,
1469
+ sin_h,
1470
+ cos_w,
1471
+ sin_w,
1472
+ img_height,
1473
+ img_width,
1474
+ rotate_style,
1475
+ reuse_freqs_front_part,
1476
+ nope_first,
1477
+ transpose_output,
1478
+ )
1479
+
1480
+ return out
1481
+
1482
+
1483
+ def rope_fwd_2d_inplace(
1484
+ x: torch.Tensor,
1485
+ cos_h: torch.Tensor,
1486
+ sin_h: torch.Tensor,
1487
+ cos_w: torch.Tensor,
1488
+ sin_w: torch.Tensor,
1489
+ img_height: torch.Tensor,
1490
+ img_width: torch.Tensor,
1491
+ rotate_style: int,
1492
+ reuse_freqs_front_part: bool,
1493
+ nope_first: bool,
1494
+ transpose_output: bool = False,
1495
+ ):
1496
+ out = x
1497
+ _rope_fwd_2d(
1498
+ x,
1499
+ out,
1500
+ cos_h,
1501
+ sin_h,
1502
+ cos_w,
1503
+ sin_w,
1504
+ img_height,
1505
+ img_width,
1506
+ rotate_style,
1507
+ reuse_freqs_front_part,
1508
+ nope_first,
1509
+ transpose_output,
1510
+ )
1511
+
1512
+ return out
1513
+
1514
+
1515
+ def rope_fwd_3d(
1516
+ x,
1517
+ grid_sizes: tl.constexpr,
1518
+ freqs: tl.constexpr,
1519
+ sp_size: tl.constexpr,
1520
+ sp_rank: tl.constexpr,
1521
+ ):
1522
+ B, s, n_heads, C = x.shape
1523
+ c_total = C // 2 # 64
1524
+ c1 = c_total - 2 * (c_total // 3) # 22
1525
+ c2 = c_total // 3 # 21
1526
+ c3 = c_total // 3 # 21
1527
+ device = x.device
1528
+
1529
+ grid_sizes = grid_sizes.to(device=device, dtype=torch.int32).contiguous()
1530
+
1531
+ freqs_real = freqs.real.to(dtype=torch.float32, device=device).contiguous()
1532
+ freqs_imag = freqs.imag.to(dtype=torch.float32, device=device).contiguous()
1533
+ out = torch.empty_like(x, dtype=torch.float32, device=device)
1534
+
1535
+ BLOCK_L, BLOCK_N, BLOCK_C = 32, 4, 64
1536
+
1537
+ grid = (B, n_heads, triton.cdiv(s, BLOCK_L))
1538
+
1539
+ num_warps = 4
1540
+ waves_per_eu = 1
1541
+
1542
+ _rope_fwd_3d[grid](
1543
+ x,
1544
+ freqs_real,
1545
+ freqs_imag,
1546
+ grid_sizes,
1547
+ out,
1548
+ *x.stride(),
1549
+ freqs_real.stride(0),
1550
+ freqs_real.stride(1),
1551
+ *grid_sizes.stride(),
1552
+ *out.stride(),
1553
+ s,
1554
+ n_heads,
1555
+ C,
1556
+ c_total,
1557
+ sp_size,
1558
+ sp_rank,
1559
+ freqs.shape[0],
1560
+ s,
1561
+ 1.0,
1562
+ 0.0,
1563
+ BLOCK_L=BLOCK_L,
1564
+ BLOCK_N=BLOCK_N,
1565
+ BLOCK_C=BLOCK_C,
1566
+ C1=c1,
1567
+ C2=c2,
1568
+ num_warps=num_warps,
1569
+ waves_per_eu=waves_per_eu,
1570
+ )
1571
+
1572
+ return out
1573
+
1574
+
1575
+ class RoPE(autograd.Function):
1576
+ @staticmethod
1577
+ def forward(
1578
+ ctx,
1579
+ x: torch.Tensor,
1580
+ freqs: torch.Tensor,
1581
+ rotate_style: int,
1582
+ reuse_freqs_front_part: bool,
1583
+ nope_first: bool,
1584
+ transpose_output: bool = False,
1585
+ ) -> torch.Tensor:
1586
+ ctx.rotate_style = rotate_style
1587
+ ctx.reuse_freqs_front_part = reuse_freqs_front_part
1588
+ ctx.nope_first = nope_first
1589
+ ctx.transpose_output = transpose_output
1590
+ ctx.save_for_backward(freqs)
1591
+ return rope_fwd(
1592
+ x, freqs, rotate_style, reuse_freqs_front_part, nope_first, transpose_output
1593
+ )
1594
+
1595
+ @staticmethod
1596
+ def backward(
1597
+ ctx, output_grads: torch.Tensor
1598
+ ) -> Tuple[Union[torch.Tensor, None], ...]:
1599
+ (freqs,) = ctx.saved_tensors
1600
+ return (
1601
+ rope_bwd(
1602
+ output_grads,
1603
+ freqs,
1604
+ ctx.rotate_style,
1605
+ ctx.reuse_freqs_front_part,
1606
+ ctx.nope_first,
1607
+ ctx.transpose_output,
1608
+ ),
1609
+ None,
1610
+ None,
1611
+ )
1612
+
1613
+
1614
+ class RoPETHD(autograd.Function):
1615
+ @staticmethod
1616
+ def forward(
1617
+ ctx,
1618
+ x: torch.Tensor,
1619
+ cu_seqlens: torch.Tensor,
1620
+ freqs: torch.Tensor,
1621
+ rotate_style: int,
1622
+ reuse_freqs_front_part: bool,
1623
+ nope_first: bool,
1624
+ ):
1625
+ ctx.rotate_style = rotate_style
1626
+ ctx.reuse_freqs_front_part = reuse_freqs_front_part
1627
+ ctx.nope_first = nope_first
1628
+ ctx.save_for_backward(cu_seqlens, freqs)
1629
+ return rope_thd_fwd(
1630
+ x, cu_seqlens, freqs, rotate_style, reuse_freqs_front_part, nope_first
1631
+ )
1632
+
1633
+ @staticmethod
1634
+ def backward(ctx, output_grads) -> Tuple[Union[torch.Tensor, None], ...]:
1635
+ cu_seqlens, freqs = ctx.saved_tensors
1636
+ return (
1637
+ rope_thd_bwd(
1638
+ output_grads,
1639
+ cu_seqlens,
1640
+ freqs,
1641
+ ctx.rotate_style,
1642
+ ctx.reuse_freqs_front_part,
1643
+ ctx.nope_first,
1644
+ ),
1645
+ None,
1646
+ None,
1647
+ )
1648
+
1649
+
1650
+ class RoPECached(autograd.Function):
1651
+
1652
+ @staticmethod
1653
+ def forward(
1654
+ ctx,
1655
+ x: torch.Tensor,
1656
+ cos: torch.Tensor,
1657
+ sin: torch.Tensor,
1658
+ rotate_style: int,
1659
+ reuse_freqs_front_part: bool,
1660
+ nope_first: bool,
1661
+ transpose_output: bool = False,
1662
+ ) -> torch.Tensor:
1663
+ ctx.rotate_style = rotate_style
1664
+ ctx.reuse_freqs_front_part = reuse_freqs_front_part
1665
+ ctx.nope_first = nope_first
1666
+ ctx.transpose_output = transpose_output
1667
+ ctx.save_for_backward(cos, sin)
1668
+ return rope_cached_fwd(
1669
+ x,
1670
+ cos,
1671
+ sin,
1672
+ rotate_style,
1673
+ reuse_freqs_front_part,
1674
+ nope_first,
1675
+ transpose_output,
1676
+ )
1677
+
1678
+ @staticmethod
1679
+ def backward(ctx, output_grads) -> Tuple[Union[torch.Tensor, None], ...]:
1680
+ cos, sin = ctx.saved_tensors
1681
+ return (
1682
+ rope_cached_bwd(
1683
+ output_grads,
1684
+ cos,
1685
+ sin,
1686
+ ctx.rotate_style,
1687
+ ctx.reuse_freqs_front_part,
1688
+ ctx.nope_first,
1689
+ ctx.transpose_output,
1690
+ ),
1691
+ None,
1692
+ None,
1693
+ )
1694
+
1695
+
1696
+ class RoPE2D(autograd.Function):
1697
+ @staticmethod
1698
+ def forward(
1699
+ ctx,
1700
+ x: torch.Tensor,
1701
+ cos_height: torch.Tensor,
1702
+ sin_height: torch.Tensor,
1703
+ cos_width: torch.Tensor,
1704
+ sin_width: torch.Tensor,
1705
+ img_height: int,
1706
+ img_width: int,
1707
+ rotate_style: int,
1708
+ reuse_freqs_front_part: bool,
1709
+ nope_first: bool,
1710
+ ) -> torch.Tensor:
1711
+ ctx.img_height = img_height
1712
+ ctx.img_width = img_width
1713
+ ctx.rotate_style = rotate_style
1714
+ ctx.reuse_freqs_front_part = reuse_freqs_front_part
1715
+ ctx.nope_first = nope_first
1716
+ ctx.save_for_backward(cos_height, sin_height, cos_width, sin_width)
1717
+ return rope_fwd_2d(
1718
+ x,
1719
+ cos_height,
1720
+ sin_height,
1721
+ cos_width,
1722
+ sin_width,
1723
+ img_height,
1724
+ img_width,
1725
+ rotate_style,
1726
+ reuse_freqs_front_part,
1727
+ nope_first,
1728
+ )
build/torch-rocm/utils/__init__.py ADDED
File without changes
build/torch-rocm/utils/logger.py ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import logging
3
+
4
+
5
+ # AITER Triton Logger which is singleton object around python logging.
6
+ # Note: Python logging is also a singleton object, but we want to read the
7
+ # env var AITER_LOG_LEVEL once at the beginning. Another alternative is to do
8
+ # this in __init__.py. In fact, that's how CK logger is setup. We can look at
9
+ # switching to that at some point
10
+ #
11
+ # AITER_LOG_LEVEL follows python logging levels
12
+ # DEBUG
13
+ # INFO
14
+ # WARNING
15
+ # ERROR
16
+ # CRITICAL
17
+ #
18
+ class AiterTritonLogger(object):
19
+ _instance = None
20
+
21
+ def __new__(cls):
22
+ if cls._instance is None:
23
+ cls._instance = super(AiterTritonLogger, cls).__new__(cls)
24
+ log_level_str = os.getenv("AITER_TRITON_LOG_LEVEL", "WARNING").upper()
25
+ numeric_level = getattr(logging, log_level_str, logging.WARNING)
26
+ cls._instance._logger = logging.getLogger("AITER_TRITON")
27
+ cls._instance._logger.setLevel(numeric_level)
28
+
29
+ return cls._instance
30
+
31
+ def get_logger(self):
32
+ return self._logger
33
+
34
+ def debug(self, msg):
35
+ self._logger.debug(msg)
36
+
37
+ def info(self, msg):
38
+ self._logger.info(msg)
39
+
40
+ def warning(self, msg):
41
+ self._logger.warning(msg)
42
+
43
+ def error(self, msg):
44
+ self._logger.error(msg)
45
+
46
+ def critical(self, msg):
47
+ self._logger.critical(msg)