32 alter_particle_position,
33 use_continuous_particles_sequences,
36 synchronise_task_graph_after_each_mesh_sweep=
True,
40 Translate one step of species into mesh traversal
42 We create a new step and then add various different action sets depending
43 on the context and behaviour. Once befilled, the new step is appended to
46 1. If this is an initialisation sequence, then I clear all the task
47 markers. This is to ensure that they do not hold any garbage. I can
48 clear the set as often as I want. It is just important that I clear
49 it at least once per particle species.
50 2. Update the task markers. This is something each and every step in Peano
51 does. As we inject the update into each and every action set, we become
52 independent of the AMR and when it is actually realised.
53 3. Pick computational kernel. This is where the actual computation per step
54 is done. We have two fundamentally different kernels: one keeps track of
55 (multiscale) neighbours, while the other just updates the particles
56 within the octant (cell).
57 4. If an action set alters the position or cut-off of a particle, then we
58 append True to alter_particle_position. Otherwise, we append False.
59 This is decided from step.effect, i.e. whether it is one of the
60 CHANGE_POSITION_OR_INTERACTION_RADIUS(_AND_MIGHT_RERUN) variants.
61 @see AlgorithmStep.may_trigger_rerun()
63 Here's where the action set differs completely from the Sequential graph
64 compiler. If we change a position, we erase all the task indices from
67 In general, we never assign any index to touchCellLastTime(), as ExaParty does
68 not only one type of plug-in points. This is actually touchCellFirstTime()
69 in the realisation, so one might be tempted to mask out touchCellLastTime()
70 and only use task indices for touchCellFirstTime(). However, we have to
71 plug into touchVertexLastTime(), too, and this one has to know about events
72 within the adjacent cells. The action set AssignTaskNumbersToMesh memorises
73 the touchCellLastTime() indices within the vertices, to we use the numbers
74 from touchCellLastTime() but actually plug into touchCellFirstTime().
77 @param current_species_set: Particle
78 You get a specific algorithmic step as input. The current_species_set
79 highlights to which this step originally belonged to.
81 @param mesh_traversals: [peano4.api.solversteps.Step]
82 Inout parameter. We append a new step to this sequence.
84 @param alter_particle_position: [Bool]
85 Inout parameter. We append a new marker to this sequence.
87 @param synchronise_task_graph_after_each_mesh_sweep: Bool
88 If set, the arising action set ill call a tarch::multicore::waitForAllTasks()
89 after each mesh traversal.
93 ## Use it to construct task graphs
95 The routine is not expected to have an argument synchronise_task_graph_after_each_mesh_sweep
96 in Sequential. But I want to use the routines from Sequential. So I give
97 this value a default value. This way, I can reuse the routine in TaskGraph,
98 where I simply redefine the default.
102 "{}{}{}_sweep{}".format(
103 get_observer_prefix(step_type),
104 current_species_set.particle_model.name,
106 len(mesh_traversals),
108 add_user_defined_actions=
False,
112 particle_set=current_species_set,
113 automatically_set_marker_in_leave_cell=
False,
114 make_reset_separate_task=
True,
116 action_set_update_marker.descend_invocation_order = (
117 new_step.highest_descend_invocation_order() + 1
119 action_set_update_marker.parallel =
True
120 new_step.add_action_set(action_set_update_marker)
123 "GRAPH COMPILER DEBUG [translate_one_step_of_species_into_mesh_traversal]: step no {} ({}) on particle {} uses UpdateParticleMarker".format(
124 len(mesh_traversals),
126 current_species_set.particle_model.name,
134 current_step_alters_particle_position = (
136 == AlgorithmStep.Effect.CHANGE_POSITION_OR_INTERACTION_RADIUS_AND_MIGHT_RERUN
137 or step.effect == AlgorithmStep.Effect.CHANGE_POSITION_OR_INTERACTION_RADIUS
144 synchronise_after_each_mesh_traversal = (
145 step.effect == AlgorithmStep.Effect.ALTER_GLOBAL_STATE
146 or step.effect == AlgorithmStep.Effect.ALTER_GLOBAL_STATE_AND_MIGHT_RERUN
147 or step.effect == AlgorithmStep.Effect.ALTER_LOCAL_STATE_AND_MIGHT_RERUN
148 or step.effect == AlgorithmStep.Effect.CHANGE_POSITION_OR_INTERACTION_RADIUS
149 or step.effect == AlgorithmStep.Effect.CHANGE_POSITION_OR_INTERACTION_RADIUS_AND_MIGHT_RERUN
150 or synchronise_task_graph_after_each_mesh_sweep
161 if step.dependencies == AlgorithmStep.Dependencies.NEIGHBOURS:
162 if use_continuous_particles_sequences:
165 "GRAPH COMPILER DEBUG [translate_one_step_of_species_into_mesh_traversal]: step no {} ({}) on particle {} can use the peano4.api.toolbox.particles.UpdateParticle_MultiLevelInteraction_StackOfLists_ContiguousParticles action set and hence optimise aggressively".format(
166 len(mesh_traversals),
168 current_species_set.particle_model.name,
172 particle_set=current_species_set,
173 particle_particle_interaction_kernel=step.cell_kernel,
174 touch_vertex_first_time_compute_particle_update_kernel=step.touch_vertex_first_time_kernel,
175 touch_vertex_last_time_compute_particle_update_kernel=step.touch_vertex_last_time_kernel,
176 prepare_traversal_kernel=step.prepare_traversal_kernel,
177 unprepare_traversal_kernel=step.unprepare_traversal_kernel,
178 additional_includes=step.includes,
179 active_particle_set=step.input_particles,
180 alter_particle_position_or_interaction_radius=current_step_alters_particle_position,
181 wait_for_all_tasks_to_finish_after_traversal=synchronise_after_each_mesh_traversal,
186 "GRAPH COMPILER DEBUG [translate_one_step_of_species_into_mesh_traversal]: step no {} ({}) on particle {} uses the peano4.api.toolbox.particles.UpdateParticle_MultiLevelInteraction_Sets".format(
187 len(mesh_traversals),
189 current_species_set.particle_model.name,
193 particle_set=current_species_set,
194 particle_particle_interaction_kernel=step.cell_kernel,
195 touch_vertex_first_time_compute_particle_update_kernel=step.touch_vertex_first_time_kernel,
196 touch_vertex_last_time_compute_particle_update_kernel=step.touch_vertex_last_time_kernel,
197 prepare_traversal_kernel=step.prepare_traversal_kernel,
198 unprepare_traversal_kernel=step.unprepare_traversal_kernel,
199 additional_includes=step.includes,
200 active_particle_set=step.input_particles,
201 alter_particle_position_or_interaction_radius=current_step_alters_particle_position,
202 wait_for_all_tasks_to_finish_after_traversal=synchronise_after_each_mesh_traversal,
204 action_set_particle_particle_interaction.descend_invocation_order = (
205 new_step.highest_descend_invocation_order() + 1
207 action_set_particle_particle_interaction.parallel =
True
208 new_step.add_action_set(action_set_particle_particle_interaction)
209 elif step.dependencies == AlgorithmStep.Dependencies.SELF:
210 if use_continuous_particles_sequences:
213 "GRAPH COMPILER DEBUG [translate_one_step_of_species_into_mesh_traversal]: step no {} ({}) on particle {} uses peano4.api.toolbox.particles.UpdateParticle_SingleLevelInteraction_ContiguousParticles action set".format(
214 len(mesh_traversals),
216 current_species_set.particle_model.name,
221 particle_set=current_species_set,
222 particle_cell_update_kernel=step.cell_kernel,
223 touch_vertex_first_time_compute_particle_update_kernel=step.touch_vertex_first_time_kernel,
224 touch_vertex_last_time_compute_particle_update_kernel=step.touch_vertex_last_time_kernel,
225 prepare_traversal_kernel=step.prepare_traversal_kernel,
226 unprepare_traversal_kernel=step.unprepare_traversal_kernel,
227 additional_includes=step.includes,
228 active_particle_set=step.input_particles,
229 alter_particle_position_or_interaction_radius=current_step_alters_particle_position,
230 wait_for_all_tasks_to_finish_after_traversal=synchronise_after_each_mesh_traversal,
232 action_set_particle_update.descend_invocation_order = (
233 new_step.highest_descend_invocation_order() + 1
235 action_set_particle_update.parallel =
True
236 new_step.add_action_set(action_set_particle_update)
240 "GRAPH COMPILER DEBUG [translate_one_step_of_species_into_mesh_traversal]: step no {} ({}) on particle {} uses peano4.api.toolbox.particles.UpdateParticle_SingleLevelInteraction action set".format(
241 len(mesh_traversals),
243 current_species_set.particle_model.name,
248 particle_set=current_species_set,
249 particle_cell_update_kernel=step.cell_kernel,
250 touch_vertex_first_time_compute_particle_update_kernel=step.touch_vertex_first_time_kernel,
251 touch_vertex_last_time_compute_particle_update_kernel=step.touch_vertex_last_time_kernel,
252 prepare_traversal_kernel=step.prepare_traversal_kernel,
253 unprepare_traversal_kernel=step.unprepare_traversal_kernel,
254 additional_includes=step.includes,
255 active_particle_set=step.input_particles,
256 alter_particle_position_or_interaction_radius=current_step_alters_particle_position,
257 wait_for_all_tasks_to_finish_after_traversal=synchronise_after_each_mesh_traversal,
259 action_set_particle_update.descend_invocation_order = (
260 new_step.highest_descend_invocation_order() + 1
262 action_set_particle_update.parallel =
True
263 new_step.add_action_set(action_set_particle_update)
265 assert False,
"step {} seems to have no action at all".format(step)
270 if current_step_alters_particle_position:
271 alter_particle_position.append(
True)
273 alter_particle_position.append(
False)
282 current_species_set.name,
284 action_set_assign_task_markers.descend_invocation_order = (
285 new_step.lowest_descend_invocation_order() - 1
287 action_set_assign_task_markers.parallel =
True
288 new_step.add_action_set(action_set_assign_task_markers)
291 "GRAPH COMPILER DEBUG [translate_one_step_of_species_into_mesh_traversal]: step no {} ({}) on particle {} is added peano4.api.toolbox.api.AssignNumbersToMesh".format(
292 len(mesh_traversals),
294 current_species_set.particle_model.name,
298 mesh_traversals.append(new_step)