CMS 3D CMS Logo

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