2 import os, time, sys, re, glob, exceptions
4 import cmsRelRegress
as crr
5 from cmsPerfCommons
import Candles, KeywordToCfi, CandFname, cmsDriverPileUpOption, getVerFromLog
6 import cmsRelValCmd,cmsCpuInfo
11 from functools
import reduce
19 subprocess._cleanup=_cleanup
24 threading.Thread.__init__(self)
30 self.suite.runPerfSuite(**(self.
args))
33 """A class defining timing objects to time the running of the various parts of the performance suite. The class depends on module datetime.""" 35 """Initialize the start time and set the end time to some indefinite time in the future""" 37 self.
end = datetime.datetime.max
49 """Return the start time in ctime timestamp format""" 50 return self.start.ctime()
52 """Return the end time in ctime timestamp format""" 53 return self.end.ctime()
55 """Return the duration between start and end as a dictionary with keys 'hours', 'minutes', 'seconds' to express the total duration in the favourite (most appropriate) unit. The function returns truncated integers.""" 68 self.
_CASTOR_DIR =
"/castor/cern.ch/cms/store/relval/performance/" 80 self.
host = os.environ[
"HOST"]
81 self.
user = os.environ[
"USER"]
83 self.logh.write(
'Error: An environment variable either SCRAM_ARCH, CMSSW_VERSION, HOST or USER is not available.\n')
84 self.logh.write(
' Please run eval `scramv1 runtime -csh` to set your environment variables\n')
89 self.
Scripts =[
"cmsDriver.py",
"cmsRelvalreport.py",
"cmsRelvalreportInput.py",
"cmsScimark2"]
90 self.
AuxiliaryScripts=[
"cmsScimarkLaunch.csh",
"cmsScimarkParser.py",
"cmsScimarkStop.py"]
111 igcommand =
'/afs/cern.ch/cms/sdt/internal/scripts/requestPerfIgprofSpace.py --version ' + self.
cmssw_version +
' --platform ' + self.
cmssw_arch 112 subprocess.Popen(igcommand,shell=
True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
116 def __init__(self,cpu,perfsuiteinstance,**simpleGenReportArgs):
120 threading.Thread.__init__(self)
123 self.PerfTest.runPerfTest()
126 def __init__(self,cpu,perfsuiteinstance,**simpleGenReportArgs):
142 self.perfsuiteinstance.logh.flush()
144 self.perfsuiteinstance.printDate()
145 self.perfsuiteinstance.logh.flush()
149 self.PerfTestPUTimer.set_end(datetime.datetime.now())
151 self.PerfTestTimer.set_end(datetime.datetime.now())
156 parser = opt.OptionParser(usage=
'''./cmsPerfSuite.py [options] 160 cmsPerfSuite.py --step GEN-HLT -t 5 -i 2 -c 1 -m 5 --RunTimeSize MinBias,TTbar --RunIgProf TTbar --RunCallgrind TTbar --RunMemcheck TTbar --RunDigiPileUp TTbar --PUInputFile /store/relval/CMSSW_2_2_1/RelValMinBias/GEN-SIM-DIGI-RAW-HLTDEBUG/IDEAL_V9_v2/0001/101C84AF-56C4-DD11-A90D-001D09F24EC0.root --cmsdriver="--eventcontent FEVTDEBUGHLT --conditions FrontierConditions_GlobalTag,IDEAL_V9::All" 161 (this will run the suite with 5 events for TimeSize tests on MinBias and TTbar, 2 for IgProf tests on TTbar only, 1 for Callgrind tests on TTbar only, 5 for Memcheck on MinBias and TTbar, it will also run DIGI PILEUP for all TTbar tests defined, i.e. 5 TimeSize, 2 IgProf, 1 Callgrind, 5 Memcheck. The file /store/relval/CMSSW_2_2_1/RelValMinBias/GEN-SIM-DIGI-RAW-HLTDEBUG/IDEAL_V9_v2/0001/101C84AF-56C4-DD11-A90D-001D09F24EC0.root will be copied locally as INPUT_PILEUP_EVENTS.root and it will be used as the input file for the MixingModule pile up events. All these tests will be done for the step GEN-HLT, i.e. GEN,SIM,DIGI,L1,DIGI2RAW,HLT at once) 163 cmsPerfSuite.py --step GEN-HLT -t 5 -i 2 -c 1 -m 5 --RunTimeSize MinBias,TTbar --RunIgProf TTbar --RunCallgrind TTbar --RunMemcheck TTbar --RunTimeSizePU TTbar --PUInputFile /store/relval/CMSSW_2_2_1/RelValMinBias/GEN-SIM-DIGI-RAW-HLTDEBUG/IDEAL_V9_v2/0001/101C84AF-56C4-DD11-A90D-001D09F24EC0.root 164 (this will run the suite with 5 events for TimeSize tests on MinBias and TTbar, 2 for IgProf tests on TTbar only, 1 for Callgrind tests on TTbar only, 5 for Memcheck on MinBias and TTbar, it will also run DIGI PILEUP on TTbar but only for 5 TimeSize events. All these tests will be done for the step GEN-HLT, i.e. GEN,SIM,DIGI,L1,DIGI2RAW,HLT at once) 166 cmsPerfSuite.py --step GEN-HLT -t 5 -i 2 -c 1 -m 5 --RunTimeSize MinBias,TTbar --RunIgProf TTbar --RunCallgrind TTbar --RunMemcheck TTbar --RunTimeSizePU TTbar --PUInputFile /store/relval/CMSSW_2_2_1/RelValMinBias/GEN-SIM-DIGI-RAW-HLTDEBUG/IDEAL_V9_v2/0001/101C84AF-56C4-DD11-A90D-001D09F24EC0.root --cmsdriver="--eventcontent RAWSIM --conditions FrontierConditions_GlobalTag,IDEAL_V9::All" 167 (this will run the suite with 5 events for TimeSize tests on MinBias and TTbar, 2 for IgProf tests on TTbar only, 1 for Callgrind tests on TTbar only, 5 for Memcheck on MinBias and TTbar, it will also run DIGI PILEUP on TTbar but only for 5 TimeSize events. All these tests will be done for the step GEN-HLT, i.e. GEN,SIM,DIGI,L1,DIGI2RAW,HLT at once. It will also add the options "--eventcontent RAWSIM --conditions FrontierConditions_GlobalTag,IDEAL_V9::All" to all cmsDriver.py commands executed by the suite. In addition it will run only 2 cmsDriver.py "steps": "GEN,SIM" and "DIGI". Note the syntax GEN-SIM for combined cmsDriver.py steps) 169 Legal entries for individual candles (--RunTimeSize, --RunIgProf, --RunCallgrind, --RunMemcheck options): 171 ''' % (
"\n".
join(Candles)))
173 parser.set_defaults(TimeSizeEvents = 0 ,
175 CallgrindEvents = 0 ,
178 cmsScimarkLarge = 10 ,
179 cmsdriverOptions =
"--eventcontent FEVTDEBUGHLT",
184 logfile = os.path.join(os.getcwd(),
"cmsPerfSuite.log"),
204 RunCallgrindPU =
"" ,
208 parser.add_option(
'--createIgVol', action=
"store_true", dest=
'create',
209 help =
'Create IgProf AFS volume for the release and architecture')
210 parser.add_option(
'-q',
'--quiet' , action=
"store_false", dest=
'verbose' ,
211 help =
'Output less information' )
212 parser.add_option(
'-b',
'--bypass-hlt' , action=
"store_true" , dest=
'bypasshlt' ,
213 help =
'Bypass HLT root file as input to RAW2DIGI')
214 parser.add_option(
'-n',
'--notrunspare', action=
"store_false", dest=
'runonspare',
215 help =
'Do not run cmsScimark on spare cores')
216 parser.add_option(
'-t',
'--timesize' , type=
'int' , dest=
'TimeSizeEvents' , metavar=
'<#EVENTS>' ,
217 help =
'specify the number of events for the TimeSize tests' )
218 parser.add_option(
'-i',
'--igprof' , type=
'int' , dest=
'IgProfEvents' , metavar=
'<#EVENTS>' ,
219 help =
'specify the number of events for the IgProf tests' )
220 parser.add_option(
'-c',
'--callgrind' , type=
'int' , dest=
'CallgrindEvents' , metavar=
'<#EVENTS>' ,
221 help =
'specify the number of events for the Callgrind tests' )
222 parser.add_option(
'-m',
'--memcheck' , type=
'int' , dest=
'MemcheckEvents' , metavar=
'<#EVENTS>' ,
223 help =
'specify the number of events for the Memcheck tests' )
224 parser.add_option(
'--cmsScimark' , type=
'int' , dest=
'cmsScimark' , metavar=
'' ,
225 help =
'specify the number of times the cmsScimark benchmark is run before and after the performance suite on cpu1')
226 parser.add_option(
'--cmsScimarkLarge' , type=
'int' , dest=
'cmsScimarkLarge' , metavar=
'' ,
227 help =
'specify the number of times the cmsScimarkLarge benchmark is run before and after the performance suite on cpu1')
228 parser.add_option(
'--cores' , type=
'int', dest=
'cores' , metavar=
'<CORES>' ,
229 help =
'specify the number of cores of the machine (can be used with 0 to stop cmsScimark from running on the other cores)')
230 parser.add_option(
'--cmsdriver' , type=
'string', dest=
'cmsdriverOptions', metavar=
'<OPTION_STR>',
231 help =
'specify special options to use with the cmsDriver.py commands (designed for integration build use')
232 parser.add_option(
'-a',
'--archive' , type=
'string', dest=
'castordir' , metavar=
'<DIR>' ,
233 help =
'specify the wanted CASTOR directory where to store the results tarball')
234 parser.add_option(
'-L',
'--logfile' , type=
'string', dest=
'logfile' , metavar=
'<FILE>' ,
235 help =
'file to store log output of the script')
236 parser.add_option(
'-o',
'--output' , type=
'string', dest=
'outputdir' , metavar=
'<DIR>' ,
237 help =
'specify the directory where to store the output of the script')
238 parser.add_option(
'-r',
'--prevrel' , type=
'string', dest=
'previousrel' , metavar=
'<DIR>' ,
239 help =
'Top level dir of previous release for regression analysis')
240 parser.add_option(
'--step' , type=
'string', dest=
'stepOptions' , metavar=
'<STEPS>' ,
241 help =
'specify the processing steps intended (instead of the default ones)' )
242 parser.add_option(
'--cpu' , type=
'string', dest=
'cpu' , metavar=
'<CPU>' ,
243 help =
'specify the core on which to run the performance suite')
246 parser.add_option(
'--RunTimeSize' , type=
'string', dest=
'RunTimeSize' , metavar=
'<CANDLES>' ,
247 help =
'specify on which candles to run the TimeSize tests')
248 parser.add_option(
'--RunIgProf' , type=
'string', dest=
'RunIgProf' , metavar=
'<CANDLES>' ,
249 help =
'specify on which candles to run the IgProf tests')
250 parser.add_option(
'--RunCallgrind' , type=
'string', dest=
'RunCallgrind' , metavar=
'<CANDLES>' ,
251 help =
'specify on which candles to run the Callgrind tests')
252 parser.add_option(
'--RunMemcheck' , type=
'string', dest=
'RunMemcheck' , metavar=
'<CANDLES>' ,
253 help =
'specify on which candles to run the Memcheck tests')
254 parser.add_option(
'--RunDigiPileUp' , type=
'string', dest=
'RunDigiPileUp' , metavar=
'<CANDLES>' ,
255 help =
'specify the candle on which to run DIGI PILE UP and repeat all the tests set to run on that candle with PILE UP')
256 parser.add_option(
'--PUInputFile' , type=
'string', dest=
'PUInputFile' , metavar=
'<FILE>' ,
257 help =
'specify the root file to pick the pile-up events from')
258 parser.add_option(
'--RunTimeSizePU' , type=
'string', dest=
'RunTimeSizePU' , metavar=
'<CANDLES>' ,
259 help =
'specify on which candles to run the TimeSize tests with PILE UP')
260 parser.add_option(
'--RunIgProfPU' , type=
'string', dest=
'RunIgProfPU' , metavar=
'<CANDLES>' ,
261 help =
'specify on which candles to run the IgProf tests with PILE UP')
262 parser.add_option(
'--RunCallgrindPU' , type=
'string', dest=
'RunCallgrindPU' , metavar=
'<CANDLES>' ,
263 help =
'specify on which candles to run the Callgrind tests with PILE UP')
264 parser.add_option(
'--RunMemcheckPU' , type=
'string', dest=
'RunMemcheckPU' , metavar=
'<CANDLES>' ,
265 help =
'specify on which candles to run the Memcheck tests with PILE UP')
268 parser.add_option(
'--filein' , type=
'string', dest=
'userInputFile' , metavar=
'<FILE>',
269 help =
'specify input RAW root file for HLT and RAW2DIGI-RECO (list the files in the same order as the candles for the tests)')
272 parser.add_option(
'--mail', type=
'string', dest=
'MailLogRecipients', metavar=
'<EMAIL ADDRESS>', default=self.
user, help=
'specify valid email address(es) name@domain in order to receive notification at the end of the performance suite running with the cmsPerfSuite.log file')
275 parser.add_option(
'--no_tarball', action=
"store_false", dest=
'tarball', default=
True, help=
'Turn off automatic tarball creation at the end of the performance suite execution')
282 devel = opt.OptionGroup(parser,
"Developer Options",
283 "Caution: use these options at your own risk." 284 "It is believed that some of them bite.\n")
286 devel.add_option(
'-p',
'--profile' , type=
"str" , dest=
'profilers', metavar=
"<PROFILERS>" ,
287 help =
'Profile codes to use for cmsRelvalInput' )
288 devel.add_option(
'-f',
'--false-run', action=
"store_true", dest=
'dryrun' ,
290 devel.add_option(
'-d',
'--debug' , action=
'store_true', dest=
'debug' ,
292 devel.add_option(
'--quicktest' , action=
"store_true", dest=
'quicktest',
293 help =
'Quick overwrite all the defaults to small numbers so that we can run a quick test of our chosing.' )
294 devel.add_option(
'--test' , action=
"store_true", dest=
'unittest' ,
295 help =
'Perform a simple test, overrides other options. Overrides verbosity and sets it to false.' )
296 devel.add_option(
'--no_exec' , action=
"store_true", dest=
'noexec' ,
297 help =
'Run the suite without executing the cmsRelvalreport.py commands in the various directories. This is a useful debugging tool.' )
298 parser.add_option_group(devel)
299 (options, args) = parser.parse_args(argslist)
302 self.
_debug = options.debug
307 create = options.create
308 castordir = options.castordir
309 TimeSizeEvents = options.TimeSizeEvents
310 IgProfEvents = options.IgProfEvents
311 CallgrindEvents = options.CallgrindEvents
312 MemcheckEvents = options.MemcheckEvents
313 cmsScimark = options.cmsScimark
314 cmsScimarkLarge = options.cmsScimarkLarge
315 cmsdriverOptions = options.cmsdriverOptions
316 stepOptions = options.stepOptions
317 quicktest = options.quicktest
319 runonspare = options.runonspare
320 profilers = options.profilers.strip()
321 cpu = options.cpu.strip()
322 bypasshlt = options.bypasshlt
323 cores = options.cores
324 logfile = options.logfile
325 prevrel = options.previousrel
326 outputdir = options.outputdir
327 RunTimeSize = options.RunTimeSize
328 RunIgProf = options.RunIgProf
329 RunCallgrind = options.RunCallgrind
330 RunMemcheck = options.RunMemcheck
331 RunDigiPileUp = options.RunDigiPileUp
332 RunTimeSizePU = options.RunTimeSizePU
333 RunIgProfPU = options.RunIgProfPU
334 RunCallgrindPU = options.RunCallgrindPU
335 RunMemcheckPU = options.RunMemcheckPU
336 PUInputFile = options.PUInputFile
337 userInputFile = options.userInputFile
338 if options.MailLogRecipients !=
"" and self.
user not in options.MailLogRecipients:
339 MailLogRecipients= self.
user+
","+options.MailLogRecipients
341 MailLogRecipients=options.MailLogRecipients
342 tarball = options.tarball
347 if not logfile ==
None:
348 logfile = os.path.abspath(logfile)
349 logdir = os.path.dirname(logfile)
350 if not os.path.exists(logdir):
351 parser.error(
"Directory to output logfile does not exist")
353 logfile = os.path.abspath(logfile)
358 if "GEN,SIM" in stepOptions:
359 self.logh.write(
"WARNING: Please use GEN-SIM with a hypen not a \",\"!\n")
362 if stepOptions ==
"" or stepOptions ==
'Default':
365 stepOptions=
'--usersteps=%s' % (stepOptions)
370 isnumreg = re.compile(
"^-?[0-9]*$")
371 found = isnumreg.search(profilers)
373 parser.error(
"profile codes option contains non-numbers")
380 outputdir = os.getcwd()
382 outputdir = os.path.abspath(outputdir)
384 if not os.path.isdir(outputdir):
385 parser.error(
"%s is not a valid output directory" % outputdir)
391 numetcomreg = re.compile(
"^[0-9,]*")
392 if not numetcomreg.search(cpu):
393 parser.error(
"cpu option needs to be a comma separted list of ints or a single int")
399 cpu =
map(
lambda x:
int(x),cpustr.split(
","))
401 cpu = [
int(cpustr) ]
406 if not prevrel ==
"":
407 prevrel = os.path.abspath(prevrel)
408 if not os.path.exists(prevrel):
409 self.logh.write(
"ERROR: Previous release dir %s could not be found" % prevrel)
428 if stepOptions ==
"":
429 stepOptions =
"GEN-SIM,DIGI,L1,DIGI2RAW,HLT,RAW2DIGI-RECO" 444 CallgrindPUCandles=[]
446 userInputRootFiles=[]
448 TimeSizeCandles = RunTimeSize.split(
",")
450 IgProfCandles = RunIgProf.split(
",")
452 CallgrindCandles = RunCallgrind.split(
",")
454 MemcheckCandles = RunMemcheck.split(
",")
456 for candle
in RunDigiPileUp.split(
","):
457 if candle
in TimeSizeCandles:
458 TimeSizePUCandles.append(candle)
459 if candle
in IgProfCandles:
460 IgProfPUCandles.append(candle)
461 if candle
in CallgrindCandles:
462 CallgrindPUCandles.append(candle)
463 if candle
in MemcheckCandles:
464 MemcheckPUCandles.append(candle)
466 TimeSizePUCandles.extend(RunTimeSizePU.split(
","))
468 temp=set(TimeSizePUCandles)
469 TimeSizePUCandles=
list(temp)
471 IgProfPUCandles.extend(RunIgProfPU.split(
","))
473 temp=set(IgProfPUCandles)
474 IgProfPUCandles=
list(temp)
476 CallgrindPUCandles.extend(RunCallgrindPU.split(
","))
478 temp=set(CallgrindPUCandles)
479 CallgrindPUCandles=
list(temp)
481 MemcheckPUCandles.extend(RunMemcheckPU.split(
","))
483 temp=set(MemcheckPUCandles)
484 MemcheckPUCandles=
list(temp)
486 userInputRootFiles=userInputFile.split(
",")
493 cmsdriverPUOptions=
"" 496 if TimeSizePUCandles
or IgProfPUCandles
or CallgrindPUCandles
or MemcheckPUCandles:
498 cmsdriverPUOptions =
'--cmsdriver="%s %s%s"'%(cmsdriverOptions,
" --pileup=",cmsDriverPileUpOption)
500 cmsdriverOptions =
'--cmsdriver="%s"'%cmsdriverOptions
544 exitstat = self.
runcmd(cmd)
561 self.logh.write(
str(command) +
"\n")
574 process = subprocess.Popen(command,shell=
True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
576 exitstat= process.wait()
577 cmdout = process.stdout.read()
578 exitstat = process.returncode
579 except OSError
as detail:
580 self.logh.write(
"Race condition in subprocess.Popen has robbed us of the exit code of the %s process (PID %s).Assume it failed!\n %s\n"%(command,pid,detail))
583 cmdout=
"Race condition in subprocess.Popen has robbed us of the exit code of the %s process (PID %s).Assume it failed!\n %s"%(command,pid,detail)
585 self.logh.write(cmdout)
588 self.logh.write(
"Something strange is going on! Exit code was None for command %s: check if it really ran!"%command)
597 self.logh.write(self.
getDate() +
"\n")
603 adir = os.path.join(pfdir,
"%s_%s" % (candle,profiler))
604 self.
runcmd(
"mkdir -p %s" % adir )
613 def cprootfile(self,dir,candle,NumOfEvents,cmsdriverOptions=""):
614 cmds = (
"cd %s" % dir,
615 "cp -pR ../%s_IgProf/%s_GEN,SIM.root ." % (candle,CandFname[candle]))
618 self.logh.write(
"Since there was no ../%s_IgProf/%s_GEN,SIM.root file it will be generated first\n"%(candle,CandFname[candle]))
620 cmd =
"cd %s ; cmsDriver.py %s -s GEN,SIM -n %s --fileout %s_GEN,SIM.root %s>& %s_GEN_SIM_for_valgrind.log" % (dir,KeywordToCfi[candle],
str(NumOfEvents),candle,cmsdriverOptions,candle)
625 cmdout=subprocess.Popen(cmd,shell=
True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT).stdout.read()
635 for line
in open(file,
"r"): 636 if "cerr" in line
or "CMSException" in line:
637 self.logh.write(
"ERROR: %s\n" % line)
639 except OSError
as detail:
640 self.logh.write(
"WARNING: %s\n" % detail)
642 except IOError
as detail:
643 self.logh.write(
"WARNING: %s\n" % detail)
655 InputFileName=os.path.join(dir,
"SimulationCandles_%s.txt"%(self.
cmssw_version))
656 InputFile=open(InputFileName,
"r") 657 InputLines=InputFile.readlines() 659 Outputfile=open(InputFileName,"w")
660 simRegxp=re.compile(
"step=GEN,SIM")
661 digiRegxp=re.compile(
"step=DIGI")
662 CallgrindRegxp=re.compile(
"ValgrindFCE")
663 MemcheckRegxp=re.compile(
"Memcheck")
664 NumEvtRegxp=re.compile(
"-n 1")
665 for line
in InputLines:
666 if simRegxp.search(line)
and CallgrindRegxp.search(line):
668 elif simRegxp.search(line)
and MemcheckRegxp.search(line):
670 if NumEvtRegxp.search(line):
671 line=NumEvtRegxp.sub(
r"-n 5",line)
673 self.logh.write(
"The number of Memcheck event was not changed since the original number of Callgrind event was not 1!\n")
674 Outputfile.write(line)
675 elif digiRegxp.search(line)
and MemcheckRegxp.search(line):
677 if NumEvtRegxp.search(line):
678 line=NumEvtRegxp.sub(
r"-n 5",line)
680 self.logh.write(
"The number of Memcheck event was not changed since the original number of Callgrind event was not 1!\n")
681 Outputfile.write(line)
683 Outputfile.write(line)
696 redirect =
" -large >>" 700 for i
in range(bencher):
702 if not os.path.exists(os.path.join(pfdir,os.path.basename(name))):
704 open(os.path.join(pfdir,os.path.basename(name)))
706 command= cmd + redirect + os.path.join(pfdir,os.path.basename(name))
707 self.
printFlush(command +
" [%s/%s]" % (i+1,bencher))
716 cmds = (
"cd %s" % (dir),
717 "%s -i SimulationCandles_%s.txt -t perfreport_tmp -R -P >& %s.log" % (cmd,self.
cmssw_version,candle))
722 if self.
_unittest and (
not exitstat == 0):
723 self.logh.write(
"ERROR: CMS Report returned a non-zero exit status \n")
732 cmsdrvreg = re.compile(
"^cmsDriver.py")
735 stepreg = re.compile(
"--step=([^ ]*)")
736 previousCmdOnline =
"" 737 for line
in open(os.path.join(dir,
"SimulationCandles_%s.txt" % (cmsver))):
738 if (
not line.lstrip().startswith(
"#"))
and not (line.isspace()
or len(line) == 0):
739 cmdonline = line.split(
"@@@",1)[0]
740 if cmsdrvreg.search(cmdonline)
and not previousCmdOnline == cmdonline:
741 stepbeingrun =
"Unknown" 742 matches = stepreg.search(cmdonline)
743 if not matches ==
None:
744 stepbeingrun = matches.groups()[0]
745 if "PILEUP" in cmdonline:
746 stepbeingrun +=
"_PILEUP" 747 self.logh.write(cmdonline +
"\n")
748 cmds = (
"cd %s" % (dir),
749 "%s >& ../cmsdriver_unit_test_%s_%s.log" % (cmdonline,candle,stepbeingrun))
751 self.logh.write(cmds +
"\n")
756 xstatus = out & 0xffff
757 self.logh.write(
"FATAL ERROR: CMS Driver returned a non-zero exit status (which is %s) when running %s for candle %s. Signal interrupt was %s\n" % (xstatus,stepbeingrun,candle,sig))
759 previousCmdOnline = cmdonline
764 def runCmsInput(self,cpu,dir,numevents,candle,cmsdrvopts,stepopt,profiles,bypasshlt,userInputFile):
769 bypass =
"--bypass-hlt" 770 userInputFileOption=
"" 772 userInputFileOption =
"--filein %s"%userInputFile
776 cmds = (
"cd %s" % (dir),
777 "%s %s \"%s\" %s %s %s %s %s" % (cmd,
783 bypass,userInputFileOption))
786 if self.
_unittest and (
not exitstat == 0):
787 self.logh.write(
"ERROR: CMS Report Input returned a non-zero exit status \n" )
793 def simpleGenReport(self,cpus,perfdir=os.getcwd(),NumEvents=1,candles=[
'MinBias'],cmsdriverOptions=
'',stepOptions=
'',Name=
'',profilers=
'',bypasshlt=
'',userInputRootFiles=
''):
794 callgrind = Name ==
"Callgrind" 795 memcheck = Name ==
"Memcheck" 797 profCodes = {
"TimeSize" :
"0123",
805 profiles = profCodes[Name]
806 if not profilers ==
"":
809 RelvalreportExitCode=0
814 pfdir = os.path.join(perfdir,
"cpu_%s" % cpu)
815 for candle
in candles:
818 if "--pileup" in cmsdriverOptions:
819 candlename=candle+
"_PU" 825 if userInputRootFiles:
826 self.logh.write(userInputRootFiles)
827 userInputFile=userInputRootFiles[0]
831 self.
runCmsInput(cpu,adir,NumEvents,candle,cmsdriverOptions,stepOptions,profiles,bypasshlt,userInputFile)
834 if userInputRootFiles:
835 self.logh.write(
"Variable userInputRootFiles is %s\n"%userInputRootFiles)
843 candleregexp=re.compile(candle)
844 for file
in userInputRootFiles:
845 if candleregexp.search(file):
847 self.logh.write(
"For these %s %s tests will use user input file %s\n"%(candlename,Name,userInputFile))
848 if userInputFile ==
"":
849 self.logh.write(
"***WARNING: For these %s %s tests could not find a matching input file in %s: will try to do without it!!!!!\n"%(candlename,Name,userInputRootFiles))
853 DummyTestName=candlename+
"_"+stepOptions.split(
"=")[1]
855 TimerInfo[Name].
update({DummyTestName:DummyTimer})
857 self.
runCmsInput(cpu,adir,NumEvents,candle,cmsdriverOptions,stepOptions,profiles,bypasshlt,userInputFile)
860 self.logh.write(
"Running in debugging mode, without executing cmsRelvalreport.py\n")
866 self.logh.write(
"Individual cmsRelvalreport.py ExitCode %s\n"%ExitCode)
867 RelvalreportExitCode=RelvalreportExitCode+ExitCode
868 self.logh.write(
"Summed cmsRelvalreport.py ExitCode %s\n"%RelvalreportExitCode)
870 DummyTimer.set_end(datetime.datetime.now())
875 globpath = os.path.join(adir,
"*.log")
876 self.logh.write(
"Looking for logs that match %s\n" % globpath)
877 logs = glob.glob(globpath)
879 self.logh.write(
"Found log %s\n" % log)
881 self.
printFlush(
"Returned cumulative RelvalreportExitCode is %s"%RelvalreportExitCode)
882 return RelvalreportExitCode
896 castordir =
"/castor/cern.ch/cms/store/relval/performance/",
897 TimeSizeEvents = 100 ,
899 CallgrindEvents = 1 ,
902 cmsScimarkLarge = 10 ,
903 cmsdriverOptions =
"" ,
904 cmsdriverPUOptions=
"" ,
914 perfsuitedir = os.getcwd(),
916 TimeSizeCandles =
"" ,
918 CallgrindCandles =
"" ,
919 MemcheckCandles =
"" ,
920 TimeSizePUCandles =
"" ,
921 IgProfPUCandles =
"" ,
922 CallgrindPUCandles =
"" ,
923 MemcheckPUCandles =
"" ,
926 MailLogRecipients =
"" ,
933 if not logfile ==
None:
935 self.
logh = open(logfile,
"a")
936 except (OSError, IOError)
as detail:
937 self.logh.write(detail +
"\n")
943 HEPSPEC06_file=open(
"/build/HEPSPEC06.score",
"r") 944 for line
in HEPSPEC06_file.readlines():
945 if not line.startswith(
"#")
and "HEPSPEC06" in line:
948 self.logh.write(
"***Warning***: Could not find file /build/HEPSPEC06.score file on this machine!\n")
952 localcpuinfo=os.path.join(perfsuitedir,
"cpuinfo")
954 if os.path.exists(localcpuinfo):
957 self.logh.write(
"Copying /proc/cpuinfo in current working directory (%s)\n"%perfsuitedir)
958 cpuinfo_exitcode=self.
runcmd(
"cp /proc/cpuinfo %s"%perfsuitedir)
959 localmeminfo=os.path.join(perfsuitedir,
"meminfo")
961 if os.path.exists(localmeminfo):
964 self.logh.write(
"Copying /proc/meminfo in current working directory (%s)\n"%perfsuitedir)
965 meminfo_exitcode=self.
runcmd(
"cp /proc/meminfo %s"%perfsuitedir)
966 if cpuinfo_exitcode
or meminfo_exitcode:
967 self.logh.write(
"There was an issue copying the cpuinfo or meminfo files!\n")
971 if not prevrel ==
"":
972 self.logh.write(
"Production of regression information has been requested with release directory %s\n" % prevrel)
973 if not cmsdriverOptions ==
"":
974 self.logh.write(
"Running cmsDriver.py with user defined options: %s\n" % cmsdriverOptions)
976 cmsdriverOptionsRelvalInput=
"--cmsdriver="+cmsdriverOptions
978 if not stepOptions ==
"":
979 self.logh.write(
"Running user defined steps only: %s\n" % stepOptions)
981 setpOptionsRelvalInput=
"--usersteps="+stepOptions
985 bypasshltRelvalInput=
"--bypass-hlt" 987 self.logh.write(
"Current Architecture is %s\n"%self.
cmssw_arch)
988 self.logh.write(
"Current CMSSW version is %s\n"%self.
cmssw_version)
989 self.logh.write(
"This machine ( %s ) is assumed to have %s cores, and the suite will be run on cpu %s\n" %(self.
host,cores,cpus))
990 self.logh.write(
"This machine's HEPSPEC06 score is: %s \n"%self.
HEPSPEC06)
991 path=os.path.abspath(
".")
992 self.logh.write(
"Performance Suite started running at %s on %s in directory %s, run by user %s\n" % (self.
getDate(),self.
host,path,self.
user))
997 TimerInfo={
'TotalTime':{
'TotalTime':TotalTime}}
1000 showtags=subprocess.Popen(
"showtags -r",shell=
True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT).stdout.read()
1001 self.logh.write(showtags)
1005 self.logh.write(
"The performance suite results tarball will be stored in CASTOR at %s\n" % self.
_CASTOR_DIR)
1006 self.logh.write(
"%s TimeSize events\n" % TimeSizeEvents)
1007 self.logh.write(
"%s IgProf events\n" % IgProfEvents)
1008 self.logh.write(
"%s Callgrind events\n" % CallgrindEvents)
1009 self.logh.write(
"%s Memcheck events\n" % MemcheckEvents)
1010 self.logh.write(
"%s cmsScimark benchmarks before starting the tests\n" % cmsScimark)
1011 self.logh.write(
"%s cmsScimarkLarge benchmarks before starting the tests\n" % cmsScimarkLarge)
1021 cpupath = os.path.join(perfsuitedir,
"cpu_%s" % cpu)
1022 if not os.path.exists(cpupath):
1032 self.logh.write(
"Full path of all the scripts used in this run of the Performance Suite:\n")
1033 for script
in AllScripts:
1034 which=
"which " + script
1039 whichstdout=subprocess.Popen(which,shell=
True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT).stdout.read()
1040 self.logh.write(whichstdout)
1043 command=
"taskset -c %s %s" % (cpu,script)
1050 if (len(cpu_list) != cores):
1051 for core
in range(cores):
1052 if (
not core
in cpus)
and runonspare:
1053 self.logh.write(
"Submitting cmsScimarkLaunch.csh to run on core cpu "+
str(core) +
"\n")
1054 subcmd =
"cd %s ; cmsScimarkLaunch.csh %s" % (perfsuitedir,
str(core))
1055 command=
"taskset -c %s sh -c \"%s\" &" % (
str(core), subcmd)
1056 self.logh.write(command +
"\n")
1062 subprocess.Popen(command,shell=
True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
1067 benching =
not self.
_debug 1073 scimark = open(os.path.join(perfsuitedir,
"cmsScimark2.log") ,
"w")
1074 scimarklarge = open(os.path.join(perfsuitedir,
"cmsScimark2_large.log"),
"w")
1076 self.logh.write(
"Starting with %s cmsScimark on cpu%s\n" % (cmsScimark,cpu))
1077 cmsScimarkInitialTime=
PerfSuiteTimer(start=datetime.datetime.now())
1078 TimerInfo.update({
'cmsScimarkTime':{
'cmsScimarkInitial':cmsScimarkInitialTime}})
1079 self.
benchmarks(cpu,perfsuitedir,scimark.name,cmsScimark)
1080 cmsScimarkInitialTime.set_end(datetime.datetime.now())
1082 if cmsScimarkLarge > 0:
1083 self.logh.write(
"Following with %s cmsScimarkLarge on cpu%s\n" % (cmsScimarkLarge,cpu))
1084 cmsScimarkLargeInitialTime=
PerfSuiteTimer(start=datetime.datetime.now())
1085 TimerInfo[
'cmsScimarkTime'].
update({
'cmsScimarkLargeInitial':cmsScimarkLargeInitialTime})
1086 self.
benchmarks(cpu,perfsuitedir,scimarklarge.name,cmsScimarkLarge, large=
True)
1087 cmsScimarkLargeInitialTime.set_end(datetime.datetime.now())
1090 if (TimeSizePUCandles
or IgProfPUCandles
or CallgrindPUCandles
or MemcheckPUCandles)
and not (
"FASTSIM" in stepOptions):
1092 PUInputName=os.path.join(perfsuitedir,
"INPUT_PILEUP_EVENTS.root")
1098 if '/store/relval/' in PUInputFile:
1103 if PUInputFile.startswith(
'/store/relval/'):
1106 PUInputFile=
"root://eoscms//eos/cms"+PUInputFile
1108 self.logh.write(
"Copying the file %s locally to %s\n"%(PUInputFile,PUInputName))
1110 GetPUInput=subprocess.Popen(
"%s %s %s"%(copycmd,PUInputFile,PUInputName), shell=
True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
1111 GetPUInputExitCode=GetPUInput.wait()
1113 if GetPUInputExitCode:
1114 self.logh.write(
"The copying of the pile-up input file returned a non-zero exit code: %s \nThis is the stdout+stderr if the command:\n%s\n"%(GetPUInputExitCode,GetPUInput.stdout))
1116 if not os.path.exists(PUInputName):
1117 self.logh.write(
"The necessary INPUT_PILEUP_EVENTS.root file was not found in the working directory %s\nExiting now!"%perfsuitedir)
1122 self.
printFlush(
"Some PILE UP tests will be run!")
1124 self.
printFlush(
"cmsdriverPUOptions is %s"%cmsdriverPUOptions)
1128 if TimeSizeEvents > 0:
1130 TimerInfo.update({
'TimeSize':{
'TotalTime':TimeSizeTime}})
1132 self.logh.write(
"Launching the TimeSize tests (TimingReport, TimeReport, SimpleMemoryCheck, EdmSize) with %s events each\n" % TimeSizeEvents)
1134 TimerInfo[
'TimeSize'].
update({
'NoPileUpTime':NoPileUpTime})
1137 ReportExit=self.
simpleGenReport(cpus,perfsuitedir,TimeSizeEvents,TimeSizeCandles,cmsdriverOptions,stepOptions,
"TimeSize",profilers,bypasshlt,userInputFile)
1138 FinalExitCode=FinalExitCode+ReportExit
1141 NoPileUpTime.set_end(datetime.datetime.now())
1144 if TimeSizePUCandles:
1145 self.logh.write(
"Launching the PILE UP TimeSize tests (TimingReport, TimeReport, SimpleMemoryCheck, EdmSize) with %s events each\n" % TimeSizeEvents)
1147 TimerInfo[
'TimeSize'].
update({
'PileUpTime':PileUpTime})
1150 ReportExit=self.
simpleGenReport(cpus,perfsuitedir,TimeSizeEvents,TimeSizePUCandles,cmsdriverPUOptions,stepOptions,
"TimeSize",profilers,bypasshlt,userInputFile)
1151 FinalExitCode=FinalExitCode+ReportExit
1154 PileUpTime.set_end(datetime.datetime.now())
1157 if not (TimeSizeCandles
or TimeSizePUCandles):
1158 self.
printFlush(
"A number of events (%s) for TimeSize tests was selected, but no candle for regular or pileup tests was selected!"%(TimeSizeEvents))
1161 TimeSizeTime.set_end(datetime.datetime.now())
1166 self.logh.write(
"Stopping all cmsScimark jobs now\n")
1168 stopcmd =
"sh -c \"%s\"" % subcmd
1173 self.
printFlush(subprocess.Popen(stopcmd,shell=
True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT).stdout.read())
1179 elif len(cpu_list) == cores:
1183 AvailableCores=range(cores)
1188 if IgProfEvents > 0:
1195 self.
printFlush(
"Special profiler option for IgProf was indicated by the user: %s"%profilers)
1197 IgProfProfilerArgs={
1198 'perfdir':perfsuitedir,
1199 'NumEvents':IgProfEvents,
1200 'candles':IgProfCandles,
1201 'cmsdriverOptions':cmsdriverOptions,
1202 'stepOptions':stepOptions,
1204 'profilers':profilers,
1205 'bypasshlt':bypasshlt,
1206 'userInputRootFiles':userInputFile
1209 TestsToDo.append(IgProfProfilerArgs)
1210 self.
printFlush(
"Appended IgProf test with profiler option %s to the TestsToDo list"%profilers)
1214 self.
printFlush(
"Splitting the IgProf tests into Perf and Mem to parallelize the cmsRun execution as much as possible:")
1218 'perfdir':perfsuitedir,
1219 'NumEvents':IgProfEvents,
1220 'candles':IgProfCandles,
1221 'cmsdriverOptions':cmsdriverOptions,
1222 'stepOptions':stepOptions,
1223 'Name':
"IgProf_Perf",
1224 'profilers':profilers,
1225 'bypasshlt':bypasshlt,
1226 'userInputRootFiles':userInputFile
1229 TestsToDo.append(IgProfPerfArgs)
1230 self.
printFlush(
"Appended IgProf PERF test to the TestsToDo list")
1234 'perfdir':perfsuitedir,
1235 'NumEvents':IgProfEvents,
1236 'candles':IgProfCandles,
1237 'cmsdriverOptions':cmsdriverOptions,
1238 'stepOptions':stepOptions,
1239 'Name':
"IgProf_Mem",
1240 'profilers':profilers,
1241 'bypasshlt':bypasshlt,
1242 'userInputRootFiles':userInputFile
1245 TestsToDo.append(IgProfMemArgs)
1246 self.
printFlush(
"Appended IgProf MEM test to the TestsToDo list")
1252 self.
printFlush(
"Preparing IgProf PileUp tests")
1257 self.
printFlush(
"Special profiler option for IgProf was indicated by the user: %s"%profilers)
1259 IgProfProfilerPUArgs={
1260 'perfdir':perfsuitedir,
1261 'NumEvents':IgProfEvents,
1262 'candles':IgProfPUCandles,
1263 'cmsdriverOptions':cmsdriverPUOptions,
1264 'stepOptions':stepOptions,
1266 'profilers':profilers,
1267 'bypasshlt':bypasshlt,
1268 'userInputRootFiles':userInputFile
1271 TestsToDo.append(IgProfProfilerPUArgs)
1272 self.
printFlush(
"Appended IgProf PileUp test with profiler option %s to the TestsToDo list"%profilers)
1274 self.
printFlush(
"Splitting the IgProf tests into Perf and Mem to parallelize the cmsRun execution as much as possible:")
1278 'perfdir':perfsuitedir,
1279 'NumEvents':IgProfEvents,
1280 'candles':IgProfPUCandles,
1281 'cmsdriverOptions':cmsdriverPUOptions,
1282 'stepOptions':stepOptions,
1283 'Name':
"IgProf_Perf",
1284 'profilers':profilers,
1285 'bypasshlt':bypasshlt,
1286 'userInputRootFiles':userInputFile
1289 TestsToDo.append(IgProfPerfPUArgs)
1290 self.
printFlush(
"Appended IgProf MEM PileUp test to the TestsToDo list")
1294 'perfdir':perfsuitedir,
1295 'NumEvents':IgProfEvents,
1296 'candles':IgProfPUCandles,
1297 'cmsdriverOptions':cmsdriverPUOptions,
1298 'stepOptions':stepOptions,
1299 'Name':
"IgProf_Mem",
1300 'profilers':profilers,
1301 'bypasshlt':bypasshlt,
1302 'userInputRootFiles':userInputFile
1305 TestsToDo.append(IgProfMemPUArgs)
1306 self.
printFlush(
"Appended IgProf MEM PileUp test to the TestsToDo list")
1307 if not (IgProfCandles
or IgProfPUCandles):
1308 self.
printFlush(
"A number of events (%s) for IgProf tests was selected, but no candle for regular or pileup tests was selected!"%(IgProfEvents))
1312 if CallgrindEvents > 0:
1313 if CallgrindCandles:
1316 'perfdir':perfsuitedir,
1317 'NumEvents':CallgrindEvents,
1318 'candles':CallgrindCandles,
1319 'cmsdriverOptions':cmsdriverOptions,
1320 'stepOptions':stepOptions,
1322 'profilers':profilers,
1323 'bypasshlt':bypasshlt,
1324 'userInputRootFiles':userInputFile
1327 TestsToDo.append(CallgrindArgs)
1328 self.
printFlush(
"Appended Callgrind test to the TestsToDo list")
1330 if CallgrindPUCandles:
1331 self.
printFlush(
"Preparing Callgrind PileUp tests")
1333 'perfdir':perfsuitedir,
1334 'NumEvents':CallgrindEvents,
1335 'candles':CallgrindPUCandles,
1336 'cmsdriverOptions':cmsdriverPUOptions,
1337 'stepOptions':stepOptions,
1339 'profilers':profilers,
1340 'bypasshlt':bypasshlt,
1341 'userInputRootFiles':userInputFile
1344 TestsToDo.append(CallgrindPUArgs)
1345 self.
printFlush(
"Appended Callgrind PileUp test to the TestsToDo list")
1346 if not (CallgrindCandles
or CallgrindPUCandles):
1347 self.
printFlush(
"A number of events (%s) for Callgrind tests was selected, but no candle for regular or pileup tests was selected!"%(CallgrindEvents))
1349 if MemcheckEvents > 0:
1353 'perfdir':perfsuitedir,
1354 'NumEvents':MemcheckEvents,
1355 'candles':MemcheckCandles,
1356 'cmsdriverOptions':cmsdriverOptions,
1357 'stepOptions':stepOptions,
1359 'profilers':profilers,
1360 'bypasshlt':bypasshlt,
1361 'userInputRootFiles':userInputFile
1364 TestsToDo.append(MemcheckArgs)
1365 self.
printFlush(
"Appended Memcheck test to the TestsToDo list")
1367 if MemcheckPUCandles:
1368 self.
printFlush(
"Preparing Memcheck PileUp tests")
1370 'perfdir':perfsuitedir,
1371 'NumEvents':MemcheckEvents,
1372 'candles':MemcheckPUCandles,
1373 'cmsdriverOptions':cmsdriverPUOptions,
1374 'stepOptions':stepOptions,
1376 'profilers':profilers,
1377 'bypasshlt':bypasshlt,
1378 'userInputRootFiles':userInputFile
1381 TestsToDo.append(MemcheckPUArgs)
1382 self.
printFlush(
"Appended Memcheck PileUp test to the TestsToDo list")
1383 if not (MemcheckCandles
or MemcheckPUCandles):
1384 self.
printFlush(
"A number of events (%s) for Memcheck tests was selected, but no candle for regular or pileup tests was selected!"%(MemcheckEvents))
1388 if IgProfEvents
or CallgrindEvents
or MemcheckEvents:
1390 self.
printFlush(
"Threading all remaining tests on all %s available cores!"%len(AvailableCores))
1396 OriginalAvailableCores=
list(AvailableCores)
1398 self.
printFlush(
"Original available cores list: %s"%AvailableCores)
1401 activePerfTestThreads={}
1410 self.
printFlush(
"Currently %s tests are scheduled to be run:"%len(TestsToDo))
1416 self.
printFlush(
"There is/are %s core(s) available"%len(AvailableCores))
1417 cpu=AvailableCores.pop()
1419 simpleGenReportArgs=TestsToDo.pop()
1420 self.
printFlush(
"Let's submit %s test on core %s"%(simpleGenReportArgs[
'Name'],cpu))
1422 if simpleGenReportArgs[
'Name']
not in TimerInfo.keys():
1425 TimerInfo.update({simpleGenReportArgs[
'Name']:{
'TotalTime':self.
PerfTestTotalTimer}})
1427 self.
printFlush(
"Starting thread %s"%threadToDo)
1428 ReportExitCode=threadToDo.start()
1429 self.
printFlush(
"Adding thread %s to the list of active threads"%threadToDo)
1430 activePerfTestThreads[cpu]=threadToDo
1436 activeTestNamesPU=[]
1437 for cpu
in activePerfTestThreads.keys():
1438 if activePerfTestThreads[cpu].isAlive():
1440 if "--pileup" in activePerfTestThreads[cpu].simpleGenReportArgs[
'cmsdriverOptions']:
1441 activeTestNamesPU.append(activePerfTestThreads[cpu].simpleGenReportArgs[
'Name'])
1443 activeTestNames.append(activePerfTestThreads[cpu].simpleGenReportArgs[
'Name'])
1445 elif cpu
not in AvailableCores:
1449 self.
printFlush(
"%s test, in thread %s is done running on core %s"%(activePerfTestThreads[cpu].simpleGenReportArgs[
'Name'],activePerfTestThreads[cpu],cpu) )
1450 self.
printFlush(
"About to append cpu %s to AvailableCores list"%cpu)
1451 AvailableCores.append(cpu)
1456 if "--pileup" in activePerfTestThreads[cpu].simpleGenReportArgs[
'cmsdriverOptions']:
1458 activeTestNamesPU.remove(activePerfTestThreads[cpu].simpleGenReportArgs[
'Name'])
1463 activeTestNames.remove(activePerfTestThreads[cpu].simpleGenReportArgs[
'Name'])
1467 activePerfTestThreads.pop(cpu)
1475 for TestName
in [
"IgProf_Perf",
"IgProf_Mem",
"Memcheck",
"Valgrind"]:
1476 if (TestName
not in activeTestNames)
and (TestName
not in activeTestNamesPU) :
1478 TimerInfo[TestName][
'TotalTime'].set_end(datetime.datetime.now())
1485 if not AvailableCores==[]
and (set(AvailableCores)==set(range(
cmsCpuInfo.get_NumOfCores()))
or set(AvailableCores)==set(OriginalAvailableCores))
and not TestsToDo:
1486 self.
printFlush(
"PHEW! We're done... all TestsToDo are done... at %s "%(self.
getDate()))
1501 self.
printFlush(
"Waiting for tests to be done...")
1510 self.logh.write(
"Ending with %s cmsScimark on cpu%s\n" % (cmsScimark,cpu))
1511 cmsScimarkFinalTime=
PerfSuiteTimer(start=datetime.datetime.now())
1512 TimerInfo[
'cmsScimarkTime'].
update({
'cmsScimarkFinal':cmsScimarkFinalTime})
1514 self.
benchmarks(cpu,perfsuitedir,scimark.name,cmsScimark)
1515 cmsScimarkFinalTime.set_end(datetime.datetime.now())
1516 if cmsScimarkLarge > 0:
1517 self.logh.write(
"Following with %s cmsScimarkLarge on cpu%s\n" % (cmsScimarkLarge,cpu))
1518 cmsScimarkLargeFinalTime=
PerfSuiteTimer(start=datetime.datetime.now())
1519 TimerInfo[
'cmsScimarkTime'].
update({
'cmsScimarkLargeFinal':cmsScimarkLargeFinalTime})
1520 self.
benchmarks(cpu,perfsuitedir,scimarklarge.name,cmsScimarkLarge,large=
True)
1521 cmsScimarkLargeFinalTime.set_end(datetime.datetime.now())
1524 self.logh.write(
"Running the regression analysis with respect to %s\n"%
getVerFromLog(prevrel))
1525 self.logh.write(time.ctime(time.time()))
1533 TimerInfo.update({
'tarballTime':{
'TotalTime':tarballTime}})
1538 if "=" in str(stepOptions):
1539 fileStepOption=
str(stepOptions).
split(
"=")[1]
1541 fileStepOption=
str(stepOptions)
1542 if fileStepOption==
"":
1543 fileStepOption=
"UnknownStep" 1545 fileWorkingDir=os.path.basename(perfsuitedir)
1550 fileEventContentOption=
"UnknownEventContent" 1551 fileConditionsOption=
"UnknownConditions" 1552 for token
in cmsdriverOptions.split(
"--"):
1553 if token!=
'' and 'cmsdriver' not in token:
1555 fileOption=token.split(
"=")[0]
1556 fileOptionValue=token.split(
"=")[1].
strip(
"'").
strip(
'"')
1558 fileOption=token.split()[0]
1559 fileOptionValue=token.split()[1].
strip(
"'").
strip(
'"')
1560 if "eventcontent" or "conditions" in fileOption:
1561 if "eventcontent" in fileOption:
1562 fileEventContentOption=fileOptionValue
1563 elif "conditions" in fileOption:
1566 if "auto:" in fileOptionValue:
1568 fileConditionsOption = autoCond[ fileOptionValue.split(
':')[1] ]
1574 if "," in fileOptionValue:
1575 fileConditionsOption=fileOptionValue.split(
"::")[0].
split(
",")[1]
1577 fileConditionsOption=fileOptionValue.split(
"::")[0]
1589 subprocess.Popen(
"ls -R | grep .root > rootFiles",shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read()
1590 LogFile =
"%s_%s_%s_%s_%s_%s_%s_%s_log.tgz" % (self.
cmssw_arch, self.
cmssw_version, fileStepOption, fileConditionsOption, fileEventContentOption.split()[0], fileWorkingDir, self.
host, self.
user)
1591 AbsTarFileLOG = os.path.join(perfsuitedir,LogFile)
1592 tarcmd =
"tar zcfX %s %s %s" %(AbsTarFileLOG,
"rootFiles", os.path.join(perfsuitedir,
"*"))
1593 self.
printFlush(
"Creating a tarball for the logfiles")
1595 self.
printFlush(subprocess.Popen(tarcmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read())
1596 self.
printFlush(subprocess.Popen(
"rm rootFiles",shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read())
1598 fullcastorpathlog=os.path.join(castordir,LogFile)
1602 TarFile =
"%s_%s_%s_%s_%s_%s_%s_%s.tgz" % (self.
cmssw_arch, self.
cmssw_version, fileStepOption, fileConditionsOption, fileEventContentOption.split()[0], fileWorkingDir, self.
host, self.
user)
1603 AbsTarFile = os.path.join(perfsuitedir,TarFile)
1604 tarcmd =
"tar -zcf %s %s" %(AbsTarFile, os.path.join(perfsuitedir,
"*"))
1605 md5cmd =
"md5sum %s" %(AbsTarFile)
1606 self.
printFlush(
"Creating a tarball with the content of the directory")
1614 self.
printFlush(subprocess.Popen(tarcmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read())
1615 md5sum = subprocess.Popen(md5cmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.read().
split()[0]
1616 self.
printFlush(
"The md5 checksum of the tarball: %s" %(md5sum))
1617 AbsTarFileMD5 = AbsTarFile +
".md5" 1618 md5filecmd =
"echo %s > %s" % (md5sum, AbsTarFileMD5)
1619 self.
printFlush(subprocess.Popen(md5filecmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read())
1623 fullcastorpathfile=os.path.join(castordir,TarFile)
1624 fullcastorpathmd5=os.path.join(castordir,TarFile +
".md5")
1626 checkcastor=
"nsls %s" % fullcastorpathfile
1629 checkcastorout=subprocess.Popen(checkcastor,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.read()
1630 if checkcastorout.rstrip()==fullcastorpathfile:
1631 castorcmdstderr=
"File %s is already on CASTOR! Will NOT OVERWRITE!!!"%fullcastorpathfile
1636 castorcmd=
"rfcp %s %s" % (AbsTarFile,fullcastorpathfile)
1637 castormd5cmd=
"rfcp %s %s" % (AbsTarFileMD5,fullcastorpathmd5)
1638 castorlogcmd=
"rfcp %s %s" % (AbsTarFileLOG,fullcastorpathlog)
1644 castorcmdstderr=subprocess.Popen(castorcmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read()
1645 subprocess.Popen(castormd5cmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read()
1646 subprocess.Popen(castorlogcmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read()
1651 self.
printFlush(
"Since the CASTOR archiving for the tarball failed the file %s is kept in directory %s"%(TarFile, perfsuitedir))
1654 self.
printFlush(
"Successfully archived the tarball %s in CASTOR!"%(TarFile))
1655 self.
printFlush(
"The tarball can be found: %s"%(fullcastorpathfile))
1656 self.
printFlush(
"The logfile can be found: %s"%(fullcastorpathlog))
1657 self.
printFlush(
"Deleting the local copy of the tarballs")
1658 rmtarballcmd=
"rm -Rf %s"%(AbsTarFile)
1659 rmtarballmd5cmd=
"rm -Rf %s"%(AbsTarFileMD5)
1660 rmtarballlogcmd=
"rm -Rf %s"%(AbsTarFileLOG)
1666 self.
printFlush(subprocess.Popen(rmtarballcmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.read() )
1667 self.
printFlush(subprocess.Popen(rmtarballmd5cmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.read() )
1668 self.
printFlush(subprocess.Popen(rmtarballlogcmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.read() )
1669 tarballTime.set_end(datetime.datetime.now())
1671 self.
printFlush(
"Performance Suite directory will not be archived in a tarball since --no_tarball option was chosen")
1676 date=time.ctime(time.time())
1677 self.logh.write(
"Performance Suite finished running at %s on %s in directory %s\n" % (date,self.
host,path))
1679 self.logh.write(
"There were no errors detected in any of the log files!\n")
1681 self.logh.write(
"ERROR: There were %s errors detected in the log files, please revise!\n" % self.
ERRORS)
1684 except exceptions.Exception
as detail:
1685 self.logh.write(
str(detail) +
"\n")
1687 if not self.logh.isatty():
1691 if MailLogRecipients !=
"":
1692 self.
printFlush(
"Sending email notification for this execution of the performance suite with command:")
1693 sendLogByMailcmd=
'cat cmsPerfSuite.log |mail -s "Performance Suite finished running on %s" '%self.
host + MailLogRecipients
1697 self.
printFlush(subprocess.Popen(sendLogByMailcmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.read() )
1699 self.
printFlush(
'No email notification will be sent for this execution of the performance suite since option --mail "" was used')
1701 TotalTime.set_end(datetime.datetime.now())
1702 self.
printFlush(
"Total Running Time\t%s hrs (%s mins)"%(TotalTime.get_duration()[
'hours'],TotalTime.get_duration()[
'minutes']))
1708 PerfSuiteTimerInfo=open(
"PerfSuiteTimerInfo.pkl",
"wb")
1712 self.logh.write(
"Test type\tActual Test\tDuration\tStart Time\tEnd Time\n")
1713 for key
in TimerInfo.keys():
1715 TimerInfoStr.update({key:{}})
1716 for test
in TimerInfo[key].
keys():
1717 TimerInfoStr[key].
update({test:[
str(TimerInfo[key][test].get_duration()[
'hours'])+
" hrs ("+
str(TimerInfo[key][test].get_duration()[
'minutes'])+
" mins)",TimerInfo[key][test].get_start(),TimerInfo[key][test].get_end()]})
1718 self.logh.write(key+
"\t"+test+
"\t")
1719 self.logh.write(
"%s hrs (%s mins)\t"%(TimerInfo[key][test].get_duration()[
'hours'],TimerInfo[key][test].get_duration()[
'minutes']))
1720 self.logh.write(
"%s\t"%TimerInfo[key][test].get_start())
1721 self.logh.write(
"%s\n"%TimerInfo[key][test].get_end())
1722 pickle.dump(TimerInfoStr,PerfSuiteTimerInfo)
1723 PerfSuiteTimerInfo.close()
1725 self.logh.write(
"Final Performance Suite exit code was %s"%FinalExitCode)
1727 sys.exit(FinalExitCode)
1745 (PerfSuiteArgs[
'create'],
1746 PerfSuiteArgs[
'castordir'],
1747 PerfSuiteArgs[
'TimeSizeEvents'],
1748 PerfSuiteArgs[
'IgProfEvents'],
1749 PerfSuiteArgs[
'CallgrindEvents'],
1750 PerfSuiteArgs[
'MemcheckEvents'],
1751 PerfSuiteArgs[
'cmsScimark'],
1752 PerfSuiteArgs[
'cmsScimarkLarge'],
1753 PerfSuiteArgs[
'cmsdriverOptions'],
1754 PerfSuiteArgs[
'cmsdriverPUOptions'],
1755 PerfSuiteArgs[
'stepOptions'],
1756 PerfSuiteArgs[
'quicktest'],
1757 PerfSuiteArgs[
'profilers'],
1758 PerfSuiteArgs[
'cpus'],
1759 PerfSuiteArgs[
'cores'],
1760 PerfSuiteArgs[
'prevrel'],
1761 PerfSuiteArgs[
'bypasshlt'],
1762 PerfSuiteArgs[
'runonspare'],
1763 PerfSuiteArgs[
'perfsuitedir'],
1764 PerfSuiteArgs[
'logfile'],
1765 PerfSuiteArgs[
'TimeSizeCandles'],
1766 PerfSuiteArgs[
'IgProfCandles'],
1767 PerfSuiteArgs[
'CallgrindCandles'],
1768 PerfSuiteArgs[
'MemcheckCandles'],
1769 PerfSuiteArgs[
'TimeSizePUCandles'],
1770 PerfSuiteArgs[
'IgProfPUCandles'],
1771 PerfSuiteArgs[
'CallgrindPUCandles'],
1772 PerfSuiteArgs[
'MemcheckPUCandles'],
1773 PerfSuiteArgs[
'PUInputFile'],
1774 PerfSuiteArgs[
'userInputFile'],
1775 PerfSuiteArgs[
'MailLogRecipients'],
1776 PerfSuiteArgs[
'tarball']
1777 ) = suite.optionParse(argv)
1779 if PerfSuiteArgs[
'create']:
1780 suite.createIgVolume()
1782 if not PerfSuiteArgs[
'logfile'] ==
None:
1783 if os.path.exists(PerfSuiteArgs[
'logfile']):
1784 oldlogfile=PerfSuiteArgs[
'logfile']+
"_"+time.strftime(
"%d-%m-%Y_%H:%M:%S")
1786 mvOldLogfile=subprocess.Popen(
"mv %s %s"%(PerfSuiteArgs[
'logfile'],oldlogfile), shell=
True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
1787 mvOldLogfileExitCode=mvOldLogfile.wait()
1790 ActualLogfile = open(PerfSuiteArgs[
'logfile'],
"w")
1791 if mvOldLogfileExitCode:
1792 ActualLogfile.write(
"Please check what happened: A file named %s existed already and the attempt to move it to %s produced the following output: %s\n"%(PerfSuiteArgs[
'logfile'],oldlogfile,mvOldLogfile.stdout))
1794 ActualLogfile.write(
"***WARNING! A file named %s existed already!\n***It has been moved to %s before starting the current logfile!\n"%(PerfSuiteArgs[
'logfile'],oldlogfile))
1795 except (OSError, IOError)
as detail:
1796 ActualLogfile.write(
"Failed to open the intended logfile %s, detail error:\n%s"%(PerfSuiteArgs[
'logfile'],detail))
1800 ActualLogfile = open(PerfSuiteArgs[
'logfile'],
"w")
1801 except (OSError, IOError)
as detail:
1802 ActualLogfile.write(
"Failed to open the intended logfile %s, detail error:\n%s"%(PerfSuiteArgs[
'logfile'],detail))
1803 ActualLogfile.flush()
1806 ActualLogfile.write(
"Performance suite invoked with command line:\n")
1807 cmdline=reduce(
lambda x,y:x+
" "+y,sys.argv)
1808 ActualLogfile.write(cmdline+
"\n")
1809 ActualLogfile.flush()
1812 ActualLogfile.write(
"Initial PerfSuite Arguments:\n")
1813 for key
in PerfSuiteArgs.keys():
1814 ActualLogfile.write(
"%s %s\n"%(key,PerfSuiteArgs[key]))
1815 ActualLogfile.flush()
1818 PerfSuiteArgs[
'cpu_list'] = PerfSuiteArgs[
'cpus']
1821 if len(PerfSuiteArgs[
'cpus']) > 1:
1822 ActualLogfile.write(
"More than 1 cpu: threading the Performance Suite!\n")
1823 outputdir=PerfSuiteArgs[
'perfsuitedir']
1824 runonspare=PerfSuiteArgs[
'runonspare']
1825 cpus=PerfSuiteArgs[
'cpus']
1826 cores=PerfSuiteArgs[
'cores']
1828 for core
in range(PerfSuiteArgs[
'cores']):
1829 cmsScimarkLaunch_pslist={}
1830 if len(cpus) != cores:
1831 if (core
not in cpus):
1833 ActualLogfile.write(
"Submitting cmsScimarkLaunch.csh to run on core cpu "+
str(core)+
"\n")
1834 subcmd =
"cd %s ; cmsScimarkLaunch.csh %s" % (outputdir,
str(core))
1835 command=
"taskset -c %s sh -c \"%s\" &" % (
str(core), subcmd)
1837 ActualLogfile.write(command+
"\n")
1840 cmsScimarkLaunch_pslist[core]=subprocess.Popen(command,shell=
True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
1841 ActualLogfile.write(
"Spawned %s \n with PID %s"%(command,cmsScimarkLaunch_pslist[core].pid))
1842 ActualLogfile.flush()
1843 PerfSuiteArgs[
'runonspare']=
False 1844 logfile=PerfSuiteArgs[
'logfile']
1852 cpudir = os.path.join(outputdir,
"cpu_%s" % cpu)
1853 if not os.path.exists(cpudir):
1855 PerfSuiteArgs[
'perfsuitedir']=cpudir
1856 PerfSuiteArgs[
'cpus']=[cpu]
1857 if PerfSuiteArgs[
'logfile']:
1858 PerfSuiteArgs[
'logfile']=os.path.join(cpudir,os.path.basename(PerfSuiteArgs[
'logfile']))
1860 PerfSuiteArgs[
'logfile']=os.path.join(cpudir,
"cmsPerfSuiteThread.log")
1862 suitethread[cpu]=PerfThread(**PerfSuiteArgs)
1864 ActualLogfile.write(
"Launching PerfSuite thread on cpu%s"%cpu)
1865 ActualLogfile.flush()
1868 suitethread[cpu].
start()
1870 while reduce(
lambda x,y: x
or y,
map(
lambda x: x.isAlive(),suitethread.values())):
1874 except (KeyboardInterrupt, SystemExit):
1876 ActualLogfile.write(
"All PerfSuite threads have completed!\n")
1877 ActualLogfile.flush()
1880 suite.runPerfSuite(**PerfSuiteArgs)
1882 if __name__ ==
"__main__":
def runCmdSet(self, cmd)
Run a list of commands using system ! We should rewrite this not to use system (most cases it is unne...
def getVerFromLog(previous)
def benchmarks(self, cpu, pfdir, name, bencher, large=False)
Run cmsScimark benchmarks a number of times.
def runCmsInput(self, cpu, dir, numevents, candle, cmsdrvopts, stepopt, profiles, bypasshlt, userInputFile)
Wrapper for cmsRelvalreportInput.
def runCmsReport(self, cpu, dir, candle)
This function is a wrapper around cmsRelvalreport.
def valFilterReport(self, dir)
Filter lines in the valgrind report that match GEN,SIM.
def displayErrors(self, file)
Display G4 cerr errors and CMSExceptions in the logfile.
def set_end(self, end=None)
def printFlush(self, command)
Print and flush a string (for output to a log file)
_verbose
Check logfile option.
def testCmsDriver(self, cpu, dir, cmsver, candle)
Test cmsDriver.py (parses the simcandles file, removing duplicate lines, and runs the cmsDriver part)...
def runcmd(self, command)
Run a command and return the exit status.
PerfTestTotalTimer
FIXME: We may want to introduce a switch here or agree on a different default (currently 10 cmsScimar...
def runPerfSuite(self, create=False, castordir="/castor/cern.ch/cms/store/relval/performance/", TimeSizeEvents=100, IgProfEvents=5, CallgrindEvents=1, MemcheckEvents=5, cmsScimark=10, cmsScimarkLarge=10, cmsdriverOptions="", cmsdriverPUOptions="", stepOptions="", quicktest=False, profilers="", cpus=[1], cpu_list=[1], cores=4, prevrel="", bypasshlt=False, runonspare=True, perfsuitedir=os.getcwd(), logfile=None, TimeSizeCandles="", IgProfCandles="", CallgrindCandles="", MemcheckCandles="", TimeSizePUCandles="", IgProfPUCandles="", CallgrindPUCandles="", MemcheckPUCandles="", PUInputFile="", userInputFile="", MailLogRecipients="", tarball="")
Runs benchmarking, cpu spinlocks on spare cores and profiles selected candles.
def simpleGenReport(self, cpus, perfdir=os.getcwd(), NumEvents=1, candles=['MinBias'], cmsdriverOptions='', stepOptions='', Name='', profilers='', bypasshlt='', userInputRootFiles='')
Prepares the profiling directory and runs all the selected profiles (if this is not a unit test) ...
def __init__(self, cpu, perfsuiteinstance, simpleGenReportArgs)
def optionParse(self, argslist=None)
def set_start(self, start=None)
static std::string join(char **cmd)
def __init__(self, cpu, perfsuiteinstance, simpleGenReportArgs)
def __init__(self, start=None)
def main(argv=[__name__])
def mkCandleDir(self, pfdir, candle, profiler)
Make directory for a particular candle and profiler.
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger list("!*","!HLTx*"if it matches 2 triggers or more) will accept the event if all the matching triggers are FAIL.It will reject the event if any of the triggers are PASS or EXCEPTION(this matches the behavior of"!*"before the partial wildcard feature was incorporated).Triggers which are in the READY state are completely ignored.(READY should never be returned since the trigger paths have been run
def cprootfile(self, dir, candle, NumOfEvents, cmsdriverOptions="")
Copy root file from another candle's directory ! Again this is messy.