CMS 3D CMS Logo

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