24 import sys, os, re, operator
25 import optparse
as opt
26 from cmsPerfCommons
import Candles, CandDesc, FileName, KeywordToCfi, CustomiseFragment, CandFname, EventContents
27 from functools
import reduce
32 THIS_PROG_NAME = os.path.basename(sys.argv[0])
33 cmsDriver =
'cmsDriver.py'
34 hypreg = re.compile(
'-')
36 DEF_STEPS = [
'GEN,SIM',
'DIGI']
37 AllSteps = [
"GEN,SIM",
"DIGI",
"L1",
"DIGI2RAW",
"HLT",
"RAW2DIGI",
"RECO"]
45 'TimingReport' :
'Timing_Parser',
46 'TimingReport @@@ reuse' :
'Timing_Parser',
47 'TimeReport' :
'Timereport_Parser',
48 'TimeReport @@@ reuse' :
'Timereport_Parser',
49 'SimpleMemReport' :
'SimpleMem_Parser',
50 'EdmSize' :
'Edm_Size',
51 'IgProfperf' :
'IgProf_perf.PERF_TICKS',
52 'IgProfperf @@@ reuse' :
'IgProf_perf.PERF_TICKS',
53 'IgProfMemTotal' :
'IgProf_mem.MEM_TOTAL',
54 'IgProfMemTotal @@@ reuse':
'IgProf_mem.MEM_TOTAL',
55 'IgProfMemLive' :
'IgProf_mem.MEM_LIVE',
56 'IgProfMemLive @@@ reuse' :
'IgProf_mem.MEM_LIVE',
57 'IgProfMemMax' :
'IgProf_mem.MEM_MAX',
58 'IgProfMemMax @@@ reuse' :
'IgProf_mem.MEM_MAX',
59 'IgProfMemAnalyse' :
'IgProf_mem.ANALYSE',
60 'valgrind' :
'ValgrindFCE',
61 'memcheck_valgrind' :
'Memcheck_Valgrind',
68 return filter(item.__eq__,list)[0]
72 for x
in range(lenlist - 1,0,-1):
77 '''Checks user steps <steps> for order against steps defined in AllSteps list.
78 If they are not, prints a warning and exits.
90 if step==
"GEN,FASTSIM":
94 split = astep.split(
"-")
95 astep = split[0].
split(
":")[0]
100 idx = AllSteps.index(astep.split(
":")[0])
101 if not ( idx == -2 ):
103 print "ERROR: Your user defined steps are not in a valid order"
107 lstidx = AllSteps.index(split[1].
split(
":")[0])
111 '''Analyzes the steps in <userSteps> to translate the cmsRelvalreportInput.py --step option into the cmsDriver.py one. Expanding hyphens for combined steps.
112 Handle the exceptional cases of GEN-, GEN-SIM and GEN-FASTSIM (GEN is never profiled by itself).
113 Returns a list of steps <steps>.'''
117 gsreg = re.compile(
'GEN-SIM')
118 greg = re.compile(
'GEN')
119 gfsreg = re.compile(
'GEN-FASTSIM')
120 StepsTokens = userSteps.split(
",")
122 for astep
in StepsTokens:
127 if gsreg.search(astep):
128 astep = gsreg.sub(
r"GEN,SIM", astep)
129 elif gfsreg.search(astep):
130 astep = gfsreg.sub(
r"GEN,FASTSIM", astep)
131 elif greg.search(astep):
132 astep = greg.sub(
r"GEN,SIM", astep)
146 explanations = map(
lambda x:
" " + x, Candles)
148 for x
in range(len(explanations)):
149 explanation +=
"%-*s %s\n" % (30, explanations[x],CandDesc[x])
150 parser = opt.OptionParser(usage=(
"""%s NUM_EVENTS_PER_CFG CANDLES PROFILE [--cmsdriver=cmsDriverOptions] [--usersteps=processingStepsOption]
152 Description - This program creates a configuration file for cmsRelvalreport.py that describes the order in which cmsDriver.py should be run with which candles, steps and profiling so that time spent running cmsDriver.py is minimised. Without this correct ordering we would have to re-run parts of the profiling steps.
155 NUM_EVENTS_PER_CFG - The number of events per config file
157 CANDLES - The simulation type to perform profiling on
159 AllCandles Run all of the candles below
162 PROFILE - the type of profiling to perform (multiple codes can be used):
175 Examples (could be obsolete!):
176 Perform Timing Report profiling for all candles, all steps and 10 events per cfg.
177 ./%s 10 AllCandles 1 \"--conditions FakeConditions --eventcontent FEVTDEBUGHLT\"
178 Perform Timing Report, Time Report and SimpleMemoryCheck profiling for HiggsZZ4LM200, all steps and 50 events.
179 ./%s 50 \"HiggsZZ4LM200\" 012 \"--conditions FakeConditions --eventcontent FEVTDEBUGHLT\"
180 Perform IgProfPerf and IgProfMemTotal profiling for TTbar, all steps and 100 events.
181 ./%s 100 \"TTbar\" 45 --cmsdriver=\"--conditions FakeConditions --eventcontent RAWRECO\"
182 Perform ValgrindFCE ValgrindMemCheck profiling for Minimum bias and 100 events. Only on GEN,SIM and DIGI steps.
183 ./%s 100 \"MinBias\" 89 --cmsdriver=\"--conditions FakeConditions --eventcontent RAWSIM\" \"--usersteps=GEN-SIM,DIGI"""
184 % ( THIS_PROG_NAME, explanation, THIS_PROG_NAME,THIS_PROG_NAME,THIS_PROG_NAME,THIS_PROG_NAME)))
186 devel = opt.OptionGroup(parser,
"Developer Options",
187 "Caution: use these options at your own risk."
188 "It is believed that some of them bite.\n")
197 help=
'Should we bypass using the HLT root file?'
205 help=
'Which steps to run',
212 dest=
'cmsDriverOptions',
213 help=
'Option for cmsDriver.py can be specified as a string to be added to all cmsDriver.py commands',
214 metavar=
'<CONDITION>',
220 dest=
'userInputFile',
221 help=
'Eventual input file (for now to be only used with HLT and RAW2DIGI-RECO workflows)',
223 metavar=
'<INPUTFILE>',
230 help=
'Do not perform profiling, ever',
239 help=
'Show debug output',
243 parser.set_defaults(debug=
False,noprof=
False)
244 parser.add_option_group(devel)
246 (options, args) = parser.parse_args()
249 _noprof = options.noprof
250 debug = options.debug
251 numofargs = len(args)
253 if ((
not numofargs == 3)
and (
not _noprof))
or (_noprof
and not (numofargs == 2)):
254 parser.error(
"There are not enough arguments specified to run this program."
255 " Please determine the correct arguments from the usage information above."
256 " Run with --help option for more information.")
259 return (options, args)
265 hypsteps = step.split(
r"-")
270 if not reduce(
lambda x,y,: x
and y,map(
lambda x: x.split(
":")[0]
in AllSteps, hypsteps)):
272 print "ERROR: One of the steps you defined is invalid"
275 if (hypsteps[0] == hypsteps[1]):
276 print "WARNING: You should not add a hypenated step that as the same source and destination step, ignoring"
277 newsteps.append(hypsteps[0])
279 newsteps.append(hypsteps[0])
281 srt = AllSteps.index(hypsteps[0].
split(
":")[0]) + 1
282 for n
in range(srt,AllSteps.index(hypsteps[-1].
split(
":")[0])):
284 if astep
in ( hypsteps[i].
split(
":")[0]
for i
in range(1,len(hypsteps))):
286 astep=
filter(
lambda x: astep == x.split(
":")[0],hypsteps)[0]
287 if astep==hypsteps[-1].
split(
":")[0]:
289 newsteps.append(astep)
290 newsteps.append(hypsteps[-1])
292 if not (step.split(
":")[0]
in AllSteps):
293 print "ERROR: One of the steps you defined is invalid"
296 newsteps.append(step)
302 cmsDriverOptions =
""
303 global AfterPileUpSteps
304 NumberOfEvents = int(args[0])
305 WhichCandles = str(args[1])
308 ProfileCode = str(args[2])
310 if options.cmsDriverOptions:
312 cmsDriverOptions = options.cmsDriverOptions
313 print 'Using user-specified cmsDriver.py options: ' + cmsDriverOptions
315 if options.userSteps:
317 userSteps = options.userSteps
320 if WhichCandles.lower() ==
'allcandles':
322 print 'ALL standard simulation candles will be PROCESSED:'
324 Candle = [WhichCandles]
325 print 'Candle %s will be PROCESSED' % Candle[0]
331 print 'The default steps will be run:'
334 print "You defined your own steps to run:"
339 return (NumberOfEvents, ProfileCode, cmsDriverOptions, steps, Candle, options.bypasshlt,options.userInputFile)
348 CMSSW_BASE = os.environ[
'CMSSW_BASE']
349 CMSSW_RELEASE_BASE = os.environ[
'CMSSW_RELEASE_BASE']
350 CMSSW_VERSION = os.environ[
'CMSSW_VERSION']
352 print 'Error: An environment variable either CMSSW_{BASE, RELEASE_BASE or VERSION} is not available.'
353 print ' Please run eval `scramv1 runtime -csh` to set your environment variables'
362 SimCandlesFile =
'SimulationCandles_%s.txt' % CMSSW_VERSION
365 simcandles = open(SimCandlesFile,
'w')
367 print "Couldn't open %s to save" % SimCandlesFile
369 simcandles.write(
'#Candles file automatically generated by %s for %s\n'
370 % (THIS_PROG_NAME, CMSSW_VERSION))
371 simcandles.write(
"#CMSSW Base : %s\n" % CMSSW_BASE)
372 simcandles.write(
"#Release Base: %s\n" % CMSSW_RELEASE_BASE)
373 simcandles.write(
"#Version : %s\n\n" % CMSSW_VERSION)
399 Profile.append(AllowedProfile[-1])
404 if str(i)
in ProfileCode:
405 firstCase = (i == 0
and (str(1)
in ProfileCode
or str(2)
in ProfileCode)) \
406 or (i == 1
and str(2)
in ProfileCode)
407 secCase = (i==4
and str(7)
in ProfileCode) \
408 or (i == 5
and (str(6)
in ProfileCode
or str(7)
in ProfileCode)) \
409 or (i == 6
and str(7)
in ProfileCode)
411 if firstCase
or secCase:
412 Profile.append(AllowedProfile[i] +
' @@@ reuse')
415 Profile.append(
"IgProfMemMax @@@ reuse")
417 Profile.append(AllowedProfile[i])
419 Profile.append(
"IgProfMemMax")
424 simcandles.write(
'#%s\n' % FileName[acandle])
425 simcandles.write(
'#Step %s\n' % step)
430 if 'DIGI2RAW' in step:
431 SavedProfile = Profile
434 Profile = SavedProfile
436 return (Profile, SavedProfile)
442 if "--pileup" in cmsdriverOptions
and not (step ==
"HLT" or step.startswith(
"RAW2DIGI")):
443 return CustomiseFragment[
'DIGI-PILEUP']
444 elif step
in CustomiseFragment:
445 return CustomiseFragment[step]
449 return CustomiseFragment[
'DIGI']
452 def setInputFile(steps,step,acandle,stepIndex,pileup=False,bypasshlt=False):
455 if pileup
and stepIndex == 0:
456 InputFileOption =
"--filein file:%s_%s" % ( FileName[acandle],
"DIGI" )
458 InputFileOption =
"--filein file:%s_%s" % ( FileName[acandle],steps[stepIndex - 1] )
463 if 'GEN,SIM' in step:
465 if 'GEN,FASTSIM' in step:
467 elif 'HLT' in steps[stepIndex - 1]
and bypasshlt:
472 InputFileOption =
"--filein file:%s_%s" % ( FileName[acandle],steps[stepIndex - 2] )
474 if not InputFileOption ==
"" :
475 InputFileOption +=
".root "
477 return InputFileOption
479 def writeUnprofiledSteps(simcandles,CustomisePythonFragment,cmsDriverOptions,unprofiledSteps,previousOutputFile,acandle,NumberOfEvents, stepIndex, pileup,bypasshlt):
487 if bypasshlt
and unprofiledSteps[-1]==
"HLT":
488 stepsStr =
",".
join(unprofiledSteps[:-1])
489 OutputFile =
"%s_%s.root" % ( FileName[acandle],unprofiledSteps[-2])
491 stepsStr =
",".
join(unprofiledSteps)
492 OutputFile =
"%s_%s.root" % ( FileName[acandle],unprofiledSteps[-1])
493 simcandles.write(
"\n#Run a %s step(s) that has not been selected for profiling but is needed to run the next step to be profiled\n" % (stepsStr))
494 OutputFileOption =
"--fileout=%s" % OutputFile
506 InputFileOption =
"--filein file:" + previousOutputFile
507 if previousOutputFile ==
"":
508 InputFileOption =
setInputFile(AllSteps,unprofiledSteps[0],acandle,stepIndex,pileup=pileup,bypasshlt=bypasshlt)
512 for eventcontent
in EventContents:
513 cmsDriverOptions=re.sub(eventcontent,
'FEVTDEBUGHLT',cmsDriverOptions)
514 Command = (
"%s %s -n %s --step=%s %s %s --customise=%s %s"
516 KeywordToCfi[acandle],
521 CustomisePythonFragment,
523 simcandles.write(
"%s @@@ None @@@ None\n\n" % (Command))
531 fstIdx = AllSteps.index(steps[0].
split(
"-")[0].
split(
":")[0])
534 CustomisePythonFragment =
pythonFragment(
"GEN,SIM",cmsDriverOptions)
535 previousOutputFile=
""
536 OutputFile =
writeUnprofiledSteps(simcandles, CustomisePythonFragment, cmsDriverOptions,AllSteps[0:fstIdx],previousOutputFile,acandle,NumberOfEvents, 0,pileup,bypasshlt)
537 return (fstIdx, OutputFile)
540 return "%s_%s.root" % ( FileName[acandle],endstep)
555 stopIndex = len(steps)
566 if (steps[0] ==
"GEN,FASTSIM"):
569 steps = [
"GEN,FASTSIM"]
571 if not (steps[0] == AllSteps[0])
and (steps[0].
split(
"-")[0] !=
"GEN,SIM"):
573 if (
"--pileup" in cmsDriverOptions)
and (steps[0]==
"HLT" or steps[0].startswith(
"RAW2DIGI")) :
574 userInputFile =
"../INPUT_PILEUP_EVENTS.root"
575 stepIndex=AllSteps.index(steps[0].
split(
"-")[0].
split(
":")[0])
578 elif userInputFile ==
"":
580 (stepIndex, rootFileStr) =
writePrerequisteSteps(simcandles,steps,acandle,NumberOfEvents,cmsDriverOptions,pileup,bypasshlt)
583 stepIndex=AllSteps.index(steps[0].
split(
"-")[0].
split(
":")[0])
591 fstROOTfileStr = rootFileStr
595 start = AllSteps.index(steps[0].
split(
"-")[0].
split(
":")[0])
600 lst = AllSteps.index(steps[-1].
split(
"-")[1].
split(
":")[0])
602 lst = AllSteps.index(steps[-1])
603 runSteps = AllSteps[start:lst]
604 numOfSteps = (lst - start) + 1
605 stopIndex = start + numOfSteps
612 stopIndex = AllSteps.index(steps[-1].
split(
"-")[1].
split(
":")[0]) + 1
615 stopIndex = AllSteps.index(steps[-1].
split(
":")[0]) + 1
620 rawreg = re.compile(
"^RAW2DIGI")
626 prevPrevOutputFile =
""
628 if userInputFile!=
"":
629 previousOutputFile=userInputFile
631 previousOutputFile =
""
633 for x
in range(start,stopIndex,1):
634 if stepIndex >= stopIndex:
636 step = steps[stepIndex]
649 if step
in userSteps
or reduce(
lambda x,y : x
or y,map(
lambda x: step == x.split(
"-")[0].
split(
":")[0],userSteps)):
651 if "GEN,FASTSIM" in userSteps:
652 stepToWrite = stepToWrite +
",HLT:GRun"
653 elif "HLT" in userSteps:
654 stepToWrite = stepToWrite.replace(
"HLT",
"HLT:GRun")
657 hypMatch =
filter(
lambda x:
"-" in x,
filter(
lambda x: step == x.split(
"-")[0],userSteps))
658 if not len(hypMatch) == 0 :
662 stepToWrite =
",".
join(hypsteps)
663 if "GEN,SIM-HLT" in userSteps:
664 stepToWrite = stepToWrite.replace(
"HLT",
"HLT:GRun")
665 befStep = hypsteps[0]
667 if bypasshlt
and hypsteps[-1]==
'HLT':
668 aftStep = hypsteps[-2]
670 aftStep = hypsteps[-1]
672 if filter(
lambda x: stepToWrite==x.split(
":")[0],userSteps):
678 stepToWrite=
filter(
lambda x: stepToWrite==x.split(
":")[0],userSteps)[0]
684 if "GEN,SIM-HLT" or "GEN,FASTSIM" or "HLT" in userSteps:
685 stepToWrite = stepToWrite.replace(
":",
"=")
687 if '--pileup' in cmsDriverOptions:
688 outfile = stepToWrite +
"_PILEUP"
690 outfile = stepToWrite
694 if "GEN,SIM-HLT" or "GEN,FASTSIM" or "HLT" in userSteps:
695 stepToWrite = stepToWrite.replace(
"=",
":")
699 fstROOTfileStr = OutputFile
701 OutputFileOption =
"--fileout=" + OutputFile
707 if 'EdmSize' in prof:
708 EdmFile =
"%s_%s.root" % (FileName[acandle],outfile)
710 if prof == Profile[0]
and not os.path.exists(
"./" + EdmFile):
717 InputFileOption =
"--filein file:" + previousOutputFile
719 if rawreg.search(step)
and bypasshlt
and 'DIGI2RAW.root' in prevPrevOutputFile:
720 InputFileOption =
"--filein file:" + prevPrevOutputFile
721 if previousOutputFile ==
"":
722 InputFileOption =
setInputFile(steps,stepToWrite,acandle,stepIndex,pileup=pileup,bypasshlt=bypasshlt)
723 Command = (
"%s %s -n %s --step=%s %s %s --customise=%s %s"
725 KeywordToCfi[acandle],
730 CustomisePythonFragment,
732 simcandles.write(
"%s @@@ None @@@ None\n" % (Command))
737 InputFileOption =
"--filein file:" + previousOutputFile
738 if rawreg.search(step)
and bypasshlt
and 'DIGI2RAW.root' in prevPrevOutputFile:
739 InputFileOption =
"--filein file:" + prevPrevOutputFile
741 if previousOutputFile ==
"":
742 InputFileOption =
setInputFile(steps,befStep,acandle,stepIndex,pileup,bypasshlt)
746 if '--pileup' in cmsDriverOptions
and ( stepToWrite==
'GEN,SIM' or stepToWrite==
'SIM'):
747 Command = (
"%s %s -n %s --step=%s %s %s --customise=%s %s" % (
749 KeywordToCfi[acandle],
754 CustomiseFragment[
'GEN,SIM'],
755 cmsDriverOptions[:cmsDriverOptions.index(
'--pileup')]
757 elif '--pileup' in cmsDriverOptions
and (stepToWrite==
'GEN,FASTSIM' or stepToWrite==
'GEN,FASTSIM,HLT:GRun'):
759 Command = (
"%s %s -n %s --step=%s %s %s --customise=%s %s" % (
761 KeywordToCfi[acandle],
766 CustomiseFragment[
'DIGI'],
771 Command = (
"%s %s -n %s --step=%s %s %s --customise=%s %s" % (
773 KeywordToCfi[acandle],
778 CustomisePythonFragment,
783 simcandles.write(
"%s @@@ None @@@ None\n" % Command)
785 if 'valgrind' in prof:
787 if 'TimeMemoryInfo.py' in Command:
788 Command=Command.replace(
'--customise=Validation/Performance/TimeMemoryInfo.py',
'')
790 elif 'TimeMemoryG4Info.py' in Command:
791 Command=Command.replace(
'--customise=Validation/Performance/TimeMemoryG4Info.py',
'')
792 stepLabel=stepToWrite
794 if '--pileup' in cmsDriverOptions
and not "_PILEUP" in stepToWrite:
795 stepLabel = stepToWrite+
"_PILEUP"
810 IgProfProfile=
"IgProf"
813 IgProfProfile=
"IgProfMem @@@ reuse"
815 IgProfProfile=
"IgProfMem"
818 IgProfProfile=
"IgProfPerf @@@ reuse"
820 IgProfProfile=
"IgProfPerf"
823 Conditions=
"UNKNOWN_CONDITIONS"
825 EventContent=
"UNKNOWN_EVENTCONTENT"
826 tokens=cmsDriverOptions.split(
"--")
828 keywords=token.split(
" ")
829 if "=" in keywords[0]:
830 keywords=keywords[0].
split(
"=")
831 if "conditions" in keywords[0]:
834 if "auto:" in keywords[1]:
836 fileConditionsOption = autoCond[ keywords[1].
split(
':')[1] ]
837 Conditions = autoCond[ keywords[1].
split(
':')[1] ].
split(
"::")[0]
844 if "," in keywords[1]:
845 Conditions=keywords[1].
split(
",")[1].
split(
"::")[0]
847 Conditions=keywords[1].
split(
"::")[0]
848 elif "pileup" in keywords[0]:
850 elif "eventcontent" in keywords[0]:
851 EventContent=keywords[1]
854 MetaName=acandle+
"___"+stepToWrite+
"___"+PileUp+
"___"+Conditions+
"___"+EventContent+
"___"+IgProfProfile
856 if 'Analyse' not in prof
and (
lambda x:
'Analyse' in x,Profile):
858 simcandles.write(
"%s @@@ %s @@@ %s\n" % (Command,
864 analyse_command = (
"%s @@@ %s @@@ %s\n" % (Command,
865 Profiler[prof].
split(
".")[0]+
'.ANALYSE.'+Profiler[prof].
split(
".")[1],
872 if Profiler[prof] ==
'IgProf_mem.MEM_MAX' or Profiler[prof] ==
'IgProf_perf.PERF_TICKS':
873 analyse_command = analyse_command.replace(
"@@@ reuse",
"")
875 simcandles.write(analyse_command)
877 elif 'Analyse' in prof:
880 simcandles.write(
"%s @@@ %s @@@ %s_%s_%s\n" % (Command,
887 print InputFileOption, step,
'GEN,SIM' in step,
'HLT' in steps[stepIndex - 1], steps
888 print "cmsDriveroptions : " + cmsDriverOption
889 prevPrevOutputFile = previousOutputFile
890 previousOutputFile = OutputFile
892 unprofiledSteps.append(step)
893 isNextStepForProfile =
False
896 isNextStepForProfile = steps[stepIndex + 1]
in userSteps
or reduce(
lambda x,y : x
or y,map(
lambda z: steps[ stepIndex + 1 ] == z.split(
"-")[0].
split(
":")[0],userSteps))
900 print "Error: Something is wrong we shouldn't have come this far"
903 if isNextStepForProfile:
905 OutputFile=
writeUnprofiledSteps(simcandles,CustomisePythonFragment,cmsDriverOptions,unprofiledSteps,previousOutputFile,acandle,NumberOfEvents,stepIndex,pileup,bypasshlt)
907 prevPrevOutputFile = previousOutputFile
908 previousOutputFile = OutputFile
911 stepIndex += len(hypsteps)
914 return fstROOTfileStr
916 def writeCommandsToReport(simcandles,Candle,Profile,debug,NumberOfEvents,cmsDriverOptions,steps,bypasshlt,userInputFile):
925 for acandle
in Candle:
926 print '*Candle ' + acandle
959 (NumberOfEvents, ProfileCode, cmsDriverOptions, steps, Candle, bypasshlt, userInputFile ) =
setupProgramParameters(options,args)
966 (CMSSW_BASE, CMSSW_RELEASE_BASE, CMSSW_VERSION ) =
init_vars()
985 writeCommandsToReport(simcandles,Candle,Profile,debug,NumberOfEvents,cmsDriverOptions,steps,bypasshlt,userInputFile)
987 print "Written out cmsRelvalreport.py input file at:\n%s"%os.path.abspath(
'./'+simcandles.name)
991 if __name__ ==
"__main__":
static std::string join(char **cmd)