2 from builtins
import range
3 import os, time, sys, re, glob, exceptions
5 import cmsRelRegress
as crr
6 from cmsPerfCommons
import Candles, KeywordToCfi, CandFname, cmsDriverPileUpOption, getVerFromLog
7 import cmsRelValCmd,cmsCpuInfo
12 from functools
import reduce
20 subprocess._cleanup=_cleanup
25 threading.Thread.__init__(self)
31 self.suite.runPerfSuite(**(self.
args))
34 """A class defining timing objects to time the running of the various parts of the performance suite. The class depends on module datetime.""" 36 """Initialize the start time and set the end time to some indefinite time in the future""" 38 self.
end = datetime.datetime.max
50 """Return the start time in ctime timestamp format""" 51 return self.start.ctime()
53 """Return the end time in ctime timestamp format""" 54 return self.end.ctime()
56 """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.""" 69 self.
_CASTOR_DIR =
"/castor/cern.ch/cms/store/relval/performance/" 81 self.
host = os.environ[
"HOST"]
82 self.
user = os.environ[
"USER"]
84 self.logh.write(
'Error: An environment variable either SCRAM_ARCH, CMSSW_VERSION, HOST or USER is not available.\n')
85 self.logh.write(
' Please run eval `scramv1 runtime -csh` to set your environment variables\n')
90 self.
Scripts =[
"cmsDriver.py",
"cmsRelvalreport.py",
"cmsRelvalreportInput.py",
"cmsScimark2"]
91 self.
AuxiliaryScripts=[
"cmsScimarkLaunch.csh",
"cmsScimarkParser.py",
"cmsScimarkStop.py"]
112 igcommand =
'/afs/cern.ch/cms/sdt/internal/scripts/requestPerfIgprofSpace.py --version ' + self.
cmssw_version +
' --platform ' + self.
cmssw_arch 113 subprocess.Popen(igcommand,shell=
True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
117 def __init__(self,cpu,perfsuiteinstance,**simpleGenReportArgs):
121 threading.Thread.__init__(self)
124 self.PerfTest.runPerfTest()
127 def __init__(self,cpu,perfsuiteinstance,**simpleGenReportArgs):
143 self.perfsuiteinstance.logh.flush()
145 self.perfsuiteinstance.printDate()
146 self.perfsuiteinstance.logh.flush()
150 self.PerfTestPUTimer.set_end(datetime.datetime.now())
152 self.PerfTestTimer.set_end(datetime.datetime.now())
157 parser = opt.OptionParser(usage=
'''./cmsPerfSuite.py [options] 161 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" 162 (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) 164 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 165 (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) 167 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" 168 (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) 170 Legal entries for individual candles (--RunTimeSize, --RunIgProf, --RunCallgrind, --RunMemcheck options): 172 ''' % (
"\n".
join(Candles)))
174 parser.set_defaults(TimeSizeEvents = 0 ,
176 CallgrindEvents = 0 ,
179 cmsScimarkLarge = 10 ,
180 cmsdriverOptions =
"--eventcontent FEVTDEBUGHLT",
185 logfile = os.path.join(os.getcwd(),
"cmsPerfSuite.log"),
205 RunCallgrindPU =
"" ,
209 parser.add_option(
'--createIgVol', action=
"store_true", dest=
'create',
210 help =
'Create IgProf AFS volume for the release and architecture')
211 parser.add_option(
'-q',
'--quiet' , action=
"store_false", dest=
'verbose' ,
212 help =
'Output less information' )
213 parser.add_option(
'-b',
'--bypass-hlt' , action=
"store_true" , dest=
'bypasshlt' ,
214 help =
'Bypass HLT root file as input to RAW2DIGI')
215 parser.add_option(
'-n',
'--notrunspare', action=
"store_false", dest=
'runonspare',
216 help =
'Do not run cmsScimark on spare cores')
217 parser.add_option(
'-t',
'--timesize' , type=
'int' , dest=
'TimeSizeEvents' , metavar=
'<#EVENTS>' ,
218 help =
'specify the number of events for the TimeSize tests' )
219 parser.add_option(
'-i',
'--igprof' , type=
'int' , dest=
'IgProfEvents' , metavar=
'<#EVENTS>' ,
220 help =
'specify the number of events for the IgProf tests' )
221 parser.add_option(
'-c',
'--callgrind' , type=
'int' , dest=
'CallgrindEvents' , metavar=
'<#EVENTS>' ,
222 help =
'specify the number of events for the Callgrind tests' )
223 parser.add_option(
'-m',
'--memcheck' , type=
'int' , dest=
'MemcheckEvents' , metavar=
'<#EVENTS>' ,
224 help =
'specify the number of events for the Memcheck tests' )
225 parser.add_option(
'--cmsScimark' , type=
'int' , dest=
'cmsScimark' , metavar=
'' ,
226 help =
'specify the number of times the cmsScimark benchmark is run before and after the performance suite on cpu1')
227 parser.add_option(
'--cmsScimarkLarge' , type=
'int' , dest=
'cmsScimarkLarge' , metavar=
'' ,
228 help =
'specify the number of times the cmsScimarkLarge benchmark is run before and after the performance suite on cpu1')
229 parser.add_option(
'--cores' , type=
'int', dest=
'cores' , metavar=
'<CORES>' ,
230 help =
'specify the number of cores of the machine (can be used with 0 to stop cmsScimark from running on the other cores)')
231 parser.add_option(
'--cmsdriver' , type=
'string', dest=
'cmsdriverOptions', metavar=
'<OPTION_STR>',
232 help =
'specify special options to use with the cmsDriver.py commands (designed for integration build use')
233 parser.add_option(
'-a',
'--archive' , type=
'string', dest=
'castordir' , metavar=
'<DIR>' ,
234 help =
'specify the wanted CASTOR directory where to store the results tarball')
235 parser.add_option(
'-L',
'--logfile' , type=
'string', dest=
'logfile' , metavar=
'<FILE>' ,
236 help =
'file to store log output of the script')
237 parser.add_option(
'-o',
'--output' , type=
'string', dest=
'outputdir' , metavar=
'<DIR>' ,
238 help =
'specify the directory where to store the output of the script')
239 parser.add_option(
'-r',
'--prevrel' , type=
'string', dest=
'previousrel' , metavar=
'<DIR>' ,
240 help =
'Top level dir of previous release for regression analysis')
241 parser.add_option(
'--step' , type=
'string', dest=
'stepOptions' , metavar=
'<STEPS>' ,
242 help =
'specify the processing steps intended (instead of the default ones)' )
243 parser.add_option(
'--cpu' , type=
'string', dest=
'cpu' , metavar=
'<CPU>' ,
244 help =
'specify the core on which to run the performance suite')
247 parser.add_option(
'--RunTimeSize' , type=
'string', dest=
'RunTimeSize' , metavar=
'<CANDLES>' ,
248 help =
'specify on which candles to run the TimeSize tests')
249 parser.add_option(
'--RunIgProf' , type=
'string', dest=
'RunIgProf' , metavar=
'<CANDLES>' ,
250 help =
'specify on which candles to run the IgProf tests')
251 parser.add_option(
'--RunCallgrind' , type=
'string', dest=
'RunCallgrind' , metavar=
'<CANDLES>' ,
252 help =
'specify on which candles to run the Callgrind tests')
253 parser.add_option(
'--RunMemcheck' , type=
'string', dest=
'RunMemcheck' , metavar=
'<CANDLES>' ,
254 help =
'specify on which candles to run the Memcheck tests')
255 parser.add_option(
'--RunDigiPileUp' , type=
'string', dest=
'RunDigiPileUp' , metavar=
'<CANDLES>' ,
256 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')
257 parser.add_option(
'--PUInputFile' , type=
'string', dest=
'PUInputFile' , metavar=
'<FILE>' ,
258 help =
'specify the root file to pick the pile-up events from')
259 parser.add_option(
'--RunTimeSizePU' , type=
'string', dest=
'RunTimeSizePU' , metavar=
'<CANDLES>' ,
260 help =
'specify on which candles to run the TimeSize tests with PILE UP')
261 parser.add_option(
'--RunIgProfPU' , type=
'string', dest=
'RunIgProfPU' , metavar=
'<CANDLES>' ,
262 help =
'specify on which candles to run the IgProf tests with PILE UP')
263 parser.add_option(
'--RunCallgrindPU' , type=
'string', dest=
'RunCallgrindPU' , metavar=
'<CANDLES>' ,
264 help =
'specify on which candles to run the Callgrind tests with PILE UP')
265 parser.add_option(
'--RunMemcheckPU' , type=
'string', dest=
'RunMemcheckPU' , metavar=
'<CANDLES>' ,
266 help =
'specify on which candles to run the Memcheck tests with PILE UP')
269 parser.add_option(
'--filein' , type=
'string', dest=
'userInputFile' , metavar=
'<FILE>',
270 help =
'specify input RAW root file for HLT and RAW2DIGI-RECO (list the files in the same order as the candles for the tests)')
273 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')
276 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')
283 devel = opt.OptionGroup(parser,
"Developer Options",
284 "Caution: use these options at your own risk." 285 "It is believed that some of them bite.\n")
287 devel.add_option(
'-p',
'--profile' , type=
"str" , dest=
'profilers', metavar=
"<PROFILERS>" ,
288 help =
'Profile codes to use for cmsRelvalInput' )
289 devel.add_option(
'-f',
'--false-run', action=
"store_true", dest=
'dryrun' ,
291 devel.add_option(
'-d',
'--debug' , action=
'store_true', dest=
'debug' ,
293 devel.add_option(
'--quicktest' , action=
"store_true", dest=
'quicktest',
294 help =
'Quick overwrite all the defaults to small numbers so that we can run a quick test of our chosing.' )
295 devel.add_option(
'--test' , action=
"store_true", dest=
'unittest' ,
296 help =
'Perform a simple test, overrides other options. Overrides verbosity and sets it to false.' )
297 devel.add_option(
'--no_exec' , action=
"store_true", dest=
'noexec' ,
298 help =
'Run the suite without executing the cmsRelvalreport.py commands in the various directories. This is a useful debugging tool.' )
299 parser.add_option_group(devel)
300 (options, args) = parser.parse_args(argslist)
303 self.
_debug = options.debug
308 create = options.create
309 castordir = options.castordir
310 TimeSizeEvents = options.TimeSizeEvents
311 IgProfEvents = options.IgProfEvents
312 CallgrindEvents = options.CallgrindEvents
313 MemcheckEvents = options.MemcheckEvents
314 cmsScimark = options.cmsScimark
315 cmsScimarkLarge = options.cmsScimarkLarge
316 cmsdriverOptions = options.cmsdriverOptions
317 stepOptions = options.stepOptions
318 quicktest = options.quicktest
320 runonspare = options.runonspare
321 profilers = options.profilers.strip()
322 cpu = options.cpu.strip()
323 bypasshlt = options.bypasshlt
324 cores = options.cores
325 logfile = options.logfile
326 prevrel = options.previousrel
327 outputdir = options.outputdir
328 RunTimeSize = options.RunTimeSize
329 RunIgProf = options.RunIgProf
330 RunCallgrind = options.RunCallgrind
331 RunMemcheck = options.RunMemcheck
332 RunDigiPileUp = options.RunDigiPileUp
333 RunTimeSizePU = options.RunTimeSizePU
334 RunIgProfPU = options.RunIgProfPU
335 RunCallgrindPU = options.RunCallgrindPU
336 RunMemcheckPU = options.RunMemcheckPU
337 PUInputFile = options.PUInputFile
338 userInputFile = options.userInputFile
339 if options.MailLogRecipients !=
"" and self.
user not in options.MailLogRecipients:
340 MailLogRecipients= self.
user+
","+options.MailLogRecipients
342 MailLogRecipients=options.MailLogRecipients
343 tarball = options.tarball
348 if not logfile ==
None:
349 logfile = os.path.abspath(logfile)
350 logdir = os.path.dirname(logfile)
351 if not os.path.exists(logdir):
352 parser.error(
"Directory to output logfile does not exist")
354 logfile = os.path.abspath(logfile)
359 if "GEN,SIM" in stepOptions:
360 self.logh.write(
"WARNING: Please use GEN-SIM with a hypen not a \",\"!\n")
363 if stepOptions ==
"" or stepOptions ==
'Default':
366 stepOptions=
'--usersteps=%s' % (stepOptions)
371 isnumreg = re.compile(
"^-?[0-9]*$")
372 found = isnumreg.search(profilers)
374 parser.error(
"profile codes option contains non-numbers")
381 outputdir = os.getcwd()
383 outputdir = os.path.abspath(outputdir)
385 if not os.path.isdir(outputdir):
386 parser.error(
"%s is not a valid output directory" % outputdir)
392 numetcomreg = re.compile(
"^[0-9,]*")
393 if not numetcomreg.search(cpu):
394 parser.error(
"cpu option needs to be a comma separted list of ints or a single int")
400 cpu =
map(
lambda x:
int(x),cpustr.split(
","))
402 cpu = [
int(cpustr) ]
407 if not prevrel ==
"":
408 prevrel = os.path.abspath(prevrel)
409 if not os.path.exists(prevrel):
410 self.logh.write(
"ERROR: Previous release dir %s could not be found" % prevrel)
429 if stepOptions ==
"":
430 stepOptions =
"GEN-SIM,DIGI,L1,DIGI2RAW,HLT,RAW2DIGI-RECO" 445 CallgrindPUCandles=[]
447 userInputRootFiles=[]
449 TimeSizeCandles = RunTimeSize.split(
",")
451 IgProfCandles = RunIgProf.split(
",")
453 CallgrindCandles = RunCallgrind.split(
",")
455 MemcheckCandles = RunMemcheck.split(
",")
457 for candle
in RunDigiPileUp.split(
","):
458 if candle
in TimeSizeCandles:
459 TimeSizePUCandles.append(candle)
460 if candle
in IgProfCandles:
461 IgProfPUCandles.append(candle)
462 if candle
in CallgrindCandles:
463 CallgrindPUCandles.append(candle)
464 if candle
in MemcheckCandles:
465 MemcheckPUCandles.append(candle)
467 TimeSizePUCandles.extend(RunTimeSizePU.split(
","))
469 temp=set(TimeSizePUCandles)
470 TimeSizePUCandles=
list(temp)
472 IgProfPUCandles.extend(RunIgProfPU.split(
","))
474 temp=set(IgProfPUCandles)
475 IgProfPUCandles=
list(temp)
477 CallgrindPUCandles.extend(RunCallgrindPU.split(
","))
479 temp=set(CallgrindPUCandles)
480 CallgrindPUCandles=
list(temp)
482 MemcheckPUCandles.extend(RunMemcheckPU.split(
","))
484 temp=set(MemcheckPUCandles)
485 MemcheckPUCandles=
list(temp)
487 userInputRootFiles=userInputFile.split(
",")
494 cmsdriverPUOptions=
"" 497 if TimeSizePUCandles
or IgProfPUCandles
or CallgrindPUCandles
or MemcheckPUCandles:
499 cmsdriverPUOptions =
'--cmsdriver="%s %s%s"'%(cmsdriverOptions,
" --pileup=",cmsDriverPileUpOption)
501 cmsdriverOptions =
'--cmsdriver="%s"'%cmsdriverOptions
545 exitstat = self.
runcmd(cmd)
562 self.logh.write(
str(command) +
"\n")
575 process = subprocess.Popen(command,shell=
True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
577 exitstat= process.wait()
578 cmdout = process.stdout.read()
579 exitstat = process.returncode
580 except OSError
as detail:
581 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))
584 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)
586 self.logh.write(cmdout)
589 self.logh.write(
"Something strange is going on! Exit code was None for command %s: check if it really ran!"%command)
598 self.logh.write(self.
getDate() +
"\n")
604 adir = os.path.join(pfdir,
"%s_%s" % (candle,profiler))
605 self.
runcmd(
"mkdir -p %s" % adir )
614 def cprootfile(self,dir,candle,NumOfEvents,cmsdriverOptions=""):
615 cmds = (
"cd %s" % dir,
616 "cp -pR ../%s_IgProf/%s_GEN,SIM.root ." % (candle,CandFname[candle]))
619 self.logh.write(
"Since there was no ../%s_IgProf/%s_GEN,SIM.root file it will be generated first\n"%(candle,CandFname[candle]))
621 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)
626 cmdout=subprocess.Popen(cmd,shell=
True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT).stdout.read()
636 for line
in open(file,
"r"): 637 if "cerr" in line
or "CMSException" in line:
638 self.logh.write(
"ERROR: %s\n" % line)
640 except OSError
as detail:
641 self.logh.write(
"WARNING: %s\n" % detail)
643 except IOError
as detail:
644 self.logh.write(
"WARNING: %s\n" % detail)
656 InputFileName=os.path.join(dir,
"SimulationCandles_%s.txt"%(self.
cmssw_version))
657 InputFile=open(InputFileName,
"r") 658 InputLines=InputFile.readlines() 660 Outputfile=open(InputFileName,"w")
661 simRegxp=re.compile(
"step=GEN,SIM")
662 digiRegxp=re.compile(
"step=DIGI")
663 CallgrindRegxp=re.compile(
"ValgrindFCE")
664 MemcheckRegxp=re.compile(
"Memcheck")
665 NumEvtRegxp=re.compile(
"-n 1")
666 for line
in InputLines:
667 if simRegxp.search(line)
and CallgrindRegxp.search(line):
669 elif simRegxp.search(line)
and MemcheckRegxp.search(line):
671 if NumEvtRegxp.search(line):
672 line=NumEvtRegxp.sub(
r"-n 5",line)
674 self.logh.write(
"The number of Memcheck event was not changed since the original number of Callgrind event was not 1!\n")
675 Outputfile.write(line)
676 elif digiRegxp.search(line)
and MemcheckRegxp.search(line):
678 if NumEvtRegxp.search(line):
679 line=NumEvtRegxp.sub(
r"-n 5",line)
681 self.logh.write(
"The number of Memcheck event was not changed since the original number of Callgrind event was not 1!\n")
682 Outputfile.write(line)
684 Outputfile.write(line)
697 redirect =
" -large >>" 701 for i
in range(bencher):
703 if not os.path.exists(os.path.join(pfdir,os.path.basename(name))):
705 open(os.path.join(pfdir,os.path.basename(name)))
707 command= cmd + redirect + os.path.join(pfdir,os.path.basename(name))
708 self.
printFlush(command +
" [%s/%s]" % (i+1,bencher))
717 cmds = (
"cd %s" % (dir),
718 "%s -i SimulationCandles_%s.txt -t perfreport_tmp -R -P >& %s.log" % (cmd,self.
cmssw_version,candle))
723 if self.
_unittest and (
not exitstat == 0):
724 self.logh.write(
"ERROR: CMS Report returned a non-zero exit status \n")
733 cmsdrvreg = re.compile(
"^cmsDriver.py")
736 stepreg = re.compile(
"--step=([^ ]*)")
737 previousCmdOnline =
"" 738 for line
in open(os.path.join(dir,
"SimulationCandles_%s.txt" % (cmsver))):
739 if (
not line.lstrip().startswith(
"#"))
and not (line.isspace()
or len(line) == 0):
740 cmdonline = line.split(
"@@@",1)[0]
741 if cmsdrvreg.search(cmdonline)
and not previousCmdOnline == cmdonline:
742 stepbeingrun =
"Unknown" 743 matches = stepreg.search(cmdonline)
744 if not matches ==
None:
745 stepbeingrun = matches.groups()[0]
746 if "PILEUP" in cmdonline:
747 stepbeingrun +=
"_PILEUP" 748 self.logh.write(cmdonline +
"\n")
749 cmds = (
"cd %s" % (dir),
750 "%s >& ../cmsdriver_unit_test_%s_%s.log" % (cmdonline,candle,stepbeingrun))
752 self.logh.write(cmds +
"\n")
757 xstatus = out & 0xffff
758 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))
760 previousCmdOnline = cmdonline
765 def runCmsInput(self,cpu,dir,numevents,candle,cmsdrvopts,stepopt,profiles,bypasshlt,userInputFile):
770 bypass =
"--bypass-hlt" 771 userInputFileOption=
"" 773 userInputFileOption =
"--filein %s"%userInputFile
777 cmds = (
"cd %s" % (dir),
778 "%s %s \"%s\" %s %s %s %s %s" % (cmd,
784 bypass,userInputFileOption))
787 if self.
_unittest and (
not exitstat == 0):
788 self.logh.write(
"ERROR: CMS Report Input returned a non-zero exit status \n" )
794 def simpleGenReport(self,cpus,perfdir=os.getcwd(),NumEvents=1,candles=[
'MinBias'],cmsdriverOptions=
'',stepOptions=
'',Name=
'',profilers=
'',bypasshlt=
'',userInputRootFiles=
''):
795 callgrind = Name ==
"Callgrind" 796 memcheck = Name ==
"Memcheck" 798 profCodes = {
"TimeSize" :
"0123",
806 profiles = profCodes[Name]
807 if not profilers ==
"":
810 RelvalreportExitCode=0
815 pfdir = os.path.join(perfdir,
"cpu_%s" % cpu)
816 for candle
in candles:
819 if "--pileup" in cmsdriverOptions:
820 candlename=candle+
"_PU" 826 if userInputRootFiles:
827 self.logh.write(userInputRootFiles)
828 userInputFile=userInputRootFiles[0]
832 self.
runCmsInput(cpu,adir,NumEvents,candle,cmsdriverOptions,stepOptions,profiles,bypasshlt,userInputFile)
835 if userInputRootFiles:
836 self.logh.write(
"Variable userInputRootFiles is %s\n"%userInputRootFiles)
844 candleregexp=re.compile(candle)
845 for file
in userInputRootFiles:
846 if candleregexp.search(file):
848 self.logh.write(
"For these %s %s tests will use user input file %s\n"%(candlename,Name,userInputFile))
849 if userInputFile ==
"":
850 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))
854 DummyTestName=candlename+
"_"+stepOptions.split(
"=")[1]
856 TimerInfo[Name].
update({DummyTestName:DummyTimer})
858 self.
runCmsInput(cpu,adir,NumEvents,candle,cmsdriverOptions,stepOptions,profiles,bypasshlt,userInputFile)
861 self.logh.write(
"Running in debugging mode, without executing cmsRelvalreport.py\n")
867 self.logh.write(
"Individual cmsRelvalreport.py ExitCode %s\n"%ExitCode)
868 RelvalreportExitCode=RelvalreportExitCode+ExitCode
869 self.logh.write(
"Summed cmsRelvalreport.py ExitCode %s\n"%RelvalreportExitCode)
871 DummyTimer.set_end(datetime.datetime.now())
876 globpath = os.path.join(adir,
"*.log")
877 self.logh.write(
"Looking for logs that match %s\n" % globpath)
878 logs = glob.glob(globpath)
880 self.logh.write(
"Found log %s\n" % log)
882 self.
printFlush(
"Returned cumulative RelvalreportExitCode is %s"%RelvalreportExitCode)
883 return RelvalreportExitCode
897 castordir =
"/castor/cern.ch/cms/store/relval/performance/",
898 TimeSizeEvents = 100 ,
900 CallgrindEvents = 1 ,
903 cmsScimarkLarge = 10 ,
904 cmsdriverOptions =
"" ,
905 cmsdriverPUOptions=
"" ,
915 perfsuitedir = os.getcwd(),
917 TimeSizeCandles =
"" ,
919 CallgrindCandles =
"" ,
920 MemcheckCandles =
"" ,
921 TimeSizePUCandles =
"" ,
922 IgProfPUCandles =
"" ,
923 CallgrindPUCandles =
"" ,
924 MemcheckPUCandles =
"" ,
927 MailLogRecipients =
"" ,
934 if not logfile ==
None:
936 self.
logh = open(logfile,
"a")
937 except (OSError, IOError)
as detail:
938 self.logh.write(detail +
"\n")
944 HEPSPEC06_file=open(
"/build/HEPSPEC06.score",
"r") 945 for line
in HEPSPEC06_file.readlines():
946 if not line.startswith(
"#")
and "HEPSPEC06" in line:
949 self.logh.write(
"***Warning***: Could not find file /build/HEPSPEC06.score file on this machine!\n")
953 localcpuinfo=os.path.join(perfsuitedir,
"cpuinfo")
955 if os.path.exists(localcpuinfo):
958 self.logh.write(
"Copying /proc/cpuinfo in current working directory (%s)\n"%perfsuitedir)
959 cpuinfo_exitcode=self.
runcmd(
"cp /proc/cpuinfo %s"%perfsuitedir)
960 localmeminfo=os.path.join(perfsuitedir,
"meminfo")
962 if os.path.exists(localmeminfo):
965 self.logh.write(
"Copying /proc/meminfo in current working directory (%s)\n"%perfsuitedir)
966 meminfo_exitcode=self.
runcmd(
"cp /proc/meminfo %s"%perfsuitedir)
967 if cpuinfo_exitcode
or meminfo_exitcode:
968 self.logh.write(
"There was an issue copying the cpuinfo or meminfo files!\n")
972 if not prevrel ==
"":
973 self.logh.write(
"Production of regression information has been requested with release directory %s\n" % prevrel)
974 if not cmsdriverOptions ==
"":
975 self.logh.write(
"Running cmsDriver.py with user defined options: %s\n" % cmsdriverOptions)
977 cmsdriverOptionsRelvalInput=
"--cmsdriver="+cmsdriverOptions
979 if not stepOptions ==
"":
980 self.logh.write(
"Running user defined steps only: %s\n" % stepOptions)
982 setpOptionsRelvalInput=
"--usersteps="+stepOptions
986 bypasshltRelvalInput=
"--bypass-hlt" 988 self.logh.write(
"Current Architecture is %s\n"%self.
cmssw_arch)
989 self.logh.write(
"Current CMSSW version is %s\n"%self.
cmssw_version)
990 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))
991 self.logh.write(
"This machine's HEPSPEC06 score is: %s \n"%self.
HEPSPEC06)
992 path=os.path.abspath(
".")
993 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))
998 TimerInfo={
'TotalTime':{
'TotalTime':TotalTime}}
1001 showtags=subprocess.Popen(
"showtags -r",shell=
True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT).stdout.read()
1002 self.logh.write(showtags)
1006 self.logh.write(
"The performance suite results tarball will be stored in CASTOR at %s\n" % self.
_CASTOR_DIR)
1007 self.logh.write(
"%s TimeSize events\n" % TimeSizeEvents)
1008 self.logh.write(
"%s IgProf events\n" % IgProfEvents)
1009 self.logh.write(
"%s Callgrind events\n" % CallgrindEvents)
1010 self.logh.write(
"%s Memcheck events\n" % MemcheckEvents)
1011 self.logh.write(
"%s cmsScimark benchmarks before starting the tests\n" % cmsScimark)
1012 self.logh.write(
"%s cmsScimarkLarge benchmarks before starting the tests\n" % cmsScimarkLarge)
1022 cpupath = os.path.join(perfsuitedir,
"cpu_%s" % cpu)
1023 if not os.path.exists(cpupath):
1033 self.logh.write(
"Full path of all the scripts used in this run of the Performance Suite:\n")
1034 for script
in AllScripts:
1035 which=
"which " + script
1040 whichstdout=subprocess.Popen(which,shell=
True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT).stdout.read()
1041 self.logh.write(whichstdout)
1044 command=
"taskset -c %s %s" % (cpu,script)
1051 if (len(cpu_list) != cores):
1052 for core
in range(cores):
1053 if (
not core
in cpus)
and runonspare:
1054 self.logh.write(
"Submitting cmsScimarkLaunch.csh to run on core cpu "+
str(core) +
"\n")
1055 subcmd =
"cd %s ; cmsScimarkLaunch.csh %s" % (perfsuitedir,
str(core))
1056 command=
"taskset -c %s sh -c \"%s\" &" % (
str(core), subcmd)
1057 self.logh.write(command +
"\n")
1063 subprocess.Popen(command,shell=
True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
1068 benching =
not self.
_debug 1074 scimark = open(os.path.join(perfsuitedir,
"cmsScimark2.log") ,
"w")
1075 scimarklarge = open(os.path.join(perfsuitedir,
"cmsScimark2_large.log"),
"w")
1077 self.logh.write(
"Starting with %s cmsScimark on cpu%s\n" % (cmsScimark,cpu))
1078 cmsScimarkInitialTime=
PerfSuiteTimer(start=datetime.datetime.now())
1079 TimerInfo.update({
'cmsScimarkTime':{
'cmsScimarkInitial':cmsScimarkInitialTime}})
1080 self.
benchmarks(cpu,perfsuitedir,scimark.name,cmsScimark)
1081 cmsScimarkInitialTime.set_end(datetime.datetime.now())
1083 if cmsScimarkLarge > 0:
1084 self.logh.write(
"Following with %s cmsScimarkLarge on cpu%s\n" % (cmsScimarkLarge,cpu))
1085 cmsScimarkLargeInitialTime=
PerfSuiteTimer(start=datetime.datetime.now())
1086 TimerInfo[
'cmsScimarkTime'].
update({
'cmsScimarkLargeInitial':cmsScimarkLargeInitialTime})
1087 self.
benchmarks(cpu,perfsuitedir,scimarklarge.name,cmsScimarkLarge, large=
True)
1088 cmsScimarkLargeInitialTime.set_end(datetime.datetime.now())
1091 if (TimeSizePUCandles
or IgProfPUCandles
or CallgrindPUCandles
or MemcheckPUCandles)
and not (
"FASTSIM" in stepOptions):
1093 PUInputName=os.path.join(perfsuitedir,
"INPUT_PILEUP_EVENTS.root")
1099 if '/store/relval/' in PUInputFile:
1104 if PUInputFile.startswith(
'/store/relval/'):
1107 PUInputFile=
"root://eoscms//eos/cms"+PUInputFile
1109 self.logh.write(
"Copying the file %s locally to %s\n"%(PUInputFile,PUInputName))
1111 GetPUInput=subprocess.Popen(
"%s %s %s"%(copycmd,PUInputFile,PUInputName), shell=
True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
1112 GetPUInputExitCode=GetPUInput.wait()
1114 if GetPUInputExitCode:
1115 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))
1117 if not os.path.exists(PUInputName):
1118 self.logh.write(
"The necessary INPUT_PILEUP_EVENTS.root file was not found in the working directory %s\nExiting now!"%perfsuitedir)
1123 self.
printFlush(
"Some PILE UP tests will be run!")
1125 self.
printFlush(
"cmsdriverPUOptions is %s"%cmsdriverPUOptions)
1129 if TimeSizeEvents > 0:
1131 TimerInfo.update({
'TimeSize':{
'TotalTime':TimeSizeTime}})
1133 self.logh.write(
"Launching the TimeSize tests (TimingReport, TimeReport, SimpleMemoryCheck, EdmSize) with %s events each\n" % TimeSizeEvents)
1135 TimerInfo[
'TimeSize'].
update({
'NoPileUpTime':NoPileUpTime})
1138 ReportExit=self.
simpleGenReport(cpus,perfsuitedir,TimeSizeEvents,TimeSizeCandles,cmsdriverOptions,stepOptions,
"TimeSize",profilers,bypasshlt,userInputFile)
1139 FinalExitCode=FinalExitCode+ReportExit
1142 NoPileUpTime.set_end(datetime.datetime.now())
1145 if TimeSizePUCandles:
1146 self.logh.write(
"Launching the PILE UP TimeSize tests (TimingReport, TimeReport, SimpleMemoryCheck, EdmSize) with %s events each\n" % TimeSizeEvents)
1148 TimerInfo[
'TimeSize'].
update({
'PileUpTime':PileUpTime})
1151 ReportExit=self.
simpleGenReport(cpus,perfsuitedir,TimeSizeEvents,TimeSizePUCandles,cmsdriverPUOptions,stepOptions,
"TimeSize",profilers,bypasshlt,userInputFile)
1152 FinalExitCode=FinalExitCode+ReportExit
1155 PileUpTime.set_end(datetime.datetime.now())
1158 if not (TimeSizeCandles
or TimeSizePUCandles):
1159 self.
printFlush(
"A number of events (%s) for TimeSize tests was selected, but no candle for regular or pileup tests was selected!"%(TimeSizeEvents))
1162 TimeSizeTime.set_end(datetime.datetime.now())
1167 self.logh.write(
"Stopping all cmsScimark jobs now\n")
1169 stopcmd =
"sh -c \"%s\"" % subcmd
1174 self.
printFlush(subprocess.Popen(stopcmd,shell=
True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT).stdout.read())
1180 elif len(cpu_list) == cores:
1184 AvailableCores=
list(range(cores))
1189 if IgProfEvents > 0:
1196 self.
printFlush(
"Special profiler option for IgProf was indicated by the user: %s"%profilers)
1198 IgProfProfilerArgs={
1199 'perfdir':perfsuitedir,
1200 'NumEvents':IgProfEvents,
1201 'candles':IgProfCandles,
1202 'cmsdriverOptions':cmsdriverOptions,
1203 'stepOptions':stepOptions,
1205 'profilers':profilers,
1206 'bypasshlt':bypasshlt,
1207 'userInputRootFiles':userInputFile
1210 TestsToDo.append(IgProfProfilerArgs)
1211 self.
printFlush(
"Appended IgProf test with profiler option %s to the TestsToDo list"%profilers)
1215 self.
printFlush(
"Splitting the IgProf tests into Perf and Mem to parallelize the cmsRun execution as much as possible:")
1219 'perfdir':perfsuitedir,
1220 'NumEvents':IgProfEvents,
1221 'candles':IgProfCandles,
1222 'cmsdriverOptions':cmsdriverOptions,
1223 'stepOptions':stepOptions,
1224 'Name':
"IgProf_Perf",
1225 'profilers':profilers,
1226 'bypasshlt':bypasshlt,
1227 'userInputRootFiles':userInputFile
1230 TestsToDo.append(IgProfPerfArgs)
1231 self.
printFlush(
"Appended IgProf PERF test to the TestsToDo list")
1235 'perfdir':perfsuitedir,
1236 'NumEvents':IgProfEvents,
1237 'candles':IgProfCandles,
1238 'cmsdriverOptions':cmsdriverOptions,
1239 'stepOptions':stepOptions,
1240 'Name':
"IgProf_Mem",
1241 'profilers':profilers,
1242 'bypasshlt':bypasshlt,
1243 'userInputRootFiles':userInputFile
1246 TestsToDo.append(IgProfMemArgs)
1247 self.
printFlush(
"Appended IgProf MEM test to the TestsToDo list")
1253 self.
printFlush(
"Preparing IgProf PileUp tests")
1258 self.
printFlush(
"Special profiler option for IgProf was indicated by the user: %s"%profilers)
1260 IgProfProfilerPUArgs={
1261 'perfdir':perfsuitedir,
1262 'NumEvents':IgProfEvents,
1263 'candles':IgProfPUCandles,
1264 'cmsdriverOptions':cmsdriverPUOptions,
1265 'stepOptions':stepOptions,
1267 'profilers':profilers,
1268 'bypasshlt':bypasshlt,
1269 'userInputRootFiles':userInputFile
1272 TestsToDo.append(IgProfProfilerPUArgs)
1273 self.
printFlush(
"Appended IgProf PileUp test with profiler option %s to the TestsToDo list"%profilers)
1275 self.
printFlush(
"Splitting the IgProf tests into Perf and Mem to parallelize the cmsRun execution as much as possible:")
1279 'perfdir':perfsuitedir,
1280 'NumEvents':IgProfEvents,
1281 'candles':IgProfPUCandles,
1282 'cmsdriverOptions':cmsdriverPUOptions,
1283 'stepOptions':stepOptions,
1284 'Name':
"IgProf_Perf",
1285 'profilers':profilers,
1286 'bypasshlt':bypasshlt,
1287 'userInputRootFiles':userInputFile
1290 TestsToDo.append(IgProfPerfPUArgs)
1291 self.
printFlush(
"Appended IgProf MEM PileUp test to the TestsToDo list")
1295 'perfdir':perfsuitedir,
1296 'NumEvents':IgProfEvents,
1297 'candles':IgProfPUCandles,
1298 'cmsdriverOptions':cmsdriverPUOptions,
1299 'stepOptions':stepOptions,
1300 'Name':
"IgProf_Mem",
1301 'profilers':profilers,
1302 'bypasshlt':bypasshlt,
1303 'userInputRootFiles':userInputFile
1306 TestsToDo.append(IgProfMemPUArgs)
1307 self.
printFlush(
"Appended IgProf MEM PileUp test to the TestsToDo list")
1308 if not (IgProfCandles
or IgProfPUCandles):
1309 self.
printFlush(
"A number of events (%s) for IgProf tests was selected, but no candle for regular or pileup tests was selected!"%(IgProfEvents))
1313 if CallgrindEvents > 0:
1314 if CallgrindCandles:
1317 'perfdir':perfsuitedir,
1318 'NumEvents':CallgrindEvents,
1319 'candles':CallgrindCandles,
1320 'cmsdriverOptions':cmsdriverOptions,
1321 'stepOptions':stepOptions,
1323 'profilers':profilers,
1324 'bypasshlt':bypasshlt,
1325 'userInputRootFiles':userInputFile
1328 TestsToDo.append(CallgrindArgs)
1329 self.
printFlush(
"Appended Callgrind test to the TestsToDo list")
1331 if CallgrindPUCandles:
1332 self.
printFlush(
"Preparing Callgrind PileUp tests")
1334 'perfdir':perfsuitedir,
1335 'NumEvents':CallgrindEvents,
1336 'candles':CallgrindPUCandles,
1337 'cmsdriverOptions':cmsdriverPUOptions,
1338 'stepOptions':stepOptions,
1340 'profilers':profilers,
1341 'bypasshlt':bypasshlt,
1342 'userInputRootFiles':userInputFile
1345 TestsToDo.append(CallgrindPUArgs)
1346 self.
printFlush(
"Appended Callgrind PileUp test to the TestsToDo list")
1347 if not (CallgrindCandles
or CallgrindPUCandles):
1348 self.
printFlush(
"A number of events (%s) for Callgrind tests was selected, but no candle for regular or pileup tests was selected!"%(CallgrindEvents))
1350 if MemcheckEvents > 0:
1354 'perfdir':perfsuitedir,
1355 'NumEvents':MemcheckEvents,
1356 'candles':MemcheckCandles,
1357 'cmsdriverOptions':cmsdriverOptions,
1358 'stepOptions':stepOptions,
1360 'profilers':profilers,
1361 'bypasshlt':bypasshlt,
1362 'userInputRootFiles':userInputFile
1365 TestsToDo.append(MemcheckArgs)
1366 self.
printFlush(
"Appended Memcheck test to the TestsToDo list")
1368 if MemcheckPUCandles:
1369 self.
printFlush(
"Preparing Memcheck PileUp tests")
1371 'perfdir':perfsuitedir,
1372 'NumEvents':MemcheckEvents,
1373 'candles':MemcheckPUCandles,
1374 'cmsdriverOptions':cmsdriverPUOptions,
1375 'stepOptions':stepOptions,
1377 'profilers':profilers,
1378 'bypasshlt':bypasshlt,
1379 'userInputRootFiles':userInputFile
1382 TestsToDo.append(MemcheckPUArgs)
1383 self.
printFlush(
"Appended Memcheck PileUp test to the TestsToDo list")
1384 if not (MemcheckCandles
or MemcheckPUCandles):
1385 self.
printFlush(
"A number of events (%s) for Memcheck tests was selected, but no candle for regular or pileup tests was selected!"%(MemcheckEvents))
1389 if IgProfEvents
or CallgrindEvents
or MemcheckEvents:
1391 self.
printFlush(
"Threading all remaining tests on all %s available cores!"%len(AvailableCores))
1397 OriginalAvailableCores=
list(AvailableCores)
1399 self.
printFlush(
"Original available cores list: %s"%AvailableCores)
1402 activePerfTestThreads={}
1411 self.
printFlush(
"Currently %s tests are scheduled to be run:"%len(TestsToDo))
1417 self.
printFlush(
"There is/are %s core(s) available"%len(AvailableCores))
1418 cpu=AvailableCores.pop()
1420 simpleGenReportArgs=TestsToDo.pop()
1421 self.
printFlush(
"Let's submit %s test on core %s"%(simpleGenReportArgs[
'Name'],cpu))
1423 if simpleGenReportArgs[
'Name']
not in TimerInfo.keys():
1426 TimerInfo.update({simpleGenReportArgs[
'Name']:{
'TotalTime':self.
PerfTestTotalTimer}})
1428 self.
printFlush(
"Starting thread %s"%threadToDo)
1429 ReportExitCode=threadToDo.start()
1430 self.
printFlush(
"Adding thread %s to the list of active threads"%threadToDo)
1431 activePerfTestThreads[cpu]=threadToDo
1437 activeTestNamesPU=[]
1438 for cpu
in activePerfTestThreads.keys():
1439 if activePerfTestThreads[cpu].isAlive():
1441 if "--pileup" in activePerfTestThreads[cpu].simpleGenReportArgs[
'cmsdriverOptions']:
1442 activeTestNamesPU.append(activePerfTestThreads[cpu].simpleGenReportArgs[
'Name'])
1444 activeTestNames.append(activePerfTestThreads[cpu].simpleGenReportArgs[
'Name'])
1446 elif cpu
not in AvailableCores:
1450 self.
printFlush(
"%s test, in thread %s is done running on core %s"%(activePerfTestThreads[cpu].simpleGenReportArgs[
'Name'],activePerfTestThreads[cpu],cpu) )
1451 self.
printFlush(
"About to append cpu %s to AvailableCores list"%cpu)
1452 AvailableCores.append(cpu)
1457 if "--pileup" in activePerfTestThreads[cpu].simpleGenReportArgs[
'cmsdriverOptions']:
1459 activeTestNamesPU.remove(activePerfTestThreads[cpu].simpleGenReportArgs[
'Name'])
1464 activeTestNames.remove(activePerfTestThreads[cpu].simpleGenReportArgs[
'Name'])
1468 activePerfTestThreads.pop(cpu)
1476 for TestName
in [
"IgProf_Perf",
"IgProf_Mem",
"Memcheck",
"Valgrind"]:
1477 if (TestName
not in activeTestNames)
and (TestName
not in activeTestNamesPU) :
1479 TimerInfo[TestName][
'TotalTime'].set_end(datetime.datetime.now())
1486 if not AvailableCores==[]
and (set(AvailableCores)==set(range(
cmsCpuInfo.get_NumOfCores()))
or set(AvailableCores)==set(OriginalAvailableCores))
and not TestsToDo:
1487 self.
printFlush(
"PHEW! We're done... all TestsToDo are done... at %s "%(self.
getDate()))
1502 self.
printFlush(
"Waiting for tests to be done...")
1511 self.logh.write(
"Ending with %s cmsScimark on cpu%s\n" % (cmsScimark,cpu))
1512 cmsScimarkFinalTime=
PerfSuiteTimer(start=datetime.datetime.now())
1513 TimerInfo[
'cmsScimarkTime'].
update({
'cmsScimarkFinal':cmsScimarkFinalTime})
1515 self.
benchmarks(cpu,perfsuitedir,scimark.name,cmsScimark)
1516 cmsScimarkFinalTime.set_end(datetime.datetime.now())
1517 if cmsScimarkLarge > 0:
1518 self.logh.write(
"Following with %s cmsScimarkLarge on cpu%s\n" % (cmsScimarkLarge,cpu))
1519 cmsScimarkLargeFinalTime=
PerfSuiteTimer(start=datetime.datetime.now())
1520 TimerInfo[
'cmsScimarkTime'].
update({
'cmsScimarkLargeFinal':cmsScimarkLargeFinalTime})
1521 self.
benchmarks(cpu,perfsuitedir,scimarklarge.name,cmsScimarkLarge,large=
True)
1522 cmsScimarkLargeFinalTime.set_end(datetime.datetime.now())
1525 self.logh.write(
"Running the regression analysis with respect to %s\n"%
getVerFromLog(prevrel))
1526 self.logh.write(time.ctime(time.time()))
1534 TimerInfo.update({
'tarballTime':{
'TotalTime':tarballTime}})
1539 if "=" in str(stepOptions):
1540 fileStepOption=
str(stepOptions).
split(
"=")[1]
1542 fileStepOption=
str(stepOptions)
1543 if fileStepOption==
"":
1544 fileStepOption=
"UnknownStep" 1546 fileWorkingDir=os.path.basename(perfsuitedir)
1551 fileEventContentOption=
"UnknownEventContent" 1552 fileConditionsOption=
"UnknownConditions" 1553 for token
in cmsdriverOptions.split(
"--"):
1554 if token!=
'' and 'cmsdriver' not in token:
1556 fileOption=token.split(
"=")[0]
1557 fileOptionValue=token.split(
"=")[1].
strip(
"'").
strip(
'"')
1559 fileOption=token.split()[0]
1560 fileOptionValue=token.split()[1].
strip(
"'").
strip(
'"')
1561 if "eventcontent" or "conditions" in fileOption:
1562 if "eventcontent" in fileOption:
1563 fileEventContentOption=fileOptionValue
1564 elif "conditions" in fileOption:
1567 if "auto:" in fileOptionValue:
1569 fileConditionsOption = autoCond[ fileOptionValue.split(
':')[1] ]
1575 if "," in fileOptionValue:
1576 fileConditionsOption=fileOptionValue.split(
"::")[0].
split(
",")[1]
1578 fileConditionsOption=fileOptionValue.split(
"::")[0]
1590 subprocess.Popen(
"ls -R | grep .root > rootFiles",shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read()
1591 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)
1592 AbsTarFileLOG = os.path.join(perfsuitedir,LogFile)
1593 tarcmd =
"tar zcfX %s %s %s" %(AbsTarFileLOG,
"rootFiles", os.path.join(perfsuitedir,
"*"))
1594 self.
printFlush(
"Creating a tarball for the logfiles")
1596 self.
printFlush(subprocess.Popen(tarcmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read())
1597 self.
printFlush(subprocess.Popen(
"rm rootFiles",shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read())
1599 fullcastorpathlog=os.path.join(castordir,LogFile)
1603 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)
1604 AbsTarFile = os.path.join(perfsuitedir,TarFile)
1605 tarcmd =
"tar -zcf %s %s" %(AbsTarFile, os.path.join(perfsuitedir,
"*"))
1606 md5cmd =
"md5sum %s" %(AbsTarFile)
1607 self.
printFlush(
"Creating a tarball with the content of the directory")
1615 self.
printFlush(subprocess.Popen(tarcmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read())
1616 md5sum = subprocess.Popen(md5cmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.read().
split()[0]
1617 self.
printFlush(
"The md5 checksum of the tarball: %s" %(md5sum))
1618 AbsTarFileMD5 = AbsTarFile +
".md5" 1619 md5filecmd =
"echo %s > %s" % (md5sum, AbsTarFileMD5)
1620 self.
printFlush(subprocess.Popen(md5filecmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read())
1624 fullcastorpathfile=os.path.join(castordir,TarFile)
1625 fullcastorpathmd5=os.path.join(castordir,TarFile +
".md5")
1627 checkcastor=
"nsls %s" % fullcastorpathfile
1630 checkcastorout=subprocess.Popen(checkcastor,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.read()
1631 if checkcastorout.rstrip()==fullcastorpathfile:
1632 castorcmdstderr=
"File %s is already on CASTOR! Will NOT OVERWRITE!!!"%fullcastorpathfile
1637 castorcmd=
"rfcp %s %s" % (AbsTarFile,fullcastorpathfile)
1638 castormd5cmd=
"rfcp %s %s" % (AbsTarFileMD5,fullcastorpathmd5)
1639 castorlogcmd=
"rfcp %s %s" % (AbsTarFileLOG,fullcastorpathlog)
1645 castorcmdstderr=subprocess.Popen(castorcmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read()
1646 subprocess.Popen(castormd5cmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read()
1647 subprocess.Popen(castorlogcmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.read()
1652 self.
printFlush(
"Since the CASTOR archiving for the tarball failed the file %s is kept in directory %s"%(TarFile, perfsuitedir))
1655 self.
printFlush(
"Successfully archived the tarball %s in CASTOR!"%(TarFile))
1656 self.
printFlush(
"The tarball can be found: %s"%(fullcastorpathfile))
1657 self.
printFlush(
"The logfile can be found: %s"%(fullcastorpathlog))
1658 self.
printFlush(
"Deleting the local copy of the tarballs")
1659 rmtarballcmd=
"rm -Rf %s"%(AbsTarFile)
1660 rmtarballmd5cmd=
"rm -Rf %s"%(AbsTarFileMD5)
1661 rmtarballlogcmd=
"rm -Rf %s"%(AbsTarFileLOG)
1667 self.
printFlush(subprocess.Popen(rmtarballcmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.read() )
1668 self.
printFlush(subprocess.Popen(rmtarballmd5cmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.read() )
1669 self.
printFlush(subprocess.Popen(rmtarballlogcmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.read() )
1670 tarballTime.set_end(datetime.datetime.now())
1672 self.
printFlush(
"Performance Suite directory will not be archived in a tarball since --no_tarball option was chosen")
1677 date=time.ctime(time.time())
1678 self.logh.write(
"Performance Suite finished running at %s on %s in directory %s\n" % (date,self.
host,path))
1680 self.logh.write(
"There were no errors detected in any of the log files!\n")
1682 self.logh.write(
"ERROR: There were %s errors detected in the log files, please revise!\n" % self.
ERRORS)
1685 except exceptions.Exception
as detail:
1686 self.logh.write(
str(detail) +
"\n")
1688 if not self.logh.isatty():
1692 if MailLogRecipients !=
"":
1693 self.
printFlush(
"Sending email notification for this execution of the performance suite with command:")
1694 sendLogByMailcmd=
'cat cmsPerfSuite.log |mail -s "Performance Suite finished running on %s" '%self.
host + MailLogRecipients
1698 self.
printFlush(subprocess.Popen(sendLogByMailcmd,shell=
True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.read() )
1700 self.
printFlush(
'No email notification will be sent for this execution of the performance suite since option --mail "" was used')
1702 TotalTime.set_end(datetime.datetime.now())
1703 self.
printFlush(
"Total Running Time\t%s hrs (%s mins)"%(TotalTime.get_duration()[
'hours'],TotalTime.get_duration()[
'minutes']))
1709 PerfSuiteTimerInfo=open(
"PerfSuiteTimerInfo.pkl",
"wb")
1713 self.logh.write(
"Test type\tActual Test\tDuration\tStart Time\tEnd Time\n")
1714 for key
in TimerInfo.keys():
1716 TimerInfoStr.update({key:{}})
1717 for test
in TimerInfo[key].
keys():
1718 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()]})
1719 self.logh.write(key+
"\t"+test+
"\t")
1720 self.logh.write(
"%s hrs (%s mins)\t"%(TimerInfo[key][test].get_duration()[
'hours'],TimerInfo[key][test].get_duration()[
'minutes']))
1721 self.logh.write(
"%s\t"%TimerInfo[key][test].get_start())
1722 self.logh.write(
"%s\n"%TimerInfo[key][test].get_end())
1723 pickle.dump(TimerInfoStr,PerfSuiteTimerInfo)
1724 PerfSuiteTimerInfo.close()
1726 self.logh.write(
"Final Performance Suite exit code was %s"%FinalExitCode)
1728 sys.exit(FinalExitCode)
1746 (PerfSuiteArgs[
'create'],
1747 PerfSuiteArgs[
'castordir'],
1748 PerfSuiteArgs[
'TimeSizeEvents'],
1749 PerfSuiteArgs[
'IgProfEvents'],
1750 PerfSuiteArgs[
'CallgrindEvents'],
1751 PerfSuiteArgs[
'MemcheckEvents'],
1752 PerfSuiteArgs[
'cmsScimark'],
1753 PerfSuiteArgs[
'cmsScimarkLarge'],
1754 PerfSuiteArgs[
'cmsdriverOptions'],
1755 PerfSuiteArgs[
'cmsdriverPUOptions'],
1756 PerfSuiteArgs[
'stepOptions'],
1757 PerfSuiteArgs[
'quicktest'],
1758 PerfSuiteArgs[
'profilers'],
1759 PerfSuiteArgs[
'cpus'],
1760 PerfSuiteArgs[
'cores'],
1761 PerfSuiteArgs[
'prevrel'],
1762 PerfSuiteArgs[
'bypasshlt'],
1763 PerfSuiteArgs[
'runonspare'],
1764 PerfSuiteArgs[
'perfsuitedir'],
1765 PerfSuiteArgs[
'logfile'],
1766 PerfSuiteArgs[
'TimeSizeCandles'],
1767 PerfSuiteArgs[
'IgProfCandles'],
1768 PerfSuiteArgs[
'CallgrindCandles'],
1769 PerfSuiteArgs[
'MemcheckCandles'],
1770 PerfSuiteArgs[
'TimeSizePUCandles'],
1771 PerfSuiteArgs[
'IgProfPUCandles'],
1772 PerfSuiteArgs[
'CallgrindPUCandles'],
1773 PerfSuiteArgs[
'MemcheckPUCandles'],
1774 PerfSuiteArgs[
'PUInputFile'],
1775 PerfSuiteArgs[
'userInputFile'],
1776 PerfSuiteArgs[
'MailLogRecipients'],
1777 PerfSuiteArgs[
'tarball']
1778 ) = suite.optionParse(argv)
1780 if PerfSuiteArgs[
'create']:
1781 suite.createIgVolume()
1783 if not PerfSuiteArgs[
'logfile'] ==
None:
1784 if os.path.exists(PerfSuiteArgs[
'logfile']):
1785 oldlogfile=PerfSuiteArgs[
'logfile']+
"_"+time.strftime(
"%d-%m-%Y_%H:%M:%S")
1787 mvOldLogfile=subprocess.Popen(
"mv %s %s"%(PerfSuiteArgs[
'logfile'],oldlogfile), shell=
True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
1788 mvOldLogfileExitCode=mvOldLogfile.wait()
1791 ActualLogfile = open(PerfSuiteArgs[
'logfile'],
"w")
1792 if mvOldLogfileExitCode:
1793 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))
1795 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))
1796 except (OSError, IOError)
as detail:
1797 ActualLogfile.write(
"Failed to open the intended logfile %s, detail error:\n%s"%(PerfSuiteArgs[
'logfile'],detail))
1801 ActualLogfile = open(PerfSuiteArgs[
'logfile'],
"w")
1802 except (OSError, IOError)
as detail:
1803 ActualLogfile.write(
"Failed to open the intended logfile %s, detail error:\n%s"%(PerfSuiteArgs[
'logfile'],detail))
1804 ActualLogfile.flush()
1807 ActualLogfile.write(
"Performance suite invoked with command line:\n")
1808 cmdline=reduce(
lambda x,y:x+
" "+y,sys.argv)
1809 ActualLogfile.write(cmdline+
"\n")
1810 ActualLogfile.flush()
1813 ActualLogfile.write(
"Initial PerfSuite Arguments:\n")
1814 for key
in PerfSuiteArgs.keys():
1815 ActualLogfile.write(
"%s %s\n"%(key,PerfSuiteArgs[key]))
1816 ActualLogfile.flush()
1819 PerfSuiteArgs[
'cpu_list'] = PerfSuiteArgs[
'cpus']
1822 if len(PerfSuiteArgs[
'cpus']) > 1:
1823 ActualLogfile.write(
"More than 1 cpu: threading the Performance Suite!\n")
1824 outputdir=PerfSuiteArgs[
'perfsuitedir']
1825 runonspare=PerfSuiteArgs[
'runonspare']
1826 cpus=PerfSuiteArgs[
'cpus']
1827 cores=PerfSuiteArgs[
'cores']
1829 for core
in range(PerfSuiteArgs[
'cores']):
1830 cmsScimarkLaunch_pslist={}
1831 if len(cpus) != cores:
1832 if (core
not in cpus):
1834 ActualLogfile.write(
"Submitting cmsScimarkLaunch.csh to run on core cpu "+
str(core)+
"\n")
1835 subcmd =
"cd %s ; cmsScimarkLaunch.csh %s" % (outputdir,
str(core))
1836 command=
"taskset -c %s sh -c \"%s\" &" % (
str(core), subcmd)
1838 ActualLogfile.write(command+
"\n")
1841 cmsScimarkLaunch_pslist[core]=subprocess.Popen(command,shell=
True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
1842 ActualLogfile.write(
"Spawned %s \n with PID %s"%(command,cmsScimarkLaunch_pslist[core].pid))
1843 ActualLogfile.flush()
1844 PerfSuiteArgs[
'runonspare']=
False 1845 logfile=PerfSuiteArgs[
'logfile']
1853 cpudir = os.path.join(outputdir,
"cpu_%s" % cpu)
1854 if not os.path.exists(cpudir):
1856 PerfSuiteArgs[
'perfsuitedir']=cpudir
1857 PerfSuiteArgs[
'cpus']=[cpu]
1858 if PerfSuiteArgs[
'logfile']:
1859 PerfSuiteArgs[
'logfile']=os.path.join(cpudir,os.path.basename(PerfSuiteArgs[
'logfile']))
1861 PerfSuiteArgs[
'logfile']=os.path.join(cpudir,
"cmsPerfSuiteThread.log")
1863 suitethread[cpu]=PerfThread(**PerfSuiteArgs)
1865 ActualLogfile.write(
"Launching PerfSuite thread on cpu%s"%cpu)
1866 ActualLogfile.flush()
1869 suitethread[cpu].
start()
1871 while reduce(
lambda x,y: x
or y,
map(
lambda x: x.isAlive(),suitethread.values())):
1875 except (KeyboardInterrupt, SystemExit):
1877 ActualLogfile.write(
"All PerfSuite threads have completed!\n")
1878 ActualLogfile.flush()
1881 suite.runPerfSuite(**PerfSuiteArgs)
1883 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.