ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Control
PerformanceMonitoring
PerfMonComps
bin
perfmonmt-printer.py
Go to the documentation of this file.
1
#!/usr/bin/env python3
2
3
# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
4
5
import
json
6
import
argparse
7
import
tarfile
8
9
# Print Header
10
def
printHeader
():
11
print
(
'='
*105)
12
print
(
'{0:^105}'
.format(
'PerfMonMTSvc Report'
))
13
print
(
'='
*105)
14
print
(
'{0:<105}'
.format(
'IMPORTANT : PLEASE NOTE THAT THIS SERVICE IS CURRENTLY IN R&D PHASE.'
))
15
print
(
'{0:<105}'
.format(
' FOR FURTHER INFORMATION/QUERIES PLEASE GET IN TOUCH WITH THE SPOT TEAM.'
))
16
print
(
'='
*105)
17
18
# Print Footer
19
def
printFooter
():
20
print
(
'='
*105)
21
print
(
'{0:^105}'
.format(
'ALL DONE!'
))
22
print
(
'='
*105)
23
24
# Print Component Level Data in Descending Order
25
def
printComponentLevelInfo
(execOnly = True, orderBy = 'cpuTime', maxComps = -1):
26
if
'componentLevel'
not
in
data:
27
return
28
print
(
'='
*105)
29
print
(
'{0:^105}'
.format(
'Component Level Monitoring'
))
30
print
(
'='
*105)
31
print
(
'{0:<18}{1:<10}{2:<20}{3:<20}{4:<20}{5:<20}'
.format(
'Step'
,
32
'Count'
,
33
'CPU Time [ms]'
,
34
'Vmem [kB]'
,
35
'Malloc [kB]'
,
36
'Component'
))
37
print
(
'='
*105)
38
steps = [
'Initialize'
,
'FirstEvent'
,
'Execute'
,
'Finalize'
,
'Callback'
,
'preLoadProxy'
]
39
if
execOnly:
40
steps = [
'Execute'
]
41
ncomps = 0
42
for
step
in
steps:
43
try
:
44
for
entry
in
sorted(data[
'componentLevel'
][step],
45
key=
lambda
x: data[
'componentLevel'
][step][x][orderBy], reverse =
True
):
46
print
(
'{0:<18}{1:<10}{2:<20.2f}{3:<20}{4:<20}{5:<20}'
.format(step,
47
data[
'componentLevel'
][step][entry][
'count'
],
48
data[
'componentLevel'
][step][entry][
'cpuTime'
],
49
data[
'componentLevel'
][step][entry][
'vmem'
],
50
data[
'componentLevel'
][step][entry][
'malloc'
],
51
entry))
52
ncomps += 1
53
if
(ncomps == maxComps):
54
break
55
except
KeyError:
56
pass
57
print
(
'='
*105)
58
59
# Event Level Data in Ascending Order
60
def
printEventLevelInfo
():
61
if
'eventLevel'
not
in
data:
62
return
63
print
(
'='
*105)
64
print
(
'{0:^105}'
.format(
'Event Level Monitoring'
))
65
print
(
'='
*105)
66
print
(
'{0:^15}{1:^15}{2:^15}{3:^15}{4:^15}{5:^15}{6:^15}'
.format(
'Event'
,
67
'CPU [s]'
,
68
'Wall [s]'
,
69
'Vmem [kB]'
,
70
'Rss [kB]'
,
71
'Pss [kB]'
,
72
'Swap [kB]'
))
73
print
(
'='
*105)
74
for
entry
in
sorted(data[
'eventLevel'
], key=float):
75
print
(
'{0:^15}{1:^15.2f}{2:^15.2f}{3:^15}{4:^15}{5:^15}{6:^15}'
.format(entry,
76
data[
'eventLevel'
][entry][
'cpuTime'
]*0.001,
77
data[
'eventLevel'
][entry][
'wallTime'
]*0.001,
78
data[
'eventLevel'
][entry][
'vmem'
],
79
data[
'eventLevel'
][entry][
'rss'
],
80
data[
'eventLevel'
][entry][
'pss'
],
81
data[
'eventLevel'
][entry][
'swap'
]))
82
# Snapshots Summary
83
def
printSnapshotsInfo
():
84
if
'summary'
not
in
data:
85
return
86
if
'snapshotLevel'
not
in
data[
'summary'
]:
87
return
88
print
(
'='
*105)
89
print
(
'{0:^105}'
.format(
'Snapshots Summary'
))
90
print
(
'='
*105)
91
print
(
'{0:<14}{1:<13}{2:<13}{3:<13}{4:<13}{5:<13}{6:<13}{7:<13}'
.format(
'Step'
,
92
'dCPU [s]'
,
93
'dWall [s]'
,
94
'<CPU>'
,
95
'dVmem [kB]'
,
96
'dRss [kB]'
,
97
'dPss [kB]'
,
98
'dSwap [kB]'
))
99
print
(
'-'
*105)
100
for
entry
in
[
'Configure'
,
'Initialize'
,
'FirstEvent'
,
'Execute'
,
'Finalize'
]:
101
print
(
'{0:<14}{1:<13.2f}{2:<13.2f}{3:<13.2f}{4:<13}{5:<13}{6:<13}{7:<13}'
.format(entry,
102
data[
'summary'
][
'snapshotLevel'
][entry][
'dCPU'
]*0.001,
103
data[
'summary'
][
'snapshotLevel'
][entry][
'dWall'
]*0.001,
104
data[
'summary'
][
'snapshotLevel'
][entry][
'cpuUtil'
],
105
data[
'summary'
][
'snapshotLevel'
][entry][
'dVmem'
],
106
data[
'summary'
][
'snapshotLevel'
][entry][
'dRss'
],
107
data[
'summary'
][
'snapshotLevel'
][entry][
'dPss'
],
108
data[
'summary'
][
'snapshotLevel'
][entry][
'dSwap'
]))
109
print
(
'*'
*105)
110
print
(
'{0:<40}{1:<}'
.format(
'Number of events processed:'
,
111
data[
'summary'
][
'nEvents'
]))
112
nEvents = float(data[
'summary'
][
'nEvents'
])
113
cpuExec = float(data[
'summary'
][
'snapshotLevel'
][
'FirstEvent'
][
'dCPU'
]) + float(data[
'summary'
][
'snapshotLevel'
][
'Execute'
][
'dCPU'
])
114
wallExec = float(data[
'summary'
][
'snapshotLevel'
][
'FirstEvent'
][
'dWall'
]) + float(data[
'summary'
][
'snapshotLevel'
][
'Execute'
][
'dWall'
])
115
print
(
'{0:<40}{1:<.0f}'
.format(
'CPU usage per event [ms]:'
, cpuExec/nEvents))
116
print
(
'{0:<40}{1:<.3f}'
.format(
'Events per second:'
, nEvents/wallExec*1000.))
117
print
(
'{0:<40}{1:<}'
.format(
'CPU utilization efficiency [%]:'
, data[
'summary'
][
'misc'
][
'cpuUtilEff'
]))
118
print
(
'*'
*105)
119
print
(
'{0:<40}{1:<.2f} GB'
.format(
'Max Vmem:'
,
120
float(data[
'summary'
][
'peaks'
][
'vmemPeak'
])/1024./1024.))
121
print
(
'{0:<40}{1:<.2f} GB'
.format(
'Max Rss:'
,
122
float(data[
'summary'
][
'peaks'
][
'rssPeak'
])/1024./1024))
123
print
(
'{0:<40}{1:<.2f} GB'
.format(
'Max Pss:'
,
124
float(data[
'summary'
][
'peaks'
][
'pssPeak'
])/1024./1024.))
125
print
(
'*'
*105)
126
print
(
'{0:<40}{1:<.2f} MB'
.format(
'Leak estimate per event Vmem:'
,
127
float(data[
'summary'
][
'leakEstimates'
][
'vmemLeak'
])/1024.))
128
print
(
'{0:<40}{1:<.2f} MB'
.format(
'Leak estimate per event Pss:'
,
129
float(data[
'summary'
][
'leakEstimates'
][
'pssLeak'
])/1024.))
130
print
(
' >> Estimated using the last {0} measurements from the Event Level Monitoring'
.format(data[
'summary'
][
'leakEstimates'
][
'nPoints'
]))
131
print
(
' >> Events prior to the first 25 are omitted...'
)
132
133
# Print System Info
134
def
printSystemInfo
():
135
print
(
'='
*105)
136
print
(
'{0:^105}'
.format(
'System Information'
))
137
print
(
'='
*105)
138
print
(
'{0:<40}{1:<}'
.format(
'CPU Model:'
,data[
'summary'
][
'sysInfo'
][
'cpuModel'
].lstrip()))
139
print
(
'{0:<40}{1:<}'
.format(
'Number of Available Cores:'
,data[
'summary'
][
'sysInfo'
][
'coreNum'
]))
140
print
(
'{0:<40}{1:<.2f} GB'
.format(
'Total Memory:'
,float(data[
'summary'
][
'sysInfo'
][
'totMem'
])/1024./1024.))
141
print
(
'='
*105)
142
143
# Print Environment Info
144
def
printEnvironmentInfo
():
145
print
(
'='
*105)
146
print
(
'{0:^105}'
.format(
'Environment Information'
))
147
print
(
'='
*105)
148
print
(
'{0:<40}{1:<}'
.format(
'Malloc Library:'
,data[
'summary'
][
'envInfo'
][
'mallocLib'
]))
149
print
(
'{0:<40}{1:<}'
.format(
'Math Library:'
,data[
'summary'
][
'envInfo'
][
'mathLib'
]))
150
print
(
'='
*105)
151
152
# Print out data
153
def
printReport
(data):
154
155
printHeader
()
156
157
# Print Component Level Data
158
if
args.level
in
[
'All'
,
'ComponentLevel'
]:
159
printComponentLevelInfo
(args.exec_only,
160
args.order_by,
161
args.max_comps)
162
163
# Print Event Level Data
164
if
args.level
in
[
'All'
,
'EventLevel'
]:
165
printEventLevelInfo
()
166
167
# Print Snapshots Summary
168
if
args.level
in
[
'All'
,
'SummaryLevel'
]:
169
printSnapshotsInfo
()
170
171
# Print System and Environment Information
172
if
args.level
in
[
'All'
]:
173
printSystemInfo
()
174
printEnvironmentInfo
()
175
# Print Footer
176
printFooter
()
177
178
# Main function
179
if
'__main__'
in
__name__:
180
181
# Parse the user input
182
parser = argparse.ArgumentParser(description =
'Script to print tables using PerfMonMTSvc JSON'
)
183
184
parser.add_argument(
'-i'
,
'--input'
, type = str, required =
True
,
185
help =
'PerfMonMTSvc JSON file'
)
186
parser.add_argument(
'-l'
,
'--level'
, nargs =
'?'
, default =
'All'
,
187
choices = [
'All'
,
'SummaryLevel'
,
'EventLevel'
,
'ComponentLevel'
],
188
help =
'Sets the level of detail in the printout'
)
189
parser.add_argument(
'-e'
,
'--exec-only'
, dest =
'exec_only'
, action =
'store_true'
,
190
help =
'Print only the execute step for the components'
)
191
parser.add_argument(
'-o'
,
'--order-by'
, dest =
'order_by'
, nargs =
'?'
, default =
'cpuTime'
,
192
choices = [
'cpuTime'
,
'vmem'
,
'malloc'
],
193
help =
'Order components by a specific metric'
)
194
parser.add_argument(
'-m'
,
'--max-components'
, dest =
'max_comps'
, type = int, default = -1,
195
help =
'The maximum number of compoments to be printed '
196
'(default: -1)'
)
197
198
args = parser.parse_args()
199
200
# Load the data and print the requested information
201
if
tarfile.is_tarfile(args.input):
202
203
tar = tarfile.open(args.input)
204
#If data is tarred, there could be more than one json in the tar file: cycle through all
205
for
member
in
tar.getmembers():
206
f = tar.extractfile(member)
207
data = json.load(f)
208
printReport
(data)
209
210
tar.close()
211
212
#if it is a json file, proceed as normal
213
else
:
214
215
with(open(args.input))
as
json_file:
216
data = json.load(json_file)
217
printReport
(data)
print
void print(char *figname, TCanvas *c1)
Definition
TRTCalib_StrawStatusPlots.cxx:26
perfmonmt-printer.printSystemInfo
printSystemInfo()
Definition
perfmonmt-printer.py:134
perfmonmt-printer.printHeader
printHeader()
Definition
perfmonmt-printer.py:10
perfmonmt-printer.printFooter
printFooter()
Definition
perfmonmt-printer.py:19
perfmonmt-printer.printReport
printReport(data)
Definition
perfmonmt-printer.py:153
perfmonmt-printer.printSnapshotsInfo
printSnapshotsInfo()
Definition
perfmonmt-printer.py:83
perfmonmt-printer.printComponentLevelInfo
printComponentLevelInfo(execOnly=True, orderBy='cpuTime', maxComps=-1)
Definition
perfmonmt-printer.py:25
perfmonmt-printer.printEnvironmentInfo
printEnvironmentInfo()
Definition
perfmonmt-printer.py:144
perfmonmt-printer.printEventLevelInfo
printEventLevelInfo()
Definition
perfmonmt-printer.py:60
Generated on
for ATLAS Offline Software by
1.17.0