13def translate(graph: Graph, identifier: str, peano_project:
"peano4.api.Project") -> List[
"peano4.api.solversteps.Step"]:
16 Simplest possible task graph compiler
18 Linearises the task graph into one mesh traversal (Observer) per task, in
19 an order that respects every dependency: a task's Observer always comes
20 after the Observers of all tasks it depends on. This throws away any
21 parallelism the task graph might encode - it is the "no fusion, no
22 reordering" baseline compiler that smarter compilers can be measured
27 A straightforward, direct mapping: graph.ordered_tasks() linearises the
28 graph's tasks into a valid topological order (a task always comes after
29 every task it depends on - @see Graph.ordered_tasks() for how), and
30 every task in that order becomes exactly one Observer, populated with
31 that task's action sets and the cell/face/vertex data it declared via
32 use_cell()/use_face()/use_vertex().
34 Note that this function no longer derives any *further* use_cell()/
35 use_face()/use_vertex() declarations itself - that is the job of
36 @ref peano4.api.taskgraph.compiler.PropagateUseStatements.propagate_use_statements(),
37 which has to run *before* translate() (it reasons about tasks, not the
38 Steps translate() produces here, and about the composability of
39 several graphs at once, which a single graph's own translate() call
40 cannot see). By the time translate() runs, every task already carries
41 every use_cell()/use_face()/use_vertex() declaration it will ever need.
43 A peano4.api.Logger().new_section() call brackets the translation, and
44 @ref peano4.api.taskgraph.compiler.ReportCompiledStepSequence.report_compiled_step_sequence()
45 reports its outcome right after - a textual listing of the resulting
46 sequence and its action sets under LoggerVerbosity.TEXT, or a flow chart
47 in the same style as Graph.visualise() under
48 LoggerVerbosity.VISUALISATION.
50 @param graph: peano4.api.taskgraph.Graph
51 The task graph to linearise. Assumed to be acyclic - translate() does
52 not check for cycles and will recurse indefinitely on one.
54 @param identifier: str
55 Identifies which of the surrounding project's algorithmic phases this
56 graph belongs to (e.g. "SetupSimulation", "TimeStep", "Plot"). Every
57 generated Observer's name is prefixed with this identifier, joined by
58 an underscore, so Observers coming from different phases never clash
59 even if their tasks happen to share a name.
61 @param peano_project: peano4.api.Project
62 Not used by this compiler. @ref peano4.api.taskgraph.compiler
64 @return [peano4.api.solversteps.Step]
65 One Observer per task, ordered so that every task's Observer comes
66 after the Observers of all tasks it depends on, carrying that task's
67 action_sets (in the order they were added to the Task) plus the
68 cell/face/vertex data use_cell()/use_face()/use_vertex() determined.
69 Each Step's cell_data_access/face_data_access/vertex_data_access is
70 also populated as a copy of the originating Task's, purely for
72 peano4.api.taskgraph.compiler.ReportCompiledStepSequence) - nothing
73 about the generated Observer depends on it.
76 order = graph.ordered_tasks()
85 task_name =
"_".join(word[:1].upper() + word[1:]
for word
in task.name.split())
87 name=f
"{identifier}_{task_name}",
88 add_user_defined_actions=
False,
90 step.has_to_repeat = task.has_to_repeat
91 for cell_data
in task.cell_data:
92 step.use_cell(cell_data)
93 step.cell_data_access[cell_data] = task.cell_data_access[cell_data]
94 for face_data
in task.face_data:
95 step.use_face(face_data)
96 step.face_data_access[face_data] = task.face_data_access[face_data]
97 for vertex_data
in task.vertex_data:
98 step.use_vertex(vertex_data)
99 step.vertex_data_access[vertex_data] = task.vertex_data_access[vertex_data]
100 for action_set
in task.action_sets:
101 step.add_action_set(action_set)
105 report_compiled_step_sequence(steps, title=f
"Compiled task graph for {identifier}")