7 __author__ =
"Hasan Ozturk <haozturk@cern.ch"
8 __doc__ =
"A python module which parses the PerfMonMTSvc results and makes plots"
14 import matplotlib.pyplot
as plt
21 colors = {
"dCPU" :
"tab:blue",
"dWall" :
"tab:orange",
22 "dVmem" :
"tab:blue",
"dPss" :
"tab:green",
23 "dRss" :
"tab:orange",
"dSwap" :
"tab:red",
24 "cpuTime" :
"tab:blue",
"wallTime" :
"tab:orange",
25 "malloc" :
"tab:orange",
"vmem" :
"tab:blue",
26 "pss" :
"tab:green",
"rss" :
"tab:orange",
"swap" :
"tab:red" }
32 offset = 1 - len(params[
"vals"])
33 for metric
in params[
"vals"]:
34 vals = params[
"vals"][metric]
35 ax.barh(params[
"index"] + (offset*0.5)*params[
"width"], vals, params[
"width"],
36 color = colors[metric], alpha=0.8, label = metric)
39 ax.set_xlabel(params[
"xlabel"], fontsize=params[
'xlabelFontSize'])
40 ax.set_ylabel(params[
"ylabel"], fontsize=params[
'ylabelFontSize'])
41 ax.set_title(params[
"title"], fontsize=params[
'titleFontSize'], fontweight=
'bold')
42 ax.set_yticks(params[
"index"])
43 ax.set_yticklabels(params[
"yTickLabels"])
44 handles, labels = ax.get_legend_handles_labels()
45 ax.legend(reversed(handles), reversed(labels), prop={
'size': params[
'legendFontSize']})
46 ax.tick_params(axis=
'both', which=
'major', labelsize=30)
47 ax.grid(linestyle=
':',linewidth=0.1)
53 for label, metric
in params[
'yVals'].
items():
54 ax.plot(params[
'xVals'], metric, color = colors[label], label = label)
56 ax.set_xlabel(params[
'xlabel'])
57 ax.set_ylabel(params[
'ylabel'])
59 ax.set_xticks(params[
'xVals'])
60 ax.set_xticklabels(params[
'xVals'], rotation=
'vertical')
61 ax.tick_params(axis=
'both', which=
'major', labelsize=10)
62 ax.set_title(params[
'title'])
64 ax.grid(linestyle=
':',linewidth=0.1)
68 metricToCompMeasDict = {}
70 for metric, meas
in measDict.items():
72 metricToCompMeasDict[metric] = dict(zip(compNames, meas))
76 sortByList = [
sum(x)
for x
in zip(*measList)]
77 sortedCompMeasTuple =
sorted(dict(zip(compNames, sortByList)).
items(), key = operator.itemgetter(1))
78 sortedCompNames = [ compMeas[0]
for compMeas
in sortedCompMeasTuple]
80 sortedMeasurements = {}
82 for comp
in sortedCompNames[-compCountPerPlot:]:
83 for metric, compMeas
in metricToCompMeasDict.items():
85 if metric
not in sortedMeasurements:
86 sortedMeasurements[metric] = []
88 sortedMeasurements[metric].
append(compMeas[comp])
92 return sortedCompNames[-compCountPerPlot:], sortedMeasurements
97 stepNames, dCPUVals, dWallVals, dVmemVals, dRssVals, dPssVals, dSwapVals = [],[],[],[],[],[],[]
98 for step
in [
'Finalize',
'FirstEvent',
'Execute',
'Initialize',
'Configure']:
99 meas = snapshotData[step]
102 dCPU = meas[
"dCPU"] * 0.001
103 dWall = meas[
"dWall"] * 0.001
106 dVmem = meas[
"dVmem"] * 0.001
107 dRss = meas[
"dRss"] * 0.001
108 dPss = meas[
"dPss"] * 0.001
109 dSwap = meas[
"dSwap"] * 0.001
111 stepNames.append(step)
112 dCPUVals.append(dCPU)
113 dWallVals.append(dWall)
115 dVmemVals.append(dVmem)
116 dRssVals.append(dRss)
117 dPssVals.append(dPss)
118 dSwapVals.append(dSwap)
133 timeMonFig, timeMonAx = plt.subplots(figsize=(20,15))
134 memMonFig, memMonAx = plt.subplots(figsize=(20,15))
138 "index": np.arange(len(stepNames)),
139 "width": 0.5/len(timeMonVals),
141 "yTickLabels": stepNames,
142 "xlabel":
"Time [sec]",
144 "title":
"Snapshot Level Monitoring: Time Metrics",
146 "xlabelFontSize": 40,
147 "ylabelFontSize": 40,
154 "index": np.arange(len(stepNames)),
155 "width": 0.5/len(memMonVals),
157 "yTickLabels": stepNames,
158 "xlabel":
"Memory [MB]",
160 "title":
"Snapshot Level Monitoring: Memory Metrics",
162 "xlabelFontSize": 40,
163 "ylabelFontSize": 40,
172 timeMonFig.set_tight_layout(
True )
173 timeMonFig.savefig(
"Snaphot_Level_Time")
175 memMonFig.set_tight_layout(
True)
176 memMonFig.savefig(
"Snapshot_Level_Memory")
181 timeMonFig = plt.figure(figsize=(35,105))
182 memMonFig = plt.figure(figsize=(35,105))
184 for idx, step
in enumerate(componentLevelData):
186 compNames, vmemVals, cpuTimeVals, wallTimeVals, mallocVals, countVals = [],[],[],[],[],[]
187 for comp, meas
in componentLevelData[step].
items():
189 count = meas[
"count"]
190 cpuTime = meas[
"cpuTime"] * 0.001
191 wallTime = meas[
"wallTime"] * 0.001
192 malloc = meas[
"malloc"] * 0.001
193 vmem = meas[
"vmem"] * 0.001
196 if vmem < 0
or malloc < 0:
201 comp = f
"{comp[:20]}[...]{comp[-20:]}"
203 compNames.append(comp +
" [" +
str(count) +
"]")
204 vmemVals.append(vmem)
205 cpuTimeVals.append(cpuTime)
206 wallTimeVals.append(wallTime)
207 mallocVals.append(malloc)
208 countVals.append(count)
211 "cpuTime": cpuTimeVals,
212 "wallTime": wallTimeVals
217 "malloc": mallocVals,
221 sortedTimeMonCompNames, sortedTimeMonVals =
sortComponents(compNames, timeMonVals, compCountPerPlot)
222 sortedCompNamesMem, sortedMemMonVals =
sortComponents(compNames, memMonVals, compCountPerPlot)
224 timeMonAx = timeMonFig.add_subplot(len(componentLevelData),1,idx+1)
225 memMonAx = memMonFig.add_subplot(len(componentLevelData),1,idx+1)
229 "index": np.arange(len(sortedTimeMonCompNames)),
230 "width": 0.5/len(sortedTimeMonVals),
231 "vals": sortedTimeMonVals,
232 "yTickLabels": sortedTimeMonCompNames,
233 "xlabel":
"Time [sec]",
234 "ylabel":
"Components",
237 "xlabelFontSize": 50,
238 "ylabelFontSize": 50,
244 "index": np.arange(len(sortedCompNamesMem)),
245 "width": 0.5/len(sortedMemMonVals),
246 "vals": sortedMemMonVals,
247 "yTickLabels": sortedCompNamesMem,
248 "xlabel":
"Memory [MB]",
249 "ylabel":
"Components",
252 "xlabelFontSize": 50,
253 "ylabelFontSize": 50,
260 timeMonFig.set_tight_layout(
True )
261 timeMonFig.savefig(
"Component_Level_Time")
263 memMonFig.set_tight_layout(
True )
264 memMonFig.savefig(
"Component_Level_Memory")
269 sortedEventLevelData =
sorted(eventLevelData.items(), key=
lambda i:
int(i[0]))
271 eventVals, cpuTimeVals, wallTimeVals, vmemVals, rssVals, pssVals, swapVals = [], [], [], [], [], [], []
273 timeMonFig, timeMonAx = plt.subplots()
274 memMonFig, memMonAx = plt.subplots()
276 for entry
in sortedEventLevelData:
282 eventVals.append(event)
283 cpuTimeVals.append(meas[
'cpuTime'] * 0.001)
284 wallTimeVals.append(meas[
'wallTime'] * 0.001)
285 vmemVals.append(meas[
'vmem'] * 0.001)
286 rssVals.append(meas[
'rss'] * 0.001)
287 pssVals.append(meas[
'pss'] * 0.001)
288 swapVals.append(meas[
'swap'] * 0.001)
292 "cpuTime": cpuTimeVals,
293 "wallTime": wallTimeVals
305 "yVals": timeMonVals,
308 "ylabel":
"Time [sec]",
309 "title":
"Event Level Time Measurements"
317 "ylabel":
"Memory [MB]",
318 "title":
"Event Level Memory Measurements"
325 timeMonFig.set_tight_layout(
True)
326 timeMonFig.savefig(
"Event_Level_Time")
328 memMonFig.set_tight_layout(
True)
329 memMonFig.savefig(
"Event_Level_Memory")
332 if "snapshotLevel" in data[
"summary"]:
333 snapshotData = data[
"summary"][
"snapshotLevel"]
336 if "componentLevel" in data:
337 componentLevelData = data[
"componentLevel"]
340 if "eventLevel" in data:
341 eventLevelData = data[
"eventLevel"]
345 ''' Main function for producing plots from PerfMonMT JSON file.'''
347 parser = argparse.ArgumentParser()
349 parser.add_argument(
"-i",
"--input", dest =
"input",
350 default =
'PerfMonMTSvc_result.json',
351 help =
'The input JSON file')
352 parser.add_argument(
"-n",
"--numberOfCompsPerPlot",
353 dest =
"numberOfCompsPerPlot", default = 20,
354 help =
"The number of components to be plotted")
356 args = parser.parse_args()
358 if tarfile.is_tarfile(args.input):
359 tar = tarfile.open(args.input)
360 for member
in tar.getmembers():
361 f = tar.extractfile(member)
366 with open(args.input)
as jsonFile:
367 data = json.load(jsonFile)
371 if __name__ ==
"__main__":