-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplot.py
More file actions
80 lines (70 loc) · 2.6 KB
/
Copy pathplot.py
File metadata and controls
80 lines (70 loc) · 2.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
"""Plot GEMM benchmark results from `./gemm --sweep > results.csv`.
Usage:
./gemm --sweep > results.csv
python plot.py # writes gflops_vs_size.png, pct_cublas.png
"""
import sys
import csv
from collections import defaultdict
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
ORDER = ["naive", "tiled", "register-tiled", "vectorized", "wmma", "cuBLAS", "cuBLAS-fp16"]
FP32_KERNALS = ["naive", "tiled", "register-tiled", "vectorized"]
STYLE = {
"cuBLAS": dict(linestyle="--", color="black", marker ="s"),
"cuBLAS-fp16": dict(linestyle="--", color="#76b900", marker="s"),
"wmma": dict(color="#76b900", marker="^"),
}
def load(path):
data = defaultdict(list)
pct = defaultdict(dict)
with open(path, newline="")as f:
reader = csv.DictReader
for row in csv.DictReader(f):
k, size = row["kernel"], int(row["size"])
data[k].append((size, float(row["gflops"])))
pct[k][size] = float(row["pct_cublas"])
for k in data:
data[k].sort()
return data, pct
def plot_gflops(data, out="gflops_vs_size.png"):
fig, ax = plt.subplots(figsize=(8, 5))
for k in [k for k in ORDER if k in data]:
sizes = [s for s, _ in data[k]]
gf = [g for _, g in data[k]]
style = dict(marker="o", linewidth=2)
style.update(STYLE.get(k, {}))
ax.plot(sizes, gf, label=k, **style)
ax.set_xscale("log", base = 2)
ax.set_xlabel("Matrix size (M = N =K)")
ax.set_ylabel("Gflop/s")
ax.set_title("SGEMM throughput vs. problem size\n(FP32 CUDA-core vs. FP16 tensor-core)")
ax.grid(True, which="both", alpha=0.3)
ax.legend()
fig.tight_layout()
fig.savefig(out, dpi=150)
print("wrote", out)
def plot_pct(pct, out="pct_cublas.png"):
custom = [k for k in FP32_KERNALS if k in pct]
if not custom:
return
largest = max(s for k in custom for s in pct[k])
vals = [pct[k].get(largest, 0.0) for k in custom]
fig, ax = plt.subplots(figsize=(8,5))
bars = ax.bar(custom, vals, color="#76b900")
ax.axhline(100, linestyle="--", color="black", linewidth=1)
ax.set_ylabel("% of FP32 cuBLS thoughput")
ax.set_title(f"FP32 kernals vs. cuBLAS at {largest} x {largest} x {largest}")
for b, v in zip(bars, vals):
ax.text(b.get_x() + b.get_width() / 2, v, f"{v:.0f}%", ha="center", va="bottom")
fig.tight_layout()
fig.savefig(out, dpi=150)
print("wrote", out)
def main():
path = sys.argv[1] if len(sys.argv) > 1 else "results.csv"
data, pct = load(path)
plot_gflops(data)
plot_pct(pct)
if __name__ == "__main__":
main()