2 from __future__
import print_function
5 from Configuration.PyReleaseValidation.MatrixReader
import MatrixReader
6 from Configuration.PyReleaseValidation.MatrixRunner
import MatrixRunner
7 from Configuration.PyReleaseValidation.MatrixInjector
import MatrixInjector,performInjectionOptionTest
14 mrd.showRaw(opt.useInput, opt.refRel, opt.fromScratch, opt.raw, opt.step1Only, selected=opt.testList)
23 mrd.prepare(opt.useInput, opt.refRel, opt.fromScratch)
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))))
37 mrd.show(opt.testList, opt.extended, opt.cafVeto)
38 if opt.testList :
print(
'testListected items:', opt.testList)
40 mRunnerHi =
MatrixRunner(mrd.workFlows, opt.nProcs, opt.nThreads)
41 ret = mRunnerHi.runTests(opt)
45 print(
'Cannot go on with wmagent injection with failing workflows')
47 wfInjector =
MatrixInjector(opt,mode=opt.wmcontrol,options=opt.wmoptions)
48 ret= wfInjector.prepare(mrd,
57 if __name__ ==
'__main__':
109 'jetmc': [5.1, 13, 15, 25, 38, 39],
110 'metmc' : [5.1, 15, 25, 37, 38, 39],
111 'muonmc' : [5.1, 124.4, 124.5, 20, 21, 22, 23, 25, 30],
116 usage =
'usage: runTheMatrix.py --show -s ' 118 parser = argparse.ArgumentParser(usage,formatter_class=argparse.ArgumentDefaultsHelpFormatter)
120 parser.add_argument(
'-b',
'--batchName',
121 help=
'relval batch: suffix to be appended to Campaign name',
125 parser.add_argument(
'-m',
'--memoryOffset',
126 help=
'memory of the wf for single core',
131 parser.add_argument(
'--addMemPerCore',
132 help=
'increase of memory per each n > 1 core: memory(n_core) = memoryOffset + (n_core-1) * memPerCore',
137 parser.add_argument(
'-j',
'--nproc',
138 help=
'number of processes. 0 Will use 4 processes, not execute anything but create the wfs',
143 parser.add_argument(
'-t',
'--nThreads',
144 help=
'number of threads per process to use in cmsRun.',
149 parser.add_argument(
'--nStreams',
150 help=
'number of streams to use in cmsRun.',
155 parser.add_argument(
'--nEvents',
156 help=
'number of events to process in cmsRun. If 0 will use the standard 10 events.',
161 parser.add_argument(
'--numberEventsInLuminosityBlock',
162 help=
'number of events in a luminosity block',
163 dest=
'numberEventsInLuminosityBlock',
167 parser.add_argument(
'-n',
'--showMatrix',
168 help=
'Only show the worflows. Use --ext to show more',
173 parser.add_argument(
'-e',
'--extended',
174 help=
'Show details of workflows, used with --show',
179 parser.add_argument(
'-s',
'--selected',
180 help=
'Run a pre-defined selected matrix of wf. Deprecated, please use -l limited',
185 parser.add_argument(
'-l',
'--list',
186 help=
'Comma separated list of workflow to be shown or ran. Possible keys are also '+
str(predefinedSet.keys())+
'. and wild card like muon, or mc',
190 parser.add_argument(
'-f',
'--failed-from',
191 help=
'Provide a matrix report to specify the workflows to be run again. Augments the -l option if specified already',
195 parser.add_argument(
'-r',
'--raw',
196 help=
'Temporary dump the .txt needed for prodAgent interface. To be discontinued soon. Argument must be the name of the set (standard, pileup,...)',
199 parser.add_argument(
'-i',
'--useInput',
200 help=
'Use recyling where available. Either all, or a comma separated list of wf number.',
202 type=
lambda x: x.split(
','),
205 parser.add_argument(
'-w',
'--what',
206 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 )',
210 parser.add_argument(
'--step1',
211 help=
'Used with --raw. Limit the production to step1',
215 parser.add_argument(
'--maxSteps',
216 help=
'Only run maximum on maxSteps. Used when we are only interested in first n steps.',
221 parser.add_argument(
'--fromScratch',
222 help=
'Comma separated list of wf to be run without recycling. all is not supported as default.',
224 type=
lambda x: x.split(
','),
227 parser.add_argument(
'--refRelease',
228 help=
'Allow to modify the recycling dataset version',
232 parser.add_argument(
'--wmcontrol',
233 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',
234 choices=[
'init',
'test',
'submit',
'force'],
238 parser.add_argument(
'--revertDqmio',
239 help=
'When submitting workflows to wmcontrol, force DQM outout to use pool and not DQMIO',
240 choices=[
'yes',
'no'],
244 parser.add_argument(
'--optionswm',
245 help=
'Specify a few things for wm injection',
249 parser.add_argument(
'--keep',
250 help=
'allow to specify for which comma separated steps the output is needed',
253 parser.add_argument(
'--label',
254 help=
'allow to give a special label to the output dataset name',
257 parser.add_argument(
'--command',
258 help=
'provide a way to add additional command to all of the cmsDriver commands in the matrix',
263 parser.add_argument(
'--apply',
264 help=
'allow to use the --command only for 1 comma separeated',
268 parser.add_argument(
'--workflow',
269 help=
'define a workflow to be created or altered from the matrix',
274 parser.add_argument(
'--dryRun',
275 help=
'do not run the wf at all',
280 parser.add_argument(
'--testbed',
281 help=
'workflow injection to cmswebtest (you need dedicated rqmgr account)',
286 parser.add_argument(
'--noCafVeto',
287 help=
'Run from any source, ignoring the CAF label',
290 action=
'store_false')
292 parser.add_argument(
'--overWrite',
293 help=
'Change the content of a step for another. List of pairs.',
297 parser.add_argument(
'--noRun',
298 help=
'Remove all run list selection from wfs',
303 parser.add_argument(
'--das-options',
304 help=
'Options to be passed to dasgoclient.',
309 parser.add_argument(
'--job-reports',
310 help=
'Dump framework job reports',
315 parser.add_argument(
'--ibeos',
316 help=
'Use IB EOS site configuration',
321 parser.add_argument(
'--sites',
322 help=
'Run DAS query to get data from a specific site. Set it to empty string to search all sites.',
324 default=
'T2_CH_CERN',
327 parser.add_argument(
'--interactive',
328 help=
"Open the Matrix interactive shell",
332 parser.add_argument(
'--dbs-url',
333 help=
'Overwrite DbsUrl value in JSON submitted to ReqMgr2',
338 gpugroup = parser.add_argument_group(
'GPU-related options',
'These options are only meaningful when --gpu is used, and is not set to forbidden.')
340 gpugroup.add_argument(
'--gpu',
'--requires-gpu',
341 help=
'Enable GPU workflows. Possible options are "forbidden" (default), "required" (implied if no argument is given), or "optional".',
343 choices=[
'forbidden',
'optional',
'required'],
349 gpugroup.add_argument(
'--gpu-memory',
350 help=
'Specify the minimum amount of GPU memory required by the job, in MB.',
355 gpugroup.add_argument(
'--cuda-capabilities',
356 help=
'Specify a comma-separated list of CUDA "compute capabilities", or GPU hardware architectures, that the job can use.',
357 dest=
'CUDACapabilities',
358 type=
lambda x: x.split(
','),
359 default=
'6.0,6.1,6.2,7.0,7.2,7.5,8.0,8.6')
362 cudart_version =
None 363 libcudart = os.path.realpath(os.path.expandvars(
'$CMSSW_RELEASE_BASE/external/$SCRAM_ARCH/lib/libcudart.so'))
364 if os.path.isfile(libcudart):
365 cudart_basename = os.path.basename(libcudart)
366 cudart_version =
'.'.
join(cudart_basename.split(
'.')[2:4])
367 gpugroup.add_argument(
'--cuda-runtime',
368 help=
'Specify major and minor version of the CUDA runtime used to build the application.',
370 default=cudart_version)
372 gpugroup.add_argument(
'--force-gpu-name',
373 help=
'Request a specific GPU model, e.g. "Tesla T4" or "NVIDIA GeForce RTX 2080". The default behaviour is to accept any supported GPU.',
377 gpugroup.add_argument(
'--force-cuda-driver-version',
378 help=
'Request a specific CUDA driver version, e.g. 470.57.02. The default behaviour is to accept any supported CUDA driver version.',
379 dest=
'CUDADriverVersion',
382 gpugroup.add_argument(
'--force-cuda-runtime-version',
383 help=
'Request a specific CUDA runtime version, e.g. 11.4. The default behaviour is to accept any supported CUDA runtime version.',
384 dest=
'CUDARuntimeVersion',
387 opt = parser.parse_args()
388 if opt.command: opt.command =
' '.
join(opt.command)
389 os.environ[
"CMSSW_DAS_QUERY_SITES"]=opt.dasSites
392 with open(opt.failed_from,
'r') as report: 393 for report_line
in report:
394 if 'FAILED' in report_line:
395 to_run,_=report_line.split(
'_',1)
396 rerunthese.append(to_run)
398 opt.testList+=
','.
join([
'']+rerunthese)
400 opt.testList =
','.
join(rerunthese)
403 from subprocess
import getstatusoutput
as run_cmd
405 ibeos_cache = os.path.join(os.getenv(
"LOCALRT"),
"ibeos_cache.txt")
406 if not os.path.exists(ibeos_cache):
407 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)
409 run_cmd(
"rm -f %s" % ibeos_cache)
410 print(
"Error: Unable to download ibeos cache information")
414 for cmssw_env
in [
"CMSSW_BASE",
"CMSSW_RELEASE_BASE" ]:
415 cmssw_base = os.getenv(cmssw_env,
None)
416 if not cmssw_base:
continue 417 cmssw_base = os.path.join(cmssw_base,
"src/Utilities/General/ibeos")
418 if os.path.exists(cmssw_base):
419 os.environ[
"PATH"]=cmssw_base+
":"+os.getenv(
"PATH")
420 os.environ[
"CMS_PATH"]=
"/cvmfs/cms-ib.cern.ch" 421 os.environ[
"SITECONFIG_PATH"]=
"/cvmfs/cms-ib.cern.ch/SITECONF/local" 422 os.environ[
"CMSSW_USE_IBEOS"]=
"true" 423 print(
">> WARNING: You are using SITECONF from /cvmfs/cms-ib.cern.ch")
426 print(
'Deprecated, please use -l limited')
427 if opt.testList: opt.testList+=
',limited' 428 else: opt.testList=
'limited' 436 opt.apply=
map(stepOrIndex,opt.apply.split(
','))
438 opt.keep=
map(stepOrIndex,opt.keep.split(
','))
442 for entry
in opt.testList.split(
','):
443 if not entry:
continue 445 for k
in predefinedSet:
446 if k.lower().startswith(entry.lower())
or k.lower().endswith(entry.lower()):
447 testList.extend(predefinedSet[k])
452 testList.append(
float(entry))
454 print(entry,
'is not a possible selected entry')
456 opt.testList = list(set(testList))
461 opt.overWrite=eval(opt.overWrite)
464 from colorama
import Fore, Style
465 from os
import isatty
468 intro =
"Welcome to the Matrix (? for help)" 472 cmd.Cmd.__init__(self)
476 for what
in tmp.files:
477 what = what.replace(
'relval_',
'')
478 self.
opt_.what = what
481 self.
opt_.fromScratch)
485 """Clear the screen, put prompt at the top""" 489 print(
"Leaving the Matrix")
493 if inp ==
'x' or inp ==
'q':
496 is_pipe =
not isatty(sys.stdin.fileno())
497 print(Fore.RED +
"Error: " + Fore.RESET +
"unrecognized command.")
503 print(
"\n".
join([
"predefined [predef1 [...]]\n",
504 "Run w/o argument, it will print the list of known predefined workflows.",
505 "Run with space-separated predefined workflows, it will print the workflow-ids registered to them"]))
508 if text
and len(text) > 0:
509 return [t
for t
in predefinedSet.keys()
if t.startswith(text)]
511 return predefinedSet.keys()
514 """Print the list of predefined workflows""" 515 print(
"List of predefined workflows")
517 for w
in arg.split():
518 if w
in predefinedSet.keys():
519 print(
"Predefined Set: %s" % w)
520 print(predefinedSet[w])
522 print(
"Unknown Set: %s" % w)
524 print(
"[ " + Fore.RED +
", ".
join([
str(k)
for k
in predefinedSet.keys()]) + Fore.RESET +
" ]")
527 print(
"\n".
join([
"showWorkflow [workflow1 [...]]\n",
528 "Run w/o arguments, it will print the list of registered macro-workflows.",
529 "Run with space-separated workflows, it will print the full list of workflow-ids registered to them"]))
532 if text
and len(text) > 0:
533 return [t
for t
in self.
matrices_.
keys()
if t.startswith(text)]
539 print(
"Available workflows:")
541 print(Fore.RED + Style.BRIGHT + k)
542 print(Style.RESET_ALL)
544 selected = arg.split()
547 print(
"Unknown workflow %s: skipping" % k)
550 print(
"%s %s" % (Fore.BLUE +
str(wfl.numId) + Fore.RESET,
551 Fore.GREEN + wfl.nameId + Fore.RESET))
552 print(
"%s contains %d workflows" % (Fore.RED + k + Fore.RESET, len(self.
matrices_[k].workFlows)))
555 print(
"\n".
join([
"searchInWorkflow wfl_name search_regexp\n",
556 "This command will search for a match within all workflows registered to wfl_name.",
557 "The search is done on both the workflow name and the names of steps registered to it."]))
560 if text
and len(text) > 0:
561 return [t
for t
in self.
matrices_.
keys()
if t.startswith(text)]
568 print(
"searchInWorkflow name regexp")
571 print(
"Unknown workflow")
576 pattern = re.compile(args[1])
578 print(
"Failed to compile regexp %s" % args[1])
581 for wfl
in self.
matrices_[args[0]].workFlows:
582 if re.match(pattern, wfl.nameId):
583 print(
"%s %s" % (Fore.BLUE +
str(wfl.numId) + Fore.RESET,
584 Fore.GREEN + wfl.nameId + Fore.RESET))
586 print(
"Found %s compatible workflows inside %s" % (Fore.RED +
str(counter) + Fore.RESET,
587 Fore.YELLOW +
str(args[0])) + Fore.RESET)
590 print(
"\n".
join([
"search search_regexp\n",
591 "This command will search for a match within all workflows registered.",
592 "The search is done on both the workflow name and the names of steps registered to it."]))
597 print(
"search regexp")
603 print(
"\n".
join([
"dumpWorkflowId [wfl-id1 [...]]\n",
604 "Dumps the details (cmsDriver commands for all steps) of the space-separated workflow-ids in input."]))
609 print(
"dumpWorkflowId [wfl-id1 [...]]")
617 for wfl
in mrd.workFlows:
618 if wfl.numId ==
float(wflid):
621 print(Fore.GREEN +
str(wfl.numId) + Fore.RESET +
" " + Fore.YELLOW + wfl.nameId + Fore.RESET)
622 for i,s
in enumerate(wfl.cmds):
623 print(fmt % (Fore.RED +
str(i+1) + Fore.RESET,
625 print(
"\nWorkflow found in %s." % key)
627 print(
"Workflow also found in %s." % key)
634 if opt.raw
and opt.show:
def performInjectionOptionTest(opt)
def do_predefined(self, arg)
def do_showWorkflow(self, arg)
def complete_showWorkflow(self, text, line, start_idx, end_idx)
def help_showWorkflow(self)
def help_dumpWorkflowId(self)
def complete_predefined(self, text, line, start_idx, end_idx)
def help_searchInWorkflow(self)
def do_dumpWorkflowId(self, arg)
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
def help_predefined(self)
static std::string join(char **cmd)
def complete_searchInWorkflow(self, text, line, start_idx, end_idx)
def do_searchInWorkflow(self, arg)