![]() |
Peano
|
Functions | |
void | runBenchmarks (int numberOfCells, double timeStamp, double timeStepSize, const tarch::la::Vector< DIMENSIONS, double > cellCenter, const tarch::la::Vector< DIMENSIONS, double > cellSize) |
Variables | |
tarch::logging::Log | _log |
This is variant 6 of the fused kernels. More... | |
void variant6::runBenchmarks | ( | int | numberOfCells, |
double | timeStamp, | ||
double | timeStepSize, | ||
const tarch::la::Vector< DIMENSIONS, double > | cellCenter, | ||
const tarch::la::Vector< DIMENSIONS, double > | cellSize | ||
) |
The construction here is a bit peculiar. Since we want to simulate there being 2*DIMENSIONS*numberOfCells faces, but each should share a pointer with one neighbouring cells' face Pointer, we have each face allocate the inner part of its data, i.e. the right side on left faces and the left side on right faces.
Then, in a second step, we have the non-allocated side point to the allocated side of the other face. This results in face having two valid pointers, but the total amount of allocated data fitting the model.
We also could have allocated all data on the lefts and have all the rights point, but I was slightly less confident about this being a good model for the actual data movements.
Definition at line 231 of file Variant6.cpp.
References variant1::_log, cellCenter, cellSize, exahype2::FaceData< inType, outType >::dt, exahype2::FaceData< inType, outType >::faceCentre, exahype2::FaceData< inType, outType >::faceSize, firstTask(), initialTask(), benchmarks::exahype2::kernelbenchmarks::initInputData(), benchmarks::exahype2::kernelbenchmarks::NumberOfInputEntriesPerCell, exahype2::FaceData< inType, outType >::QIn, exahype2::FaceData< inType, outType >::QOut, benchmarks::exahype2::kernelbenchmarks::reportRuntime(), secondTask(), exahype2::FaceData< inType, outType >::t, timeStamp, timeStepSize, and timingComputeKernel.
Referenced by main().
|
extern |
This is variant 6 of the fused kernels.
In this variant, we will assume that faceData is constructed per FACE, and that it contains data from both from sides of said face, i.e. the "left" and "right" sides. We assume that this data IS shared with the neighbour, i.e. there always exist two instances of a faceData object which share a pointer.
This means that the Riemann kernel can be performed only once per face, but it also means that we need to be careful about the order in which the cells are computed, as we have to assume that certain Riemann solvers have already been computed. The simplest solution to this is to assume a grid of cells, precompute the topmost, leftmost (,frontmost if 3D) Riemann solvers. After this we can iterate over the grid front-to-back in all three dimensions, first solving the Riemann problems on the negative side of the current cell while assuming that the problems on the positive side of the cell have already been solved.
This can be implemented as two enclave tasks, with the first being solving the pre-required Riemann problems, and the second being solving the problems inside of all of the cells.
Upsides: only one dependency which occurs between timesteps Riemann kernels are only performed once per face No copying or duplicating of data whatsoever
Downsides: Cells cannot be performed independently, they require specific orders Costly data dependency at the beginning of the step due to the initial Riemann solves