loki.batch.scheduler
Classes
|
Work queue manager to discover and capture dependencies for a given call tree, and apply transformations for batch processing |
- class Scheduler(paths, config=None, seed_routines=None, preprocess=False, includes=None, defines=None, definitions=None, xmods=None, omni_includes=None, full_parse=True, frontend=Frontend.FP)
Bases:
object
Work queue manager to discover and capture dependencies for a given call tree, and apply transformations for batch processing
Using a given list of
paths
andseed_routines
(can be inferred fromconfig
), all scopes and symbols defined in the source tree are discovered and a dependency graph is created. The nodes of the dependency graph areItem
objects, each corresponding to a specific Loki IR node.The dependency graph is re-generated on-the-fly and can be filtered for specific dependency classes during traversals (see
SFilter
). All items, are stored in the cache of the associateditem_factory
.Under the hood, the Scheduler is initialised in a three-stage procedure:
A discovery step, where the minimum top-level definitions (modules and procedures) are determined for every source file in the path list.
A populate step, which instantiates a first
SGraph
dependency graph by chasing dependencies starting from the provided seed nodes.Optionally, a full parse is triggered for all
Sourcefile
that appear in anItem
in the dependency graph.
This first two stages rely on an incremental, incomplete parsing of the source files that extract only the minimum set of symbols in each file. This is driven by the
Item._parser_class
andItem._depends_class
attributes, which declare the minimumRegexParserClass
classes to use with theREGEX
frontend.To discover dependencies, the item’s IR is concretized. This calls
Scope.make_complete
with the minimum set of additional parser classes (as defined in the_parser_class
attribute) that are required to discover the dependencies (e.g., calls, imports). When creating the corresponding dependency’s item, the defining scope’s item (e.g., a module containing a derived type declaration) is queried for itsdefinitions
, which in turn may trigger also a concretize step with the_parser_class
of all item types that are listed in the scope item’sdefines_items
attribute.A
Transformation
can be applied across all nodes in the dependency graph using theprocess()
method. The class properties in the transformation implementation (such asTransformation.reverse_traversal
,Transformation.traverse_file_graph
orTransformation.item_filter
) determine, what nodes should be processed.- config
The config object describing the Scheduler’s behaviour
- Type:
- paths
List of paths where sourcefiles are searched
- Type:
list of
pathlib.Path
- build_args
List of frontend arguments that are given to
Sourcefile.from_file
when performing a full parse- Type:
- Parameters:
paths (str or list of str) – List of paths to search for automated source file detection.
config (dict or str, optional) – Configuration dict or path to scheduler configuration file
seed_routines (list of str, optional) – Names of routines from which to populate the callgraph initially. If not provided, these will be inferred from the given config.
preprocess (bool, optional) – Flag to trigger CPP preprocessing (by default False).
includes (list of str, optional) – Include paths to pass to the C-preprocessor.
defines (list of str, optional) – Symbol definitions to pass to the C-preprocessor.
definitions (list of
Module
, optional) –Module
object(s) that may supply external type or procedure definitions.xmods (str, optional) – Path to directory to find and store
.xmod
files when using the OMNI frontend.omni_includes (list of str, optional) – Additional include paths to pass to the preprocessor run as part of the OMNI frontend parse. If set, this replaces (!)
includes
, otherwiseomni_includes
defaults to the value ofincludes
.full_parse (bool, optional) – Flag indicating whether a full parse of all sourcefiles is required. By default a full parse is executed, use this flag to suppress.
frontend (
Frontend
, optional) – Frontend to use for full parse of source files (defaultFP
).
- source_suffixes = ['.f90', '.F90', '.f', '.F']
- property dependencies
All individual pairs of
Item
that represent a dependency and form an edge in the :any`Scheduler` call graph.
- property definitions
The list of definitions that the source files in the callgraph provide
- property file_graph
Alternative dependency graph based on relations between source files
- rekey_item_cache()
Rebuild the mapping of item names to items in the
item_factory
’s cacheThis is required when a
Transformation
renames items during processing, and is triggered automatically at the end of theprocess()
method if the transformation hasTransformation.renames_items
specified.This update also updates
config
entries that are affected by the renaming.
- process(transformation)
Process all
items
in the scheduler’s graph with either aPipeline
or a singleTransformation
.A single
Transformation
pass invokesprocess_transformation()
individually, while aPipeline
will apply each contained transformation in turn over the full dependency graph of the scheduler.- Parameters:
transformation (
Transformation
orPipeline
) – The transformation or transformation pipeline to apply
- process_pipeline(pipeline)
Process a given
Pipeline
by applying its assocaited transformations in turn.- Parameters:
transformation (
Pipeline
) – The transformation pipeline to apply
- process_transformation(transformation)
Process all
items
in the scheduler’s graphBy default, the traversal is performed in topological order, which ensures that an item is processed before the items it depends upon (e.g., via a procedure call) This order can be reversed in the
Transformation
manifest by settingTransformation.reverse_traversal
toTrue
.The scheduler applies the transformation to the scope corresponding to each item in the scheduler’s graph, determined by the
Item.scope_ir
property. For example, for aProcedureItem
, the transformation is applied to the correspondingSubroutine
object.Optionally, the traversal can be performed on a source file level only, if the transformation has set
Transformation.traverse_file_graph
toTrue
. This uses thefilegraph
to process the dependency tree. If combined with aTransformation.item_filter
, only source files with at least one object corresponding to an item of that type are processed.- Parameters:
transformation (
Transformation
) – The transformation to apply over the dependency tree
- callgraph(path, with_file_graph=False, with_legend=False)
Generate a callgraph visualization and dump to file.
- Parameters:
path (str or pathlib.Path) – Path to write the callgraph figure to.
with_filegraph (bool or str or pathlib.Path) – Visualize file dependencies in an additional file. Can be set to True or a file path to write to.
with_legend (bool) – Add a key/legend to the plot. Can be enabled by setting the argument to True.
- write_cmake_plan(filepath, mode, buildpath, rootpath)
Generate the “plan file” for CMake
The plan file is a CMake file defining three lists:
LOKI_SOURCES_TO_TRANSFORM
: The list of files that are processed in the dependency graphLOKI_SOURCES_TO_APPEND
: The list of files that are created and have to be added to the build target as part of the processingLOKI_SOURCES_TO_REMOVE
: The list of files that are no longer required (because they have been replaced by transformed files) and should be removed from the build target.
These lists are used by the CMake wrappers to schedule the source updates and update the source lists of the CMake target object accordingly.