Peano
Loading...
Searching...
No Matches
print-kernel-throughput.py
Go to the documentation of this file.
1import matplotlib.pyplot as plt
2import matplotlib as mpl
3import numpy as np
4import re
5from math import log
6import sys
7import os.path
8import math
9from matplotlib.lines import Line2D
10
11
12params = {
13 "axes.labelsize": 20,
14 "axes.titlesize": 20,
15 "font.size": 20,
16 "font.family": "serif",
17 "legend.fontsize": 20,
18 "xtick.labelsize": 16,
19 "ytick.labelsize": 16,
20 "xtick.direction": "in",
21 "ytick.direction": "in",
22 "xtick.top": True,
23 "ytick.right": True,
24 "xtick.major.width": 1.5,
25 "ytick.major.width": 1.5,
26 "axes.linewidth": 1.5,
27 "axes.labelsize": 20,
28 "text.usetex": True,
29 "figure.dpi": 300,
30 "figure.autolayout": True,
31 # 'figure.figsize': (10,10),
32}
33
34mpl.rcParams.update(params)
35
36
37def read_file(file_name,
38 kernel_name,
39 ):
40 """!
41
42 Read one output file
43
44 Parses one input file identified through file_name and returns two
45 lists: the first one is a list of the number of particles, the second gives
46 the timings. We only parse data from one kernel type identified through
47 kernel_name.
48
49 """
50 particle_counts = []
51 timings = []
52
53 file = open( file_name, "r" )
54
55 for line in file:
56 if "Experiment:" in line:
57 number_of_particles = line.split( "Experiment:" )[1].split( "particles" )[0]
58 particle_counts.append( float(number_of_particles) )
59 if kernel_name in line:
60 time = line.split( kernel_name + ":" )[1].split( "(" )[0]
61 timings.append( float(time) )
62
63 assert len(particle_counts)==len(timings) or len(timings)==0, "array dimensions don't match: {} vs {} for kernel {} in {}".format(particle_counts, timings, kernel_name, file_name)
64 return particle_counts, timings
65
66
67
68Kernels = [ "density", "force", "kick1", "kick2", "drift" ]
69
70KernelName = {
71 'density' : 'density',
72 'force' : 'force',
73 'kick1' : '1st kick',
74 'kick2' : '2nd kick',
75 'drift' : 'drift',
76}
77
78ImplementationVariant = {
79 'force': ['(scattered,generic)',
80 '(continuous,generic)',
81 '(continuous,coalesced)', # not really true, but ensures consistent colours in plots
82 '(continuous,local-active-coalesced)',
83 '(continuous,active-local-coalesced)'],
84 'density': ['(scattered,generic)',
85 '(continuous,generic)',
86 '(continuous,coalesced)', # not really true, but ensures consistent colours in plots
87 '(continuous,local-active-coalesced)',
88 '(continuous,active-local-coalesced)'],
89 'kick1': ['(scattered,generic)',
90 '(continuous,generic)',
91 '(continuous,coalesced)'],
92 'kick2': ['(scattered,generic)',
93 '(continuous,generic)',
94 '(continuous,coalesced)'],
95 'drift': ['(scattered,generic)',
96 '(continuous,generic)',
97 '(continuous,coalesced)'],
98}
99
100ImplementationVariantName = {
101 '(scattered,generic)': 'generic (scat.)',
102 '(continuous,generic)': 'generic (cont.)',
103 '(continuous,coalesced)': 'coalesced (cont.)',
104 '(continuous,local-active-coalesced)': 'coalesced local-active (cont.)',
105 '(continuous,active-local-coalesced)': 'coalesced active-local (cont.)',
106}
107
108Colors = [ "#20a040", "#a04020", "#4020a0", "#f0a0f0", "#f06030", "#6030f0" ]
109Symbols = [ "-s", "-o", "-^", "-v", "-<", "->" ]
110
111ParticleSize = 272
112
113L2CacheSizeMap = {
114 'gi001': 1024*1024*2*56,
115 'gh003': 1024*1024*72,
116}
117
118def process_file(filename):
119 print( "process file {}".format(filename) )
120
121 plt.clf()
122 mpl.rcParams.update(params)
123
124 fig, ax = plt.subplots()
125
126 kernel_legend_handles = []
127 variants_legend_handles = []
128 for k, kernel in enumerate(Kernels):
129 kernel_legend_handles += [Line2D([0], [0], marker=Symbols[k][-1], color=Colors[0], label=f'{KernelName[kernel]}', linestyle='--')]
130 for im, implementation in enumerate(ImplementationVariant[kernel]):
131 if 'gpu' in filename and im > 2: continue
132 x_data, y_data = read_file(filename,
133 kernel + " " + implementation,
134 )
135
136 symbol = Symbols[ k % len(Symbols) ]
137 color = Colors[ im % len(Colors) ]
138 label = f'{KernelName[kernel]} - {ImplementationVariantName[implementation]}'
139
140 if len( y_data) > 0:
141 plt.plot( x_data,
142 y_data,
143 symbol,
144 color=color,
145 label=label,
146 markevery=(im,len(ImplementationVariant[kernel]))
147 )
148
149 for i, impl in enumerate(ImplementationVariant['force']):
150 if 'gpu' in filename and i > 2: continue
151 variants_legend_handles += [Line2D([0], [0], marker=Symbols[0][-1], color=Colors[i], label=f'... {ImplementationVariantName[impl]}', linestyle='--')]
152
153 plt.xlabel("Particles")
154 plt.ylabel("Time per particle update [t]=s")
155
156 plt.xscale('log', base=10)
157 plt.yscale('log', base=10)
158
159 plt.minorticks_on()
160 plt.grid(True, which='both')
161
162 filename = filename.replace('.log', '')
163
164 if 'gi001' in filename:
165 plt.axvline(x = L2CacheSizeMap['gi001']/ParticleSize, color = 'k', linestyle = '--')
166 elif 'gh003' in filename:
167 plt.axvline(x = L2CacheSizeMap['gh003']/ParticleSize, color = 'k', linestyle = '--')
168 else:
169 raise Exception("I don't know what CPU I'm working on!")
170
171 plt.ylim(1e-10, 1e-3)
172
173 plt.savefig(f"{filename}.pdf")
174 plt.savefig(f"{filename}.png")
175
176 plt.clf()
177 fig, ax = plt.subplots(figsize=(15, 1.2), constrained_layout=True)
178
179 ax.axis("off")
180
181 other_legend = ax.legend(loc="center right", handles=variants_legend_handles, fontsize=20, ncol=2, frameon=False)
182 ax.add_artist(other_legend)
183
184 plt.legend(loc="center left", handles=kernel_legend_handles, fontsize=20, ncol=3, frameon=False)
185
186 plt.savefig(f"{filename}-legend.pdf")
187 plt.savefig(f"{filename}-legend.png")
188
189if __name__== "__main__":
190 if len(sys.argv) < 2:
191 print( "ERROR: Please pass in file to work on. ")
192 else:
193 for file in sys.argv[1:]:
194 process_file(file)
read_file(file_name, kernel_name)
Read one output file.