CMS 3D CMS Logo

runTheMatrix.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 from __future__ import print_function
3 import sys, os
4 
5 from Configuration.PyReleaseValidation.MatrixReader import MatrixReader
6 from Configuration.PyReleaseValidation.MatrixRunner import MatrixRunner
7 from Configuration.PyReleaseValidation.MatrixInjector import MatrixInjector,performInjectionOptionTest
8 
9 # ================================================================================
10 
11 def showRaw(opt):
12 
13  mrd = MatrixReader(opt)
14  mrd.showRaw(opt.useInput, opt.refRel, opt.fromScratch, opt.raw, opt.step1Only, selected=opt.testList)
15 
16  return 0
17 
18 # ================================================================================
19 
20 def runSelected(opt):
21 
22  mrd = MatrixReader(opt)
23  mrd.prepare(opt.useInput, opt.refRel, opt.fromScratch)
24 
25  # test for wrong input workflows
26  if opt.testList:
27  definedWf = [dwf.numId for dwf in mrd.workFlows]
28  definedSet = set(definedWf)
29  testSet = set(opt.testList)
30  undefSet = testSet - definedSet
31  if len(undefSet)>0: raise ValueError('Undefined workflows: '+', '.join(map(str,list(undefSet))))
32  duplicates = [wf for wf in testSet if definedWf.count(wf)>1 ]
33  if len(duplicates)>0: raise ValueError('Duplicated workflows: '+', '.join(map(str,list(duplicates))))
34 
35  ret = 0
36  if opt.show:
37  mrd.show(opt.testList, opt.extended, opt.cafVeto)
38  if opt.testList : print('testListected items:', opt.testList)
39  else:
40  mRunnerHi = MatrixRunner(mrd.workFlows, opt.nProcs, opt.nThreads)
41  ret = mRunnerHi.runTests(opt)
42 
43  if opt.wmcontrol:
44  if ret!=0:
45  print('Cannot go on with wmagent injection with failing workflows')
46  else:
47  wfInjector = MatrixInjector(opt,mode=opt.wmcontrol,options=opt.wmoptions)
48  ret= wfInjector.prepare(mrd,
49  mRunnerHi.runDirs)
50  if ret==0:
51  wfInjector.upload()
52  wfInjector.submit()
53  return ret
54 
55 # ================================================================================
56 
57 if __name__ == '__main__':
58 
59  #this can get out of here
60  predefinedSet={
61  'limited' : [5.1, #FastSim ttbar
62  7.3, #CosmicsSPLoose_UP17
63  8, #BH/Cosmic MC
64  25, #MC ttbar
65  4.22, #cosmic data
66  4.53, #run1 data + miniAOD
67  9.0, #Higgs200 charged taus
68  1000, #data+prompt
69  1001, #data+express
70  101.0, #SingleElectron120E120EHCAL
71  136.731, #2016B Photon data
72  136.7611, #2016E JetHT reMINIAOD from 80X legacy
73  136.8311, #2017F JetHT reMINIAOD from 94X reprocessing
74  136.88811,#2018D JetHT reMINIAOD from UL processing
75  136.793, #2017C DoubleEG
76  136.874, #2018C EGamma
77  140.53, #2011 HI data
78  140.56, #2018 HI data
79  158.01, #reMiniAOD of 2018 HI MC with pp-like reco
80  312.0, #2021/Run3 HI MC Pyquen_ZeemumuJets_pt10 with pp-like reco
81  1306.0, #SingleMu Pt1 UP15
82  1325.81, #test NanoAOD from existing MINI UL 106Xv1
83  136.8523, #test NanoAOD from existing reMINI UL 106Xv2
84  1330, #Run2 MC Zmm
85  135.4, #Run 2 Zee ttbar
86  10042.0, #2017 ZMM
87  10024.0, #2017 ttbar
88  10224.0, #2017 ttbar PU
89  10824.0, #2018 ttbar
90  11634.911, #2021 DD4hep ttbar reading geometry from XML
91  11634.912, #2021 DD4hep ttbar reading geometry from the DB
92  11634.0, #2021 ttbar
93  12434.0, #2023 ttbar
94  23234.0, #2026D49 ttbar (HLT TDR baseline w/ HGCal v11)
95  28234.0, #2026D60 (exercise HF nose)
96  34634.0, #2026D76 ttbar (2021 new baseline)
97  34834.999, #2026D76 ttbar premixing stage1+stage2, PU50
98  25202.0, #2016 ttbar UP15 PU
99  250202.181, #2018 ttbar stage1 + stage2 premix
100  ],
101  'jetmc': [5.1, 13, 15, 25, 38, 39], #MC
102  'metmc' : [5.1, 15, 25, 37, 38, 39], #MC
103  'muonmc' : [5.1, 124.4, 124.5, 20, 21, 22, 23, 25, 30], #MC
104  }
105 
106 
107  import optparse
108  usage = 'usage: runTheMatrix.py --show -s '
109 
110  parser = optparse.OptionParser(usage)
111 
112  parser.add_option('-b','--batchName',
113  help='relval batch: suffix to be appended to Campaign name',
114  dest='batchName',
115  default=''
116  )
117 
118  parser.add_option('-m','--memoryOffset',
119  help='memory of the wf for single core',
120  dest='memoryOffset',
121  default=3000
122  )
123  parser.add_option('--addMemPerCore',
124  help='increase of memory per each n > 1 core: memory(n_core) = memoryOffset + (n_core-1) * memPerCore',
125  dest='memPerCore',
126  default=1500
127  )
128  parser.add_option('-j','--nproc',
129  help='number of processes. 0 Will use 4 processes, not execute anything but create the wfs',
130  dest='nProcs',
131  default=4
132  )
133  parser.add_option('-t','--nThreads',
134  help='number of threads per process to use in cmsRun.',
135  dest='nThreads',
136  default=1
137  )
138  parser.add_option('--nStreams',
139  help='number of streams to use in cmsRun.',
140  dest='nStreams',
141  default=0
142  )
143  parser.add_option('--numberEventsInLuminosityBlock',
144  help='number of events in a luminosity block',
145  dest='numberEventsInLuminosityBlock',
146  default=-1
147  )
148 
149  parser.add_option('-n','--showMatrix',
150  help='Only show the worflows. Use --ext to show more',
151  dest='show',
152  default=False,
153  action='store_true'
154  )
155  parser.add_option('-e','--extended',
156  help='Show details of workflows, used with --show',
157  dest='extended',
158  default=False,
159  action='store_true'
160  )
161  parser.add_option('-s','--selected',
162  help='Run a pre-defined selected matrix of wf. Deprecated, please use -l limited',
163  dest='restricted',
164  default=False,
165  action='store_true'
166  )
167  parser.add_option('-l','--list',
168  help='Coma separated list of workflow to be shown or ran. Possible keys are also '+str(predefinedSet.keys())+'. and wild card like muon, or mc',
169  dest='testList',
170  default=None
171  )
172  parser.add_option('-r','--raw',
173  help='Temporary dump the .txt needed for prodAgent interface. To be discontinued soon. Argument must be the name of the set (standard, pileup,...)',
174  dest='raw'
175  )
176  parser.add_option('-i','--useInput',
177  help='Use recyling where available. Either all, or a coma separated list of wf number.',
178  dest='useInput',
179  default=None
180  )
181  parser.add_option('-w','--what',
182  help='Specify the set to be used. Argument must be the name of a set (standard, pileup,...) or multiple sets separated by commas (--what standard,pileup )',
183  dest='what',
184  default='all'
185  )
186  parser.add_option('--step1',
187  help='Used with --raw. Limit the production to step1',
188  dest='step1Only',
189  default=False
190  )
191  parser.add_option('--maxSteps',
192  help='Only run maximum on maxSteps. Used when we are only interested in first n steps.',
193  dest='maxSteps',
194  default=9999,
195  type="int"
196  )
197  parser.add_option('--fromScratch',
198  help='Coma separated list of wf to be run without recycling. all is not supported as default.',
199  dest='fromScratch',
200  default=None
201  )
202  parser.add_option('--refRelease',
203  help='Allow to modify the recycling dataset version',
204  dest='refRel',
205  default=None
206  )
207  parser.add_option('--wmcontrol',
208  help='Create the workflows for injection to WMAgent. In the WORKING. -wmcontrol init will create the the workflows, -wmcontrol test will dryRun a test, -wmcontrol submit will submit to wmagent',
209  choices=['init','test','submit','force'],
210  dest='wmcontrol',
211  default=None,
212  )
213  parser.add_option('--revertDqmio',
214  help='When submitting workflows to wmcontrol, force DQM outout to use pool and not DQMIO',
215  choices=['yes','no'],
216  dest='revertDqmio',
217  default='no',
218  )
219  parser.add_option('--optionswm',
220  help='Specify a few things for wm injection',
221  default='',
222  dest='wmoptions')
223  parser.add_option('--keep',
224  help='allow to specify for which coma separated steps the output is needed',
225  default=None)
226  parser.add_option('--label',
227  help='allow to give a special label to the output dataset name',
228  default='')
229  parser.add_option('--command',
230  help='provide a way to add additional command to all of the cmsDriver commands in the matrix',
231  dest='command',
232  default=None
233  )
234  parser.add_option('--apply',
235  help='allow to use the --command only for 1 coma separeated',
236  dest='apply',
237  default=None)
238  parser.add_option('--workflow',
239  help='define a workflow to be created or altered from the matrix',
240  action='append',
241  dest='workflow',
242  default=None
243  )
244  parser.add_option('--dryRun',
245  help='do not run the wf at all',
246  action='store_true',
247  dest='dryRun',
248  default=False
249  )
250  parser.add_option('--testbed',
251  help='workflow injection to cmswebtest (you need dedicated rqmgr account)',
252  dest='testbed',
253  default=False,
254  action='store_true'
255  )
256  parser.add_option('--noCafVeto',
257  help='Run from any source, ignoring the CAF label',
258  dest='cafVeto',
259  default=True,
260  action='store_false'
261  )
262  parser.add_option('--overWrite',
263  help='Change the content of a step for another. List of pairs.',
264  dest='overWrite',
265  default=None
266  )
267  parser.add_option('--noRun',
268  help='Remove all run list selection from wfs',
269  dest='noRun',
270  default=False,
271  action='store_true')
272 
273  parser.add_option('--das-options',
274  help='Options to be passed to dasgoclient.',
275  dest='dasOptions',
276  default="--limit 0",
277  action='store')
278 
279  parser.add_option('--job-reports',
280  help='Dump framework job reports',
281  dest='jobReports',
282  default=False,
283  action='store_true')
284 
285  parser.add_option('--ibeos',
286  help='Use IB EOS site configuration',
287  dest='IBEos',
288  default=False,
289  action='store_true')
290 
291  parser.add_option('--sites',
292  help='Run DAS query to get data from a specific site (default is T2_CH_CERN). Set it to empty string to search all sites.',
293  dest='dasSites',
294  default='T2_CH_CERN',
295  action='store')
296  parser.add_option('--interactive',
297  help="Open the Matrix interactive shell",
298  action='store_true',
299  default=False)
300 
301  parser.add_option('--dbs-url',
302  help='Overwrite DbsUrl value in JSON submitted to ReqMgr2',
303  dest='dbsUrl',
304  default=None,
305  action='store')
306 
307  opt,args = parser.parse_args()
308  os.environ["CMSSW_DAS_QUERY_SITES"]=opt.dasSites
309  if opt.IBEos:
310  try:from commands import getstatusoutput as run_cmd
311  except:from subprocess import getstatusoutput as run_cmd
312 
313  ibeos_cache = os.path.join(os.getenv("LOCALRT"), "ibeos_cache.txt")
314  if not os.path.exists(ibeos_cache):
315  err, out = run_cmd("curl -L -s -o %s https://raw.githubusercontent.com/cms-sw/cms-sw.github.io/master/das_queries/ibeos.txt" % ibeos_cache)
316  if err:
317  run_cmd("rm -f %s" % ibeos_cache)
318  print("Error: Unable to download ibeos cache information")
319  print(out)
320  sys.exit(err)
321 
322  for cmssw_env in [ "CMSSW_BASE", "CMSSW_RELEASE_BASE" ]:
323  cmssw_base = os.getenv(cmssw_env,None)
324  if not cmssw_base: continue
325  cmssw_base = os.path.join(cmssw_base,"src/Utilities/General/ibeos")
326  if os.path.exists(cmssw_base):
327  os.environ["PATH"]=cmssw_base+":"+os.getenv("PATH")
328  os.environ["CMS_PATH"]="/cvmfs/cms-ib.cern.ch"
329  os.environ["CMSSW_USE_IBEOS"]="true"
330  print(">> WARNING: You are using SITECONF from /cvmfs/cms-ib.cern.ch")
331  break
332  if opt.restricted:
333  print('Deprecated, please use -l limited')
334  if opt.testList: opt.testList+=',limited'
335  else: opt.testList='limited'
336 
337  def stepOrIndex(s):
338  if s.isdigit():
339  return int(s)
340  else:
341  return s
342  if opt.apply:
343  opt.apply=map(stepOrIndex,opt.apply.split(','))
344  if opt.keep:
345  opt.keep=map(stepOrIndex,opt.keep.split(','))
346 
347 
348 
349  if opt.testList:
350  testList=[]
351  for entry in opt.testList.split(','):
352  if not entry: continue
353  mapped=False
354  for k in predefinedSet:
355  if k.lower().startswith(entry.lower()) or k.lower().endswith(entry.lower()):
356  testList.extend(predefinedSet[k])
357  mapped=True
358  break
359  if not mapped:
360  try:
361  testList.append(float(entry))
362  except:
363  print(entry,'is not a possible selected entry')
364 
365  opt.testList = list(set(testList))
366 
367 
368  if opt.useInput: opt.useInput = opt.useInput.split(',')
369  if opt.fromScratch: opt.fromScratch = opt.fromScratch.split(',')
370  if opt.nProcs: opt.nProcs=int(opt.nProcs)
371  if opt.nThreads: opt.nThreads=int(opt.nThreads)
372  if opt.nStreams: opt.nStreams=int(opt.nStreams)
373  if (opt.numberEventsInLuminosityBlock): opt.numberEventsInLuminosityBlock=int(opt.numberEventsInLuminosityBlock)
374  if (opt.memoryOffset): opt.memoryOffset=int(opt.memoryOffset)
375  if (opt.memPerCore): opt.memPerCore=int(opt.memPerCore)
376 
377  if opt.wmcontrol:
379  if opt.overWrite:
380  opt.overWrite=eval(opt.overWrite)
381  if opt.interactive:
382  import cmd
383 
384  class TheMatrix(cmd.Cmd):
385  intro = "Welcome to the Matrix (? for help)"
386  prompt = "matrix> "
387 
388  def __init__(self, opt):
389  cmd.Cmd.__init__(self)
390  self.opt_ = opt
391  self.matrices_ = {}
392  tmp = MatrixReader(self.opt_)
393  for what in tmp.files:
394  self.opt_.what = what
395  self.matrices_[what] = MatrixReader(self.opt_)
396  self.matrices_[what].prepare(self.opt_.useInput, self.opt_.refRel,
397  self.opt_.fromScratch)
398  os.system("clear")
399 
400  def do_clear(self, arg):
401  """Clear the screen, put prompt at the top"""
402  os.system("clear")
403 
404  def do_exit(self, arg):
405  print("Leaving the Matrix")
406  return True
407 
408  def default(self, inp):
409  if inp == 'x' or inp == 'q':
410  return self.do_exit(inp)
411 
412  def help_predefined(self):
413  print("\n".join(["predefined [predef1 [...]]\n",
414  "Run w/o argument, it will print the list of known predefined workflows.",
415  "Run with space-separated predefined workflows, it will print the workflow-ids registered to them"]))
416 
417  def complete_predefined(self, text, line, start_idx, end_idx):
418  if text and len(text) > 0:
419  return [t for t in predefinedSet.keys() if t.startswith(text)]
420  else:
421  return predefinedSet.keys()
422 
423  def do_predefined(self, arg):
424  """Print the list of predefined workflows"""
425  print("List of predefined workflows")
426  if arg:
427  for w in arg.split():
428  if w in predefinedSet.keys():
429  print("Predefined Set: %s" % w)
430  print(predefinedSet[w])
431  else:
432  print("Unknown Set: %s" % w)
433  else:
434  print(predefinedSet.keys())
435 
436  def help_showWorkflow(self):
437  print("\n".join(["showWorkflow [workflow1 [...]]\n",
438  "Run w/o arguments, it will print the list of registered macro-workflows.",
439  "Run with space-separated workflows, it will print the full list of workflow-ids registered to them"]))
440 
441  def complete_showWorkflow(self, text, line, start_idx, end_idx):
442  if text and len(text) > 0:
443  return [t for t in self.matrices_.keys() if t.startswith(text)]
444  else:
445  return self.matrices_.keys()
446 
447  def do_showWorkflow(self, arg):
448  if arg == '':
449  print("Available workflows:")
450  for k in self.matrices_.keys():
451  print(k)
452  else:
453  selected = arg.split()
454  for k in selected:
455  if k not in self.matrices_.keys():
456  print("Unknown workflow %s: skipping" % k)
457  else:
458  for wfl in self.matrices_[k].workFlows:
459  wfName, stepNames = wfl.nameId.split('+',1)
460  print("%s %s %s" % (wfl.numId, wfName, stepNames))
461  print("%s contains %d workflows" % (k, len(self.matrices_[k].workFlows)))
462 
464  print("\n".join(["searchInWorkflow wfl_name search_regexp\n",
465  "This command will search for a match within all workflows registered to wfl_name.",
466  "The search is done on both the workflow name and the names of steps registered to it."]))
467 
468  def complete_searchInWorkflow(self, text, line, start_idx, end_idx):
469  if text and len(text) > 0:
470  return [t for t in self.matrices_.keys() if t.startswith(text)]
471  else:
472  return self.matrices_.keys()
473 
474  def do_searchInWorkflow(self, arg):
475  args = arg.split()
476  if len(args) < 2:
477  print("searchInWorkflow name regexp")
478  return
479  if args[0] not in self.matrices_.keys():
480  print("Unknown workflow")
481  return
482  import re
483  pattern = None
484  try:
485  pattern = re.compile(args[1])
486  except:
487  print("Failed to compile regexp %s" % args[1])
488  return
489  counter = 0
490  for wfl in self.matrices_[args[0]].workFlows:
491  wfName, stepNames = wfl.nameId.split('+',1)
492  if re.match(pattern, wfName) or re.match(pattern, stepNames):
493  print("%s %s %s" % (wfl.numId, wfName, stepNames))
494  counter += 1
495  print("Found %d compatible workflows inside %s" % (counter, args[0]))
496 
497  def help_search(self):
498  print("\n".join(["search search_regexp\n",
499  "This command will search for a match within all workflows registered.",
500  "The search is done on both the workflow name and the names of steps registered to it."]))
501 
502  def do_search(self, arg):
503  args = arg.split()
504  if len(args) < 1:
505  print("search regexp")
506  return
507  for wfl in self.matrices_.keys():
508  self.do_searchInWorkflow(' '.join([wfl, args[0]]))
509 
511  print("\n".join(["dumpWorkflowId [wfl-id1 [...]]\n",
512  "Dumps the details (cmsDriver commands for all steps) of the space-separated workflow-ids in input."]))
513 
514  def do_dumpWorkflowId(self, arg):
515  wflids = arg.split()
516  if len(wflids) == 0:
517  print("dumpWorkflowId [wfl-id1 [...]]")
518  return
519 
520  fmt = "[%d]: %s\n"
521  maxLen = 100
522  for wflid in wflids:
523  dump = True
524  for key, mrd in self.matrices_.iteritems():
525  for wfl in mrd.workFlows:
526  if wfl.numId == float(wflid):
527  wfName, stepNames = wfl.nameId.split('+',1)
528  if dump:
529  dump = False
530  print(wfl.numId, stepNames)
531  for i,s in enumerate(wfl.cmds):
532  print(fmt % (i+1, (str(s)+' ')))
533  print("\nWorkflow found in %s." % key)
534  else:
535  print("Workflow also found in %s." % key)
536 
537  do_EOF = do_exit
538 
539  TheMatrix(opt).cmdloop()
540  sys.exit(0)
541 
542  if opt.raw and opt.show:
543  ret = showRaw(opt)
544  else:
545  ret = runSelected(opt)
546 
547 
548  sys.exit(ret)
runTheMatrix.TheMatrix.help_predefined
def help_predefined(self)
Definition: runTheMatrix.py:412
MatrixReader
Definition: MatrixReader.py:1
dqmMemoryStats.float
float
Definition: dqmMemoryStats.py:127
runTheMatrix.TheMatrix.__init__
def __init__(self, opt)
Definition: runTheMatrix.py:388
runTheMatrix.TheMatrix.complete_searchInWorkflow
def complete_searchInWorkflow(self, text, line, start_idx, end_idx)
Definition: runTheMatrix.py:468
runTheMatrix.TheMatrix.do_exit
def do_exit(self, arg)
Definition: runTheMatrix.py:404
runTheMatrix.TheMatrix.do_searchInWorkflow
def do_searchInWorkflow(self, arg)
Definition: runTheMatrix.py:474
runTheMatrix.TheMatrix.help_searchInWorkflow
def help_searchInWorkflow(self)
Definition: runTheMatrix.py:463
runTheMatrix.TheMatrix.do_predefined
def do_predefined(self, arg)
Definition: runTheMatrix.py:423
runTheMatrix.TheMatrix.help_search
def help_search(self)
Definition: runTheMatrix.py:497
join
static std::string join(char **cmd)
Definition: RemoteFile.cc:17
MatrixRunner
Definition: MatrixRunner.py:1
runTheMatrix.TheMatrix.help_dumpWorkflowId
def help_dumpWorkflowId(self)
Definition: runTheMatrix.py:510
relativeConstraints.keys
keys
Definition: relativeConstraints.py:89
runTheMatrix.TheMatrix
Definition: runTheMatrix.py:384
runTheMatrix.TheMatrix.matrices_
matrices_
Definition: runTheMatrix.py:391
runTheMatrix.showRaw
def showRaw(opt)
Definition: runTheMatrix.py:11
runTheMatrix.runSelected
def runSelected(opt)
Definition: runTheMatrix.py:20
runTheMatrix.TheMatrix.do_clear
def do_clear(self, arg)
Definition: runTheMatrix.py:400
runTheMatrix.TheMatrix.do_dumpWorkflowId
def do_dumpWorkflowId(self, arg)
Definition: runTheMatrix.py:514
str
#define str(s)
Definition: TestProcessor.cc:53
runTheMatrix.TheMatrix.complete_predefined
def complete_predefined(self, text, line, start_idx, end_idx)
Definition: runTheMatrix.py:417
print
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:46
runTheMatrix.TheMatrix.default
def default(self, inp)
Definition: runTheMatrix.py:408
runTheMatrix.TheMatrix.do_showWorkflow
def do_showWorkflow(self, arg)
Definition: runTheMatrix.py:447
createfilelist.int
int
Definition: createfilelist.py:10
runTheMatrix.TheMatrix.complete_showWorkflow
def complete_showWorkflow(self, text, line, start_idx, end_idx)
Definition: runTheMatrix.py:441
MatrixInjector.performInjectionOptionTest
def performInjectionOptionTest(opt)
Definition: MatrixInjector.py:12
MatrixInjector
Definition: MatrixInjector.py:1
runTheMatrix.TheMatrix.opt_
opt_
Definition: runTheMatrix.py:390
runTheMatrix.TheMatrix.help_showWorkflow
def help_showWorkflow(self)
Definition: runTheMatrix.py:436
genParticles_cff.map
map
Definition: genParticles_cff.py:11
runTheMatrix.TheMatrix.do_search
def do_search(self, arg)
Definition: runTheMatrix.py:502
runTheMatrix.stepOrIndex
def stepOrIndex(s)
Definition: runTheMatrix.py:337