Peano
Loading...
Searching...
No Matches
RefinementControlService.cpp
Go to the documentation of this file.
2
3#include "RefinementControl.h"
4#include "peano4/grid/grid.h"
7
8tarch::logging::Log exahype2::RefinementControlService::_log("exahype2::RefinementControlService");
9
11 "RefinementControlService"));
12
14
19
23
27
29
31#ifdef Parallel
32 int guardFlag;
33 MPI_Iprobe(
34 MPI_ANY_SOURCE, _reductionTag, tarch::mpi::Rank::getInstance().getCommunicator(), &guardFlag, MPI_STATUS_IGNORE
35 );
36
37 if (guardFlag) {
38 tarch::multicore::RecursiveLock lock(_semaphore);
39
40 MPI_Status status;
41 int flag;
42 MPI_Iprobe(MPI_ANY_SOURCE, _reductionTag, tarch::mpi::Rank::getInstance().getCommunicator(), &flag, &status);
43 if (flag) {
44 const int rank = status.MPI_SOURCE;
45 int numberOfMessages;
46 MPI_Get_count(&status, peano4::grid::GridControlEvent::getGlobalCommunciationDatatype(), &numberOfMessages);
47
48 logDebug("receiveDanglingMessages()", "got " << numberOfMessages << " event(s) from rank " << rank);
49
50 std::vector<peano4::grid::GridControlEvent> receiveBuffer;
51 receiveBuffer.resize(numberOfMessages);
52 MPI_Recv(
53 receiveBuffer.data(),
54 numberOfMessages,
56 rank,
57 _reductionTag,
59 MPI_STATUS_IGNORE
60 );
61
62 for (auto p : receiveBuffer) {
63 _remoteNewEvents.push_back(p);
64 _committedEvents.push_back(p);
65 }
66
68 "receiveDanglingMessages()",
69 "now hold "
70 << _remoteNewEvents.size() << " new remote events and " << _committedEvents.size()
71 << " committed events (valid for this traversal)"
72 );
73 }
74 }
75#endif
76}
77
79 std::ostringstream msg;
80 msg
81 << "("
82 << "#new-local-events=" << _localNewEvents.size() << "#new-remote-events=" << _remoteNewEvents.size()
83 << ",#committed-events=" << _committedEvents.size() << ")";
84 return msg.str();
85}
86
88 tarch::multicore::RecursiveLock lock(_semaphore);
89 _localNewEvents.insert(_localNewEvents.end(), control._newEvents.begin(), control._newEvents.end());
90}
91
93 tarch::multicore::RecursiveLock lock(_semaphore);
94
95 _committedEvents.clear();
96
97 int maxLifetime = 0;
98 RefinementControl::NewEvents::iterator p = _localNewEvents.begin();
99 while (p != _localNewEvents.end()) {
100 _committedEvents.push_back(p->first);
101 p->second--;
102
103 if (p->second <= 0) {
104 p = _localNewEvents.erase(p);
105 } else {
106 maxLifetime = std::max(maxLifetime, p->second);
107 p++;
108 }
109 }
110
111 if (not _committedEvents.empty()) {
112 logInfo(
113 "finishStep()",
114 "activate "
115 << _committedEvents.size()
116 << " refinement/erase instructions (can be taken into account in next grid sweep). Keep "
117 << _localNewEvents.size() << " local event(s) to be re-delivered later (max lifetime " << maxLifetime
118 << ") besides the " << _remoteNewEvents.size() << " remote events which will also be re-delivered next"
119 );
120 }
121
122#ifdef Parallel
123 freeAllPendingSendRequests();
124 _copyOfCommittedEvents = _committedEvents;
125 triggerSendOfCopyOfCommittedEvents();
126#endif
127
128 for (auto p : _remoteNewEvents) {
129 _committedEvents.push_back(p);
130 }
131 _remoteNewEvents.clear();
132
133 _committedEvents = ::peano4::grid::merge(_committedEvents);
134}
135
136#ifdef Parallel
138 while (not _sendRequests.empty()) {
139 std::vector<MPI_Request*>::iterator p = _sendRequests.begin();
140 while (p != _sendRequests.end()) {
141 if (*p == nullptr) {
142 p = _sendRequests.erase(p);
143 } else {
144 int flag;
145 MPI_Test(*p, &flag, MPI_STATUS_IGNORE);
146 if (flag) {
147 *p = nullptr;
148 }
149 p++;
150 }
151 }
153 }
154}
155
157 _sendRequests.clear();
158
159 logInfo(
160 "triggerSendOfCopyOfCommittedEvents()", "share my " << _copyOfCommittedEvents.size() << " event(s) with others"
161 );
162 if (_copyOfCommittedEvents.size() > 0) {
163 _sendRequests = std::vector<MPI_Request*>(tarch::mpi::Rank::getInstance().getNumberOfRanks(), nullptr);
164 for (int rank = 0; rank < tarch::mpi::Rank::getInstance().getNumberOfRanks(); rank++) {
165 if (rank != tarch::mpi::Rank::getInstance().getRank()) {
166 _sendRequests[rank] = new MPI_Request;
167 MPI_Isend(
168 _copyOfCommittedEvents.data(),
169 _copyOfCommittedEvents.size(),
171 rank,
172 _reductionTag,
174 _sendRequests[rank]
175 );
176 }
177 }
178 }
179}
180#endif
181
182std::vector<peano4::grid::GridControlEvent> exahype2::RefinementControlService::getGridControlEvents() const {
183 return _committedEvents;
184}
#define logDebug(methodName, logMacroMessageStream)
Definition Log.h:50
#define logInfo(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
Definition Log.h:411
virtual void receiveDanglingMessages() override
Receive refinement control messages as shared by other ranks.
void merge(const RefinementControl &control)
static tarch::multicore::RecursiveSemaphore _semaphore
static RefinementControlService & getInstance()
std::vector< peano4::grid::GridControlEvent > getGridControlEvents() const
void freeAllPendingSendRequests()
Complete pending sends from previous mesh traversal.
static int _reductionTag
I need a tag of my own to exchange control info after each step.
void finishStep()
Should be called after each traversal per rank.
Manage refine/erase requests within ExaHyPE 2.
NewEvents _newEvents
Container to accumulate new events.
Log Device.
Definition Log.h:516
int getNumberOfRanks() const
Definition Rank.cpp:552
static Rank & getInstance()
This operation returns the singleton instance.
Definition Rank.cpp:539
int getRank() const
Return rank of this node.
Definition Rank.cpp:529
static int reserveFreeTag(const std::string &fullQualifiedMessageName, int numberOfTags=1)
Return a Free Tag.
Definition Rank.cpp:39
MPI_Comm getCommunicator() const
Definition Rank.cpp:545
Create a lock around a boolean semaphore region.
virtual void receiveDanglingMessages() override
Answer to MPI Messages.
static ServiceRepository & getInstance()
void removeService(Service *const service)
This routine is thread-safe, i.e.
void addService(Service *const service, const std::string &name)
Add a new service.
std::vector< GridControlEvent > merge(std::vector< GridControlEvent > events, const double Tolerance=0.1)
Merge set of refinement/coarsening commands.
Definition grid.cpp:112
static MPI_Datatype getGlobalCommunciationDatatype()