Peano
Loading...
Searching...
No Matches
AlgorithmStep.py
Go to the documentation of this file.
1# This file is part of the SWIFT2 project. For conditions of distribution and
2# use, please see the copyright notice at www.peano-framework.org
3
4from enum import Enum, IntEnum
5
6from abc import abstractmethod
7
8import peano4
9
10
11class AlgorithmStep(object):
12 """!
13
14 Defines the meta data around one algorithmic step per particle
15
16 A sequence of these steps describes the particle lifecycle per time step. It
17 is Peano's/SWIFT's responsibility to arrange these steps in grid sweeps and
18 to identify concurrency.
19
20 """
21
22 class Dependencies(Enum):
23 """
24
25 An algorithmic step for one particle can depend on different
26 pre-conditions:
27
28 - It can only depend on its own previous step (SELF);
29 - It can depend on the neighbours within a particle's interaction radius
30 (NEIGHBOURS);
31
32 """
33
34 SELF = 0
35 NEIGHBOURS = 1
36
37 class Effect(Enum):
38 """
39
40 What happens in this algorithmic step per particle:
41
42 - ALTER_GLOBAL_STATE is the most generic baseline routine. No local data
43 are changed, but the code (might) alter some global properties. Typical
44 examples are the reduction of the global admissible time step size.
45 - ALTER_LOCAL_STATE implies that only the local state of a particle is
46 changed. The code might also modify the global state, but it may not
47 change a particle's position or its search radius, i.e. the spatial
48 topology between particles.
49 - CHANGE_POSITION_OR_INTERACTION_RADIUS is the most general update which
50 means that literally any global or local attribute might be modified.
51 However, the graph compilers have to know whether you might ask it to
52 rerun this step. This is important, as this step might change the
53 topology.
54
55 Please note that any update of a particle position should happen within
56 touch vertex last time. Otherwise, we'd destroy the particle topology.
57
58 By default, any algorithm step runs only once. However, there are
59 variants of each step which can rerun. But the user has to flag this
60 possibility explicitly.
61
62 """
63
64 ALTER_GLOBAL_STATE = 0
65 ALTER_GLOBAL_STATE_AND_MIGHT_RERUN = 1
66 ALTER_LOCAL_STATE = 2
67 ALTER_LOCAL_STATE_AND_MIGHT_RERUN = 3
68 CHANGE_POSITION_OR_INTERACTION_RADIUS = 4
69 CHANGE_POSITION_OR_INTERACTION_RADIUS_AND_MIGHT_RERUN = 5
70
71 def may_trigger_rerun(effect: Effect):
72 """!
73
74 Return True if the effect object may trigger a rerun
75
76 """
77 if effect in [
78 AlgorithmStep.Effect.ALTER_GLOBAL_STATE_AND_MIGHT_RERUN,
79 AlgorithmStep.Effect.ALTER_LOCAL_STATE_AND_MIGHT_RERUN,
80 AlgorithmStep.Effect.CHANGE_POSITION_OR_INTERACTION_RADIUS_AND_MIGHT_RERUN,
81 ]:
82 return True
83 else:
84 return False
85
86 class PeanoEventUsedBySwift(IntEnum):
87 """!
88
89 Enumeration of different @ref peano_action_sets "Peano events" during a
90 grid traversal into which Swift 2 plugs in. We don't use all events.
91 Therefore, this is a subset of the operations in
92 peano4.solversteps.ActionSet. The enumeration is based upon integers,
93 as we need to know the order of the enumerations.
94
95 Should we ever pick up more events, make sure to also update the dict
96 containing the names of the stages in
97 """
98
99 TOUCH_VERTEX_FIRST_TIME = 0
100 CELL_KERNEL = 1
101 TOUCH_VERTEX_LAST_TIME = 2
102 EVENT_COUNT = 3
103
104 @staticmethod
105 def get_event_name(stage: PeanoEventUsedBySwift):
106 """!
107
108 Get the name as a string of a sweep stage for a given PeanoEventUsedBySwift enum.
109
110 """
111 Results = {
112 AlgorithmStep.PeanoEventUsedBySwift.TOUCH_VERTEX_FIRST_TIME: peano4.solversteps.ActionSet.OPERATION_TOUCH_VERTEX_FIRST_TIME,
113 AlgorithmStep.PeanoEventUsedBySwift.CELL_KERNEL: "cellKernel",
114 AlgorithmStep.PeanoEventUsedBySwift.TOUCH_VERTEX_LAST_TIME: peano4.solversteps.ActionSet.OPERATION_TOUCH_VERTEX_LAST_TIME,
115 AlgorithmStep.PeanoEventUsedBySwift.EVENT_COUNT: "count",
116 }
117 return Results[stage]
118
120 self,
121 name,
122 dependencies: Dependencies,
123 effect: Effect,
124 cell_kernel=None,
125 touch_vertex_first_time_kernel=None,
126 touch_vertex_last_time_kernel=None,
127 prepare_traversal_kernel="",
128 unprepare_traversal_kernel="",
129 input_particles=None,
130 includes="",
131 cell_kernel_dependency_policy=None,
132 touch_vertex_first_time_dependency_policy=None,
133 touch_vertex_last_time_dependency_policy=None,
134 ):
135 """!
136
137 The algorithmic step description is a meta data object, i.e. it only
138 holds properties.
139
140 ## Parameters/attributes
141
142 @param cell_kernel: C++ code (string)
143 Kernel invocation what happens in a cell. Set to None if nothing
144 is to be done per cell.
145
146 @param touch_vertex_first_time_kernel: C++ code (string)
147 Kernel invocation what happens when we read a vertex and its particles
148 for the first time. Set to None if nothing is to be done.
149
150 @param touch_vertex_last_time_kernel: C++ code (string)
151 Kernel invocation what happens when we read a vertex and its particles
152 for the last time. Set to None if nothing is to be done.
153
154 @param input_particles: ParticleSet
155 Switch to None in most cases. This fragment gives you the opportunity
156 to couple the particles of one step with another particle species. If
157 you hand in None, then we assume that the algorithm step updates the
158 particles as input function from the particles.
159
160 @param includes: String
161 Additional include statements
162
163 prepare_traversals_kernel = None,
164
165 @param prepare_traversal_kernel: String (C++ code snippet)
166 Whenever Peano runs through the mesh, it creates one instance of the
167 mesh observer and then runs through all subpartitions (trees) in
168 parallel. Each replica of the observer issues its own touchVertexFirstTime(),
169 touchCellLastTime(), ... events, and each replica starts its traversal
170 with a call to beginTraversal() and endTraversal(). If you want to
171 plug into the phase such before these parallel instances are created,
172 you can use prepareTraversal() - the C++ code snippet passed to this
173 attribute is copied into prepareTraversal(). The overview over
174 @ref peano_action_sets "action sets" provides more details. Note that
175 no action set (or observer object) is created at this point, i.e. the
176 C++ code snippet will be injected into a static routine and can
177 therefore only access static information. Often, this routine is used
178 for some MPI communication (global data exchange), e.g., or to update
179 some other static properties for whole sets of objects.
180
181 @param unprepare_traversal_kernel: String (C++ code snippet)
182 Counterpart of prepare_traversal_kernel. Consult
183 @ref peano_action_sets "action sets" for more context.
184
185 @param cell_kernel_dependency_policy: String or None
186 If it is a string, it should identify one of the variants of
187 swift2::dependencychecks::Invariant. If you pick None, Swift 2
188 will add default dependencies. They might be too strict.
189
190 @param touch_vertex_first_time_dependency_policy: String or None
191 If it is a string, it should identify one of the variants of
192 swift2::dependencychecks::Invariant. If you pick None, Swift 2
193 will add default dependencies. They might be too strict.
194
195 @param touch_vertex_last_time_dependency_policy: String or None
196 If it is a string, it should identify one of the variants of
197 swift2::dependencychecks::Invariant. If you pick None, Swift 2
198 will add default dependencies. They might be too strict.
199
200 """
201 self.name = name
202 self.dependencies = dependencies
203 self.effect = effect
204
205 self.cell_kernel = cell_kernel
206 self.touch_vertex_first_time_kernel = touch_vertex_first_time_kernel
207 self.touch_vertex_last_time_kernel = touch_vertex_last_time_kernel
208 self.prepare_traversal_kernel = prepare_traversal_kernel
209 self.unprepare_traversal_kernel = unprepare_traversal_kernel
210
211 self.input_particles = input_particles
212 self.includes = (
213 """
214#include "Constants.h"
215#include "swift2/kernels/ParticleUpdatePredicates.h"
216#include "swift2/kernels/ParticleSetIterators.h"
217
218#include "swift2/dependencychecks/DependencyChecks.h"
219#include "toolbox/particles/assignmentchecks/TracingAPI.h"
220 """
221 + includes
222 )
223
224 self.cell_kernel_dependency_policy = cell_kernel_dependency_policy
226 touch_vertex_first_time_dependency_policy
227 )
229 touch_vertex_last_time_dependency_policy
230 )
231
232 def __str__(self):
233 return "({},{},{})".format(self.name, self.dependencies, self.effect)
An algorithmic step for one particle can depend on different pre-conditions:
What happens in this algorithmic step per particle:
Enumeration of different Peano events during a grid traversal into which Swift 2 plugs in.
Defines the meta data around one algorithmic step per particle.
may_trigger_rerun(Effect effect)
Return True if the effect object may trigger a rerun.
get_event_name(PeanoEventUsedBySwift stage)
Get the name as a string of a sweep stage for a given PeanoEventUsedBySwift enum.
__init__(self, name, Dependencies dependencies, Effect effect, cell_kernel=None, touch_vertex_first_time_kernel=None, touch_vertex_last_time_kernel=None, prepare_traversal_kernel="", unprepare_traversal_kernel="", input_particles=None, includes="", cell_kernel_dependency_policy=None, touch_vertex_first_time_dependency_policy=None, touch_vertex_last_time_dependency_policy=None)
The algorithmic step description is a meta data object, i.e.