liangsu9988 commited on
Commit
072b453
·
verified ·
1 Parent(s): 94da621

Uploaded using `kernel-builder`.

Browse files
Files changed (21) hide show
  1. benchmarks/benchmark.py +122 -0
  2. build/torch211-cxx11-cu128-x86_64-linux/__init__.py +129 -0
  3. build/torch211-cxx11-cu128-x86_64-linux/_ops.py +9 -0
  4. build/torch211-cxx11-cu128-x86_64-linux/_transformer_layout_primitives_cuda_c9b2fa0.abi3.so +3 -0
  5. build/torch211-cxx11-cu128-x86_64-linux/metadata.json +23 -0
  6. build/torch211-cxx11-cu128-x86_64-linux/transformer_layout_primitives/__init__.py +26 -0
  7. build/torch211-cxx11-cu130-x86_64-linux/__init__.py +129 -0
  8. build/torch211-cxx11-cu130-x86_64-linux/_ops.py +9 -0
  9. build/torch211-cxx11-cu130-x86_64-linux/_transformer_layout_primitives_cuda_c9b2fa0.abi3.so +3 -0
  10. build/torch211-cxx11-cu130-x86_64-linux/metadata.json +22 -0
  11. build/torch211-cxx11-cu130-x86_64-linux/transformer_layout_primitives/__init__.py +26 -0
  12. build/torch212-cxx11-cu130-x86_64-linux/__init__.py +129 -0
  13. build/torch212-cxx11-cu130-x86_64-linux/_ops.py +9 -0
  14. build/torch212-cxx11-cu130-x86_64-linux/_transformer_layout_primitives_cuda_c9b2fa0.abi3.so +3 -0
  15. build/torch212-cxx11-cu130-x86_64-linux/metadata.json +22 -0
  16. build/torch212-cxx11-cu130-x86_64-linux/transformer_layout_primitives/__init__.py +26 -0
  17. build/torch212-cxx11-cu132-x86_64-linux/__init__.py +129 -0
  18. build/torch212-cxx11-cu132-x86_64-linux/_ops.py +9 -0
  19. build/torch212-cxx11-cu132-x86_64-linux/_transformer_layout_primitives_cuda_c9b2fa0.abi3.so +3 -0
  20. build/torch212-cxx11-cu132-x86_64-linux/metadata.json +22 -0
  21. build/torch212-cxx11-cu132-x86_64-linux/transformer_layout_primitives/__init__.py +26 -0
benchmarks/benchmark.py ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Benchmark transformer layout primitives."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import importlib
8
+ import sys
9
+ from pathlib import Path
10
+
11
+ 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):
19
+ if backend == "source":
20
+ return load_source_ops()
21
+ if artifact:
22
+ sys.path.insert(0, artifact)
23
+ try:
24
+ return importlib.import_module("transformer_layout_primitives")
25
+ finally:
26
+ if artifact:
27
+ sys.path.remove(artifact)
28
+
29
+
30
+ def time_us(fn, warmup: int, iters: int) -> float:
31
+ for _ in range(warmup):
32
+ fn()
33
+ torch.cuda.synchronize()
34
+ start = torch.cuda.Event(enable_timing=True)
35
+ end = torch.cuda.Event(enable_timing=True)
36
+ start.record()
37
+ for _ in range(iters):
38
+ fn()
39
+ end.record()
40
+ torch.cuda.synchronize()
41
+ return start.elapsed_time(end) * 1000.0 / iters
42
+
43
+
44
+ def main() -> int:
45
+ parser = argparse.ArgumentParser()
46
+ parser.add_argument("--backend", choices=["source", "installed"], default="source")
47
+ parser.add_argument("--artifact", default=None)
48
+ parser.add_argument("--mode", choices=["headline", "full"], default="headline")
49
+ parser.add_argument("--warmup", type=int, default=20)
50
+ parser.add_argument("--iters", type=int, default=100)
51
+ args = parser.parse_args()
52
+ ops = load_ops(args.backend, args.artifact)
53
+
54
+ print("workload,shape,op,flashrt_us,torch_eager_us,speedup")
55
+
56
+ repeat_shapes = [("gqa_prefill", 2520, 8, 128, 4), ("decode_gqa", 1, 8, 128, 4)]
57
+ if args.mode == "full":
58
+ repeat_shapes += [("short_prefill", 128, 8, 128, 4), ("vl_prefill", 4096, 8, 128, 4)]
59
+ for name, seq, heads, dim, repeat in repeat_shapes:
60
+ src = torch.randn((seq, heads, dim), device="cuda", dtype=torch.bfloat16)
61
+ out = torch.empty((seq, heads * repeat, dim), device="cuda", dtype=torch.bfloat16)
62
+
63
+ def flash():
64
+ ops.repeat_interleave_heads_bf16(src, repeat, out=out)
65
+
66
+ def eager():
67
+ src.repeat_interleave(repeat, dim=1)
68
+
69
+ fu = time_us(flash, args.warmup, args.iters)
70
+ eu = time_us(eager, max(5, args.warmup // 2), max(20, args.iters // 2))
71
+ print(f"{name},{seq}x{heads}x{dim}x{repeat},repeat_interleave_heads_bf16,{fu:.3f},{eu:.3f},{eu/fu:.2f}x")
72
+
73
+ rope_shapes = [("qwen_prefill", 4096, 32, 128), ("video_prefill", 2520, 24, 128)]
74
+ if args.mode == "full":
75
+ rope_shapes += [("decode", 1, 32, 128), ("short_prefill", 128, 32, 128)]
76
+ for name, seq, heads, dim in rope_shapes:
77
+ x = torch.randn((seq, heads, dim), device="cuda", dtype=torch.bfloat16)
78
+ weight = torch.randn((dim,), device="cuda", dtype=torch.bfloat16)
79
+ cos = torch.randn((seq, dim), device="cuda", dtype=torch.bfloat16)
80
+ sin = torch.randn((seq, dim), device="cuda", dtype=torch.bfloat16)
81
+ out = x.clone()
82
+
83
+ def flash():
84
+ out.copy_(x)
85
+ ops.qk_rmsnorm_rope_bf16_(out, weight, cos, sin)
86
+
87
+ def eager():
88
+ qk_rmsnorm_rope_ref(x, weight, cos, sin)
89
+
90
+ fu = time_us(flash, args.warmup, args.iters)
91
+ eu = time_us(eager, max(5, args.warmup // 2), max(20, args.iters // 2))
92
+ print(f"{name},{seq}x{heads}x{dim},qk_rmsnorm_rope_bf16_,{fu:.3f},{eu:.3f},{eu/fu:.2f}x")
93
+
94
+ def flash_rope():
95
+ out.copy_(x)
96
+ ops.rope_rotate_half_bf16_(out, cos, sin)
97
+
98
+ def eager_rope():
99
+ rotate_half_ref(x, cos, sin)
100
+
101
+ fu = time_us(flash_rope, args.warmup, args.iters)
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)
108
+
109
+ def flash_gather():
110
+ ops.text_gather_bf16(x, batch, seq, out=gathered)
111
+
112
+ def eager_gather():
113
+ torch.stack([x[b * seq + offset] for b in range(batch) for offset in (0, seq - 1)], dim=0)
114
+
115
+ fu = time_us(flash_gather, args.warmup, args.iters)
116
+ eu = time_us(eager_gather, max(5, args.warmup // 2), max(20, args.iters // 2))
117
+ print(f"text_tokens,{batch}x{seq}x{dim},text_gather_bf16,{fu:.3f},{eu:.3f},{eu/fu:.2f}x")
118
+ return 0
119
+
120
+
121
+ if __name__ == "__main__":
122
+ raise SystemExit(main())
build/torch211-cxx11-cu128-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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,
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
68
+
69
+
70
+ def add_bias_bf16_(data: torch.Tensor, bias: torch.Tensor) -> torch.Tensor:
71
+ ops.add_bias_bf16_(data, bias)
72
+ return data
73
+
74
+
75
+ def repeat_interleave_heads_bf16(
76
+ src: torch.Tensor,
77
+ repeat: int,
78
+ *,
79
+ out: Optional[torch.Tensor] = None,
80
+ ) -> torch.Tensor:
81
+ if out is None:
82
+ out = torch.empty((src.shape[0], src.shape[1] * repeat, src.shape[2]), device=src.device, dtype=src.dtype)
83
+ ops.repeat_interleave_heads_bf16(src, int(repeat), out)
84
+ return out
85
+
86
+
87
+ def text_gather_bf16(
88
+ src: torch.Tensor,
89
+ batch: int,
90
+ seq: int,
91
+ *,
92
+ out: Optional[torch.Tensor] = None,
93
+ ) -> torch.Tensor:
94
+ if out is None:
95
+ out = torch.empty((2 * batch, src.shape[1]), device=src.device, dtype=src.dtype)
96
+ ops.text_gather_bf16(src, int(batch), int(seq), out)
97
+ return out
98
+
99
+
100
+ def text_scatter_bf16(dst: torch.Tensor, src: torch.Tensor, batch: int, seq: int) -> torch.Tensor:
101
+ ops.text_scatter_bf16(dst, src, int(batch), int(seq))
102
+ return dst
103
+
104
+
105
+ def rope_rotate_half_bf16_(x: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor) -> torch.Tensor:
106
+ ops.rope_rotate_half_bf16_(x, cos, sin)
107
+ return x
108
+
109
+
110
+ def qk_rmsnorm_rope_bf16_(
111
+ qk: torch.Tensor,
112
+ weight: torch.Tensor,
113
+ cos: torch.Tensor,
114
+ sin: torch.Tensor,
115
+ eps: float = 1e-6,
116
+ ) -> torch.Tensor:
117
+ ops.qk_rmsnorm_rope_bf16_(qk, weight, cos, sin, float(eps))
118
+ return qk
119
+
120
+
121
+ __all__ = [
122
+ "fill_neginf_bf16",
123
+ "add_bias_bf16_",
124
+ "repeat_interleave_heads_bf16",
125
+ "text_gather_bf16",
126
+ "text_scatter_bf16",
127
+ "rope_rotate_half_bf16_",
128
+ "qk_rmsnorm_rope_bf16_",
129
+ ]
build/torch211-cxx11-cu128-x86_64-linux/_ops.py ADDED
@@ -0,0 +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}"
build/torch211-cxx11-cu128-x86_64-linux/_transformer_layout_primitives_cuda_c9b2fa0.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8391a04a4384cc92d83c6df4c86ecdd205567c00105c13a01ca54c2b88fdd371
3
+ size 572816
build/torch211-cxx11-cu128-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "transformer-layout-primitives",
3
+ "id": "_transformer_layout_primitives_cuda_c9b2fa0",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "10.0",
11
+ "10.1",
12
+ "12.0+PTX",
13
+ "7.0",
14
+ "7.2",
15
+ "7.5",
16
+ "8.0",
17
+ "8.6",
18
+ "8.7",
19
+ "8.9",
20
+ "9.0"
21
+ ]
22
+ }
23
+ }
build/torch211-cxx11-cu128-x86_64-linux/transformer_layout_primitives/__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/torch211-cxx11-cu130-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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,
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
68
+
69
+
70
+ def add_bias_bf16_(data: torch.Tensor, bias: torch.Tensor) -> torch.Tensor:
71
+ ops.add_bias_bf16_(data, bias)
72
+ return data
73
+
74
+
75
+ def repeat_interleave_heads_bf16(
76
+ src: torch.Tensor,
77
+ repeat: int,
78
+ *,
79
+ out: Optional[torch.Tensor] = None,
80
+ ) -> torch.Tensor:
81
+ if out is None:
82
+ out = torch.empty((src.shape[0], src.shape[1] * repeat, src.shape[2]), device=src.device, dtype=src.dtype)
83
+ ops.repeat_interleave_heads_bf16(src, int(repeat), out)
84
+ return out
85
+
86
+
87
+ def text_gather_bf16(
88
+ src: torch.Tensor,
89
+ batch: int,
90
+ seq: int,
91
+ *,
92
+ out: Optional[torch.Tensor] = None,
93
+ ) -> torch.Tensor:
94
+ if out is None:
95
+ out = torch.empty((2 * batch, src.shape[1]), device=src.device, dtype=src.dtype)
96
+ ops.text_gather_bf16(src, int(batch), int(seq), out)
97
+ return out
98
+
99
+
100
+ def text_scatter_bf16(dst: torch.Tensor, src: torch.Tensor, batch: int, seq: int) -> torch.Tensor:
101
+ ops.text_scatter_bf16(dst, src, int(batch), int(seq))
102
+ return dst
103
+
104
+
105
+ def rope_rotate_half_bf16_(x: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor) -> torch.Tensor:
106
+ ops.rope_rotate_half_bf16_(x, cos, sin)
107
+ return x
108
+
109
+
110
+ def qk_rmsnorm_rope_bf16_(
111
+ qk: torch.Tensor,
112
+ weight: torch.Tensor,
113
+ cos: torch.Tensor,
114
+ sin: torch.Tensor,
115
+ eps: float = 1e-6,
116
+ ) -> torch.Tensor:
117
+ ops.qk_rmsnorm_rope_bf16_(qk, weight, cos, sin, float(eps))
118
+ return qk
119
+
120
+
121
+ __all__ = [
122
+ "fill_neginf_bf16",
123
+ "add_bias_bf16_",
124
+ "repeat_interleave_heads_bf16",
125
+ "text_gather_bf16",
126
+ "text_scatter_bf16",
127
+ "rope_rotate_half_bf16_",
128
+ "qk_rmsnorm_rope_bf16_",
129
+ ]
build/torch211-cxx11-cu130-x86_64-linux/_ops.py ADDED
@@ -0,0 +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}"
build/torch211-cxx11-cu130-x86_64-linux/_transformer_layout_primitives_cuda_c9b2fa0.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:99943084af51325b92b740243b59d224141161ee451749776e1c89ce7cceded2
3
+ size 564160
build/torch211-cxx11-cu130-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "transformer-layout-primitives",
3
+ "id": "_transformer_layout_primitives_cuda_c9b2fa0",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "10.0",
11
+ "11.0",
12
+ "12.0",
13
+ "12.1+PTX",
14
+ "7.5",
15
+ "8.0",
16
+ "8.6",
17
+ "8.7",
18
+ "8.9",
19
+ "9.0"
20
+ ]
21
+ }
22
+ }
build/torch211-cxx11-cu130-x86_64-linux/transformer_layout_primitives/__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/torch212-cxx11-cu130-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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,
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
68
+
69
+
70
+ def add_bias_bf16_(data: torch.Tensor, bias: torch.Tensor) -> torch.Tensor:
71
+ ops.add_bias_bf16_(data, bias)
72
+ return data
73
+
74
+
75
+ def repeat_interleave_heads_bf16(
76
+ src: torch.Tensor,
77
+ repeat: int,
78
+ *,
79
+ out: Optional[torch.Tensor] = None,
80
+ ) -> torch.Tensor:
81
+ if out is None:
82
+ out = torch.empty((src.shape[0], src.shape[1] * repeat, src.shape[2]), device=src.device, dtype=src.dtype)
83
+ ops.repeat_interleave_heads_bf16(src, int(repeat), out)
84
+ return out
85
+
86
+
87
+ def text_gather_bf16(
88
+ src: torch.Tensor,
89
+ batch: int,
90
+ seq: int,
91
+ *,
92
+ out: Optional[torch.Tensor] = None,
93
+ ) -> torch.Tensor:
94
+ if out is None:
95
+ out = torch.empty((2 * batch, src.shape[1]), device=src.device, dtype=src.dtype)
96
+ ops.text_gather_bf16(src, int(batch), int(seq), out)
97
+ return out
98
+
99
+
100
+ def text_scatter_bf16(dst: torch.Tensor, src: torch.Tensor, batch: int, seq: int) -> torch.Tensor:
101
+ ops.text_scatter_bf16(dst, src, int(batch), int(seq))
102
+ return dst
103
+
104
+
105
+ def rope_rotate_half_bf16_(x: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor) -> torch.Tensor:
106
+ ops.rope_rotate_half_bf16_(x, cos, sin)
107
+ return x
108
+
109
+
110
+ def qk_rmsnorm_rope_bf16_(
111
+ qk: torch.Tensor,
112
+ weight: torch.Tensor,
113
+ cos: torch.Tensor,
114
+ sin: torch.Tensor,
115
+ eps: float = 1e-6,
116
+ ) -> torch.Tensor:
117
+ ops.qk_rmsnorm_rope_bf16_(qk, weight, cos, sin, float(eps))
118
+ return qk
119
+
120
+
121
+ __all__ = [
122
+ "fill_neginf_bf16",
123
+ "add_bias_bf16_",
124
+ "repeat_interleave_heads_bf16",
125
+ "text_gather_bf16",
126
+ "text_scatter_bf16",
127
+ "rope_rotate_half_bf16_",
128
+ "qk_rmsnorm_rope_bf16_",
129
+ ]
build/torch212-cxx11-cu130-x86_64-linux/_ops.py ADDED
@@ -0,0 +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}"
build/torch212-cxx11-cu130-x86_64-linux/_transformer_layout_primitives_cuda_c9b2fa0.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6c4ebdc5e5faa851f8c4f537f5a1e75e28cebad98a650c5bf72dbf60db981844
3
+ size 570424
build/torch212-cxx11-cu130-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "transformer-layout-primitives",
3
+ "id": "_transformer_layout_primitives_cuda_c9b2fa0",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "10.0",
11
+ "11.0",
12
+ "12.0",
13
+ "12.1+PTX",
14
+ "7.5",
15
+ "8.0",
16
+ "8.6",
17
+ "8.7",
18
+ "8.9",
19
+ "9.0"
20
+ ]
21
+ }
22
+ }
build/torch212-cxx11-cu130-x86_64-linux/transformer_layout_primitives/__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/torch212-cxx11-cu132-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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,
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
68
+
69
+
70
+ def add_bias_bf16_(data: torch.Tensor, bias: torch.Tensor) -> torch.Tensor:
71
+ ops.add_bias_bf16_(data, bias)
72
+ return data
73
+
74
+
75
+ def repeat_interleave_heads_bf16(
76
+ src: torch.Tensor,
77
+ repeat: int,
78
+ *,
79
+ out: Optional[torch.Tensor] = None,
80
+ ) -> torch.Tensor:
81
+ if out is None:
82
+ out = torch.empty((src.shape[0], src.shape[1] * repeat, src.shape[2]), device=src.device, dtype=src.dtype)
83
+ ops.repeat_interleave_heads_bf16(src, int(repeat), out)
84
+ return out
85
+
86
+
87
+ def text_gather_bf16(
88
+ src: torch.Tensor,
89
+ batch: int,
90
+ seq: int,
91
+ *,
92
+ out: Optional[torch.Tensor] = None,
93
+ ) -> torch.Tensor:
94
+ if out is None:
95
+ out = torch.empty((2 * batch, src.shape[1]), device=src.device, dtype=src.dtype)
96
+ ops.text_gather_bf16(src, int(batch), int(seq), out)
97
+ return out
98
+
99
+
100
+ def text_scatter_bf16(dst: torch.Tensor, src: torch.Tensor, batch: int, seq: int) -> torch.Tensor:
101
+ ops.text_scatter_bf16(dst, src, int(batch), int(seq))
102
+ return dst
103
+
104
+
105
+ def rope_rotate_half_bf16_(x: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor) -> torch.Tensor:
106
+ ops.rope_rotate_half_bf16_(x, cos, sin)
107
+ return x
108
+
109
+
110
+ def qk_rmsnorm_rope_bf16_(
111
+ qk: torch.Tensor,
112
+ weight: torch.Tensor,
113
+ cos: torch.Tensor,
114
+ sin: torch.Tensor,
115
+ eps: float = 1e-6,
116
+ ) -> torch.Tensor:
117
+ ops.qk_rmsnorm_rope_bf16_(qk, weight, cos, sin, float(eps))
118
+ return qk
119
+
120
+
121
+ __all__ = [
122
+ "fill_neginf_bf16",
123
+ "add_bias_bf16_",
124
+ "repeat_interleave_heads_bf16",
125
+ "text_gather_bf16",
126
+ "text_scatter_bf16",
127
+ "rope_rotate_half_bf16_",
128
+ "qk_rmsnorm_rope_bf16_",
129
+ ]
build/torch212-cxx11-cu132-x86_64-linux/_ops.py ADDED
@@ -0,0 +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}"
build/torch212-cxx11-cu132-x86_64-linux/_transformer_layout_primitives_cuda_c9b2fa0.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1947aebc33c49a48c82a0da681b56e16c0517460121fa5ce7cbc1d39f1e9832b
3
+ size 574520
build/torch212-cxx11-cu132-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "transformer-layout-primitives",
3
+ "id": "_transformer_layout_primitives_cuda_c9b2fa0",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "10.0",
11
+ "11.0",
12
+ "12.0",
13
+ "12.1+PTX",
14
+ "7.5",
15
+ "8.0",
16
+ "8.6",
17
+ "8.7",
18
+ "8.9",
19
+ "9.0"
20
+ ]
21
+ }
22
+ }
build/torch212-cxx11-cu132-x86_64-linux/transformer_layout_primitives/__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")))