196 Add dependency checks as well as mesh consistency checks to the algorithm steps
198 This function actually modifies the AlgorithmSteps to contain the
199 debug dependency checks. Is called by self._add_dependency_checks()
200 and uses the validation routines from exaparty::dependencychecks.
202 The routine is used to either add checks for the init phase or the
203 actual time stepping. Which one is meant is identified through
204 step_type_name. You can obviously call the routine twice: once for
205 init and once for the time stepping. Later on, you might want to
208 Besides the name of interest, we also require a list of algorithmic
209 steps through which the code runs through.
214 If the user does not define bespoke default settings, this routine adds
215 default ones. These are set through instances of exaparty::dependencychecks::Invariant.
217 - For vertices, this is touch-at-most-once-mask-out-otherwise-all-previous-steps-update-at-least-once.
218 - For cells, this is also touch-at-most-once-mask-out-otherwise-all-previous-steps-update-at-least-once.
220 For any step whose effect may trigger a rerun, we switch to the
221 _SweepMayRerun variant of the invariant instead, as such a step may
222 legitimately touch a particle more than once within a sweep.
223 @see AlgorithmStep.may_trigger_rerun()
225 ## Additional attributes
227 First, the particle is added two counters which count up how often a
228 particle is touched or masked out.
230 @param Steplist: list
231 list of AlgorithmStep objects to work on
233 @param step_type_name: str
234 name of type of steps we're dealing with. Either AlgorithmStep
237 @param peano4_event_enum: list
238 list of enums of peano4 events within a single mesh traversal
239 (e.g. touch vertex first time, cell kernel, ...)
242 the modified list of AlgorithmSteps, now including dependency checks
245 steps = copy.deepcopy(steplist)
247 nevents = AlgorithmStep.PeanoEventUsedBySwift.EVENT_COUNT.value
252 step_name_list = [step.name
for step
in steps]
253 step_name_list.append(
"count")
259 self.
data.add_attribute(step_name_enum)
267 self.
data.add_attribute(number_of_updates)
274 self.
data.add_attribute(number_of_mask_outs)
277 check_template_cell_operation =
"""
278 ::exaparty::dependencychecks::check{STEP_TYPE}(
279 ::exaparty::dependencychecks::Invariant::{INVARIANT},
283 globaldata::{NAME}::DependencyChecks{STEP_TYPE}LastUpdated::{STEP_NAME},
284 globaldata::{NAME}::{PEANO4_EVENT_TYPE}::{EVENT},
290 check_template_vertex_operation =
"""
291 ::exaparty::dependencychecks::check{STEP_TYPE}(
292 ::exaparty::dependencychecks::Invariant::{INVARIANT},
295 globaldata::{NAME}::DependencyChecks{STEP_TYPE}LastUpdated::{STEP_NAME},
296 globaldata::{NAME}::{PEANO4_EVENT_TYPE}::{EVENT},
302 mark_template_cell_operation =
"""
303 ::exaparty::dependencychecks::mark{STEP_TYPE}(
307 globaldata::{NAME}::DependencyChecks{STEP_TYPE}LastUpdated::{STEP_NAME},
308 globaldata::{NAME}::{PEANO4_EVENT_TYPE}::{EVENT},
309 ::exaparty::dependencychecks::Invariant::{INVARIANT},
315 mark_template_vertex_operation =
"""
316 ::exaparty::dependencychecks::mark{STEP_TYPE}(
319 globaldata::{NAME}::DependencyChecks{STEP_TYPE}LastUpdated::{STEP_NAME},
320 globaldata::{NAME}::{PEANO4_EVENT_TYPE}::{EVENT},
321 ::exaparty::dependencychecks::Invariant::{INVARIANT},
327 check_template_vertex_operation_local_particles_after_sweep =
"""
328 ::exaparty::dependencychecks::checkParticlesAssignedToVertexInTouchLastTime{STEP_TYPE}(
329 ::exaparty::dependencychecks::Invariant::{INVARIANT},
331 globaldata::{NAME}::DependencyChecks{STEP_TYPE}LastUpdated::{STEP_NAME},
336 for i, step
in enumerate(steps):
339 "STEP_TYPE": step_type_name,
340 "STEP_NAME": step.name,
341 "PEANO4_EVENT_TYPE": peano4_event_enum.get_accessor_name(),
342 "CHECK_FUNCTION":
None,
347 step.prepare_traversal_kernel = (
349 toolbox::particles::assignmentchecks::startMeshSweep( "{}" );
353 + step.prepare_traversal_kernel
357 step.touch_vertex_first_time_dependency_policy ==
None
358 and AlgorithmStep.may_trigger_rerun(step.effect)
362 ] =
"TouchFirstUsage_MaskOutAfterwards_AllPreviousStepsUpdateAtLeastOnce_SweepMayRerun"
363 elif step.touch_vertex_first_time_dependency_policy ==
None:
366 ] =
"TouchFirstUsage_MaskOutAfterwards_AllPreviousStepsUpdateAtLeastOnce"
368 d[
"INVARIANT"] = step.touch_vertex_first_time_dependency_policy
372 d[
"EVENT"] = AlgorithmStep.get_event_name(
373 AlgorithmStep.PeanoEventUsedBySwift.TOUCH_VERTEX_FIRST_TIME
377 ] =
"::exaparty::kernels::localParticleCanBeUpdatedInVertexKernel<globaldata::{}>".format(
381 if step.touch_vertex_first_time_kernel
is None:
382 step.touch_vertex_first_time_kernel =
""
387 step.touch_vertex_first_time_kernel = (
388 "\n ::exaparty::dependencychecks::clearDependencyChecks"
390 +
"(assignedParticles);\n"
391 + mark_template_vertex_operation.format(**d)
392 + step.touch_vertex_first_time_kernel
395 step.touch_vertex_first_time_kernel = (
396 mark_template_vertex_operation.format(**d)
397 + step.touch_vertex_first_time_kernel
401 step.touch_vertex_first_time_kernel += (
402 check_template_vertex_operation.format(**d)
407 d[
"EVENT"] = AlgorithmStep.get_event_name(
408 AlgorithmStep.PeanoEventUsedBySwift.CELL_KERNEL
412 ] =
"::exaparty::kernels::localParticleCanBeUpdatedInCellKernelFromAnyOtherParticle<globaldata::{}>".format(
417 step.cell_kernel_dependency_policy ==
None
418 and AlgorithmStep.may_trigger_rerun(step.effect)
422 ] =
"TouchAtMostOnce_MaskOutOtherwise_AllPreviousStepsUpdateAtLeastOnce_SweepMayRerun"
423 elif step.cell_kernel_dependency_policy ==
None:
426 ] =
"TouchAtMostOnce_MaskOutOtherwise_AllPreviousStepsUpdateAtLeastOnce"
428 d[
"INVARIANT"] = step.cell_kernel_dependency_policy
430 if step.cell_kernel
is None:
431 step.cell_kernel =
""
434 mark_template_cell_operation.format(**d) + step.cell_kernel
438 step.cell_kernel += check_template_cell_operation.format(**d)
442 d[
"EVENT"] = AlgorithmStep.get_event_name(
443 AlgorithmStep.PeanoEventUsedBySwift.TOUCH_VERTEX_LAST_TIME
447 ] =
"::exaparty::kernels::localParticleCanBeUpdatedInVertexKernel<globaldata::{}>".format(
452 step.touch_vertex_last_time_dependency_policy ==
None
453 and AlgorithmStep.may_trigger_rerun(step.effect)
457 ] =
"TouchFirstUsage_MaskOutAfterwards_AllPreviousStepsUpdateAtLeastOnce_SweepMayRerun"
458 elif step.touch_vertex_last_time_dependency_policy ==
None:
461 ] =
"TouchFirstUsage_MaskOutAfterwards_AllPreviousStepsUpdateAtLeastOnce"
463 d[
"INVARIANT"] = step.touch_vertex_last_time_dependency_policy
465 if step.touch_vertex_last_time_kernel
is None:
466 step.touch_vertex_last_time_kernel =
""
468 step.touch_vertex_last_time_kernel = (
469 mark_template_vertex_operation.format(**d)
470 + step.touch_vertex_last_time_kernel
474 step.touch_vertex_last_time_kernel += (
475 check_template_vertex_operation.format(**d)
481 step.touch_vertex_last_time_kernel += (
482 check_template_vertex_operation_local_particles_after_sweep.format(**d)