liangsu9988 commited on
Commit
568cd0f
·
verified ·
1 Parent(s): fc06c53

Promote latest kernel artifacts to main

Browse files
Files changed (33) hide show
  1. .gitattributes +3 -35
  2. README.md +0 -9
  3. benchmarks/benchmark.py +139 -0
  4. build/torch211-cxx11-cu128-x86_64-linux/__init__.py +112 -0
  5. build/torch211-cxx11-cu128-x86_64-linux/_grouped_moe_gemm_cuda_32e9b2c.abi3.so +3 -0
  6. build/torch211-cxx11-cu128-x86_64-linux/_ops.py +9 -0
  7. build/torch211-cxx11-cu128-x86_64-linux/grouped_moe_gemm/__init__.py +26 -0
  8. build/torch211-cxx11-cu128-x86_64-linux/metadata.json +33 -0
  9. build/torch211-cxx11-cu130-x86_64-linux/__init__.py +112 -0
  10. build/torch211-cxx11-cu130-x86_64-linux/_grouped_moe_gemm_cuda_32e9b2c.abi3.so +3 -0
  11. build/torch211-cxx11-cu130-x86_64-linux/_ops.py +9 -0
  12. build/torch211-cxx11-cu130-x86_64-linux/grouped_moe_gemm/__init__.py +26 -0
  13. build/torch211-cxx11-cu130-x86_64-linux/metadata.json +33 -0
  14. build/torch212-cxx11-cu130-x86_64-linux/__init__.py +112 -0
  15. build/torch212-cxx11-cu130-x86_64-linux/_grouped_moe_gemm_cuda_32e9b2c.abi3.so +3 -0
  16. build/torch212-cxx11-cu130-x86_64-linux/_ops.py +9 -0
  17. build/torch212-cxx11-cu130-x86_64-linux/grouped_moe_gemm/__init__.py +26 -0
  18. build/torch212-cxx11-cu130-x86_64-linux/metadata.json +33 -0
  19. build/torch212-cxx11-cu132-x86_64-linux/__init__.py +112 -0
  20. build/torch212-cxx11-cu132-x86_64-linux/_grouped_moe_gemm_cuda_32e9b2c.abi3.so +3 -0
  21. build/torch212-cxx11-cu132-x86_64-linux/_ops.py +9 -0
  22. build/torch212-cxx11-cu132-x86_64-linux/grouped_moe_gemm/__init__.py +26 -0
  23. build/torch212-cxx11-cu132-x86_64-linux/metadata.json +33 -0
  24. build/torch213-cxx11-cu130-x86_64-linux/__init__.py +112 -0
  25. build/torch213-cxx11-cu130-x86_64-linux/_grouped_moe_gemm_cuda_32e9b2c.abi3.so +3 -0
  26. build/torch213-cxx11-cu130-x86_64-linux/_ops.py +9 -0
  27. build/torch213-cxx11-cu130-x86_64-linux/grouped_moe_gemm/__init__.py +26 -0
  28. build/torch213-cxx11-cu130-x86_64-linux/metadata.json +33 -0
  29. build/torch213-cxx11-cu132-x86_64-linux/__init__.py +112 -0
  30. build/torch213-cxx11-cu132-x86_64-linux/_grouped_moe_gemm_cuda_32e9b2c.abi3.so +3 -0
  31. build/torch213-cxx11-cu132-x86_64-linux/_ops.py +9 -0
  32. build/torch213-cxx11-cu132-x86_64-linux/grouped_moe_gemm/__init__.py +26 -0
  33. build/torch213-cxx11-cu132-x86_64-linux/metadata.json +33 -0
.gitattributes CHANGED
@@ -1,35 +1,3 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ *.so filter=lfs diff=lfs merge=lfs -text
2
+ *.pyd filter=lfs diff=lfs merge=lfs -text
3
+ *.dylib filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
README.md DELETED
@@ -1,9 +0,0 @@
1
- # flashrt/grouped-moe-gemm
2
-
3
- This repository is a compatibility mirror for older `kernels` clients
4
- that resolve repositories through the default Hugging Face model repo API.
5
-
6
- Canonical Kernel Hub repo: https://huggingface.co/kernels/flashrt/grouped-moe-gemm
7
-
8
- Do not edit this mirror by hand. It is generated from the Kernel Hub
9
- `vN` branches and contains the same `build/**` artifacts.
 
 
 
 
 
 
 
 
 
 
benchmarks/benchmark.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """35B-A3B grouped expert prefill GEMM package/native parity benchmark."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import importlib
8
+ import json
9
+ import sys
10
+ from pathlib import Path
11
+
12
+ import torch
13
+
14
+
15
+ PACKAGE = Path(__file__).resolve().parents[1]
16
+ sys.path.insert(0, str(PACKAGE / "tests"))
17
+ from _source_loader import load_source_ops # noqa: E402
18
+ from test_grouped_moe_gemm import make_sf # noqa: E402
19
+
20
+
21
+ WORKLOADS = {
22
+ "35b_gate_up": (64, 1024, 2048, 16, 256),
23
+ "35b_down": (64, 2048, 512, 16, 256),
24
+ }
25
+
26
+
27
+ def time_us(fn, warmup: int, iters: int) -> float:
28
+ for _ in range(warmup):
29
+ fn()
30
+ torch.cuda.synchronize()
31
+ start = torch.cuda.Event(enable_timing=True)
32
+ end = torch.cuda.Event(enable_timing=True)
33
+ start.record()
34
+ for _ in range(iters):
35
+ fn()
36
+ end.record()
37
+ torch.cuda.synchronize()
38
+ return start.elapsed_time(end) * 1000.0 / iters
39
+
40
+
41
+ def load_ops(backend: str, artifact: str | None):
42
+ if backend == "source":
43
+ return load_source_ops()
44
+ if artifact:
45
+ sys.path.insert(0, artifact)
46
+ try:
47
+ return importlib.import_module("grouped_moe_gemm")
48
+ finally:
49
+ if artifact:
50
+ sys.path.remove(artifact)
51
+
52
+
53
+ def make_case(tile_rows: int, n: int, k: int, tiles: int, experts: int):
54
+ rows = tile_rows * tiles
55
+ dev = "cuda"
56
+ packed = torch.randint(0, 256, (rows, k // 2), device=dev, dtype=torch.uint8)
57
+ weights = torch.randint(
58
+ 0, 256, (experts, n, k // 2), device=dev, dtype=torch.uint8
59
+ )
60
+ input_scale, _ = make_sf(rows, k, dev)
61
+ weight_scales = torch.stack([make_sf(n, k, dev)[0] for _ in range(experts)])
62
+ alpha = torch.rand(experts, device=dev, dtype=torch.float32) + 0.5
63
+ tile_expert = torch.arange(tiles, device=dev, dtype=torch.int32) % experts
64
+ out = torch.empty(rows, n, device=dev, dtype=torch.bfloat16)
65
+ return packed, weights, input_scale, weight_scales, alpha, tile_expert, out
66
+
67
+
68
+ def main() -> int:
69
+ parser = argparse.ArgumentParser()
70
+ parser.add_argument("--backend", choices=("source", "installed"), default="source")
71
+ parser.add_argument("--artifact")
72
+ parser.add_argument("--warmup", type=int, default=20)
73
+ parser.add_argument("--iters", type=int, default=100)
74
+ parser.add_argument("--json-out")
75
+ args = parser.parse_args()
76
+
77
+ torch.manual_seed(9102)
78
+ ops = load_ops(args.backend, args.artifact)
79
+ rows = []
80
+ for name, (tile_rows, n, k, tiles, experts) in WORKLOADS.items():
81
+ packed, weights, input_scale, weight_scales, alpha, tile_expert, out = make_case(
82
+ tile_rows, n, k, tiles, experts
83
+ )
84
+ kwargs = dict(
85
+ tile_rows=tile_rows,
86
+ weight_stride=weights[0].numel(),
87
+ weight_scale_stride=weight_scales[0].numel(),
88
+ )
89
+
90
+ def public_call():
91
+ return ops.grouped_nvfp4_gemm_bf16(
92
+ packed, weights, input_scale, weight_scales, alpha,
93
+ tile_expert, out=out, **kwargs
94
+ )
95
+
96
+ def raw_call():
97
+ ops.ops.grouped_nvfp4_gemm_bf16_out(
98
+ packed, weights, input_scale, weight_scales, alpha,
99
+ tile_expert, tile_rows, 0, kwargs["weight_stride"],
100
+ kwargs["weight_scale_stride"], out,
101
+ )
102
+
103
+ expected = public_call().clone()
104
+ raw_call()
105
+ torch.cuda.synchronize()
106
+ if not torch.equal(out, expected):
107
+ raise AssertionError(f"{name}: public/raw output mismatch")
108
+ public_us = time_us(public_call, args.warmup, args.iters)
109
+ raw_us = time_us(raw_call, args.warmup, args.iters)
110
+ ratio = public_us / raw_us
111
+ accepted = public_us - raw_us <= max(0.75, raw_us * 0.05)
112
+ row = {
113
+ "workload": name,
114
+ "tile_rows": tile_rows,
115
+ "rows": tile_rows * tiles,
116
+ "n": n,
117
+ "k": k,
118
+ "experts": experts,
119
+ "raw_native_us": raw_us,
120
+ "public_wrapper_us": public_us,
121
+ "wrapper_native": ratio,
122
+ "bit_exact": True,
123
+ "accepted": accepted,
124
+ }
125
+ rows.append(row)
126
+ print(
127
+ f"{name}: raw={raw_us:.3f}us public={public_us:.3f}us "
128
+ f"ratio={ratio:.4f} accepted={accepted}"
129
+ )
130
+ if args.json_out:
131
+ Path(args.json_out).parent.mkdir(parents=True, exist_ok=True)
132
+ Path(args.json_out).write_text(json.dumps(rows, indent=2) + "\n")
133
+ if not all(row["accepted"] for row in rows):
134
+ raise AssertionError("grouped MoE wrapper/native parity failed")
135
+ return 0
136
+
137
+
138
+ if __name__ == "__main__":
139
+ raise SystemExit(main())
build/torch211-cxx11-cu128-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Grouped NVFP4 MoE GEMM for Blackwell prefill workloads."""
2
+
3
+ from __future__ import annotations
4
+ import torch
5
+ from ._ops import add_op_namespace_prefix, ops
6
+
7
+
8
+ @torch.library.custom_op(
9
+ add_op_namespace_prefix("_grouped_nvfp4_gemm_bf16"),
10
+ mutates_args=(),
11
+ device_types="cuda",
12
+ )
13
+ def _compileable(
14
+ input: torch.Tensor,
15
+ weight: torch.Tensor,
16
+ input_scale: torch.Tensor,
17
+ weight_scale: torch.Tensor,
18
+ alpha: torch.Tensor,
19
+ tile_expert: torch.Tensor,
20
+ tile_rows: int,
21
+ input_scale_stride: int,
22
+ weight_stride: int,
23
+ weight_scale_stride: int,
24
+ ) -> torch.Tensor:
25
+ output = torch.empty(
26
+ (input.shape[0], weight.shape[1]), device=input.device, dtype=torch.bfloat16
27
+ )
28
+ ops.grouped_nvfp4_gemm_bf16_out(
29
+ input,
30
+ weight,
31
+ input_scale,
32
+ weight_scale,
33
+ alpha,
34
+ tile_expert,
35
+ tile_rows,
36
+ input_scale_stride,
37
+ weight_stride,
38
+ weight_scale_stride,
39
+ output,
40
+ )
41
+ return output
42
+
43
+
44
+ @torch.library.register_fake(add_op_namespace_prefix("_grouped_nvfp4_gemm_bf16"))
45
+ def _fake(
46
+ input,
47
+ weight,
48
+ input_scale,
49
+ weight_scale,
50
+ alpha,
51
+ tile_expert,
52
+ tile_rows,
53
+ input_scale_stride,
54
+ weight_stride,
55
+ weight_scale_stride,
56
+ ):
57
+ if input.ndim != 2 or weight.ndim != 3:
58
+ raise RuntimeError("invalid grouped GEMM tensor shapes")
59
+ return torch.empty(
60
+ (input.shape[0], weight.shape[1]), device=input.device, dtype=torch.bfloat16
61
+ )
62
+
63
+
64
+ def grouped_nvfp4_gemm_bf16(
65
+ input,
66
+ weight,
67
+ input_scale,
68
+ weight_scale,
69
+ alpha,
70
+ tile_expert,
71
+ *,
72
+ tile_rows,
73
+ input_scale_stride=0,
74
+ weight_stride=None,
75
+ weight_scale_stride=None,
76
+ out=None,
77
+ ):
78
+ """Compute expert-selected packed NVFP4 GEMM tiles with BF16 output."""
79
+ if weight_stride is None:
80
+ weight_stride = weight[0].numel()
81
+ if weight_scale_stride is None:
82
+ weight_scale_stride = weight_scale[0].numel()
83
+ if out is None:
84
+ return _compileable(
85
+ input,
86
+ weight,
87
+ input_scale,
88
+ weight_scale,
89
+ alpha,
90
+ tile_expert,
91
+ int(tile_rows),
92
+ int(input_scale_stride),
93
+ int(weight_stride),
94
+ int(weight_scale_stride),
95
+ )
96
+ ops.grouped_nvfp4_gemm_bf16_out(
97
+ input,
98
+ weight,
99
+ input_scale,
100
+ weight_scale,
101
+ alpha,
102
+ tile_expert,
103
+ int(tile_rows),
104
+ int(input_scale_stride),
105
+ int(weight_stride),
106
+ int(weight_scale_stride),
107
+ out,
108
+ )
109
+ return out
110
+
111
+
112
+ __all__ = ["grouped_nvfp4_gemm_bf16"]
build/torch211-cxx11-cu128-x86_64-linux/_grouped_moe_gemm_cuda_32e9b2c.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a19fb3043235055688d9e01dda3990ca2c00e9a5f8aec3656429a67bbdbac6fd
3
+ size 175392
build/torch211-cxx11-cu128-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _grouped_moe_gemm_cuda_32e9b2c
3
+ ops = torch.ops._grouped_moe_gemm_cuda_32e9b2c
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_grouped_moe_gemm_cuda_32e9b2c::{op_name}"
build/torch211-cxx11-cu128-x86_64-linux/grouped_moe_gemm/__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-cu128-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "grouped-moe-gemm",
3
+ "id": "_grouped_moe_gemm_cuda_32e9b2c",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "12.0a"
11
+ ]
12
+ },
13
+ "digest": {
14
+ "algorithm": "sha256",
15
+ "files": {
16
+ "__init__.py": "/pd/JqQCw5Ie4nddrEvVeqaOFtlbkqNDqykgQLlZJF0=",
17
+ "_grouped_moe_gemm_cuda_32e9b2c.abi3.so": "oZ+zBDI1BVaI2eAd2jmQyiwA6aX4rsNlZCmme726xv0=",
18
+ "_ops.py": "AxmxTU/RwyGFkTVT0IV6Y0/bjHdcILOm6O5JNy/zf6k=",
19
+ "grouped_moe_gemm/__init__.py": "DFYPlrhXwYjEqCl/8n0SmWGZV8NFml5DPhMjKfv98GY="
20
+ }
21
+ },
22
+ "provenance": {
23
+ "kernel-builder": {
24
+ "version": "0.17.0-dev0",
25
+ "sha": "19aaa6421e674e9fecc352bbae6eab81d19a6bf4",
26
+ "dirty": false
27
+ },
28
+ "kernel": {
29
+ "sha": "32e9b2c39ee268d8a76fcfef667974a13022c283",
30
+ "dirty": false
31
+ }
32
+ }
33
+ }
build/torch211-cxx11-cu130-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Grouped NVFP4 MoE GEMM for Blackwell prefill workloads."""
2
+
3
+ from __future__ import annotations
4
+ import torch
5
+ from ._ops import add_op_namespace_prefix, ops
6
+
7
+
8
+ @torch.library.custom_op(
9
+ add_op_namespace_prefix("_grouped_nvfp4_gemm_bf16"),
10
+ mutates_args=(),
11
+ device_types="cuda",
12
+ )
13
+ def _compileable(
14
+ input: torch.Tensor,
15
+ weight: torch.Tensor,
16
+ input_scale: torch.Tensor,
17
+ weight_scale: torch.Tensor,
18
+ alpha: torch.Tensor,
19
+ tile_expert: torch.Tensor,
20
+ tile_rows: int,
21
+ input_scale_stride: int,
22
+ weight_stride: int,
23
+ weight_scale_stride: int,
24
+ ) -> torch.Tensor:
25
+ output = torch.empty(
26
+ (input.shape[0], weight.shape[1]), device=input.device, dtype=torch.bfloat16
27
+ )
28
+ ops.grouped_nvfp4_gemm_bf16_out(
29
+ input,
30
+ weight,
31
+ input_scale,
32
+ weight_scale,
33
+ alpha,
34
+ tile_expert,
35
+ tile_rows,
36
+ input_scale_stride,
37
+ weight_stride,
38
+ weight_scale_stride,
39
+ output,
40
+ )
41
+ return output
42
+
43
+
44
+ @torch.library.register_fake(add_op_namespace_prefix("_grouped_nvfp4_gemm_bf16"))
45
+ def _fake(
46
+ input,
47
+ weight,
48
+ input_scale,
49
+ weight_scale,
50
+ alpha,
51
+ tile_expert,
52
+ tile_rows,
53
+ input_scale_stride,
54
+ weight_stride,
55
+ weight_scale_stride,
56
+ ):
57
+ if input.ndim != 2 or weight.ndim != 3:
58
+ raise RuntimeError("invalid grouped GEMM tensor shapes")
59
+ return torch.empty(
60
+ (input.shape[0], weight.shape[1]), device=input.device, dtype=torch.bfloat16
61
+ )
62
+
63
+
64
+ def grouped_nvfp4_gemm_bf16(
65
+ input,
66
+ weight,
67
+ input_scale,
68
+ weight_scale,
69
+ alpha,
70
+ tile_expert,
71
+ *,
72
+ tile_rows,
73
+ input_scale_stride=0,
74
+ weight_stride=None,
75
+ weight_scale_stride=None,
76
+ out=None,
77
+ ):
78
+ """Compute expert-selected packed NVFP4 GEMM tiles with BF16 output."""
79
+ if weight_stride is None:
80
+ weight_stride = weight[0].numel()
81
+ if weight_scale_stride is None:
82
+ weight_scale_stride = weight_scale[0].numel()
83
+ if out is None:
84
+ return _compileable(
85
+ input,
86
+ weight,
87
+ input_scale,
88
+ weight_scale,
89
+ alpha,
90
+ tile_expert,
91
+ int(tile_rows),
92
+ int(input_scale_stride),
93
+ int(weight_stride),
94
+ int(weight_scale_stride),
95
+ )
96
+ ops.grouped_nvfp4_gemm_bf16_out(
97
+ input,
98
+ weight,
99
+ input_scale,
100
+ weight_scale,
101
+ alpha,
102
+ tile_expert,
103
+ int(tile_rows),
104
+ int(input_scale_stride),
105
+ int(weight_stride),
106
+ int(weight_scale_stride),
107
+ out,
108
+ )
109
+ return out
110
+
111
+
112
+ __all__ = ["grouped_nvfp4_gemm_bf16"]
build/torch211-cxx11-cu130-x86_64-linux/_grouped_moe_gemm_cuda_32e9b2c.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:43c9de9e12cfb9e84101046e351c8c9279f580d69a0f4dca9c98c5d6b5b3f0bd
3
+ size 183176
build/torch211-cxx11-cu130-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _grouped_moe_gemm_cuda_32e9b2c
3
+ ops = torch.ops._grouped_moe_gemm_cuda_32e9b2c
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_grouped_moe_gemm_cuda_32e9b2c::{op_name}"
build/torch211-cxx11-cu130-x86_64-linux/grouped_moe_gemm/__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/metadata.json ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "grouped-moe-gemm",
3
+ "id": "_grouped_moe_gemm_cuda_32e9b2c",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "12.0a"
11
+ ]
12
+ },
13
+ "digest": {
14
+ "algorithm": "sha256",
15
+ "files": {
16
+ "__init__.py": "/pd/JqQCw5Ie4nddrEvVeqaOFtlbkqNDqykgQLlZJF0=",
17
+ "_grouped_moe_gemm_cuda_32e9b2c.abi3.so": "Q8nenhLPuehBAQRuNRyMknn1gNaaD03KnJjF1rWz8L0=",
18
+ "_ops.py": "AxmxTU/RwyGFkTVT0IV6Y0/bjHdcILOm6O5JNy/zf6k=",
19
+ "grouped_moe_gemm/__init__.py": "DFYPlrhXwYjEqCl/8n0SmWGZV8NFml5DPhMjKfv98GY="
20
+ }
21
+ },
22
+ "provenance": {
23
+ "kernel-builder": {
24
+ "version": "0.17.0-dev0",
25
+ "sha": "19aaa6421e674e9fecc352bbae6eab81d19a6bf4",
26
+ "dirty": false
27
+ },
28
+ "kernel": {
29
+ "sha": "32e9b2c39ee268d8a76fcfef667974a13022c283",
30
+ "dirty": false
31
+ }
32
+ }
33
+ }
build/torch212-cxx11-cu130-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Grouped NVFP4 MoE GEMM for Blackwell prefill workloads."""
2
+
3
+ from __future__ import annotations
4
+ import torch
5
+ from ._ops import add_op_namespace_prefix, ops
6
+
7
+
8
+ @torch.library.custom_op(
9
+ add_op_namespace_prefix("_grouped_nvfp4_gemm_bf16"),
10
+ mutates_args=(),
11
+ device_types="cuda",
12
+ )
13
+ def _compileable(
14
+ input: torch.Tensor,
15
+ weight: torch.Tensor,
16
+ input_scale: torch.Tensor,
17
+ weight_scale: torch.Tensor,
18
+ alpha: torch.Tensor,
19
+ tile_expert: torch.Tensor,
20
+ tile_rows: int,
21
+ input_scale_stride: int,
22
+ weight_stride: int,
23
+ weight_scale_stride: int,
24
+ ) -> torch.Tensor:
25
+ output = torch.empty(
26
+ (input.shape[0], weight.shape[1]), device=input.device, dtype=torch.bfloat16
27
+ )
28
+ ops.grouped_nvfp4_gemm_bf16_out(
29
+ input,
30
+ weight,
31
+ input_scale,
32
+ weight_scale,
33
+ alpha,
34
+ tile_expert,
35
+ tile_rows,
36
+ input_scale_stride,
37
+ weight_stride,
38
+ weight_scale_stride,
39
+ output,
40
+ )
41
+ return output
42
+
43
+
44
+ @torch.library.register_fake(add_op_namespace_prefix("_grouped_nvfp4_gemm_bf16"))
45
+ def _fake(
46
+ input,
47
+ weight,
48
+ input_scale,
49
+ weight_scale,
50
+ alpha,
51
+ tile_expert,
52
+ tile_rows,
53
+ input_scale_stride,
54
+ weight_stride,
55
+ weight_scale_stride,
56
+ ):
57
+ if input.ndim != 2 or weight.ndim != 3:
58
+ raise RuntimeError("invalid grouped GEMM tensor shapes")
59
+ return torch.empty(
60
+ (input.shape[0], weight.shape[1]), device=input.device, dtype=torch.bfloat16
61
+ )
62
+
63
+
64
+ def grouped_nvfp4_gemm_bf16(
65
+ input,
66
+ weight,
67
+ input_scale,
68
+ weight_scale,
69
+ alpha,
70
+ tile_expert,
71
+ *,
72
+ tile_rows,
73
+ input_scale_stride=0,
74
+ weight_stride=None,
75
+ weight_scale_stride=None,
76
+ out=None,
77
+ ):
78
+ """Compute expert-selected packed NVFP4 GEMM tiles with BF16 output."""
79
+ if weight_stride is None:
80
+ weight_stride = weight[0].numel()
81
+ if weight_scale_stride is None:
82
+ weight_scale_stride = weight_scale[0].numel()
83
+ if out is None:
84
+ return _compileable(
85
+ input,
86
+ weight,
87
+ input_scale,
88
+ weight_scale,
89
+ alpha,
90
+ tile_expert,
91
+ int(tile_rows),
92
+ int(input_scale_stride),
93
+ int(weight_stride),
94
+ int(weight_scale_stride),
95
+ )
96
+ ops.grouped_nvfp4_gemm_bf16_out(
97
+ input,
98
+ weight,
99
+ input_scale,
100
+ weight_scale,
101
+ alpha,
102
+ tile_expert,
103
+ int(tile_rows),
104
+ int(input_scale_stride),
105
+ int(weight_stride),
106
+ int(weight_scale_stride),
107
+ out,
108
+ )
109
+ return out
110
+
111
+
112
+ __all__ = ["grouped_nvfp4_gemm_bf16"]
build/torch212-cxx11-cu130-x86_64-linux/_grouped_moe_gemm_cuda_32e9b2c.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b0b5048bcc55227f23f3606ffc6fe52cd8359293104c6f0e5cee8865813aaf62
3
+ size 194088
build/torch212-cxx11-cu130-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _grouped_moe_gemm_cuda_32e9b2c
3
+ ops = torch.ops._grouped_moe_gemm_cuda_32e9b2c
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_grouped_moe_gemm_cuda_32e9b2c::{op_name}"
build/torch212-cxx11-cu130-x86_64-linux/grouped_moe_gemm/__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/metadata.json ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "grouped-moe-gemm",
3
+ "id": "_grouped_moe_gemm_cuda_32e9b2c",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "12.0a"
11
+ ]
12
+ },
13
+ "digest": {
14
+ "algorithm": "sha256",
15
+ "files": {
16
+ "__init__.py": "/pd/JqQCw5Ie4nddrEvVeqaOFtlbkqNDqykgQLlZJF0=",
17
+ "_grouped_moe_gemm_cuda_32e9b2c.abi3.so": "sLUEi8xVIn8j82Bv/G/lLNg1kpMQTG8OXO6IZYE6r2I=",
18
+ "_ops.py": "AxmxTU/RwyGFkTVT0IV6Y0/bjHdcILOm6O5JNy/zf6k=",
19
+ "grouped_moe_gemm/__init__.py": "DFYPlrhXwYjEqCl/8n0SmWGZV8NFml5DPhMjKfv98GY="
20
+ }
21
+ },
22
+ "provenance": {
23
+ "kernel-builder": {
24
+ "version": "0.17.0-dev0",
25
+ "sha": "19aaa6421e674e9fecc352bbae6eab81d19a6bf4",
26
+ "dirty": false
27
+ },
28
+ "kernel": {
29
+ "sha": "32e9b2c39ee268d8a76fcfef667974a13022c283",
30
+ "dirty": false
31
+ }
32
+ }
33
+ }
build/torch212-cxx11-cu132-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Grouped NVFP4 MoE GEMM for Blackwell prefill workloads."""
2
+
3
+ from __future__ import annotations
4
+ import torch
5
+ from ._ops import add_op_namespace_prefix, ops
6
+
7
+
8
+ @torch.library.custom_op(
9
+ add_op_namespace_prefix("_grouped_nvfp4_gemm_bf16"),
10
+ mutates_args=(),
11
+ device_types="cuda",
12
+ )
13
+ def _compileable(
14
+ input: torch.Tensor,
15
+ weight: torch.Tensor,
16
+ input_scale: torch.Tensor,
17
+ weight_scale: torch.Tensor,
18
+ alpha: torch.Tensor,
19
+ tile_expert: torch.Tensor,
20
+ tile_rows: int,
21
+ input_scale_stride: int,
22
+ weight_stride: int,
23
+ weight_scale_stride: int,
24
+ ) -> torch.Tensor:
25
+ output = torch.empty(
26
+ (input.shape[0], weight.shape[1]), device=input.device, dtype=torch.bfloat16
27
+ )
28
+ ops.grouped_nvfp4_gemm_bf16_out(
29
+ input,
30
+ weight,
31
+ input_scale,
32
+ weight_scale,
33
+ alpha,
34
+ tile_expert,
35
+ tile_rows,
36
+ input_scale_stride,
37
+ weight_stride,
38
+ weight_scale_stride,
39
+ output,
40
+ )
41
+ return output
42
+
43
+
44
+ @torch.library.register_fake(add_op_namespace_prefix("_grouped_nvfp4_gemm_bf16"))
45
+ def _fake(
46
+ input,
47
+ weight,
48
+ input_scale,
49
+ weight_scale,
50
+ alpha,
51
+ tile_expert,
52
+ tile_rows,
53
+ input_scale_stride,
54
+ weight_stride,
55
+ weight_scale_stride,
56
+ ):
57
+ if input.ndim != 2 or weight.ndim != 3:
58
+ raise RuntimeError("invalid grouped GEMM tensor shapes")
59
+ return torch.empty(
60
+ (input.shape[0], weight.shape[1]), device=input.device, dtype=torch.bfloat16
61
+ )
62
+
63
+
64
+ def grouped_nvfp4_gemm_bf16(
65
+ input,
66
+ weight,
67
+ input_scale,
68
+ weight_scale,
69
+ alpha,
70
+ tile_expert,
71
+ *,
72
+ tile_rows,
73
+ input_scale_stride=0,
74
+ weight_stride=None,
75
+ weight_scale_stride=None,
76
+ out=None,
77
+ ):
78
+ """Compute expert-selected packed NVFP4 GEMM tiles with BF16 output."""
79
+ if weight_stride is None:
80
+ weight_stride = weight[0].numel()
81
+ if weight_scale_stride is None:
82
+ weight_scale_stride = weight_scale[0].numel()
83
+ if out is None:
84
+ return _compileable(
85
+ input,
86
+ weight,
87
+ input_scale,
88
+ weight_scale,
89
+ alpha,
90
+ tile_expert,
91
+ int(tile_rows),
92
+ int(input_scale_stride),
93
+ int(weight_stride),
94
+ int(weight_scale_stride),
95
+ )
96
+ ops.grouped_nvfp4_gemm_bf16_out(
97
+ input,
98
+ weight,
99
+ input_scale,
100
+ weight_scale,
101
+ alpha,
102
+ tile_expert,
103
+ int(tile_rows),
104
+ int(input_scale_stride),
105
+ int(weight_stride),
106
+ int(weight_scale_stride),
107
+ out,
108
+ )
109
+ return out
110
+
111
+
112
+ __all__ = ["grouped_nvfp4_gemm_bf16"]
build/torch212-cxx11-cu132-x86_64-linux/_grouped_moe_gemm_cuda_32e9b2c.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bceb0dc19dbe93563d630998a23384b2fe27896c9b72f5488886bac02c2cc471
3
+ size 194144
build/torch212-cxx11-cu132-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _grouped_moe_gemm_cuda_32e9b2c
3
+ ops = torch.ops._grouped_moe_gemm_cuda_32e9b2c
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_grouped_moe_gemm_cuda_32e9b2c::{op_name}"
build/torch212-cxx11-cu132-x86_64-linux/grouped_moe_gemm/__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/metadata.json ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "grouped-moe-gemm",
3
+ "id": "_grouped_moe_gemm_cuda_32e9b2c",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "12.0a"
11
+ ]
12
+ },
13
+ "digest": {
14
+ "algorithm": "sha256",
15
+ "files": {
16
+ "__init__.py": "/pd/JqQCw5Ie4nddrEvVeqaOFtlbkqNDqykgQLlZJF0=",
17
+ "_grouped_moe_gemm_cuda_32e9b2c.abi3.so": "vOsNwZ2+k1Y9YwmYojOEsv4niWybcvVIiIa6wCwsxHE=",
18
+ "_ops.py": "AxmxTU/RwyGFkTVT0IV6Y0/bjHdcILOm6O5JNy/zf6k=",
19
+ "grouped_moe_gemm/__init__.py": "DFYPlrhXwYjEqCl/8n0SmWGZV8NFml5DPhMjKfv98GY="
20
+ }
21
+ },
22
+ "provenance": {
23
+ "kernel-builder": {
24
+ "version": "0.17.0-dev0",
25
+ "sha": "19aaa6421e674e9fecc352bbae6eab81d19a6bf4",
26
+ "dirty": false
27
+ },
28
+ "kernel": {
29
+ "sha": "32e9b2c39ee268d8a76fcfef667974a13022c283",
30
+ "dirty": false
31
+ }
32
+ }
33
+ }
build/torch213-cxx11-cu130-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Grouped NVFP4 MoE GEMM for Blackwell prefill workloads."""
2
+
3
+ from __future__ import annotations
4
+ import torch
5
+ from ._ops import add_op_namespace_prefix, ops
6
+
7
+
8
+ @torch.library.custom_op(
9
+ add_op_namespace_prefix("_grouped_nvfp4_gemm_bf16"),
10
+ mutates_args=(),
11
+ device_types="cuda",
12
+ )
13
+ def _compileable(
14
+ input: torch.Tensor,
15
+ weight: torch.Tensor,
16
+ input_scale: torch.Tensor,
17
+ weight_scale: torch.Tensor,
18
+ alpha: torch.Tensor,
19
+ tile_expert: torch.Tensor,
20
+ tile_rows: int,
21
+ input_scale_stride: int,
22
+ weight_stride: int,
23
+ weight_scale_stride: int,
24
+ ) -> torch.Tensor:
25
+ output = torch.empty(
26
+ (input.shape[0], weight.shape[1]), device=input.device, dtype=torch.bfloat16
27
+ )
28
+ ops.grouped_nvfp4_gemm_bf16_out(
29
+ input,
30
+ weight,
31
+ input_scale,
32
+ weight_scale,
33
+ alpha,
34
+ tile_expert,
35
+ tile_rows,
36
+ input_scale_stride,
37
+ weight_stride,
38
+ weight_scale_stride,
39
+ output,
40
+ )
41
+ return output
42
+
43
+
44
+ @torch.library.register_fake(add_op_namespace_prefix("_grouped_nvfp4_gemm_bf16"))
45
+ def _fake(
46
+ input,
47
+ weight,
48
+ input_scale,
49
+ weight_scale,
50
+ alpha,
51
+ tile_expert,
52
+ tile_rows,
53
+ input_scale_stride,
54
+ weight_stride,
55
+ weight_scale_stride,
56
+ ):
57
+ if input.ndim != 2 or weight.ndim != 3:
58
+ raise RuntimeError("invalid grouped GEMM tensor shapes")
59
+ return torch.empty(
60
+ (input.shape[0], weight.shape[1]), device=input.device, dtype=torch.bfloat16
61
+ )
62
+
63
+
64
+ def grouped_nvfp4_gemm_bf16(
65
+ input,
66
+ weight,
67
+ input_scale,
68
+ weight_scale,
69
+ alpha,
70
+ tile_expert,
71
+ *,
72
+ tile_rows,
73
+ input_scale_stride=0,
74
+ weight_stride=None,
75
+ weight_scale_stride=None,
76
+ out=None,
77
+ ):
78
+ """Compute expert-selected packed NVFP4 GEMM tiles with BF16 output."""
79
+ if weight_stride is None:
80
+ weight_stride = weight[0].numel()
81
+ if weight_scale_stride is None:
82
+ weight_scale_stride = weight_scale[0].numel()
83
+ if out is None:
84
+ return _compileable(
85
+ input,
86
+ weight,
87
+ input_scale,
88
+ weight_scale,
89
+ alpha,
90
+ tile_expert,
91
+ int(tile_rows),
92
+ int(input_scale_stride),
93
+ int(weight_stride),
94
+ int(weight_scale_stride),
95
+ )
96
+ ops.grouped_nvfp4_gemm_bf16_out(
97
+ input,
98
+ weight,
99
+ input_scale,
100
+ weight_scale,
101
+ alpha,
102
+ tile_expert,
103
+ int(tile_rows),
104
+ int(input_scale_stride),
105
+ int(weight_stride),
106
+ int(weight_scale_stride),
107
+ out,
108
+ )
109
+ return out
110
+
111
+
112
+ __all__ = ["grouped_nvfp4_gemm_bf16"]
build/torch213-cxx11-cu130-x86_64-linux/_grouped_moe_gemm_cuda_32e9b2c.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3cb23ee178877d6ab527694d23c227f9ed6272fd48f8befa080b15107ef6e2a6
3
+ size 193928
build/torch213-cxx11-cu130-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _grouped_moe_gemm_cuda_32e9b2c
3
+ ops = torch.ops._grouped_moe_gemm_cuda_32e9b2c
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_grouped_moe_gemm_cuda_32e9b2c::{op_name}"
build/torch213-cxx11-cu130-x86_64-linux/grouped_moe_gemm/__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/torch213-cxx11-cu130-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "grouped-moe-gemm",
3
+ "id": "_grouped_moe_gemm_cuda_32e9b2c",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "12.0a"
11
+ ]
12
+ },
13
+ "digest": {
14
+ "algorithm": "sha256",
15
+ "files": {
16
+ "__init__.py": "/pd/JqQCw5Ie4nddrEvVeqaOFtlbkqNDqykgQLlZJF0=",
17
+ "_grouped_moe_gemm_cuda_32e9b2c.abi3.so": "PLI+4XiHfWq1J2lNI8In+e1icv1I+L76CAsVEH724qY=",
18
+ "_ops.py": "AxmxTU/RwyGFkTVT0IV6Y0/bjHdcILOm6O5JNy/zf6k=",
19
+ "grouped_moe_gemm/__init__.py": "DFYPlrhXwYjEqCl/8n0SmWGZV8NFml5DPhMjKfv98GY="
20
+ }
21
+ },
22
+ "provenance": {
23
+ "kernel-builder": {
24
+ "version": "0.17.0-dev0",
25
+ "sha": "19aaa6421e674e9fecc352bbae6eab81d19a6bf4",
26
+ "dirty": false
27
+ },
28
+ "kernel": {
29
+ "sha": "32e9b2c39ee268d8a76fcfef667974a13022c283",
30
+ "dirty": false
31
+ }
32
+ }
33
+ }
build/torch213-cxx11-cu132-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Grouped NVFP4 MoE GEMM for Blackwell prefill workloads."""
2
+
3
+ from __future__ import annotations
4
+ import torch
5
+ from ._ops import add_op_namespace_prefix, ops
6
+
7
+
8
+ @torch.library.custom_op(
9
+ add_op_namespace_prefix("_grouped_nvfp4_gemm_bf16"),
10
+ mutates_args=(),
11
+ device_types="cuda",
12
+ )
13
+ def _compileable(
14
+ input: torch.Tensor,
15
+ weight: torch.Tensor,
16
+ input_scale: torch.Tensor,
17
+ weight_scale: torch.Tensor,
18
+ alpha: torch.Tensor,
19
+ tile_expert: torch.Tensor,
20
+ tile_rows: int,
21
+ input_scale_stride: int,
22
+ weight_stride: int,
23
+ weight_scale_stride: int,
24
+ ) -> torch.Tensor:
25
+ output = torch.empty(
26
+ (input.shape[0], weight.shape[1]), device=input.device, dtype=torch.bfloat16
27
+ )
28
+ ops.grouped_nvfp4_gemm_bf16_out(
29
+ input,
30
+ weight,
31
+ input_scale,
32
+ weight_scale,
33
+ alpha,
34
+ tile_expert,
35
+ tile_rows,
36
+ input_scale_stride,
37
+ weight_stride,
38
+ weight_scale_stride,
39
+ output,
40
+ )
41
+ return output
42
+
43
+
44
+ @torch.library.register_fake(add_op_namespace_prefix("_grouped_nvfp4_gemm_bf16"))
45
+ def _fake(
46
+ input,
47
+ weight,
48
+ input_scale,
49
+ weight_scale,
50
+ alpha,
51
+ tile_expert,
52
+ tile_rows,
53
+ input_scale_stride,
54
+ weight_stride,
55
+ weight_scale_stride,
56
+ ):
57
+ if input.ndim != 2 or weight.ndim != 3:
58
+ raise RuntimeError("invalid grouped GEMM tensor shapes")
59
+ return torch.empty(
60
+ (input.shape[0], weight.shape[1]), device=input.device, dtype=torch.bfloat16
61
+ )
62
+
63
+
64
+ def grouped_nvfp4_gemm_bf16(
65
+ input,
66
+ weight,
67
+ input_scale,
68
+ weight_scale,
69
+ alpha,
70
+ tile_expert,
71
+ *,
72
+ tile_rows,
73
+ input_scale_stride=0,
74
+ weight_stride=None,
75
+ weight_scale_stride=None,
76
+ out=None,
77
+ ):
78
+ """Compute expert-selected packed NVFP4 GEMM tiles with BF16 output."""
79
+ if weight_stride is None:
80
+ weight_stride = weight[0].numel()
81
+ if weight_scale_stride is None:
82
+ weight_scale_stride = weight_scale[0].numel()
83
+ if out is None:
84
+ return _compileable(
85
+ input,
86
+ weight,
87
+ input_scale,
88
+ weight_scale,
89
+ alpha,
90
+ tile_expert,
91
+ int(tile_rows),
92
+ int(input_scale_stride),
93
+ int(weight_stride),
94
+ int(weight_scale_stride),
95
+ )
96
+ ops.grouped_nvfp4_gemm_bf16_out(
97
+ input,
98
+ weight,
99
+ input_scale,
100
+ weight_scale,
101
+ alpha,
102
+ tile_expert,
103
+ int(tile_rows),
104
+ int(input_scale_stride),
105
+ int(weight_stride),
106
+ int(weight_scale_stride),
107
+ out,
108
+ )
109
+ return out
110
+
111
+
112
+ __all__ = ["grouped_nvfp4_gemm_bf16"]
build/torch213-cxx11-cu132-x86_64-linux/_grouped_moe_gemm_cuda_32e9b2c.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:aaa4d78336ddd1b195d8cb02d379da8e4b253d756a0624228f910a79382dae95
3
+ size 193984
build/torch213-cxx11-cu132-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _grouped_moe_gemm_cuda_32e9b2c
3
+ ops = torch.ops._grouped_moe_gemm_cuda_32e9b2c
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_grouped_moe_gemm_cuda_32e9b2c::{op_name}"
build/torch213-cxx11-cu132-x86_64-linux/grouped_moe_gemm/__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/torch213-cxx11-cu132-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "grouped-moe-gemm",
3
+ "id": "_grouped_moe_gemm_cuda_32e9b2c",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "12.0a"
11
+ ]
12
+ },
13
+ "digest": {
14
+ "algorithm": "sha256",
15
+ "files": {
16
+ "__init__.py": "/pd/JqQCw5Ie4nddrEvVeqaOFtlbkqNDqykgQLlZJF0=",
17
+ "_grouped_moe_gemm_cuda_32e9b2c.abi3.so": "qqTXgzbd0bGV2MsC03najkslPXVqBiQij5EKeTgtrpU=",
18
+ "_ops.py": "AxmxTU/RwyGFkTVT0IV6Y0/bjHdcILOm6O5JNy/zf6k=",
19
+ "grouped_moe_gemm/__init__.py": "DFYPlrhXwYjEqCl/8n0SmWGZV8NFml5DPhMjKfv98GY="
20
+ }
21
+ },
22
+ "provenance": {
23
+ "kernel-builder": {
24
+ "version": "0.17.0-dev0",
25
+ "sha": "19aaa6421e674e9fecc352bbae6eab81d19a6bf4",
26
+ "dirty": false
27
+ },
28
+ "kernel": {
29
+ "sha": "32e9b2c39ee268d8a76fcfef667974a13022c283",
30
+ "dirty": false
31
+ }
32
+ }
33
+ }