CMS 3D CMS Logo

plotThroughput.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 import re
4 import sys
5 import array
6 
7 import ROOT
8 ROOT.gROOT.SetBatch(True)
9 ROOT.PyConfig.IgnoreCommandLineOptions = True
10 
11 
12 colors = [
13  ROOT.kBlue,
14  ROOT.kRed+1,
15  ROOT.kBlack
16 ]
17 
18 def findBounds(x, ys, xmin=None, ymin=None, xmax=None, ymax=None):
19  if xmin is None:
20  xmin = min(x)
21  if xmax is None:
22  xmax = max(x)
23  if ymin is None:
24  ymin = min([min(y) for y in ys])
25  if ymax is None:
26  ymax = max([max(y) for y in ys]) * 1.1
27 
28  return (xmin, ymin, xmax, ymax)
29 
30 
31 def makePlot(name, x, ys, ytitle,
32  title=None,
33  legends=None,
34  ideal1=None,
35  bounds={},
36  legendYmax=0.99
37  ):
38  canv = ROOT.TCanvas()
39  canv.cd()
40  canv.SetTickx(1)
41  canv.SetTicky(1)
42  canv.SetGridy(1)
43 
44  bounds = findBounds(x, ys, **bounds)
45  frame = canv.DrawFrame(*bounds)
46 
47  frame.GetXaxis().SetTitle("Number of threads")
48  frame.GetYaxis().SetTitle(ytitle)
49  if title is not None:
50  frame.SetTitle(title)
51  frame.Draw("")
52 
53  leg = None
54  if legends is not None:
55  leg = ROOT.TLegend(0.77,legendYmax-0.19,0.99,legendYmax)
56 
57  graphs = []
58 
59  if ideal1 is not None:
60  ymax = bounds[3]
61  ideal_y = [ideal1, ymax]
62  ideal_x = [1, ymax/ideal1]
63  gr = ROOT.TGraph(2, array.array("d", ideal_x), array.array("d", ideal_y))
64  gr.SetLineColor(ROOT.kBlack)
65  gr.SetLineStyle(3)
66  gr.Draw("same")
67  if leg:
68  leg.AddEntry(gr, "Ideal scaling", "l")
69  graphs.append(gr)
70 
71  for i, y in enumerate(ys):
72  gr = ROOT.TGraph(len(x), array.array("d", x), array.array("d", y))
73  color = colors[i]
74  gr.SetLineColor(color)
75  gr.SetMarkerColor(color)
76  gr.SetMarkerStyle(ROOT.kFullCircle)
77  gr.SetMarkerSize(1)
78 
79  gr.Draw("LP SAME")
80  if leg:
81  leg.AddEntry(gr, legends[i], "lp")
82 
83  graphs.append(gr)
84 
85  if leg:
86  leg.Draw("same")
87 
88  canv.SaveAs(name+".png")
89  canv.SaveAs(name+".pdf")
90 
91 
92 def main(argv):
93  (inputfile, outputfile, graph_label) = argv[1:4]
94 
95  re_mt = re.compile("nTH(?P<th>\d+)_nEV(?P<ev>\d+)")
96  re_mp = re.compile("nJOB(?P<job>\d+)")
97 
98  mt = {}
99  mp = {}
100 
101  f = open(inputfile)
102  for line in f:
103  if not "AVX512" in line:
104  continue
105  comp = line.split(" ")
106  m = re_mt.search(comp[0])
107  if m:
108  if m.group("th") != m.group("ev"):
109  raise Exception("Can't handle yet different numbers of threads (%s) and events (%s)" % (m.group("th"), m.group("ev")))
110  mt[int(m.group("th"))] = float(comp[1])
111  continue
112  m = re_mp.search(comp[0])
113  if m:
114  mp[int(m.group("job"))] = float(comp[1])
115  f.close()
116 
117  ncores = sorted(list(set(mt.keys() + mp.keys())))
118  mt_y = [mt[n] for n in ncores]
119  mp_y = [mp[n] for n in ncores]
120  ideal1 = mt_y[0]/ncores[0]
121  ideal1_mp = mp_y[0]/ncores[0]
122 
123  makePlot(outputfile+"_throughput", ncores,
124  [mt_y, mp_y],
125  "Throughput (events/s)",
126  title=graph_label,
127  legends=["Multithreading", "Multiprocessing"],
128  ideal1=ideal1,
129  bounds=dict(ymin=0, xmin=0),
130  legendYmax=0.5
131  )
132 
133  eff = [mt_y[i]/mp_y[i] for i in xrange(0, len(ncores))]
134  makePlot(outputfile+"_efficiency", ncores,
135  [eff],
136  "Multithreading efficiency (MT/MP)",
137  title=graph_label,
138  bounds=dict(ymin=0.9, ymax=1.1)
139  )
140 
141  eff_vs_ideal_mt = [mt_y[i]/(ideal1*n) for i, n in enumerate(ncores)]
142  eff_vs_ideal_mp = [mp_y[i]/(ideal1*n) for i, n in enumerate(ncores)]
143  makePlot(outputfile+"_efficiency_ideal", ncores,
144  [eff_vs_ideal_mt, eff_vs_ideal_mp],
145  "Efficiency wrt. ideal",
146  title=graph_label,
147  legends=["Multithreading", "Multiprocessing"],
148  bounds=dict(ymin=0.8, ymax=1.01, xmax=65),
149  legendYmax=0.9
150  )
151 
152  speedup_mt = [mt_y[i]/ideal1 for i in xrange(0, len(ncores))]
153  speedup_mp = [mp_y[i]/ideal1 for i in xrange(0, len(ncores))]
154  makePlot(outputfile+"_speedup", ncores,
155  [speedup_mt, speedup_mp],
156  "Speedup wrt. 1 thread",
157  title=graph_label,
158  legends=["Multithreading", "Multiprocessing"],
159  ideal1=1,
160  bounds=dict(ymin=0, xmin=0),
161  legendYmax=0.5
162  )
163 
164 
165 if __name__ == "__main__":
166  main(sys.argv)
def findBounds(x, ys, xmin=None, ymin=None, xmax=None, ymax=None)
def main(argv)
Definition: main.py:1
def makePlot(name, x, ys, ytitle, title=None, legends=None, ideal1=None, bounds={}, legendYmax=0.99)