liangsu9988 commited on
Commit
fef614d
·
verified ·
1 Parent(s): 83fd86e

Promote latest kernel artifacts to main

Browse files
Files changed (43) hide show
  1. .gitattributes +3 -35
  2. README.md +0 -9
  3. benchmarks/benchmark.py +460 -0
  4. build/torch211-cxx11-cu128-x86_64-linux/__init__.py +261 -0
  5. build/torch211-cxx11-cu128-x86_64-linux/_ops.py +9 -0
  6. build/torch211-cxx11-cu128-x86_64-linux/_weight_only_ffn_cuda_38d37b6.abi3.so +3 -0
  7. build/torch211-cxx11-cu128-x86_64-linux/metadata.json +33 -0
  8. build/torch211-cxx11-cu128-x86_64-linux/weight_only_ffn/__init__.py +26 -0
  9. build/torch211-cxx11-cu130-aarch64-linux/__init__.py +261 -0
  10. build/torch211-cxx11-cu130-aarch64-linux/_ops.py +9 -0
  11. build/torch211-cxx11-cu130-aarch64-linux/_weight_only_ffn_cuda_38d37b6.abi3.so +3 -0
  12. build/torch211-cxx11-cu130-aarch64-linux/metadata.json +26 -0
  13. build/torch211-cxx11-cu130-aarch64-linux/weight_only_ffn/__init__.py +26 -0
  14. build/torch211-cxx11-cu130-x86_64-linux/__init__.py +261 -0
  15. build/torch211-cxx11-cu130-x86_64-linux/_ops.py +9 -0
  16. build/torch211-cxx11-cu130-x86_64-linux/_weight_only_ffn_cuda_38d37b6.abi3.so +3 -0
  17. build/torch211-cxx11-cu130-x86_64-linux/metadata.json +35 -0
  18. build/torch211-cxx11-cu130-x86_64-linux/weight_only_ffn/__init__.py +26 -0
  19. build/torch212-cxx11-cu130-x86_64-linux/__init__.py +261 -0
  20. build/torch212-cxx11-cu130-x86_64-linux/_ops.py +9 -0
  21. build/torch212-cxx11-cu130-x86_64-linux/_weight_only_ffn_cuda_38d37b6.abi3.so +3 -0
  22. build/torch212-cxx11-cu130-x86_64-linux/metadata.json +35 -0
  23. build/torch212-cxx11-cu130-x86_64-linux/weight_only_ffn/__init__.py +26 -0
  24. build/torch212-cxx11-cu132-x86_64-linux/__init__.py +261 -0
  25. build/torch212-cxx11-cu132-x86_64-linux/_ops.py +9 -0
  26. build/torch212-cxx11-cu132-x86_64-linux/_weight_only_ffn_cuda_38d37b6.abi3.so +3 -0
  27. build/torch212-cxx11-cu132-x86_64-linux/metadata.json +35 -0
  28. build/torch212-cxx11-cu132-x86_64-linux/weight_only_ffn/__init__.py +26 -0
  29. build/torch213-cxx11-cu130-aarch64-linux/__init__.py +261 -0
  30. build/torch213-cxx11-cu130-aarch64-linux/_ops.py +6 -0
  31. build/torch213-cxx11-cu130-aarch64-linux/metadata.json +32 -0
  32. build/torch213-cxx11-cu130-aarch64-linux/weight_only_ffn/__init__.py +14 -0
  33. build/torch213-cxx11-cu130-aarch64-linux/weight_only_ffn_source_test.abi3.so +3 -0
  34. build/torch213-cxx11-cu130-x86_64-linux/__init__.py +261 -0
  35. build/torch213-cxx11-cu130-x86_64-linux/_ops.py +9 -0
  36. build/torch213-cxx11-cu130-x86_64-linux/_weight_only_ffn_cuda_38d37b6.abi3.so +3 -0
  37. build/torch213-cxx11-cu130-x86_64-linux/metadata.json +35 -0
  38. build/torch213-cxx11-cu130-x86_64-linux/weight_only_ffn/__init__.py +26 -0
  39. build/torch213-cxx11-cu132-x86_64-linux/__init__.py +261 -0
  40. build/torch213-cxx11-cu132-x86_64-linux/_ops.py +9 -0
  41. build/torch213-cxx11-cu132-x86_64-linux/_weight_only_ffn_cuda_38d37b6.abi3.so +3 -0
  42. build/torch213-cxx11-cu132-x86_64-linux/metadata.json +35 -0
  43. build/torch213-cxx11-cu132-x86_64-linux/weight_only_ffn/__init__.py +26 -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/weight-only-ffn
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/weight-only-ffn
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,460 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Tile/variant benchmark for the production M<=4 weight-only domain."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import importlib
8
+ import json
9
+ import os
10
+ import statistics
11
+ import sys
12
+ from pathlib import Path
13
+
14
+ import torch
15
+ import torch.nn.functional as F
16
+
17
+
18
+ SHAPES = {
19
+ "llm_m1": (1, 4096, 11008, 4096),
20
+ "llm_m2": (2, 4096, 11008, 4096),
21
+ "llm_m3": (3, 4096, 11008, 4096),
22
+ "llm_m4": (4, 4096, 11008, 4096),
23
+ "vla_m1": (1, 1024, 4096, 1024),
24
+ "vla_m2": (2, 1024, 4096, 1024),
25
+ "vla_m4": (4, 1024, 4096, 1024),
26
+ "vision_m1": (1, 1536, 6144, 1536),
27
+ "vision_m2": (2, 1536, 6144, 1536),
28
+ "vision_m4": (4, 1536, 6144, 1536),
29
+ }
30
+
31
+ LINEAR_SHAPES = {
32
+ "llm_square_m1": (1, 4096, 4096),
33
+ "llm_wide_m1": (1, 4096, 11008),
34
+ "vla_wide_m1": (1, 1024, 4096),
35
+ "vision_wide_m1": (1, 1536, 6144),
36
+ "llm_square_m2": (2, 4096, 4096),
37
+ "llm_wide_m2": (2, 4096, 11008),
38
+ "vla_wide_m2": (2, 1024, 4096),
39
+ "vision_wide_m2": (2, 1536, 6144),
40
+ }
41
+
42
+
43
+ def bench(fn, warmup: int, iterations: int, repeats: int = 3) -> float:
44
+ for _ in range(warmup):
45
+ fn()
46
+ torch.cuda.synchronize()
47
+ samples = []
48
+ for _ in range(repeats):
49
+ start = torch.cuda.Event(enable_timing=True)
50
+ end = torch.cuda.Event(enable_timing=True)
51
+ start.record()
52
+ for _ in range(iterations):
53
+ fn()
54
+ end.record()
55
+ torch.cuda.synchronize()
56
+ samples.append(float(start.elapsed_time(end) * 1000.0 / iterations))
57
+ return statistics.median(samples)
58
+
59
+
60
+ def sfb_bytes(rows: int, cols: int) -> int:
61
+ return ((rows + 127) // 128) * (((cols // 16) + 3) // 4) * 512
62
+
63
+
64
+ class SourceModule:
65
+ def __init__(self, ops) -> None:
66
+ self.ops = ops
67
+
68
+ def quantize_w4_weight_bf16(self, weight):
69
+ n, k = weight.shape
70
+ packed = torch.empty((n, k // 2), device="cuda", dtype=torch.uint8)
71
+ scale = torch.empty((sfb_bytes(n, k),), device="cuda", dtype=torch.uint8)
72
+ self.ops.quantize_w4_weight_bf16(weight, packed, scale)
73
+ return packed, scale
74
+
75
+ def dequantize_w4_weight_bf16(self, packed, scale, *, cols):
76
+ out = torch.empty((packed.shape[0], cols), device="cuda", dtype=torch.bfloat16)
77
+ self.ops.dequantize_w4_weight_bf16(packed, scale, out)
78
+ return out
79
+
80
+ def quantize_w8_weight_bf16(self, weight):
81
+ packed = torch.empty_like(weight, dtype=torch.int8)
82
+ scale = torch.empty((weight.shape[0],), device="cuda", dtype=torch.float32)
83
+ self.ops.quantize_w8_weight_bf16(weight, packed, scale)
84
+ return packed, scale
85
+
86
+ def dequantize_w8_weight_bf16(self, packed, scale):
87
+ out = torch.empty_like(packed, dtype=torch.bfloat16)
88
+ self.ops.dequantize_w8_weight_bf16(packed, scale, out)
89
+ return out
90
+
91
+ def w4a16_linear_bf16(self, x, weight, scale, *, variant=0, out=None):
92
+ if out is None:
93
+ out = torch.empty(
94
+ (x.shape[0], weight.shape[0]), device=x.device,
95
+ dtype=torch.bfloat16,
96
+ )
97
+ self.ops.w4a16_linear_bf16(
98
+ x, weight, scale, 1.0, variant, out,
99
+ )
100
+ return out
101
+
102
+ def w8a16_linear_bf16(self, x, weight, scale, *, variant=0, out=None):
103
+ if out is None:
104
+ out = torch.empty(
105
+ (x.shape[0], weight.shape[0]), device=x.device,
106
+ dtype=torch.bfloat16,
107
+ )
108
+ self.ops.w8a16_linear_bf16(x, weight, scale, variant, out)
109
+ return out
110
+
111
+ def _gated(self, bits, x, gu_w, gu_s, dn_w, dn_s, *, gelu,
112
+ gate_up_bias, down_bias, variant, workspace, out):
113
+ gu, hidden = workspace
114
+ if bits == 4:
115
+ self.ops.w4a16_gated_ffn_bf16(
116
+ x, gu_w, gu_s, dn_w, dn_s, gate_up_bias, down_bias,
117
+ gelu, 1.0, 1.0, variant, gu, hidden, out,
118
+ )
119
+ else:
120
+ self.ops.w8a16_gated_ffn_bf16(
121
+ x, gu_w, gu_s, dn_w, dn_s, gate_up_bias, down_bias,
122
+ gelu, variant, gu, hidden, out,
123
+ )
124
+ return out
125
+
126
+ def w4a16_swiglu_ffn_bf16(self, *args, **kwargs):
127
+ return self._gated(4, *args, gelu=False, **kwargs)
128
+
129
+ def w4a16_geglu_ffn_bf16(self, *args, **kwargs):
130
+ return self._gated(4, *args, gelu=True, **kwargs)
131
+
132
+ def w8a16_swiglu_ffn_bf16(self, *args, **kwargs):
133
+ return self._gated(8, *args, gelu=False, **kwargs)
134
+
135
+ def w8a16_geglu_ffn_bf16(self, *args, **kwargs):
136
+ return self._gated(8, *args, gelu=True, **kwargs)
137
+
138
+ def _gelu(self, bits, x, up_w, up_s, dn_w, dn_s, *, up_bias,
139
+ down_bias, variant, workspace, out):
140
+ up, hidden = workspace
141
+ if bits == 4:
142
+ self.ops.w4a16_gelu_ffn_bf16(
143
+ x, up_w, up_s, dn_w, dn_s, up_bias, down_bias,
144
+ 1.0, 1.0, variant, up, hidden, out,
145
+ )
146
+ else:
147
+ self.ops.w8a16_gelu_ffn_bf16(
148
+ x, up_w, up_s, dn_w, dn_s, up_bias, down_bias,
149
+ variant, up, hidden, out,
150
+ )
151
+ return out
152
+
153
+ def w4a16_gelu_ffn_bf16(self, *args, **kwargs):
154
+ return self._gelu(4, *args, **kwargs)
155
+
156
+ def w8a16_gelu_ffn_bf16(self, *args, **kwargs):
157
+ return self._gelu(8, *args, **kwargs)
158
+
159
+
160
+ def load_source_module():
161
+ from torch.utils.cpp_extension import load
162
+
163
+ root = Path(__file__).resolve().parents[1]
164
+ registration = root.parent.parent / "kernels" / "kernel-builder" / "src" / "pyproject" / "templates" / "torch"
165
+ major, minor = torch.cuda.get_device_capability(0)
166
+ if major == 11 and minor == 0:
167
+ arch = "11.0a"
168
+ elif major == 12 and minor == 1:
169
+ arch = "12.1"
170
+ elif major >= 12:
171
+ arch = "12.0a"
172
+ else:
173
+ raise RuntimeError("source benchmark requires Blackwell SM110/SM120/SM121")
174
+ os.environ.setdefault("TORCH_CUDA_ARCH_LIST", arch)
175
+ namespace = "weight_only_ffn_benchmark_source"
176
+ load(
177
+ name=namespace,
178
+ sources=[str(root / path) for path in [
179
+ "torch-ext/torch_binding.cpp", "csrc/w4_weight_only.cu",
180
+ "csrc/w4a16_gemm_sm120.cu", "csrc/w4a16_matvec_sm120.cu",
181
+ "csrc/w8_weight_only.cu", "csrc/ffn_epilogues.cu",
182
+ ]],
183
+ extra_include_paths=[str(root / "csrc"), str(registration)],
184
+ extra_cflags=["-O3", "-std=c++17", "-DCUDA_KERNEL"],
185
+ extra_cuda_cflags=["-O3", "-std=c++17", "-DCUDA_KERNEL", "--use_fast_math"],
186
+ is_python_module=False,
187
+ verbose=False,
188
+ )
189
+ return SourceModule(getattr(torch.ops, namespace))
190
+
191
+
192
+ def load_module(backend: str, artifact: str | None):
193
+ if backend == "source":
194
+ return load_source_module()
195
+ if artifact:
196
+ sys.path.insert(0, artifact)
197
+ try:
198
+ return importlib.import_module("weight_only_ffn")
199
+ finally:
200
+ if artifact:
201
+ sys.path.remove(artifact)
202
+
203
+
204
+ def quantize(module, bits: int, weight: torch.Tensor):
205
+ if bits == 4:
206
+ packed, scale = module.quantize_w4_weight_bf16(weight)
207
+ dequant = module.dequantize_w4_weight_bf16(packed, scale, cols=weight.shape[1])
208
+ else:
209
+ packed, scale = module.quantize_w8_weight_bf16(weight)
210
+ dequant = module.dequantize_w8_weight_bf16(packed, scale)
211
+ return packed, scale, dequant
212
+
213
+
214
+ def run_case(module, name: str, shape, bits: int, activation: str,
215
+ warmup: int, iterations: int):
216
+ m, k, h, n = shape
217
+ gated = activation in {"swiglu", "geglu"}
218
+ up_rows = 2 * h if gated else h
219
+ generator = torch.Generator(device="cuda").manual_seed(
220
+ 91000 + m + k + h + n + bits + len(activation)
221
+ )
222
+ x = (torch.randn((m, k), generator=generator, device="cuda") * 0.1).bfloat16()
223
+ up_weight = (torch.randn((up_rows, k), generator=generator, device="cuda") * 0.02).bfloat16()
224
+ down_weight = (torch.randn((n, h), generator=generator, device="cuda") * 0.02).bfloat16()
225
+ up_bias = (torch.randn((up_rows,), generator=generator, device="cuda") * 0.01).bfloat16()
226
+ down_bias = (torch.randn((n,), generator=generator, device="cuda") * 0.01).bfloat16()
227
+ up_packed, up_scale, up_dequant = quantize(module, bits, up_weight)
228
+ down_packed, down_scale, down_dequant = quantize(module, bits, down_weight)
229
+ first = torch.empty((m, up_rows), device="cuda", dtype=torch.bfloat16)
230
+ hidden = torch.empty((m, h), device="cuda", dtype=torch.bfloat16)
231
+ out = torch.empty((m, n), device="cuda", dtype=torch.bfloat16)
232
+
233
+ if gated:
234
+ fn_name = f"w{bits}a16_{activation}_ffn_bf16"
235
+ kernel_fn = getattr(module, fn_name)
236
+
237
+ def kernel(variant: int):
238
+ return kernel_fn(
239
+ x, up_packed, up_scale, down_packed, down_scale,
240
+ gate_up_bias=up_bias, down_bias=down_bias, variant=variant,
241
+ workspace=(first, hidden), out=out,
242
+ )
243
+
244
+ def reference():
245
+ merged = F.linear(x, up_dequant, up_bias)
246
+ gate, up = merged.split(h, dim=-1)
247
+ act = F.silu(gate) if activation == "swiglu" else F.gelu(gate, approximate="tanh")
248
+ return F.linear(act * up, down_dequant, down_bias)
249
+ else:
250
+ fn_name = f"w{bits}a16_gelu_ffn_bf16"
251
+ kernel_fn = getattr(module, fn_name)
252
+
253
+ def kernel(variant: int):
254
+ return kernel_fn(
255
+ x, up_packed, up_scale, down_packed, down_scale,
256
+ up_bias=up_bias, down_bias=down_bias, variant=variant,
257
+ workspace=(first, hidden), out=out,
258
+ )
259
+
260
+ def reference():
261
+ return F.linear(
262
+ F.gelu(F.linear(x, up_dequant, up_bias), approximate="tanh"),
263
+ down_dequant, down_bias,
264
+ )
265
+
266
+ eager_us = bench(reference, warmup, iterations)
267
+ compiled = torch.compile(reference, fullgraph=True, mode="max-autotune-no-cudagraphs")
268
+ compiled()
269
+ torch.cuda.synchronize()
270
+ compiled_us = bench(compiled, warmup, iterations)
271
+ variants = {
272
+ str(variant): bench(
273
+ lambda variant=variant: kernel(variant), warmup, iterations
274
+ )
275
+ for variant in (1, 2, 3)
276
+ }
277
+ auto_error = None
278
+ try:
279
+ auto_us = bench(lambda: kernel(0), warmup, iterations)
280
+ kernel(0)
281
+ except RuntimeError as exc:
282
+ if "not qualified" not in str(exc) and "no qualified fast path" not in str(exc):
283
+ raise
284
+ auto_us = None
285
+ auto_error = str(exc)
286
+ best_diagnostic_variant = min(variants, key=variants.get)
287
+ kernel(int(best_diagnostic_variant))
288
+ ref = reference()
289
+ torch.cuda.synchronize()
290
+ diff = (out.float() - ref.float()).abs().flatten()
291
+ cosine = F.cosine_similarity(out.float().flatten(), ref.float().flatten(), dim=0)
292
+ best_diagnostic_variant = min(variants, key=variants.get)
293
+ best_diagnostic_us = variants[best_diagnostic_variant]
294
+ if auto_us is not None and auto_us > best_diagnostic_us * 1.05:
295
+ raise AssertionError(
296
+ f"{name} W{bits}A16 {activation}: auto {auto_us:.3f} us is more "
297
+ f"than 5% slower than diagnostic variant {best_diagnostic_variant} "
298
+ f"at {best_diagnostic_us:.3f} us"
299
+ )
300
+ if auto_us is not None and auto_us * 1.02 >= min(eager_us, compiled_us):
301
+ raise AssertionError(
302
+ f"{name} W{bits}A16 {activation}: accepted auto path must beat "
303
+ f"the strongest eager/compile baseline by at least 2%; "
304
+ f"auto={auto_us:.3f} us, eager={eager_us:.3f} us, "
305
+ f"compile={compiled_us:.3f} us"
306
+ )
307
+ return {
308
+ "region": "ffn",
309
+ "shape": name,
310
+ "M": m,
311
+ "K": k,
312
+ "H": h,
313
+ "N": n,
314
+ "precision": f"W{bits}A16",
315
+ "op": activation,
316
+ "eager_us": eager_us,
317
+ "compile_us": compiled_us,
318
+ "variant_us": variants,
319
+ "auto_status": "accepted" if auto_us is not None else "rejected",
320
+ "auto_us": auto_us,
321
+ "auto_error": auto_error,
322
+ "auto_speedup_vs_eager": eager_us / auto_us if auto_us is not None else None,
323
+ "auto_speedup_vs_compile": compiled_us / auto_us if auto_us is not None else None,
324
+ "best_diagnostic_variant": int(best_diagnostic_variant),
325
+ "best_diagnostic_us": best_diagnostic_us,
326
+ "max_abs": float(diff.max()),
327
+ "mean_abs": float(diff.mean()),
328
+ "p99_abs": float(torch.quantile(diff, 0.99)),
329
+ "cosine": float(cosine),
330
+ }
331
+
332
+
333
+ def run_linear_case(module, name: str, shape, bits: int, warmup: int,
334
+ iterations: int):
335
+ m, k, n = shape
336
+ generator = torch.Generator(device="cuda").manual_seed(
337
+ 92000 + m + k + n + bits
338
+ )
339
+ x = (torch.randn((m, k), generator=generator, device="cuda") * 0.1).bfloat16()
340
+ weight = (
341
+ torch.randn((n, k), generator=generator, device="cuda") * 0.02
342
+ ).bfloat16()
343
+ packed, scale, dequant = quantize(module, bits, weight)
344
+ out = torch.empty((m, n), device="cuda", dtype=torch.bfloat16)
345
+ linear = getattr(module, f"w{bits}a16_linear_bf16")
346
+
347
+ def kernel(variant: int):
348
+ return linear(x, packed, scale, variant=variant, out=out)
349
+
350
+ def reference():
351
+ return F.linear(x, dequant)
352
+
353
+ eager_us = bench(reference, warmup, iterations)
354
+ compiled = torch.compile(
355
+ reference, fullgraph=True, mode="max-autotune-no-cudagraphs"
356
+ )
357
+ compiled()
358
+ torch.cuda.synchronize()
359
+ compiled_us = bench(compiled, warmup, iterations)
360
+ variants = {
361
+ str(variant): bench(
362
+ lambda variant=variant: kernel(variant), warmup, iterations
363
+ )
364
+ for variant in (1, 2, 3)
365
+ }
366
+ auto_error = None
367
+ try:
368
+ auto_us = bench(lambda: kernel(0), warmup, iterations)
369
+ kernel(0)
370
+ except RuntimeError as exc:
371
+ if "no qualified fast path" not in str(exc):
372
+ raise
373
+ auto_us = None
374
+ auto_error = str(exc)
375
+ kernel(int(min(variants, key=variants.get)))
376
+ ref = reference()
377
+ torch.cuda.synchronize()
378
+ diff = (out.float() - ref.float()).abs().flatten()
379
+ cosine = F.cosine_similarity(
380
+ out.float().flatten(), ref.float().flatten(), dim=0
381
+ )
382
+ best_variant = min(variants, key=variants.get)
383
+ best_us = variants[best_variant]
384
+ if auto_us is not None and auto_us > best_us * 1.05:
385
+ raise AssertionError(
386
+ f"{name} W{bits}A16 linear: auto {auto_us:.3f} us is more than "
387
+ f"5% slower than diagnostic variant {best_variant} at {best_us:.3f} us"
388
+ )
389
+ if auto_us is not None and auto_us * 1.02 >= min(eager_us, compiled_us):
390
+ raise AssertionError(
391
+ f"{name} W{bits}A16 linear: accepted auto path must beat the "
392
+ f"strongest eager/compile baseline by at least 2%; "
393
+ f"auto={auto_us:.3f} us, eager={eager_us:.3f} us, "
394
+ f"compile={compiled_us:.3f} us"
395
+ )
396
+ return {
397
+ "region": "linear",
398
+ "shape": name,
399
+ "M": m,
400
+ "K": k,
401
+ "N": n,
402
+ "precision": f"W{bits}A16",
403
+ "op": "linear",
404
+ "eager_us": eager_us,
405
+ "compile_us": compiled_us,
406
+ "variant_us": variants,
407
+ "auto_status": "accepted" if auto_us is not None else "rejected",
408
+ "auto_us": auto_us,
409
+ "auto_error": auto_error,
410
+ "auto_speedup_vs_eager": eager_us / auto_us if auto_us else None,
411
+ "auto_speedup_vs_compile": compiled_us / auto_us if auto_us else None,
412
+ "best_diagnostic_variant": int(best_variant),
413
+ "best_diagnostic_us": best_us,
414
+ "max_abs": float(diff.max()),
415
+ "mean_abs": float(diff.mean()),
416
+ "p99_abs": float(torch.quantile(diff, 0.99)),
417
+ "cosine": float(cosine),
418
+ }
419
+
420
+
421
+ def main() -> int:
422
+ parser = argparse.ArgumentParser()
423
+ parser.add_argument("--backend", choices=["source", "installed"], default="source")
424
+ parser.add_argument("--artifact")
425
+ parser.add_argument("--mode", choices=["smoke", "full"], default="smoke")
426
+ parser.add_argument("--warmup", type=int, default=20)
427
+ parser.add_argument("--iterations", type=int, default=100)
428
+ parser.add_argument("--json-out")
429
+ args = parser.parse_args()
430
+ module = load_module(args.backend, args.artifact)
431
+ names = ["llm_m1"] if args.mode == "smoke" else list(SHAPES)
432
+ rows = []
433
+ for name in names:
434
+ for bits in (4, 8):
435
+ for activation in ("swiglu", "geglu", "gelu"):
436
+ rows.append(run_case(module, name, SHAPES[name], bits, activation,
437
+ args.warmup, args.iterations))
438
+ linear_names = ["llm_square_m1"] if args.mode == "smoke" else list(LINEAR_SHAPES)
439
+ for name in linear_names:
440
+ for bits in (4, 8):
441
+ rows.append(run_linear_case(
442
+ module, name, LINEAR_SHAPES[name], bits,
443
+ args.warmup, args.iterations,
444
+ ))
445
+ payload = {
446
+ "device": torch.cuda.get_device_name(),
447
+ "capability": list(torch.cuda.get_device_capability()),
448
+ "torch": torch.__version__,
449
+ "rows": rows,
450
+ }
451
+ print(json.dumps(payload, indent=2))
452
+ if args.json_out:
453
+ path = Path(args.json_out)
454
+ path.parent.mkdir(parents=True, exist_ok=True)
455
+ path.write_text(json.dumps(payload, indent=2) + "\n")
456
+ return 0
457
+
458
+
459
+ if __name__ == "__main__":
460
+ raise SystemExit(main())
build/torch211-cxx11-cu128-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Weight-only BF16-activation linear and FFN regions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Optional
6
+
7
+ import torch
8
+
9
+ from ._ops import add_op_namespace_prefix, ops
10
+
11
+
12
+ def w4_sfb_size_bytes(rows: int, cols: int) -> int:
13
+ if rows <= 0 or cols <= 0 or cols % 64:
14
+ raise ValueError("rows must be positive and cols must be divisible by 64")
15
+ return ((int(rows) + 127) // 128) * (((int(cols) // 16) + 3) // 4) * 512
16
+
17
+
18
+ @torch.library.register_fake(add_op_namespace_prefix("quantize_w4_weight_bf16"))
19
+ def _quantize_w4_fake(weight: torch.Tensor, packed: torch.Tensor, sfb: torch.Tensor) -> None:
20
+ return None
21
+
22
+
23
+ @torch.library.register_fake(add_op_namespace_prefix("dequantize_w4_weight_bf16"))
24
+ def _dequantize_w4_fake(packed: torch.Tensor, sfb: torch.Tensor, weight: torch.Tensor) -> None:
25
+ return None
26
+
27
+
28
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_linear_bf16"))
29
+ def _w4_linear_fake(
30
+ x: torch.Tensor,
31
+ packed: torch.Tensor,
32
+ sfb: torch.Tensor,
33
+ alpha: float,
34
+ variant: int,
35
+ out: torch.Tensor,
36
+ ) -> None:
37
+ return None
38
+
39
+
40
+ @torch.library.register_fake(add_op_namespace_prefix("quantize_w8_weight_bf16"))
41
+ def _quantize_w8_fake(weight: torch.Tensor, quantized: torch.Tensor, scales: torch.Tensor) -> None:
42
+ return None
43
+
44
+
45
+ @torch.library.register_fake(add_op_namespace_prefix("dequantize_w8_weight_bf16"))
46
+ def _dequantize_w8_fake(quantized: torch.Tensor, scales: torch.Tensor, weight: torch.Tensor) -> None:
47
+ return None
48
+
49
+
50
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_linear_bf16"))
51
+ def _w8_linear_fake(
52
+ x: torch.Tensor,
53
+ quantized: torch.Tensor,
54
+ scales: torch.Tensor,
55
+ variant: int,
56
+ out: torch.Tensor,
57
+ ) -> None:
58
+ return None
59
+
60
+
61
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_gated_ffn_bf16"))
62
+ def _w4_gated_fake(
63
+ x, gu_w, gu_s, dn_w, dn_s, gu_b, dn_b, gelu, gu_alpha, dn_alpha,
64
+ variant, gu, hidden, out,
65
+ ) -> None:
66
+ return None
67
+
68
+
69
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_gated_ffn_bf16"))
70
+ def _w8_gated_fake(
71
+ x, gu_w, gu_s, dn_w, dn_s, gu_b, dn_b, gelu, variant, gu, hidden, out,
72
+ ) -> None:
73
+ return None
74
+
75
+
76
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_gelu_ffn_bf16"))
77
+ def _w4_gelu_fake(
78
+ x, up_w, up_s, dn_w, dn_s, up_b, dn_b, up_alpha, dn_alpha,
79
+ variant, up, hidden, out,
80
+ ) -> None:
81
+ return None
82
+
83
+
84
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_gelu_ffn_bf16"))
85
+ def _w8_gelu_fake(
86
+ x, up_w, up_s, dn_w, dn_s, up_b, dn_b, variant, up, hidden, out,
87
+ ) -> None:
88
+ return None
89
+
90
+
91
+ def quantize_w4_weight_bf16(weight: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
92
+ """Pack a static BF16 weight matrix into NVFP4 data and SFB scales."""
93
+ n, k = weight.shape
94
+ packed = torch.empty((n, k // 2), device=weight.device, dtype=torch.uint8)
95
+ sfb = torch.empty((w4_sfb_size_bytes(n, k),), device=weight.device, dtype=torch.uint8)
96
+ ops.quantize_w4_weight_bf16(weight, packed, sfb)
97
+ return packed, sfb
98
+
99
+
100
+ def dequantize_w4_weight_bf16(
101
+ packed: torch.Tensor, sfb: torch.Tensor, *, cols: int
102
+ ) -> torch.Tensor:
103
+ weight = torch.empty((packed.shape[0], int(cols)), device=packed.device, dtype=torch.bfloat16)
104
+ ops.dequantize_w4_weight_bf16(packed, sfb, weight)
105
+ return weight
106
+
107
+
108
+ def quantize_w8_weight_bf16(weight: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
109
+ """Symmetrically quantize a static BF16 weight matrix per output channel."""
110
+ quantized = torch.empty_like(weight, dtype=torch.int8)
111
+ scales = torch.empty((weight.shape[0],), device=weight.device, dtype=torch.float32)
112
+ ops.quantize_w8_weight_bf16(weight, quantized, scales)
113
+ return quantized, scales
114
+
115
+
116
+ def dequantize_w8_weight_bf16(
117
+ quantized: torch.Tensor, scales: torch.Tensor
118
+ ) -> torch.Tensor:
119
+ weight = torch.empty_like(quantized, dtype=torch.bfloat16)
120
+ ops.dequantize_w8_weight_bf16(quantized, scales, weight)
121
+ return weight
122
+
123
+
124
+ def w4a16_linear_bf16(
125
+ x: torch.Tensor,
126
+ weight_packed: torch.Tensor,
127
+ weight_sfb: torch.Tensor,
128
+ *,
129
+ alpha: float = 1.0,
130
+ variant: int = 0,
131
+ out: Optional[torch.Tensor] = None,
132
+ ) -> torch.Tensor:
133
+ if out is None:
134
+ out = torch.empty((x.shape[0], weight_packed.shape[0]), device=x.device, dtype=torch.bfloat16)
135
+ ops.w4a16_linear_bf16(x, weight_packed, weight_sfb, float(alpha), int(variant), out)
136
+ return out
137
+
138
+
139
+ def w8a16_linear_bf16(
140
+ x: torch.Tensor,
141
+ weight_int8: torch.Tensor,
142
+ weight_scale: torch.Tensor,
143
+ *,
144
+ variant: int = 0,
145
+ out: Optional[torch.Tensor] = None,
146
+ ) -> torch.Tensor:
147
+ if out is None:
148
+ out = torch.empty((x.shape[0], weight_int8.shape[0]), device=x.device, dtype=torch.bfloat16)
149
+ ops.w8a16_linear_bf16(x, weight_int8, weight_scale, int(variant), out)
150
+ return out
151
+
152
+
153
+ def _gated_workspace(x: torch.Tensor, gate_up_rows: int, out_rows: int, workspace, out):
154
+ hidden_size = gate_up_rows // 2
155
+ if workspace is None:
156
+ gate_up = torch.empty((x.shape[0], gate_up_rows), device=x.device, dtype=torch.bfloat16)
157
+ hidden = torch.empty((x.shape[0], hidden_size), device=x.device, dtype=torch.bfloat16)
158
+ else:
159
+ gate_up, hidden = workspace
160
+ if out is None:
161
+ out = torch.empty((x.shape[0], out_rows), device=x.device, dtype=torch.bfloat16)
162
+ return gate_up, hidden, out
163
+
164
+
165
+ def _gelu_workspace(x: torch.Tensor, hidden_size: int, out_rows: int, workspace, out):
166
+ if workspace is None:
167
+ up = torch.empty((x.shape[0], hidden_size), device=x.device, dtype=torch.bfloat16)
168
+ hidden = torch.empty_like(up)
169
+ else:
170
+ up, hidden = workspace
171
+ if out is None:
172
+ out = torch.empty((x.shape[0], out_rows), device=x.device, dtype=torch.bfloat16)
173
+ return up, hidden, out
174
+
175
+
176
+ def _w4_gated(
177
+ x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, *, gelu,
178
+ gate_up_bias=None, down_bias=None, gate_up_alpha=1.0, down_alpha=1.0,
179
+ variant=0, workspace=None, out=None,
180
+ ):
181
+ gate_up, hidden, out = _gated_workspace(
182
+ x, gate_up_weight.shape[0], down_weight.shape[0], workspace, out
183
+ )
184
+ ops.w4a16_gated_ffn_bf16(
185
+ x, gate_up_weight, gate_up_sfb, down_weight, down_sfb,
186
+ gate_up_bias, down_bias, bool(gelu), float(gate_up_alpha),
187
+ float(down_alpha), int(variant), gate_up, hidden, out,
188
+ )
189
+ return out
190
+
191
+
192
+ def w4a16_swiglu_ffn_bf16(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, **kwargs):
193
+ return _w4_gated(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, gelu=False, **kwargs)
194
+
195
+
196
+ def w4a16_geglu_ffn_bf16(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, **kwargs):
197
+ return _w4_gated(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, gelu=True, **kwargs)
198
+
199
+
200
+ def _w8_gated(
201
+ x, gate_up_weight, gate_up_scale, down_weight, down_scale, *, gelu,
202
+ gate_up_bias=None, down_bias=None, variant=0, workspace=None, out=None,
203
+ ):
204
+ gate_up, hidden, out = _gated_workspace(
205
+ x, gate_up_weight.shape[0], down_weight.shape[0], workspace, out
206
+ )
207
+ ops.w8a16_gated_ffn_bf16(
208
+ x, gate_up_weight, gate_up_scale, down_weight, down_scale,
209
+ gate_up_bias, down_bias, bool(gelu), int(variant), gate_up, hidden, out,
210
+ )
211
+ return out
212
+
213
+
214
+ def w8a16_swiglu_ffn_bf16(x, gate_up_weight, gate_up_scale, down_weight, down_scale, **kwargs):
215
+ return _w8_gated(x, gate_up_weight, gate_up_scale, down_weight, down_scale, gelu=False, **kwargs)
216
+
217
+
218
+ def w8a16_geglu_ffn_bf16(x, gate_up_weight, gate_up_scale, down_weight, down_scale, **kwargs):
219
+ return _w8_gated(x, gate_up_weight, gate_up_scale, down_weight, down_scale, gelu=True, **kwargs)
220
+
221
+
222
+ def w4a16_gelu_ffn_bf16(
223
+ x, up_weight, up_sfb, down_weight, down_sfb, *, up_bias=None,
224
+ down_bias=None, up_alpha=1.0, down_alpha=1.0, variant=0,
225
+ workspace=None, out=None,
226
+ ):
227
+ up, hidden, out = _gelu_workspace(x, up_weight.shape[0], down_weight.shape[0], workspace, out)
228
+ ops.w4a16_gelu_ffn_bf16(
229
+ x, up_weight, up_sfb, down_weight, down_sfb, up_bias, down_bias,
230
+ float(up_alpha), float(down_alpha), int(variant), up, hidden, out,
231
+ )
232
+ return out
233
+
234
+
235
+ def w8a16_gelu_ffn_bf16(
236
+ x, up_weight, up_scale, down_weight, down_scale, *, up_bias=None,
237
+ down_bias=None, variant=0, workspace=None, out=None,
238
+ ):
239
+ up, hidden, out = _gelu_workspace(x, up_weight.shape[0], down_weight.shape[0], workspace, out)
240
+ ops.w8a16_gelu_ffn_bf16(
241
+ x, up_weight, up_scale, down_weight, down_scale, up_bias, down_bias,
242
+ int(variant), up, hidden, out,
243
+ )
244
+ return out
245
+
246
+
247
+ __all__ = [
248
+ "dequantize_w4_weight_bf16",
249
+ "dequantize_w8_weight_bf16",
250
+ "quantize_w4_weight_bf16",
251
+ "quantize_w8_weight_bf16",
252
+ "w4_sfb_size_bytes",
253
+ "w4a16_geglu_ffn_bf16",
254
+ "w4a16_gelu_ffn_bf16",
255
+ "w4a16_linear_bf16",
256
+ "w4a16_swiglu_ffn_bf16",
257
+ "w8a16_geglu_ffn_bf16",
258
+ "w8a16_gelu_ffn_bf16",
259
+ "w8a16_linear_bf16",
260
+ "w8a16_swiglu_ffn_bf16",
261
+ ]
build/torch211-cxx11-cu128-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _weight_only_ffn_cuda_38d37b6
3
+ ops = torch.ops._weight_only_ffn_cuda_38d37b6
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_weight_only_ffn_cuda_38d37b6::{op_name}"
build/torch211-cxx11-cu128-x86_64-linux/_weight_only_ffn_cuda_38d37b6.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7ee391e51802ca24eda6c3c73cb1b711e61864dbe9272b9f6b79cce491deaffe
3
+ size 767928
build/torch211-cxx11-cu128-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "weight-only-ffn",
3
+ "id": "_weight_only_ffn_cuda_38d37b6",
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": "0q6TMj65una1LdyHLC291Dwy2VzrBbAD8Wm8MEdmqwA=",
17
+ "_ops.py": "iqY+HoE4nGHqvVlEZTwEAcyu1/w+QrjwuuW9sdTI2uk=",
18
+ "_weight_only_ffn_cuda_38d37b6.abi3.so": "fuOR5RgCyiTtpsPHPLG3EeYYZNvpJyufa3nM5JHer/4=",
19
+ "weight_only_ffn/__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": "38d37b67acfe940c99d7b3db721fa67163b82cec",
30
+ "dirty": false
31
+ }
32
+ }
33
+ }
build/torch211-cxx11-cu128-x86_64-linux/weight_only_ffn/__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-aarch64-linux/__init__.py ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Weight-only BF16-activation linear and FFN regions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Optional
6
+
7
+ import torch
8
+
9
+ from ._ops import add_op_namespace_prefix, ops
10
+
11
+
12
+ def w4_sfb_size_bytes(rows: int, cols: int) -> int:
13
+ if rows <= 0 or cols <= 0 or cols % 64:
14
+ raise ValueError("rows must be positive and cols must be divisible by 64")
15
+ return ((int(rows) + 127) // 128) * (((int(cols) // 16) + 3) // 4) * 512
16
+
17
+
18
+ @torch.library.register_fake(add_op_namespace_prefix("quantize_w4_weight_bf16"))
19
+ def _quantize_w4_fake(weight: torch.Tensor, packed: torch.Tensor, sfb: torch.Tensor) -> None:
20
+ return None
21
+
22
+
23
+ @torch.library.register_fake(add_op_namespace_prefix("dequantize_w4_weight_bf16"))
24
+ def _dequantize_w4_fake(packed: torch.Tensor, sfb: torch.Tensor, weight: torch.Tensor) -> None:
25
+ return None
26
+
27
+
28
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_linear_bf16"))
29
+ def _w4_linear_fake(
30
+ x: torch.Tensor,
31
+ packed: torch.Tensor,
32
+ sfb: torch.Tensor,
33
+ alpha: float,
34
+ variant: int,
35
+ out: torch.Tensor,
36
+ ) -> None:
37
+ return None
38
+
39
+
40
+ @torch.library.register_fake(add_op_namespace_prefix("quantize_w8_weight_bf16"))
41
+ def _quantize_w8_fake(weight: torch.Tensor, quantized: torch.Tensor, scales: torch.Tensor) -> None:
42
+ return None
43
+
44
+
45
+ @torch.library.register_fake(add_op_namespace_prefix("dequantize_w8_weight_bf16"))
46
+ def _dequantize_w8_fake(quantized: torch.Tensor, scales: torch.Tensor, weight: torch.Tensor) -> None:
47
+ return None
48
+
49
+
50
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_linear_bf16"))
51
+ def _w8_linear_fake(
52
+ x: torch.Tensor,
53
+ quantized: torch.Tensor,
54
+ scales: torch.Tensor,
55
+ variant: int,
56
+ out: torch.Tensor,
57
+ ) -> None:
58
+ return None
59
+
60
+
61
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_gated_ffn_bf16"))
62
+ def _w4_gated_fake(
63
+ x, gu_w, gu_s, dn_w, dn_s, gu_b, dn_b, gelu, gu_alpha, dn_alpha,
64
+ variant, gu, hidden, out,
65
+ ) -> None:
66
+ return None
67
+
68
+
69
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_gated_ffn_bf16"))
70
+ def _w8_gated_fake(
71
+ x, gu_w, gu_s, dn_w, dn_s, gu_b, dn_b, gelu, variant, gu, hidden, out,
72
+ ) -> None:
73
+ return None
74
+
75
+
76
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_gelu_ffn_bf16"))
77
+ def _w4_gelu_fake(
78
+ x, up_w, up_s, dn_w, dn_s, up_b, dn_b, up_alpha, dn_alpha,
79
+ variant, up, hidden, out,
80
+ ) -> None:
81
+ return None
82
+
83
+
84
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_gelu_ffn_bf16"))
85
+ def _w8_gelu_fake(
86
+ x, up_w, up_s, dn_w, dn_s, up_b, dn_b, variant, up, hidden, out,
87
+ ) -> None:
88
+ return None
89
+
90
+
91
+ def quantize_w4_weight_bf16(weight: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
92
+ """Pack a static BF16 weight matrix into NVFP4 data and SFB scales."""
93
+ n, k = weight.shape
94
+ packed = torch.empty((n, k // 2), device=weight.device, dtype=torch.uint8)
95
+ sfb = torch.empty((w4_sfb_size_bytes(n, k),), device=weight.device, dtype=torch.uint8)
96
+ ops.quantize_w4_weight_bf16(weight, packed, sfb)
97
+ return packed, sfb
98
+
99
+
100
+ def dequantize_w4_weight_bf16(
101
+ packed: torch.Tensor, sfb: torch.Tensor, *, cols: int
102
+ ) -> torch.Tensor:
103
+ weight = torch.empty((packed.shape[0], int(cols)), device=packed.device, dtype=torch.bfloat16)
104
+ ops.dequantize_w4_weight_bf16(packed, sfb, weight)
105
+ return weight
106
+
107
+
108
+ def quantize_w8_weight_bf16(weight: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
109
+ """Symmetrically quantize a static BF16 weight matrix per output channel."""
110
+ quantized = torch.empty_like(weight, dtype=torch.int8)
111
+ scales = torch.empty((weight.shape[0],), device=weight.device, dtype=torch.float32)
112
+ ops.quantize_w8_weight_bf16(weight, quantized, scales)
113
+ return quantized, scales
114
+
115
+
116
+ def dequantize_w8_weight_bf16(
117
+ quantized: torch.Tensor, scales: torch.Tensor
118
+ ) -> torch.Tensor:
119
+ weight = torch.empty_like(quantized, dtype=torch.bfloat16)
120
+ ops.dequantize_w8_weight_bf16(quantized, scales, weight)
121
+ return weight
122
+
123
+
124
+ def w4a16_linear_bf16(
125
+ x: torch.Tensor,
126
+ weight_packed: torch.Tensor,
127
+ weight_sfb: torch.Tensor,
128
+ *,
129
+ alpha: float = 1.0,
130
+ variant: int = 0,
131
+ out: Optional[torch.Tensor] = None,
132
+ ) -> torch.Tensor:
133
+ if out is None:
134
+ out = torch.empty((x.shape[0], weight_packed.shape[0]), device=x.device, dtype=torch.bfloat16)
135
+ ops.w4a16_linear_bf16(x, weight_packed, weight_sfb, float(alpha), int(variant), out)
136
+ return out
137
+
138
+
139
+ def w8a16_linear_bf16(
140
+ x: torch.Tensor,
141
+ weight_int8: torch.Tensor,
142
+ weight_scale: torch.Tensor,
143
+ *,
144
+ variant: int = 0,
145
+ out: Optional[torch.Tensor] = None,
146
+ ) -> torch.Tensor:
147
+ if out is None:
148
+ out = torch.empty((x.shape[0], weight_int8.shape[0]), device=x.device, dtype=torch.bfloat16)
149
+ ops.w8a16_linear_bf16(x, weight_int8, weight_scale, int(variant), out)
150
+ return out
151
+
152
+
153
+ def _gated_workspace(x: torch.Tensor, gate_up_rows: int, out_rows: int, workspace, out):
154
+ hidden_size = gate_up_rows // 2
155
+ if workspace is None:
156
+ gate_up = torch.empty((x.shape[0], gate_up_rows), device=x.device, dtype=torch.bfloat16)
157
+ hidden = torch.empty((x.shape[0], hidden_size), device=x.device, dtype=torch.bfloat16)
158
+ else:
159
+ gate_up, hidden = workspace
160
+ if out is None:
161
+ out = torch.empty((x.shape[0], out_rows), device=x.device, dtype=torch.bfloat16)
162
+ return gate_up, hidden, out
163
+
164
+
165
+ def _gelu_workspace(x: torch.Tensor, hidden_size: int, out_rows: int, workspace, out):
166
+ if workspace is None:
167
+ up = torch.empty((x.shape[0], hidden_size), device=x.device, dtype=torch.bfloat16)
168
+ hidden = torch.empty_like(up)
169
+ else:
170
+ up, hidden = workspace
171
+ if out is None:
172
+ out = torch.empty((x.shape[0], out_rows), device=x.device, dtype=torch.bfloat16)
173
+ return up, hidden, out
174
+
175
+
176
+ def _w4_gated(
177
+ x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, *, gelu,
178
+ gate_up_bias=None, down_bias=None, gate_up_alpha=1.0, down_alpha=1.0,
179
+ variant=0, workspace=None, out=None,
180
+ ):
181
+ gate_up, hidden, out = _gated_workspace(
182
+ x, gate_up_weight.shape[0], down_weight.shape[0], workspace, out
183
+ )
184
+ ops.w4a16_gated_ffn_bf16(
185
+ x, gate_up_weight, gate_up_sfb, down_weight, down_sfb,
186
+ gate_up_bias, down_bias, bool(gelu), float(gate_up_alpha),
187
+ float(down_alpha), int(variant), gate_up, hidden, out,
188
+ )
189
+ return out
190
+
191
+
192
+ def w4a16_swiglu_ffn_bf16(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, **kwargs):
193
+ return _w4_gated(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, gelu=False, **kwargs)
194
+
195
+
196
+ def w4a16_geglu_ffn_bf16(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, **kwargs):
197
+ return _w4_gated(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, gelu=True, **kwargs)
198
+
199
+
200
+ def _w8_gated(
201
+ x, gate_up_weight, gate_up_scale, down_weight, down_scale, *, gelu,
202
+ gate_up_bias=None, down_bias=None, variant=0, workspace=None, out=None,
203
+ ):
204
+ gate_up, hidden, out = _gated_workspace(
205
+ x, gate_up_weight.shape[0], down_weight.shape[0], workspace, out
206
+ )
207
+ ops.w8a16_gated_ffn_bf16(
208
+ x, gate_up_weight, gate_up_scale, down_weight, down_scale,
209
+ gate_up_bias, down_bias, bool(gelu), int(variant), gate_up, hidden, out,
210
+ )
211
+ return out
212
+
213
+
214
+ def w8a16_swiglu_ffn_bf16(x, gate_up_weight, gate_up_scale, down_weight, down_scale, **kwargs):
215
+ return _w8_gated(x, gate_up_weight, gate_up_scale, down_weight, down_scale, gelu=False, **kwargs)
216
+
217
+
218
+ def w8a16_geglu_ffn_bf16(x, gate_up_weight, gate_up_scale, down_weight, down_scale, **kwargs):
219
+ return _w8_gated(x, gate_up_weight, gate_up_scale, down_weight, down_scale, gelu=True, **kwargs)
220
+
221
+
222
+ def w4a16_gelu_ffn_bf16(
223
+ x, up_weight, up_sfb, down_weight, down_sfb, *, up_bias=None,
224
+ down_bias=None, up_alpha=1.0, down_alpha=1.0, variant=0,
225
+ workspace=None, out=None,
226
+ ):
227
+ up, hidden, out = _gelu_workspace(x, up_weight.shape[0], down_weight.shape[0], workspace, out)
228
+ ops.w4a16_gelu_ffn_bf16(
229
+ x, up_weight, up_sfb, down_weight, down_sfb, up_bias, down_bias,
230
+ float(up_alpha), float(down_alpha), int(variant), up, hidden, out,
231
+ )
232
+ return out
233
+
234
+
235
+ def w8a16_gelu_ffn_bf16(
236
+ x, up_weight, up_scale, down_weight, down_scale, *, up_bias=None,
237
+ down_bias=None, variant=0, workspace=None, out=None,
238
+ ):
239
+ up, hidden, out = _gelu_workspace(x, up_weight.shape[0], down_weight.shape[0], workspace, out)
240
+ ops.w8a16_gelu_ffn_bf16(
241
+ x, up_weight, up_scale, down_weight, down_scale, up_bias, down_bias,
242
+ int(variant), up, hidden, out,
243
+ )
244
+ return out
245
+
246
+
247
+ __all__ = [
248
+ "dequantize_w4_weight_bf16",
249
+ "dequantize_w8_weight_bf16",
250
+ "quantize_w4_weight_bf16",
251
+ "quantize_w8_weight_bf16",
252
+ "w4_sfb_size_bytes",
253
+ "w4a16_geglu_ffn_bf16",
254
+ "w4a16_gelu_ffn_bf16",
255
+ "w4a16_linear_bf16",
256
+ "w4a16_swiglu_ffn_bf16",
257
+ "w8a16_geglu_ffn_bf16",
258
+ "w8a16_gelu_ffn_bf16",
259
+ "w8a16_linear_bf16",
260
+ "w8a16_swiglu_ffn_bf16",
261
+ ]
build/torch211-cxx11-cu130-aarch64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _weight_only_ffn_cuda_38d37b6
3
+ ops = torch.ops._weight_only_ffn_cuda_38d37b6
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_weight_only_ffn_cuda_38d37b6::{op_name}"
build/torch211-cxx11-cu130-aarch64-linux/_weight_only_ffn_cuda_38d37b6.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8f9889ec68f033ef59caf861ffe0664d95e9775e842019af06a3bcdc5175e5bd
3
+ size 1927752
build/torch211-cxx11-cu130-aarch64-linux/metadata.json ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "weight-only-ffn",
3
+ "id": "_weight_only_ffn_cuda_38d37b6",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "11.0a",
11
+ "12.0a",
12
+ "12.1"
13
+ ]
14
+ },
15
+ "provenance": {
16
+ "kernel-builder": {
17
+ "version": "0.17.0-dev0",
18
+ "sha": "19aaa6421e674e9fecc352bbae6eab81d19a6bf4",
19
+ "dirty": false
20
+ },
21
+ "kernel": {
22
+ "sha": "38d37b67acfe940c99d7b3db721fa67163b82cec",
23
+ "dirty": false
24
+ }
25
+ }
26
+ }
build/torch211-cxx11-cu130-aarch64-linux/weight_only_ffn/__init__.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ctypes
2
+ import importlib.util
3
+ import sys
4
+ from pathlib import Path
5
+ from types import ModuleType
6
+
7
+
8
+ def _import_from_path(file_path: Path) -> ModuleType:
9
+ # We cannot use the module name as-is, after adding it to `sys.modules`,
10
+ # it would also be used for other imports. So, we make a module name that
11
+ # depends on the path for it to be unique using the hex-encoded hash of
12
+ # the path.
13
+ path_hash = "{:x}".format(ctypes.c_size_t(hash(file_path.absolute())).value)
14
+ module_name = path_hash
15
+ spec = importlib.util.spec_from_file_location(module_name, file_path)
16
+ if spec is None:
17
+ raise ImportError(f"Cannot load spec for {module_name} from {file_path}")
18
+ module = importlib.util.module_from_spec(spec)
19
+ if module is None:
20
+ raise ImportError(f"Cannot load module {module_name} from spec")
21
+ sys.modules[module_name] = module
22
+ spec.loader.exec_module(module) # type: ignore
23
+ return module
24
+
25
+
26
+ globals().update(vars(_import_from_path(Path(__file__).parent.parent / "__init__.py")))
build/torch211-cxx11-cu130-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Weight-only BF16-activation linear and FFN regions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Optional
6
+
7
+ import torch
8
+
9
+ from ._ops import add_op_namespace_prefix, ops
10
+
11
+
12
+ def w4_sfb_size_bytes(rows: int, cols: int) -> int:
13
+ if rows <= 0 or cols <= 0 or cols % 64:
14
+ raise ValueError("rows must be positive and cols must be divisible by 64")
15
+ return ((int(rows) + 127) // 128) * (((int(cols) // 16) + 3) // 4) * 512
16
+
17
+
18
+ @torch.library.register_fake(add_op_namespace_prefix("quantize_w4_weight_bf16"))
19
+ def _quantize_w4_fake(weight: torch.Tensor, packed: torch.Tensor, sfb: torch.Tensor) -> None:
20
+ return None
21
+
22
+
23
+ @torch.library.register_fake(add_op_namespace_prefix("dequantize_w4_weight_bf16"))
24
+ def _dequantize_w4_fake(packed: torch.Tensor, sfb: torch.Tensor, weight: torch.Tensor) -> None:
25
+ return None
26
+
27
+
28
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_linear_bf16"))
29
+ def _w4_linear_fake(
30
+ x: torch.Tensor,
31
+ packed: torch.Tensor,
32
+ sfb: torch.Tensor,
33
+ alpha: float,
34
+ variant: int,
35
+ out: torch.Tensor,
36
+ ) -> None:
37
+ return None
38
+
39
+
40
+ @torch.library.register_fake(add_op_namespace_prefix("quantize_w8_weight_bf16"))
41
+ def _quantize_w8_fake(weight: torch.Tensor, quantized: torch.Tensor, scales: torch.Tensor) -> None:
42
+ return None
43
+
44
+
45
+ @torch.library.register_fake(add_op_namespace_prefix("dequantize_w8_weight_bf16"))
46
+ def _dequantize_w8_fake(quantized: torch.Tensor, scales: torch.Tensor, weight: torch.Tensor) -> None:
47
+ return None
48
+
49
+
50
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_linear_bf16"))
51
+ def _w8_linear_fake(
52
+ x: torch.Tensor,
53
+ quantized: torch.Tensor,
54
+ scales: torch.Tensor,
55
+ variant: int,
56
+ out: torch.Tensor,
57
+ ) -> None:
58
+ return None
59
+
60
+
61
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_gated_ffn_bf16"))
62
+ def _w4_gated_fake(
63
+ x, gu_w, gu_s, dn_w, dn_s, gu_b, dn_b, gelu, gu_alpha, dn_alpha,
64
+ variant, gu, hidden, out,
65
+ ) -> None:
66
+ return None
67
+
68
+
69
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_gated_ffn_bf16"))
70
+ def _w8_gated_fake(
71
+ x, gu_w, gu_s, dn_w, dn_s, gu_b, dn_b, gelu, variant, gu, hidden, out,
72
+ ) -> None:
73
+ return None
74
+
75
+
76
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_gelu_ffn_bf16"))
77
+ def _w4_gelu_fake(
78
+ x, up_w, up_s, dn_w, dn_s, up_b, dn_b, up_alpha, dn_alpha,
79
+ variant, up, hidden, out,
80
+ ) -> None:
81
+ return None
82
+
83
+
84
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_gelu_ffn_bf16"))
85
+ def _w8_gelu_fake(
86
+ x, up_w, up_s, dn_w, dn_s, up_b, dn_b, variant, up, hidden, out,
87
+ ) -> None:
88
+ return None
89
+
90
+
91
+ def quantize_w4_weight_bf16(weight: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
92
+ """Pack a static BF16 weight matrix into NVFP4 data and SFB scales."""
93
+ n, k = weight.shape
94
+ packed = torch.empty((n, k // 2), device=weight.device, dtype=torch.uint8)
95
+ sfb = torch.empty((w4_sfb_size_bytes(n, k),), device=weight.device, dtype=torch.uint8)
96
+ ops.quantize_w4_weight_bf16(weight, packed, sfb)
97
+ return packed, sfb
98
+
99
+
100
+ def dequantize_w4_weight_bf16(
101
+ packed: torch.Tensor, sfb: torch.Tensor, *, cols: int
102
+ ) -> torch.Tensor:
103
+ weight = torch.empty((packed.shape[0], int(cols)), device=packed.device, dtype=torch.bfloat16)
104
+ ops.dequantize_w4_weight_bf16(packed, sfb, weight)
105
+ return weight
106
+
107
+
108
+ def quantize_w8_weight_bf16(weight: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
109
+ """Symmetrically quantize a static BF16 weight matrix per output channel."""
110
+ quantized = torch.empty_like(weight, dtype=torch.int8)
111
+ scales = torch.empty((weight.shape[0],), device=weight.device, dtype=torch.float32)
112
+ ops.quantize_w8_weight_bf16(weight, quantized, scales)
113
+ return quantized, scales
114
+
115
+
116
+ def dequantize_w8_weight_bf16(
117
+ quantized: torch.Tensor, scales: torch.Tensor
118
+ ) -> torch.Tensor:
119
+ weight = torch.empty_like(quantized, dtype=torch.bfloat16)
120
+ ops.dequantize_w8_weight_bf16(quantized, scales, weight)
121
+ return weight
122
+
123
+
124
+ def w4a16_linear_bf16(
125
+ x: torch.Tensor,
126
+ weight_packed: torch.Tensor,
127
+ weight_sfb: torch.Tensor,
128
+ *,
129
+ alpha: float = 1.0,
130
+ variant: int = 0,
131
+ out: Optional[torch.Tensor] = None,
132
+ ) -> torch.Tensor:
133
+ if out is None:
134
+ out = torch.empty((x.shape[0], weight_packed.shape[0]), device=x.device, dtype=torch.bfloat16)
135
+ ops.w4a16_linear_bf16(x, weight_packed, weight_sfb, float(alpha), int(variant), out)
136
+ return out
137
+
138
+
139
+ def w8a16_linear_bf16(
140
+ x: torch.Tensor,
141
+ weight_int8: torch.Tensor,
142
+ weight_scale: torch.Tensor,
143
+ *,
144
+ variant: int = 0,
145
+ out: Optional[torch.Tensor] = None,
146
+ ) -> torch.Tensor:
147
+ if out is None:
148
+ out = torch.empty((x.shape[0], weight_int8.shape[0]), device=x.device, dtype=torch.bfloat16)
149
+ ops.w8a16_linear_bf16(x, weight_int8, weight_scale, int(variant), out)
150
+ return out
151
+
152
+
153
+ def _gated_workspace(x: torch.Tensor, gate_up_rows: int, out_rows: int, workspace, out):
154
+ hidden_size = gate_up_rows // 2
155
+ if workspace is None:
156
+ gate_up = torch.empty((x.shape[0], gate_up_rows), device=x.device, dtype=torch.bfloat16)
157
+ hidden = torch.empty((x.shape[0], hidden_size), device=x.device, dtype=torch.bfloat16)
158
+ else:
159
+ gate_up, hidden = workspace
160
+ if out is None:
161
+ out = torch.empty((x.shape[0], out_rows), device=x.device, dtype=torch.bfloat16)
162
+ return gate_up, hidden, out
163
+
164
+
165
+ def _gelu_workspace(x: torch.Tensor, hidden_size: int, out_rows: int, workspace, out):
166
+ if workspace is None:
167
+ up = torch.empty((x.shape[0], hidden_size), device=x.device, dtype=torch.bfloat16)
168
+ hidden = torch.empty_like(up)
169
+ else:
170
+ up, hidden = workspace
171
+ if out is None:
172
+ out = torch.empty((x.shape[0], out_rows), device=x.device, dtype=torch.bfloat16)
173
+ return up, hidden, out
174
+
175
+
176
+ def _w4_gated(
177
+ x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, *, gelu,
178
+ gate_up_bias=None, down_bias=None, gate_up_alpha=1.0, down_alpha=1.0,
179
+ variant=0, workspace=None, out=None,
180
+ ):
181
+ gate_up, hidden, out = _gated_workspace(
182
+ x, gate_up_weight.shape[0], down_weight.shape[0], workspace, out
183
+ )
184
+ ops.w4a16_gated_ffn_bf16(
185
+ x, gate_up_weight, gate_up_sfb, down_weight, down_sfb,
186
+ gate_up_bias, down_bias, bool(gelu), float(gate_up_alpha),
187
+ float(down_alpha), int(variant), gate_up, hidden, out,
188
+ )
189
+ return out
190
+
191
+
192
+ def w4a16_swiglu_ffn_bf16(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, **kwargs):
193
+ return _w4_gated(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, gelu=False, **kwargs)
194
+
195
+
196
+ def w4a16_geglu_ffn_bf16(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, **kwargs):
197
+ return _w4_gated(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, gelu=True, **kwargs)
198
+
199
+
200
+ def _w8_gated(
201
+ x, gate_up_weight, gate_up_scale, down_weight, down_scale, *, gelu,
202
+ gate_up_bias=None, down_bias=None, variant=0, workspace=None, out=None,
203
+ ):
204
+ gate_up, hidden, out = _gated_workspace(
205
+ x, gate_up_weight.shape[0], down_weight.shape[0], workspace, out
206
+ )
207
+ ops.w8a16_gated_ffn_bf16(
208
+ x, gate_up_weight, gate_up_scale, down_weight, down_scale,
209
+ gate_up_bias, down_bias, bool(gelu), int(variant), gate_up, hidden, out,
210
+ )
211
+ return out
212
+
213
+
214
+ def w8a16_swiglu_ffn_bf16(x, gate_up_weight, gate_up_scale, down_weight, down_scale, **kwargs):
215
+ return _w8_gated(x, gate_up_weight, gate_up_scale, down_weight, down_scale, gelu=False, **kwargs)
216
+
217
+
218
+ def w8a16_geglu_ffn_bf16(x, gate_up_weight, gate_up_scale, down_weight, down_scale, **kwargs):
219
+ return _w8_gated(x, gate_up_weight, gate_up_scale, down_weight, down_scale, gelu=True, **kwargs)
220
+
221
+
222
+ def w4a16_gelu_ffn_bf16(
223
+ x, up_weight, up_sfb, down_weight, down_sfb, *, up_bias=None,
224
+ down_bias=None, up_alpha=1.0, down_alpha=1.0, variant=0,
225
+ workspace=None, out=None,
226
+ ):
227
+ up, hidden, out = _gelu_workspace(x, up_weight.shape[0], down_weight.shape[0], workspace, out)
228
+ ops.w4a16_gelu_ffn_bf16(
229
+ x, up_weight, up_sfb, down_weight, down_sfb, up_bias, down_bias,
230
+ float(up_alpha), float(down_alpha), int(variant), up, hidden, out,
231
+ )
232
+ return out
233
+
234
+
235
+ def w8a16_gelu_ffn_bf16(
236
+ x, up_weight, up_scale, down_weight, down_scale, *, up_bias=None,
237
+ down_bias=None, variant=0, workspace=None, out=None,
238
+ ):
239
+ up, hidden, out = _gelu_workspace(x, up_weight.shape[0], down_weight.shape[0], workspace, out)
240
+ ops.w8a16_gelu_ffn_bf16(
241
+ x, up_weight, up_scale, down_weight, down_scale, up_bias, down_bias,
242
+ int(variant), up, hidden, out,
243
+ )
244
+ return out
245
+
246
+
247
+ __all__ = [
248
+ "dequantize_w4_weight_bf16",
249
+ "dequantize_w8_weight_bf16",
250
+ "quantize_w4_weight_bf16",
251
+ "quantize_w8_weight_bf16",
252
+ "w4_sfb_size_bytes",
253
+ "w4a16_geglu_ffn_bf16",
254
+ "w4a16_gelu_ffn_bf16",
255
+ "w4a16_linear_bf16",
256
+ "w4a16_swiglu_ffn_bf16",
257
+ "w8a16_geglu_ffn_bf16",
258
+ "w8a16_gelu_ffn_bf16",
259
+ "w8a16_linear_bf16",
260
+ "w8a16_swiglu_ffn_bf16",
261
+ ]
build/torch211-cxx11-cu130-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _weight_only_ffn_cuda_38d37b6
3
+ ops = torch.ops._weight_only_ffn_cuda_38d37b6
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_weight_only_ffn_cuda_38d37b6::{op_name}"
build/torch211-cxx11-cu130-x86_64-linux/_weight_only_ffn_cuda_38d37b6.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6d98010a7e6bbe8b925689ee60f1026519835d2d841d6f1a58fb7922714d274d
3
+ size 1896120
build/torch211-cxx11-cu130-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "weight-only-ffn",
3
+ "id": "_weight_only_ffn_cuda_38d37b6",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "11.0a",
11
+ "12.0a",
12
+ "12.1"
13
+ ]
14
+ },
15
+ "digest": {
16
+ "algorithm": "sha256",
17
+ "files": {
18
+ "__init__.py": "0q6TMj65una1LdyHLC291Dwy2VzrBbAD8Wm8MEdmqwA=",
19
+ "_ops.py": "iqY+HoE4nGHqvVlEZTwEAcyu1/w+QrjwuuW9sdTI2uk=",
20
+ "_weight_only_ffn_cuda_38d37b6.abi3.so": "bZgBCn5rvouSVonuYPECZRmDXS2EHW8aWPt5InFNJ00=",
21
+ "weight_only_ffn/__init__.py": "DFYPlrhXwYjEqCl/8n0SmWGZV8NFml5DPhMjKfv98GY="
22
+ }
23
+ },
24
+ "provenance": {
25
+ "kernel-builder": {
26
+ "version": "0.17.0-dev0",
27
+ "sha": "19aaa6421e674e9fecc352bbae6eab81d19a6bf4",
28
+ "dirty": false
29
+ },
30
+ "kernel": {
31
+ "sha": "38d37b67acfe940c99d7b3db721fa67163b82cec",
32
+ "dirty": false
33
+ }
34
+ }
35
+ }
build/torch211-cxx11-cu130-x86_64-linux/weight_only_ffn/__init__.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ctypes
2
+ import importlib.util
3
+ import sys
4
+ from pathlib import Path
5
+ from types import ModuleType
6
+
7
+
8
+ def _import_from_path(file_path: Path) -> ModuleType:
9
+ # We cannot use the module name as-is, after adding it to `sys.modules`,
10
+ # it would also be used for other imports. So, we make a module name that
11
+ # depends on the path for it to be unique using the hex-encoded hash of
12
+ # the path.
13
+ path_hash = "{:x}".format(ctypes.c_size_t(hash(file_path.absolute())).value)
14
+ module_name = path_hash
15
+ spec = importlib.util.spec_from_file_location(module_name, file_path)
16
+ if spec is None:
17
+ raise ImportError(f"Cannot load spec for {module_name} from {file_path}")
18
+ module = importlib.util.module_from_spec(spec)
19
+ if module is None:
20
+ raise ImportError(f"Cannot load module {module_name} from spec")
21
+ sys.modules[module_name] = module
22
+ spec.loader.exec_module(module) # type: ignore
23
+ return module
24
+
25
+
26
+ globals().update(vars(_import_from_path(Path(__file__).parent.parent / "__init__.py")))
build/torch212-cxx11-cu130-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Weight-only BF16-activation linear and FFN regions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Optional
6
+
7
+ import torch
8
+
9
+ from ._ops import add_op_namespace_prefix, ops
10
+
11
+
12
+ def w4_sfb_size_bytes(rows: int, cols: int) -> int:
13
+ if rows <= 0 or cols <= 0 or cols % 64:
14
+ raise ValueError("rows must be positive and cols must be divisible by 64")
15
+ return ((int(rows) + 127) // 128) * (((int(cols) // 16) + 3) // 4) * 512
16
+
17
+
18
+ @torch.library.register_fake(add_op_namespace_prefix("quantize_w4_weight_bf16"))
19
+ def _quantize_w4_fake(weight: torch.Tensor, packed: torch.Tensor, sfb: torch.Tensor) -> None:
20
+ return None
21
+
22
+
23
+ @torch.library.register_fake(add_op_namespace_prefix("dequantize_w4_weight_bf16"))
24
+ def _dequantize_w4_fake(packed: torch.Tensor, sfb: torch.Tensor, weight: torch.Tensor) -> None:
25
+ return None
26
+
27
+
28
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_linear_bf16"))
29
+ def _w4_linear_fake(
30
+ x: torch.Tensor,
31
+ packed: torch.Tensor,
32
+ sfb: torch.Tensor,
33
+ alpha: float,
34
+ variant: int,
35
+ out: torch.Tensor,
36
+ ) -> None:
37
+ return None
38
+
39
+
40
+ @torch.library.register_fake(add_op_namespace_prefix("quantize_w8_weight_bf16"))
41
+ def _quantize_w8_fake(weight: torch.Tensor, quantized: torch.Tensor, scales: torch.Tensor) -> None:
42
+ return None
43
+
44
+
45
+ @torch.library.register_fake(add_op_namespace_prefix("dequantize_w8_weight_bf16"))
46
+ def _dequantize_w8_fake(quantized: torch.Tensor, scales: torch.Tensor, weight: torch.Tensor) -> None:
47
+ return None
48
+
49
+
50
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_linear_bf16"))
51
+ def _w8_linear_fake(
52
+ x: torch.Tensor,
53
+ quantized: torch.Tensor,
54
+ scales: torch.Tensor,
55
+ variant: int,
56
+ out: torch.Tensor,
57
+ ) -> None:
58
+ return None
59
+
60
+
61
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_gated_ffn_bf16"))
62
+ def _w4_gated_fake(
63
+ x, gu_w, gu_s, dn_w, dn_s, gu_b, dn_b, gelu, gu_alpha, dn_alpha,
64
+ variant, gu, hidden, out,
65
+ ) -> None:
66
+ return None
67
+
68
+
69
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_gated_ffn_bf16"))
70
+ def _w8_gated_fake(
71
+ x, gu_w, gu_s, dn_w, dn_s, gu_b, dn_b, gelu, variant, gu, hidden, out,
72
+ ) -> None:
73
+ return None
74
+
75
+
76
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_gelu_ffn_bf16"))
77
+ def _w4_gelu_fake(
78
+ x, up_w, up_s, dn_w, dn_s, up_b, dn_b, up_alpha, dn_alpha,
79
+ variant, up, hidden, out,
80
+ ) -> None:
81
+ return None
82
+
83
+
84
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_gelu_ffn_bf16"))
85
+ def _w8_gelu_fake(
86
+ x, up_w, up_s, dn_w, dn_s, up_b, dn_b, variant, up, hidden, out,
87
+ ) -> None:
88
+ return None
89
+
90
+
91
+ def quantize_w4_weight_bf16(weight: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
92
+ """Pack a static BF16 weight matrix into NVFP4 data and SFB scales."""
93
+ n, k = weight.shape
94
+ packed = torch.empty((n, k // 2), device=weight.device, dtype=torch.uint8)
95
+ sfb = torch.empty((w4_sfb_size_bytes(n, k),), device=weight.device, dtype=torch.uint8)
96
+ ops.quantize_w4_weight_bf16(weight, packed, sfb)
97
+ return packed, sfb
98
+
99
+
100
+ def dequantize_w4_weight_bf16(
101
+ packed: torch.Tensor, sfb: torch.Tensor, *, cols: int
102
+ ) -> torch.Tensor:
103
+ weight = torch.empty((packed.shape[0], int(cols)), device=packed.device, dtype=torch.bfloat16)
104
+ ops.dequantize_w4_weight_bf16(packed, sfb, weight)
105
+ return weight
106
+
107
+
108
+ def quantize_w8_weight_bf16(weight: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
109
+ """Symmetrically quantize a static BF16 weight matrix per output channel."""
110
+ quantized = torch.empty_like(weight, dtype=torch.int8)
111
+ scales = torch.empty((weight.shape[0],), device=weight.device, dtype=torch.float32)
112
+ ops.quantize_w8_weight_bf16(weight, quantized, scales)
113
+ return quantized, scales
114
+
115
+
116
+ def dequantize_w8_weight_bf16(
117
+ quantized: torch.Tensor, scales: torch.Tensor
118
+ ) -> torch.Tensor:
119
+ weight = torch.empty_like(quantized, dtype=torch.bfloat16)
120
+ ops.dequantize_w8_weight_bf16(quantized, scales, weight)
121
+ return weight
122
+
123
+
124
+ def w4a16_linear_bf16(
125
+ x: torch.Tensor,
126
+ weight_packed: torch.Tensor,
127
+ weight_sfb: torch.Tensor,
128
+ *,
129
+ alpha: float = 1.0,
130
+ variant: int = 0,
131
+ out: Optional[torch.Tensor] = None,
132
+ ) -> torch.Tensor:
133
+ if out is None:
134
+ out = torch.empty((x.shape[0], weight_packed.shape[0]), device=x.device, dtype=torch.bfloat16)
135
+ ops.w4a16_linear_bf16(x, weight_packed, weight_sfb, float(alpha), int(variant), out)
136
+ return out
137
+
138
+
139
+ def w8a16_linear_bf16(
140
+ x: torch.Tensor,
141
+ weight_int8: torch.Tensor,
142
+ weight_scale: torch.Tensor,
143
+ *,
144
+ variant: int = 0,
145
+ out: Optional[torch.Tensor] = None,
146
+ ) -> torch.Tensor:
147
+ if out is None:
148
+ out = torch.empty((x.shape[0], weight_int8.shape[0]), device=x.device, dtype=torch.bfloat16)
149
+ ops.w8a16_linear_bf16(x, weight_int8, weight_scale, int(variant), out)
150
+ return out
151
+
152
+
153
+ def _gated_workspace(x: torch.Tensor, gate_up_rows: int, out_rows: int, workspace, out):
154
+ hidden_size = gate_up_rows // 2
155
+ if workspace is None:
156
+ gate_up = torch.empty((x.shape[0], gate_up_rows), device=x.device, dtype=torch.bfloat16)
157
+ hidden = torch.empty((x.shape[0], hidden_size), device=x.device, dtype=torch.bfloat16)
158
+ else:
159
+ gate_up, hidden = workspace
160
+ if out is None:
161
+ out = torch.empty((x.shape[0], out_rows), device=x.device, dtype=torch.bfloat16)
162
+ return gate_up, hidden, out
163
+
164
+
165
+ def _gelu_workspace(x: torch.Tensor, hidden_size: int, out_rows: int, workspace, out):
166
+ if workspace is None:
167
+ up = torch.empty((x.shape[0], hidden_size), device=x.device, dtype=torch.bfloat16)
168
+ hidden = torch.empty_like(up)
169
+ else:
170
+ up, hidden = workspace
171
+ if out is None:
172
+ out = torch.empty((x.shape[0], out_rows), device=x.device, dtype=torch.bfloat16)
173
+ return up, hidden, out
174
+
175
+
176
+ def _w4_gated(
177
+ x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, *, gelu,
178
+ gate_up_bias=None, down_bias=None, gate_up_alpha=1.0, down_alpha=1.0,
179
+ variant=0, workspace=None, out=None,
180
+ ):
181
+ gate_up, hidden, out = _gated_workspace(
182
+ x, gate_up_weight.shape[0], down_weight.shape[0], workspace, out
183
+ )
184
+ ops.w4a16_gated_ffn_bf16(
185
+ x, gate_up_weight, gate_up_sfb, down_weight, down_sfb,
186
+ gate_up_bias, down_bias, bool(gelu), float(gate_up_alpha),
187
+ float(down_alpha), int(variant), gate_up, hidden, out,
188
+ )
189
+ return out
190
+
191
+
192
+ def w4a16_swiglu_ffn_bf16(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, **kwargs):
193
+ return _w4_gated(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, gelu=False, **kwargs)
194
+
195
+
196
+ def w4a16_geglu_ffn_bf16(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, **kwargs):
197
+ return _w4_gated(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, gelu=True, **kwargs)
198
+
199
+
200
+ def _w8_gated(
201
+ x, gate_up_weight, gate_up_scale, down_weight, down_scale, *, gelu,
202
+ gate_up_bias=None, down_bias=None, variant=0, workspace=None, out=None,
203
+ ):
204
+ gate_up, hidden, out = _gated_workspace(
205
+ x, gate_up_weight.shape[0], down_weight.shape[0], workspace, out
206
+ )
207
+ ops.w8a16_gated_ffn_bf16(
208
+ x, gate_up_weight, gate_up_scale, down_weight, down_scale,
209
+ gate_up_bias, down_bias, bool(gelu), int(variant), gate_up, hidden, out,
210
+ )
211
+ return out
212
+
213
+
214
+ def w8a16_swiglu_ffn_bf16(x, gate_up_weight, gate_up_scale, down_weight, down_scale, **kwargs):
215
+ return _w8_gated(x, gate_up_weight, gate_up_scale, down_weight, down_scale, gelu=False, **kwargs)
216
+
217
+
218
+ def w8a16_geglu_ffn_bf16(x, gate_up_weight, gate_up_scale, down_weight, down_scale, **kwargs):
219
+ return _w8_gated(x, gate_up_weight, gate_up_scale, down_weight, down_scale, gelu=True, **kwargs)
220
+
221
+
222
+ def w4a16_gelu_ffn_bf16(
223
+ x, up_weight, up_sfb, down_weight, down_sfb, *, up_bias=None,
224
+ down_bias=None, up_alpha=1.0, down_alpha=1.0, variant=0,
225
+ workspace=None, out=None,
226
+ ):
227
+ up, hidden, out = _gelu_workspace(x, up_weight.shape[0], down_weight.shape[0], workspace, out)
228
+ ops.w4a16_gelu_ffn_bf16(
229
+ x, up_weight, up_sfb, down_weight, down_sfb, up_bias, down_bias,
230
+ float(up_alpha), float(down_alpha), int(variant), up, hidden, out,
231
+ )
232
+ return out
233
+
234
+
235
+ def w8a16_gelu_ffn_bf16(
236
+ x, up_weight, up_scale, down_weight, down_scale, *, up_bias=None,
237
+ down_bias=None, variant=0, workspace=None, out=None,
238
+ ):
239
+ up, hidden, out = _gelu_workspace(x, up_weight.shape[0], down_weight.shape[0], workspace, out)
240
+ ops.w8a16_gelu_ffn_bf16(
241
+ x, up_weight, up_scale, down_weight, down_scale, up_bias, down_bias,
242
+ int(variant), up, hidden, out,
243
+ )
244
+ return out
245
+
246
+
247
+ __all__ = [
248
+ "dequantize_w4_weight_bf16",
249
+ "dequantize_w8_weight_bf16",
250
+ "quantize_w4_weight_bf16",
251
+ "quantize_w8_weight_bf16",
252
+ "w4_sfb_size_bytes",
253
+ "w4a16_geglu_ffn_bf16",
254
+ "w4a16_gelu_ffn_bf16",
255
+ "w4a16_linear_bf16",
256
+ "w4a16_swiglu_ffn_bf16",
257
+ "w8a16_geglu_ffn_bf16",
258
+ "w8a16_gelu_ffn_bf16",
259
+ "w8a16_linear_bf16",
260
+ "w8a16_swiglu_ffn_bf16",
261
+ ]
build/torch212-cxx11-cu130-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _weight_only_ffn_cuda_38d37b6
3
+ ops = torch.ops._weight_only_ffn_cuda_38d37b6
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_weight_only_ffn_cuda_38d37b6::{op_name}"
build/torch212-cxx11-cu130-x86_64-linux/_weight_only_ffn_cuda_38d37b6.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ebcf5ff2f3270a0327712bb8c917a6aa036140f7a2c065849dd897a58898261b
3
+ size 1906560
build/torch212-cxx11-cu130-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "weight-only-ffn",
3
+ "id": "_weight_only_ffn_cuda_38d37b6",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "11.0a",
11
+ "12.0a",
12
+ "12.1"
13
+ ]
14
+ },
15
+ "digest": {
16
+ "algorithm": "sha256",
17
+ "files": {
18
+ "__init__.py": "0q6TMj65una1LdyHLC291Dwy2VzrBbAD8Wm8MEdmqwA=",
19
+ "_ops.py": "iqY+HoE4nGHqvVlEZTwEAcyu1/w+QrjwuuW9sdTI2uk=",
20
+ "_weight_only_ffn_cuda_38d37b6.abi3.so": "689f8vMnCgMncSu4yRemqgNhQPeiwGWEndiXpYiYJhs=",
21
+ "weight_only_ffn/__init__.py": "DFYPlrhXwYjEqCl/8n0SmWGZV8NFml5DPhMjKfv98GY="
22
+ }
23
+ },
24
+ "provenance": {
25
+ "kernel-builder": {
26
+ "version": "0.17.0-dev0",
27
+ "sha": "19aaa6421e674e9fecc352bbae6eab81d19a6bf4",
28
+ "dirty": false
29
+ },
30
+ "kernel": {
31
+ "sha": "38d37b67acfe940c99d7b3db721fa67163b82cec",
32
+ "dirty": false
33
+ }
34
+ }
35
+ }
build/torch212-cxx11-cu130-x86_64-linux/weight_only_ffn/__init__.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ctypes
2
+ import importlib.util
3
+ import sys
4
+ from pathlib import Path
5
+ from types import ModuleType
6
+
7
+
8
+ def _import_from_path(file_path: Path) -> ModuleType:
9
+ # We cannot use the module name as-is, after adding it to `sys.modules`,
10
+ # it would also be used for other imports. So, we make a module name that
11
+ # depends on the path for it to be unique using the hex-encoded hash of
12
+ # the path.
13
+ path_hash = "{:x}".format(ctypes.c_size_t(hash(file_path.absolute())).value)
14
+ module_name = path_hash
15
+ spec = importlib.util.spec_from_file_location(module_name, file_path)
16
+ if spec is None:
17
+ raise ImportError(f"Cannot load spec for {module_name} from {file_path}")
18
+ module = importlib.util.module_from_spec(spec)
19
+ if module is None:
20
+ raise ImportError(f"Cannot load module {module_name} from spec")
21
+ sys.modules[module_name] = module
22
+ spec.loader.exec_module(module) # type: ignore
23
+ return module
24
+
25
+
26
+ globals().update(vars(_import_from_path(Path(__file__).parent.parent / "__init__.py")))
build/torch212-cxx11-cu132-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Weight-only BF16-activation linear and FFN regions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Optional
6
+
7
+ import torch
8
+
9
+ from ._ops import add_op_namespace_prefix, ops
10
+
11
+
12
+ def w4_sfb_size_bytes(rows: int, cols: int) -> int:
13
+ if rows <= 0 or cols <= 0 or cols % 64:
14
+ raise ValueError("rows must be positive and cols must be divisible by 64")
15
+ return ((int(rows) + 127) // 128) * (((int(cols) // 16) + 3) // 4) * 512
16
+
17
+
18
+ @torch.library.register_fake(add_op_namespace_prefix("quantize_w4_weight_bf16"))
19
+ def _quantize_w4_fake(weight: torch.Tensor, packed: torch.Tensor, sfb: torch.Tensor) -> None:
20
+ return None
21
+
22
+
23
+ @torch.library.register_fake(add_op_namespace_prefix("dequantize_w4_weight_bf16"))
24
+ def _dequantize_w4_fake(packed: torch.Tensor, sfb: torch.Tensor, weight: torch.Tensor) -> None:
25
+ return None
26
+
27
+
28
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_linear_bf16"))
29
+ def _w4_linear_fake(
30
+ x: torch.Tensor,
31
+ packed: torch.Tensor,
32
+ sfb: torch.Tensor,
33
+ alpha: float,
34
+ variant: int,
35
+ out: torch.Tensor,
36
+ ) -> None:
37
+ return None
38
+
39
+
40
+ @torch.library.register_fake(add_op_namespace_prefix("quantize_w8_weight_bf16"))
41
+ def _quantize_w8_fake(weight: torch.Tensor, quantized: torch.Tensor, scales: torch.Tensor) -> None:
42
+ return None
43
+
44
+
45
+ @torch.library.register_fake(add_op_namespace_prefix("dequantize_w8_weight_bf16"))
46
+ def _dequantize_w8_fake(quantized: torch.Tensor, scales: torch.Tensor, weight: torch.Tensor) -> None:
47
+ return None
48
+
49
+
50
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_linear_bf16"))
51
+ def _w8_linear_fake(
52
+ x: torch.Tensor,
53
+ quantized: torch.Tensor,
54
+ scales: torch.Tensor,
55
+ variant: int,
56
+ out: torch.Tensor,
57
+ ) -> None:
58
+ return None
59
+
60
+
61
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_gated_ffn_bf16"))
62
+ def _w4_gated_fake(
63
+ x, gu_w, gu_s, dn_w, dn_s, gu_b, dn_b, gelu, gu_alpha, dn_alpha,
64
+ variant, gu, hidden, out,
65
+ ) -> None:
66
+ return None
67
+
68
+
69
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_gated_ffn_bf16"))
70
+ def _w8_gated_fake(
71
+ x, gu_w, gu_s, dn_w, dn_s, gu_b, dn_b, gelu, variant, gu, hidden, out,
72
+ ) -> None:
73
+ return None
74
+
75
+
76
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_gelu_ffn_bf16"))
77
+ def _w4_gelu_fake(
78
+ x, up_w, up_s, dn_w, dn_s, up_b, dn_b, up_alpha, dn_alpha,
79
+ variant, up, hidden, out,
80
+ ) -> None:
81
+ return None
82
+
83
+
84
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_gelu_ffn_bf16"))
85
+ def _w8_gelu_fake(
86
+ x, up_w, up_s, dn_w, dn_s, up_b, dn_b, variant, up, hidden, out,
87
+ ) -> None:
88
+ return None
89
+
90
+
91
+ def quantize_w4_weight_bf16(weight: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
92
+ """Pack a static BF16 weight matrix into NVFP4 data and SFB scales."""
93
+ n, k = weight.shape
94
+ packed = torch.empty((n, k // 2), device=weight.device, dtype=torch.uint8)
95
+ sfb = torch.empty((w4_sfb_size_bytes(n, k),), device=weight.device, dtype=torch.uint8)
96
+ ops.quantize_w4_weight_bf16(weight, packed, sfb)
97
+ return packed, sfb
98
+
99
+
100
+ def dequantize_w4_weight_bf16(
101
+ packed: torch.Tensor, sfb: torch.Tensor, *, cols: int
102
+ ) -> torch.Tensor:
103
+ weight = torch.empty((packed.shape[0], int(cols)), device=packed.device, dtype=torch.bfloat16)
104
+ ops.dequantize_w4_weight_bf16(packed, sfb, weight)
105
+ return weight
106
+
107
+
108
+ def quantize_w8_weight_bf16(weight: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
109
+ """Symmetrically quantize a static BF16 weight matrix per output channel."""
110
+ quantized = torch.empty_like(weight, dtype=torch.int8)
111
+ scales = torch.empty((weight.shape[0],), device=weight.device, dtype=torch.float32)
112
+ ops.quantize_w8_weight_bf16(weight, quantized, scales)
113
+ return quantized, scales
114
+
115
+
116
+ def dequantize_w8_weight_bf16(
117
+ quantized: torch.Tensor, scales: torch.Tensor
118
+ ) -> torch.Tensor:
119
+ weight = torch.empty_like(quantized, dtype=torch.bfloat16)
120
+ ops.dequantize_w8_weight_bf16(quantized, scales, weight)
121
+ return weight
122
+
123
+
124
+ def w4a16_linear_bf16(
125
+ x: torch.Tensor,
126
+ weight_packed: torch.Tensor,
127
+ weight_sfb: torch.Tensor,
128
+ *,
129
+ alpha: float = 1.0,
130
+ variant: int = 0,
131
+ out: Optional[torch.Tensor] = None,
132
+ ) -> torch.Tensor:
133
+ if out is None:
134
+ out = torch.empty((x.shape[0], weight_packed.shape[0]), device=x.device, dtype=torch.bfloat16)
135
+ ops.w4a16_linear_bf16(x, weight_packed, weight_sfb, float(alpha), int(variant), out)
136
+ return out
137
+
138
+
139
+ def w8a16_linear_bf16(
140
+ x: torch.Tensor,
141
+ weight_int8: torch.Tensor,
142
+ weight_scale: torch.Tensor,
143
+ *,
144
+ variant: int = 0,
145
+ out: Optional[torch.Tensor] = None,
146
+ ) -> torch.Tensor:
147
+ if out is None:
148
+ out = torch.empty((x.shape[0], weight_int8.shape[0]), device=x.device, dtype=torch.bfloat16)
149
+ ops.w8a16_linear_bf16(x, weight_int8, weight_scale, int(variant), out)
150
+ return out
151
+
152
+
153
+ def _gated_workspace(x: torch.Tensor, gate_up_rows: int, out_rows: int, workspace, out):
154
+ hidden_size = gate_up_rows // 2
155
+ if workspace is None:
156
+ gate_up = torch.empty((x.shape[0], gate_up_rows), device=x.device, dtype=torch.bfloat16)
157
+ hidden = torch.empty((x.shape[0], hidden_size), device=x.device, dtype=torch.bfloat16)
158
+ else:
159
+ gate_up, hidden = workspace
160
+ if out is None:
161
+ out = torch.empty((x.shape[0], out_rows), device=x.device, dtype=torch.bfloat16)
162
+ return gate_up, hidden, out
163
+
164
+
165
+ def _gelu_workspace(x: torch.Tensor, hidden_size: int, out_rows: int, workspace, out):
166
+ if workspace is None:
167
+ up = torch.empty((x.shape[0], hidden_size), device=x.device, dtype=torch.bfloat16)
168
+ hidden = torch.empty_like(up)
169
+ else:
170
+ up, hidden = workspace
171
+ if out is None:
172
+ out = torch.empty((x.shape[0], out_rows), device=x.device, dtype=torch.bfloat16)
173
+ return up, hidden, out
174
+
175
+
176
+ def _w4_gated(
177
+ x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, *, gelu,
178
+ gate_up_bias=None, down_bias=None, gate_up_alpha=1.0, down_alpha=1.0,
179
+ variant=0, workspace=None, out=None,
180
+ ):
181
+ gate_up, hidden, out = _gated_workspace(
182
+ x, gate_up_weight.shape[0], down_weight.shape[0], workspace, out
183
+ )
184
+ ops.w4a16_gated_ffn_bf16(
185
+ x, gate_up_weight, gate_up_sfb, down_weight, down_sfb,
186
+ gate_up_bias, down_bias, bool(gelu), float(gate_up_alpha),
187
+ float(down_alpha), int(variant), gate_up, hidden, out,
188
+ )
189
+ return out
190
+
191
+
192
+ def w4a16_swiglu_ffn_bf16(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, **kwargs):
193
+ return _w4_gated(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, gelu=False, **kwargs)
194
+
195
+
196
+ def w4a16_geglu_ffn_bf16(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, **kwargs):
197
+ return _w4_gated(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, gelu=True, **kwargs)
198
+
199
+
200
+ def _w8_gated(
201
+ x, gate_up_weight, gate_up_scale, down_weight, down_scale, *, gelu,
202
+ gate_up_bias=None, down_bias=None, variant=0, workspace=None, out=None,
203
+ ):
204
+ gate_up, hidden, out = _gated_workspace(
205
+ x, gate_up_weight.shape[0], down_weight.shape[0], workspace, out
206
+ )
207
+ ops.w8a16_gated_ffn_bf16(
208
+ x, gate_up_weight, gate_up_scale, down_weight, down_scale,
209
+ gate_up_bias, down_bias, bool(gelu), int(variant), gate_up, hidden, out,
210
+ )
211
+ return out
212
+
213
+
214
+ def w8a16_swiglu_ffn_bf16(x, gate_up_weight, gate_up_scale, down_weight, down_scale, **kwargs):
215
+ return _w8_gated(x, gate_up_weight, gate_up_scale, down_weight, down_scale, gelu=False, **kwargs)
216
+
217
+
218
+ def w8a16_geglu_ffn_bf16(x, gate_up_weight, gate_up_scale, down_weight, down_scale, **kwargs):
219
+ return _w8_gated(x, gate_up_weight, gate_up_scale, down_weight, down_scale, gelu=True, **kwargs)
220
+
221
+
222
+ def w4a16_gelu_ffn_bf16(
223
+ x, up_weight, up_sfb, down_weight, down_sfb, *, up_bias=None,
224
+ down_bias=None, up_alpha=1.0, down_alpha=1.0, variant=0,
225
+ workspace=None, out=None,
226
+ ):
227
+ up, hidden, out = _gelu_workspace(x, up_weight.shape[0], down_weight.shape[0], workspace, out)
228
+ ops.w4a16_gelu_ffn_bf16(
229
+ x, up_weight, up_sfb, down_weight, down_sfb, up_bias, down_bias,
230
+ float(up_alpha), float(down_alpha), int(variant), up, hidden, out,
231
+ )
232
+ return out
233
+
234
+
235
+ def w8a16_gelu_ffn_bf16(
236
+ x, up_weight, up_scale, down_weight, down_scale, *, up_bias=None,
237
+ down_bias=None, variant=0, workspace=None, out=None,
238
+ ):
239
+ up, hidden, out = _gelu_workspace(x, up_weight.shape[0], down_weight.shape[0], workspace, out)
240
+ ops.w8a16_gelu_ffn_bf16(
241
+ x, up_weight, up_scale, down_weight, down_scale, up_bias, down_bias,
242
+ int(variant), up, hidden, out,
243
+ )
244
+ return out
245
+
246
+
247
+ __all__ = [
248
+ "dequantize_w4_weight_bf16",
249
+ "dequantize_w8_weight_bf16",
250
+ "quantize_w4_weight_bf16",
251
+ "quantize_w8_weight_bf16",
252
+ "w4_sfb_size_bytes",
253
+ "w4a16_geglu_ffn_bf16",
254
+ "w4a16_gelu_ffn_bf16",
255
+ "w4a16_linear_bf16",
256
+ "w4a16_swiglu_ffn_bf16",
257
+ "w8a16_geglu_ffn_bf16",
258
+ "w8a16_gelu_ffn_bf16",
259
+ "w8a16_linear_bf16",
260
+ "w8a16_swiglu_ffn_bf16",
261
+ ]
build/torch212-cxx11-cu132-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _weight_only_ffn_cuda_38d37b6
3
+ ops = torch.ops._weight_only_ffn_cuda_38d37b6
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_weight_only_ffn_cuda_38d37b6::{op_name}"
build/torch212-cxx11-cu132-x86_64-linux/_weight_only_ffn_cuda_38d37b6.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8ef5420caa2f23097e3e8f9777250c9bbb98618fe76493d492e5cb5a5f09336c
3
+ size 1906560
build/torch212-cxx11-cu132-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "weight-only-ffn",
3
+ "id": "_weight_only_ffn_cuda_38d37b6",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "11.0a",
11
+ "12.0a",
12
+ "12.1"
13
+ ]
14
+ },
15
+ "digest": {
16
+ "algorithm": "sha256",
17
+ "files": {
18
+ "__init__.py": "0q6TMj65una1LdyHLC291Dwy2VzrBbAD8Wm8MEdmqwA=",
19
+ "_ops.py": "iqY+HoE4nGHqvVlEZTwEAcyu1/w+QrjwuuW9sdTI2uk=",
20
+ "_weight_only_ffn_cuda_38d37b6.abi3.so": "jvVCDKovIwl+Po+XdyUMm7uYYY/nZJPUkuXLWl8JM2w=",
21
+ "weight_only_ffn/__init__.py": "DFYPlrhXwYjEqCl/8n0SmWGZV8NFml5DPhMjKfv98GY="
22
+ }
23
+ },
24
+ "provenance": {
25
+ "kernel-builder": {
26
+ "version": "0.17.0-dev0",
27
+ "sha": "19aaa6421e674e9fecc352bbae6eab81d19a6bf4",
28
+ "dirty": false
29
+ },
30
+ "kernel": {
31
+ "sha": "38d37b67acfe940c99d7b3db721fa67163b82cec",
32
+ "dirty": false
33
+ }
34
+ }
35
+ }
build/torch212-cxx11-cu132-x86_64-linux/weight_only_ffn/__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-aarch64-linux/__init__.py ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Weight-only BF16-activation linear and FFN regions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Optional
6
+
7
+ import torch
8
+
9
+ from ._ops import add_op_namespace_prefix, ops
10
+
11
+
12
+ def w4_sfb_size_bytes(rows: int, cols: int) -> int:
13
+ if rows <= 0 or cols <= 0 or cols % 64:
14
+ raise ValueError("rows must be positive and cols must be divisible by 64")
15
+ return ((int(rows) + 127) // 128) * (((int(cols) // 16) + 3) // 4) * 512
16
+
17
+
18
+ @torch.library.register_fake(add_op_namespace_prefix("quantize_w4_weight_bf16"))
19
+ def _quantize_w4_fake(weight: torch.Tensor, packed: torch.Tensor, sfb: torch.Tensor) -> None:
20
+ return None
21
+
22
+
23
+ @torch.library.register_fake(add_op_namespace_prefix("dequantize_w4_weight_bf16"))
24
+ def _dequantize_w4_fake(packed: torch.Tensor, sfb: torch.Tensor, weight: torch.Tensor) -> None:
25
+ return None
26
+
27
+
28
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_linear_bf16"))
29
+ def _w4_linear_fake(
30
+ x: torch.Tensor,
31
+ packed: torch.Tensor,
32
+ sfb: torch.Tensor,
33
+ alpha: float,
34
+ variant: int,
35
+ out: torch.Tensor,
36
+ ) -> None:
37
+ return None
38
+
39
+
40
+ @torch.library.register_fake(add_op_namespace_prefix("quantize_w8_weight_bf16"))
41
+ def _quantize_w8_fake(weight: torch.Tensor, quantized: torch.Tensor, scales: torch.Tensor) -> None:
42
+ return None
43
+
44
+
45
+ @torch.library.register_fake(add_op_namespace_prefix("dequantize_w8_weight_bf16"))
46
+ def _dequantize_w8_fake(quantized: torch.Tensor, scales: torch.Tensor, weight: torch.Tensor) -> None:
47
+ return None
48
+
49
+
50
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_linear_bf16"))
51
+ def _w8_linear_fake(
52
+ x: torch.Tensor,
53
+ quantized: torch.Tensor,
54
+ scales: torch.Tensor,
55
+ variant: int,
56
+ out: torch.Tensor,
57
+ ) -> None:
58
+ return None
59
+
60
+
61
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_gated_ffn_bf16"))
62
+ def _w4_gated_fake(
63
+ x, gu_w, gu_s, dn_w, dn_s, gu_b, dn_b, gelu, gu_alpha, dn_alpha,
64
+ variant, gu, hidden, out,
65
+ ) -> None:
66
+ return None
67
+
68
+
69
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_gated_ffn_bf16"))
70
+ def _w8_gated_fake(
71
+ x, gu_w, gu_s, dn_w, dn_s, gu_b, dn_b, gelu, variant, gu, hidden, out,
72
+ ) -> None:
73
+ return None
74
+
75
+
76
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_gelu_ffn_bf16"))
77
+ def _w4_gelu_fake(
78
+ x, up_w, up_s, dn_w, dn_s, up_b, dn_b, up_alpha, dn_alpha,
79
+ variant, up, hidden, out,
80
+ ) -> None:
81
+ return None
82
+
83
+
84
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_gelu_ffn_bf16"))
85
+ def _w8_gelu_fake(
86
+ x, up_w, up_s, dn_w, dn_s, up_b, dn_b, variant, up, hidden, out,
87
+ ) -> None:
88
+ return None
89
+
90
+
91
+ def quantize_w4_weight_bf16(weight: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
92
+ """Pack a static BF16 weight matrix into NVFP4 data and SFB scales."""
93
+ n, k = weight.shape
94
+ packed = torch.empty((n, k // 2), device=weight.device, dtype=torch.uint8)
95
+ sfb = torch.empty((w4_sfb_size_bytes(n, k),), device=weight.device, dtype=torch.uint8)
96
+ ops.quantize_w4_weight_bf16(weight, packed, sfb)
97
+ return packed, sfb
98
+
99
+
100
+ def dequantize_w4_weight_bf16(
101
+ packed: torch.Tensor, sfb: torch.Tensor, *, cols: int
102
+ ) -> torch.Tensor:
103
+ weight = torch.empty((packed.shape[0], int(cols)), device=packed.device, dtype=torch.bfloat16)
104
+ ops.dequantize_w4_weight_bf16(packed, sfb, weight)
105
+ return weight
106
+
107
+
108
+ def quantize_w8_weight_bf16(weight: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
109
+ """Symmetrically quantize a static BF16 weight matrix per output channel."""
110
+ quantized = torch.empty_like(weight, dtype=torch.int8)
111
+ scales = torch.empty((weight.shape[0],), device=weight.device, dtype=torch.float32)
112
+ ops.quantize_w8_weight_bf16(weight, quantized, scales)
113
+ return quantized, scales
114
+
115
+
116
+ def dequantize_w8_weight_bf16(
117
+ quantized: torch.Tensor, scales: torch.Tensor
118
+ ) -> torch.Tensor:
119
+ weight = torch.empty_like(quantized, dtype=torch.bfloat16)
120
+ ops.dequantize_w8_weight_bf16(quantized, scales, weight)
121
+ return weight
122
+
123
+
124
+ def w4a16_linear_bf16(
125
+ x: torch.Tensor,
126
+ weight_packed: torch.Tensor,
127
+ weight_sfb: torch.Tensor,
128
+ *,
129
+ alpha: float = 1.0,
130
+ variant: int = 0,
131
+ out: Optional[torch.Tensor] = None,
132
+ ) -> torch.Tensor:
133
+ if out is None:
134
+ out = torch.empty((x.shape[0], weight_packed.shape[0]), device=x.device, dtype=torch.bfloat16)
135
+ ops.w4a16_linear_bf16(x, weight_packed, weight_sfb, float(alpha), int(variant), out)
136
+ return out
137
+
138
+
139
+ def w8a16_linear_bf16(
140
+ x: torch.Tensor,
141
+ weight_int8: torch.Tensor,
142
+ weight_scale: torch.Tensor,
143
+ *,
144
+ variant: int = 0,
145
+ out: Optional[torch.Tensor] = None,
146
+ ) -> torch.Tensor:
147
+ if out is None:
148
+ out = torch.empty((x.shape[0], weight_int8.shape[0]), device=x.device, dtype=torch.bfloat16)
149
+ ops.w8a16_linear_bf16(x, weight_int8, weight_scale, int(variant), out)
150
+ return out
151
+
152
+
153
+ def _gated_workspace(x: torch.Tensor, gate_up_rows: int, out_rows: int, workspace, out):
154
+ hidden_size = gate_up_rows // 2
155
+ if workspace is None:
156
+ gate_up = torch.empty((x.shape[0], gate_up_rows), device=x.device, dtype=torch.bfloat16)
157
+ hidden = torch.empty((x.shape[0], hidden_size), device=x.device, dtype=torch.bfloat16)
158
+ else:
159
+ gate_up, hidden = workspace
160
+ if out is None:
161
+ out = torch.empty((x.shape[0], out_rows), device=x.device, dtype=torch.bfloat16)
162
+ return gate_up, hidden, out
163
+
164
+
165
+ def _gelu_workspace(x: torch.Tensor, hidden_size: int, out_rows: int, workspace, out):
166
+ if workspace is None:
167
+ up = torch.empty((x.shape[0], hidden_size), device=x.device, dtype=torch.bfloat16)
168
+ hidden = torch.empty_like(up)
169
+ else:
170
+ up, hidden = workspace
171
+ if out is None:
172
+ out = torch.empty((x.shape[0], out_rows), device=x.device, dtype=torch.bfloat16)
173
+ return up, hidden, out
174
+
175
+
176
+ def _w4_gated(
177
+ x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, *, gelu,
178
+ gate_up_bias=None, down_bias=None, gate_up_alpha=1.0, down_alpha=1.0,
179
+ variant=0, workspace=None, out=None,
180
+ ):
181
+ gate_up, hidden, out = _gated_workspace(
182
+ x, gate_up_weight.shape[0], down_weight.shape[0], workspace, out
183
+ )
184
+ ops.w4a16_gated_ffn_bf16(
185
+ x, gate_up_weight, gate_up_sfb, down_weight, down_sfb,
186
+ gate_up_bias, down_bias, bool(gelu), float(gate_up_alpha),
187
+ float(down_alpha), int(variant), gate_up, hidden, out,
188
+ )
189
+ return out
190
+
191
+
192
+ def w4a16_swiglu_ffn_bf16(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, **kwargs):
193
+ return _w4_gated(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, gelu=False, **kwargs)
194
+
195
+
196
+ def w4a16_geglu_ffn_bf16(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, **kwargs):
197
+ return _w4_gated(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, gelu=True, **kwargs)
198
+
199
+
200
+ def _w8_gated(
201
+ x, gate_up_weight, gate_up_scale, down_weight, down_scale, *, gelu,
202
+ gate_up_bias=None, down_bias=None, variant=0, workspace=None, out=None,
203
+ ):
204
+ gate_up, hidden, out = _gated_workspace(
205
+ x, gate_up_weight.shape[0], down_weight.shape[0], workspace, out
206
+ )
207
+ ops.w8a16_gated_ffn_bf16(
208
+ x, gate_up_weight, gate_up_scale, down_weight, down_scale,
209
+ gate_up_bias, down_bias, bool(gelu), int(variant), gate_up, hidden, out,
210
+ )
211
+ return out
212
+
213
+
214
+ def w8a16_swiglu_ffn_bf16(x, gate_up_weight, gate_up_scale, down_weight, down_scale, **kwargs):
215
+ return _w8_gated(x, gate_up_weight, gate_up_scale, down_weight, down_scale, gelu=False, **kwargs)
216
+
217
+
218
+ def w8a16_geglu_ffn_bf16(x, gate_up_weight, gate_up_scale, down_weight, down_scale, **kwargs):
219
+ return _w8_gated(x, gate_up_weight, gate_up_scale, down_weight, down_scale, gelu=True, **kwargs)
220
+
221
+
222
+ def w4a16_gelu_ffn_bf16(
223
+ x, up_weight, up_sfb, down_weight, down_sfb, *, up_bias=None,
224
+ down_bias=None, up_alpha=1.0, down_alpha=1.0, variant=0,
225
+ workspace=None, out=None,
226
+ ):
227
+ up, hidden, out = _gelu_workspace(x, up_weight.shape[0], down_weight.shape[0], workspace, out)
228
+ ops.w4a16_gelu_ffn_bf16(
229
+ x, up_weight, up_sfb, down_weight, down_sfb, up_bias, down_bias,
230
+ float(up_alpha), float(down_alpha), int(variant), up, hidden, out,
231
+ )
232
+ return out
233
+
234
+
235
+ def w8a16_gelu_ffn_bf16(
236
+ x, up_weight, up_scale, down_weight, down_scale, *, up_bias=None,
237
+ down_bias=None, variant=0, workspace=None, out=None,
238
+ ):
239
+ up, hidden, out = _gelu_workspace(x, up_weight.shape[0], down_weight.shape[0], workspace, out)
240
+ ops.w8a16_gelu_ffn_bf16(
241
+ x, up_weight, up_scale, down_weight, down_scale, up_bias, down_bias,
242
+ int(variant), up, hidden, out,
243
+ )
244
+ return out
245
+
246
+
247
+ __all__ = [
248
+ "dequantize_w4_weight_bf16",
249
+ "dequantize_w8_weight_bf16",
250
+ "quantize_w4_weight_bf16",
251
+ "quantize_w8_weight_bf16",
252
+ "w4_sfb_size_bytes",
253
+ "w4a16_geglu_ffn_bf16",
254
+ "w4a16_gelu_ffn_bf16",
255
+ "w4a16_linear_bf16",
256
+ "w4a16_swiglu_ffn_bf16",
257
+ "w8a16_geglu_ffn_bf16",
258
+ "w8a16_gelu_ffn_bf16",
259
+ "w8a16_linear_bf16",
260
+ "w8a16_swiglu_ffn_bf16",
261
+ ]
build/torch213-cxx11-cu130-aarch64-linux/_ops.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import weight_only_ffn_source_test
3
+ ops = torch.ops.weight_only_ffn_source_test
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ return f"weight_only_ffn_source_test::{op_name}"
build/torch213-cxx11-cu130-aarch64-linux/metadata.json ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "weight-only-ffn",
3
+ "id": "weight_only_ffn_source_test",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "11.0a"
11
+ ]
12
+ },
13
+ "digest": {
14
+ "algorithm": "sha256",
15
+ "files": {
16
+ "__init__.py": "0q6TMj65una1LdyHLC291Dwy2VzrBbAD8Wm8MEdmqwA=",
17
+ "weight_only_ffn_source_test.abi3.so": "4bTmrdGoTStyhYzGGZQbYZmrMo/Hbq9EVXN9i//6Q3Q=",
18
+ "_ops.py": "sIcm8AtiXP5iJMFaDNUMdBLwzQULjS0N7fOxWIFF1DQ=",
19
+ "weight_only_ffn/__init__.py": "v6p5XMfQzddhi1fLSAw4HX9CyS0rQsidvu9VsT01xi4="
20
+ }
21
+ },
22
+ "provenance": {
23
+ "kernel": {
24
+ "sha": "456d297",
25
+ "dirty": false
26
+ },
27
+ "validation": {
28
+ "torch": "2.13.0+cu130",
29
+ "cuda": "13.0"
30
+ }
31
+ }
32
+ }
build/torch213-cxx11-cu130-aarch64-linux/weight_only_ffn/__init__.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ctypes
2
+ import importlib.util
3
+ import sys
4
+ from pathlib import Path
5
+
6
+ def _import_from_path(file_path: Path):
7
+ path_hash = '{:x}'.format(ctypes.c_size_t(hash(file_path.absolute())).value)
8
+ spec = importlib.util.spec_from_file_location(path_hash, file_path)
9
+ module = importlib.util.module_from_spec(spec)
10
+ sys.modules[path_hash] = module
11
+ spec.loader.exec_module(module)
12
+ return module
13
+
14
+ globals().update(vars(_import_from_path(Path(__file__).parent.parent / '__init__.py')))
build/torch213-cxx11-cu130-aarch64-linux/weight_only_ffn_source_test.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e1b4e6add1a84d2b72858cc619941b6199ab328fc76eaf4455737d8bfffa4374
3
+ size 825064
build/torch213-cxx11-cu130-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Weight-only BF16-activation linear and FFN regions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Optional
6
+
7
+ import torch
8
+
9
+ from ._ops import add_op_namespace_prefix, ops
10
+
11
+
12
+ def w4_sfb_size_bytes(rows: int, cols: int) -> int:
13
+ if rows <= 0 or cols <= 0 or cols % 64:
14
+ raise ValueError("rows must be positive and cols must be divisible by 64")
15
+ return ((int(rows) + 127) // 128) * (((int(cols) // 16) + 3) // 4) * 512
16
+
17
+
18
+ @torch.library.register_fake(add_op_namespace_prefix("quantize_w4_weight_bf16"))
19
+ def _quantize_w4_fake(weight: torch.Tensor, packed: torch.Tensor, sfb: torch.Tensor) -> None:
20
+ return None
21
+
22
+
23
+ @torch.library.register_fake(add_op_namespace_prefix("dequantize_w4_weight_bf16"))
24
+ def _dequantize_w4_fake(packed: torch.Tensor, sfb: torch.Tensor, weight: torch.Tensor) -> None:
25
+ return None
26
+
27
+
28
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_linear_bf16"))
29
+ def _w4_linear_fake(
30
+ x: torch.Tensor,
31
+ packed: torch.Tensor,
32
+ sfb: torch.Tensor,
33
+ alpha: float,
34
+ variant: int,
35
+ out: torch.Tensor,
36
+ ) -> None:
37
+ return None
38
+
39
+
40
+ @torch.library.register_fake(add_op_namespace_prefix("quantize_w8_weight_bf16"))
41
+ def _quantize_w8_fake(weight: torch.Tensor, quantized: torch.Tensor, scales: torch.Tensor) -> None:
42
+ return None
43
+
44
+
45
+ @torch.library.register_fake(add_op_namespace_prefix("dequantize_w8_weight_bf16"))
46
+ def _dequantize_w8_fake(quantized: torch.Tensor, scales: torch.Tensor, weight: torch.Tensor) -> None:
47
+ return None
48
+
49
+
50
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_linear_bf16"))
51
+ def _w8_linear_fake(
52
+ x: torch.Tensor,
53
+ quantized: torch.Tensor,
54
+ scales: torch.Tensor,
55
+ variant: int,
56
+ out: torch.Tensor,
57
+ ) -> None:
58
+ return None
59
+
60
+
61
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_gated_ffn_bf16"))
62
+ def _w4_gated_fake(
63
+ x, gu_w, gu_s, dn_w, dn_s, gu_b, dn_b, gelu, gu_alpha, dn_alpha,
64
+ variant, gu, hidden, out,
65
+ ) -> None:
66
+ return None
67
+
68
+
69
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_gated_ffn_bf16"))
70
+ def _w8_gated_fake(
71
+ x, gu_w, gu_s, dn_w, dn_s, gu_b, dn_b, gelu, variant, gu, hidden, out,
72
+ ) -> None:
73
+ return None
74
+
75
+
76
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_gelu_ffn_bf16"))
77
+ def _w4_gelu_fake(
78
+ x, up_w, up_s, dn_w, dn_s, up_b, dn_b, up_alpha, dn_alpha,
79
+ variant, up, hidden, out,
80
+ ) -> None:
81
+ return None
82
+
83
+
84
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_gelu_ffn_bf16"))
85
+ def _w8_gelu_fake(
86
+ x, up_w, up_s, dn_w, dn_s, up_b, dn_b, variant, up, hidden, out,
87
+ ) -> None:
88
+ return None
89
+
90
+
91
+ def quantize_w4_weight_bf16(weight: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
92
+ """Pack a static BF16 weight matrix into NVFP4 data and SFB scales."""
93
+ n, k = weight.shape
94
+ packed = torch.empty((n, k // 2), device=weight.device, dtype=torch.uint8)
95
+ sfb = torch.empty((w4_sfb_size_bytes(n, k),), device=weight.device, dtype=torch.uint8)
96
+ ops.quantize_w4_weight_bf16(weight, packed, sfb)
97
+ return packed, sfb
98
+
99
+
100
+ def dequantize_w4_weight_bf16(
101
+ packed: torch.Tensor, sfb: torch.Tensor, *, cols: int
102
+ ) -> torch.Tensor:
103
+ weight = torch.empty((packed.shape[0], int(cols)), device=packed.device, dtype=torch.bfloat16)
104
+ ops.dequantize_w4_weight_bf16(packed, sfb, weight)
105
+ return weight
106
+
107
+
108
+ def quantize_w8_weight_bf16(weight: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
109
+ """Symmetrically quantize a static BF16 weight matrix per output channel."""
110
+ quantized = torch.empty_like(weight, dtype=torch.int8)
111
+ scales = torch.empty((weight.shape[0],), device=weight.device, dtype=torch.float32)
112
+ ops.quantize_w8_weight_bf16(weight, quantized, scales)
113
+ return quantized, scales
114
+
115
+
116
+ def dequantize_w8_weight_bf16(
117
+ quantized: torch.Tensor, scales: torch.Tensor
118
+ ) -> torch.Tensor:
119
+ weight = torch.empty_like(quantized, dtype=torch.bfloat16)
120
+ ops.dequantize_w8_weight_bf16(quantized, scales, weight)
121
+ return weight
122
+
123
+
124
+ def w4a16_linear_bf16(
125
+ x: torch.Tensor,
126
+ weight_packed: torch.Tensor,
127
+ weight_sfb: torch.Tensor,
128
+ *,
129
+ alpha: float = 1.0,
130
+ variant: int = 0,
131
+ out: Optional[torch.Tensor] = None,
132
+ ) -> torch.Tensor:
133
+ if out is None:
134
+ out = torch.empty((x.shape[0], weight_packed.shape[0]), device=x.device, dtype=torch.bfloat16)
135
+ ops.w4a16_linear_bf16(x, weight_packed, weight_sfb, float(alpha), int(variant), out)
136
+ return out
137
+
138
+
139
+ def w8a16_linear_bf16(
140
+ x: torch.Tensor,
141
+ weight_int8: torch.Tensor,
142
+ weight_scale: torch.Tensor,
143
+ *,
144
+ variant: int = 0,
145
+ out: Optional[torch.Tensor] = None,
146
+ ) -> torch.Tensor:
147
+ if out is None:
148
+ out = torch.empty((x.shape[0], weight_int8.shape[0]), device=x.device, dtype=torch.bfloat16)
149
+ ops.w8a16_linear_bf16(x, weight_int8, weight_scale, int(variant), out)
150
+ return out
151
+
152
+
153
+ def _gated_workspace(x: torch.Tensor, gate_up_rows: int, out_rows: int, workspace, out):
154
+ hidden_size = gate_up_rows // 2
155
+ if workspace is None:
156
+ gate_up = torch.empty((x.shape[0], gate_up_rows), device=x.device, dtype=torch.bfloat16)
157
+ hidden = torch.empty((x.shape[0], hidden_size), device=x.device, dtype=torch.bfloat16)
158
+ else:
159
+ gate_up, hidden = workspace
160
+ if out is None:
161
+ out = torch.empty((x.shape[0], out_rows), device=x.device, dtype=torch.bfloat16)
162
+ return gate_up, hidden, out
163
+
164
+
165
+ def _gelu_workspace(x: torch.Tensor, hidden_size: int, out_rows: int, workspace, out):
166
+ if workspace is None:
167
+ up = torch.empty((x.shape[0], hidden_size), device=x.device, dtype=torch.bfloat16)
168
+ hidden = torch.empty_like(up)
169
+ else:
170
+ up, hidden = workspace
171
+ if out is None:
172
+ out = torch.empty((x.shape[0], out_rows), device=x.device, dtype=torch.bfloat16)
173
+ return up, hidden, out
174
+
175
+
176
+ def _w4_gated(
177
+ x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, *, gelu,
178
+ gate_up_bias=None, down_bias=None, gate_up_alpha=1.0, down_alpha=1.0,
179
+ variant=0, workspace=None, out=None,
180
+ ):
181
+ gate_up, hidden, out = _gated_workspace(
182
+ x, gate_up_weight.shape[0], down_weight.shape[0], workspace, out
183
+ )
184
+ ops.w4a16_gated_ffn_bf16(
185
+ x, gate_up_weight, gate_up_sfb, down_weight, down_sfb,
186
+ gate_up_bias, down_bias, bool(gelu), float(gate_up_alpha),
187
+ float(down_alpha), int(variant), gate_up, hidden, out,
188
+ )
189
+ return out
190
+
191
+
192
+ def w4a16_swiglu_ffn_bf16(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, **kwargs):
193
+ return _w4_gated(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, gelu=False, **kwargs)
194
+
195
+
196
+ def w4a16_geglu_ffn_bf16(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, **kwargs):
197
+ return _w4_gated(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, gelu=True, **kwargs)
198
+
199
+
200
+ def _w8_gated(
201
+ x, gate_up_weight, gate_up_scale, down_weight, down_scale, *, gelu,
202
+ gate_up_bias=None, down_bias=None, variant=0, workspace=None, out=None,
203
+ ):
204
+ gate_up, hidden, out = _gated_workspace(
205
+ x, gate_up_weight.shape[0], down_weight.shape[0], workspace, out
206
+ )
207
+ ops.w8a16_gated_ffn_bf16(
208
+ x, gate_up_weight, gate_up_scale, down_weight, down_scale,
209
+ gate_up_bias, down_bias, bool(gelu), int(variant), gate_up, hidden, out,
210
+ )
211
+ return out
212
+
213
+
214
+ def w8a16_swiglu_ffn_bf16(x, gate_up_weight, gate_up_scale, down_weight, down_scale, **kwargs):
215
+ return _w8_gated(x, gate_up_weight, gate_up_scale, down_weight, down_scale, gelu=False, **kwargs)
216
+
217
+
218
+ def w8a16_geglu_ffn_bf16(x, gate_up_weight, gate_up_scale, down_weight, down_scale, **kwargs):
219
+ return _w8_gated(x, gate_up_weight, gate_up_scale, down_weight, down_scale, gelu=True, **kwargs)
220
+
221
+
222
+ def w4a16_gelu_ffn_bf16(
223
+ x, up_weight, up_sfb, down_weight, down_sfb, *, up_bias=None,
224
+ down_bias=None, up_alpha=1.0, down_alpha=1.0, variant=0,
225
+ workspace=None, out=None,
226
+ ):
227
+ up, hidden, out = _gelu_workspace(x, up_weight.shape[0], down_weight.shape[0], workspace, out)
228
+ ops.w4a16_gelu_ffn_bf16(
229
+ x, up_weight, up_sfb, down_weight, down_sfb, up_bias, down_bias,
230
+ float(up_alpha), float(down_alpha), int(variant), up, hidden, out,
231
+ )
232
+ return out
233
+
234
+
235
+ def w8a16_gelu_ffn_bf16(
236
+ x, up_weight, up_scale, down_weight, down_scale, *, up_bias=None,
237
+ down_bias=None, variant=0, workspace=None, out=None,
238
+ ):
239
+ up, hidden, out = _gelu_workspace(x, up_weight.shape[0], down_weight.shape[0], workspace, out)
240
+ ops.w8a16_gelu_ffn_bf16(
241
+ x, up_weight, up_scale, down_weight, down_scale, up_bias, down_bias,
242
+ int(variant), up, hidden, out,
243
+ )
244
+ return out
245
+
246
+
247
+ __all__ = [
248
+ "dequantize_w4_weight_bf16",
249
+ "dequantize_w8_weight_bf16",
250
+ "quantize_w4_weight_bf16",
251
+ "quantize_w8_weight_bf16",
252
+ "w4_sfb_size_bytes",
253
+ "w4a16_geglu_ffn_bf16",
254
+ "w4a16_gelu_ffn_bf16",
255
+ "w4a16_linear_bf16",
256
+ "w4a16_swiglu_ffn_bf16",
257
+ "w8a16_geglu_ffn_bf16",
258
+ "w8a16_gelu_ffn_bf16",
259
+ "w8a16_linear_bf16",
260
+ "w8a16_swiglu_ffn_bf16",
261
+ ]
build/torch213-cxx11-cu130-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _weight_only_ffn_cuda_38d37b6
3
+ ops = torch.ops._weight_only_ffn_cuda_38d37b6
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_weight_only_ffn_cuda_38d37b6::{op_name}"
build/torch213-cxx11-cu130-x86_64-linux/_weight_only_ffn_cuda_38d37b6.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2c2083db3ce3c5ad71f964444503f9ca653986e9e878d20ea08572f4c2c7eec9
3
+ size 1906400
build/torch213-cxx11-cu130-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "weight-only-ffn",
3
+ "id": "_weight_only_ffn_cuda_38d37b6",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "11.0a",
11
+ "12.0a",
12
+ "12.1"
13
+ ]
14
+ },
15
+ "digest": {
16
+ "algorithm": "sha256",
17
+ "files": {
18
+ "__init__.py": "0q6TMj65una1LdyHLC291Dwy2VzrBbAD8Wm8MEdmqwA=",
19
+ "_ops.py": "iqY+HoE4nGHqvVlEZTwEAcyu1/w+QrjwuuW9sdTI2uk=",
20
+ "_weight_only_ffn_cuda_38d37b6.abi3.so": "LCCD2zzjxa1x+WRERQP5ymU5hunoeNIOoIVy9MLH7sk=",
21
+ "weight_only_ffn/__init__.py": "DFYPlrhXwYjEqCl/8n0SmWGZV8NFml5DPhMjKfv98GY="
22
+ }
23
+ },
24
+ "provenance": {
25
+ "kernel-builder": {
26
+ "version": "0.17.0-dev0",
27
+ "sha": "19aaa6421e674e9fecc352bbae6eab81d19a6bf4",
28
+ "dirty": false
29
+ },
30
+ "kernel": {
31
+ "sha": "38d37b67acfe940c99d7b3db721fa67163b82cec",
32
+ "dirty": false
33
+ }
34
+ }
35
+ }
build/torch213-cxx11-cu130-x86_64-linux/weight_only_ffn/__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/__init__.py ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Weight-only BF16-activation linear and FFN regions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Optional
6
+
7
+ import torch
8
+
9
+ from ._ops import add_op_namespace_prefix, ops
10
+
11
+
12
+ def w4_sfb_size_bytes(rows: int, cols: int) -> int:
13
+ if rows <= 0 or cols <= 0 or cols % 64:
14
+ raise ValueError("rows must be positive and cols must be divisible by 64")
15
+ return ((int(rows) + 127) // 128) * (((int(cols) // 16) + 3) // 4) * 512
16
+
17
+
18
+ @torch.library.register_fake(add_op_namespace_prefix("quantize_w4_weight_bf16"))
19
+ def _quantize_w4_fake(weight: torch.Tensor, packed: torch.Tensor, sfb: torch.Tensor) -> None:
20
+ return None
21
+
22
+
23
+ @torch.library.register_fake(add_op_namespace_prefix("dequantize_w4_weight_bf16"))
24
+ def _dequantize_w4_fake(packed: torch.Tensor, sfb: torch.Tensor, weight: torch.Tensor) -> None:
25
+ return None
26
+
27
+
28
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_linear_bf16"))
29
+ def _w4_linear_fake(
30
+ x: torch.Tensor,
31
+ packed: torch.Tensor,
32
+ sfb: torch.Tensor,
33
+ alpha: float,
34
+ variant: int,
35
+ out: torch.Tensor,
36
+ ) -> None:
37
+ return None
38
+
39
+
40
+ @torch.library.register_fake(add_op_namespace_prefix("quantize_w8_weight_bf16"))
41
+ def _quantize_w8_fake(weight: torch.Tensor, quantized: torch.Tensor, scales: torch.Tensor) -> None:
42
+ return None
43
+
44
+
45
+ @torch.library.register_fake(add_op_namespace_prefix("dequantize_w8_weight_bf16"))
46
+ def _dequantize_w8_fake(quantized: torch.Tensor, scales: torch.Tensor, weight: torch.Tensor) -> None:
47
+ return None
48
+
49
+
50
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_linear_bf16"))
51
+ def _w8_linear_fake(
52
+ x: torch.Tensor,
53
+ quantized: torch.Tensor,
54
+ scales: torch.Tensor,
55
+ variant: int,
56
+ out: torch.Tensor,
57
+ ) -> None:
58
+ return None
59
+
60
+
61
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_gated_ffn_bf16"))
62
+ def _w4_gated_fake(
63
+ x, gu_w, gu_s, dn_w, dn_s, gu_b, dn_b, gelu, gu_alpha, dn_alpha,
64
+ variant, gu, hidden, out,
65
+ ) -> None:
66
+ return None
67
+
68
+
69
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_gated_ffn_bf16"))
70
+ def _w8_gated_fake(
71
+ x, gu_w, gu_s, dn_w, dn_s, gu_b, dn_b, gelu, variant, gu, hidden, out,
72
+ ) -> None:
73
+ return None
74
+
75
+
76
+ @torch.library.register_fake(add_op_namespace_prefix("w4a16_gelu_ffn_bf16"))
77
+ def _w4_gelu_fake(
78
+ x, up_w, up_s, dn_w, dn_s, up_b, dn_b, up_alpha, dn_alpha,
79
+ variant, up, hidden, out,
80
+ ) -> None:
81
+ return None
82
+
83
+
84
+ @torch.library.register_fake(add_op_namespace_prefix("w8a16_gelu_ffn_bf16"))
85
+ def _w8_gelu_fake(
86
+ x, up_w, up_s, dn_w, dn_s, up_b, dn_b, variant, up, hidden, out,
87
+ ) -> None:
88
+ return None
89
+
90
+
91
+ def quantize_w4_weight_bf16(weight: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
92
+ """Pack a static BF16 weight matrix into NVFP4 data and SFB scales."""
93
+ n, k = weight.shape
94
+ packed = torch.empty((n, k // 2), device=weight.device, dtype=torch.uint8)
95
+ sfb = torch.empty((w4_sfb_size_bytes(n, k),), device=weight.device, dtype=torch.uint8)
96
+ ops.quantize_w4_weight_bf16(weight, packed, sfb)
97
+ return packed, sfb
98
+
99
+
100
+ def dequantize_w4_weight_bf16(
101
+ packed: torch.Tensor, sfb: torch.Tensor, *, cols: int
102
+ ) -> torch.Tensor:
103
+ weight = torch.empty((packed.shape[0], int(cols)), device=packed.device, dtype=torch.bfloat16)
104
+ ops.dequantize_w4_weight_bf16(packed, sfb, weight)
105
+ return weight
106
+
107
+
108
+ def quantize_w8_weight_bf16(weight: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
109
+ """Symmetrically quantize a static BF16 weight matrix per output channel."""
110
+ quantized = torch.empty_like(weight, dtype=torch.int8)
111
+ scales = torch.empty((weight.shape[0],), device=weight.device, dtype=torch.float32)
112
+ ops.quantize_w8_weight_bf16(weight, quantized, scales)
113
+ return quantized, scales
114
+
115
+
116
+ def dequantize_w8_weight_bf16(
117
+ quantized: torch.Tensor, scales: torch.Tensor
118
+ ) -> torch.Tensor:
119
+ weight = torch.empty_like(quantized, dtype=torch.bfloat16)
120
+ ops.dequantize_w8_weight_bf16(quantized, scales, weight)
121
+ return weight
122
+
123
+
124
+ def w4a16_linear_bf16(
125
+ x: torch.Tensor,
126
+ weight_packed: torch.Tensor,
127
+ weight_sfb: torch.Tensor,
128
+ *,
129
+ alpha: float = 1.0,
130
+ variant: int = 0,
131
+ out: Optional[torch.Tensor] = None,
132
+ ) -> torch.Tensor:
133
+ if out is None:
134
+ out = torch.empty((x.shape[0], weight_packed.shape[0]), device=x.device, dtype=torch.bfloat16)
135
+ ops.w4a16_linear_bf16(x, weight_packed, weight_sfb, float(alpha), int(variant), out)
136
+ return out
137
+
138
+
139
+ def w8a16_linear_bf16(
140
+ x: torch.Tensor,
141
+ weight_int8: torch.Tensor,
142
+ weight_scale: torch.Tensor,
143
+ *,
144
+ variant: int = 0,
145
+ out: Optional[torch.Tensor] = None,
146
+ ) -> torch.Tensor:
147
+ if out is None:
148
+ out = torch.empty((x.shape[0], weight_int8.shape[0]), device=x.device, dtype=torch.bfloat16)
149
+ ops.w8a16_linear_bf16(x, weight_int8, weight_scale, int(variant), out)
150
+ return out
151
+
152
+
153
+ def _gated_workspace(x: torch.Tensor, gate_up_rows: int, out_rows: int, workspace, out):
154
+ hidden_size = gate_up_rows // 2
155
+ if workspace is None:
156
+ gate_up = torch.empty((x.shape[0], gate_up_rows), device=x.device, dtype=torch.bfloat16)
157
+ hidden = torch.empty((x.shape[0], hidden_size), device=x.device, dtype=torch.bfloat16)
158
+ else:
159
+ gate_up, hidden = workspace
160
+ if out is None:
161
+ out = torch.empty((x.shape[0], out_rows), device=x.device, dtype=torch.bfloat16)
162
+ return gate_up, hidden, out
163
+
164
+
165
+ def _gelu_workspace(x: torch.Tensor, hidden_size: int, out_rows: int, workspace, out):
166
+ if workspace is None:
167
+ up = torch.empty((x.shape[0], hidden_size), device=x.device, dtype=torch.bfloat16)
168
+ hidden = torch.empty_like(up)
169
+ else:
170
+ up, hidden = workspace
171
+ if out is None:
172
+ out = torch.empty((x.shape[0], out_rows), device=x.device, dtype=torch.bfloat16)
173
+ return up, hidden, out
174
+
175
+
176
+ def _w4_gated(
177
+ x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, *, gelu,
178
+ gate_up_bias=None, down_bias=None, gate_up_alpha=1.0, down_alpha=1.0,
179
+ variant=0, workspace=None, out=None,
180
+ ):
181
+ gate_up, hidden, out = _gated_workspace(
182
+ x, gate_up_weight.shape[0], down_weight.shape[0], workspace, out
183
+ )
184
+ ops.w4a16_gated_ffn_bf16(
185
+ x, gate_up_weight, gate_up_sfb, down_weight, down_sfb,
186
+ gate_up_bias, down_bias, bool(gelu), float(gate_up_alpha),
187
+ float(down_alpha), int(variant), gate_up, hidden, out,
188
+ )
189
+ return out
190
+
191
+
192
+ def w4a16_swiglu_ffn_bf16(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, **kwargs):
193
+ return _w4_gated(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, gelu=False, **kwargs)
194
+
195
+
196
+ def w4a16_geglu_ffn_bf16(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, **kwargs):
197
+ return _w4_gated(x, gate_up_weight, gate_up_sfb, down_weight, down_sfb, gelu=True, **kwargs)
198
+
199
+
200
+ def _w8_gated(
201
+ x, gate_up_weight, gate_up_scale, down_weight, down_scale, *, gelu,
202
+ gate_up_bias=None, down_bias=None, variant=0, workspace=None, out=None,
203
+ ):
204
+ gate_up, hidden, out = _gated_workspace(
205
+ x, gate_up_weight.shape[0], down_weight.shape[0], workspace, out
206
+ )
207
+ ops.w8a16_gated_ffn_bf16(
208
+ x, gate_up_weight, gate_up_scale, down_weight, down_scale,
209
+ gate_up_bias, down_bias, bool(gelu), int(variant), gate_up, hidden, out,
210
+ )
211
+ return out
212
+
213
+
214
+ def w8a16_swiglu_ffn_bf16(x, gate_up_weight, gate_up_scale, down_weight, down_scale, **kwargs):
215
+ return _w8_gated(x, gate_up_weight, gate_up_scale, down_weight, down_scale, gelu=False, **kwargs)
216
+
217
+
218
+ def w8a16_geglu_ffn_bf16(x, gate_up_weight, gate_up_scale, down_weight, down_scale, **kwargs):
219
+ return _w8_gated(x, gate_up_weight, gate_up_scale, down_weight, down_scale, gelu=True, **kwargs)
220
+
221
+
222
+ def w4a16_gelu_ffn_bf16(
223
+ x, up_weight, up_sfb, down_weight, down_sfb, *, up_bias=None,
224
+ down_bias=None, up_alpha=1.0, down_alpha=1.0, variant=0,
225
+ workspace=None, out=None,
226
+ ):
227
+ up, hidden, out = _gelu_workspace(x, up_weight.shape[0], down_weight.shape[0], workspace, out)
228
+ ops.w4a16_gelu_ffn_bf16(
229
+ x, up_weight, up_sfb, down_weight, down_sfb, up_bias, down_bias,
230
+ float(up_alpha), float(down_alpha), int(variant), up, hidden, out,
231
+ )
232
+ return out
233
+
234
+
235
+ def w8a16_gelu_ffn_bf16(
236
+ x, up_weight, up_scale, down_weight, down_scale, *, up_bias=None,
237
+ down_bias=None, variant=0, workspace=None, out=None,
238
+ ):
239
+ up, hidden, out = _gelu_workspace(x, up_weight.shape[0], down_weight.shape[0], workspace, out)
240
+ ops.w8a16_gelu_ffn_bf16(
241
+ x, up_weight, up_scale, down_weight, down_scale, up_bias, down_bias,
242
+ int(variant), up, hidden, out,
243
+ )
244
+ return out
245
+
246
+
247
+ __all__ = [
248
+ "dequantize_w4_weight_bf16",
249
+ "dequantize_w8_weight_bf16",
250
+ "quantize_w4_weight_bf16",
251
+ "quantize_w8_weight_bf16",
252
+ "w4_sfb_size_bytes",
253
+ "w4a16_geglu_ffn_bf16",
254
+ "w4a16_gelu_ffn_bf16",
255
+ "w4a16_linear_bf16",
256
+ "w4a16_swiglu_ffn_bf16",
257
+ "w8a16_geglu_ffn_bf16",
258
+ "w8a16_gelu_ffn_bf16",
259
+ "w8a16_linear_bf16",
260
+ "w8a16_swiglu_ffn_bf16",
261
+ ]
build/torch213-cxx11-cu132-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _weight_only_ffn_cuda_38d37b6
3
+ ops = torch.ops._weight_only_ffn_cuda_38d37b6
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_weight_only_ffn_cuda_38d37b6::{op_name}"
build/torch213-cxx11-cu132-x86_64-linux/_weight_only_ffn_cuda_38d37b6.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:93ff16c4abd9057f9166fb2dd0b765053ea8d4bd69ddcb514b4fc3e6de56bb10
3
+ size 1906400
build/torch213-cxx11-cu132-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "weight-only-ffn",
3
+ "id": "_weight_only_ffn_cuda_38d37b6",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "11.0a",
11
+ "12.0a",
12
+ "12.1"
13
+ ]
14
+ },
15
+ "digest": {
16
+ "algorithm": "sha256",
17
+ "files": {
18
+ "__init__.py": "0q6TMj65una1LdyHLC291Dwy2VzrBbAD8Wm8MEdmqwA=",
19
+ "_ops.py": "iqY+HoE4nGHqvVlEZTwEAcyu1/w+QrjwuuW9sdTI2uk=",
20
+ "_weight_only_ffn_cuda_38d37b6.abi3.so": "k/8WxKvZBX+RZvst0LdlBT6o1L1p3ctRS0/D5t5WuxA=",
21
+ "weight_only_ffn/__init__.py": "DFYPlrhXwYjEqCl/8n0SmWGZV8NFml5DPhMjKfv98GY="
22
+ }
23
+ },
24
+ "provenance": {
25
+ "kernel-builder": {
26
+ "version": "0.17.0-dev0",
27
+ "sha": "19aaa6421e674e9fecc352bbae6eab81d19a6bf4",
28
+ "dirty": false
29
+ },
30
+ "kernel": {
31
+ "sha": "38d37b67acfe940c99d7b3db721fa67163b82cec",
32
+ "dirty": false
33
+ }
34
+ }
35
+ }
build/torch213-cxx11-cu132-x86_64-linux/weight_only_ffn/__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")))