liangsu9988's picture
Uploaded using `kernel-builder`.
31d0af0 verified
Raw
History Blame
2.81 kB
#!/usr/bin/env python3
"""Benchmark the fused GeGLU region against eager, compile, and raw native op."""
from __future__ import annotations
import argparse
import importlib
import sys
from pathlib import Path
import torch
import torch.nn.functional as F
def elapsed_us(fn, warmup, iterations):
for _ in range(warmup):
fn()
torch.cuda.synchronize()
start = torch.cuda.Event(enable_timing=True)
end = torch.cuda.Event(enable_timing=True)
start.record()
for _ in range(iterations):
fn()
end.record()
end.synchronize()
return start.elapsed_time(end) * 1000.0 / iterations
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--backend", choices=("source", "installed"), default="source")
parser.add_argument("--artifact")
parser.add_argument("--m", type=int, default=768)
parser.add_argument("--n", type=int, default=16384)
parser.add_argument("--k", type=int, default=2048)
parser.add_argument("--warmup", type=int, default=20)
parser.add_argument("--iterations", type=int, default=100)
args = parser.parse_args()
if args.backend == "source":
tests = Path(__file__).resolve().parents[1] / "tests"
sys.path.insert(0, str(tests))
from test_fused_mlp_megakernels_blackwell import load_source_ops
ops = load_source_ops()
else:
if args.artifact:
sys.path.insert(0, args.artifact)
ops = importlib.import_module("fused_mlp_megakernels_blackwell")
x = (torch.randn((args.m, args.k), device="cuda") * 0.15).half()
gate = (torch.randn((args.n, args.k), device="cuda") * 0.05).half()
up = (torch.randn((args.n, args.k), device="cuda") * 0.05).half()
scratch = torch.empty((args.m, args.n), device="cuda", dtype=torch.float16)
output = torch.empty_like(scratch)
def eager():
return F.gelu(x @ gate.t(), approximate="tanh") * (x @ up.t())
compiled = torch.compile(eager, fullgraph=True)
def wrapper():
return ops.fp16_geglu_fused(
x, gate, up, gate_scratch=scratch, output=output
)
def raw():
ops.ops.fp16_geglu_fused_out(x, gate, up, scratch, output)
expected = eager()
actual = wrapper()
torch.testing.assert_close(actual, expected, rtol=2e-2, atol=2e-2)
rows = {
"torch_eager_us": elapsed_us(eager, args.warmup, args.iterations),
"torch_compile_us": elapsed_us(compiled, args.warmup, args.iterations),
"hub_wrapper_us": elapsed_us(wrapper, args.warmup, args.iterations),
"raw_native_op_us": elapsed_us(raw, args.warmup, args.iterations),
}
print(f"shape=M{args.m}_N{args.n}_K{args.k}")
for name, value in rows.items():
print(f"{name}={value:.3f}")
if __name__ == "__main__":
main()