Peano
Loading...
Searching...
No Matches
plot-scaling.py
Go to the documentation of this file.
1# This file is part of the ExaHyPE2 project. For conditions of distribution and
2# use, please see the copyright notice at www.peano-framework.org
3import argparse
4import tarfile
5import os
6import exahype2.postprocessing
7import sys
8
9from tkinter import Tcl
10import numpy as np
11
12import matplotlib.pyplot as plt
13
14
15Colors = ["#aa0000", "#00aa00", "#0000aa", "#797900", "#790079", "#007979", "#ababab"]
16#
17# Number of symbols should differ from colours by one
18#
19Symbols = ["o", "s", "<", ">", "v", "^"]
20
21
23 global max_x
24 global max_serial_y
25 global min_serial_y
26
27 plt.plot([1, max_x], [max_serial_y, max_serial_y / max_x], "--", color="#ababab")
28 plt.plot([1, max_x], [min_serial_y, min_serial_y / max_x], "--", color="#ababab")
29
30
31def compute_min_max(x_data, y_data):
32 global max_x
33 global max_serial_y
34 global min_serial_y
35
36 if len(x_data) > 0:
37 max_x = max(max_x, x_data[-1])
38
39 for i in range(0, len(x_data)):
40 serialised_value = y_data[i] * x_data[i]
41 max_serial_y = max(max_serial_y, serialised_value)
42 min_serial_y = min(min_serial_y, serialised_value)
43
44
45def visualise(data_points, symbol_counter, colour_counter):
46 global max_x
47 global max_time
48 global max_serial_y
49 global min_serial_y
50
51 (x_data, y_data) = exahype2.postprocessing.extract_times_per_step(
52 data_points, args.max_cores_per_rank
53 )
54
55 compute_min_max(x_data, y_data)
56
57 if args.plot_efficiency:
58 normalised_fasted_time = y_data[0] * x_data[0]
59 for i in range(0, len(x_data)):
60 y_data[i] = normalised_fasted_time / y_data[i] / x_data[i]
61 if args.max_cores_per_rank > 0:
62 y_data = [y / float(args.max_cores_per_rank) for y in y_data]
63 y_data = [min(y, 1.1) for y in y_data]
64
65 symbol = "-" + Symbols[symbol_counter % len(Symbols)]
66 my_color = Colors[colour_counter % len(Colors)]
67 # my_markevery = ( 0.1 + 0.8 * (colour_counter+1/len(Colors) )**3, 0.1 * 0.8 * symbol_counter / len(Symbols) )
68 # First entry is first marker (start to to count with 0), second is spacing
69 my_markevery = (
70 symbol_counter % len(Symbols) % (len(x_data) + 1),
71 int(len(x_data) / 8) + 1,
72 )
73
74 if len(y_data) > 0:
75 max_time = max(y_data[0], max_time)
76
77 if args.labels == "":
78 plt.plot(x_data, y_data, symbol, color=my_color, markevery=my_markevery)
79 else:
80 try:
81 my_label = args.labels.split(",")[args.file.index(file)]
82 except:
83 raise Exception(
84 "Unable to extract "
85 + str(args.file.index(file))
86 + "th entry from "
87 + args.labels
88 + ": "
89 + str(args.labels.split(","))
90 )
91 plt.plot(
92 x_data,
93 y_data,
94 symbol,
95 label=my_label,
96 color=my_color,
97 markevery=my_markevery,
98 )
99
100 # Save plot data into a file
101 if args.export_data:
102 np.savetxt(
103 args.output + ".txt", np.c_[x_data, y_data], fmt=["%1.f", "%1.2f"]
104 )
105
106
107if __name__ == "__main__":
108 parser = argparse.ArgumentParser(
109 description="""
110ExaHyPE 2 scaling plotter:
111
112A generic script to create speedup plots.
113
114"""
115 )
116 parser.add_argument(
117 "file",
118 nargs="+",
119 help="filename of the file to parse. You can specify multiple files",
120 )
121 parser.add_argument(
122 "-v", "--verbose", help="increase output verbosity", action="store_true"
123 )
124 parser.add_argument(
125 "--max-cores-per-rank",
126 dest="max_cores_per_rank",
127 type=int,
128 help="max number of cores per rank (pick 0 if you have only one core count per rank, pick -1 if you want to plot single-node data)",
129 default=0,
130 )
131 parser.add_argument(
132 "--group-data",
133 dest="group_data",
134 help="group k consecutive measurements as one piece of data, i.e. use similar styles (default=0, i.e. off)",
135 default=0,
136 type=int,
137 )
138 parser.add_argument(
139 "--log-x", dest="log_x", help="plot with logarithmic axes", action="store_true"
140 )
141 parser.add_argument(
142 "--log-y", dest="log_y", help="plot with logarithmic axes", action="store_true"
143 )
144 parser.add_argument(
145 "--plot-efficiency",
146 dest="plot_efficiency",
147 help="Don't plot raw times but efficiency",
148 action="store_true",
149 )
150 parser.add_argument(
151 "--labels",
152 dest="labels",
153 help="Plot labels. You can use $...$ to use the math mode, but you will have to escape the dollars with a \\. Separate with , and ensure there's exactly one entry per file",
154 default="",
155 )
156 parser.add_argument(
157 "--output",
158 dest="output",
159 help="output file prefix (file name extension is added automatically)",
160 default="",
161 )
162 parser.add_argument(
163 "--solver-name",
164 dest="solver_name",
165 help="Solver name (leave blank if there is only one solver)",
166 default="",
167 )
168 parser.add_argument(
169 "--export-data",
170 dest="export_data",
171 help="Export plot data into a txt file",
172 action="store_true",
173 )
174 parser.add_argument(
175 "--sort-files",
176 dest="sort_files",
177 help="Switch file sorting (natural sort)",
178 default=True,
179 )
180 parser.add_argument("--title", dest="title", help="Title of plot", default=None)
181 args = parser.parse_args()
182
183 max_x = -1
184 max_time = -1
185 min_serial_y = sys.float_info.max
186 max_serial_y = 0
187
188 plt.clf()
189
190 symbol_counter = 0
191 colour_counter = 0
192
193 for file in args.file:
194 if os.path.isdir(file):
195 print("Parse file " + file)
196 data_points = []
197 for data_file in os.listdir(file):
198 print(
199 "========================================================================"
200 )
201 print(file + "/" + data_file + " from " + file)
202 print(
203 "========================================================================"
204 )
205 new_data = exahype2.postprocessing.PerformanceData(
206 file + "/" + data_file, args.solver_name, args.verbose
207 )
208 if new_data.valid:
209 data_points.append(new_data)
210 visualise(data_points, symbol_counter, colour_counter)
211 elif file.endswith("tar") or file.endswith("tar.gz"):
212 print("Parse archive " + file)
213 open_mode = ""
214 if file.endswith("tar.gz"):
215 open_mode = "r:gz"
216 elif file.endswith("tar"):
217 open_mode = "r:"
218
219 tar = None
220 try:
221 tar = tarfile.open(file, open_mode)
222 data_files = tar.getnames()
223
224 # Sort input data
225 if args.sort_files:
226 data_files = Tcl().call("lsort", "-dict", data_files)
227
228 data_points = []
229 for data_file in data_files:
230 print(
231 "========================================================================"
232 )
233 print(data_file + " from " + file)
234 print(
235 "========================================================================"
236 )
237 tar.extract(data_file)
238 new_data = exahype2.postprocessing.PerformanceData(
239 data_file, args.solver_name, args.verbose
240 )
241 if new_data.valid:
242 data_points.append(new_data)
243 os.remove(data_file)
244
245 if args.verbose:
246 print("have successfully parsed {} files".format(len(data_files)))
247
248 if len(data_files) > 0:
249 visualise(data_points, symbol_counter, colour_counter)
250 else:
251 print("ERROR: no files in archive")
252 except Exception as e:
253 print("Error: " + str(e))
254 tar = None
255 if tar != None:
256 tar.close()
257 else:
258 print(file + " is neither a directory or an archive")
259
260 symbol_counter += 1
261 if args.group_data > 0:
262 if symbol_counter >= args.group_data:
263 symbol_counter = 0
264 colour_counter += 1
265 else:
266 colour_counter += 1
267
268 if args.plot_efficiency:
269 plt.ylabel("Efficiency")
270 else:
272 plt.ylabel("Time per time step [t]=s")
273 if args.log_x:
274 plt.xscale("log", base=2)
275 if args.log_y:
276 plt.yscale("log", base=2)
277
278 if args.max_cores_per_rank < 0:
279 plt.xlabel("Cores")
280 else:
281 plt.xlabel("Ranks")
282
283 xtics = [1]
284 xlabels = ["1"]
285 while xtics[-1] < max_x:
286 xtics.append(xtics[-1] * 2)
287 xlabels.append(str(xtics[-1]))
288 plt.xticks(xtics, xlabels)
289
290 plt.legend()
291 output_file_name = args.output
292 if output_file_name == "":
293 output_file_name = args.file[0].replace(".tar.gz", "").replace(".tar", "")
294
295 if args.title != None:
296 plt.title(args.title)
297
298 plt.savefig(output_file_name + ".pdf")
299 plt.savefig(output_file_name + ".png")
compute_min_max(x_data, y_data)
visualise(data_points, symbol_counter, colour_counter)