3#include "{{CLASSNAME}}.h"
29#if defined(UseSmartMPI)
30#include "communication/Tags.h"
39int {{NAMESPACE | join(
"::")}}::{{CLASSNAME}}::getEnclaveTaskTypeId() {
40 return _enclaveTaskTypeId;
43double {{NAMESPACE | join(
"::")}}::{{CLASSNAME}}::applyKernelToCell(
44 const ::peano4::datamanagement::CellMarker& marker,
47 double* __restrict__ reconstructedPatch,
48 double* __restrict__ targetPatch
52 {%
if STATELESS_PDE_TERMS %}
53 if (repositories::{{SOLVER_INSTANCE}}.patchCanUseStatelessPDETerms(
59 ::exahype2::fv::{{KERNEL_NAMESPACE}}::{{COMPUTE_KERNEL_CALL_STATELESS}}
63 ::exahype2::fv::{{KERNEL_NAMESPACE}}::{{COMPUTE_KERNEL_CALL}}
67 {{NUMBER_OF_UNKNOWNS}},
68 {{NUMBER_OF_AUXILIARY_VARIABLES}},
69 {{NUMBER_OF_VOLUMES_PER_AXIS}},
71 std::string(__FILE__) +
"(" + std::to_string(__LINE__) +
"): " +
marker.toString()
76 {%
if COMPUTE_MAX_EIGENVALUE %}
77 return patchData.maxEigenvalue[0];
83{{NAMESPACE | join(
"::")}}::{{CLASSNAME}}::{{CLASSNAME}}(
84 const ::peano4::datamanagement::CellMarker&
marker,
87 double* __restrict__ reconstructedPatch,
88 double* __restrict__ output
98 {{NUMBER_OF_DOUBLE_VALUES_IN_PATCH_PLUS_HALO_2D}},
99 {{NUMBER_OF_DOUBLE_VALUES_IN_PATCH_2D}},
101 {{NUMBER_OF_DOUBLE_VALUES_IN_PATCH_PLUS_HALO_3D}},
102 {{NUMBER_OF_DOUBLE_VALUES_IN_PATCH_3D}},
105 _maxEigenvalue = applyKernelToCell(
115 , smartmpi::Task(_enclaveTaskTypeId)
118 setPriority({{ENCLAVE_TASK_PRIORITY}});
123bool {{NAMESPACE | join(
"::")}}::{{CLASSNAME}}::isSmartMPITask()
const {
132void {{NAMESPACE | join(
"::")}}::{{CLASSNAME}}::runLocally() {
134 if (_remoteTaskId != -1) {
141void {{NAMESPACE | join(
"::")}}::{{CLASSNAME}}::moveTask(
int rank,
int tag, MPI_Comm communicator) {
146 if ( tag != smartmpi::communication::MoveTaskToMyServerForEvaluationTag &&
147 tag != smartmpi::communication::MoveTaskToComputesComputeRankTag ) {
148 taskIdMessage.
setValue(_remoteTaskId);
150 taskIdMessage.
setValue(getTaskId());
159 MPI_Isend( _inputValues, _numberOfInputValues, MPI_DOUBLE, rank, tag, communicator, &request );
163 "sent (" << _marker.toString() <<
"," << tMessage.toString() <<
"," << dtMessage.toString() <<
"," << _numberOfInputValues <<
164 "," << taskIdMessage.
toString() <<
") to rank " << rank <<
169smartmpi::Task* {{NAMESPACE | join(
"::")}}::{{CLASSNAME}}::receiveTask(
int rank,
int tag, MPI_Comm communicator) {
171 const int NumberOfInputValues =
173 {{NUMBER_OF_DOUBLE_VALUES_IN_PATCH_PLUS_HALO_2D}};
175 {{NUMBER_OF_DOUBLE_VALUES_IN_PATCH_PLUS_HALO_3D}};
191 "received (" << markerMessage.toString() <<
"," << tMessage.
toString() <<
"," << dtMessage.
toString() <<
"," << taskIdMessage.
toString() <<
") from rank " << rank <<
192 " via tag " << tag <<
" and will now receive " << NumberOfInputValues <<
" doubles"
195 MPI_Recv( inputValues, NumberOfInputValues, MPI_DOUBLE, rank, tag, communicator,
199 {{CLASSNAME}}* result =
new {{CLASSNAME}}(
205 result->_remoteTaskId = taskIdMessage.
getValue();
209void {{NAMESPACE | join(
"::")}}::{{CLASSNAME}}::runLocallyAndSendTaskOutputToRank(
int rank,
int tag, MPI_Comm communicator) {
217 "runLocallyAndSendTaskOutputToRank(...)",
218 "executed remote task on this rank. Will start to send result back"
221 forwardTaskOutputToRank(rank, tag, communicator);
224void {{NAMESPACE | join(
"::")}}::{{CLASSNAME}}::forwardTaskOutputToRank(
int rank,
int tag, MPI_Comm communicator) {
226 "forwardTaskOutputToRank(...)",
227 "will start to forward task output (which has already been computed)"
242 MPI_Isend( _outputValues, _numberOfResultValues, MPI_DOUBLE, rank, tag, communicator, &request );
245 "forwardTaskOutputToRank(...)",
246 "sent (" << _marker.toString() <<
"," << tMessage.
toString() <<
"," << dtMessage.
toString() <<
"," << _numberOfResultValues <<
247 "," << taskIdMessage.
toString() <<
") to rank " << rank <<
254smartmpi::Task* {{NAMESPACE | join(
"::")}}::{{CLASSNAME}}::receiveOutcome(
int rank,
int tag, MPI_Comm communicator,
const bool intentionToForward) {
255 logInfo(
"receiveOutcome(...)",
"rank=" << rank <<
", tag=" << tag );
257 const int NumberOfResultValues =
259 {{NUMBER_OF_DOUBLE_VALUES_IN_PATCH_2D}};
261 {{NUMBER_OF_DOUBLE_VALUES_IN_PATCH_3D}};
278 "receiveOutcome(...)",
279 "received (" << markerMessage.toString() <<
"," << tMessage.
toString() <<
"," << dtMessage.
toString() <<
"," << taskIdMessage.
toString() <<
") from rank " << rank <<
280 " via tag " << tag <<
" and will now receive " << NumberOfResultValues <<
" doubles"
283 MPI_Recv( outputValues, NumberOfResultValues, MPI_DOUBLE, rank, tag, communicator,
293 if(intentionToForward) {
294 double* inputValues =
nullptr;
296 {{CLASSNAME}}* result =
new {{CLASSNAME}}(
302 result->_remoteTaskId = taskIdMessage.
getValue();
303 result->_outputValues = outputValues;
304 result->_maxEigenvalue = eValueMessage.
getValue();
308 "receiveOutcome(...)",
309 "bookmark outcome of task " << taskIdMessage.
getValue()
317{%
if STATELESS_PDE_TERMS %}
319bool {{NAMESPACE | join(
"::")}}::{{CLASSNAME}}::canFuse()
const {
320 return repositories::{{SOLVER_INSTANCE}}.patchCanUseStatelessPDETerms(
332bool {{NAMESPACE | join(
"::")}}::{{CLASSNAME}}::fuse(
const std::list<Task*>& otherTasks,
int targetDevice) {
334 <<
" asked to fuse " << (otherTasks.size() + 1) <<
" tasks into one large GPU task on device " << targetDevice);
338 for (
auto& p: otherTasks) {
339 patchData.QIn[currentTask] =
static_cast<{{NAMESPACE | join("::")}}::{{CLASSNAME}}*
>(
p)->_inputValues;
340 patchData.cellCentre[currentTask] =
static_cast<{{NAMESPACE | join("::")}}::{{CLASSNAME}}*
>(
p)->_marker.x();
341 patchData.cellSize[currentTask] =
static_cast<{{NAMESPACE | join("::")}}::{{CLASSNAME}}*
>(
p)->_marker.h();
342 patchData.t[currentTask] =
static_cast<{{NAMESPACE | join("::")}}::{{CLASSNAME}}*
>(
p)->_t;
343 patchData.dt[currentTask] =
static_cast<{{NAMESPACE | join("::")}}::{{CLASSNAME}}*
>(
p)->_dt;
344 patchData.id[currentTask] =
static_cast<{{NAMESPACE | join("::")}}::{{CLASSNAME}}*
>(
p)->_taskNumber;
349 patchData.QIn[currentTask] = _inputValues;
350 patchData.cellCentre[currentTask] = _marker.x();
351 patchData.cellSize[currentTask] = _marker.h();
352 patchData.t[currentTask] = _t;
353 patchData.dt[currentTask] = _dt;
354 patchData.id[currentTask] = _taskNumber;
362 bool foundOffloadingBranch =
false;
364#if defined(GPUOffloadingOMP)
365 if (targetDevice >= 0) {
366 foundOffloadingBranch =
true;
367 ::exahype2::fv::{{KERNEL_NAMESPACE}}::omp::{{FUSED_COMPUTE_KERNEL_CALL_STATELESS_GPU}}
371#if defined(GPUOffloadingHIP)
372 if (targetDevice >= 0) {
373 foundOffloadingBranch =
true;
374 ::exahype2::fv::{{KERNEL_NAMESPACE}}::hip::{{FUSED_COMPUTE_KERNEL_CALL_STATELESS_GPU}}
378#if defined(GPUOffloadingSYCL)
379 if (targetDevice >= 0 or targetDevice == Host) {
380 foundOffloadingBranch =
true;
381 ::exahype2::fv::{{KERNEL_NAMESPACE}}::sycl::{{FUSED_COMPUTE_KERNEL_CALL_STATELESS_GPU}}
385#if defined(GPUOffloadingCPP)
386 if (targetDevice >= 0 or targetDevice == Host) {
387 foundOffloadingBranch =
true;
388 ::exahype2::fv::{{KERNEL_NAMESPACE}}::cpp::{{FUSED_COMPUTE_KERNEL_CALL_STATELESS_GPU}}
392 if (not foundOffloadingBranch) {
394 <<
" cannot find offloading branch for device " << targetDevice <<
". Process fused tasks on the CPU.");
395 ::exahype2::fv::{{KERNEL_NAMESPACE}}::{{FUSED_COMPUTE_KERNEL_CALL_STATELESS_CPU}}
403 for (
int i = 0;
i < patchData.numberOfCells;
i++) {
#define logDebug(methodName, logMacroMessageStream)
#define logInfo(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
static EnclaveBookkeeping & getInstance()
void finishedTask(int taskNumber, int numberOfResultValues, double *data, double maxEigenvalue)
Usually called directly by EnclaveTask.
static Rank & getInstance()
This operation returns the singleton instance.
tarch::logging::Log _log("exahype2::fv")
void validatePatch(const double *__restrict__ Q, int unknowns, int auxiliaryVariables, int numberOfVolumesPerAxisInPatch, int haloSize, const std::string &location="", bool triggerNonCriticalAssertion=true, double *minValues=nullptr, double *maxValues=nullptr)
Just runs over the patch and ensures that no entry is non or infinite.
For the generic kernels that I use here most of the time.
int getTaskType(const std::string &className)
Get unique number (id) for task.
void freeMemory(void *data, MemoryLocation location, int device=accelerator::Device::HostDevice)
Free memory.
@ ManagedSharedAcceleratorDeviceMemory
To be used on host only.
T * allocateMemory(std::size_t count, MemoryLocation location, int device=accelerator::Device::HostDevice)
Allocates memory on the specified memory location.
Representation of a number of cells which contains all information that's required to process the sto...
static void receive(CellMarker &buffer, int source, int tag, MPI_Comm communicator)
static void send(const CellMarker &buffer, int destination, int tag, MPI_Comm communicator)
In DaStGen (the first version), I had a non-static version of the send as well as the receive.
std::string toString() const
static void receive(tarch::mpi::DoubleMessage &buffer, int source, int tag, MPI_Comm communicator)
static void send(const tarch::mpi::DoubleMessage &buffer, int destination, int tag, MPI_Comm communicator)
In DaStGen (the first version), I had a non-static version of the send as well as the receive.
std::string toString() const
static void receive(tarch::mpi::IntegerMessage &buffer, int source, int tag, MPI_Comm communicator)
static void send(const tarch::mpi::IntegerMessage &buffer, int destination, int tag, MPI_Comm communicator)
In DaStGen (the first version), I had a non-static version of the send as well as the receive.