3 import os, sys, re, time
6 from threading
import Thread
20 def doCmd(self, cmd, dryRun=False):
22 msg =
"\n# in: " +os.getcwd()
23 if dryRun: msg +=
" dryRun for '"
24 else: msg +=
" going to execute "
25 msg += cmd.replace(
';',
'\n')
28 cmdLog = open(self.wf.numId+
'_'+self.wf.nameId+
'/cmdLog',
'a')
29 cmdLog.write(msg+
'\n')
36 print "ERROR executing ",cmd,
'ret=', ret
42 startDir = os.getcwd()
44 wfDir = self.wf.numId+
'_'+self.wf.nameId
45 if not os.path.exists(wfDir):
49 if os.path.exists( os.path.join(os.environ[
"CMS_PATH"],
'cmsset_default.sh') ) :
50 preamble =
'source $CMS_PATH/cmsset_default.sh; '
52 preamble =
'source $CMS_PATH/sw/cmsset_default.sh; '
53 preamble +=
'eval `scram run -sh`; '
54 preamble +=
'cd '+wfDir+
'; '
55 preamble +=
'ulimit -v 4069000;'
57 startime=
'date %s' %time.asctime()
64 if not self.wf.cmdStep2: stat2 =
'NOSTEP'
65 if not self.wf.cmdStep3: stat3 =
'NOSTEP'
66 if not self.wf.cmdStep4: stat4 =
'NOSTEP'
71 inFile =
'file:raw.root'
72 if self.wf.cmdStep1.startswith(
'DATAINPUT'):
73 print "going to run with file input ... "
75 run = str(self.wf.input.run)
79 label = self.wf.input.label
80 location = self.wf.input.location.lower().
strip()
82 print "ignoring workflow ",self.wf.numId, self.wf.nameId,
' as this is on CAF ...'
83 self.
npass = [0,0,0,0]
84 self.
nfail = [0,0,0,0]
86 logStat =
'Step1-NOTRUN Step2-NOTRUN Step3-NOTRUN Step4-NOTRUN '
87 self.
report+=
'%s_%s %s - time %s; exit: %s %s %s %s \n' % (self.wf.numId, self.wf.nameId, logStat, 0, 0,0,0,0)
90 files = str(self.wf.input.files)
92 if self.wf.cmdStep2
and ' -n ' not in self.wf.cmdStep2: self.wf.cmdStep2 +=
' -n ' + events
93 if self.wf.cmdStep3
and ' -n ' not in self.wf.cmdStep3: self.wf.cmdStep3 +=
' -n ' + events
94 if self.wf.cmdStep4
and ' -n ' not in self.wf.cmdStep4: self.wf.cmdStep4 +=
' -n ' + events
96 print "run, files, events, label", run, files, events, label
97 cmd +=
'dbs search --noheader --url=http://cmsdbsprod.cern.ch/cms_dbs_prod_global/servlet/DBSServlet '
98 cmd +=
"--query='find file where dataset like "+self.wf.input.dataSet
99 if run: cmd +=
" and run=" + run
101 cmd +=
' > %s 2>&1; ' % (
'step1_'+self.wf.nameId+
'-dbsquery.log',)
102 retStep1 = self.
doCmd(cmd)
104 lf = open(wfDir+
'/step1_'+self.wf.nameId+
'-dbsquery.log',
'r')
105 lines = lf.readlines()
107 if not lines
or len(lines)==0 :
108 inFile =
"NoFileFoundInDBS"
112 inFile = lines[0].
strip()
114 print "ERROR determining file from DBS query: ", str(e)
115 inFile =
"NoFileFoundInDBS"
118 cmd += self.wf.cmdStep1 +
' --fileout file:raw.root '
119 cmd +=
' > %s 2>&1; ' % (
'step1_'+self.wf.nameId+
'.log ',)
120 retStep1 = self.
doCmd(cmd)
122 print " ... ret: " , retStep1
129 if self.wf.cmdStep2
and retStep1 == 0:
131 fullcmd += self.wf.cmdStep2
132 if ' -n ' not in fullcmd : fullcmd +=
' -n -1 '
133 fullcmd +=
' --fileout file:reco.root '
134 print '=====>>> ', self.wf.nameId, self.wf.numId
139 if (
'40.0' in str(self.wf.numId) ) :
140 fullcmd +=
' --himix '
141 inFile =
'/store/relval/CMSSW_3_8_0_pre1/RelValPyquen_ZeemumuJets_pt10_2760GeV/GEN-SIM-RAW/MC_37Y_V5-v1/0001/E0DE7C01-2C6F-DF11-B61F-0026189438F4.root'
142 if (
'41.0' in str(self.wf.numId) ) :
143 fullcmd +=
' --himix '
144 inFile =
'/store/relval/CMSSW_3_8_0_pre1/RelValPyquen_GammaJet_pt20_2760GeV/GEN-SIM-RAW/MC_37Y_V5-v1/0001/F68A53A5-2B6F-DF11-8958-003048678FE6.root'
146 fullcmd +=
' --filein '+inFile+
' '
147 fullcmd +=
' > %s 2>&1; ' % (
'step2_'+self.wf.nameId+
'.log ',)
149 retStep2 = self.
doCmd(fullcmd)
152 if self.wf.cmdStep3
and retStep2 == 0:
154 fullcmd += self.wf.cmdStep3
155 if ' -n ' not in fullcmd : fullcmd +=
' -n -1 '
157 if not '134' in str(self.wf.numId):
158 fullcmd +=
' --filein file:reco.root --fileout file:step3.root '
159 fullcmd +=
' > %s 2>&1; ' % (
'step3_'+self.wf.nameId+
'.log ',)
161 retStep3 = self.
doCmd(fullcmd)
163 if self.wf.cmdStep4
and retStep3 == 0:
165 fullcmd += self.wf.cmdStep4
166 if ' -n ' not in fullcmd : fullcmd +=
' -n -1 '
168 if not '134' in str(self.wf.numId):
169 fullcmd +=
' --filein file:step3.root '
170 fullcmd +=
' > %s 2>&1; ' % (
'step4_'+self.wf.nameId+
'.log ',)
172 retStep4 = self.
doCmd(fullcmd)
177 endtime=
'date %s' %time.asctime()
178 tottime=
'%s-%s'%(endtime,startime)
180 self.
nfail = [0,0,0,0]
181 self.
npass = [1,1,1,1]
182 if 'NOSTEP' in stat2:
183 self.
npass = [1,0,0,0]
185 if 'NOSTEP' in stat3 :
186 self.
npass = [1,1,0,0]
187 if 'NOSTEP' in stat4 :
188 self.
npass = [1,1,1,0]
194 self.
npass = [0,0,0,0]
195 self.
nfail = [1,0,0,0]
201 self.
npass = [1,0,0,0]
202 self.
nfail = [0,1,0,0]
207 self.
npass = [1,1,0,0]
208 self.
nfail = [0,0,1,0]
212 self.
npass = [1,1,1,0]
213 self.
nfail = [0,0,0,1]
215 logStat =
'Step1-'+stat1+
' Step2-'+stat2+
' Step3-'+stat3+
' '+
' Step4-'+stat4+
' '
216 self.
report+=
'%s_%s %s - time %s; exit: %s %s %s %s \n' % (self.wf.numId, self.wf.nameId, logStat, tottime, retStep1,retStep2,retStep3, retStep4)
225 def __init__(self, num, nameID, cmd1, cmd2=None, cmd3=None, cmd4=None, inputInfo=None):
239 if not cmd :
return None
242 if 'DATAINPUT' in cmd:
return cmd
245 reN = re.compile(
'\s*-n\s*\d+\s*')
246 newCmd = reN.sub(
' -n 10 ', cmd)
247 if not reN.match(newCmd) :
273 'relval_highstats':
'hi-' ,
274 'relval_generator':
'gen-' ,
293 for k,v
in step.items():
294 if 'no_exec' in k :
continue
295 if k.lower() ==
'cfg':
298 if k.lower() ==
'input':
302 cmd +=
' ' + k +
' ' + str(v)
303 return cfg, input, cmd
309 print "processing ", fileNameIn
312 _tmpMod = __import__(
'Configuration.PyReleaseValidation.'+fileNameIn )
313 self.
relvalModule = sys.modules[
'Configuration.PyReleaseValidation.'+fileNameIn]
315 print "ERROR importing file ", fileNameIn, str(e)
318 print "request for INPUT for ", useInput
320 for num, wfInfo
in self.relvalModule.workflows.items():
324 if wfName.strip() ==
'': wfName = stepList[0]
325 stepCmds = [
'',
'',
'',
'']
329 for step
in stepList:
330 if len(name) > 0 : name +=
'+'
332 if stepIndex==0
and useInput
and (str(num)
in useInput
or "all" in useInput):
334 if step+
'INPUT' in self.relvalModule.step1.keys():
335 stepName = step+
"INPUT"
337 cfg, input, opts = self.
makeCmd(self.relvalModule.stepList[stepIndex][stepName])
339 msg =
"FATAL ERROR: found both cfg and input for workflow "+str(num)+
' step '+stepName
343 cmd =
'cmsDriver.py '+cfg+
' '+opts
344 if stepIndex==0
and not inputInfo
and input:
346 cmd =
'DATAINPUT from '+inputInfo.dataSet
349 cmd =
'cmsDriver.py step'+str(stepIndex+1)+
'.py '+opts
351 stepCmds[stepIndex] = cmd
354 self.
step1WorkFlows[(float(num),prefix)] = (str(float(num)), name, stepCmds[0], stepCmds[1], stepCmds[2], stepCmds[3], inputInfo)
360 for matrixFile
in self.
files:
365 print "ERROR reading file:", matrixFile, str(e)
370 dataFileName = matrixFile.replace(
'relval_',
'cmsDriver_')+
'_hlt.txt'
371 outFile = open(dataFileName,
'w')
373 print "found ", len(self.step1WorkFlows.keys()),
' workflows for ', dataFileName
374 ids = self.step1WorkFlows.keys()
376 stepCmds = [
'',
'',
'',
'']
378 num, name, stepCmds[0], stepCmds[1], stepCmds[2], stepCmds[3], inputInfo = self.
step1WorkFlows[key]
379 wfName,stepNames= name.split(
'+',1)
382 step1,otherSteps = stepNames.split(
'+',1)
383 line = num +
' ++ '+ wfName
385 line +=
' ++ ' +otherSteps.replace(
'+',
',')
389 line +=
' ++ REALDATA: '+inputInfo.dataSet
390 line +=
', FILES: ' +str(inputInfo.files)
391 line +=
', EVENTS: '+str(inputInfo.events)
392 line +=
', LABEL: ' +inputInfo.label
393 line +=
', LOCATION:'+inputInfo.location
396 line +=
' @@@ '+stepCmds[0]
398 outFile.write(line+
'\n')
400 outFile.write(
'\n'+
'\n')
401 for stepName
in self.relvalModule.step2.keys():
402 cfg,input,cmd = self.
makeCmd(self.relvalModule.step2[stepName])
403 line =
'STEP2 ++ ' +stepName +
' @@@ cmsDriver.py step2 ' +cmd
405 outFile.write(line+
'\n')
407 outFile.write(
'\n'+
'\n')
408 for stepName
in self.relvalModule.step3.keys():
409 cfg,input,cmd = self.
makeCmd(self.relvalModule.step3[stepName])
410 line =
'STEP3 ++ ' +stepName +
' @@@ cmsDriver.py step3_RELVAL ' +cmd
412 outFile.write(line+
'\n')
414 outFile.write(
'\n'+
'\n')
415 for stepName
in self.relvalModule.step4.keys():
416 cfg,input,cmd = self.
makeCmd(self.relvalModule.step4[stepName])
417 line =
'STEP4 ++ ' +stepName +
' @@@ cmsDriver.py step4 ' +cmd
419 outFile.write(line+
'\n')
429 fmt1 =
"%-6s %-35s [1]: %s ..."
430 fmt2 =
" %35s [%d]: %s ..."
431 print "\nfound a total of ", len(self.
workFlows),
' workflows:'
433 print " of which the following", len(selected),
'were selected:'
436 fmt1 =
"%-6s %-35s [1]: %s "
437 fmt2 =
" %35s [%d]: %s"
444 if selected
and float(wf.numId)
not in selected:
continue
447 wfName, stepNames = wf.nameId.split(
'+',1)
448 print fmt1 % (wf.numId, stepNames, (wf.cmdStep1+
' ')[:maxLen])
451 print fmt2 % (
' ', 2, (wf.cmdStep2+
' ')[:maxLen])
454 print fmt2 % (
' ', 3, (wf.cmdStep3+
' ')[:maxLen])
457 print fmt2 % (
' ', 4, (wf.cmdStep4+
' ')[:maxLen])
459 print n1,
'workflows for step1,'
460 print n2,
'workflows for step1 + step2,'
461 print n3,
'workflows for step1 + step2 + step3'
462 print n4,
'workflows for step1 + step2 + step3 + step4'
471 keyList = self.step1WorkFlows.keys()
475 if pref != prefixIn :
continue
476 ids.append( float(id) )
485 num, name, cmd, step2, step3, step4, inputInfo = val
486 nameId = num+
'_'+name
487 if nameId
in self.nameList.keys():
488 print "==> duplicate name found for ", nameId
489 print ' keeping : ', self.
nameList[nameId]
490 print ' ignoring : ', val
500 if step2.lower() !=
'':
503 if step3.lower() !=
'':
506 if step4.lower() !=
'':
510 self.workFlows.append(
WorkFlow(num, name, cmd, cmd2, cmd3, cmd4, inputInfo) )
516 for matrixFile
in self.
files:
520 print "ERROR reading file:", matrixFile, str(e)
526 print "ERROR creating workflows :", str(e)
532 print '\n',
'-'*80,
'\n'
538 pickle.dump(self.
workFlows, open(
'theMatrix.pkl',
'w') )
558 if t.isAlive() : nActive += 1
565 startDir = os.getcwd()
568 if not os.environ.has_key(
'CMS_PATH'):
569 cmsPath =
'/afs/cern.ch/cms'
570 print "setting default for CMS_PATH to", cmsPath
571 os.environ[
'CMS_PATH'] = cmsPath
574 print 'Running in %s thread(s)' % self.
maxThreads
578 if testList
and float(wf.numId)
not in [float(x)
for x
in testList]:
continue
581 if os.path.islink(item) :
continue
588 print '\nPreparing to run %s %s' % (wf.numId, item)
594 self.threadList.append(current)
596 time.sleep(random.randint(1,5))
599 while self.activeThreads() > 0:
612 for pingle
in self.threadList:
615 nfail1 += pingle.nfail[0]
616 nfail2 += pingle.nfail[1]
617 nfail3 += pingle.nfail[2]
618 nfail4 += pingle.nfail[3]
619 npass1 += pingle.npass[0]
620 npass2 += pingle.npass[1]
621 npass3 += pingle.npass[2]
622 npass4 += pingle.npass[3]
623 npass += npass1+npass2+npass3+npass4
624 report += pingle.report
627 msg =
"ERROR retrieving info from thread: " + str(e)
635 report+=
'\n %s %s %s %s tests passed, %s %s %s %s failed\n' %(npass1, npass2, npass3, npass4, nfail1, nfail2, nfail3, nfail4)
638 runall_report_name=
'runall-report-step123-.log'
639 runall_report=open(runall_report_name,
'w')
640 runall_report.write(report)
641 runall_report.close()
653 mrd.showRaw(useInput)
659 def runSelected(testList, nThreads=4, show=False, useInput=None) :
672 mrd.prepare(useInput)
675 testList = stdList+hiStatList
679 mrd.show([float(x)
for x
in testList])
680 print 'selected items:', testList
683 ret = mRunnerHi.runTests(testList)
689 def runData(testList, nThreads=4, show=False, useInput=None) :
692 mrd.prepare(useInput)
696 if not testList
or testList == [
'all']:
699 mrd.show([float(x)
for x
in testList])
700 print 'selected items:', testList
703 if not testList
or testList == [
'all']:
704 ret = mRunnerHi.runTests()
706 ret = mRunnerHi.runTests(testList)
712 def runAll(testList=None, nThreads=4, show=False, useInput=None) :
715 mrd.prepare(useInput)
721 print "nThreads = ",nThreads
724 ret = mRunnerHi.runTests()
731 def runOnly(only, show, nThreads=4, useInput=None):
736 print "found request to run relvals only for ",what
737 print "not implemented, nothing done"
742 print "Usage:", sys.argv[0],
' [options] '
744 Where options is one of the following:
745 -d, --data <list> comma-separated list of workflows to use from the realdata file.
746 <list> can be "all" to select all data workflows
747 -l, --list <list> comma-separated list of workflows to use from the cmsDriver*.txt files
748 -j, --nproc <n> run <n> processes in parallel (default: 4 procs)
749 -s, --selected run a subset of 8 workflows (usually in the CustomIB)
750 -n, -q, --show show the (selected) workflows
751 -i, --useInput <list> will use data input (if defined) for the step1 instead of step1. <list> can be "all" for this option
752 -r, --raw in combination with --show will create the old style cmsDriver_*_hlt.txt file (in the working dir)
754 <list>s should be put in single- or double-quotes to avoid confusion with/by the shell
759 if __name__ ==
'__main__':
764 opts, args = getopt.getopt(sys.argv[1:],
"hj:sl:nqo:d:i:r", [
'help',
"nproc=",
'selected',
'list=',
'showMatrix',
'only=',
'data=',
'useInput=',
'raw'])
765 except getopt.GetoptError, e:
766 print "unknown option", str(e)
778 for opt, arg
in opts :
779 if opt
in (
'-h',
'--help'):
782 if opt
in (
'-j',
"--nproc" ):
784 if opt
in (
'-n',
'-q',
'--showMatrix', ):
786 if opt
in (
'-s',
'--selected',) :
788 if opt
in (
'-o',
'--only',) :
790 if opt
in (
'-l',
'--list',) :
792 if opt
in (
'-i',
'--useInput',) :
793 input = arg.split(
',')
794 if opt
in (
'-d',
'--data',) :
795 data = arg.split(
',')
796 if opt
in (
'-r',
'--raw') :
806 ret =
runSelected(testList=sel, nThreads=np, show=show, useInput=input)
808 ret =
runOnly(only=only, show=show, nThreads=np, useInput=input)
810 ret =
runData(testList=data, show=show, nThreads=np, useInput=input)
812 ret =
runAll(show=show, nThreads=np, useInput=input)