ATLAS Offline Software
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
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
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
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
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
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
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']:
166 
167  # Print Snapshots Summary
168  if args.level in ['All', 'SummaryLevel']:
170 
171  # Print System and Environment Information
172  if args.level in ['All']:
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)
perfmonmt-printer.printFooter
def printFooter()
Definition: perfmonmt-printer.py:19
vtune_athena.format
format
Definition: vtune_athena.py:14
perfmonmt-printer.printHeader
def printHeader()
Definition: perfmonmt-printer.py:10
perfmonmt-printer.printEnvironmentInfo
def printEnvironmentInfo()
Definition: perfmonmt-printer.py:144
perfmonmt-printer.printEventLevelInfo
def printEventLevelInfo()
Definition: perfmonmt-printer.py:60
perfmonmt-printer.printComponentLevelInfo
def printComponentLevelInfo(execOnly=True, orderBy='cpuTime', maxComps=-1)
Definition: perfmonmt-printer.py:25
perfmonmt-printer.printReport
def printReport(data)
Definition: perfmonmt-printer.py:153
perfmonmt-printer.printSnapshotsInfo
def printSnapshotsInfo()
Definition: perfmonmt-printer.py:83
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename T::value_type > sorted(T begin, T end)
Helper function to create a sorted vector from an unsorted one.
perfmonmt-printer.printSystemInfo
def printSystemInfo()
Definition: perfmonmt-printer.py:134
Trk::open
@ open
Definition: BinningType.h:40
dbg::print
void print(std::FILE *stream, std::format_string< Args... > fmt, Args &&... args)
Definition: SGImplSvc.cxx:70
readCCLHist.float
float
Definition: readCCLHist.py:83