Peano
Loading...
Searching...
No Matches
ActionSet.py
Go to the documentation of this file.
1# This file is part of the Peano project. For conditions of distribution and
2# use, please see the copyright notice at www.peano-framework.org
3from abc import abstractmethod
4
5
6class ActionSet(object):
7 """!
8
9 Action set (reactions to events)
10
11 Peano runs through the mesh tied to an observer. The observer
12 "sees" events and issues actions tied to these events. That is
13 the observer listens to the tree traversal for events alike "this
14 is the first time I see (touch) a vertex". A list of events
15 that we can listen to is specified by this class through class
16 attributes starting with OPERATION_. Peano's documentation holds
17 a @ref peano_action_sets "discussion of events and their temporal and spatial ordering".
18
19 For each grid traversal, Peano expects one C++ observer. The
20 observer is represented within Python through
21 peano4.solversteps.Step, i.e. this class creates eventually one
22 peano4.output.Observer which in return writes out the C++ code.
23 Each observer can have an arbitrary number of action set classes.
24 Each step consequently can hold an action set. The observer's job
25 is it to take information like "I've just entered a spacetree
26 cell" and to break it down into actions like
27
28 - this vertex is read for the first time
29 - this hanging vertex has to be created
30 - this face is read for the first time
31 - this cell now is entered and these are the associated faces
32 and vertices
33
34 For each of these "actions", the generated C++ code will call the
35 corresponding functions of all associated action sets one by one.
36
37 @image html ActionSet.png
38
39 The cartoon above illustrates these three layers: Users or Peano
40 extensions build up logical program steps (left top). They are
41 basically containers with a unique name. Each step holds an arbitrary
42 number of ActionSets. They are, first of all, mappings where each
43 logical action is potentially tied to a C++ code snippet. When
44 the Peano project is generated, each action set is translated into
45 its counterpart in the output namespace which is now a complete
46 description of this class, i.e. holds all functions required, all
47 parameters, ... It copies over the C++ code snippet from its
48 specifiation. This Python representation can then be dumped into
49 a C++ class.
50
51
52 ## Lifecycle and parallelisation
53
54 Action sets are non-persistent, i.e. if you generate C++ code,
55 remind yourself that the class implementing a particular action
56 set will be generated once per grid sweep per tree. As a logical
57 consequence, different action sets are in principle totally
58 independent. If they exchange data, you have to realise this.
59 However, there's a creational routine and a merge command, i.e.
60 you can implement forks and joins (reductions) "natively". There
61 are also functions to inject static data into an action set.
62
63 There will be one class per action set per context (observer)
64 in which it is used. One object will be created per grid sweep, and
65 it will have the tree identifier -1 by default. The actual
66 objects that then are used are constructed from this prototype
67 object via the augmented copy constructor. The other important
68 role of the prototype object, i.e. the one tied to spacetree id
69 -1, is to manage the grid traversal events. It is this object
70 that is asked to hand out grid traversals. Consult the documentation
71 of get_constructor_body() for details on the tree id.
72
73 If you want to realise BSP-like programming, then you typically
74 realise the data sharing via the copy constructor. The
75 attributes of the action set then are all thread-local, i.e.
76 there's no need to be afraid of memory races. The join in turn
77 should be done within OPERATION_END_TRAVERSAL. Here, you'll need a
78 semaphore, as the fusion of objects is not per se thread-safe.
79
80
81 ## The injected C++ snippets
82
83 To inject C++ code, i.e. what has to be done, you make get_body_of_operation()
84 return this code if the corresponding argument is passed in. This result
85 should be plain C++ code which the generator really can take and copy
86 n paste into the generated implementation files. If you want these
87 injected snippets to do something solver-specific, a lot of action
88 sets read out there environment and apply jinja2 templates to tailor
89 the snippet to their needs. For example: If you want to do something
90 with the adjacent vertices of a cell, you have to know what these will
91 be called eventually. In this case, it makes sense to study the naming
92 conventions that peano4.output.ActionSet will put in place.
93
94 The easiest way to find these out is to generate some code, to look into
95 the generated output, and then to reconstruct the naming conventions.
96 To be able to do so, it makes sense to let get_action_set_name() return
97 a unique name, so it is easier for you to find what C++ file corresponds
98 to which action set.
99
100 A discussion some event functions and their semantics as well as further
101 info on the arguments can be found in the documentation of
102 @ref peano_action_sets.
103
104
105 ## Order of invocation and concurrency level
106
107 A discussion of the order of events can be found in the documentation of
108 @ref peano_action_sets.
109
110
111
112
113 @param parallel: Boolean
114 See section on "Order of invocation and concurrency level" in class
115 documentation.
116
117 @param descend_invocation_order: Integer
118 See section on "Order of invocation and concurrency level" in class
119 documentation.
120
121 """
122
123 def __init__(self, descend_invocation_order=0, parallel=False):
124 self.descend_invocation_order = descend_invocation_order
125 self.parallel = parallel
126 pass
127
128 @abstractmethod
130 """! Define a tailored constructor body
131
132 By default, the constructor of an action set is empty. If you you assign
133 attributes to your action set, you however might want to initialise them
134 here. We do not support initialisation lists, to all has to be done via
135 setters unless you create attributes on the heap.
136
137 The constructor's signature will look similar to
138
139
140 EnumerateAndInitSolution2petsc_actionsets_InitVertexDoFs0(int treeNumber);
141
142
143 where the treeNumber is -1 if this is the global instance of the
144 action set owned by a rank, or a number greater or equal 0 if this action
145 set is a clone of the glocal action set that's used by one tree traversal.
146
147 @see get_attributes() to add attributes to your action set
148
149 """
150 return "// @todo Should be overwritten\n"
151
152 def get_static_initialisations(self, full_qualified_classname):
153 return ""
154
155 @abstractmethod
157 return "// @todo Should be overwritten\n"
158
160 return "return std::vector< peano4::grid::GridControlEvent >();\n"
161
162 @abstractmethod
164 return "\n"
165
166 @abstractmethod
168 return "\n"
169
170 OPERATION_BEGIN_TRAVERSAL = "beginTraversal"
171 OPERATION_END_TRAVERSAL = "endTraversal"
172
173 OPERATION_CREATE_PERSISTENT_VERTEX = "createPersistentVertex"
174 OPERATION_DESTROY_PERSISTENT_VERTEX = "destroyPersistentVertex"
175 OPERATION_CREATE_HANGING_VERTEX = "createHangingVertex"
176 OPERATION_DESTROY_HANGING_VERTEX = "destroyHangingVertex"
177 OPERATION_CREATE_PERSISTENT_FACE = "createPersistentFace"
178 OPERATION_DESTROY_PERSISTENT_FACE = "destroyPersistentFace"
179 OPERATION_CREATE_HANGING_FACE = "createHangingFace"
180 OPERATION_DESTROY_HANGING_FACE = "destroyHangingFace"
181 OPERATION_CREATE_CELL = "createCell"
182 OPERATION_DESTROY_CELL = "destroyCell"
183
184 OPERATION_TOUCH_VERTEX_FIRST_TIME = "touchVertexFirstTime"
185 OPERATION_TOUCH_VERTEX_LAST_TIME = "touchVertexLastTime"
186 OPERATION_TOUCH_FACE_FIRST_TIME = "touchFaceFirstTime"
187 OPERATION_TOUCH_FACE_LAST_TIME = "touchFaceLastTime"
188 OPERATION_TOUCH_CELL_FIRST_TIME = "touchCellFirstTime"
189 OPERATION_TOUCH_CELL_LAST_TIME = "touchCellLastTime"
190
191 @abstractmethod
192 def get_body_of_operation(self, operation_name):
193 """!
194
195 Return actual C++ code snippets to be inserted into C++ code
196
197 See class' string constants starting with OPERATION_ for possible values
198 of operation_name.
199
200 """
201 return "// @todo Should be overwritten by mapping\n"
202
203 @abstractmethod
205 """!
206
207 Return unique action set name
208
209 Returns a description (word) for the mapping which is also used as class name
210 for the generated type. As a consequence, the result should be one word (if
211 possible) and uppercase. Also, every subclass should overwrite this routine.
212
213 The generator will take the result and construct eventually classes similar to
214 MyStep2Dummy.h and MyStep2Dummy.cpp or similar for the example below, where we
215 return Dummy.
216
217 """
218 return "Dummy"
219
220 @abstractmethod
222 """!
223
224 Is the user allowed to modify the output
225
226 Return whether you expect the user to modify the generated code. If this
227 is the case, then the API places the generated output in the directory
228 actions. Otherwise, it goes into the observer directory and will be
229 overwritten in each and every Python run.
230
231 """
232 return True
233
234 @abstractmethod
235 def get_attributes(self):
236 """!
237
238 Return attributes as copied and pasted into the generated class.
239
240 Please note that action sets are not persistent, i.e. there is one
241 object creation per grid sweep per tree.
242
243 """
244 return ""
245
246 @abstractmethod
247 def get_includes(self):
248 """!
249
250 Return include statements that you need.
251
252 All of these includes will eventually end up in the header of the generated
253 C++ code.
254
255 """
256 return ""
Action set (reactions to events)
Definition ActionSet.py:6
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
Definition ActionSet.py:192
__init__(self, descend_invocation_order=0, parallel=False)
Definition ActionSet.py:123
get_constructor_body(self)
Define a tailored constructor body.
Definition ActionSet.py:129
get_action_set_name(self)
Return unique action set name.
Definition ActionSet.py:204
get_attributes(self)
Return attributes as copied and pasted into the generated class.
Definition ActionSet.py:235
get_static_initialisations(self, full_qualified_classname)
Definition ActionSet.py:152
user_should_modify_template(self)
Is the user allowed to modify the output.
Definition ActionSet.py:221
get_includes(self)
Return include statements that you need.
Definition ActionSet.py:247