2This module contains functions usefull to build scripts around the pyfortool library
6from multiprocessing
import cpu_count, Pool
7from multiprocessing.managers
import BaseManager
18from pyfortool
import __version__
23 Function to use on each file
24 :param clsPYFT: PYFT class to use
25 :param filename: file name
29 allArgs, orderedOptions = allFileArgs[filename]
32 with PYFT(filename, filename, parser=allArgs.parser,
35 enableCache=allArgs.enableCache)
as pft:
38 for arg
in orderedOptions:
39 logging.debug(
'Applying %s on %s', arg, filename)
41 filename
if filename == allArgs.plotCentralFile
else None)
42 logging.debug(
' -> Done')
45 if not allArgs.dryRun:
51 except Exception
as exc:
52 logging.error(
"The following error has occurred in the file %s", filename)
53 traceback.print_exception(exc, file=sys.stdout)
60 Core of the pyfortool_parallel.py command
63 class MyManager(BaseManager):
65 Custom manager to deal with Tree instances
68 MyManager.register(
'Tree', Tree)
81 parser = argparse.ArgumentParser(description=
'Python FORTRAN tool', allow_abbrev=
False,
82 epilog=
"The argument order matters.")
84 updateParser(parser, withInput=
False, withOutput=
False, withXml=
False, withPlotCentralFile=
True,
85 treeIsOptional=
False, nbPar=
True, restrictScope=
False)
86 commonArgs, getFileArgs =
getArgs(parser)
89 with MyManager()
as manager:
94 PYFT.setParallel(sharedTree)
97 allFileArgs = {file: getFileArgs(file)
for file
in sharedTree.getFiles()}
98 logging.info(
'Executing in parallel on %i files with a maximum of %i processes',
99 len(allFileArgs), commonArgs.nbPar)
100 with Pool(commonArgs.nbPar, initializer=init, initargs=(PYFT, allFileArgs))
as pool:
101 result = pool.map(task, sharedTree.getFiles())
104 sharedTree.toJson(commonArgs.descTree)
107 errors = [item[1]
for item
in result
if item[0] != 0]
110 logging.error(
'List of files with error:')
112 logging.error(
' - %s', error)
113 raise PYFTError(f
"Errors have been reported in {status} file(s).")
118 Core of the pyfortool.py command
120 parser = argparse.ArgumentParser(description=
'Python FORTRAN tool', allow_abbrev=
False,
121 epilog=
"The argument order matters.")
123 updateParser(parser, withInput=
True, withOutput=
True, withXml=
True, withPlotCentralFile=
False,
124 treeIsOptional=
True, nbPar=
False, restrictScope=
True)
125 args, orderedOptions =
getArgs(parser)[1]()
132 pft =
PYFT(args.INPUT, args.OUTPUT, parser=args.parser, parserOptions=parserOptions,
133 verbosity=args.logLevel, wrapH=args.wrapH, tree=descTree,
134 enableCache=args.enableCache)
135 if args.restrictScope !=
'':
136 pft = pft.getScopeNode(args.restrictScope)
139 for arg
in orderedOptions:
140 logging.debug(
'Applying %s on %s', arg, args.INPUT)
141 applyTransfo(pft, arg, args, plotCentralFile=args.INPUT)
142 logging.debug(
' -> Done')
145 if descTree
is not None:
146 descTree.toJson(args.descTree)
147 if args.xml
is not None:
148 pft.mainScope.writeXML(args.xml)
150 pft.mainScope.write()
153 pft.mainScope.close()
157 logging.error(
"The following error has occurred in the file %s", args.INPUT)
161ARG_UPDATE_CNT = (
'--alignContinuation',
'--addBeginContinuation',
162 '--removeBeginContinuation',
163 '--emoveALLContinuation')
168 Parse arguments and interpret the --optsByEnv option
169 :param parser: argparse parser
170 :return: a tuple with
171 - an argparse namespace containing common arguments (not using the --optsEnv option)
172 - a function taking a filename as input and returning
173 - an argparse namespace with the common arguments and the ones added by
174 interpreting the --optsEnv option
175 - an ordered list of arguments
177 args = parser.parse_args()
179 def getFileArgs(filename=args.INPUT if hasattr(args,
'INPUT')
else None):
181 :param filename: name of source code file
182 :return: argparse namespace to use with this file and
183 a list given the order in which the arguments were provided
186 arguments = sys.argv[1:]
187 if args.optsByEnv
is not None:
189 for line
in []
if args.optsByEnv
is None else os.environ[args.optsByEnv].split(
'\n'):
191 if re.match(line.split(
':=:')[0], filename):
192 extra = line.split(
':=:')[1]
195 arguments.extend(shlex.split(extra))
200 for arg
in arguments:
201 if arg.startswith(
'--')
and arg
not in optList:
202 if arg
in ARG_UPDATE_CNT:
209 return parser.parse_args(arguments), optList
211 return args, getFileArgs
216 Get the options to use for the fxtran parser
217 :param args: arguments parsed by the argparse parser
219 if args.parserOption
is None:
220 parserOptions = PYFT.DEFAULT_FXTRAN_OPTIONS.copy()
222 parserOptions = [el
for elements
in args.parserOption
for el
in elements]
224 parserOptions = [opt
for opt
in parserOptions
if opt
not in (
'-no-include',
'-noinclude')]
230 get the Tree object built with the parsed arguments
231 :param args: arguments parsed by the argparse parser
232 :param cls: class to use (usefull for manager)
233 :return: a Tree instance
237 descTree = cls(tree=args.tree, descTreeFile=args.descTree,
238 parser=args.parser, parserOptions=parserOptions,
239 wrapH=args.wrapH, verbosity=args.logLevel)
245def updateParser(parser, withInput, withOutput, withXml, withPlotCentralFile, treeIsOptional,
246 nbPar, restrictScope):
248 Updates an argparse parser with arguments common to all the different tools
249 :param parser: parser in which arguments are added
250 :param withOutput: do we need the INPUT argument
251 :param withOutput: do we need the OUTPUT argument
252 :param withXml: do we need to be able to define an XML output file
253 :param withPlotCentralFile: to add the --plotCentralFile argument
254 :param treeIsOptional: is the --tree argument optional?
255 :param nbPar: number of parallel processes
256 :param restrictScope: can we specify the scope path
267 assert not parser.allow_abbrev,
'parser must be created with allow_abbrev=False'
269 parser.add_argument(
'--version', action=
'version',
270 version=
'%(prog)s {version}'.format(version=__version__))
271 parser.add_argument(
'--simplify', default=
False, action=
'store_true',
272 help=
'After a deletion, recursively deletes the code ' +
273 'and variables that have become useless')
274 parser.add_argument(
'--logLevel', default=
'warning',
275 help=
'Provide logging level. Example --logLevel debug (default is warning)')
276 parser.add_argument(
'--enableCache', default=
False, action=
'store_true',
277 help=
'Precompute parent of each xml node and store the result')
279 parser.add_argument(
'--nbPar', default=cpu_count(), type=int,
280 help=
'Number of parallel processes, 0 to get as many processes ' +
281 'as the number of cores (default=0)')
282 parser.add_argument(
'--optsByEnv', default=
None, type=str,
283 help=
'Name of the environment variable containing additional arguments ' +
284 'to use. These arguments are processed after all other arguments. ' +
285 'The variable can contain a multi-lines string. The ' +
286 'variable is read line by line and the last applicable line is ' +
287 'used. A line can take one of these two forms: ' +
288 '1) "FILE_DESCRIPTOR:=:OPTIONS" (where FILE_DESCRIPTOR is a ' +
289 'regular expression to test against the filename. If there ' +
290 'is a match, the OPTIONS can be used for the file) and ' +
291 '2) "OPTIONS" (if the line doesn\'t contain the FILE_DESCRIPTOR ' +
292 'part, it applies to all source code).')
295 parser.add_argument(
'--restrictScope', default=
'', type=str, metavar=
'SCOPEPATH',
296 help=
"Limit the action to this scope path (SUBROUTINE/FUNCTION/" +
297 "MODULE/TYPE). It is '/'-separated path with each element " +
298 "having the form 'module:<name of the module>', " +
299 "'sub:<name of the subroutine>', " +
300 "'func:<name of the function>' or 'type:<name of the type>'.")
338 Updates an argparse parser with input/output arguments
339 :param parser: parser in which arguments are added
340 :param withOutput: do we need the INPUT argument
341 :param withOutput: do we need the OUTPUT argument
342 :param withXml: do we need to be able to define an XML output file
344 gInOut = parser.add_argument_group(
'Input and output')
346 gInOut.add_argument(
'INPUT', help=
'FORTRAN input file')
348 gInOut.add_argument(
'OUTPUT', default=
None, help=
'FORTRAN output file', nargs=
'?')
349 gInOut.add_argument(
'--renamefF', default=
False, action=
'store_true',
350 help=
'Put file extension in upper case')
351 gInOut.add_argument(
'--renameFf', default=
False, action=
'store_true',
352 help=
'Put file extension in lower case')
354 gInOut.add_argument(
'--xml', default=
None, type=str,
355 help=
'Output file for xml')
356 gInOut.add_argument(
'--dryRun', default=
False, action=
'store_true',
357 help=
'Dry run without writing the FORTRAN file (the xml ' +
363 Updates an argparse parser with fxtran arguments
365 gParser = parser.add_argument_group(
'fxtran parser relative options')
366 gParser.add_argument(
'--parser', default=
None, type=str,
367 help=
'Path to the fxtran parser binary')
368 gParser.add_argument(
'--parserOption', nargs=
'*', action=
'append',
369 help=
'Option to pass to fxtran, defaults ' +
370 f
'to {PYFT.DEFAULT_FXTRAN_OPTIONS}')
371 gParser.add_argument(
'--wrapH', default=
False, action=
'store_true',
372 help=
'Wrap .h file content into a MODULE to enable the reading')
377 Updates an argparse parser with variables arguments
379 gVariables = parser.add_argument_group(
'Options to deal with variables')
380 gVariables.add_argument(
'--showVariables', default=
False, action=
'store_true',
381 help=
'Show the declared variables')
382 gVariables.add_argument(
'--removeVariable', nargs=2, action=
'append',
383 metavar=(
'SCOPEPATH',
'VARNAME'),
384 help=
"Variable to remove from declaration. The first argument " +
385 "is the SUBROUTINE/FUNCTION/MODULE/TYPE where the variable " +
386 "is declared. It is '/'-separated path with each element having " +
387 "the form 'module:<name of the module>', " +
388 "'sub:<name of the subroutine>', " +
389 "'func:<name of the function>' or 'type:<name of the type>'. " +
390 "The second argument is the variable name")
391 gVariables.add_argument(
'--attachArraySpecToEntity', default=
False, action=
'store_true',
392 help=
'Find all T-decl-stmt elements that have a child element ' +
393 'attribute with attribute-N=DIMENSION and move the attribute ' +
394 'into EN-N elements')
395 gVariables.add_argument(
'--addVariable', nargs=4, action=
'append',
396 metavar=(
'SCOPEPATH',
'VARNAME',
'DECLARATION',
'POSITION'),
397 help=
'Add a variable. First argument is the scope path (as for ' +
398 'the --removeVariable option. The second is the variable ' +
399 'name, the third is the declarative statement to insert, ' +
400 'the fourth is the position (python indexing) the new ' +
401 'variable will have in the calling statment of the ' +
402 'routine (non-integer value for a local variable).')
403 gVariables.add_argument(
'--addModuleVariable', nargs=3, action=
'append',
404 metavar=(
'SCOPEPATH',
'MODULENAME',
'VARNAME'),
405 help=
'Add a USE statement. The first argument is the scope path ' +
406 '(as for the --removeVariable option). The second is the module ' +
407 'name; the third is the variable name.')
408 gVariables.add_argument(
'--showUnusedVariables', default=
False, action=
'store_true',
409 help=
'Show a list of unused variables.')
410 gVariables.add_argument(
'--removeUnusedLocalVariables',
411 help=
'Remove unused local variables, excluding some variables (comma-' +
412 'separated list or NONE to exclude nothing).')
413 gVariables.add_argument(
'--removePHYEXUnusedLocalVariables',
414 help=
'Remove unused local variables, excluding some variables (comma-' +
415 'separated list or NONE to exclude nothing). This option takes ' +
416 'into account the mnh_expand directives to prevent from ' +
417 'removing useful variables.')
418 gVariables.add_argument(
'--addExplicitArrayBounds', action=
'store_true',
419 help=
'Adds explicit bounds to arrays that already have parentheses.')
420 gVariables.add_argument(
'--addArrayParentheses', action=
'store_true',
421 help=
'Adds parentheses to arrays (A => A(:))')
422 gVariables.add_argument(
'--modifyAutomaticArrays', metavar=
"DECL#START#END",
423 help=
'Transform all automatic arrays declaration using the templates.' +
424 ' The DECL part of the template will replace the declaration ' +
425 'statement, the START part will be inserted as the first ' +
426 'executable statement while the END part will be inserted as ' +
427 'the last executable statement. Each part ' +
428 'of the template can use the following place holders: ' +
429 '"{doubledotshape}", "{shape}", "{lowUpList}", "{name}" and ' +
430 '"{type}" which are, respectively modified into ' +
431 '":, :, :", "I, I:J, 0:I", "1, I, I, J, 0, I", "A", "REAL" ' +
432 'if the original declaration statement ' +
433 'was "A(I, I:J, 0:I)". For example, the template ' +
434 '"{type}, DIMENSION({doubledotshape}), ALLOCATABLE :: ' +
435 '{name}#ALLOCATE({name}({shape}))#DEALLOCATE({name})"' +
436 'will replace automatic arrays by allocatables.')
437 gVariables.add_argument(
'--replaceAutomaticWithAllocatable', action=
'store_true',
438 help=
'Replace all automatic arrays with allocatable arrays.')
439 gVariables.add_argument(
'--addArgInTree', default=
None, action=
'append', nargs=3,
440 metavar=(
'VARNAME',
'DECLARATION',
'POSITION'),
441 help=
'Add an argument variable. The first argument is the variable ' +
442 'name, the second one is the declarative statement to insert, ' +
443 'the third one is the position (python indexing) the new ' +
444 'variable will have in the calling statement of the ' +
445 'routine. Needs the --stopScopes argument')
450 Updates an argparse parser with cosmetics arguments
452 gCosmetics = parser.add_argument_group(
'Cosmetics options')
453 gCosmetics.add_argument(
'--upperCase', default=
False, action=
'store_true',
454 help=
'Put FORTRAN code in upper case letters')
455 gCosmetics.add_argument(
'--lowerCase', default=
False, action=
'store_true',
456 help=
'Put FORTRAN code in lower case letters')
457 gCosmetics.add_argument(
'--changeIfStatementsInIfConstructs', default=
False,
459 help=
'Find all if-statement and convert it to if-then-statement')
460 gCosmetics.add_argument(
'--indent', default=
False, action=
'store_true',
461 help=
'Correct indentation')
462 gCosmetics.add_argument(
'--removeIndent', default=
False, action=
'store_true',
463 help=
'Remove indentation')
464 gCosmetics.add_argument(
'--removeEmptyLines', default=
False, action=
'store_true',
465 help=
'Remove empty lines')
466 gCosmetics.add_argument(
'--removeComments', default=
False, action=
'store_true',
467 help=
'Remove comments')
468 gCosmetics.add_argument(
'--updateSpaces', default=
False, action=
'store_true',
469 help=
'Updates spaces around operators, commas, parenthesis and ' +
470 'at the end of line')
471 gCosmetics.add_argument(
'--alignContinuation', default=
False, action=
'store_true',
472 help=
'Align the beginings of continued lines')
473 gCosmetics.add_argument(
'--addBeginContinuation', default=
False, action=
'store_true',
474 help=
'Add missing continuation characters (\'&\') at the ' +
476 gCosmetics.add_argument(
'--removeBeginContinuation', default=
False, action=
'store_true',
477 help=
'Remove continuation characters (\'&\') at the begining of lines')
478 gCosmetics.add_argument(
'--removeALLContinuation', default=
False, action=
'store_true',
479 help=
'Remove all continuation characters(\'&\')')
480 gCosmetics.add_argument(
'--prettify', default=
False, action=
'store_true',
481 help=
'Prettify the source code (indentation, spaces...)')
482 gCosmetics.add_argument(
'--minify', default=
False, action=
'store_true',
483 help=
'Simplify the source code (indentation, spaces...)')
484 gCosmetics.add_argument(
'--removeEmptyCONTAINS', default=
False, action=
'store_true',
485 help=
'Remove useless CONTAINS statements')
490 Updates an argparse parser with applications arguments
492 gApplications = parser.add_argument_group(
'Options to apply upper level transformation')
493 gApplications.add_argument(
'--deleteDrHook', default=
False, action=
'store_true',
494 help=
'Delete DR HOOK use')
495 gApplications.add_argument(
'--addDrHook', default=
False, action=
'store_true',
497 gApplications.add_argument(
'--deleteBudgetDDH', default=
False, action=
'store_true',
498 help=
'Delete Budget/DDH use')
499 gApplications.add_argument(
'--deleteRoutineCallsMesoNHGPU', default=
False, action=
'store_true',
500 help=
'Delete parts of the code not compatible with MesoNH-OpenACC' +
501 'such as OCND2 blocks')
502 gApplications.add_argument(
'--splitModuleRoutineFile', default=
False, action=
'store_true',
504 gApplications.add_argument(
'--deleteNonColumnCallsPHYEX', default=
False, action=
'store_true',
505 help=
'Delete call to PHYEX routines that needs information on ' +
506 'horizontal points (multiple column dependency')
507 gApplications.add_argument(
'--removeIJDim', default=
False, action=
'store_true',
508 help=
'Remove I and J dimensions (1, KLON). ' +
509 'Needs the --stopScopes argument.')
510 gApplications.add_argument(
'--expandAllArraysPHYEX', default=
False, action=
'store_true',
511 help=
'Expand all array syntax (computing and where block) ' +
512 'using PHYEX conventions')
513 gApplications.add_argument(
'--expandAllArraysPHYEXConcurrent', default=
False,
515 help=
'Expand all array syntax with DO CONCURRENT loops ' +
516 '(computing and where block) using PHYEX conventions')
517 gApplications.add_argument(
'--expandAllArrays', default=
False, action=
'store_true',
518 help=
'Expand all array syntax (computing and where block) ' +
519 'using mnh directives if present')
520 gApplications.add_argument(
'--expandAllArraysConcurrent', default=
False, action=
'store_true',
521 help=
'Expand all array syntax with DO CONCURRENT loops ' +
522 '(computing and where block) using mnh directives if present')
523 gApplications.add_argument(
'--inlineContainedSubroutinesPHYEX', default=
False,
525 help=
'Inline containted subroutines in main routine, using ' +
527 gApplications.add_argument(
'--addStack', metavar=
'MODEL', type=str,
528 help=
'Add local arrays to the stack. The argument is the ' +
529 'the model name in which stack must be added ("AROME" ' +
530 'or "MESONH"). Needs the --stopScopes argument for AROME.')
531 gApplications.add_argument(
'--addIncludes', default=
False, action=
'store_true',
532 help=
'Add .h includes in the file and remove the INCLUDE statement')
533 gApplications.add_argument(
'--mnhExpand', default=
False, action=
'store_true',
534 help=
'Apply the mnh_expand directives with DO loops')
535 gApplications.add_argument(
'--mnhExpandConcurrent', default=
False, action=
'store_true',
536 help=
'Apply the mnh_expand directives with DO CONCURRENT loops')
537 gApplications.add_argument(
'--addMPPDB_CHECKS', default=
False, action=
'store_true',
538 help=
'Add MPPDB_CHEKS bit-repro checking routines of MesoNH for ' +
539 'all in and inout arrays in subroutines')
540 gApplications.add_argument(
'--addPrints', default=
False, action=
'store_true',
541 help=
'Add Prints of min/maxval and shape of all in, out, inout ' +
542 'arguments of all scopes')
543 gApplications.add_argument(
'--shumanFUNCtoCALL', default=
False, action=
'store_true',
544 help=
'Transform shuman functions to call statements')
545 gApplications.add_argument(
'--mathFunctoBRFunc', default=
False, action=
'store_true',
546 help=
'Convert intrinsic math functions **, LOG, ATAN, **2, **3, ' +
547 '**4, EXP, COS, SIN, ATAN2 into a self defined function BR_ ' +
548 'for MesoNH bit-repro.')
549 gApplications.add_argument(
'--convertTypesInCompute', default=
False, action=
'store_true',
550 help=
'Use single variable instead of variable contained in ' +
551 'structure in compute statement for optimization issue ')
552 gApplications.add_argument(
'--buildModi', default=
False, action=
'store_true',
553 help=
'Builds the corresponding modi_ file')
558 Updates an argparse parser with openACC arguments
560 gOpenACC = parser.add_argument_group(
'OpenACC')
561 gOpenACC.add_argument(
'--addACCData', default=
False, action=
'store_true',
562 help=
'Add !$acc data present and !$acc end data directives')
563 gOpenACC.add_argument(
'--addACCRoutineSeq', default=
False, action=
'store_true',
564 help=
'Add "!$acc routine seq" to routines under stopScopes')
565 gOpenACC.add_argument(
'--craybyPassDOCONCURRENT', default=
False, action=
'store_true',
566 help=
'remove acc loop independant collapse for BR_ fonctions and ' +
567 'mnh_undef(OPENACC) macro' +
568 ' use DO CONCURRENT with mnh_undef(LOOP)')
569 gOpenACC.add_argument(
'--removeACC', default=
False, action=
'store_true',
570 help=
'remove all ACC directives')
571 gOpenACC.add_argument(
'--removebyPassDOCONCURRENT', default=
False, action=
'store_true',
572 help=
'remove macro !$mnh_(un)def(OPENACC) and !$mnh_(un)def(LOOP) ' +
574 gOpenACC.add_argument(
'--buildACCTypeHelpers', default=
False, action=
'store_true',
575 help=
'build module files containing helpers to copy user ' +
581 Updates an argparse parser with checks arguments
584 gChecks = parser.add_argument_group(
'Check options')
585 gChecks.add_argument(
'--checkIMPLICIT', choices={
'Warn',
'Err'}, default=
None,
586 help=
'Send a warning or raise an error if the "IMPLICIT NONE" ' +
588 gChecks.add_argument(
'--checkINTENT', choices={
'Warn',
'Err'}, default=
None,
589 help=
'Send a warning or raise an error if the "INTENT" ' +
590 'attribute is missing for a dummy argument')
591 gChecks.add_argument(
'--checkOpInCall', choices={
'Warn',
'Err'}, default=
None,
592 help=
'Send a warning or raise an error if a call argument is an '
598 Updates an argparse parser with statements arguments
601 gStatement = parser.add_argument_group(
'Statements options')
602 gStatement.add_argument(
'--removeCall', action=
'append',
603 help=
"Call to remove from the source code. The argument " +
604 "is the subprogram name")
605 gStatement.add_argument(
'--removePrints', default=
False, action=
'store_true',
606 help=
"Remove print statements from the source code.")
607 gStatement.add_argument(
'--inlineContainedSubroutines', default=
False, action=
'store_true',
608 help=
'Inline containted subroutines in main routine')
609 gStatement.add_argument(
'--setFalseIfStmt', default=
None,
610 help=
'Replace this value by .FALSE. in if statements')
615 Updates an argparse parser with misc arguments
617 gMisc = parser.add_argument_group(
'Miscellaneous')
618 gMisc.add_argument(
'--showScopes', default=
False, action=
'store_true',
619 help=
'Show the different scopes found in the source code')
620 gMisc.add_argument(
'--empty', default=
False, action=
'store_true',
621 help=
'Empty the different scopes')
626 Updates an argparse parser with statements arguments
627 :param withPlotCentralFile: to add the --plotCentralFile argumen
628 :param treeIsOptional: is the --tree argument optional?
630 gTree = parser.add_argument_group(
'Tree')
631 gTree.add_argument(
'--tree', default=
None, action=
'append', required=
not treeIsOptional,
632 help=
'Directories where source code must be searched for')
633 gTree.add_argument(
'--descTree', default=
None, required=
not treeIsOptional,
634 help=
'File to write and/or read the description of the tree.')
635 if withPlotCentralFile:
636 gTree.add_argument(
'--plotCentralFile', default=
None, type=str,
637 help=
'Central file of the plot')
638 gTree.add_argument(
'--plotCompilTree', default=
None,
639 help=
'File name for compilation dependency graph (.dot or image extension)')
640 gTree.add_argument(
'--plotExecTree', default=
None,
641 help=
'File name for execution dependency graph (.dot or image extension)')
642 gTree.add_argument(
'--plotMaxUpper', default=
None, type=int,
643 help=
'Maximum number of upper elements in the plot tree')
644 gTree.add_argument(
'--plotMaxLower', default=
None, type=int,
645 help=
'Maximum number of lower elements in the plot tree')
646 gTree.add_argument(
'--stopScopes', default=
None, type=str,
647 help=
'#-separated list of scopes ' +
648 'where the recursive inclusion of an argument variable ' +
649 'must stop (needed for some transformations).')
654 Updates an argparse parser with statements arguments
656 gCpp = parser.add_argument_group(
'Preprocessor')
657 gCpp.add_argument(
'--applyCPPifdef', nargs=
'*', action=
'append',
658 help=
"This option is followed by the list of defined or undefined " +
660 "All #ifdef and #ifndef concerning these keys are evaluated. " +
661 "Undefined keys are preceded by a percentage sign.")
666 Apply transformation on a PYFT instance
667 :param pft: PYFT instance
668 :param arg: argument to deal with
669 :param args: parsed argparsed arguments
670 :param plotCentralFile: central file for plots
672 simplify = {
'simplify': args.simplify}
674 stopScopes = args.stopScopes.split(
'#')
if args.stopScopes
is not None else None
709 Apply file name transformations on a PYFT instance
710 :param pft: PYFT instance
711 :param arg: argument to deal with
712 :param args: parsed argparsed arguments
716 if arg ==
'--renamefF':
718 elif arg ==
'--renameFf':
724 Apply variables transformations on a PYFT instance
725 :param pft: PYFT instance
726 :param arg: argument to deal with
727 :param args: parsed argparsed arguments
728 :param simplify: kwargs to simplify
729 :param parserOptions: fxtran parser options
730 :param stopScopes: upper limit in call tree for some transformations
732 if arg ==
'--showVariables':
733 pft.varList.showVarList()
734 elif arg ==
'--attachArraySpecToEntity':
735 pft.attachArraySpecToEntity()
736 elif arg ==
'--removeVariable':
737 pft.removeVar(args.removeVariable, **simplify)
738 elif arg ==
'--addVariable':
739 pft.addVar([[v[0], v[1], v[2], (int(v[3])
if isint(v[3])
else None)]
740 for v
in args.addVariable])
741 elif arg ==
'--addModuleVariable':
742 pft.addModuleVar([[v[0], v[1], v[2]]
for v
in args.addModuleVariable])
743 elif arg ==
'--showUnusedVariables':
745 elif arg ==
'--removeUnusedLocalVariables':
746 pft.removeUnusedLocalVar(
747 [item.strip()
for item
in args.removeUnusedLocalVariables.split(
',')]
748 if args.removeUnusedLocalVariables !=
'NONE' else None, **simplify)
749 elif arg ==
'--removePHYEXUnusedLocalVariables':
750 pft.removePHYEXUnusedLocalVar(
751 [item.strip()
for item
in args.removePHYEXUnusedLocalVariables.split(
',')]
752 if args.removePHYEXUnusedLocalVariables !=
'NONE' else None, **simplify)
753 elif arg ==
'--addExplicitArrayBounds':
754 pft.addExplicitArrayBounds()
755 elif arg ==
'--addArrayParentheses':
756 pft.addArrayParentheses()
757 elif arg ==
'--modifyAutomaticArrays':
758 pft.modifyAutomaticArrays(*(args.modifyAutomaticArrays.split(
'#')))
759 elif arg ==
'--replaceAutomaticWithAllocatable':
760 pft.modifyAutomaticArrays(
761 "{type}, DIMENSION({doubledotshape}), ALLOCATABLE :: {name}",
762 "ALLOCATE({name}({shape}))",
"DEALLOCATE({name})")
763 elif arg ==
'--addArgInTree':
764 for varName, declStmt, pos
in args.addArgInTree:
765 pft.addArgInTree(varName, declStmt, int(pos), stopScopes,
767 parserOptions=parserOptions,
773 Apply applications transformations on a PYFT instance
774 :param pft: PYFT instance
775 :param arg: argument to deal with
776 :param args: parsed argparsed arguments
777 :param simplify: kwargs to simplify
778 :param parserOptions: fxtran parser options
779 :param stopScopes: upper limit in call tree for some transformations
781 if arg ==
'--addStack':
782 pft.addStack(args.addStack, stopScopes,
783 parser=args.parser, parserOptions=parserOptions,
785 elif arg ==
'--deleteDrHook':
786 pft.deleteDrHook(**simplify)
787 elif arg ==
'--addDrHook':
789 elif arg ==
'--deleteBudgetDDH':
790 pft.deleteBudgetDDH(**simplify)
791 elif arg ==
'--deleteRoutineCallsMesoNHGPU':
792 pft.deleteRoutineCallsMesoNHGPU(**simplify)
793 elif arg ==
'--deleteNonColumnCallsPHYEX':
794 pft.deleteNonColumnCallsPHYEX(**simplify)
795 elif arg ==
'--addMPPDB_CHECKS':
796 pft.addMPPDB_CHECKS()
797 elif arg ==
'--addPrints':
798 pft.addMPPDB_CHECKS(printsMode=
True)
801 assert not (args.mnhExpand
and args.mnhExpandConcurrent), \
802 "Only one of --mnhExpand and --mnhExpandConcurrent"
803 if arg ==
'--mnhExpand':
804 pft.removeArraySyntax(everywhere=
False, addAccIndependentCollapse=
False)
805 elif arg ==
'--mnhExpandConcurrent':
806 pft.removeArraySyntax(concurrent=
True, everywhere=
False)
807 elif arg ==
'--inlineContainedSubroutines':
808 pft.inlineContainedSubroutines(**simplify)
809 elif arg ==
'--inlineContainedSubroutinesPHYEX':
810 pft.inlineContainedSubroutinesPHYEX(**simplify)
811 elif arg ==
'--expandAllArrays':
812 pft.removeArraySyntax()
813 elif arg ==
'--expandAllArraysConcurrent':
814 pft.removeArraySyntax(concurrent=
True)
815 elif arg ==
'--expandAllArraysPHYEX':
816 pft.expandAllArraysPHYEX()
817 elif arg ==
'--expandAllArraysPHYEXConcurrent':
818 pft.expandAllArraysPHYEX(concurrent=
True)
819 elif arg ==
'--removeIJDim':
820 pft.removeIJDim(stopScopes,
821 parser=args.parser, parserOptions=parserOptions,
822 wrapH=args.wrapH, **simplify)
823 elif arg ==
'--shumanFUNCtoCALL':
824 pft.shumanFUNCtoCALL()
825 elif arg ==
'--buildACCTypeHelpers':
826 pft.buildACCTypeHelpers()
827 elif arg ==
'--mathFunctoBRFunc':
828 pft.mathFunctoBRFunc()
829 elif arg ==
'--convertTypesInCompute':
830 pft.convertTypesInCompute()
831 elif arg ==
'--buildModi':
833 elif arg ==
'--splitModuleRoutineFile':
834 pft.splitModuleRoutineFile()
839 Apply openACC transformations on a PYFT instance
840 :param pft: PYFT instance
841 :param arg: argument to deal with
842 :param args: parsed argparsed arguments
843 :param stopScopes: upper limit in call tree for some transformations
845 if arg ==
'--addACCData':
847 elif arg ==
'--craybyPassDOCONCURRENT':
848 pft.craybyPassDOCONCURRENT()
849 elif arg ==
'--removebyPassDOCONCURRENT':
850 pft.removebyPassDOCONCURRENT()
851 elif arg ==
'--addACCRoutineSeq':
852 pft.addACCRoutineSeq(stopScopes)
853 elif arg ==
'--removeACC':
859 Apply cosmetics transformations on a PYFT instance
860 :param pft: PYFT instance
861 :param arg: argument to deal with
862 :param args: parsed argparsed arguments
864 if arg ==
'--upperCase':
866 elif arg ==
'--lowerCase':
868 elif arg ==
'--changeIfStatementsInIfConstructs':
869 pft.changeIfStatementsInIfConstructs()
870 elif arg ==
'--indent':
872 elif arg ==
'--removeIndent':
873 pft.indent(indentProgramunit=0, indentBranch=0)
874 elif arg ==
'--removeEmptyLines':
875 pft.removeEmptyLines()
876 elif arg ==
'--removeComments':
878 elif arg ==
'--updateSpaces':
880 elif arg
in ARG_UPDATE_CNT:
881 pft.updateContinuation(align=args.alignContinuation,
882 addBegin=args.addBeginContinuation,
883 removeBegin=args.removeBeginContinuation,
884 removeALL=args.removeALLContinuation)
885 elif arg ==
'--prettify':
888 pft.removeEmptyLines()
890 pft.updateContinuation()
891 elif arg ==
'--minify':
892 pft.indent(indentProgramunit=0, indentBranch=0)
895 pft.removeEmptyLines()
897 pft.updateContinuation(align=
False, removeALL=
True, addBegin=
False)
898 elif arg ==
'--removeEmptyCONTAINS':
899 pft.removeEmptyCONTAINS()
904 Apply checks transformations on a PYFT instance
905 :param pft: PYFT instance
906 :param arg: argument to deal with
907 :param args: parsed argparsed arguments
909 if arg ==
'--checkIMPLICIT':
910 pft.checkImplicitNone(args.checkIMPLICIT ==
'Err')
911 elif arg ==
'--checkINTENT':
912 pft.checkIntent(args.checkINTENT ==
'Err')
913 elif arg ==
'--checkOpInCall':
914 pft.checkOpInCall(args.checkOpInCall ==
'Err')
919 Apply statements transformations on a PYFT instance
920 :param pft: PYFT instance
921 :param arg: argument to deal with
922 :param args: parsed argparsed arguments
923 :param simplify: kwargs to simplify
925 if arg ==
'--removeCall':
926 for rc
in args.removeCall:
927 pft.removeCall(rc, **simplify)
928 elif arg ==
'--removePrints':
929 pft.removePrints(**simplify)
930 elif arg ==
'--setFalseIfStmt':
931 pft.setFalseIfStmt(args.setFalseIfStmt, **simplify)
936 Apply misc transformations on a PYFT instance
937 :param pft: PYFT instance
938 :param arg: argument to deal with
939 :param args: parsed argparsed arguments
940 :param simplify: kwargs to simplify
942 if arg ==
'--showScopes':
944 elif arg ==
'--empty':
945 pft.empty(**simplify)
950 Apply tree transformations on a PYFT instance
951 :param pft: PYFT instance
952 :param arg: argument to deal with
953 :param args: parsed argparsed arguments
954 :param plotCentralFile: central file for plots
956 if arg ==
'--plotCompilTree' and plotCentralFile
is not None:
957 pft.tree.plotCompilTreeFromFile(plotCentralFile, args.plotCompilTree,
958 args.plotMaxUpper, args.plotMaxLower)
959 elif arg ==
'--plotExecTree' and plotCentralFile
is not None:
960 pft.tree.plotExecTreeFromFile(plotCentralFile, args.plotExecTree,
961 args.plotMaxUpper, args.plotMaxLower)
966 Apply preprocessor transformations on a PYFT instance
967 :param pft: PYFT instance
968 :param arg: argument to deal with
969 :param args: parsed argparsed arguments
971 if arg ==
'--applyCPPifdef':
972 pft.applyCPPifdef([k
for aList
in args.applyCPPifdef
for k
in aList])