Peano 4
Loading...
Searching...
No Matches
SieveParticles.cpph
Go to the documentation of this file.
4
5
6template <typename T>
7tarch::logging::Log toolbox::particles::SieveParticles<T>::_log("toolbox::particles::SieveParticles<T>");
8
9
10template <typename T>
12 "toolbox::particles::"
13 "SieveParticles<T>::_"
14 "SieveReductionTag"
15);
16
17
18template <typename T>
20
21
22template <typename T>
24
25
26template <typename T>
28 for (auto* p : list) {
29 delete p;
30 }
31 list.clear();
32}
33
34
35template <typename T>
37 logDebug("finishedTraversal()", "there are " << _particlesThatHaveToBeSieved.size() << " sieve sets (each tied to one tree or the global sorting, respectively)");
38
39 deleteParticles(_particlesThatHaveToBeSieved);
40
41#ifdef Parallel
42 const int numberOfParticlesToSend = _particlesThatCanNotBeLiftedWithinTheirTree.size();
43 logDebug("finishedTraversal()", "inform all other ranks that I host " << numberOfParticlesToSend << " particles that cannot be sorted locally. Use tag " << _SieveReductionTag);
44 for (int rank = 0; rank < tarch::mpi::Rank::getInstance().getNumberOfRanks(); rank++) {
45 if (rank != tarch::mpi::Rank::getInstance().getRank()) {
46 tarch::mpi::IntegerMessage message(numberOfParticlesToSend);
47 tarch::mpi::IntegerMessage::sendAndPollDanglingMessages(message, rank, _SieveReductionTag, tarch::mpi::Rank::getInstance().getCommunicator());
48 }
49 }
50
51 logDebug("finishedTraversal()", "pack send information (vector of pointers) into array");
52 std::vector<T> sendBuffer; // no pointers here
53 sendBuffer.resize(numberOfParticlesToSend);
54 int i = 0;
55 for (auto& p : _particlesThatCanNotBeLiftedWithinTheirTree) {
56 sendBuffer[i] = *p;
57 i++;
58 }
59
60 for (int rank = 0; rank < tarch::mpi::Rank::getInstance().getNumberOfRanks(); rank++) {
61 if (rank != tarch::mpi::Rank::getInstance().getRank()) {
62 logDebug("finishedTraversal()", "ask rank " << rank << " how many messages have to be received");
63 tarch::mpi::IntegerMessage numberOfReceivedMessages;
64 tarch::mpi::IntegerMessage::receiveAndPollDanglingMessages(numberOfReceivedMessages, rank, _SieveReductionTag, tarch::mpi::Rank::getInstance().getCommunicator());
65 logDebug("finishedTraversal()", "will receive " << numberOfReceivedMessages.getValue() << " particles from rank " << rank);
66
67 MPI_Request* sendRequest = nullptr;
68 MPI_Request* receiveRequest = nullptr;
69
70 std::vector<T> receiveBuffer; // no pointers here
71 if (numberOfReceivedMessages.getValue() > 0) {
72 receiveRequest = new MPI_Request();
73 receiveBuffer.resize(numberOfReceivedMessages.getValue());
74 MPI_Irecv(
75 receiveBuffer.data(),
76 numberOfReceivedMessages.getValue(),
77 T::getGlobalCommunciationDatatype(),
78 rank,
79 _SieveReductionTag,
81 receiveRequest
82 );
83 }
84
85 if (numberOfParticlesToSend > 0) {
86 sendRequest = new MPI_Request();
87 MPI_Isend(
88 sendBuffer.data(),
89 numberOfParticlesToSend, // this is important
90 T::getGlobalCommunciationDatatype(),
91 rank,
92 _SieveReductionTag,
94 sendRequest
95 );
96 }
97
98 logDebug("finishedTraversal()", "issued my sends and receives");
99 int flag = 0;
102 while (not flag) {
103 int sendFlag = 1;
104 int receiveFlag = 1;
105 if (sendRequest != nullptr)
106 MPI_Test(sendRequest, &sendFlag, MPI_STATUS_IGNORE);
107 if (receiveRequest != nullptr)
108 MPI_Test(receiveRequest, &receiveFlag, MPI_STATUS_IGNORE);
109 flag = sendFlag and receiveFlag;
110
111 tarch::mpi::Rank::getInstance().writeTimeOutWarning("toolbox::particles::ParticleSet", "finishedTraversal()", rank, _SieveReductionTag);
112 tarch::mpi::Rank::getInstance().triggerDeadlockTimeOut("toolbox::particles::ParticleSet", "finishedTraversal()", rank, _SieveReductionTag);
114 }
115
116 logDebug("finishedTraversal()", "append " << receiveBuffer.size() << " messages to local sieve particle list");
117 for (int i = 0; i < numberOfReceivedMessages.getValue(); i++) {
118 _particlesThatHaveToBeSieved.push_back(new T(receiveBuffer[i]));
119 }
120
121 if (sendRequest != nullptr)
122 delete sendRequest;
123 if (receiveRequest != nullptr)
124 delete receiveRequest;
125 }
126 }
127#endif
128
129 _particlesThatHaveToBeSieved.insert(
130 _particlesThatHaveToBeSieved.end(), _particlesThatCanNotBeLiftedWithinTheirTree.begin(), _particlesThatCanNotBeLiftedWithinTheirTree.end()
131 );
132
133 // shallow clear, as the pointers have already been rolled over into _particlesThatHaveToBeSieved
134 _particlesThatCanNotBeLiftedWithinTheirTree.clear();
135}
136
137
138template <typename T>
140 _particlesThatCanNotBeLiftedWithinTheirTree.push_back(p);
141}
142
143
144template <typename T>
146 return _particlesThatHaveToBeSieved.size();
147}
148
149
150template <typename T>
152 return not _particlesThatHaveToBeSieved.empty();
153}
154
155
156template <typename T>
159 bool removeReturnedParticlesFromSet,
160 bool onlyReturnParticlesThatWillBeLocal
161) {
162 tarch::multicore::Lock lock(_particlesToBeSievedSemaphore, removeReturnedParticlesFromSet);
163
164 ParticleList result;
165 typename ParticleList::iterator p = _particlesThatHaveToBeSieved.begin();
166 while (p != _particlesThatHaveToBeSieved.end()) {
167 bool willBeLocal = toolbox::particles::particleAssignedToVertexWillBeLocal( (*p)->getX(), marker );
168 if (
170 and
171 (willBeLocal or not onlyReturnParticlesThatWillBeLocal)
172 ) {
173 logDebug("getParticlesToBeSievedIntoVertex(...)", "drop particle " << (*p)->toString() << " from global sieve list into vertex " << marker.toString());
174
175 (*p)->setCellH(marker.h());
176
177 result.push_back(*p);
178 if (removeReturnedParticlesFromSet) {
179 p = _particlesThatHaveToBeSieved.erase(p);
180 }
181 else {
182 p++;
183 }
184 } else {
185 p++;
186 }
187 }
188 return result;
189}
#define logDebug(methodName, logMacroMessageStream)
Definition Log.h:50
Log Device.
Definition Log.h:516
int getNumberOfRanks() const
Definition Rank.cpp:551
void triggerDeadlockTimeOut(const std::string &className, const std::string &methodName, int communicationPartnerRank, int tag, int numberOfExpectedMessages=1, const std::string &comment="")
Triggers a time out and shuts down the cluster if a timeout is violated.
Definition Rank.cpp:119
void setDeadlockWarningTimeStamp()
Memorise global timeout.
Definition Rank.cpp:188
void writeTimeOutWarning(const std::string &className, const std::string &methodName, int communicationPartnerRank, int tag, int numberOfExpectedMessages=1)
Writes a warning if relevant.
Definition Rank.cpp:143
void setDeadlockTimeOutTimeStamp()
Definition Rank.cpp:193
static Rank & getInstance()
This operation returns the singleton instance.
Definition Rank.cpp:538
int getRank() const
Return rank of this node.
Definition Rank.cpp:528
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:544
Create a lock around a boolean semaphore region.
Definition Lock.h:19
virtual void receiveDanglingMessages() override
Answer to MPI Messages.
static ServiceRepository & getInstance()
Utility class for all flavours of particle sets.
void exchangeSieveListsGlobally()
Get all the global sieve data consistent.
void addParticleThatCanNotBeLiftedWithinItsTree(T *)
Add a particle to the list of particles which cannot be lifted.
int getNumberOfParticlesThatHaveBeSievedIntoVertices() const
hasParticlesToBeSievedIntoVertices() is equivalent to checking if this routine returns something grea...
static void deleteParticles(ParticleList &list)
bool hasParticlesToBeSievedIntoVertices() const
Fine out how many particles still to sieve.
ParticleList getParticlesToBeSievedIntoVertex(const peano4::datamanagement::VertexMarker &marker, bool removeReturnedParticlesFromSet, bool onlyReturnParticlesThatWillBeLocal)
Get particles that are to be sieved into one vertex.
static tarch::logging::Log _log
bool sieveParticle(const Particle &particle, const peano4::datamanagement::VertexMarker &marker)
A particle is to be sieved into a vertex if.
bool particleAssignedToVertexWillBeLocal(const tarch::la::Vector< Dimensions, double > &x, const peano4::datamanagement::VertexMarker &marker)
Definition particles.cpp:6
Vertex marker to provide information about selected vertex.
static void sendAndPollDanglingMessages(const tarch::mpi::IntegerMessage &message, int destination, int tag, MPI_Comm communicator=tarch::mpi::Rank::getInstance().getCommunicator())
static void receiveAndPollDanglingMessages(tarch::mpi::IntegerMessage &message, int source, int tag, MPI_Comm communicator=tarch::mpi::Rank::getInstance().getCommunicator())