Skip to content

Commit 55571a2

Browse files
committed
[Tool] Add script to dump sass
1 parent 58e8693 commit 55571a2

1 file changed

Lines changed: 97 additions & 0 deletions

File tree

tools/dump_sass.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#!/usr/bin/env python3
2+
"""Dump PTX and SASS of cute-dsl kernels from any script.
3+
4+
Sets CUTE_DSL_KEEP_CUBIN=1 and CUTE_DSL_KEEP_PTX=1, runs the target script,
5+
then disassembles all generated .cubin files with nvdisasm.
6+
7+
Usage::
8+
9+
python tools/dump_sass.py benchmarks/benchmark_gemm.py -- --mnkl 4096,4096,4096,1
10+
python tools/dump_sass.py benchmarks/benchmark_gemm.py -o /tmp/sass -- --mnkl 4096,4096,4096,1
11+
python tools/dump_sass.py benchmarks/benchmark_gemm.py --ptx-only -- --mnkl 4096,4096,4096,1
12+
"""
13+
14+
import argparse
15+
import os
16+
import shutil
17+
import subprocess
18+
import sys
19+
from pathlib import Path
20+
21+
22+
def find_nvdisasm():
23+
path = shutil.which("nvdisasm")
24+
if path:
25+
return path
26+
for cuda_dir in sorted(Path("/usr/local").glob("cuda*"), reverse=True):
27+
candidate = cuda_dir / "bin" / "nvdisasm"
28+
if candidate.is_file():
29+
return str(candidate)
30+
return None
31+
32+
33+
def main():
34+
argv = sys.argv[1:]
35+
if "--" in argv:
36+
idx = argv.index("--")
37+
our_argv, script_args = argv[:idx], argv[idx + 1:]
38+
else:
39+
our_argv, script_args = argv, []
40+
41+
parser = argparse.ArgumentParser(
42+
description="Dump PTX and SASS of cute-dsl kernels.",
43+
usage="%(prog)s SCRIPT [-o DIR] [--ptx-only] [-- SCRIPT_ARGS...]",
44+
)
45+
parser.add_argument("script", help="Python script to run")
46+
parser.add_argument("-o", "--output-dir", default="dump_sass_out", help="Output directory")
47+
parser.add_argument("--ptx-only", action="store_true", help="Skip SASS disassembly")
48+
args = parser.parse_args(our_argv)
49+
50+
script = Path(args.script)
51+
if not script.is_file():
52+
print(f"Error: {script} not found", file=sys.stderr)
53+
sys.exit(1)
54+
55+
out_dir = Path(args.output_dir)
56+
out_dir.mkdir(parents=True, exist_ok=True)
57+
for ext in ("*.ptx", "*.cubin", "*.sass"):
58+
for f in out_dir.glob(ext):
59+
f.unlink()
60+
61+
env = os.environ.copy()
62+
env["CUTE_DSL_KEEP_PTX"] = "1"
63+
env["CUTE_DSL_KEEP_CUBIN"] = "1"
64+
env["CUTE_DSL_DUMP_DIR"] = str(out_dir.resolve())
65+
66+
cmd = [sys.executable, str(script)] + script_args
67+
print(f"Running: {' '.join(cmd)}")
68+
print(f"Dump dir: {out_dir.resolve()}\n")
69+
subprocess.run(cmd, env=env)
70+
71+
ptx_files = sorted(out_dir.glob("*.ptx"))
72+
cubin_files = sorted(out_dir.glob("*.cubin"))
73+
print(f"\nPTX: {len(ptx_files)}, CUBIN: {len(cubin_files)}")
74+
for f in ptx_files:
75+
print(f" {f.name} ({f.stat().st_size:,} bytes)")
76+
77+
if not args.ptx_only and cubin_files:
78+
nvdisasm = find_nvdisasm()
79+
if nvdisasm is None:
80+
print("nvdisasm not found — skipping SASS disassembly", file=sys.stderr)
81+
else:
82+
for cubin in cubin_files:
83+
sass_path = cubin.with_suffix(".sass")
84+
result = subprocess.run([nvdisasm, str(cubin)], capture_output=True, text=True)
85+
if result.returncode != 0:
86+
print(f" nvdisasm failed: {cubin.name}: {result.stderr.strip()}", file=sys.stderr)
87+
continue
88+
sass_path.write_text(result.stdout)
89+
print(f" {sass_path.name} ({result.stdout.count(chr(10))} lines)")
90+
91+
print("\nSASS files:")
92+
for f in sorted(out_dir.glob("*.sass")):
93+
print(f" {f}")
94+
95+
96+
if __name__ == "__main__":
97+
main()

0 commit comments

Comments
 (0)