4from .AbstractRKFDActionSet
import AbstractRKFDActionSet
16 PreprocessSolution differs from other action sets, as I only create it once. See
17 FV.create_action_sets(). Once the instance does exist, you can tailor it. But you
18 can also completely overwrite it.
22 AbstractRKFDActionSet.__init__(self,solver)
34 return __name__.replace(
".py",
"").replace(
".",
"_")
41 Preprocess the solution and reconstruct halo for this
43 This action set preprocesses the solution. By default, it only plugs into the
44 very first grid sweep of a time step. That is, if you have a Runge-Kutta solver
45 and/or enclave solver, these guys usually need multiple sweeps. We only plug
46 into the very first one.
48 If it becomes active, it first of all creates an array called oldQWithHalo. It
49 is held on the heap and will be destroyed automatically later on. This array
50 is properly befilled. You can postprocess it, but if you alter entries
51 therein, these alterations will be lost after the preprocessing step.
53 ## Enclave solver variant
55 The action set can work in an enclave solver style or as plain invocation.
56 Plain invocation means we just reconstruct the patch plus halo, invoke a
57 compute kernel on it, and then free this reconstruction data structure
60 Enclave-style means that we do the reconstruction, but then embed the actual
61 operation and the freeing into a task. We use the actual enclave task number
62 as task number. Peano does not allow multiple tasks in the system with the
63 same number, so if an enclave task is spawned afterwards, we have a read-write-read
72 compute_kernel_implementation,
73 enclave_task_cell_label = None
77 Construct the preprocessing
79 If we work with an enclave task, the modelling is pretty straightforward.
80 However, we have to explicitly delete the reconstructed data structure
81 oldQWithHalo, as we tell the parent class not to delete stuff. If they
82 deleted the oldQWithHalo, it would be at the end of the function. At this
83 point our task might not have finished yet. We need the delete within the
86 @param enclave_task_cell_label: String or None
87 If this field is none, we do not use any tasking. If it is a string, we assume
88 it denotes a cell label (usually it is something similar to
89 fineGridCellMySolver_FD4CellLabel). In this case, we spawn a separate task as
93 if enclave_task_cell_label==
None:
94 functor_implementation = compute_kernel_implementation
95 reconstructed_array_memory_location = peano4.toolbox.blockstructured.ReconstructedArrayMemoryLocation.HeapThroughTarch
97 functor_implementation =
"""
98 auto taskBody = [=,this]() -> bool { """ + compute_kernel_implementation +
"""
99 ::tarch::freeMemory(oldQWithHalo, tarch::MemoryLocation::Heap );
104 marker.willBeEnclaveCell()
106 marker.hasBeenEnclaveCell()
111 assertion( """ + enclave_task_cell_label +
""".getSemaphoreNumber()<0 );
113 tarch::multicore::Task* newTask = new tarch::multicore::TaskWithCopyOfFunctor (
114 tarch::multicore::Task::DontFuse,
115 tarch::multicore::Task::DefaultPriority,
119 int newTaskNumber = ::exahype2::EnclaveTask::reserveTaskNumber();
121 tarch::multicore::spawnTask(
123 tarch::multicore::NoInDependencies,
127 """ + enclave_task_cell_label +
""".setSemaphoreNumber( newTaskNumber );
130 reconstructed_array_memory_location = peano4.toolbox.blockstructured.ReconstructedArrayMemoryLocation.HeapThroughTarchWithoutDelete
132 super(PreprocessReconstructedSolutionWithHalo,self).
__init__(patch = solver._patch,
133 patch_overlap = solver._patch_overlap_new,
134 functor_implementation = functor_implementation,
135 reconstructed_array_memory_location = reconstructed_array_memory_location,
136 guard =
"repositories::instanceOf" + solver._name +
".isFirstGridSweepOfTimeStep()",
137 add_assertions_to_halo_exchange =
False
142 return __name__.replace(
".py",
"").replace(
".",
"_")
146 return super(PreprocessReconstructedSolutionWithHalo,self).
get_includes() +
"""
148#include "exahype2/fd/PatchUtils.h"
149#include "exahype2/EnclaveTask.h"
150#include "tarch/multicore/Task.h"
151""" + self.
_solver._get_default_includes() + self.
_solver.user_action_set_includes
157 Preprocess solution mesh cell by mesh cell without mesh cell interactions
159 PreprocessSolution differs from other action sets, as I only create it once. See
160 FV.create_action_sets(). Once the instance does exist, you can tailor it. But you
161 can also completely overwrite it.
163 The postprocessing plugs into touch cell last time. It is the last action set added
164 by the default implementation. Therefore, it is the first action set of which
165 touchCellLastTime() is called. The reason why I plug into the leaving of the cell
166 is that some solvers may add further action sets to the solve. Enclave tasking for
167 example adds the merger as additional action set. These action sets plug into
168 touchCellFirstTime() - and consequently their first time is called after the
169 postprocessing's first time. By making the postprocessing use touchCellLastTime(),
170 I ensure that any additional action set added by a subclass can still precede the
176 AbstractRKFDActionSet.__init__(self,solver)
185 Add a code snippet which is applied to each and every point. You have the following
186 variables which are well-defined:
188 - value: Is a pointer to the current finite volume's data
189 - volumeX: A tarch::la::Vector over doubles
190 - volumeH: A tarch::la::Vector over doubles
193 operation_per_point: String
199 not marker.hasBeenRefined()
203 logTraceIn( "touchCellFirstTime(...)" );
205 dfor( volume, {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}} ) {
206 double* value = fineGridCell{{UNKNOWN_IDENTIFIER}}.value + index;
207 auto volumeX = ::exahype2::fv::getVolumeCentre( marker.x(), marker.h(), {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}}, volume);
208 auto volumeH = ::exahype2::fv::getVolumeSize( marker.h(), {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}});
210 """ + operation_per_point +
"""
212 index += {{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}};
214 logTraceOut( "touchCellFirstTime(...)" );
221 if operation_name==peano4.solversteps.ActionSet.OPERATION_TOUCH_CELL_LAST_TIME:
223 self.
_solver._init_dictionary_with_default_parameters(d)
224 self.
_solver.add_entries_to_text_replacement_dictionary(d)
225 d[
"PREDICATE" ] = jinja2.Template(self.
guard, undefined=jinja2.DebugUndefined).render(**d)
226 result = jinja2.Template(self.
_compute_kernel, undefined=jinja2.DebugUndefined).render(**d)
232 return __name__.replace(
".py",
"").replace(
".",
"_")
Preprocess solution mesh cell by mesh cell without mesh cell interactions.
__init__(self, solver)
solver: ADERDG Reference to creating class
get_action_set_name(self)
You should replicate this function in each subclass, so you get meaningful action set names (otherwis...
add_postprocessing_kernel(self, operation_per_point)
Add a code snippet which is applied to each and every point.
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
PreprocessSolution differs from other action sets, as I only create it once.
__init__(self, solver)
solver: ADERDG Reference to creating class
get_body_of_operation(self, operation_name)
Return actual C++ code snippets to be inserted into C++ code.
get_action_set_name(self)
You should replicate this function in each subclass, so you get meaningful action set names (otherwis...
Preprocess the solution and reconstruct halo for this.
get_includes(self)
Return include statements that you need.
get_action_set_name(self)
Return unique action set name.
__init__(self, solver, compute_kernel_implementation, enclave_task_cell_label=None)
Construct the preprocessing.