Skip to content

Commit 74b4f78

Browse files
committed
Add new script for plotting results and rename bench
1 parent e960d22 commit 74b4f78

File tree

2 files changed

+210
-0
lines changed

2 files changed

+210
-0
lines changed

bench/ndarray/roofline-plot.py

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
#######################################################################
2+
# Copyright (c) 2019-present, Blosc Development Team <blosc@blosc.org>
3+
# All rights reserved.
4+
#
5+
# This source code is licensed under a BSD-style license (found in the
6+
# LICENSE file in the root directory of this source tree)
7+
#######################################################################
8+
9+
# This plots the roofline results from the 7800X3D CPU when using
10+
# the flops-vs-arithmetic-intensity.py script. The default is potting
11+
# the disk results. To plot the in-memory results, set mem_mode=True
12+
# below.
13+
14+
import matplotlib.pyplot as plt
15+
import ast
16+
17+
mem_mode = False
18+
legend = "on-disk"
19+
20+
result = """
21+
{'blosc2': {'low': {'GFLOPS': 6.327852773687432,
22+
'Intensity': 11.0,
23+
'Time': 78.22558736801147},
24+
'matmul0': {'GFLOPS': 139.6079603241232,
25+
'Intensity': 2000,
26+
'Time': 0.12893247604370117},
27+
'matmul1': {'GFLOPS': 285.5730560584079,
28+
'Intensity': 10000,
29+
'Time': 7.878894567489624},
30+
'matmul2': {'GFLOPS': 275.25046270149494,
31+
'Intensity': 20000,
32+
'Time': 65.39498543739319},
33+
'medium': {'GFLOPS': 41.090081101862665,
34+
'Intensity': 73.5,
35+
'Time': 80.49387860298157},
36+
'very low': {'GFLOPS': 1.8312096896017473,
37+
'Intensity': 0.5,
38+
'Time': 12.286959886550903}},
39+
'blosc2-nocomp': {'low': {'GFLOPS': 2.411916710121926,
40+
'Intensity': 11.0,
41+
'Time': 205.23096752166748},
42+
'matmul0': {'GFLOPS': 1.3107291477971774,
43+
'Intensity': 2000,
44+
'Time': 13.732814311981201},
45+
'matmul1': {'GFLOPS': 250.65634985918948,
46+
'Intensity': 10000,
47+
'Time': 8.976433277130127},
48+
'matmul2': {'GFLOPS': 259.70444823051554,
49+
'Intensity': 20000,
50+
'Time': 69.30955600738525},
51+
'medium': {'GFLOPS': 16.14344559666435,
52+
'Intensity': 73.5,
53+
'Time': 204.88191199302673},
54+
'very low': {'GFLOPS': 0.17230079619691702,
55+
'Intensity': 0.5,
56+
'Time': 130.58558344841003}},
57+
'numpy/numexpr': {'low': {'GFLOPS': 3.507544548886978,
58+
'Intensity': 11.0,
59+
'Time': 141.1243658065796},
60+
'matmul0': {'GFLOPS': 0.9969869122268231,
61+
'Intensity': 2000,
62+
'Time': 18.054399490356445},
63+
'matmul1': {'GFLOPS': 285.9938969965044,
64+
'Intensity': 10000,
65+
'Time': 7.867300748825073},
66+
'matmul2': {'GFLOPS': 331.3412081775571,
67+
'Intensity': 20000,
68+
'Time': 54.32466459274292},
69+
'medium': {'GFLOPS': 20.830858799336102,
70+
'Intensity': 73.5,
71+
'Time': 158.77885937690735},
72+
'very low': {'GFLOPS': 0.2501104809770888,
73+
'Intensity': 0.5,
74+
'Time': 89.96024441719055}}}
75+
"""
76+
77+
result_mem = """
78+
{'blosc2': {'low': {'GFLOPS': 4.866522333848727,
79+
'Intensity': 11.0,
80+
'Time': 2.5428836345672607},
81+
'matmul0': {'GFLOPS': 85.0395948600573,
82+
'Intensity': 1000,
83+
'Time': 0.026458263397216797},
84+
'matmul1': {'GFLOPS': 268.91185402574024,
85+
'Intensity': 5000,
86+
'Time': 1.045881748199463},
87+
'matmul2': {'GFLOPS': 299.895418397909,
88+
'Intensity': 10000,
89+
'Time': 7.502615451812744},
90+
'medium': {'GFLOPS': 35.53410004647491,
91+
'Intensity': 73.5,
92+
'Time': 2.3269901275634766},
93+
'very low': {'GFLOPS': 0.9519585532368179,
94+
'Intensity': 0.5,
95+
'Time': 0.5908870697021484}},
96+
'blosc2-nocomp': {'low': {'GFLOPS': 4.6922734647067745,
97+
'Intensity': 11.0,
98+
'Time': 2.6373143196105957},
99+
'matmul0': {'GFLOPS': 58.503040710180954,
100+
'Intensity': 1000,
101+
'Time': 0.03845953941345215},
102+
'matmul1': {'GFLOPS': 273.2579472297275,
103+
'Intensity': 5000,
104+
'Time': 1.0292472839355469},
105+
'matmul2': {'GFLOPS': 301.0879153190238,
106+
'Intensity': 10000,
107+
'Time': 7.472900390625},
108+
'medium': {'GFLOPS': 32.61464583666784,
109+
'Intensity': 73.5,
110+
'Time': 2.535287380218506},
111+
'very low': {'GFLOPS': 0.6691234986315745,
112+
'Intensity': 0.5,
113+
'Time': 0.8406519889831543}},
114+
'numpy/numexpr': {'low': {'GFLOPS': 9.115128287351304,
115+
'Intensity': 11.0,
116+
'Time': 1.357633113861084},
117+
'matmul0': {'GFLOPS': 266.15855825365935,
118+
'Intensity': 1000,
119+
'Time': 0.008453607559204102},
120+
'matmul1': {'GFLOPS': 362.16460995052523,
121+
'Intensity': 5000,
122+
'Time': 0.7765805721282959},
123+
'matmul2': {'GFLOPS': 371.33744743751464,
124+
'Intensity': 10000,
125+
'Time': 6.059178829193115},
126+
'medium': {'GFLOPS': 46.40747408437248,
127+
'Intensity': 73.5,
128+
'Time': 1.781771183013916},
129+
'very low': {'GFLOPS': 2.681374682770323,
130+
'Intensity': 0.5,
131+
'Time': 0.20978045463562012}}}
132+
"""
133+
134+
if mem_mode:
135+
result = result_mem
136+
legend = "in-memory"
137+
138+
# Parse the result string as a dictionary
139+
results = ast.literal_eval(result)
140+
141+
# Create roofline plot
142+
fig, ax = plt.subplots(figsize=(10, 6))
143+
144+
# Define colors and markers for each backend
145+
styles = {
146+
'numpy/numexpr': {'color': 'blue', 'marker': 'o', 'label': 'NumPy/NumExpr'},
147+
'blosc2': {'color': 'red', 'marker': 's', 'label': 'Blosc2 (compressed)'},
148+
'blosc2-nocomp': {'color': 'green', 'marker': '^', 'label': 'Blosc2 (uncompressed)'}
149+
}
150+
151+
# Plot each backend's results
152+
for backend, backend_results in results.items():
153+
intensities = []
154+
gflops = []
155+
labels = []
156+
157+
for workload, metrics in backend_results.items():
158+
intensities.append(metrics['Intensity'])
159+
gflops.append(metrics['GFLOPS'])
160+
labels.append(workload)
161+
162+
style = styles[backend]
163+
ax.loglog(intensities, gflops,
164+
marker=style['marker'],
165+
color=style['color'],
166+
label=style['label'],
167+
markersize=8,
168+
linestyle='',
169+
alpha=0.7)
170+
171+
# Build a single annotation per unique x (Intensity)
172+
intensity_map = {}
173+
for backend_results in results.values():
174+
for workload, metrics in backend_results.items():
175+
intensity = metrics['Intensity']
176+
gflop = metrics['GFLOPS']
177+
# Apply same mapping used above, but only for annotation text
178+
if intensity not in intensity_map:
179+
intensity_map[intensity] = {'label': workload, 'gflops': []}
180+
intensity_map[intensity]['gflops'].append(gflop)
181+
182+
# Ensure labels fit inside the plot by extending the lower y-limit if necessary
183+
all_min_gflops = [min(info['gflops']) for info in intensity_map.values()]
184+
cur_ymin, cur_ymax = ax.get_ylim()
185+
new_ymin = min(cur_ymin, min(all_min_gflops) * 0.5)
186+
ax.set_ylim(new_ymin, cur_ymax)
187+
188+
# Annotate once per intensity, centered under the cluster of points
189+
for intensity, info in sorted(intensity_map.items()):
190+
# place label below the lowest point for this x, but keep a margin above x-axis
191+
raw_ypos = min(info['gflops']) * 0.6
192+
ymin, ymax = ax.get_ylim()
193+
# ensure at least 1.5x above current ymin to avoid overlapping the axis
194+
safe_ypos = max(raw_ypos, ymin * 1.5 if ymin > 0 else raw_ypos)
195+
ax.annotate(info['label'],
196+
(intensity, safe_ypos),
197+
ha='center',
198+
va='top',
199+
fontsize=10,
200+
alpha=0.9)
201+
202+
ax.set_xlabel('Arithmetic Intensity (FLOPs/element)', fontsize=12)
203+
ax.set_ylabel('Performance (GFLOPS/sec)', fontsize=12)
204+
ax.set_title(f'Roofline Analysis: AMD 7800X3D ({legend})', fontsize=14, fontweight='bold')
205+
ax.legend(loc='best')
206+
ax.grid(False)
207+
208+
plt.tight_layout()
209+
plt.savefig(f'roofline_plot-7800X3D-{legend}.png', dpi=300, bbox_inches='tight')
210+
plt.show()
File renamed without changes.

0 commit comments

Comments
 (0)