4 try:
import simplejson
as json
5 except ImportError:
import json
10 Given a list of dictionaries, where each dict holds the information
11 about an IB, this function returns a tuple (low, high) with the lowest
12 and the highest value of y-axis, respectively.
14 low, high = sys.maxint, -1
16 low =
min((node[
'average'] - node[
'error']), low)
17 high =
max((node[
'average'] + node[
'error']), high)
21 def operate(timelog, memlog, json_f, num):
23 Main operation of the script (i.e. json db update, histograms' creation)
24 with respect to the specifications of all the files & formats concerned.
29 from datetime
import datetime
31 script_name=os.path.basename(__file__)
34 timefile=open(timelog,
'r')
35 timelog_lines=timefile.readlines()
38 memfile=open(memlog, 'r')
39 memlog_lines=memfile.readlines()
43 max_rss=average=error=
' '
45 while i<len(timelog_lines):
47 if 'Uncertainty of Average Time' in line:
49 line_list=line.split(
' ')
54 while i<len(memlog_lines):
56 if 'Maximum rss' in line:
58 line_list=line.split(
' ')
64 IB=os.path.basename(commands.getoutput(
"echo $CMSSW_BASE"))
71 if average ==
' ' or re.match(regex, average)
is None:
72 raise RuntimeError(
'Could not parse \"' + timelog +
'\" properly. ' +\
73 'Check if Average Time is defined correctly.')
74 if error ==
' ' or re.match(regex, error)
is None:
75 raise RuntimeError(
'Could not parse \"' + timelog +
'\" properly. ' +\
76 'Check if Uncertainty of Average Time is defined correctly.')
77 if max_rss ==
' ' or re.match(regex, max_rss)
is None:
78 raise RuntimeError(
'Could not parse \"' + memlog +
'\" properly. ' +\
79 ' Check if Maximum rss is defined correct.')
82 regex =
'(19|20|21)\d\d-(0[1-9]|1[012])-(0[1-9]|[12]'+\
83 '[0-9]|3[01])-([01][0-9]|2[0-4])([0-5][0-9])$'
84 if re.search(regex, IB)
is None:
85 raise RuntimeError(
'Not a valid IB. Valid IB: ' +\
86 '[CMSSW_X_X_X_YYYY-MM-DD-HHMM]')
87 except Exception, err:
88 sys.stderr.write(script_name +
': Error: ' + str(err) +
'\n')
92 json_db=open(json_f,
"r")
93 dict=json.load(json_db)
98 cmsrelease=ib_list[0] +
'_' + ib_list[1] +\
99 '_' + ib_list[2] +
'_' + ib_list[3]
100 data={
"IB" : ib_list[4],
"average" : float(average),
"error" : float(error),
"max_rss" : float(max_rss)}
102 if data
in dict[
"strips"]:
103 sys.stderr.write(script_name +
": Warning: Entry already exists " +\
104 "in json file and will not be stored! " +\
105 "Only the strip charts will be created.\n")
107 dict[
"strips"].
append(data)
108 print 'Storing entry to \"' + json_f +\
109 '\" file with attribute values:\n' +\
110 'IB=' + IB +
'\naverage=' + average +\
111 '\nUncertainty of average=' + error +
'\nmax_rss=' + max_rss
113 json_db = open(json_f,
"w+")
114 json.dump(dict, json_db, indent=2)
116 print 'File "' + json_f +
'" was updated successfully!'
119 for record
in dict[
"strips"]:
120 time_list = record[
'IB'].
split(
'-')
121 d = datetime(int(time_list[0]), int(time_list[1]),
122 int(time_list[2]), int(time_list[3][0:2]),
123 int(time_list[3][2:]))
127 list = sorted(dict[
"strips"], key=
lambda k : k[
'IB'], reverse=
True)
132 sys.stderr.write(script_name +
': Warning: There are less than ' +\
133 str(num) +
' entries in json file. Changed number to ' +\
134 str(new_num) +
'.\n')
138 ROOT.gROOT.SetStyle(
"Plain")
142 rootfilename=outdir +
'/histograms.root'
143 myfile=ROOT.TFile(rootfilename,
'RECREATE')
146 histo1=ROOT.TH1F(
"AveCPU per IB",
"Ave CPU per IB", num, 0., num)
147 histo1.SetTitle(cmsrelease +
": Showing last " + str(num) +
" IBs")
148 histo1.SetName(
'avecpu_histo')
151 histo2=ROOT.TH1F(
"Max rrs per IB",
"Max rss per IB", num, 0., num)
152 histo2.SetTitle(cmsrelease +
": Showing last " + str(num) +
" IBs")
153 histo2.SetName(
'maxrss_histo')
157 datime = list[i][
'IB'].__format__(
'%Y-%b-%d %H:%M')
158 average = list[i][
'average']
159 max_rss = list[i][
'max_rss']
160 error = list[i][
'error']
162 histo1.GetXaxis().SetBinLabel(num-i, datime)
163 histo1.SetBinContent(num-i, average)
164 histo1.SetBinError(num-i, error)
165 histo2.GetXaxis().SetBinLabel(num-i, datime)
166 histo2.SetBinContent(num-i, max_rss)
169 histo1.GetYaxis().SetTitle(
"Average CPU time")
170 histo1.GetYaxis().SetTitleOffset(1.8)
171 histo1.GetXaxis().SetTitle(
"Integration Build")
172 histo1.GetXaxis().SetTitleOffset(4.)
173 histo1.GetXaxis().CenterTitle()
174 histo1.GetXaxis().LabelsOption(
'v')
179 min = min-interval*0.1
180 max = max+interval*0.1
181 histo1.GetYaxis().SetRangeUser(min, max)
184 histo2.GetYaxis().SetTitle(
"Maximum rss")
185 histo2.GetYaxis().SetTitleOffset(1.8)
186 histo2.GetXaxis().SetTitle(
"Integration Build")
187 histo2.GetXaxis().SetTitleOffset(4.)
188 histo2.GetXaxis().CenterTitle()
189 histo2.GetXaxis().LabelsOption(
'v')
193 ave_canvas = ROOT.TCanvas(cmsrelease +
'_average_canvas')
194 ave_canvas.SetGridy()
195 ave_canvas.SetBottomMargin(0.28)
196 ave_canvas.SetLeftMargin(0.18)
199 histo1.SetLineColor(2)
200 histo1.SetLineWidth(2)
201 histo1.DrawCopy(
"HISTO L")
203 histo1.SetLineColor(1)
204 histo1.SetLineStyle(2)
205 histo1.SetLineWidth(1)
206 histo1.SetMarkerStyle(8)
207 histo1.SetMarkerSize(.6)
208 histo1.SetMarkerColor(1)
209 histo1.Draw(
"E1P SAME")
210 ROOT.gStyle.SetErrorX(0)
211 ave_canvas.Print(outdir +
"/average_cpu_histo.png",
"png")
213 rss_canvas = ROOT.TCanvas(cmsrelease +
'_maxrss_canvas')
214 rss_canvas.SetGridy()
215 rss_canvas.SetBottomMargin(0.28)
216 rss_canvas.SetLeftMargin(0.18)
219 histo2.SetLineColor(2)
220 histo2.SetLineWidth(2)
223 histo2.SetMarkerStyle(8)
224 histo2.SetMarkerSize(.6)
225 histo2.SetMarkerColor(1)
226 histo2.Draw(
"P SAME")
227 rss_canvas.Print(outdir +
"/maximum_rss_histo.png",
"png")
238 if __name__ ==
'__main__':
240 import optparse, stat
245 script_name= os.path.basename(__file__)
246 usage = script_name +
' <options> -t TIMELOG -m MEMLOG'
247 parser = optparse.OptionParser(usage)
248 parser.add_option(
'-t',
'--timelog',
253 help=
'input file TIMELOG, the output of cmsTiming_parser.py')
254 parser.add_option(
'-m',
'--memlog',
259 help=
'input file MEMLOG, the output of cmsSimplememchecker_parser.py')
260 parser.add_option(
'-j',
'--jsonfile',
263 default=
'strips.json',
265 help=
'the .json file database')
266 parser.add_option(
'-n', type=
'int',
271 help=
'last NUM entries to be printed in the strip charts. Default is 30.')
272 (options, args) = parser.parse_args()
277 if options.timelog ==
'' or\
278 options.memlog ==
'':
279 sys.exit(
'%s: Missing file operands!\n' % script_name+\
280 'Type %s --help for more information!' % script_name)
281 if not os.path.exists(options.timelog)
or\
282 not os.path.exists(options.memlog):
283 sys.exit(
'%s: Error: Not present file(s)!' % script_name)
290 format =
"\n { \"strips\" :\n" +\
291 " [\n {\"IB\" : \"XXX_XXX\", \"average\" : M, \"error\" : E \"max_rss\" : N},\n" +\
292 " .........................................\n" +\
297 json_db = open(options.json_f,
"r+")
300 if os.stat(options.json_f)[stat.ST_SIZE] == 0:
301 sys.stderr.write(script_name +
': Warning: File \"' + options.json_f +\
302 '\" is empty. A new database will be created upon it.\n')
303 json_db.write(
"{\n \"strips\" : [\n ]\n}\n")
307 dict = json.load(json_db)
313 if not isinstance(dict[
"strips"], list):
318 for item
in dict[
"strips"]:
319 if not set([
'IB',
'average',
'error',
'max_rss']).issubset(item):
322 sys.exit(script_name +
': Error: Not a valid json file! Please, check the format:\n' + format)
324 sys.exit(script_name +
': Error: Invalid format in the json file! Check it here:\n' + format)
333 sys.exit(
operate(options.timelog, options.memlog, options.json_f, options.num))
const T & max(const T &a, const T &b)