CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
cmsSimplememchecker_parser.py
Go to the documentation of this file.
1 #! /usr/bin/env python3
2 
3 
4 from __future__ import print_function
5 def manipulate_log(outdir,logfile_name,startevt):
6 
7  import time
8  import sys
9  import ROOT
10 
11  os.system('pwd')
12 
13  # the fundamental structure: the key is the evt number the value is a list containing
14  # VSIZE deltaVSIZE RSS deltaRSS
15  data=[]
16  values_set=('vsize','delta_vsize','rss','delta_rss')
17  report=''
18 
19  # open file and read it and fill the structure!
20  logfile=open(logfile_name,'r')
21  logfile_lines=logfile.readlines()
22  logfile.close()
23 
24  # we get the info we need!
25  i=0
26  max_rss=(0,0)
27  parse_report=True
28  while i < len(logfile_lines):
29  line=logfile_lines[i]
30  if '%MSG-w MemoryCheck:' in line:
31  line=line[:-1] #no \n!
32  line_content_list=line.split(' ')
33  event_number=int(line_content_list[-1])
34  if event_number<startevt:
35  i+=1
36  continue
37  i+=1 # we inspect the following line
38  line=logfile_lines[i]
39  line=line[:-1] #no \n!
40  line_content_list=line.split(' ')
41  vsize=float(line_content_list[4])
42  delta_vsize=float(line_content_list[5])
43  rss=float(line_content_list[7])
44  delta_rss=float(line_content_list[8])
45 
46  data.append((event_number,{'vsize':vsize,
47  'delta_vsize':delta_vsize,
48  'rss':rss,
49  'delta_rss':delta_rss}))
50  # find maximum rss of the job
51  if rss > max_rss[1]:
52  max_rss=(event_number, rss)
53 
54  # include memory report
55  elif parse_report and 'MemoryReport' in line:
56  while 'TimeReport' not in line:
57  report += line.replace('MemoryReport', '')
58  i+=1
59  line = logfile_lines[i]
60  parse_report=False
61  i+=1
62 
63  # print maximum rss for this job
64  print('Maximum rss =', max_rss[1])
65 
66  # skim the second entry when the event number is the same BUG!!!!!!!
67  # i take elements in couples!
68  new_data=[]
69  if len(data)>2:
70  if data[0][0]==data[1][0]:
71  print('Two modules seem to have some output.\nCollapsing ...')
72  i=0
73  while True:
74  dataline1=data[i]
75  i+=1
76  dataline2=data[i]
77  new_eventnumber=dataline1[0]
78  new_vsize=dataline2[1]['vsize']
79  new_delta_vsize=dataline1[1]['delta_vsize']+dataline2[1]['delta_vsize']
80  new_rss=dataline2[1]['rss']
81  new_delta_rss=dataline1[1]['delta_rss']+dataline2[1]['delta_rss']
82 
83  new_data.append((new_eventnumber,{'vsize':new_vsize,
84  'delta_vsize':new_delta_vsize,
85  'rss':new_rss,
86  'delta_rss':new_delta_rss}))
87  i+=1
88  if i==len(data): break
89 
90  data=new_data
91  print('Collapsing: Done!')
92 
93  npoints=len(data)
94 
95  print('%s values read and stored ...' %npoints)
96 
97 
98  # The Graphs
99  __argv=sys.argv # trick for a strange behaviour of the TApp..
100  sys.argv=sys.argv[:1]
101  ROOT.gROOT.SetStyle("Plain") # style paranoia
102  sys.argv=__argv
103 
104  #Cannot use this option when the logfile includes
105  #a large number of events... PyRoot seg-faults.
106  #Set ROOT in batch mode to avoid canvases popping up!
107  ROOT.gROOT.SetBatch(1)
108 
109  # Save in file
110  rootfilename='%s/graphs.root' %outdir
111  myfile=ROOT.TFile(rootfilename,'RECREATE')
112 
113  # dictionary of graphs!
114  graph_dict={}
115  for value in values_set:
116  #graph_dict[value]
117  graph=ROOT.TGraph(npoints)
118  graph.SetMarkerStyle(8)
119  graph.SetMarkerSize(.7)
120  graph.SetMarkerColor(1)
121  graph.SetLineWidth(3)
122  graph.SetLineColor(2)
123  graph.SetTitle(value)
124  graph.SetName('%s_graph' %value)
125 
126 
127  #fill the graphs
128  point_counter=0
129  for event_number,vals_dict in data:
130  graph.SetPoint(point_counter,
131  event_number,
132  vals_dict[value])
133  point_counter+=1
134 
135  graph.GetXaxis().SetTitle("Event")
136  last_event=data[-1][0]
137  graph.GetXaxis().SetRangeUser(0,last_event+1)
138  graph.GetYaxis().SetTitleOffset(1.3)
139  graph.GetYaxis().SetTitle("MB")
140 
141 
142 
143  #print the graphs as files :)
144  mycanvas=ROOT.TCanvas('%s_canvas' %value)
145  mycanvas.cd()
146  graph.Draw("ALP")
147 
148  mycanvas.Print("%s/%s_graph.png"%(outdir,value),"png")
149 
150  # write it on file
151  graph.Write()
152  mycanvas.Write()
153 
154  myfile.Close()
155 
156  os.system('pwd')
157 
158  # The html page!------------------------------------------------------------------------------
159 
160  titlestring='<b>Report executed with release %s on %s.</b>\n<br>\n<hr>\n'\
161  %(os.environ['CMSSW_VERSION'],time.asctime())
162  #Introducing this if to catch the cmsRelvalreport.py use case of "reuse" of TimingReport
163  #profile when doing the SimpleMemReport... otherwise the filename for the html
164  #would be misleadingly TimingReport...
165  if len(logfile_name)>16 and 'TimingReport.log' in logfile_name[-16:]:
166  file_name=logfile_name[:-16]+"_SimpleMemReport"
167  else:
168  file_name=logfile_name[:-4]+"_SimpleMemReport"
169  html_file_name='%s/%s.html' %(outdir,file_name)
170  html_file=open(html_file_name,'w')
171  html_file.write('<html>\n<body>\n'+\
172  titlestring)
173  html_file.write('<table>\n'+\
174  '<tr>\n<td><img src=vsize_graph.png></img></td>\n'+\
175  '<td><img src=rss_graph.png></img></td>\n</tr>\n'+\
176  '<tr>\n<td><img src=delta_vsize_graph.png></img></td>\n'+\
177  '<td><img src=delta_rss_graph.png></img></td>\n</tr>\n' +\
178  '</table>\n')
179  html_file.write('<hr>\n<h1>Memory Checker Report</h1>\n<pre>\n' + report + '</pre>')
180  html_file.write('\n</body>\n</html>')
181  html_file.close()
182 
183 
184 #################################################################################################
185 
186 if __name__ == '__main__':
187 
188  import optparse
189  import os
190 
191  # Here we define an option parser to handle commandline options..
192  usage='simplememchecker_parser.py <options>'
193  parser = optparse.OptionParser(usage)
194  parser.add_option('-i', '--in_ profile',
195  help='The profile to manipulate' ,
196  default='',
197  dest='profile')
198 
199  parser.add_option('-o', '--outdir',
200  help='The directory of the output' ,
201  default='',
202  dest='outdir')
203 
204  parser.add_option('-n',
205  help='The event number from which we start. Default is 1.' ,
206  default='1',
207  dest='startevt')
208 
209  (options,args) = parser.parse_args()
210 
211  # Now some fault control..If an error is found we raise an exception
212  if options.profile=='' or\
213  options.outdir=='':
214  raise('Please select a profile and an output dir!')
215 
216  if not os.path.exists(options.profile) or\
217  not os.path.exists(options.outdir):
218  raise ('Outdir or input profile not present!')
219 
220  try:
221  startevt=int(options.startevt)
222  except ValueError:
223  print('Problems in convertng starting event value!')
224 
225 
226  #launch the function!
227  manipulate_log(options.outdir,options.profile,startevt)
228 
229 
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47