liangsu9988 commited on
Commit
b34d99d
·
verified ·
1 Parent(s): ed6548a

Uploaded using `kernel-builder`.

Browse files
Files changed (48) hide show
  1. benchmarks/benchmark.py +25 -7
  2. benchmarks/benchmark_channel_scale.py +21 -4
  3. build/torch211-cxx11-cu126-x86_64-linux/__init__.py +7 -1
  4. build/torch211-cxx11-cu126-x86_64-linux/{_flashrt_gemm_epilogues_cuda_5de4768.abi3.so → _flashrt_gemm_epilogues_cuda_4a17df5.abi3.so} +2 -2
  5. build/torch211-cxx11-cu126-x86_64-linux/_ops.py +3 -3
  6. build/torch211-cxx11-cu126-x86_64-linux/metadata.json +1 -1
  7. build/torch211-cxx11-cu128-x86_64-linux/__init__.py +7 -1
  8. build/torch211-cxx11-cu128-x86_64-linux/{_flashrt_gemm_epilogues_cuda_5de4768.abi3.so → _flashrt_gemm_epilogues_cuda_4a17df5.abi3.so} +2 -2
  9. build/torch211-cxx11-cu128-x86_64-linux/_ops.py +3 -3
  10. build/torch211-cxx11-cu128-x86_64-linux/metadata.json +1 -1
  11. build/torch211-cxx11-cu130-x86_64-linux/__init__.py +7 -1
  12. build/torch211-cxx11-cu130-x86_64-linux/{_flashrt_gemm_epilogues_cuda_5de4768.abi3.so → _flashrt_gemm_epilogues_cuda_4a17df5.abi3.so} +2 -2
  13. build/torch211-cxx11-cu130-x86_64-linux/_ops.py +3 -3
  14. build/torch211-cxx11-cu130-x86_64-linux/metadata.json +1 -1
  15. build/torch211-cxx11-rocm71-x86_64-linux/__init__.py +277 -0
  16. build/{torch212-cxx11-cu126-x86_64-linux/_flashrt_gemm_epilogues_cuda_5de4768.abi3.so → torch211-cxx11-rocm71-x86_64-linux/_flashrt_gemm_epilogues_rocm_4a17df5.abi3.so} +2 -2
  17. build/torch211-cxx11-rocm71-x86_64-linux/_ops.py +9 -0
  18. build/torch211-cxx11-rocm71-x86_64-linux/flashrt_gemm_epilogues/__init__.py +26 -0
  19. build/torch211-cxx11-rocm71-x86_64-linux/metadata.json +13 -0
  20. build/torch211-cxx11-rocm72-x86_64-linux/__init__.py +277 -0
  21. build/torch211-cxx11-rocm72-x86_64-linux/_flashrt_gemm_epilogues_rocm_4a17df5.abi3.so +3 -0
  22. build/torch211-cxx11-rocm72-x86_64-linux/_ops.py +9 -0
  23. build/torch211-cxx11-rocm72-x86_64-linux/flashrt_gemm_epilogues/__init__.py +26 -0
  24. build/torch211-cxx11-rocm72-x86_64-linux/metadata.json +13 -0
  25. build/torch212-cxx11-cu126-x86_64-linux/__init__.py +7 -1
  26. build/torch212-cxx11-cu126-x86_64-linux/_flashrt_gemm_epilogues_cuda_4a17df5.abi3.so +3 -0
  27. build/torch212-cxx11-cu126-x86_64-linux/_ops.py +3 -3
  28. build/torch212-cxx11-cu126-x86_64-linux/metadata.json +1 -1
  29. build/torch212-cxx11-cu130-x86_64-linux/__init__.py +7 -1
  30. build/torch212-cxx11-cu130-x86_64-linux/_flashrt_gemm_epilogues_cuda_4a17df5.abi3.so +3 -0
  31. build/torch212-cxx11-cu130-x86_64-linux/_flashrt_gemm_epilogues_cuda_5de4768.abi3.so +0 -3
  32. build/torch212-cxx11-cu130-x86_64-linux/_ops.py +3 -3
  33. build/torch212-cxx11-cu130-x86_64-linux/metadata.json +1 -1
  34. build/torch212-cxx11-cu132-x86_64-linux/__init__.py +7 -1
  35. build/torch212-cxx11-cu132-x86_64-linux/_flashrt_gemm_epilogues_cuda_4a17df5.abi3.so +3 -0
  36. build/torch212-cxx11-cu132-x86_64-linux/_flashrt_gemm_epilogues_cuda_5de4768.abi3.so +0 -3
  37. build/torch212-cxx11-cu132-x86_64-linux/_ops.py +3 -3
  38. build/torch212-cxx11-cu132-x86_64-linux/metadata.json +1 -1
  39. build/torch212-cxx11-rocm71-x86_64-linux/__init__.py +277 -0
  40. build/torch212-cxx11-rocm71-x86_64-linux/_flashrt_gemm_epilogues_rocm_4a17df5.abi3.so +3 -0
  41. build/torch212-cxx11-rocm71-x86_64-linux/_ops.py +9 -0
  42. build/torch212-cxx11-rocm71-x86_64-linux/flashrt_gemm_epilogues/__init__.py +26 -0
  43. build/torch212-cxx11-rocm71-x86_64-linux/metadata.json +13 -0
  44. build/torch212-cxx11-rocm72-x86_64-linux/__init__.py +277 -0
  45. build/torch212-cxx11-rocm72-x86_64-linux/_flashrt_gemm_epilogues_rocm_4a17df5.abi3.so +3 -0
  46. build/torch212-cxx11-rocm72-x86_64-linux/_ops.py +9 -0
  47. build/torch212-cxx11-rocm72-x86_64-linux/flashrt_gemm_epilogues/__init__.py +26 -0
  48. build/torch212-cxx11-rocm72-x86_64-linux/metadata.json +13 -0
benchmarks/benchmark.py CHANGED
@@ -6,8 +6,24 @@ from kernels.benchmark import Benchmark
6
  _original_allclose = torch.allclose
7
 
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  def _flashrt_allclose(input, other, rtol=1e-05, atol=1e-08, equal_nan=False):
10
- if input.dtype == torch.float8_e4m3fn or other.dtype == torch.float8_e4m3fn:
11
  return _original_allclose(
12
  input.float(),
13
  other.float(),
@@ -47,13 +63,14 @@ class BiasGeluFp8QuantizeBenchmark(Benchmark):
47
  self.input = torch.randn((m, n), device=self.device, dtype=torch.bfloat16)
48
  self.bias = torch.randn((n,), device=self.device, dtype=torch.bfloat16)
49
  self.scale = torch.tensor([0.25], device=self.device, dtype=torch.float32)
50
- self.out = torch.empty_like(self.input, dtype=torch.float8_e4m3fn)
51
 
52
  def _reference(self) -> torch.Tensor:
53
  y = self.input.float() + self.bias.float()
54
  y = torch.nn.functional.gelu(y, approximate="tanh")
55
- y = torch.clamp(y / self.scale.float(), -448.0, 448.0)
56
- return y.to(torch.float8_e4m3fn)
 
57
 
58
  def setup_decode_m1(self) -> None:
59
  self._setup_shape(1, 4096)
@@ -158,12 +175,13 @@ class GeluFp8QuantizeBenchmark(Benchmark):
158
  def _setup_shape(self, m: int, n: int) -> None:
159
  self.input = torch.randn((m, n), device=self.device, dtype=torch.bfloat16)
160
  self.scale = torch.tensor([0.25], device=self.device, dtype=torch.float32)
161
- self.out = torch.empty_like(self.input, dtype=torch.float8_e4m3fn)
162
 
163
  def _reference(self) -> torch.Tensor:
164
  y = torch.nn.functional.gelu(self.input.float(), approximate="tanh")
165
- y = torch.clamp(y / self.scale.float(), -448.0, 448.0)
166
- return y.to(torch.float8_e4m3fn)
 
167
 
168
  def setup_decode_m1(self) -> None:
169
  self._setup_shape(1, 4096)
 
6
  _original_allclose = torch.allclose
7
 
8
 
9
+ def _fp8_dtype() -> torch.dtype:
10
+ if torch.version.hip is not None and hasattr(torch, "float8_e4m3fnuz"):
11
+ return torch.float8_e4m3fnuz
12
+ return torch.float8_e4m3fn
13
+
14
+
15
+ def _fp8_max() -> float:
16
+ return 240.0 if torch.version.hip is not None else 448.0
17
+
18
+
19
+ def _is_fp8_dtype(dtype: torch.dtype) -> bool:
20
+ return dtype == torch.float8_e4m3fn or (
21
+ hasattr(torch, "float8_e4m3fnuz") and dtype == torch.float8_e4m3fnuz
22
+ )
23
+
24
+
25
  def _flashrt_allclose(input, other, rtol=1e-05, atol=1e-08, equal_nan=False):
26
+ if _is_fp8_dtype(input.dtype) or _is_fp8_dtype(other.dtype):
27
  return _original_allclose(
28
  input.float(),
29
  other.float(),
 
63
  self.input = torch.randn((m, n), device=self.device, dtype=torch.bfloat16)
64
  self.bias = torch.randn((n,), device=self.device, dtype=torch.bfloat16)
65
  self.scale = torch.tensor([0.25], device=self.device, dtype=torch.float32)
66
+ self.out = torch.empty_like(self.input, dtype=_fp8_dtype())
67
 
68
  def _reference(self) -> torch.Tensor:
69
  y = self.input.float() + self.bias.float()
70
  y = torch.nn.functional.gelu(y, approximate="tanh")
71
+ limit = _fp8_max()
72
+ y = torch.clamp(y / self.scale.float(), -limit, limit)
73
+ return y.to(_fp8_dtype())
74
 
75
  def setup_decode_m1(self) -> None:
76
  self._setup_shape(1, 4096)
 
175
  def _setup_shape(self, m: int, n: int) -> None:
176
  self.input = torch.randn((m, n), device=self.device, dtype=torch.bfloat16)
177
  self.scale = torch.tensor([0.25], device=self.device, dtype=torch.float32)
178
+ self.out = torch.empty_like(self.input, dtype=_fp8_dtype())
179
 
180
  def _reference(self) -> torch.Tensor:
181
  y = torch.nn.functional.gelu(self.input.float(), approximate="tanh")
182
+ limit = _fp8_max()
183
+ y = torch.clamp(y / self.scale.float(), -limit, limit)
184
+ return y.to(_fp8_dtype())
185
 
186
  def setup_decode_m1(self) -> None:
187
  self._setup_shape(1, 4096)
benchmarks/benchmark_channel_scale.py CHANGED
@@ -6,8 +6,24 @@ from kernels.benchmark import Benchmark
6
  _original_allclose = torch.allclose
7
 
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  def _flashrt_allclose(input, other, rtol=1e-05, atol=1e-08, equal_nan=False):
10
- if input.dtype == torch.float8_e4m3fn or other.dtype == torch.float8_e4m3fn:
11
  return _original_allclose(
12
  input.float(),
13
  other.float(),
@@ -49,12 +65,13 @@ class ChannelScaleFp8QuantizeBenchmark(Benchmark):
49
  (n,), device=self.device, dtype=torch.bfloat16
50
  )
51
  self.scale = torch.tensor([0.25], device=self.device, dtype=torch.float32)
52
- self.out = torch.empty_like(self.input, dtype=torch.float8_e4m3fn)
53
 
54
  def _reference(self) -> torch.Tensor:
55
  y = self.input.float() * self.channel_scale.float()
56
- y = torch.clamp(y / self.scale.float(), -448.0, 448.0)
57
- return y.to(torch.float8_e4m3fn)
 
58
 
59
  def setup_decode_m1(self) -> None:
60
  self._setup_shape(1, 4096)
 
6
  _original_allclose = torch.allclose
7
 
8
 
9
+ def _fp8_dtype() -> torch.dtype:
10
+ if torch.version.hip is not None and hasattr(torch, "float8_e4m3fnuz"):
11
+ return torch.float8_e4m3fnuz
12
+ return torch.float8_e4m3fn
13
+
14
+
15
+ def _fp8_max() -> float:
16
+ return 240.0 if torch.version.hip is not None else 448.0
17
+
18
+
19
+ def _is_fp8_dtype(dtype: torch.dtype) -> bool:
20
+ return dtype == torch.float8_e4m3fn or (
21
+ hasattr(torch, "float8_e4m3fnuz") and dtype == torch.float8_e4m3fnuz
22
+ )
23
+
24
+
25
  def _flashrt_allclose(input, other, rtol=1e-05, atol=1e-08, equal_nan=False):
26
+ if _is_fp8_dtype(input.dtype) or _is_fp8_dtype(other.dtype):
27
  return _original_allclose(
28
  input.float(),
29
  other.float(),
 
65
  (n,), device=self.device, dtype=torch.bfloat16
66
  )
67
  self.scale = torch.tensor([0.25], device=self.device, dtype=torch.float32)
68
+ self.out = torch.empty_like(self.input, dtype=_fp8_dtype())
69
 
70
  def _reference(self) -> torch.Tensor:
71
  y = self.input.float() * self.channel_scale.float()
72
+ limit = _fp8_max()
73
+ y = torch.clamp(y / self.scale.float(), -limit, limit)
74
+ return y.to(_fp8_dtype())
75
 
76
  def setup_decode_m1(self) -> None:
77
  self._setup_shape(1, 4096)
build/torch211-cxx11-cu126-x86_64-linux/__init__.py CHANGED
@@ -126,8 +126,14 @@ def _channel_scale_quantize_fp8_static_bf16_fake(
126
  return None
127
 
128
 
 
 
 
 
 
 
129
  def _allocate_fp8_like(input: torch.Tensor) -> torch.Tensor:
130
- return torch.empty(input.shape, device=input.device, dtype=torch.float8_e4m3fn)
131
 
132
 
133
  def bf16_linear_bf16(
 
126
  return None
127
 
128
 
129
+ def _fp8_dtype() -> torch.dtype:
130
+ if torch.version.hip is not None and hasattr(torch, "float8_e4m3fnuz"):
131
+ return torch.float8_e4m3fnuz
132
+ return torch.float8_e4m3fn
133
+
134
+
135
  def _allocate_fp8_like(input: torch.Tensor) -> torch.Tensor:
136
+ return torch.empty(input.shape, device=input.device, dtype=_fp8_dtype())
137
 
138
 
139
  def bf16_linear_bf16(
build/torch211-cxx11-cu126-x86_64-linux/{_flashrt_gemm_epilogues_cuda_5de4768.abi3.so → _flashrt_gemm_epilogues_cuda_4a17df5.abi3.so} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:6bcd10ce657fc484db78b199189dd445f4006a69ccdae5529957fb849140c45f
3
- size 311384
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fb5e2bf3a388a8f86dd83dcbfdbe02e35bbe1aafca724dc6d833f5e00513ad5d
3
+ size 302272
build/torch211-cxx11-cu126-x86_64-linux/_ops.py CHANGED
@@ -1,9 +1,9 @@
1
  import torch
2
- from . import _flashrt_gemm_epilogues_cuda_5de4768
3
- ops = torch.ops._flashrt_gemm_epilogues_cuda_5de4768
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
- return f"_flashrt_gemm_epilogues_cuda_5de4768::{op_name}"
 
1
  import torch
2
+ from . import _flashrt_gemm_epilogues_cuda_4a17df5
3
+ ops = torch.ops._flashrt_gemm_epilogues_cuda_4a17df5
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
+ return f"_flashrt_gemm_epilogues_cuda_4a17df5::{op_name}"
build/torch211-cxx11-cu126-x86_64-linux/metadata.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "name": "flashrt-gemm-epilogues",
3
- "id": "_flashrt_gemm_epilogues_cuda_5de4768",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "python-depends": [],
 
1
  {
2
  "name": "flashrt-gemm-epilogues",
3
+ "id": "_flashrt_gemm_epilogues_cuda_4a17df5",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "python-depends": [],
build/torch211-cxx11-cu128-x86_64-linux/__init__.py CHANGED
@@ -126,8 +126,14 @@ def _channel_scale_quantize_fp8_static_bf16_fake(
126
  return None
127
 
128
 
 
 
 
 
 
 
129
  def _allocate_fp8_like(input: torch.Tensor) -> torch.Tensor:
130
- return torch.empty(input.shape, device=input.device, dtype=torch.float8_e4m3fn)
131
 
132
 
133
  def bf16_linear_bf16(
 
126
  return None
127
 
128
 
129
+ def _fp8_dtype() -> torch.dtype:
130
+ if torch.version.hip is not None and hasattr(torch, "float8_e4m3fnuz"):
131
+ return torch.float8_e4m3fnuz
132
+ return torch.float8_e4m3fn
133
+
134
+
135
  def _allocate_fp8_like(input: torch.Tensor) -> torch.Tensor:
136
+ return torch.empty(input.shape, device=input.device, dtype=_fp8_dtype())
137
 
138
 
139
  def bf16_linear_bf16(
build/torch211-cxx11-cu128-x86_64-linux/{_flashrt_gemm_epilogues_cuda_5de4768.abi3.so → _flashrt_gemm_epilogues_cuda_4a17df5.abi3.so} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:b363e586bd34526b3630cf93726c8a34d67f1f8a578f1862ac02718978f8cc2d
3
- size 397600
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8bf38d750282de45d0bbe2dbd9cca35740f97d2f1d0541dae68761c2113079b8
3
+ size 388208
build/torch211-cxx11-cu128-x86_64-linux/_ops.py CHANGED
@@ -1,9 +1,9 @@
1
  import torch
2
- from . import _flashrt_gemm_epilogues_cuda_5de4768
3
- ops = torch.ops._flashrt_gemm_epilogues_cuda_5de4768
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
- return f"_flashrt_gemm_epilogues_cuda_5de4768::{op_name}"
 
1
  import torch
2
+ from . import _flashrt_gemm_epilogues_cuda_4a17df5
3
+ ops = torch.ops._flashrt_gemm_epilogues_cuda_4a17df5
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
+ return f"_flashrt_gemm_epilogues_cuda_4a17df5::{op_name}"
build/torch211-cxx11-cu128-x86_64-linux/metadata.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "name": "flashrt-gemm-epilogues",
3
- "id": "_flashrt_gemm_epilogues_cuda_5de4768",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "python-depends": [],
 
1
  {
2
  "name": "flashrt-gemm-epilogues",
3
+ "id": "_flashrt_gemm_epilogues_cuda_4a17df5",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "python-depends": [],
build/torch211-cxx11-cu130-x86_64-linux/__init__.py CHANGED
@@ -126,8 +126,14 @@ def _channel_scale_quantize_fp8_static_bf16_fake(
126
  return None
127
 
128
 
 
 
 
 
 
 
129
  def _allocate_fp8_like(input: torch.Tensor) -> torch.Tensor:
130
- return torch.empty(input.shape, device=input.device, dtype=torch.float8_e4m3fn)
131
 
132
 
133
  def bf16_linear_bf16(
 
126
  return None
127
 
128
 
129
+ def _fp8_dtype() -> torch.dtype:
130
+ if torch.version.hip is not None and hasattr(torch, "float8_e4m3fnuz"):
131
+ return torch.float8_e4m3fnuz
132
+ return torch.float8_e4m3fn
133
+
134
+
135
  def _allocate_fp8_like(input: torch.Tensor) -> torch.Tensor:
136
+ return torch.empty(input.shape, device=input.device, dtype=_fp8_dtype())
137
 
138
 
139
  def bf16_linear_bf16(
build/torch211-cxx11-cu130-x86_64-linux/{_flashrt_gemm_epilogues_cuda_5de4768.abi3.so → _flashrt_gemm_epilogues_cuda_4a17df5.abi3.so} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:a4f0778f4f7231cba857741fb77d84938f31b41f2e3e05898311a32444819688
3
- size 400200
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c96cf9ac67cd49f8d7b710e4bdd68e8f517e8f3c1c787de265fd45d292f3c53b
3
+ size 390816
build/torch211-cxx11-cu130-x86_64-linux/_ops.py CHANGED
@@ -1,9 +1,9 @@
1
  import torch
2
- from . import _flashrt_gemm_epilogues_cuda_5de4768
3
- ops = torch.ops._flashrt_gemm_epilogues_cuda_5de4768
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
- return f"_flashrt_gemm_epilogues_cuda_5de4768::{op_name}"
 
1
  import torch
2
+ from . import _flashrt_gemm_epilogues_cuda_4a17df5
3
+ ops = torch.ops._flashrt_gemm_epilogues_cuda_4a17df5
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
+ return f"_flashrt_gemm_epilogues_cuda_4a17df5::{op_name}"
build/torch211-cxx11-cu130-x86_64-linux/metadata.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "name": "flashrt-gemm-epilogues",
3
- "id": "_flashrt_gemm_epilogues_cuda_5de4768",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "python-depends": [],
 
1
  {
2
  "name": "flashrt-gemm-epilogues",
3
+ "id": "_flashrt_gemm_epilogues_cuda_4a17df5",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "python-depends": [],
build/torch211-cxx11-rocm71-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,277 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """FlashRT fused GEMM epilogue kernels."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import ctypes
6
+ import ctypes.util
7
+ from pathlib import Path
8
+ from typing import Optional
9
+
10
+ import torch
11
+
12
+
13
+ def _torch_bundled_cublaslt() -> Optional[Path]:
14
+ for parent in Path(torch.__file__).resolve().parents:
15
+ candidate = parent / "nvidia" / "cublas" / "lib" / "libcublasLt.so.12"
16
+ if candidate.exists():
17
+ return candidate
18
+ return None
19
+
20
+
21
+ def _preload_cublaslt() -> None:
22
+ bundled = _torch_bundled_cublaslt()
23
+ library = str(bundled) if bundled is not None else (
24
+ ctypes.util.find_library("cublasLt") or "libcublasLt.so"
25
+ )
26
+ try:
27
+ ctypes.CDLL(library, mode=ctypes.RTLD_GLOBAL)
28
+ except OSError:
29
+ pass
30
+
31
+
32
+ _preload_cublaslt()
33
+
34
+ from ._ops import add_op_namespace_prefix, ops
35
+
36
+
37
+ @torch.library.register_fake(add_op_namespace_prefix("bf16_linear_bf16"))
38
+ def _bf16_linear_bf16_fake(
39
+ x: torch.Tensor,
40
+ w: torch.Tensor,
41
+ out: torch.Tensor,
42
+ ) -> None:
43
+ if x.dim() != 2 or w.dim() != 2:
44
+ raise RuntimeError("x and w must be rank-2 tensors")
45
+ if out.shape != (x.shape[0], w.shape[1]):
46
+ raise RuntimeError("out shape must be (x.shape[0], w.shape[1])")
47
+ return None
48
+
49
+
50
+ @torch.library.register_fake(add_op_namespace_prefix("bf16_linear_bias_bf16"))
51
+ def _bf16_linear_bias_bf16_fake(
52
+ x: torch.Tensor,
53
+ w: torch.Tensor,
54
+ bias: torch.Tensor,
55
+ out: torch.Tensor,
56
+ ) -> None:
57
+ if x.dim() != 2 or w.dim() != 2:
58
+ raise RuntimeError("x and w must be rank-2 tensors")
59
+ if bias.dim() != 1:
60
+ raise RuntimeError("bias must be rank-1")
61
+ if out.shape != (x.shape[0], w.shape[1]):
62
+ raise RuntimeError("out shape must be (x.shape[0], w.shape[1])")
63
+ return None
64
+
65
+
66
+ @torch.library.register_fake(add_op_namespace_prefix("bf16_gemm_bias_gelu"))
67
+ def _bf16_gemm_bias_gelu_fake(
68
+ a: torch.Tensor,
69
+ b: torch.Tensor,
70
+ bias: torch.Tensor,
71
+ out: torch.Tensor,
72
+ ) -> None:
73
+ if a.dim() != 2 or b.dim() != 2:
74
+ raise RuntimeError("a and b must be rank-2 tensors")
75
+ if out.shape != (a.shape[0], b.shape[1]):
76
+ raise RuntimeError("out shape must be (a.shape[0], b.shape[1])")
77
+ return None
78
+
79
+
80
+ @torch.library.register_fake(add_op_namespace_prefix("bf16_gemm_bias"))
81
+ def _bf16_gemm_bias_fake(
82
+ a: torch.Tensor,
83
+ b: torch.Tensor,
84
+ bias: torch.Tensor,
85
+ out: torch.Tensor,
86
+ ) -> None:
87
+ if a.dim() != 2 or b.dim() != 2:
88
+ raise RuntimeError("a and b must be rank-2 tensors")
89
+ if out.shape != (a.shape[0], b.shape[1]):
90
+ raise RuntimeError("out shape must be (a.shape[0], b.shape[1])")
91
+ return None
92
+
93
+
94
+ @torch.library.register_fake(add_op_namespace_prefix("bias_gelu_quantize_fp8_static_bf16"))
95
+ def _bias_gelu_quantize_fp8_static_bf16_fake(
96
+ input: torch.Tensor,
97
+ bias: torch.Tensor,
98
+ scale: torch.Tensor,
99
+ out: torch.Tensor,
100
+ ) -> None:
101
+ if out.shape != input.shape:
102
+ raise RuntimeError("out shape must match input shape")
103
+ return None
104
+
105
+
106
+ @torch.library.register_fake(add_op_namespace_prefix("gelu_quantize_fp8_static_bf16"))
107
+ def _gelu_quantize_fp8_static_bf16_fake(
108
+ input: torch.Tensor,
109
+ scale: torch.Tensor,
110
+ out: torch.Tensor,
111
+ ) -> None:
112
+ if out.shape != input.shape:
113
+ raise RuntimeError("out shape must match input shape")
114
+ return None
115
+
116
+
117
+ @torch.library.register_fake(add_op_namespace_prefix("channel_scale_quantize_fp8_static_bf16"))
118
+ def _channel_scale_quantize_fp8_static_bf16_fake(
119
+ input: torch.Tensor,
120
+ channel_scale: torch.Tensor,
121
+ scale: torch.Tensor,
122
+ out: torch.Tensor,
123
+ ) -> None:
124
+ if out.shape != input.shape:
125
+ raise RuntimeError("out shape must match input shape")
126
+ return None
127
+
128
+
129
+ def _fp8_dtype() -> torch.dtype:
130
+ if torch.version.hip is not None and hasattr(torch, "float8_e4m3fnuz"):
131
+ return torch.float8_e4m3fnuz
132
+ return torch.float8_e4m3fn
133
+
134
+
135
+ def _allocate_fp8_like(input: torch.Tensor) -> torch.Tensor:
136
+ return torch.empty(input.shape, device=input.device, dtype=_fp8_dtype())
137
+
138
+
139
+ def bf16_linear_bf16(
140
+ x: torch.Tensor,
141
+ w: torch.Tensor,
142
+ out: Optional[torch.Tensor] = None,
143
+ ) -> torch.Tensor:
144
+ """Compute ``x @ w`` and store BF16 output.
145
+
146
+ ``x`` must be contiguous BF16 with shape ``(M, K)``. ``w`` must be
147
+ contiguous BF16 with shape ``(K, N)``. If ``out`` is omitted, a BF16
148
+ ``(M, N)`` tensor is allocated.
149
+ """
150
+
151
+ if out is None:
152
+ out = torch.empty(
153
+ (x.shape[0], w.shape[1]), device=x.device, dtype=torch.bfloat16
154
+ )
155
+ ops.bf16_linear_bf16(x, w, out)
156
+ return out
157
+
158
+
159
+ def bf16_linear_bias_bf16(
160
+ x: torch.Tensor,
161
+ w: torch.Tensor,
162
+ bias: torch.Tensor,
163
+ out: Optional[torch.Tensor] = None,
164
+ ) -> torch.Tensor:
165
+ """Compute ``x @ w + bias`` and store BF16 output.
166
+
167
+ ``x`` must be contiguous BF16 with shape ``(M, K)``. ``w`` must be
168
+ contiguous BF16 with shape ``(K, N)``. ``bias`` must be contiguous BF16
169
+ with shape ``(N,)``. If ``out`` is omitted, a BF16 ``(M, N)`` tensor is
170
+ allocated.
171
+ """
172
+
173
+ if out is None:
174
+ out = torch.empty(
175
+ (x.shape[0], w.shape[1]), device=x.device, dtype=torch.bfloat16
176
+ )
177
+ ops.bf16_linear_bias_bf16(x, w, bias, out)
178
+ return out
179
+
180
+
181
+ def bf16_gemm_bias_gelu(
182
+ a: torch.Tensor,
183
+ b: torch.Tensor,
184
+ bias: torch.Tensor,
185
+ out: Optional[torch.Tensor] = None,
186
+ ) -> torch.Tensor:
187
+ """Compute ``gelu(a @ b + bias)`` and store BF16 output.
188
+
189
+ ``a`` must be contiguous BF16 with shape ``(M, K)``. ``b`` must be
190
+ contiguous BF16 with shape ``(K, N)``. ``bias`` must be contiguous BF16
191
+ with shape ``(N,)``. If ``out`` is omitted, a BF16 ``(M, N)`` tensor is
192
+ allocated.
193
+ """
194
+
195
+ if out is None:
196
+ out = torch.empty(
197
+ (a.shape[0], b.shape[1]), device=a.device, dtype=torch.bfloat16
198
+ )
199
+ ops.bf16_gemm_bias_gelu(a, b, bias, out)
200
+ return out
201
+
202
+
203
+ def bf16_gemm_bias(
204
+ a: torch.Tensor,
205
+ b: torch.Tensor,
206
+ bias: torch.Tensor,
207
+ out: Optional[torch.Tensor] = None,
208
+ ) -> torch.Tensor:
209
+ """Compute ``a @ b + bias`` and store BF16 output."""
210
+
211
+ if out is None:
212
+ out = torch.empty(
213
+ (a.shape[0], b.shape[1]), device=a.device, dtype=torch.bfloat16
214
+ )
215
+ ops.bf16_gemm_bias(a, b, bias, out)
216
+ return out
217
+
218
+
219
+ def bias_gelu_quantize_fp8_static_bf16(
220
+ input: torch.Tensor,
221
+ bias: torch.Tensor,
222
+ scale: torch.Tensor,
223
+ out: Optional[torch.Tensor] = None,
224
+ ) -> torch.Tensor:
225
+ """Compute ``gelu(input + bias) / scale`` and store FP8 e4m3 output.
226
+
227
+ ``input`` must be contiguous BF16 with shape ``(..., N)``. ``bias`` must be
228
+ contiguous BF16 with shape ``(N,)``. ``scale`` must be a CUDA float32 scalar
229
+ tensor. If ``out`` is omitted, an FP8 e4m3 output tensor is allocated.
230
+ """
231
+
232
+ if out is None:
233
+ out = _allocate_fp8_like(input)
234
+ ops.bias_gelu_quantize_fp8_static_bf16(input, bias, scale, out)
235
+ return out
236
+
237
+
238
+ def gelu_quantize_fp8_static_bf16(
239
+ input: torch.Tensor,
240
+ scale: torch.Tensor,
241
+ out: Optional[torch.Tensor] = None,
242
+ ) -> torch.Tensor:
243
+ """Compute ``gelu(input) / scale`` and store FP8 e4m3 output."""
244
+
245
+ if out is None:
246
+ out = _allocate_fp8_like(input)
247
+ ops.gelu_quantize_fp8_static_bf16(input, scale, out)
248
+ return out
249
+
250
+
251
+ def channel_scale_quantize_fp8_static_bf16(
252
+ input: torch.Tensor,
253
+ channel_scale: torch.Tensor,
254
+ scale: torch.Tensor,
255
+ out: Optional[torch.Tensor] = None,
256
+ ) -> torch.Tensor:
257
+ """Compute ``input * channel_scale / scale`` and store FP8 e4m3 output.
258
+
259
+ ``channel_scale`` must be contiguous BF16 with shape ``(input.shape[-1],)``.
260
+ It is broadcast over all leading input dimensions.
261
+ """
262
+
263
+ if out is None:
264
+ out = _allocate_fp8_like(input)
265
+ ops.channel_scale_quantize_fp8_static_bf16(input, channel_scale, scale, out)
266
+ return out
267
+
268
+
269
+ __all__ = [
270
+ "bf16_linear_bf16",
271
+ "bf16_linear_bias_bf16",
272
+ "bf16_gemm_bias_gelu",
273
+ "bf16_gemm_bias",
274
+ "bias_gelu_quantize_fp8_static_bf16",
275
+ "channel_scale_quantize_fp8_static_bf16",
276
+ "gelu_quantize_fp8_static_bf16",
277
+ ]
build/{torch212-cxx11-cu126-x86_64-linux/_flashrt_gemm_epilogues_cuda_5de4768.abi3.so → torch211-cxx11-rocm71-x86_64-linux/_flashrt_gemm_epilogues_rocm_4a17df5.abi3.so} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:b2f33d7f74d9ca7adebca7d1f4a98e74e8652b891e1ad7cf86807a8a7af607e4
3
- size 322520
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:466c2f4bd1a6a50f798707736e5d2f2bbfda6acfd216a9ffaa2b686a781c4a25
3
+ size 157472
build/torch211-cxx11-rocm71-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _flashrt_gemm_epilogues_rocm_4a17df5
3
+ ops = torch.ops._flashrt_gemm_epilogues_rocm_4a17df5
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_flashrt_gemm_epilogues_rocm_4a17df5::{op_name}"
build/torch211-cxx11-rocm71-x86_64-linux/flashrt_gemm_epilogues/__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-rocm71-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "flashrt-gemm-epilogues",
3
+ "id": "_flashrt_gemm_epilogues_rocm_4a17df5",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "rocm",
9
+ "archs": [
10
+ "gfx942"
11
+ ]
12
+ }
13
+ }
build/torch211-cxx11-rocm72-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,277 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """FlashRT fused GEMM epilogue kernels."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import ctypes
6
+ import ctypes.util
7
+ from pathlib import Path
8
+ from typing import Optional
9
+
10
+ import torch
11
+
12
+
13
+ def _torch_bundled_cublaslt() -> Optional[Path]:
14
+ for parent in Path(torch.__file__).resolve().parents:
15
+ candidate = parent / "nvidia" / "cublas" / "lib" / "libcublasLt.so.12"
16
+ if candidate.exists():
17
+ return candidate
18
+ return None
19
+
20
+
21
+ def _preload_cublaslt() -> None:
22
+ bundled = _torch_bundled_cublaslt()
23
+ library = str(bundled) if bundled is not None else (
24
+ ctypes.util.find_library("cublasLt") or "libcublasLt.so"
25
+ )
26
+ try:
27
+ ctypes.CDLL(library, mode=ctypes.RTLD_GLOBAL)
28
+ except OSError:
29
+ pass
30
+
31
+
32
+ _preload_cublaslt()
33
+
34
+ from ._ops import add_op_namespace_prefix, ops
35
+
36
+
37
+ @torch.library.register_fake(add_op_namespace_prefix("bf16_linear_bf16"))
38
+ def _bf16_linear_bf16_fake(
39
+ x: torch.Tensor,
40
+ w: torch.Tensor,
41
+ out: torch.Tensor,
42
+ ) -> None:
43
+ if x.dim() != 2 or w.dim() != 2:
44
+ raise RuntimeError("x and w must be rank-2 tensors")
45
+ if out.shape != (x.shape[0], w.shape[1]):
46
+ raise RuntimeError("out shape must be (x.shape[0], w.shape[1])")
47
+ return None
48
+
49
+
50
+ @torch.library.register_fake(add_op_namespace_prefix("bf16_linear_bias_bf16"))
51
+ def _bf16_linear_bias_bf16_fake(
52
+ x: torch.Tensor,
53
+ w: torch.Tensor,
54
+ bias: torch.Tensor,
55
+ out: torch.Tensor,
56
+ ) -> None:
57
+ if x.dim() != 2 or w.dim() != 2:
58
+ raise RuntimeError("x and w must be rank-2 tensors")
59
+ if bias.dim() != 1:
60
+ raise RuntimeError("bias must be rank-1")
61
+ if out.shape != (x.shape[0], w.shape[1]):
62
+ raise RuntimeError("out shape must be (x.shape[0], w.shape[1])")
63
+ return None
64
+
65
+
66
+ @torch.library.register_fake(add_op_namespace_prefix("bf16_gemm_bias_gelu"))
67
+ def _bf16_gemm_bias_gelu_fake(
68
+ a: torch.Tensor,
69
+ b: torch.Tensor,
70
+ bias: torch.Tensor,
71
+ out: torch.Tensor,
72
+ ) -> None:
73
+ if a.dim() != 2 or b.dim() != 2:
74
+ raise RuntimeError("a and b must be rank-2 tensors")
75
+ if out.shape != (a.shape[0], b.shape[1]):
76
+ raise RuntimeError("out shape must be (a.shape[0], b.shape[1])")
77
+ return None
78
+
79
+
80
+ @torch.library.register_fake(add_op_namespace_prefix("bf16_gemm_bias"))
81
+ def _bf16_gemm_bias_fake(
82
+ a: torch.Tensor,
83
+ b: torch.Tensor,
84
+ bias: torch.Tensor,
85
+ out: torch.Tensor,
86
+ ) -> None:
87
+ if a.dim() != 2 or b.dim() != 2:
88
+ raise RuntimeError("a and b must be rank-2 tensors")
89
+ if out.shape != (a.shape[0], b.shape[1]):
90
+ raise RuntimeError("out shape must be (a.shape[0], b.shape[1])")
91
+ return None
92
+
93
+
94
+ @torch.library.register_fake(add_op_namespace_prefix("bias_gelu_quantize_fp8_static_bf16"))
95
+ def _bias_gelu_quantize_fp8_static_bf16_fake(
96
+ input: torch.Tensor,
97
+ bias: torch.Tensor,
98
+ scale: torch.Tensor,
99
+ out: torch.Tensor,
100
+ ) -> None:
101
+ if out.shape != input.shape:
102
+ raise RuntimeError("out shape must match input shape")
103
+ return None
104
+
105
+
106
+ @torch.library.register_fake(add_op_namespace_prefix("gelu_quantize_fp8_static_bf16"))
107
+ def _gelu_quantize_fp8_static_bf16_fake(
108
+ input: torch.Tensor,
109
+ scale: torch.Tensor,
110
+ out: torch.Tensor,
111
+ ) -> None:
112
+ if out.shape != input.shape:
113
+ raise RuntimeError("out shape must match input shape")
114
+ return None
115
+
116
+
117
+ @torch.library.register_fake(add_op_namespace_prefix("channel_scale_quantize_fp8_static_bf16"))
118
+ def _channel_scale_quantize_fp8_static_bf16_fake(
119
+ input: torch.Tensor,
120
+ channel_scale: torch.Tensor,
121
+ scale: torch.Tensor,
122
+ out: torch.Tensor,
123
+ ) -> None:
124
+ if out.shape != input.shape:
125
+ raise RuntimeError("out shape must match input shape")
126
+ return None
127
+
128
+
129
+ def _fp8_dtype() -> torch.dtype:
130
+ if torch.version.hip is not None and hasattr(torch, "float8_e4m3fnuz"):
131
+ return torch.float8_e4m3fnuz
132
+ return torch.float8_e4m3fn
133
+
134
+
135
+ def _allocate_fp8_like(input: torch.Tensor) -> torch.Tensor:
136
+ return torch.empty(input.shape, device=input.device, dtype=_fp8_dtype())
137
+
138
+
139
+ def bf16_linear_bf16(
140
+ x: torch.Tensor,
141
+ w: torch.Tensor,
142
+ out: Optional[torch.Tensor] = None,
143
+ ) -> torch.Tensor:
144
+ """Compute ``x @ w`` and store BF16 output.
145
+
146
+ ``x`` must be contiguous BF16 with shape ``(M, K)``. ``w`` must be
147
+ contiguous BF16 with shape ``(K, N)``. If ``out`` is omitted, a BF16
148
+ ``(M, N)`` tensor is allocated.
149
+ """
150
+
151
+ if out is None:
152
+ out = torch.empty(
153
+ (x.shape[0], w.shape[1]), device=x.device, dtype=torch.bfloat16
154
+ )
155
+ ops.bf16_linear_bf16(x, w, out)
156
+ return out
157
+
158
+
159
+ def bf16_linear_bias_bf16(
160
+ x: torch.Tensor,
161
+ w: torch.Tensor,
162
+ bias: torch.Tensor,
163
+ out: Optional[torch.Tensor] = None,
164
+ ) -> torch.Tensor:
165
+ """Compute ``x @ w + bias`` and store BF16 output.
166
+
167
+ ``x`` must be contiguous BF16 with shape ``(M, K)``. ``w`` must be
168
+ contiguous BF16 with shape ``(K, N)``. ``bias`` must be contiguous BF16
169
+ with shape ``(N,)``. If ``out`` is omitted, a BF16 ``(M, N)`` tensor is
170
+ allocated.
171
+ """
172
+
173
+ if out is None:
174
+ out = torch.empty(
175
+ (x.shape[0], w.shape[1]), device=x.device, dtype=torch.bfloat16
176
+ )
177
+ ops.bf16_linear_bias_bf16(x, w, bias, out)
178
+ return out
179
+
180
+
181
+ def bf16_gemm_bias_gelu(
182
+ a: torch.Tensor,
183
+ b: torch.Tensor,
184
+ bias: torch.Tensor,
185
+ out: Optional[torch.Tensor] = None,
186
+ ) -> torch.Tensor:
187
+ """Compute ``gelu(a @ b + bias)`` and store BF16 output.
188
+
189
+ ``a`` must be contiguous BF16 with shape ``(M, K)``. ``b`` must be
190
+ contiguous BF16 with shape ``(K, N)``. ``bias`` must be contiguous BF16
191
+ with shape ``(N,)``. If ``out`` is omitted, a BF16 ``(M, N)`` tensor is
192
+ allocated.
193
+ """
194
+
195
+ if out is None:
196
+ out = torch.empty(
197
+ (a.shape[0], b.shape[1]), device=a.device, dtype=torch.bfloat16
198
+ )
199
+ ops.bf16_gemm_bias_gelu(a, b, bias, out)
200
+ return out
201
+
202
+
203
+ def bf16_gemm_bias(
204
+ a: torch.Tensor,
205
+ b: torch.Tensor,
206
+ bias: torch.Tensor,
207
+ out: Optional[torch.Tensor] = None,
208
+ ) -> torch.Tensor:
209
+ """Compute ``a @ b + bias`` and store BF16 output."""
210
+
211
+ if out is None:
212
+ out = torch.empty(
213
+ (a.shape[0], b.shape[1]), device=a.device, dtype=torch.bfloat16
214
+ )
215
+ ops.bf16_gemm_bias(a, b, bias, out)
216
+ return out
217
+
218
+
219
+ def bias_gelu_quantize_fp8_static_bf16(
220
+ input: torch.Tensor,
221
+ bias: torch.Tensor,
222
+ scale: torch.Tensor,
223
+ out: Optional[torch.Tensor] = None,
224
+ ) -> torch.Tensor:
225
+ """Compute ``gelu(input + bias) / scale`` and store FP8 e4m3 output.
226
+
227
+ ``input`` must be contiguous BF16 with shape ``(..., N)``. ``bias`` must be
228
+ contiguous BF16 with shape ``(N,)``. ``scale`` must be a CUDA float32 scalar
229
+ tensor. If ``out`` is omitted, an FP8 e4m3 output tensor is allocated.
230
+ """
231
+
232
+ if out is None:
233
+ out = _allocate_fp8_like(input)
234
+ ops.bias_gelu_quantize_fp8_static_bf16(input, bias, scale, out)
235
+ return out
236
+
237
+
238
+ def gelu_quantize_fp8_static_bf16(
239
+ input: torch.Tensor,
240
+ scale: torch.Tensor,
241
+ out: Optional[torch.Tensor] = None,
242
+ ) -> torch.Tensor:
243
+ """Compute ``gelu(input) / scale`` and store FP8 e4m3 output."""
244
+
245
+ if out is None:
246
+ out = _allocate_fp8_like(input)
247
+ ops.gelu_quantize_fp8_static_bf16(input, scale, out)
248
+ return out
249
+
250
+
251
+ def channel_scale_quantize_fp8_static_bf16(
252
+ input: torch.Tensor,
253
+ channel_scale: torch.Tensor,
254
+ scale: torch.Tensor,
255
+ out: Optional[torch.Tensor] = None,
256
+ ) -> torch.Tensor:
257
+ """Compute ``input * channel_scale / scale`` and store FP8 e4m3 output.
258
+
259
+ ``channel_scale`` must be contiguous BF16 with shape ``(input.shape[-1],)``.
260
+ It is broadcast over all leading input dimensions.
261
+ """
262
+
263
+ if out is None:
264
+ out = _allocate_fp8_like(input)
265
+ ops.channel_scale_quantize_fp8_static_bf16(input, channel_scale, scale, out)
266
+ return out
267
+
268
+
269
+ __all__ = [
270
+ "bf16_linear_bf16",
271
+ "bf16_linear_bias_bf16",
272
+ "bf16_gemm_bias_gelu",
273
+ "bf16_gemm_bias",
274
+ "bias_gelu_quantize_fp8_static_bf16",
275
+ "channel_scale_quantize_fp8_static_bf16",
276
+ "gelu_quantize_fp8_static_bf16",
277
+ ]
build/torch211-cxx11-rocm72-x86_64-linux/_flashrt_gemm_epilogues_rocm_4a17df5.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6cfb636f94c660abc971f44c3b62f1c386ade8527204deb1e6dac268926bf01b
3
+ size 156096
build/torch211-cxx11-rocm72-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _flashrt_gemm_epilogues_rocm_4a17df5
3
+ ops = torch.ops._flashrt_gemm_epilogues_rocm_4a17df5
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_flashrt_gemm_epilogues_rocm_4a17df5::{op_name}"
build/torch211-cxx11-rocm72-x86_64-linux/flashrt_gemm_epilogues/__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-rocm72-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "flashrt-gemm-epilogues",
3
+ "id": "_flashrt_gemm_epilogues_rocm_4a17df5",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "rocm",
9
+ "archs": [
10
+ "gfx942"
11
+ ]
12
+ }
13
+ }
build/torch212-cxx11-cu126-x86_64-linux/__init__.py CHANGED
@@ -126,8 +126,14 @@ def _channel_scale_quantize_fp8_static_bf16_fake(
126
  return None
127
 
128
 
 
 
 
 
 
 
129
  def _allocate_fp8_like(input: torch.Tensor) -> torch.Tensor:
130
- return torch.empty(input.shape, device=input.device, dtype=torch.float8_e4m3fn)
131
 
132
 
133
  def bf16_linear_bf16(
 
126
  return None
127
 
128
 
129
+ def _fp8_dtype() -> torch.dtype:
130
+ if torch.version.hip is not None and hasattr(torch, "float8_e4m3fnuz"):
131
+ return torch.float8_e4m3fnuz
132
+ return torch.float8_e4m3fn
133
+
134
+
135
  def _allocate_fp8_like(input: torch.Tensor) -> torch.Tensor:
136
+ return torch.empty(input.shape, device=input.device, dtype=_fp8_dtype())
137
 
138
 
139
  def bf16_linear_bf16(
build/torch212-cxx11-cu126-x86_64-linux/_flashrt_gemm_epilogues_cuda_4a17df5.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d45f8c4f76ed67ebd7e0b63d839f2d60a8fb7d32e0056ba18527fbee08e83c6c
3
+ size 301968
build/torch212-cxx11-cu126-x86_64-linux/_ops.py CHANGED
@@ -1,9 +1,9 @@
1
  import torch
2
- from . import _flashrt_gemm_epilogues_cuda_5de4768
3
- ops = torch.ops._flashrt_gemm_epilogues_cuda_5de4768
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
- return f"_flashrt_gemm_epilogues_cuda_5de4768::{op_name}"
 
1
  import torch
2
+ from . import _flashrt_gemm_epilogues_cuda_4a17df5
3
+ ops = torch.ops._flashrt_gemm_epilogues_cuda_4a17df5
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
+ return f"_flashrt_gemm_epilogues_cuda_4a17df5::{op_name}"
build/torch212-cxx11-cu126-x86_64-linux/metadata.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "name": "flashrt-gemm-epilogues",
3
- "id": "_flashrt_gemm_epilogues_cuda_5de4768",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "python-depends": [],
 
1
  {
2
  "name": "flashrt-gemm-epilogues",
3
+ "id": "_flashrt_gemm_epilogues_cuda_4a17df5",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "python-depends": [],
build/torch212-cxx11-cu130-x86_64-linux/__init__.py CHANGED
@@ -126,8 +126,14 @@ def _channel_scale_quantize_fp8_static_bf16_fake(
126
  return None
127
 
128
 
 
 
 
 
 
 
129
  def _allocate_fp8_like(input: torch.Tensor) -> torch.Tensor:
130
- return torch.empty(input.shape, device=input.device, dtype=torch.float8_e4m3fn)
131
 
132
 
133
  def bf16_linear_bf16(
 
126
  return None
127
 
128
 
129
+ def _fp8_dtype() -> torch.dtype:
130
+ if torch.version.hip is not None and hasattr(torch, "float8_e4m3fnuz"):
131
+ return torch.float8_e4m3fnuz
132
+ return torch.float8_e4m3fn
133
+
134
+
135
  def _allocate_fp8_like(input: torch.Tensor) -> torch.Tensor:
136
+ return torch.empty(input.shape, device=input.device, dtype=_fp8_dtype())
137
 
138
 
139
  def bf16_linear_bf16(
build/torch212-cxx11-cu130-x86_64-linux/_flashrt_gemm_epilogues_cuda_4a17df5.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:25b9331cadbe889a5ac03a849e4d37b1e155ddccdb9c00c2750ab9865c2deac6
3
+ size 390632
build/torch212-cxx11-cu130-x86_64-linux/_flashrt_gemm_epilogues_cuda_5de4768.abi3.so DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:135bebc3472441c41ad7730b7bcaf287aa8aa34f2d2565e20d30fcd107b165e3
3
- size 406728
 
 
 
 
build/torch212-cxx11-cu130-x86_64-linux/_ops.py CHANGED
@@ -1,9 +1,9 @@
1
  import torch
2
- from . import _flashrt_gemm_epilogues_cuda_5de4768
3
- ops = torch.ops._flashrt_gemm_epilogues_cuda_5de4768
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
- return f"_flashrt_gemm_epilogues_cuda_5de4768::{op_name}"
 
1
  import torch
2
+ from . import _flashrt_gemm_epilogues_cuda_4a17df5
3
+ ops = torch.ops._flashrt_gemm_epilogues_cuda_4a17df5
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
+ return f"_flashrt_gemm_epilogues_cuda_4a17df5::{op_name}"
build/torch212-cxx11-cu130-x86_64-linux/metadata.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "name": "flashrt-gemm-epilogues",
3
- "id": "_flashrt_gemm_epilogues_cuda_5de4768",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "python-depends": [],
 
1
  {
2
  "name": "flashrt-gemm-epilogues",
3
+ "id": "_flashrt_gemm_epilogues_cuda_4a17df5",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "python-depends": [],
build/torch212-cxx11-cu132-x86_64-linux/__init__.py CHANGED
@@ -126,8 +126,14 @@ def _channel_scale_quantize_fp8_static_bf16_fake(
126
  return None
127
 
128
 
 
 
 
 
 
 
129
  def _allocate_fp8_like(input: torch.Tensor) -> torch.Tensor:
130
- return torch.empty(input.shape, device=input.device, dtype=torch.float8_e4m3fn)
131
 
132
 
133
  def bf16_linear_bf16(
 
126
  return None
127
 
128
 
129
+ def _fp8_dtype() -> torch.dtype:
130
+ if torch.version.hip is not None and hasattr(torch, "float8_e4m3fnuz"):
131
+ return torch.float8_e4m3fnuz
132
+ return torch.float8_e4m3fn
133
+
134
+
135
  def _allocate_fp8_like(input: torch.Tensor) -> torch.Tensor:
136
+ return torch.empty(input.shape, device=input.device, dtype=_fp8_dtype())
137
 
138
 
139
  def bf16_linear_bf16(
build/torch212-cxx11-cu132-x86_64-linux/_flashrt_gemm_epilogues_cuda_4a17df5.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4119535ec007c4b1a76db5bdd1f8841415b9e6322f8cdd97f40bb191057e7efe
3
+ size 390632
build/torch212-cxx11-cu132-x86_64-linux/_flashrt_gemm_epilogues_cuda_5de4768.abi3.so DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:761b9677d400b1f629ea7bc099e7616d8d9b90f219f2e7008b2a29f23eb812b6
3
- size 406728
 
 
 
 
build/torch212-cxx11-cu132-x86_64-linux/_ops.py CHANGED
@@ -1,9 +1,9 @@
1
  import torch
2
- from . import _flashrt_gemm_epilogues_cuda_5de4768
3
- ops = torch.ops._flashrt_gemm_epilogues_cuda_5de4768
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
- return f"_flashrt_gemm_epilogues_cuda_5de4768::{op_name}"
 
1
  import torch
2
+ from . import _flashrt_gemm_epilogues_cuda_4a17df5
3
+ ops = torch.ops._flashrt_gemm_epilogues_cuda_4a17df5
4
 
5
  def add_op_namespace_prefix(op_name: str):
6
  """
7
  Prefix op by namespace.
8
  """
9
+ return f"_flashrt_gemm_epilogues_cuda_4a17df5::{op_name}"
build/torch212-cxx11-cu132-x86_64-linux/metadata.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "name": "flashrt-gemm-epilogues",
3
- "id": "_flashrt_gemm_epilogues_cuda_5de4768",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "python-depends": [],
 
1
  {
2
  "name": "flashrt-gemm-epilogues",
3
+ "id": "_flashrt_gemm_epilogues_cuda_4a17df5",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "python-depends": [],
build/torch212-cxx11-rocm71-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,277 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """FlashRT fused GEMM epilogue kernels."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import ctypes
6
+ import ctypes.util
7
+ from pathlib import Path
8
+ from typing import Optional
9
+
10
+ import torch
11
+
12
+
13
+ def _torch_bundled_cublaslt() -> Optional[Path]:
14
+ for parent in Path(torch.__file__).resolve().parents:
15
+ candidate = parent / "nvidia" / "cublas" / "lib" / "libcublasLt.so.12"
16
+ if candidate.exists():
17
+ return candidate
18
+ return None
19
+
20
+
21
+ def _preload_cublaslt() -> None:
22
+ bundled = _torch_bundled_cublaslt()
23
+ library = str(bundled) if bundled is not None else (
24
+ ctypes.util.find_library("cublasLt") or "libcublasLt.so"
25
+ )
26
+ try:
27
+ ctypes.CDLL(library, mode=ctypes.RTLD_GLOBAL)
28
+ except OSError:
29
+ pass
30
+
31
+
32
+ _preload_cublaslt()
33
+
34
+ from ._ops import add_op_namespace_prefix, ops
35
+
36
+
37
+ @torch.library.register_fake(add_op_namespace_prefix("bf16_linear_bf16"))
38
+ def _bf16_linear_bf16_fake(
39
+ x: torch.Tensor,
40
+ w: torch.Tensor,
41
+ out: torch.Tensor,
42
+ ) -> None:
43
+ if x.dim() != 2 or w.dim() != 2:
44
+ raise RuntimeError("x and w must be rank-2 tensors")
45
+ if out.shape != (x.shape[0], w.shape[1]):
46
+ raise RuntimeError("out shape must be (x.shape[0], w.shape[1])")
47
+ return None
48
+
49
+
50
+ @torch.library.register_fake(add_op_namespace_prefix("bf16_linear_bias_bf16"))
51
+ def _bf16_linear_bias_bf16_fake(
52
+ x: torch.Tensor,
53
+ w: torch.Tensor,
54
+ bias: torch.Tensor,
55
+ out: torch.Tensor,
56
+ ) -> None:
57
+ if x.dim() != 2 or w.dim() != 2:
58
+ raise RuntimeError("x and w must be rank-2 tensors")
59
+ if bias.dim() != 1:
60
+ raise RuntimeError("bias must be rank-1")
61
+ if out.shape != (x.shape[0], w.shape[1]):
62
+ raise RuntimeError("out shape must be (x.shape[0], w.shape[1])")
63
+ return None
64
+
65
+
66
+ @torch.library.register_fake(add_op_namespace_prefix("bf16_gemm_bias_gelu"))
67
+ def _bf16_gemm_bias_gelu_fake(
68
+ a: torch.Tensor,
69
+ b: torch.Tensor,
70
+ bias: torch.Tensor,
71
+ out: torch.Tensor,
72
+ ) -> None:
73
+ if a.dim() != 2 or b.dim() != 2:
74
+ raise RuntimeError("a and b must be rank-2 tensors")
75
+ if out.shape != (a.shape[0], b.shape[1]):
76
+ raise RuntimeError("out shape must be (a.shape[0], b.shape[1])")
77
+ return None
78
+
79
+
80
+ @torch.library.register_fake(add_op_namespace_prefix("bf16_gemm_bias"))
81
+ def _bf16_gemm_bias_fake(
82
+ a: torch.Tensor,
83
+ b: torch.Tensor,
84
+ bias: torch.Tensor,
85
+ out: torch.Tensor,
86
+ ) -> None:
87
+ if a.dim() != 2 or b.dim() != 2:
88
+ raise RuntimeError("a and b must be rank-2 tensors")
89
+ if out.shape != (a.shape[0], b.shape[1]):
90
+ raise RuntimeError("out shape must be (a.shape[0], b.shape[1])")
91
+ return None
92
+
93
+
94
+ @torch.library.register_fake(add_op_namespace_prefix("bias_gelu_quantize_fp8_static_bf16"))
95
+ def _bias_gelu_quantize_fp8_static_bf16_fake(
96
+ input: torch.Tensor,
97
+ bias: torch.Tensor,
98
+ scale: torch.Tensor,
99
+ out: torch.Tensor,
100
+ ) -> None:
101
+ if out.shape != input.shape:
102
+ raise RuntimeError("out shape must match input shape")
103
+ return None
104
+
105
+
106
+ @torch.library.register_fake(add_op_namespace_prefix("gelu_quantize_fp8_static_bf16"))
107
+ def _gelu_quantize_fp8_static_bf16_fake(
108
+ input: torch.Tensor,
109
+ scale: torch.Tensor,
110
+ out: torch.Tensor,
111
+ ) -> None:
112
+ if out.shape != input.shape:
113
+ raise RuntimeError("out shape must match input shape")
114
+ return None
115
+
116
+
117
+ @torch.library.register_fake(add_op_namespace_prefix("channel_scale_quantize_fp8_static_bf16"))
118
+ def _channel_scale_quantize_fp8_static_bf16_fake(
119
+ input: torch.Tensor,
120
+ channel_scale: torch.Tensor,
121
+ scale: torch.Tensor,
122
+ out: torch.Tensor,
123
+ ) -> None:
124
+ if out.shape != input.shape:
125
+ raise RuntimeError("out shape must match input shape")
126
+ return None
127
+
128
+
129
+ def _fp8_dtype() -> torch.dtype:
130
+ if torch.version.hip is not None and hasattr(torch, "float8_e4m3fnuz"):
131
+ return torch.float8_e4m3fnuz
132
+ return torch.float8_e4m3fn
133
+
134
+
135
+ def _allocate_fp8_like(input: torch.Tensor) -> torch.Tensor:
136
+ return torch.empty(input.shape, device=input.device, dtype=_fp8_dtype())
137
+
138
+
139
+ def bf16_linear_bf16(
140
+ x: torch.Tensor,
141
+ w: torch.Tensor,
142
+ out: Optional[torch.Tensor] = None,
143
+ ) -> torch.Tensor:
144
+ """Compute ``x @ w`` and store BF16 output.
145
+
146
+ ``x`` must be contiguous BF16 with shape ``(M, K)``. ``w`` must be
147
+ contiguous BF16 with shape ``(K, N)``. If ``out`` is omitted, a BF16
148
+ ``(M, N)`` tensor is allocated.
149
+ """
150
+
151
+ if out is None:
152
+ out = torch.empty(
153
+ (x.shape[0], w.shape[1]), device=x.device, dtype=torch.bfloat16
154
+ )
155
+ ops.bf16_linear_bf16(x, w, out)
156
+ return out
157
+
158
+
159
+ def bf16_linear_bias_bf16(
160
+ x: torch.Tensor,
161
+ w: torch.Tensor,
162
+ bias: torch.Tensor,
163
+ out: Optional[torch.Tensor] = None,
164
+ ) -> torch.Tensor:
165
+ """Compute ``x @ w + bias`` and store BF16 output.
166
+
167
+ ``x`` must be contiguous BF16 with shape ``(M, K)``. ``w`` must be
168
+ contiguous BF16 with shape ``(K, N)``. ``bias`` must be contiguous BF16
169
+ with shape ``(N,)``. If ``out`` is omitted, a BF16 ``(M, N)`` tensor is
170
+ allocated.
171
+ """
172
+
173
+ if out is None:
174
+ out = torch.empty(
175
+ (x.shape[0], w.shape[1]), device=x.device, dtype=torch.bfloat16
176
+ )
177
+ ops.bf16_linear_bias_bf16(x, w, bias, out)
178
+ return out
179
+
180
+
181
+ def bf16_gemm_bias_gelu(
182
+ a: torch.Tensor,
183
+ b: torch.Tensor,
184
+ bias: torch.Tensor,
185
+ out: Optional[torch.Tensor] = None,
186
+ ) -> torch.Tensor:
187
+ """Compute ``gelu(a @ b + bias)`` and store BF16 output.
188
+
189
+ ``a`` must be contiguous BF16 with shape ``(M, K)``. ``b`` must be
190
+ contiguous BF16 with shape ``(K, N)``. ``bias`` must be contiguous BF16
191
+ with shape ``(N,)``. If ``out`` is omitted, a BF16 ``(M, N)`` tensor is
192
+ allocated.
193
+ """
194
+
195
+ if out is None:
196
+ out = torch.empty(
197
+ (a.shape[0], b.shape[1]), device=a.device, dtype=torch.bfloat16
198
+ )
199
+ ops.bf16_gemm_bias_gelu(a, b, bias, out)
200
+ return out
201
+
202
+
203
+ def bf16_gemm_bias(
204
+ a: torch.Tensor,
205
+ b: torch.Tensor,
206
+ bias: torch.Tensor,
207
+ out: Optional[torch.Tensor] = None,
208
+ ) -> torch.Tensor:
209
+ """Compute ``a @ b + bias`` and store BF16 output."""
210
+
211
+ if out is None:
212
+ out = torch.empty(
213
+ (a.shape[0], b.shape[1]), device=a.device, dtype=torch.bfloat16
214
+ )
215
+ ops.bf16_gemm_bias(a, b, bias, out)
216
+ return out
217
+
218
+
219
+ def bias_gelu_quantize_fp8_static_bf16(
220
+ input: torch.Tensor,
221
+ bias: torch.Tensor,
222
+ scale: torch.Tensor,
223
+ out: Optional[torch.Tensor] = None,
224
+ ) -> torch.Tensor:
225
+ """Compute ``gelu(input + bias) / scale`` and store FP8 e4m3 output.
226
+
227
+ ``input`` must be contiguous BF16 with shape ``(..., N)``. ``bias`` must be
228
+ contiguous BF16 with shape ``(N,)``. ``scale`` must be a CUDA float32 scalar
229
+ tensor. If ``out`` is omitted, an FP8 e4m3 output tensor is allocated.
230
+ """
231
+
232
+ if out is None:
233
+ out = _allocate_fp8_like(input)
234
+ ops.bias_gelu_quantize_fp8_static_bf16(input, bias, scale, out)
235
+ return out
236
+
237
+
238
+ def gelu_quantize_fp8_static_bf16(
239
+ input: torch.Tensor,
240
+ scale: torch.Tensor,
241
+ out: Optional[torch.Tensor] = None,
242
+ ) -> torch.Tensor:
243
+ """Compute ``gelu(input) / scale`` and store FP8 e4m3 output."""
244
+
245
+ if out is None:
246
+ out = _allocate_fp8_like(input)
247
+ ops.gelu_quantize_fp8_static_bf16(input, scale, out)
248
+ return out
249
+
250
+
251
+ def channel_scale_quantize_fp8_static_bf16(
252
+ input: torch.Tensor,
253
+ channel_scale: torch.Tensor,
254
+ scale: torch.Tensor,
255
+ out: Optional[torch.Tensor] = None,
256
+ ) -> torch.Tensor:
257
+ """Compute ``input * channel_scale / scale`` and store FP8 e4m3 output.
258
+
259
+ ``channel_scale`` must be contiguous BF16 with shape ``(input.shape[-1],)``.
260
+ It is broadcast over all leading input dimensions.
261
+ """
262
+
263
+ if out is None:
264
+ out = _allocate_fp8_like(input)
265
+ ops.channel_scale_quantize_fp8_static_bf16(input, channel_scale, scale, out)
266
+ return out
267
+
268
+
269
+ __all__ = [
270
+ "bf16_linear_bf16",
271
+ "bf16_linear_bias_bf16",
272
+ "bf16_gemm_bias_gelu",
273
+ "bf16_gemm_bias",
274
+ "bias_gelu_quantize_fp8_static_bf16",
275
+ "channel_scale_quantize_fp8_static_bf16",
276
+ "gelu_quantize_fp8_static_bf16",
277
+ ]
build/torch212-cxx11-rocm71-x86_64-linux/_flashrt_gemm_epilogues_rocm_4a17df5.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:31963b516aa5c67cad683bb0a2f7caa3250e2adb100f97df649043eb8f2f4fb7
3
+ size 155688
build/torch212-cxx11-rocm71-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _flashrt_gemm_epilogues_rocm_4a17df5
3
+ ops = torch.ops._flashrt_gemm_epilogues_rocm_4a17df5
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_flashrt_gemm_epilogues_rocm_4a17df5::{op_name}"
build/torch212-cxx11-rocm71-x86_64-linux/flashrt_gemm_epilogues/__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-rocm71-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "flashrt-gemm-epilogues",
3
+ "id": "_flashrt_gemm_epilogues_rocm_4a17df5",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "rocm",
9
+ "archs": [
10
+ "gfx942"
11
+ ]
12
+ }
13
+ }
build/torch212-cxx11-rocm72-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,277 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """FlashRT fused GEMM epilogue kernels."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import ctypes
6
+ import ctypes.util
7
+ from pathlib import Path
8
+ from typing import Optional
9
+
10
+ import torch
11
+
12
+
13
+ def _torch_bundled_cublaslt() -> Optional[Path]:
14
+ for parent in Path(torch.__file__).resolve().parents:
15
+ candidate = parent / "nvidia" / "cublas" / "lib" / "libcublasLt.so.12"
16
+ if candidate.exists():
17
+ return candidate
18
+ return None
19
+
20
+
21
+ def _preload_cublaslt() -> None:
22
+ bundled = _torch_bundled_cublaslt()
23
+ library = str(bundled) if bundled is not None else (
24
+ ctypes.util.find_library("cublasLt") or "libcublasLt.so"
25
+ )
26
+ try:
27
+ ctypes.CDLL(library, mode=ctypes.RTLD_GLOBAL)
28
+ except OSError:
29
+ pass
30
+
31
+
32
+ _preload_cublaslt()
33
+
34
+ from ._ops import add_op_namespace_prefix, ops
35
+
36
+
37
+ @torch.library.register_fake(add_op_namespace_prefix("bf16_linear_bf16"))
38
+ def _bf16_linear_bf16_fake(
39
+ x: torch.Tensor,
40
+ w: torch.Tensor,
41
+ out: torch.Tensor,
42
+ ) -> None:
43
+ if x.dim() != 2 or w.dim() != 2:
44
+ raise RuntimeError("x and w must be rank-2 tensors")
45
+ if out.shape != (x.shape[0], w.shape[1]):
46
+ raise RuntimeError("out shape must be (x.shape[0], w.shape[1])")
47
+ return None
48
+
49
+
50
+ @torch.library.register_fake(add_op_namespace_prefix("bf16_linear_bias_bf16"))
51
+ def _bf16_linear_bias_bf16_fake(
52
+ x: torch.Tensor,
53
+ w: torch.Tensor,
54
+ bias: torch.Tensor,
55
+ out: torch.Tensor,
56
+ ) -> None:
57
+ if x.dim() != 2 or w.dim() != 2:
58
+ raise RuntimeError("x and w must be rank-2 tensors")
59
+ if bias.dim() != 1:
60
+ raise RuntimeError("bias must be rank-1")
61
+ if out.shape != (x.shape[0], w.shape[1]):
62
+ raise RuntimeError("out shape must be (x.shape[0], w.shape[1])")
63
+ return None
64
+
65
+
66
+ @torch.library.register_fake(add_op_namespace_prefix("bf16_gemm_bias_gelu"))
67
+ def _bf16_gemm_bias_gelu_fake(
68
+ a: torch.Tensor,
69
+ b: torch.Tensor,
70
+ bias: torch.Tensor,
71
+ out: torch.Tensor,
72
+ ) -> None:
73
+ if a.dim() != 2 or b.dim() != 2:
74
+ raise RuntimeError("a and b must be rank-2 tensors")
75
+ if out.shape != (a.shape[0], b.shape[1]):
76
+ raise RuntimeError("out shape must be (a.shape[0], b.shape[1])")
77
+ return None
78
+
79
+
80
+ @torch.library.register_fake(add_op_namespace_prefix("bf16_gemm_bias"))
81
+ def _bf16_gemm_bias_fake(
82
+ a: torch.Tensor,
83
+ b: torch.Tensor,
84
+ bias: torch.Tensor,
85
+ out: torch.Tensor,
86
+ ) -> None:
87
+ if a.dim() != 2 or b.dim() != 2:
88
+ raise RuntimeError("a and b must be rank-2 tensors")
89
+ if out.shape != (a.shape[0], b.shape[1]):
90
+ raise RuntimeError("out shape must be (a.shape[0], b.shape[1])")
91
+ return None
92
+
93
+
94
+ @torch.library.register_fake(add_op_namespace_prefix("bias_gelu_quantize_fp8_static_bf16"))
95
+ def _bias_gelu_quantize_fp8_static_bf16_fake(
96
+ input: torch.Tensor,
97
+ bias: torch.Tensor,
98
+ scale: torch.Tensor,
99
+ out: torch.Tensor,
100
+ ) -> None:
101
+ if out.shape != input.shape:
102
+ raise RuntimeError("out shape must match input shape")
103
+ return None
104
+
105
+
106
+ @torch.library.register_fake(add_op_namespace_prefix("gelu_quantize_fp8_static_bf16"))
107
+ def _gelu_quantize_fp8_static_bf16_fake(
108
+ input: torch.Tensor,
109
+ scale: torch.Tensor,
110
+ out: torch.Tensor,
111
+ ) -> None:
112
+ if out.shape != input.shape:
113
+ raise RuntimeError("out shape must match input shape")
114
+ return None
115
+
116
+
117
+ @torch.library.register_fake(add_op_namespace_prefix("channel_scale_quantize_fp8_static_bf16"))
118
+ def _channel_scale_quantize_fp8_static_bf16_fake(
119
+ input: torch.Tensor,
120
+ channel_scale: torch.Tensor,
121
+ scale: torch.Tensor,
122
+ out: torch.Tensor,
123
+ ) -> None:
124
+ if out.shape != input.shape:
125
+ raise RuntimeError("out shape must match input shape")
126
+ return None
127
+
128
+
129
+ def _fp8_dtype() -> torch.dtype:
130
+ if torch.version.hip is not None and hasattr(torch, "float8_e4m3fnuz"):
131
+ return torch.float8_e4m3fnuz
132
+ return torch.float8_e4m3fn
133
+
134
+
135
+ def _allocate_fp8_like(input: torch.Tensor) -> torch.Tensor:
136
+ return torch.empty(input.shape, device=input.device, dtype=_fp8_dtype())
137
+
138
+
139
+ def bf16_linear_bf16(
140
+ x: torch.Tensor,
141
+ w: torch.Tensor,
142
+ out: Optional[torch.Tensor] = None,
143
+ ) -> torch.Tensor:
144
+ """Compute ``x @ w`` and store BF16 output.
145
+
146
+ ``x`` must be contiguous BF16 with shape ``(M, K)``. ``w`` must be
147
+ contiguous BF16 with shape ``(K, N)``. If ``out`` is omitted, a BF16
148
+ ``(M, N)`` tensor is allocated.
149
+ """
150
+
151
+ if out is None:
152
+ out = torch.empty(
153
+ (x.shape[0], w.shape[1]), device=x.device, dtype=torch.bfloat16
154
+ )
155
+ ops.bf16_linear_bf16(x, w, out)
156
+ return out
157
+
158
+
159
+ def bf16_linear_bias_bf16(
160
+ x: torch.Tensor,
161
+ w: torch.Tensor,
162
+ bias: torch.Tensor,
163
+ out: Optional[torch.Tensor] = None,
164
+ ) -> torch.Tensor:
165
+ """Compute ``x @ w + bias`` and store BF16 output.
166
+
167
+ ``x`` must be contiguous BF16 with shape ``(M, K)``. ``w`` must be
168
+ contiguous BF16 with shape ``(K, N)``. ``bias`` must be contiguous BF16
169
+ with shape ``(N,)``. If ``out`` is omitted, a BF16 ``(M, N)`` tensor is
170
+ allocated.
171
+ """
172
+
173
+ if out is None:
174
+ out = torch.empty(
175
+ (x.shape[0], w.shape[1]), device=x.device, dtype=torch.bfloat16
176
+ )
177
+ ops.bf16_linear_bias_bf16(x, w, bias, out)
178
+ return out
179
+
180
+
181
+ def bf16_gemm_bias_gelu(
182
+ a: torch.Tensor,
183
+ b: torch.Tensor,
184
+ bias: torch.Tensor,
185
+ out: Optional[torch.Tensor] = None,
186
+ ) -> torch.Tensor:
187
+ """Compute ``gelu(a @ b + bias)`` and store BF16 output.
188
+
189
+ ``a`` must be contiguous BF16 with shape ``(M, K)``. ``b`` must be
190
+ contiguous BF16 with shape ``(K, N)``. ``bias`` must be contiguous BF16
191
+ with shape ``(N,)``. If ``out`` is omitted, a BF16 ``(M, N)`` tensor is
192
+ allocated.
193
+ """
194
+
195
+ if out is None:
196
+ out = torch.empty(
197
+ (a.shape[0], b.shape[1]), device=a.device, dtype=torch.bfloat16
198
+ )
199
+ ops.bf16_gemm_bias_gelu(a, b, bias, out)
200
+ return out
201
+
202
+
203
+ def bf16_gemm_bias(
204
+ a: torch.Tensor,
205
+ b: torch.Tensor,
206
+ bias: torch.Tensor,
207
+ out: Optional[torch.Tensor] = None,
208
+ ) -> torch.Tensor:
209
+ """Compute ``a @ b + bias`` and store BF16 output."""
210
+
211
+ if out is None:
212
+ out = torch.empty(
213
+ (a.shape[0], b.shape[1]), device=a.device, dtype=torch.bfloat16
214
+ )
215
+ ops.bf16_gemm_bias(a, b, bias, out)
216
+ return out
217
+
218
+
219
+ def bias_gelu_quantize_fp8_static_bf16(
220
+ input: torch.Tensor,
221
+ bias: torch.Tensor,
222
+ scale: torch.Tensor,
223
+ out: Optional[torch.Tensor] = None,
224
+ ) -> torch.Tensor:
225
+ """Compute ``gelu(input + bias) / scale`` and store FP8 e4m3 output.
226
+
227
+ ``input`` must be contiguous BF16 with shape ``(..., N)``. ``bias`` must be
228
+ contiguous BF16 with shape ``(N,)``. ``scale`` must be a CUDA float32 scalar
229
+ tensor. If ``out`` is omitted, an FP8 e4m3 output tensor is allocated.
230
+ """
231
+
232
+ if out is None:
233
+ out = _allocate_fp8_like(input)
234
+ ops.bias_gelu_quantize_fp8_static_bf16(input, bias, scale, out)
235
+ return out
236
+
237
+
238
+ def gelu_quantize_fp8_static_bf16(
239
+ input: torch.Tensor,
240
+ scale: torch.Tensor,
241
+ out: Optional[torch.Tensor] = None,
242
+ ) -> torch.Tensor:
243
+ """Compute ``gelu(input) / scale`` and store FP8 e4m3 output."""
244
+
245
+ if out is None:
246
+ out = _allocate_fp8_like(input)
247
+ ops.gelu_quantize_fp8_static_bf16(input, scale, out)
248
+ return out
249
+
250
+
251
+ def channel_scale_quantize_fp8_static_bf16(
252
+ input: torch.Tensor,
253
+ channel_scale: torch.Tensor,
254
+ scale: torch.Tensor,
255
+ out: Optional[torch.Tensor] = None,
256
+ ) -> torch.Tensor:
257
+ """Compute ``input * channel_scale / scale`` and store FP8 e4m3 output.
258
+
259
+ ``channel_scale`` must be contiguous BF16 with shape ``(input.shape[-1],)``.
260
+ It is broadcast over all leading input dimensions.
261
+ """
262
+
263
+ if out is None:
264
+ out = _allocate_fp8_like(input)
265
+ ops.channel_scale_quantize_fp8_static_bf16(input, channel_scale, scale, out)
266
+ return out
267
+
268
+
269
+ __all__ = [
270
+ "bf16_linear_bf16",
271
+ "bf16_linear_bias_bf16",
272
+ "bf16_gemm_bias_gelu",
273
+ "bf16_gemm_bias",
274
+ "bias_gelu_quantize_fp8_static_bf16",
275
+ "channel_scale_quantize_fp8_static_bf16",
276
+ "gelu_quantize_fp8_static_bf16",
277
+ ]
build/torch212-cxx11-rocm72-x86_64-linux/_flashrt_gemm_epilogues_rocm_4a17df5.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c21f5a7cb50ef45ce45bd825e801629525ee5a1cbcbcc7d71a835499e964e691
3
+ size 154344
build/torch212-cxx11-rocm72-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _flashrt_gemm_epilogues_rocm_4a17df5
3
+ ops = torch.ops._flashrt_gemm_epilogues_rocm_4a17df5
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_flashrt_gemm_epilogues_rocm_4a17df5::{op_name}"
build/torch212-cxx11-rocm72-x86_64-linux/flashrt_gemm_epilogues/__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-rocm72-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "flashrt-gemm-epilogues",
3
+ "id": "_flashrt_gemm_epilogues_rocm_4a17df5",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "rocm",
9
+ "archs": [
10
+ "gfx942"
11
+ ]
12
+ }
13
+ }