liangsu9988 commited on
Commit
c7f77da
·
verified ·
1 Parent(s): 273c7d1

Promote latest kernel artifacts to main

Browse files
Files changed (28) hide show
  1. README.md +0 -9
  2. benchmarks/benchmark.py +44 -1
  3. build/torch211-cxx11-cu128-x86_64-linux/__init__.py +121 -1
  4. build/torch211-cxx11-cu128-x86_64-linux/_ops.py +3 -3
  5. build/{torch212-cxx11-cu132-x86_64-linux/_transformer_layout_primitives_cuda_c9b2fa0.abi3.so → torch211-cxx11-cu128-x86_64-linux/_transformer_layout_primitives_cuda_0a2c98e.abi3.so} +2 -2
  6. build/torch211-cxx11-cu128-x86_64-linux/metadata.json +1 -1
  7. build/torch211-cxx11-cu130-aarch64-linux/__init__.py +249 -0
  8. build/torch211-cxx11-cu130-aarch64-linux/_ops.py +6 -0
  9. build/{torch211-cxx11-cu128-x86_64-linux/_transformer_layout_primitives_cuda_c9b2fa0.abi3.so → torch211-cxx11-cu130-aarch64-linux/_transformer_layout_primitives_cuda_916f685.abi3.so} +2 -2
  10. build/torch211-cxx11-cu130-aarch64-linux/metadata.json +22 -0
  11. build/torch211-cxx11-cu130-aarch64-linux/transformer_layout_primitives/__init__.py +14 -0
  12. build/torch211-cxx11-cu130-x86_64-linux/__init__.py +121 -1
  13. build/torch211-cxx11-cu130-x86_64-linux/_ops.py +3 -3
  14. build/torch211-cxx11-cu130-x86_64-linux/{_transformer_layout_primitives_cuda_c9b2fa0.abi3.so → _transformer_layout_primitives_cuda_0a2c98e.abi3.so} +2 -2
  15. build/torch211-cxx11-cu130-x86_64-linux/metadata.json +1 -1
  16. build/torch212-cxx11-cu130-x86_64-linux/__init__.py +121 -1
  17. build/torch212-cxx11-cu130-x86_64-linux/_ops.py +3 -3
  18. build/torch212-cxx11-cu130-x86_64-linux/{_transformer_layout_primitives_cuda_c9b2fa0.abi3.so → _transformer_layout_primitives_cuda_0a2c98e.abi3.so} +2 -2
  19. build/torch212-cxx11-cu130-x86_64-linux/metadata.json +1 -1
  20. build/torch212-cxx11-cu132-x86_64-linux/__init__.py +121 -1
  21. build/torch212-cxx11-cu132-x86_64-linux/_ops.py +3 -3
  22. build/torch212-cxx11-cu132-x86_64-linux/_transformer_layout_primitives_cuda_0a2c98e.abi3.so +3 -0
  23. build/torch212-cxx11-cu132-x86_64-linux/metadata.json +1 -1
  24. build/torch213-cxx11-cu130-aarch64-linux/__init__.py +249 -0
  25. build/torch213-cxx11-cu130-aarch64-linux/_ops.py +6 -0
  26. build/torch213-cxx11-cu130-aarch64-linux/metadata.json +32 -0
  27. build/torch213-cxx11-cu130-aarch64-linux/transformer_layout_primitives/__init__.py +14 -0
  28. build/torch213-cxx11-cu130-aarch64-linux/transformer_layout_primitives_source_test.abi3.so +3 -0
README.md DELETED
@@ -1,9 +0,0 @@
1
- # flashrt/transformer-layout-primitives
2
-
3
- This repository is a compatibility mirror for older `kernels` clients
4
- that resolve repositories through the default Hugging Face model repo API.
5
-
6
- Canonical Kernel Hub repo: https://huggingface.co/kernels/flashrt/transformer-layout-primitives
7
-
8
- Do not edit this mirror by hand. It is generated from the Kernel Hub
9
- `vN` branches and contains the same `build/**` artifacts.
 
 
 
 
 
 
 
 
 
 
benchmarks/benchmark.py CHANGED
@@ -12,7 +12,12 @@ import torch
12
 
13
  ROOT = Path(__file__).resolve().parents[2]
14
  sys.path.insert(0, str(ROOT / "transformer-layout-primitives" / "tests"))
15
- from test_transformer_layout_primitives import load_source_ops, qk_rmsnorm_rope_ref, rotate_half_ref # noqa: E402
 
 
 
 
 
16
 
17
 
18
  def load_ops(backend: str, artifact: str | None):
@@ -102,6 +107,44 @@ def main() -> int:
102
  eu = time_us(eager_rope, max(5, args.warmup // 2), max(20, args.iters // 2))
103
  print(f"{name},{seq}x{heads}x{dim},rope_rotate_half_bf16_,{fu:.3f},{eu:.3f},{eu/fu:.2f}x")
104
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  batch, seq, dim = 8, 2048, 2048
106
  x = torch.randn((batch * seq, dim), device="cuda", dtype=torch.bfloat16)
107
  gathered = torch.empty((2 * batch, dim), device="cuda", dtype=torch.bfloat16)
 
12
 
13
  ROOT = Path(__file__).resolve().parents[2]
14
  sys.path.insert(0, str(ROOT / "transformer-layout-primitives" / "tests"))
15
+ from test_transformer_layout_primitives import ( # noqa: E402
16
+ load_source_ops,
17
+ qk_pair_rmsnorm_rope_ref,
18
+ qk_rmsnorm_rope_ref,
19
+ rotate_half_ref,
20
+ )
21
 
22
 
23
  def load_ops(backend: str, artifact: str | None):
 
107
  eu = time_us(eager_rope, max(5, args.warmup // 2), max(20, args.iters // 2))
108
  print(f"{name},{seq}x{heads}x{dim},rope_rotate_half_bf16_,{fu:.3f},{eu:.3f},{eu/fu:.2f}x")
109
 
110
+ pair_shapes = [
111
+ ("groot_n17_llm", 277, 16, 8, 128),
112
+ ("qwen3vl_vision", 1024, 16, 16, 72),
113
+ ("lingbot_vision", 1024, 16, 16, 80),
114
+ ("video_transformer", 2520, 24, 24, 128),
115
+ ]
116
+ if args.mode == "full":
117
+ pair_shapes += [
118
+ ("action_boundary", 51, 16, 16, 64),
119
+ ("wan_partial_tile", 5070, 24, 24, 128),
120
+ ]
121
+ for name, rows, q_heads, k_heads, dim in pair_shapes:
122
+ q = torch.randn((rows, q_heads, dim), device="cuda", dtype=torch.bfloat16)
123
+ k = torch.randn((rows, k_heads, dim), device="cuda", dtype=torch.bfloat16)
124
+ q_weight = torch.randn((dim,), device="cuda", dtype=torch.bfloat16)
125
+ k_weight = torch.randn((dim,), device="cuda", dtype=torch.bfloat16)
126
+ cos = torch.randn((rows, dim), device="cuda", dtype=torch.bfloat16)
127
+ sin = torch.randn((rows, dim), device="cuda", dtype=torch.bfloat16)
128
+ q_out = torch.empty_like(q)
129
+ k_out = torch.empty_like(k)
130
+
131
+ def flash_pair():
132
+ ops.qk_pair_rmsnorm_rope_bf16(
133
+ q, k, q_weight, k_weight, cos, sin, q_out=q_out, k_out=k_out
134
+ )
135
+
136
+ def eager_pair():
137
+ qk_pair_rmsnorm_rope_ref(
138
+ q, k, q_weight, k_weight, cos, sin
139
+ )
140
+
141
+ fu = time_us(flash_pair, args.warmup, args.iters)
142
+ eu = time_us(eager_pair, max(5, args.warmup // 2), max(20, args.iters // 2))
143
+ print(
144
+ f"{name},{rows}x{q_heads}+{k_heads}x{dim},"
145
+ f"qk_pair_rmsnorm_rope_bf16,{fu:.3f},{eu:.3f},{eu/fu:.2f}x"
146
+ )
147
+
148
  batch, seq, dim = 8, 2048, 2048
149
  x = torch.randn((batch * seq, dim), device="cuda", dtype=torch.bfloat16)
150
  gathered = torch.empty((2 * batch, dim), device="cuda", dtype=torch.bfloat16)
build/torch211-cxx11-cu128-x86_64-linux/__init__.py CHANGED
@@ -55,13 +55,75 @@ def _qk_rmsnorm_rope_bf16_fake(
55
  weight: torch.Tensor,
56
  cos: torch.Tensor,
57
  sin: torch.Tensor,
58
- eps: float,
59
  ) -> None:
60
  if qk.dim() != 3 or weight.shape != (qk.shape[2],) or cos.shape != (qk.shape[0], qk.shape[2]) or sin.shape != cos.shape:
61
  raise RuntimeError("qk_rmsnorm_rope_bf16_ expects qk (rows, heads, dim), weight (dim,), cos/sin (rows, dim)")
62
  return None
63
 
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  def fill_neginf_bf16(dst: torch.Tensor) -> torch.Tensor:
66
  ops.fill_neginf_bf16(dst)
67
  return dst
@@ -118,6 +180,61 @@ def qk_rmsnorm_rope_bf16_(
118
  return qk
119
 
120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  __all__ = [
122
  "fill_neginf_bf16",
123
  "add_bias_bf16_",
@@ -126,4 +243,7 @@ __all__ = [
126
  "text_scatter_bf16",
127
  "rope_rotate_half_bf16_",
128
  "qk_rmsnorm_rope_bf16_",
 
 
 
129
  ]
 
55
  weight: torch.Tensor,
56
  cos: torch.Tensor,
57
  sin: torch.Tensor,
58
+ eps: float = 1e-6,
59
  ) -> None:
60
  if qk.dim() != 3 or weight.shape != (qk.shape[2],) or cos.shape != (qk.shape[0], qk.shape[2]) or sin.shape != cos.shape:
61
  raise RuntimeError("qk_rmsnorm_rope_bf16_ expects qk (rows, heads, dim), weight (dim,), cos/sin (rows, dim)")
62
  return None
63
 
64
 
65
+ @torch.library.register_fake(add_op_namespace_prefix("qk_pair_rmsnorm_rope_bf16"))
66
+ def _qk_pair_rmsnorm_rope_bf16_fake(
67
+ q: torch.Tensor,
68
+ k: torch.Tensor,
69
+ q_weight: torch.Tensor,
70
+ k_weight: torch.Tensor,
71
+ cos: torch.Tensor,
72
+ sin: torch.Tensor,
73
+ eps: float,
74
+ q_out: torch.Tensor,
75
+ k_out: torch.Tensor,
76
+ ) -> None:
77
+ if (
78
+ q.dim() != 3
79
+ or k.dim() != 3
80
+ or q.shape[0] != k.shape[0]
81
+ or q.shape[2] != k.shape[2]
82
+ or q.shape[2] < 8
83
+ or q.shape[2] > 256
84
+ or q.shape[2] % 2 != 0
85
+ or q_weight.shape != (q.shape[2],)
86
+ or k_weight.shape != q_weight.shape
87
+ or cos.shape != (q.shape[0], q.shape[2])
88
+ or sin.shape != cos.shape
89
+ or q_out.shape != q.shape
90
+ or k_out.shape != k.shape
91
+ ):
92
+ raise RuntimeError(
93
+ "qk_pair_rmsnorm_rope_bf16 expects q/k (rows, heads, even_dim), "
94
+ "weights (dim,), cos/sin (rows, dim), and matching outputs"
95
+ )
96
+ return None
97
+
98
+
99
+ @torch.library.register_fake(add_op_namespace_prefix("gather_rows_bf16"))
100
+ def _gather_rows_bf16_fake(
101
+ src: torch.Tensor,
102
+ row_indices: torch.Tensor,
103
+ dst: torch.Tensor,
104
+ ) -> None:
105
+ if src.dim() != 2 or row_indices.dim() != 1 or dst.shape != (row_indices.numel(), src.shape[1]):
106
+ raise RuntimeError(
107
+ "gather_rows_bf16 expects src (source_rows, hidden), "
108
+ "row_indices (rows,), dst (rows, hidden)"
109
+ )
110
+ return None
111
+
112
+
113
+ @torch.library.register_fake(add_op_namespace_prefix("scatter_rows_bf16"))
114
+ def _scatter_rows_bf16_fake(
115
+ src: torch.Tensor,
116
+ row_indices: torch.Tensor,
117
+ dst: torch.Tensor,
118
+ ) -> None:
119
+ if src.dim() != 2 or row_indices.dim() != 1 or src.shape != (row_indices.numel(), dst.shape[1]):
120
+ raise RuntimeError(
121
+ "scatter_rows_bf16 expects src (rows, hidden), "
122
+ "row_indices (rows,), dst (destination_rows, hidden)"
123
+ )
124
+ return None
125
+
126
+
127
  def fill_neginf_bf16(dst: torch.Tensor) -> torch.Tensor:
128
  ops.fill_neginf_bf16(dst)
129
  return dst
 
180
  return qk
181
 
182
 
183
+ def qk_pair_rmsnorm_rope_bf16(
184
+ q: torch.Tensor,
185
+ k: torch.Tensor,
186
+ q_weight: torch.Tensor,
187
+ k_weight: torch.Tensor,
188
+ cos: torch.Tensor,
189
+ sin: torch.Tensor,
190
+ eps: float = 1e-6,
191
+ *,
192
+ q_out: Optional[torch.Tensor] = None,
193
+ k_out: Optional[torch.Tensor] = None,
194
+ ) -> tuple[torch.Tensor, torch.Tensor]:
195
+ if q_out is None:
196
+ q_out = torch.empty_like(q)
197
+ if k_out is None:
198
+ k_out = torch.empty_like(k)
199
+ ops.qk_pair_rmsnorm_rope_bf16(
200
+ q, k, q_weight, k_weight, cos, sin, float(eps), q_out, k_out
201
+ )
202
+ return q_out, k_out
203
+
204
+
205
+ def gather_rows_bf16(
206
+ src: torch.Tensor,
207
+ row_indices: torch.Tensor,
208
+ *,
209
+ out: Optional[torch.Tensor] = None,
210
+ ) -> torch.Tensor:
211
+ """Gather rows using in-range CUDA int64 indices without host synchronization."""
212
+
213
+ if out is None:
214
+ out = torch.empty(
215
+ (row_indices.numel(), src.shape[1]), device=src.device, dtype=src.dtype
216
+ )
217
+ ops.gather_rows_bf16(src, row_indices, out)
218
+ return out
219
+
220
+
221
+ def scatter_rows_bf16(
222
+ src: torch.Tensor,
223
+ row_indices: torch.Tensor,
224
+ destination_rows: int,
225
+ *,
226
+ out: Optional[torch.Tensor] = None,
227
+ ) -> torch.Tensor:
228
+ """Scatter rows to unique, in-range CUDA int64 indices."""
229
+
230
+ if out is None:
231
+ out = torch.zeros(
232
+ (destination_rows, src.shape[1]), device=src.device, dtype=src.dtype
233
+ )
234
+ ops.scatter_rows_bf16(src, row_indices, out)
235
+ return out
236
+
237
+
238
  __all__ = [
239
  "fill_neginf_bf16",
240
  "add_bias_bf16_",
 
243
  "text_scatter_bf16",
244
  "rope_rotate_half_bf16_",
245
  "qk_rmsnorm_rope_bf16_",
246
+ "qk_pair_rmsnorm_rope_bf16",
247
+ "gather_rows_bf16",
248
+ "scatter_rows_bf16",
249
  ]
build/torch211-cxx11-cu128-x86_64-linux/_ops.py CHANGED
@@ -1,9 +1,9 @@
1
  import torch
2
- from . import _transformer_layout_primitives_cuda_c9b2fa0
3
- ops = torch.ops._transformer_layout_primitives_cuda_c9b2fa0
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
- return f"_transformer_layout_primitives_cuda_c9b2fa0::{op_name}"
 
1
  import torch
2
+ from . import _transformer_layout_primitives_cuda_0a2c98e
3
+ ops = torch.ops._transformer_layout_primitives_cuda_0a2c98e
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
+ return f"_transformer_layout_primitives_cuda_0a2c98e::{op_name}"
build/{torch212-cxx11-cu132-x86_64-linux/_transformer_layout_primitives_cuda_c9b2fa0.abi3.so → torch211-cxx11-cu128-x86_64-linux/_transformer_layout_primitives_cuda_0a2c98e.abi3.so} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:1947aebc33c49a48c82a0da681b56e16c0517460121fa5ce7cbc1d39f1e9832b
3
- size 574520
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:837e8b7e5c5f099bdad66ac56e375101f4e54ba47af08478f3f132222fadaa84
3
+ size 816416
build/torch211-cxx11-cu128-x86_64-linux/metadata.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "name": "transformer-layout-primitives",
3
- "id": "_transformer_layout_primitives_cuda_c9b2fa0",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "python-depends": [],
 
1
  {
2
  "name": "transformer-layout-primitives",
3
+ "id": "_transformer_layout_primitives_cuda_0a2c98e",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "python-depends": [],
build/torch211-cxx11-cu130-aarch64-linux/__init__.py ADDED
@@ -0,0 +1,249 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """FlashRT transformer layout primitives."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Optional
6
+
7
+ import torch
8
+
9
+ from ._ops import add_op_namespace_prefix, ops
10
+
11
+
12
+ @torch.library.register_fake(add_op_namespace_prefix("fill_neginf_bf16"))
13
+ def _fill_neginf_bf16_fake(dst: torch.Tensor) -> None:
14
+ return None
15
+
16
+
17
+ @torch.library.register_fake(add_op_namespace_prefix("add_bias_bf16_"))
18
+ def _add_bias_bf16_fake(data: torch.Tensor, bias: torch.Tensor) -> None:
19
+ if data.dim() != 2 or bias.shape != (data.shape[1],):
20
+ raise RuntimeError("add_bias_bf16_ expects data (rows, cols), bias (cols,)")
21
+ return None
22
+
23
+
24
+ @torch.library.register_fake(add_op_namespace_prefix("repeat_interleave_heads_bf16"))
25
+ def _repeat_interleave_heads_bf16_fake(src: torch.Tensor, repeat: int, dst: torch.Tensor) -> None:
26
+ if src.dim() != 3 or dst.shape != (src.shape[0], src.shape[1] * repeat, src.shape[2]):
27
+ raise RuntimeError("repeat_interleave_heads_bf16 expects src (seq, heads, dim), dst (seq, heads*repeat, dim)")
28
+ return None
29
+
30
+
31
+ @torch.library.register_fake(add_op_namespace_prefix("text_gather_bf16"))
32
+ def _text_gather_bf16_fake(src: torch.Tensor, batch: int, seq: int, dst: torch.Tensor) -> None:
33
+ if src.dim() != 2 or src.shape[0] != batch * seq or dst.shape != (2 * batch, src.shape[1]):
34
+ raise RuntimeError("text_gather_bf16 expects src (batch*seq, dim), dst (2*batch, dim)")
35
+ return None
36
+
37
+
38
+ @torch.library.register_fake(add_op_namespace_prefix("text_scatter_bf16"))
39
+ def _text_scatter_bf16_fake(dst: torch.Tensor, src: torch.Tensor, batch: int, seq: int) -> None:
40
+ if dst.dim() != 2 or dst.shape[0] != batch * seq or src.shape != (2 * batch, dst.shape[1]):
41
+ raise RuntimeError("text_scatter_bf16 expects dst (batch*seq, dim), src (2*batch, dim)")
42
+ return None
43
+
44
+
45
+ @torch.library.register_fake(add_op_namespace_prefix("rope_rotate_half_bf16_"))
46
+ def _rope_rotate_half_bf16_fake(x: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor) -> None:
47
+ if x.dim() != 3 or x.shape[2] % 2 != 0 or cos.shape != (x.shape[0], x.shape[2]) or sin.shape != cos.shape:
48
+ raise RuntimeError("rope_rotate_half_bf16_ expects x (seq, heads, even_dim), cos/sin (seq, dim)")
49
+ return None
50
+
51
+
52
+ @torch.library.register_fake(add_op_namespace_prefix("qk_rmsnorm_rope_bf16_"))
53
+ def _qk_rmsnorm_rope_bf16_fake(
54
+ qk: torch.Tensor,
55
+ weight: torch.Tensor,
56
+ cos: torch.Tensor,
57
+ sin: torch.Tensor,
58
+ eps: float = 1e-6,
59
+ ) -> None:
60
+ if qk.dim() != 3 or weight.shape != (qk.shape[2],) or cos.shape != (qk.shape[0], qk.shape[2]) or sin.shape != cos.shape:
61
+ raise RuntimeError("qk_rmsnorm_rope_bf16_ expects qk (rows, heads, dim), weight (dim,), cos/sin (rows, dim)")
62
+ return None
63
+
64
+
65
+ @torch.library.register_fake(add_op_namespace_prefix("qk_pair_rmsnorm_rope_bf16"))
66
+ def _qk_pair_rmsnorm_rope_bf16_fake(
67
+ q: torch.Tensor,
68
+ k: torch.Tensor,
69
+ q_weight: torch.Tensor,
70
+ k_weight: torch.Tensor,
71
+ cos: torch.Tensor,
72
+ sin: torch.Tensor,
73
+ eps: float,
74
+ q_out: torch.Tensor,
75
+ k_out: torch.Tensor,
76
+ ) -> None:
77
+ if (
78
+ q.dim() != 3
79
+ or k.dim() != 3
80
+ or q.shape[0] != k.shape[0]
81
+ or q.shape[2] != k.shape[2]
82
+ or q.shape[2] < 8
83
+ or q.shape[2] > 256
84
+ or q.shape[2] % 2 != 0
85
+ or q_weight.shape != (q.shape[2],)
86
+ or k_weight.shape != q_weight.shape
87
+ or cos.shape != (q.shape[0], q.shape[2])
88
+ or sin.shape != cos.shape
89
+ or q_out.shape != q.shape
90
+ or k_out.shape != k.shape
91
+ ):
92
+ raise RuntimeError(
93
+ "qk_pair_rmsnorm_rope_bf16 expects q/k (rows, heads, even_dim), "
94
+ "weights (dim,), cos/sin (rows, dim), and matching outputs"
95
+ )
96
+ return None
97
+
98
+
99
+ @torch.library.register_fake(add_op_namespace_prefix("gather_rows_bf16"))
100
+ def _gather_rows_bf16_fake(
101
+ src: torch.Tensor,
102
+ row_indices: torch.Tensor,
103
+ dst: torch.Tensor,
104
+ ) -> None:
105
+ if src.dim() != 2 or row_indices.dim() != 1 or dst.shape != (row_indices.numel(), src.shape[1]):
106
+ raise RuntimeError(
107
+ "gather_rows_bf16 expects src (source_rows, hidden), "
108
+ "row_indices (rows,), dst (rows, hidden)"
109
+ )
110
+ return None
111
+
112
+
113
+ @torch.library.register_fake(add_op_namespace_prefix("scatter_rows_bf16"))
114
+ def _scatter_rows_bf16_fake(
115
+ src: torch.Tensor,
116
+ row_indices: torch.Tensor,
117
+ dst: torch.Tensor,
118
+ ) -> None:
119
+ if src.dim() != 2 or row_indices.dim() != 1 or src.shape != (row_indices.numel(), dst.shape[1]):
120
+ raise RuntimeError(
121
+ "scatter_rows_bf16 expects src (rows, hidden), "
122
+ "row_indices (rows,), dst (destination_rows, hidden)"
123
+ )
124
+ return None
125
+
126
+
127
+ def fill_neginf_bf16(dst: torch.Tensor) -> torch.Tensor:
128
+ ops.fill_neginf_bf16(dst)
129
+ return dst
130
+
131
+
132
+ def add_bias_bf16_(data: torch.Tensor, bias: torch.Tensor) -> torch.Tensor:
133
+ ops.add_bias_bf16_(data, bias)
134
+ return data
135
+
136
+
137
+ def repeat_interleave_heads_bf16(
138
+ src: torch.Tensor,
139
+ repeat: int,
140
+ *,
141
+ out: Optional[torch.Tensor] = None,
142
+ ) -> torch.Tensor:
143
+ if out is None:
144
+ out = torch.empty((src.shape[0], src.shape[1] * repeat, src.shape[2]), device=src.device, dtype=src.dtype)
145
+ ops.repeat_interleave_heads_bf16(src, int(repeat), out)
146
+ return out
147
+
148
+
149
+ def text_gather_bf16(
150
+ src: torch.Tensor,
151
+ batch: int,
152
+ seq: int,
153
+ *,
154
+ out: Optional[torch.Tensor] = None,
155
+ ) -> torch.Tensor:
156
+ if out is None:
157
+ out = torch.empty((2 * batch, src.shape[1]), device=src.device, dtype=src.dtype)
158
+ ops.text_gather_bf16(src, int(batch), int(seq), out)
159
+ return out
160
+
161
+
162
+ def text_scatter_bf16(dst: torch.Tensor, src: torch.Tensor, batch: int, seq: int) -> torch.Tensor:
163
+ ops.text_scatter_bf16(dst, src, int(batch), int(seq))
164
+ return dst
165
+
166
+
167
+ def rope_rotate_half_bf16_(x: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor) -> torch.Tensor:
168
+ ops.rope_rotate_half_bf16_(x, cos, sin)
169
+ return x
170
+
171
+
172
+ def qk_rmsnorm_rope_bf16_(
173
+ qk: torch.Tensor,
174
+ weight: torch.Tensor,
175
+ cos: torch.Tensor,
176
+ sin: torch.Tensor,
177
+ eps: float = 1e-6,
178
+ ) -> torch.Tensor:
179
+ ops.qk_rmsnorm_rope_bf16_(qk, weight, cos, sin, float(eps))
180
+ return qk
181
+
182
+
183
+ def qk_pair_rmsnorm_rope_bf16(
184
+ q: torch.Tensor,
185
+ k: torch.Tensor,
186
+ q_weight: torch.Tensor,
187
+ k_weight: torch.Tensor,
188
+ cos: torch.Tensor,
189
+ sin: torch.Tensor,
190
+ eps: float = 1e-6,
191
+ *,
192
+ q_out: Optional[torch.Tensor] = None,
193
+ k_out: Optional[torch.Tensor] = None,
194
+ ) -> tuple[torch.Tensor, torch.Tensor]:
195
+ if q_out is None:
196
+ q_out = torch.empty_like(q)
197
+ if k_out is None:
198
+ k_out = torch.empty_like(k)
199
+ ops.qk_pair_rmsnorm_rope_bf16(
200
+ q, k, q_weight, k_weight, cos, sin, float(eps), q_out, k_out
201
+ )
202
+ return q_out, k_out
203
+
204
+
205
+ def gather_rows_bf16(
206
+ src: torch.Tensor,
207
+ row_indices: torch.Tensor,
208
+ *,
209
+ out: Optional[torch.Tensor] = None,
210
+ ) -> torch.Tensor:
211
+ """Gather rows using in-range CUDA int64 indices without host synchronization."""
212
+
213
+ if out is None:
214
+ out = torch.empty(
215
+ (row_indices.numel(), src.shape[1]), device=src.device, dtype=src.dtype
216
+ )
217
+ ops.gather_rows_bf16(src, row_indices, out)
218
+ return out
219
+
220
+
221
+ def scatter_rows_bf16(
222
+ src: torch.Tensor,
223
+ row_indices: torch.Tensor,
224
+ destination_rows: int,
225
+ *,
226
+ out: Optional[torch.Tensor] = None,
227
+ ) -> torch.Tensor:
228
+ """Scatter rows to unique, in-range CUDA int64 indices."""
229
+
230
+ if out is None:
231
+ out = torch.zeros(
232
+ (destination_rows, src.shape[1]), device=src.device, dtype=src.dtype
233
+ )
234
+ ops.scatter_rows_bf16(src, row_indices, out)
235
+ return out
236
+
237
+
238
+ __all__ = [
239
+ "fill_neginf_bf16",
240
+ "add_bias_bf16_",
241
+ "repeat_interleave_heads_bf16",
242
+ "text_gather_bf16",
243
+ "text_scatter_bf16",
244
+ "rope_rotate_half_bf16_",
245
+ "qk_rmsnorm_rope_bf16_",
246
+ "qk_pair_rmsnorm_rope_bf16",
247
+ "gather_rows_bf16",
248
+ "scatter_rows_bf16",
249
+ ]
build/torch211-cxx11-cu130-aarch64-linux/_ops.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _transformer_layout_primitives_cuda_916f685
3
+ ops = torch.ops._transformer_layout_primitives_cuda_916f685
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ return f"_transformer_layout_primitives_cuda_916f685::{op_name}"
build/{torch211-cxx11-cu128-x86_64-linux/_transformer_layout_primitives_cuda_c9b2fa0.abi3.so → torch211-cxx11-cu130-aarch64-linux/_transformer_layout_primitives_cuda_916f685.abi3.so} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:8391a04a4384cc92d83c6df4c86ecdd205567c00105c13a01ca54c2b88fdd371
3
- size 572816
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c8756d718dd2b2d6ebb87618d7db67c81f18b842e7f6e4368b17e2bf60a1c9dc
3
+ size 328480
build/torch211-cxx11-cu130-aarch64-linux/metadata.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "transformer-layout-primitives",
3
+ "id": "_transformer_layout_primitives_cuda_916f685",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "11.0"
11
+ ]
12
+ },
13
+ "digest": {
14
+ "algorithm": "sha256",
15
+ "files": {
16
+ "__init__.py": "Le2NlMbv2iPKF5/hg87FKZwzjsVjK1dras7vbnPWYx8=",
17
+ "_transformer_layout_primitives_cuda_916f685.abi3.so": "yHVtcY3SstbruHYY19tnyB8YuELn9uQ2ixfiv2Chydw=",
18
+ "_ops.py": "YTOtZXEGILlA33lBYiZozOFNN4oQApx6STt61PAHcUc=",
19
+ "transformer_layout_primitives/__init__.py": "v6p5XMfQzddhi1fLSAw4HX9CyS0rQsidvu9VsT01xi4="
20
+ }
21
+ }
22
+ }
build/torch211-cxx11-cu130-aarch64-linux/transformer_layout_primitives/__init__.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ctypes
2
+ import importlib.util
3
+ import sys
4
+ from pathlib import Path
5
+
6
+ def _import_from_path(file_path: Path):
7
+ path_hash = '{:x}'.format(ctypes.c_size_t(hash(file_path.absolute())).value)
8
+ spec = importlib.util.spec_from_file_location(path_hash, file_path)
9
+ module = importlib.util.module_from_spec(spec)
10
+ sys.modules[path_hash] = module
11
+ spec.loader.exec_module(module)
12
+ return module
13
+
14
+ globals().update(vars(_import_from_path(Path(__file__).parent.parent / '__init__.py')))
build/torch211-cxx11-cu130-x86_64-linux/__init__.py CHANGED
@@ -55,13 +55,75 @@ def _qk_rmsnorm_rope_bf16_fake(
55
  weight: torch.Tensor,
56
  cos: torch.Tensor,
57
  sin: torch.Tensor,
58
- eps: float,
59
  ) -> None:
60
  if qk.dim() != 3 or weight.shape != (qk.shape[2],) or cos.shape != (qk.shape[0], qk.shape[2]) or sin.shape != cos.shape:
61
  raise RuntimeError("qk_rmsnorm_rope_bf16_ expects qk (rows, heads, dim), weight (dim,), cos/sin (rows, dim)")
62
  return None
63
 
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  def fill_neginf_bf16(dst: torch.Tensor) -> torch.Tensor:
66
  ops.fill_neginf_bf16(dst)
67
  return dst
@@ -118,6 +180,61 @@ def qk_rmsnorm_rope_bf16_(
118
  return qk
119
 
120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  __all__ = [
122
  "fill_neginf_bf16",
123
  "add_bias_bf16_",
@@ -126,4 +243,7 @@ __all__ = [
126
  "text_scatter_bf16",
127
  "rope_rotate_half_bf16_",
128
  "qk_rmsnorm_rope_bf16_",
 
 
 
129
  ]
 
55
  weight: torch.Tensor,
56
  cos: torch.Tensor,
57
  sin: torch.Tensor,
58
+ eps: float = 1e-6,
59
  ) -> None:
60
  if qk.dim() != 3 or weight.shape != (qk.shape[2],) or cos.shape != (qk.shape[0], qk.shape[2]) or sin.shape != cos.shape:
61
  raise RuntimeError("qk_rmsnorm_rope_bf16_ expects qk (rows, heads, dim), weight (dim,), cos/sin (rows, dim)")
62
  return None
63
 
64
 
65
+ @torch.library.register_fake(add_op_namespace_prefix("qk_pair_rmsnorm_rope_bf16"))
66
+ def _qk_pair_rmsnorm_rope_bf16_fake(
67
+ q: torch.Tensor,
68
+ k: torch.Tensor,
69
+ q_weight: torch.Tensor,
70
+ k_weight: torch.Tensor,
71
+ cos: torch.Tensor,
72
+ sin: torch.Tensor,
73
+ eps: float,
74
+ q_out: torch.Tensor,
75
+ k_out: torch.Tensor,
76
+ ) -> None:
77
+ if (
78
+ q.dim() != 3
79
+ or k.dim() != 3
80
+ or q.shape[0] != k.shape[0]
81
+ or q.shape[2] != k.shape[2]
82
+ or q.shape[2] < 8
83
+ or q.shape[2] > 256
84
+ or q.shape[2] % 2 != 0
85
+ or q_weight.shape != (q.shape[2],)
86
+ or k_weight.shape != q_weight.shape
87
+ or cos.shape != (q.shape[0], q.shape[2])
88
+ or sin.shape != cos.shape
89
+ or q_out.shape != q.shape
90
+ or k_out.shape != k.shape
91
+ ):
92
+ raise RuntimeError(
93
+ "qk_pair_rmsnorm_rope_bf16 expects q/k (rows, heads, even_dim), "
94
+ "weights (dim,), cos/sin (rows, dim), and matching outputs"
95
+ )
96
+ return None
97
+
98
+
99
+ @torch.library.register_fake(add_op_namespace_prefix("gather_rows_bf16"))
100
+ def _gather_rows_bf16_fake(
101
+ src: torch.Tensor,
102
+ row_indices: torch.Tensor,
103
+ dst: torch.Tensor,
104
+ ) -> None:
105
+ if src.dim() != 2 or row_indices.dim() != 1 or dst.shape != (row_indices.numel(), src.shape[1]):
106
+ raise RuntimeError(
107
+ "gather_rows_bf16 expects src (source_rows, hidden), "
108
+ "row_indices (rows,), dst (rows, hidden)"
109
+ )
110
+ return None
111
+
112
+
113
+ @torch.library.register_fake(add_op_namespace_prefix("scatter_rows_bf16"))
114
+ def _scatter_rows_bf16_fake(
115
+ src: torch.Tensor,
116
+ row_indices: torch.Tensor,
117
+ dst: torch.Tensor,
118
+ ) -> None:
119
+ if src.dim() != 2 or row_indices.dim() != 1 or src.shape != (row_indices.numel(), dst.shape[1]):
120
+ raise RuntimeError(
121
+ "scatter_rows_bf16 expects src (rows, hidden), "
122
+ "row_indices (rows,), dst (destination_rows, hidden)"
123
+ )
124
+ return None
125
+
126
+
127
  def fill_neginf_bf16(dst: torch.Tensor) -> torch.Tensor:
128
  ops.fill_neginf_bf16(dst)
129
  return dst
 
180
  return qk
181
 
182
 
183
+ def qk_pair_rmsnorm_rope_bf16(
184
+ q: torch.Tensor,
185
+ k: torch.Tensor,
186
+ q_weight: torch.Tensor,
187
+ k_weight: torch.Tensor,
188
+ cos: torch.Tensor,
189
+ sin: torch.Tensor,
190
+ eps: float = 1e-6,
191
+ *,
192
+ q_out: Optional[torch.Tensor] = None,
193
+ k_out: Optional[torch.Tensor] = None,
194
+ ) -> tuple[torch.Tensor, torch.Tensor]:
195
+ if q_out is None:
196
+ q_out = torch.empty_like(q)
197
+ if k_out is None:
198
+ k_out = torch.empty_like(k)
199
+ ops.qk_pair_rmsnorm_rope_bf16(
200
+ q, k, q_weight, k_weight, cos, sin, float(eps), q_out, k_out
201
+ )
202
+ return q_out, k_out
203
+
204
+
205
+ def gather_rows_bf16(
206
+ src: torch.Tensor,
207
+ row_indices: torch.Tensor,
208
+ *,
209
+ out: Optional[torch.Tensor] = None,
210
+ ) -> torch.Tensor:
211
+ """Gather rows using in-range CUDA int64 indices without host synchronization."""
212
+
213
+ if out is None:
214
+ out = torch.empty(
215
+ (row_indices.numel(), src.shape[1]), device=src.device, dtype=src.dtype
216
+ )
217
+ ops.gather_rows_bf16(src, row_indices, out)
218
+ return out
219
+
220
+
221
+ def scatter_rows_bf16(
222
+ src: torch.Tensor,
223
+ row_indices: torch.Tensor,
224
+ destination_rows: int,
225
+ *,
226
+ out: Optional[torch.Tensor] = None,
227
+ ) -> torch.Tensor:
228
+ """Scatter rows to unique, in-range CUDA int64 indices."""
229
+
230
+ if out is None:
231
+ out = torch.zeros(
232
+ (destination_rows, src.shape[1]), device=src.device, dtype=src.dtype
233
+ )
234
+ ops.scatter_rows_bf16(src, row_indices, out)
235
+ return out
236
+
237
+
238
  __all__ = [
239
  "fill_neginf_bf16",
240
  "add_bias_bf16_",
 
243
  "text_scatter_bf16",
244
  "rope_rotate_half_bf16_",
245
  "qk_rmsnorm_rope_bf16_",
246
+ "qk_pair_rmsnorm_rope_bf16",
247
+ "gather_rows_bf16",
248
+ "scatter_rows_bf16",
249
  ]
build/torch211-cxx11-cu130-x86_64-linux/_ops.py CHANGED
@@ -1,9 +1,9 @@
1
  import torch
2
- from . import _transformer_layout_primitives_cuda_c9b2fa0
3
- ops = torch.ops._transformer_layout_primitives_cuda_c9b2fa0
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
- return f"_transformer_layout_primitives_cuda_c9b2fa0::{op_name}"
 
1
  import torch
2
+ from . import _transformer_layout_primitives_cuda_0a2c98e
3
+ ops = torch.ops._transformer_layout_primitives_cuda_0a2c98e
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
+ return f"_transformer_layout_primitives_cuda_0a2c98e::{op_name}"
build/torch211-cxx11-cu130-x86_64-linux/{_transformer_layout_primitives_cuda_c9b2fa0.abi3.so → _transformer_layout_primitives_cuda_0a2c98e.abi3.so} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:99943084af51325b92b740243b59d224141161ee451749776e1c89ce7cceded2
3
- size 564160
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f184cbedf680649ed33eed7aeab4e5421ebb99ec37323b0cf21b57577c9d594d
3
+ size 803048
build/torch211-cxx11-cu130-x86_64-linux/metadata.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "name": "transformer-layout-primitives",
3
- "id": "_transformer_layout_primitives_cuda_c9b2fa0",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "python-depends": [],
 
1
  {
2
  "name": "transformer-layout-primitives",
3
+ "id": "_transformer_layout_primitives_cuda_0a2c98e",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "python-depends": [],
build/torch212-cxx11-cu130-x86_64-linux/__init__.py CHANGED
@@ -55,13 +55,75 @@ def _qk_rmsnorm_rope_bf16_fake(
55
  weight: torch.Tensor,
56
  cos: torch.Tensor,
57
  sin: torch.Tensor,
58
- eps: float,
59
  ) -> None:
60
  if qk.dim() != 3 or weight.shape != (qk.shape[2],) or cos.shape != (qk.shape[0], qk.shape[2]) or sin.shape != cos.shape:
61
  raise RuntimeError("qk_rmsnorm_rope_bf16_ expects qk (rows, heads, dim), weight (dim,), cos/sin (rows, dim)")
62
  return None
63
 
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  def fill_neginf_bf16(dst: torch.Tensor) -> torch.Tensor:
66
  ops.fill_neginf_bf16(dst)
67
  return dst
@@ -118,6 +180,61 @@ def qk_rmsnorm_rope_bf16_(
118
  return qk
119
 
120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  __all__ = [
122
  "fill_neginf_bf16",
123
  "add_bias_bf16_",
@@ -126,4 +243,7 @@ __all__ = [
126
  "text_scatter_bf16",
127
  "rope_rotate_half_bf16_",
128
  "qk_rmsnorm_rope_bf16_",
 
 
 
129
  ]
 
55
  weight: torch.Tensor,
56
  cos: torch.Tensor,
57
  sin: torch.Tensor,
58
+ eps: float = 1e-6,
59
  ) -> None:
60
  if qk.dim() != 3 or weight.shape != (qk.shape[2],) or cos.shape != (qk.shape[0], qk.shape[2]) or sin.shape != cos.shape:
61
  raise RuntimeError("qk_rmsnorm_rope_bf16_ expects qk (rows, heads, dim), weight (dim,), cos/sin (rows, dim)")
62
  return None
63
 
64
 
65
+ @torch.library.register_fake(add_op_namespace_prefix("qk_pair_rmsnorm_rope_bf16"))
66
+ def _qk_pair_rmsnorm_rope_bf16_fake(
67
+ q: torch.Tensor,
68
+ k: torch.Tensor,
69
+ q_weight: torch.Tensor,
70
+ k_weight: torch.Tensor,
71
+ cos: torch.Tensor,
72
+ sin: torch.Tensor,
73
+ eps: float,
74
+ q_out: torch.Tensor,
75
+ k_out: torch.Tensor,
76
+ ) -> None:
77
+ if (
78
+ q.dim() != 3
79
+ or k.dim() != 3
80
+ or q.shape[0] != k.shape[0]
81
+ or q.shape[2] != k.shape[2]
82
+ or q.shape[2] < 8
83
+ or q.shape[2] > 256
84
+ or q.shape[2] % 2 != 0
85
+ or q_weight.shape != (q.shape[2],)
86
+ or k_weight.shape != q_weight.shape
87
+ or cos.shape != (q.shape[0], q.shape[2])
88
+ or sin.shape != cos.shape
89
+ or q_out.shape != q.shape
90
+ or k_out.shape != k.shape
91
+ ):
92
+ raise RuntimeError(
93
+ "qk_pair_rmsnorm_rope_bf16 expects q/k (rows, heads, even_dim), "
94
+ "weights (dim,), cos/sin (rows, dim), and matching outputs"
95
+ )
96
+ return None
97
+
98
+
99
+ @torch.library.register_fake(add_op_namespace_prefix("gather_rows_bf16"))
100
+ def _gather_rows_bf16_fake(
101
+ src: torch.Tensor,
102
+ row_indices: torch.Tensor,
103
+ dst: torch.Tensor,
104
+ ) -> None:
105
+ if src.dim() != 2 or row_indices.dim() != 1 or dst.shape != (row_indices.numel(), src.shape[1]):
106
+ raise RuntimeError(
107
+ "gather_rows_bf16 expects src (source_rows, hidden), "
108
+ "row_indices (rows,), dst (rows, hidden)"
109
+ )
110
+ return None
111
+
112
+
113
+ @torch.library.register_fake(add_op_namespace_prefix("scatter_rows_bf16"))
114
+ def _scatter_rows_bf16_fake(
115
+ src: torch.Tensor,
116
+ row_indices: torch.Tensor,
117
+ dst: torch.Tensor,
118
+ ) -> None:
119
+ if src.dim() != 2 or row_indices.dim() != 1 or src.shape != (row_indices.numel(), dst.shape[1]):
120
+ raise RuntimeError(
121
+ "scatter_rows_bf16 expects src (rows, hidden), "
122
+ "row_indices (rows,), dst (destination_rows, hidden)"
123
+ )
124
+ return None
125
+
126
+
127
  def fill_neginf_bf16(dst: torch.Tensor) -> torch.Tensor:
128
  ops.fill_neginf_bf16(dst)
129
  return dst
 
180
  return qk
181
 
182
 
183
+ def qk_pair_rmsnorm_rope_bf16(
184
+ q: torch.Tensor,
185
+ k: torch.Tensor,
186
+ q_weight: torch.Tensor,
187
+ k_weight: torch.Tensor,
188
+ cos: torch.Tensor,
189
+ sin: torch.Tensor,
190
+ eps: float = 1e-6,
191
+ *,
192
+ q_out: Optional[torch.Tensor] = None,
193
+ k_out: Optional[torch.Tensor] = None,
194
+ ) -> tuple[torch.Tensor, torch.Tensor]:
195
+ if q_out is None:
196
+ q_out = torch.empty_like(q)
197
+ if k_out is None:
198
+ k_out = torch.empty_like(k)
199
+ ops.qk_pair_rmsnorm_rope_bf16(
200
+ q, k, q_weight, k_weight, cos, sin, float(eps), q_out, k_out
201
+ )
202
+ return q_out, k_out
203
+
204
+
205
+ def gather_rows_bf16(
206
+ src: torch.Tensor,
207
+ row_indices: torch.Tensor,
208
+ *,
209
+ out: Optional[torch.Tensor] = None,
210
+ ) -> torch.Tensor:
211
+ """Gather rows using in-range CUDA int64 indices without host synchronization."""
212
+
213
+ if out is None:
214
+ out = torch.empty(
215
+ (row_indices.numel(), src.shape[1]), device=src.device, dtype=src.dtype
216
+ )
217
+ ops.gather_rows_bf16(src, row_indices, out)
218
+ return out
219
+
220
+
221
+ def scatter_rows_bf16(
222
+ src: torch.Tensor,
223
+ row_indices: torch.Tensor,
224
+ destination_rows: int,
225
+ *,
226
+ out: Optional[torch.Tensor] = None,
227
+ ) -> torch.Tensor:
228
+ """Scatter rows to unique, in-range CUDA int64 indices."""
229
+
230
+ if out is None:
231
+ out = torch.zeros(
232
+ (destination_rows, src.shape[1]), device=src.device, dtype=src.dtype
233
+ )
234
+ ops.scatter_rows_bf16(src, row_indices, out)
235
+ return out
236
+
237
+
238
  __all__ = [
239
  "fill_neginf_bf16",
240
  "add_bias_bf16_",
 
243
  "text_scatter_bf16",
244
  "rope_rotate_half_bf16_",
245
  "qk_rmsnorm_rope_bf16_",
246
+ "qk_pair_rmsnorm_rope_bf16",
247
+ "gather_rows_bf16",
248
+ "scatter_rows_bf16",
249
  ]
build/torch212-cxx11-cu130-x86_64-linux/_ops.py CHANGED
@@ -1,9 +1,9 @@
1
  import torch
2
- from . import _transformer_layout_primitives_cuda_c9b2fa0
3
- ops = torch.ops._transformer_layout_primitives_cuda_c9b2fa0
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
- return f"_transformer_layout_primitives_cuda_c9b2fa0::{op_name}"
 
1
  import torch
2
+ from . import _transformer_layout_primitives_cuda_0a2c98e
3
+ ops = torch.ops._transformer_layout_primitives_cuda_0a2c98e
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
+ return f"_transformer_layout_primitives_cuda_0a2c98e::{op_name}"
build/torch212-cxx11-cu130-x86_64-linux/{_transformer_layout_primitives_cuda_c9b2fa0.abi3.so → _transformer_layout_primitives_cuda_0a2c98e.abi3.so} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:6c4ebdc5e5faa851f8c4f537f5a1e75e28cebad98a650c5bf72dbf60db981844
3
- size 570424
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cb4fd9c8372d2543efd339d10b2787539fc96db7368a509e175d001882d51e20
3
+ size 809400
build/torch212-cxx11-cu130-x86_64-linux/metadata.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "name": "transformer-layout-primitives",
3
- "id": "_transformer_layout_primitives_cuda_c9b2fa0",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "python-depends": [],
 
1
  {
2
  "name": "transformer-layout-primitives",
3
+ "id": "_transformer_layout_primitives_cuda_0a2c98e",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "python-depends": [],
build/torch212-cxx11-cu132-x86_64-linux/__init__.py CHANGED
@@ -55,13 +55,75 @@ def _qk_rmsnorm_rope_bf16_fake(
55
  weight: torch.Tensor,
56
  cos: torch.Tensor,
57
  sin: torch.Tensor,
58
- eps: float,
59
  ) -> None:
60
  if qk.dim() != 3 or weight.shape != (qk.shape[2],) or cos.shape != (qk.shape[0], qk.shape[2]) or sin.shape != cos.shape:
61
  raise RuntimeError("qk_rmsnorm_rope_bf16_ expects qk (rows, heads, dim), weight (dim,), cos/sin (rows, dim)")
62
  return None
63
 
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  def fill_neginf_bf16(dst: torch.Tensor) -> torch.Tensor:
66
  ops.fill_neginf_bf16(dst)
67
  return dst
@@ -118,6 +180,61 @@ def qk_rmsnorm_rope_bf16_(
118
  return qk
119
 
120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  __all__ = [
122
  "fill_neginf_bf16",
123
  "add_bias_bf16_",
@@ -126,4 +243,7 @@ __all__ = [
126
  "text_scatter_bf16",
127
  "rope_rotate_half_bf16_",
128
  "qk_rmsnorm_rope_bf16_",
 
 
 
129
  ]
 
55
  weight: torch.Tensor,
56
  cos: torch.Tensor,
57
  sin: torch.Tensor,
58
+ eps: float = 1e-6,
59
  ) -> None:
60
  if qk.dim() != 3 or weight.shape != (qk.shape[2],) or cos.shape != (qk.shape[0], qk.shape[2]) or sin.shape != cos.shape:
61
  raise RuntimeError("qk_rmsnorm_rope_bf16_ expects qk (rows, heads, dim), weight (dim,), cos/sin (rows, dim)")
62
  return None
63
 
64
 
65
+ @torch.library.register_fake(add_op_namespace_prefix("qk_pair_rmsnorm_rope_bf16"))
66
+ def _qk_pair_rmsnorm_rope_bf16_fake(
67
+ q: torch.Tensor,
68
+ k: torch.Tensor,
69
+ q_weight: torch.Tensor,
70
+ k_weight: torch.Tensor,
71
+ cos: torch.Tensor,
72
+ sin: torch.Tensor,
73
+ eps: float,
74
+ q_out: torch.Tensor,
75
+ k_out: torch.Tensor,
76
+ ) -> None:
77
+ if (
78
+ q.dim() != 3
79
+ or k.dim() != 3
80
+ or q.shape[0] != k.shape[0]
81
+ or q.shape[2] != k.shape[2]
82
+ or q.shape[2] < 8
83
+ or q.shape[2] > 256
84
+ or q.shape[2] % 2 != 0
85
+ or q_weight.shape != (q.shape[2],)
86
+ or k_weight.shape != q_weight.shape
87
+ or cos.shape != (q.shape[0], q.shape[2])
88
+ or sin.shape != cos.shape
89
+ or q_out.shape != q.shape
90
+ or k_out.shape != k.shape
91
+ ):
92
+ raise RuntimeError(
93
+ "qk_pair_rmsnorm_rope_bf16 expects q/k (rows, heads, even_dim), "
94
+ "weights (dim,), cos/sin (rows, dim), and matching outputs"
95
+ )
96
+ return None
97
+
98
+
99
+ @torch.library.register_fake(add_op_namespace_prefix("gather_rows_bf16"))
100
+ def _gather_rows_bf16_fake(
101
+ src: torch.Tensor,
102
+ row_indices: torch.Tensor,
103
+ dst: torch.Tensor,
104
+ ) -> None:
105
+ if src.dim() != 2 or row_indices.dim() != 1 or dst.shape != (row_indices.numel(), src.shape[1]):
106
+ raise RuntimeError(
107
+ "gather_rows_bf16 expects src (source_rows, hidden), "
108
+ "row_indices (rows,), dst (rows, hidden)"
109
+ )
110
+ return None
111
+
112
+
113
+ @torch.library.register_fake(add_op_namespace_prefix("scatter_rows_bf16"))
114
+ def _scatter_rows_bf16_fake(
115
+ src: torch.Tensor,
116
+ row_indices: torch.Tensor,
117
+ dst: torch.Tensor,
118
+ ) -> None:
119
+ if src.dim() != 2 or row_indices.dim() != 1 or src.shape != (row_indices.numel(), dst.shape[1]):
120
+ raise RuntimeError(
121
+ "scatter_rows_bf16 expects src (rows, hidden), "
122
+ "row_indices (rows,), dst (destination_rows, hidden)"
123
+ )
124
+ return None
125
+
126
+
127
  def fill_neginf_bf16(dst: torch.Tensor) -> torch.Tensor:
128
  ops.fill_neginf_bf16(dst)
129
  return dst
 
180
  return qk
181
 
182
 
183
+ def qk_pair_rmsnorm_rope_bf16(
184
+ q: torch.Tensor,
185
+ k: torch.Tensor,
186
+ q_weight: torch.Tensor,
187
+ k_weight: torch.Tensor,
188
+ cos: torch.Tensor,
189
+ sin: torch.Tensor,
190
+ eps: float = 1e-6,
191
+ *,
192
+ q_out: Optional[torch.Tensor] = None,
193
+ k_out: Optional[torch.Tensor] = None,
194
+ ) -> tuple[torch.Tensor, torch.Tensor]:
195
+ if q_out is None:
196
+ q_out = torch.empty_like(q)
197
+ if k_out is None:
198
+ k_out = torch.empty_like(k)
199
+ ops.qk_pair_rmsnorm_rope_bf16(
200
+ q, k, q_weight, k_weight, cos, sin, float(eps), q_out, k_out
201
+ )
202
+ return q_out, k_out
203
+
204
+
205
+ def gather_rows_bf16(
206
+ src: torch.Tensor,
207
+ row_indices: torch.Tensor,
208
+ *,
209
+ out: Optional[torch.Tensor] = None,
210
+ ) -> torch.Tensor:
211
+ """Gather rows using in-range CUDA int64 indices without host synchronization."""
212
+
213
+ if out is None:
214
+ out = torch.empty(
215
+ (row_indices.numel(), src.shape[1]), device=src.device, dtype=src.dtype
216
+ )
217
+ ops.gather_rows_bf16(src, row_indices, out)
218
+ return out
219
+
220
+
221
+ def scatter_rows_bf16(
222
+ src: torch.Tensor,
223
+ row_indices: torch.Tensor,
224
+ destination_rows: int,
225
+ *,
226
+ out: Optional[torch.Tensor] = None,
227
+ ) -> torch.Tensor:
228
+ """Scatter rows to unique, in-range CUDA int64 indices."""
229
+
230
+ if out is None:
231
+ out = torch.zeros(
232
+ (destination_rows, src.shape[1]), device=src.device, dtype=src.dtype
233
+ )
234
+ ops.scatter_rows_bf16(src, row_indices, out)
235
+ return out
236
+
237
+
238
  __all__ = [
239
  "fill_neginf_bf16",
240
  "add_bias_bf16_",
 
243
  "text_scatter_bf16",
244
  "rope_rotate_half_bf16_",
245
  "qk_rmsnorm_rope_bf16_",
246
+ "qk_pair_rmsnorm_rope_bf16",
247
+ "gather_rows_bf16",
248
+ "scatter_rows_bf16",
249
  ]
build/torch212-cxx11-cu132-x86_64-linux/_ops.py CHANGED
@@ -1,9 +1,9 @@
1
  import torch
2
- from . import _transformer_layout_primitives_cuda_c9b2fa0
3
- ops = torch.ops._transformer_layout_primitives_cuda_c9b2fa0
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
- return f"_transformer_layout_primitives_cuda_c9b2fa0::{op_name}"
 
1
  import torch
2
+ from . import _transformer_layout_primitives_cuda_0a2c98e
3
+ ops = torch.ops._transformer_layout_primitives_cuda_0a2c98e
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
+ return f"_transformer_layout_primitives_cuda_0a2c98e::{op_name}"
build/torch212-cxx11-cu132-x86_64-linux/_transformer_layout_primitives_cuda_0a2c98e.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f626c935c5d08c16e13d8cea35b46179a86156dfae6343ded56a6cc7eec455b0
3
+ size 813496
build/torch212-cxx11-cu132-x86_64-linux/metadata.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "name": "transformer-layout-primitives",
3
- "id": "_transformer_layout_primitives_cuda_c9b2fa0",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "python-depends": [],
 
1
  {
2
  "name": "transformer-layout-primitives",
3
+ "id": "_transformer_layout_primitives_cuda_0a2c98e",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "python-depends": [],
build/torch213-cxx11-cu130-aarch64-linux/__init__.py ADDED
@@ -0,0 +1,249 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """FlashRT transformer layout primitives."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Optional
6
+
7
+ import torch
8
+
9
+ from ._ops import add_op_namespace_prefix, ops
10
+
11
+
12
+ @torch.library.register_fake(add_op_namespace_prefix("fill_neginf_bf16"))
13
+ def _fill_neginf_bf16_fake(dst: torch.Tensor) -> None:
14
+ return None
15
+
16
+
17
+ @torch.library.register_fake(add_op_namespace_prefix("add_bias_bf16_"))
18
+ def _add_bias_bf16_fake(data: torch.Tensor, bias: torch.Tensor) -> None:
19
+ if data.dim() != 2 or bias.shape != (data.shape[1],):
20
+ raise RuntimeError("add_bias_bf16_ expects data (rows, cols), bias (cols,)")
21
+ return None
22
+
23
+
24
+ @torch.library.register_fake(add_op_namespace_prefix("repeat_interleave_heads_bf16"))
25
+ def _repeat_interleave_heads_bf16_fake(src: torch.Tensor, repeat: int, dst: torch.Tensor) -> None:
26
+ if src.dim() != 3 or dst.shape != (src.shape[0], src.shape[1] * repeat, src.shape[2]):
27
+ raise RuntimeError("repeat_interleave_heads_bf16 expects src (seq, heads, dim), dst (seq, heads*repeat, dim)")
28
+ return None
29
+
30
+
31
+ @torch.library.register_fake(add_op_namespace_prefix("text_gather_bf16"))
32
+ def _text_gather_bf16_fake(src: torch.Tensor, batch: int, seq: int, dst: torch.Tensor) -> None:
33
+ if src.dim() != 2 or src.shape[0] != batch * seq or dst.shape != (2 * batch, src.shape[1]):
34
+ raise RuntimeError("text_gather_bf16 expects src (batch*seq, dim), dst (2*batch, dim)")
35
+ return None
36
+
37
+
38
+ @torch.library.register_fake(add_op_namespace_prefix("text_scatter_bf16"))
39
+ def _text_scatter_bf16_fake(dst: torch.Tensor, src: torch.Tensor, batch: int, seq: int) -> None:
40
+ if dst.dim() != 2 or dst.shape[0] != batch * seq or src.shape != (2 * batch, dst.shape[1]):
41
+ raise RuntimeError("text_scatter_bf16 expects dst (batch*seq, dim), src (2*batch, dim)")
42
+ return None
43
+
44
+
45
+ @torch.library.register_fake(add_op_namespace_prefix("rope_rotate_half_bf16_"))
46
+ def _rope_rotate_half_bf16_fake(x: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor) -> None:
47
+ if x.dim() != 3 or x.shape[2] % 2 != 0 or cos.shape != (x.shape[0], x.shape[2]) or sin.shape != cos.shape:
48
+ raise RuntimeError("rope_rotate_half_bf16_ expects x (seq, heads, even_dim), cos/sin (seq, dim)")
49
+ return None
50
+
51
+
52
+ @torch.library.register_fake(add_op_namespace_prefix("qk_rmsnorm_rope_bf16_"))
53
+ def _qk_rmsnorm_rope_bf16_fake(
54
+ qk: torch.Tensor,
55
+ weight: torch.Tensor,
56
+ cos: torch.Tensor,
57
+ sin: torch.Tensor,
58
+ eps: float = 1e-6,
59
+ ) -> None:
60
+ if qk.dim() != 3 or weight.shape != (qk.shape[2],) or cos.shape != (qk.shape[0], qk.shape[2]) or sin.shape != cos.shape:
61
+ raise RuntimeError("qk_rmsnorm_rope_bf16_ expects qk (rows, heads, dim), weight (dim,), cos/sin (rows, dim)")
62
+ return None
63
+
64
+
65
+ @torch.library.register_fake(add_op_namespace_prefix("qk_pair_rmsnorm_rope_bf16"))
66
+ def _qk_pair_rmsnorm_rope_bf16_fake(
67
+ q: torch.Tensor,
68
+ k: torch.Tensor,
69
+ q_weight: torch.Tensor,
70
+ k_weight: torch.Tensor,
71
+ cos: torch.Tensor,
72
+ sin: torch.Tensor,
73
+ eps: float,
74
+ q_out: torch.Tensor,
75
+ k_out: torch.Tensor,
76
+ ) -> None:
77
+ if (
78
+ q.dim() != 3
79
+ or k.dim() != 3
80
+ or q.shape[0] != k.shape[0]
81
+ or q.shape[2] != k.shape[2]
82
+ or q.shape[2] < 8
83
+ or q.shape[2] > 256
84
+ or q.shape[2] % 2 != 0
85
+ or q_weight.shape != (q.shape[2],)
86
+ or k_weight.shape != q_weight.shape
87
+ or cos.shape != (q.shape[0], q.shape[2])
88
+ or sin.shape != cos.shape
89
+ or q_out.shape != q.shape
90
+ or k_out.shape != k.shape
91
+ ):
92
+ raise RuntimeError(
93
+ "qk_pair_rmsnorm_rope_bf16 expects q/k (rows, heads, even_dim), "
94
+ "weights (dim,), cos/sin (rows, dim), and matching outputs"
95
+ )
96
+ return None
97
+
98
+
99
+ @torch.library.register_fake(add_op_namespace_prefix("gather_rows_bf16"))
100
+ def _gather_rows_bf16_fake(
101
+ src: torch.Tensor,
102
+ row_indices: torch.Tensor,
103
+ dst: torch.Tensor,
104
+ ) -> None:
105
+ if src.dim() != 2 or row_indices.dim() != 1 or dst.shape != (row_indices.numel(), src.shape[1]):
106
+ raise RuntimeError(
107
+ "gather_rows_bf16 expects src (source_rows, hidden), "
108
+ "row_indices (rows,), dst (rows, hidden)"
109
+ )
110
+ return None
111
+
112
+
113
+ @torch.library.register_fake(add_op_namespace_prefix("scatter_rows_bf16"))
114
+ def _scatter_rows_bf16_fake(
115
+ src: torch.Tensor,
116
+ row_indices: torch.Tensor,
117
+ dst: torch.Tensor,
118
+ ) -> None:
119
+ if src.dim() != 2 or row_indices.dim() != 1 or src.shape != (row_indices.numel(), dst.shape[1]):
120
+ raise RuntimeError(
121
+ "scatter_rows_bf16 expects src (rows, hidden), "
122
+ "row_indices (rows,), dst (destination_rows, hidden)"
123
+ )
124
+ return None
125
+
126
+
127
+ def fill_neginf_bf16(dst: torch.Tensor) -> torch.Tensor:
128
+ ops.fill_neginf_bf16(dst)
129
+ return dst
130
+
131
+
132
+ def add_bias_bf16_(data: torch.Tensor, bias: torch.Tensor) -> torch.Tensor:
133
+ ops.add_bias_bf16_(data, bias)
134
+ return data
135
+
136
+
137
+ def repeat_interleave_heads_bf16(
138
+ src: torch.Tensor,
139
+ repeat: int,
140
+ *,
141
+ out: Optional[torch.Tensor] = None,
142
+ ) -> torch.Tensor:
143
+ if out is None:
144
+ out = torch.empty((src.shape[0], src.shape[1] * repeat, src.shape[2]), device=src.device, dtype=src.dtype)
145
+ ops.repeat_interleave_heads_bf16(src, int(repeat), out)
146
+ return out
147
+
148
+
149
+ def text_gather_bf16(
150
+ src: torch.Tensor,
151
+ batch: int,
152
+ seq: int,
153
+ *,
154
+ out: Optional[torch.Tensor] = None,
155
+ ) -> torch.Tensor:
156
+ if out is None:
157
+ out = torch.empty((2 * batch, src.shape[1]), device=src.device, dtype=src.dtype)
158
+ ops.text_gather_bf16(src, int(batch), int(seq), out)
159
+ return out
160
+
161
+
162
+ def text_scatter_bf16(dst: torch.Tensor, src: torch.Tensor, batch: int, seq: int) -> torch.Tensor:
163
+ ops.text_scatter_bf16(dst, src, int(batch), int(seq))
164
+ return dst
165
+
166
+
167
+ def rope_rotate_half_bf16_(x: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor) -> torch.Tensor:
168
+ ops.rope_rotate_half_bf16_(x, cos, sin)
169
+ return x
170
+
171
+
172
+ def qk_rmsnorm_rope_bf16_(
173
+ qk: torch.Tensor,
174
+ weight: torch.Tensor,
175
+ cos: torch.Tensor,
176
+ sin: torch.Tensor,
177
+ eps: float = 1e-6,
178
+ ) -> torch.Tensor:
179
+ ops.qk_rmsnorm_rope_bf16_(qk, weight, cos, sin, float(eps))
180
+ return qk
181
+
182
+
183
+ def qk_pair_rmsnorm_rope_bf16(
184
+ q: torch.Tensor,
185
+ k: torch.Tensor,
186
+ q_weight: torch.Tensor,
187
+ k_weight: torch.Tensor,
188
+ cos: torch.Tensor,
189
+ sin: torch.Tensor,
190
+ eps: float = 1e-6,
191
+ *,
192
+ q_out: Optional[torch.Tensor] = None,
193
+ k_out: Optional[torch.Tensor] = None,
194
+ ) -> tuple[torch.Tensor, torch.Tensor]:
195
+ if q_out is None:
196
+ q_out = torch.empty_like(q)
197
+ if k_out is None:
198
+ k_out = torch.empty_like(k)
199
+ ops.qk_pair_rmsnorm_rope_bf16(
200
+ q, k, q_weight, k_weight, cos, sin, float(eps), q_out, k_out
201
+ )
202
+ return q_out, k_out
203
+
204
+
205
+ def gather_rows_bf16(
206
+ src: torch.Tensor,
207
+ row_indices: torch.Tensor,
208
+ *,
209
+ out: Optional[torch.Tensor] = None,
210
+ ) -> torch.Tensor:
211
+ """Gather rows using in-range CUDA int64 indices without host synchronization."""
212
+
213
+ if out is None:
214
+ out = torch.empty(
215
+ (row_indices.numel(), src.shape[1]), device=src.device, dtype=src.dtype
216
+ )
217
+ ops.gather_rows_bf16(src, row_indices, out)
218
+ return out
219
+
220
+
221
+ def scatter_rows_bf16(
222
+ src: torch.Tensor,
223
+ row_indices: torch.Tensor,
224
+ destination_rows: int,
225
+ *,
226
+ out: Optional[torch.Tensor] = None,
227
+ ) -> torch.Tensor:
228
+ """Scatter rows to unique, in-range CUDA int64 indices."""
229
+
230
+ if out is None:
231
+ out = torch.zeros(
232
+ (destination_rows, src.shape[1]), device=src.device, dtype=src.dtype
233
+ )
234
+ ops.scatter_rows_bf16(src, row_indices, out)
235
+ return out
236
+
237
+
238
+ __all__ = [
239
+ "fill_neginf_bf16",
240
+ "add_bias_bf16_",
241
+ "repeat_interleave_heads_bf16",
242
+ "text_gather_bf16",
243
+ "text_scatter_bf16",
244
+ "rope_rotate_half_bf16_",
245
+ "qk_rmsnorm_rope_bf16_",
246
+ "qk_pair_rmsnorm_rope_bf16",
247
+ "gather_rows_bf16",
248
+ "scatter_rows_bf16",
249
+ ]
build/torch213-cxx11-cu130-aarch64-linux/_ops.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import transformer_layout_primitives_source_test
3
+ ops = torch.ops.transformer_layout_primitives_source_test
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ return f"transformer_layout_primitives_source_test::{op_name}"
build/torch213-cxx11-cu130-aarch64-linux/metadata.json ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "transformer-layout-primitives",
3
+ "id": "transformer_layout_primitives_source_test",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "11.0"
11
+ ]
12
+ },
13
+ "digest": {
14
+ "algorithm": "sha256",
15
+ "files": {
16
+ "__init__.py": "Le2NlMbv2iPKF5/hg87FKZwzjsVjK1dras7vbnPWYx8=",
17
+ "transformer_layout_primitives_source_test.abi3.so": "rTS3hp8n1EQCUhT21GetFkjokJSYi7tWSDu8POFV274=",
18
+ "_ops.py": "YSImh8cFlOo35GBoY1uX2AQlaapTWG5MigCcM3MXx6U=",
19
+ "transformer_layout_primitives/__init__.py": "v6p5XMfQzddhi1fLSAw4HX9CyS0rQsidvu9VsT01xi4="
20
+ }
21
+ },
22
+ "provenance": {
23
+ "kernel": {
24
+ "sha": "456d297",
25
+ "dirty": false
26
+ },
27
+ "validation": {
28
+ "torch": "2.13.0+cu130",
29
+ "cuda": "13.0"
30
+ }
31
+ }
32
+ }
build/torch213-cxx11-cu130-aarch64-linux/transformer_layout_primitives/__init__.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ctypes
2
+ import importlib.util
3
+ import sys
4
+ from pathlib import Path
5
+
6
+ def _import_from_path(file_path: Path):
7
+ path_hash = '{:x}'.format(ctypes.c_size_t(hash(file_path.absolute())).value)
8
+ spec = importlib.util.spec_from_file_location(path_hash, file_path)
9
+ module = importlib.util.module_from_spec(spec)
10
+ sys.modules[path_hash] = module
11
+ spec.loader.exec_module(module)
12
+ return module
13
+
14
+ globals().update(vars(_import_from_path(Path(__file__).parent.parent / '__init__.py')))
build/torch213-cxx11-cu130-aarch64-linux/transformer_layout_primitives_source_test.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ad34b7869f27d444025214f6d467ad1648e89094988bbb56483bbc3ce155dbbe
3
+ size 330960