Peano
Loading...
Searching...
No Matches
GridVertex.cpp
Go to the documentation of this file.
1#include "GridVertex.h"
2
3#include <sstream>
4#include <algorithm>
5
7 [[maybe_unused]] State __state,
8 [[maybe_unused]] tarch::la::Vector<TwoPowerD, int> __adjacentRanks,
9 [[maybe_unused]] tarch::la::Vector<TwoPowerD, int> __backupOfAdjacentRanks,
10 [[maybe_unused]] bool __hasBeenAntecessorOfRefinedVertexInPreviousTreeSweep,
11 [[maybe_unused]] bool __isAntecessorOfRefinedVertexInCurrentTreeSweep,
12 [[maybe_unused]] bool __hasBeenParentOfSubtreeVertexInPreviousTreeSweep,
13 [[maybe_unused]] bool __isParentOfSubtreeVertexInCurrentTreeSweep,
14 [[maybe_unused]] int __numberOfAdjacentRefinedLocalCells,
15 [[maybe_unused]] tarch::la::Vector<Dimensions, double> __x,
16 [[maybe_unused]] int __level
17) {
18 setState( __state);
19 setAdjacentRanks( __adjacentRanks);
20 setBackupOfAdjacentRanks( __backupOfAdjacentRanks);
21 setHasBeenAntecessorOfRefinedVertexInPreviousTreeSweep( __hasBeenAntecessorOfRefinedVertexInPreviousTreeSweep);
22 setIsAntecessorOfRefinedVertexInCurrentTreeSweep( __isAntecessorOfRefinedVertexInCurrentTreeSweep);
23 setHasBeenParentOfSubtreeVertexInPreviousTreeSweep( __hasBeenParentOfSubtreeVertexInPreviousTreeSweep);
24 setIsParentOfSubtreeVertexInCurrentTreeSweep( __isParentOfSubtreeVertexInCurrentTreeSweep);
25 setNumberOfAdjacentRefinedLocalCells( __numberOfAdjacentRefinedLocalCells);
26 #if PeanoDebug>0
27 setX( __x);
28 #endif
29 setLevel( __level);
30}
31
33 setState( copy.getState() );
34 setAdjacentRanks( copy.getAdjacentRanks() );
35 setBackupOfAdjacentRanks( copy.getBackupOfAdjacentRanks() );
36 setHasBeenAntecessorOfRefinedVertexInPreviousTreeSweep( copy.getHasBeenAntecessorOfRefinedVertexInPreviousTreeSweep() );
37 setIsAntecessorOfRefinedVertexInCurrentTreeSweep( copy.getIsAntecessorOfRefinedVertexInCurrentTreeSweep() );
38 setHasBeenParentOfSubtreeVertexInPreviousTreeSweep( copy.getHasBeenParentOfSubtreeVertexInPreviousTreeSweep() );
39 setIsParentOfSubtreeVertexInCurrentTreeSweep( copy.getIsParentOfSubtreeVertexInCurrentTreeSweep() );
40 setNumberOfAdjacentRefinedLocalCells( copy.getNumberOfAdjacentRefinedLocalCells() );
41#if PeanoDebug>0
42 setX( copy.getX() );
43#endif
44 setLevel( copy.getLevel() );
45}
46
48 if (this == &other) {
49 return *this; // Self-assignment check
50 }
51
52 setState(other.getState());
53 setAdjacentRanks(other.getAdjacentRanks());
54 setBackupOfAdjacentRanks(other.getBackupOfAdjacentRanks());
55 setHasBeenAntecessorOfRefinedVertexInPreviousTreeSweep(other.getHasBeenAntecessorOfRefinedVertexInPreviousTreeSweep());
56 setIsAntecessorOfRefinedVertexInCurrentTreeSweep(other.getIsAntecessorOfRefinedVertexInCurrentTreeSweep());
57 setHasBeenParentOfSubtreeVertexInPreviousTreeSweep(other.getHasBeenParentOfSubtreeVertexInPreviousTreeSweep());
58 setIsParentOfSubtreeVertexInCurrentTreeSweep(other.getIsParentOfSubtreeVertexInCurrentTreeSweep());
59 setNumberOfAdjacentRefinedLocalCells(other.getNumberOfAdjacentRefinedLocalCells());
60#if PeanoDebug>0
61 setX(other.getX());
62#endif
63 setLevel(other.getLevel());
64
65 return *this;
66}
67
69 std::ostringstream out;
70 out << "(";
71 out << "state=" << (_state==State::HangingVertex? "HangingVertex" : "") << (_state==State::New? "New" : "") << (_state==State::Unrefined? "Unrefined" : "") << (_state==State::Refined? "Refined" : "") << (_state==State::RefinementTriggered? "RefinementTriggered" : "") << (_state==State::Refining? "Refining" : "") << (_state==State::EraseTriggered? "EraseTriggered" : "") << (_state==State::Erasing? "Erasing" : "") << (_state==State::Delete? "Delete" : "") ;
72 out << ",";
73 out << "adjacentRanks=" << getAdjacentRanks();
74 out << ",";
75 out << "backupOfAdjacentRanks=" << _backupOfAdjacentRanks;
76 out << ",";
77 out << "hasBeenAntecessorOfRefinedVertexInPreviousTreeSweep=" << _hasBeenAntecessorOfRefinedVertexInPreviousTreeSweep;
78 out << ",";
79 out << "isAntecessorOfRefinedVertexInCurrentTreeSweep=" << _isAntecessorOfRefinedVertexInCurrentTreeSweep;
80 out << ",";
81 out << "hasBeenParentOfSubtreeVertexInPreviousTreeSweep=" << _hasBeenParentOfSubtreeVertexInPreviousTreeSweep;
82 out << ",";
83 out << "isParentOfSubtreeVertexInCurrentTreeSweep=" << _isParentOfSubtreeVertexInCurrentTreeSweep;
84 out << ",";
85 out << "numberOfAdjacentRefinedLocalCells=" << _numberOfAdjacentRefinedLocalCells;
86#if PeanoDebug>0
87 out << ",";
88 out << "x=" << getX();
89#endif
90 out << ",";
91 out << "level=" << _level;
92 out << ")";
93 return out.str();
94}
95
96
97
98
99
103
104
106 _state = value;
107}
108
109
111
113 for( int i=0; i<TwoPowerD; i++) {
114 result(i) = _adjacentRanks[i];
115 }
116 return result;
117 }
118
119
121
122 for( int i=0; i<TwoPowerD; i++) {
123 _adjacentRanks[i] = value(i);
124 }
125 }
126
127
129 return _adjacentRanks[index];
130}
131
132
134 _adjacentRanks[index] = value;
135}
136
137
141
142
144 _backupOfAdjacentRanks = value;
145}
146
147
149 return _backupOfAdjacentRanks(index);
150}
151
152
154 _backupOfAdjacentRanks(index) = value;
155}
156
157
159 return _hasBeenAntecessorOfRefinedVertexInPreviousTreeSweep;
160}
161
162
164 _hasBeenAntecessorOfRefinedVertexInPreviousTreeSweep = value;
165}
166
167
169 return _isAntecessorOfRefinedVertexInCurrentTreeSweep;
170}
171
172
174 _isAntecessorOfRefinedVertexInCurrentTreeSweep = value;
175}
176
177
179 return _hasBeenParentOfSubtreeVertexInPreviousTreeSweep;
180}
181
182
184 _hasBeenParentOfSubtreeVertexInPreviousTreeSweep = value;
185}
186
187
189 return _isParentOfSubtreeVertexInCurrentTreeSweep;
190}
191
192
194 _isParentOfSubtreeVertexInCurrentTreeSweep = value;
195}
196
197
199 return _numberOfAdjacentRefinedLocalCells;
200}
201
202
204 _numberOfAdjacentRefinedLocalCells = value;
205}
206
207
208#if PeanoDebug>0
209tarch::la::Vector<Dimensions,double> peano4::grid::GridVertex::getX() const {
210
212 for( int i=0; i<Dimensions; i++) {
213 result(i) = _x[i];
214 }
215 return result;
216 }
217
218
219void peano4::grid::GridVertex::setX(const tarch::la::Vector<Dimensions,double>& value) {
220
221 for( int i=0; i<Dimensions; i++) {
222 _x[i] = value(i);
223 }
224 }
225
226
227double peano4::grid::GridVertex::getX(int index) const {
228 return _x[index];
229}
230
231
232void peano4::grid::GridVertex::setX(int index, double value) {
233 _x[index] = value;
234}
235
236
237#endif
238
239
241 return _level;
242}
243
244
246 _level = value;
247}
248
249
250
251
252
253
254#ifdef Parallel
255
256#if !defined(__MPI_ATTRIBUTES_LANGUAGE_EXTENSION__)
257MPI_Datatype peano4::grid::GridVertex::Datatype = MPI_DATATYPE_NULL;
258#endif
259
260
261[[clang::map_mpi_datatype]]
263 return Datatype;
264}
265
266
267[[clang::map_mpi_datatype]]
269 return Datatype;
270}
271
272
273[[clang::map_mpi_datatype]]
275 return Datatype;
276}
277
278
279[[clang::map_mpi_datatype]]
281 return Datatype;
282}
283
284
285[[clang::map_mpi_datatype]]
287 return Datatype;
288}
289
290
291[[clang::map_mpi_datatype]]
293 if (Datatype != MPI_DATATYPE_NULL){
294 MPI_Type_free(&Datatype);
295 Datatype = MPI_DATATYPE_NULL;
296 }
297}
298
299
300[[clang::map_mpi_datatype]]
302 if (Datatype != MPI_DATATYPE_NULL){
303 MPI_Type_free(&Datatype);
304 Datatype = MPI_DATATYPE_NULL;
305 }
306}
307
308
309[[clang::map_mpi_datatype]]
311 if (Datatype != MPI_DATATYPE_NULL){
312 MPI_Type_free(&Datatype);
313 Datatype = MPI_DATATYPE_NULL;
314 }
315}
316
317
318[[clang::map_mpi_datatype]]
320 if (Datatype != MPI_DATATYPE_NULL){
321 MPI_Type_free(&Datatype);
322 Datatype = MPI_DATATYPE_NULL;
323 }
324}
325
326
327[[clang::map_mpi_datatype]]
329 if (Datatype != MPI_DATATYPE_NULL){
330 MPI_Type_free(&Datatype);
331 Datatype = MPI_DATATYPE_NULL;
332 }
333}
334
335
337 return _senderDestinationRank;
338}
339
340
342 #if !defined(__MPI_ATTRIBUTES_LANGUAGE_EXTENSION__)
343 peano4::grid::GridVertex instances[2];
344
345 int NumberOfAttributes = 0;
346 NumberOfAttributes++;
347 NumberOfAttributes++;
348 NumberOfAttributes++;
349 NumberOfAttributes++;
350 NumberOfAttributes++;
351 NumberOfAttributes++;
352 NumberOfAttributes++;
353 NumberOfAttributes++;
354#if PeanoDebug>0
355 NumberOfAttributes++;
356#endif
357 NumberOfAttributes++;
358
359 MPI_Datatype* subtypes = new MPI_Datatype[NumberOfAttributes];
360 int* blocklen = new int[NumberOfAttributes];
361 MPI_Aint* disp = new MPI_Aint[NumberOfAttributes];
362
363 int counter = 0;
364 subtypes[counter] = MPI_INT;
365 blocklen[counter] = 1;
366 counter++;
367 subtypes[counter] = MPI_INT;
368 blocklen[counter] = TwoPowerD;
369 counter++;
370 subtypes[counter] = MPI_INT;
371 blocklen[counter] = TwoPowerD;
372 counter++;
373 subtypes[counter] = MPI_BYTE;
374 blocklen[counter] = 1;
375 counter++;
376 subtypes[counter] = MPI_BYTE;
377 blocklen[counter] = 1;
378 counter++;
379 subtypes[counter] = MPI_BYTE;
380 blocklen[counter] = 1;
381 counter++;
382 subtypes[counter] = MPI_BYTE;
383 blocklen[counter] = 1;
384 counter++;
385 subtypes[counter] = MPI_INT;
386 blocklen[counter] = 1;
387 counter++;
388#if PeanoDebug>0
389 subtypes[counter] = MPI_DOUBLE;
390 blocklen[counter] = Dimensions;
391 counter++;
392#endif
393 subtypes[counter] = MPI_INT;
394 blocklen[counter] = 1;
395 counter++;
396
397 MPI_Aint baseFirstInstance;
398 MPI_Aint baseSecondInstance;
399 MPI_Get_address( &instances[0], &baseFirstInstance );
400 MPI_Get_address( &instances[1], &baseSecondInstance );
401
402 counter = 0;
403 MPI_Get_address( &(instances[0]._state), &disp[counter] );
404 counter++;
405 MPI_Get_address( &(instances[0]._adjacentRanks.data()[0]), &disp[counter] );
406 counter++;
407 MPI_Get_address( &(instances[0]._backupOfAdjacentRanks.data()[0]), &disp[counter] );
408 counter++;
409 MPI_Get_address( &(instances[0]._hasBeenAntecessorOfRefinedVertexInPreviousTreeSweep), &disp[counter] );
410 counter++;
411 MPI_Get_address( &(instances[0]._isAntecessorOfRefinedVertexInCurrentTreeSweep), &disp[counter] );
412 counter++;
413 MPI_Get_address( &(instances[0]._hasBeenParentOfSubtreeVertexInPreviousTreeSweep), &disp[counter] );
414 counter++;
415 MPI_Get_address( &(instances[0]._isParentOfSubtreeVertexInCurrentTreeSweep), &disp[counter] );
416 counter++;
417 MPI_Get_address( &(instances[0]._numberOfAdjacentRefinedLocalCells), &disp[counter] );
418 counter++;
419
420#if PeanoDebug>0
421 MPI_Get_address( &(instances[0]._x.data()[0]), &disp[counter] );
422 counter++;
423#endif
424 MPI_Get_address( &(instances[0]._level), &disp[counter] );
425 counter++;
426
427 MPI_Aint offset = disp[0] - baseFirstInstance;
428 MPI_Aint extent = baseSecondInstance - baseFirstInstance - offset;
429 for (int i=NumberOfAttributes-1; i>=0; i--) {
430 disp[i] = disp[i] - disp[0];
431 }
432
433 int errorCode = 0;
434 MPI_Datatype tmpType;
435 errorCode += MPI_Type_create_struct( NumberOfAttributes, blocklen, disp, subtypes, &tmpType );
436 errorCode += MPI_Type_create_resized( tmpType, offset, extent, &Datatype );
437 errorCode += MPI_Type_commit( &Datatype );
438 errorCode += MPI_Type_free( &tmpType );
439 if (errorCode) std::cerr << "error constructing MPI datatype in " << __FILE__ << ":" << __LINE__ << std::endl;
440
441 delete[] subtypes;
442 delete[] blocklen;
443 delete[] disp;
444
445 #else
446 // invoke routine once to trigger lazy initialisation
447 getForkDatatype();
448 getJoinDatatype();
449 getBoundaryExchangeDatatype();
450 getMultiscaleDataExchangeDatatype();
451 getGlobalCommunciationDatatype();
452 #endif
453}
454
455
457 #if !defined(__MPI_ATTRIBUTES_LANGUAGE_EXTENSION__)
458 freeForkDatatype();
459 freeJoinDatatype();
460 freeBoundaryExchangeDatatype();
461 freeMultiscaleDataExchangeDatatype();
462 freeGlobalCommunciationDatatype();
463 #else
464 MPI_Datatype type = Datatype;
465 MPI_Type_free( &type );
466 #endif
467}
468
469
470void peano4::grid::GridVertex::send(const peano4::grid::GridVertex& buffer, int destination, int tag, MPI_Comm communicator ) {
471 MPI_Send( &buffer, 1, Datatype, destination, tag, communicator);
472}
473
474
475void peano4::grid::GridVertex::receive(peano4::grid::GridVertex& buffer, int source, int tag, MPI_Comm communicator ) {
476 MPI_Status status;
477 MPI_Recv( &buffer, 1, Datatype, source, tag, communicator, &status);
478 buffer._senderDestinationRank = status.MPI_SOURCE;
479}
480
481
483 const peano4::grid::GridVertex& buffer,
484 int destination,
485 int tag,
486 std::function<void()> startCommunicationFunctor,
487 std::function<void()> waitFunctor,
488 MPI_Comm communicator
489) {
490 MPI_Request sendRequestHandle;
491 int flag = 0;
492 MPI_Isend( &buffer, 1, Datatype, destination, tag, communicator, &sendRequestHandle );
493 MPI_Test( &sendRequestHandle, &flag, MPI_STATUS_IGNORE );
494 startCommunicationFunctor();
495 while (!flag) {
496 waitFunctor();
497 MPI_Test( &sendRequestHandle, &flag, MPI_STATUS_IGNORE );
498 }
499}
500
501
504 int source,
505 int tag,
506 std::function<void()> startCommunicationFunctor,
507 std::function<void()> waitFunctor,
508 MPI_Comm communicator
509) {
510 MPI_Status status;
511 MPI_Request receiveRequestHandle;
512 int flag = 0;
513 MPI_Irecv( &buffer, 1, Datatype, source, tag, communicator, &receiveRequestHandle );
514 MPI_Test( &receiveRequestHandle, &flag, &status );
515 startCommunicationFunctor();
516 while (!flag) {
517 waitFunctor();
518 MPI_Test( &receiveRequestHandle, &flag, &status );
519 }
520 buffer._senderDestinationRank = status.MPI_SOURCE;
521}
522#endif
523
524#ifdef Parallel
525void peano4::grid::GridVertex::sendAndPollDanglingMessages(const peano4::grid::GridVertex& message, int destination, int tag, MPI_Comm communicator ) {
527 message, destination, tag,
528 [&]() {
531 },
532 [&]() {
533 tarch::mpi::Rank::getInstance().writeTimeOutWarning( "peano4::grid::GridVertex", "sendAndPollDanglingMessages()",destination, tag );
534 tarch::mpi::Rank::getInstance().triggerDeadlockTimeOut( "peano4::grid::GridVertex", "sendAndPollDanglingMessages()", destination, tag );
536 },
537 communicator
538 );
539}
540
541
542void peano4::grid::GridVertex::receiveAndPollDanglingMessages(peano4::grid::GridVertex& message, int source, int tag, MPI_Comm communicator ) {
544 message, source, tag,
545 [&]() {
548 },
549 [&]() {
550 tarch::mpi::Rank::getInstance().writeTimeOutWarning( "peano4::grid::GridVertex", "receiveAndPollDanglingMessages()", source, tag );
551 tarch::mpi::Rank::getInstance().triggerDeadlockTimeOut( "peano4::grid::GridVertex", "receiveAndPollDanglingMessages()", source, tag );
553 },
554 communicator
555 );
556}
557#endif
558
#define TwoPowerD
Definition Globals.h:19
state setX(0.0)
state setLevel(0)
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:124
void setDeadlockWarningTimeStamp()
Memorise global timeout.
Definition Rank.cpp:193
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:148
void setDeadlockTimeOutTimeStamp()
Definition Rank.cpp:198
static Rank & getInstance()
This operation returns the singleton instance.
Definition Rank.cpp:539
virtual void receiveDanglingMessages() override
Answer to MPI Messages.
static ServiceRepository & getInstance()
index
Definition makeIC.py:38
bool getIsParentOfSubtreeVertexInCurrentTreeSweep() const
tarch::la::Vector< TwoPowerD, int > getAdjacentRanks() const
static MPI_Datatype getJoinDatatype()
int getNumberOfAdjacentRefinedLocalCells() const
static MPI_Datatype Datatype
Whenever we use LLVM's MPI extension (DaStGe), we rely on lazy initialisation of the datatype.
Definition GridVertex.h:231
static void freeMultiscaleDataExchangeDatatype()
static void freeBoundaryExchangeDatatype()
void setBackupOfAdjacentRanks(const tarch::la::Vector< TwoPowerD, int > &value)
void setIsAntecessorOfRefinedVertexInCurrentTreeSweep(bool value)
static MPI_Datatype getForkDatatype()
Hands out MPI datatype if we work without the LLVM MPI extension.
static MPI_Datatype getBoundaryExchangeDatatype()
bool getHasBeenAntecessorOfRefinedVertexInPreviousTreeSweep() const
static void freeJoinDatatype()
static void freeForkDatatype()
static MPI_Datatype getMultiscaleDataExchangeDatatype()
static MPI_Datatype getGlobalCommunciationDatatype()
tarch::la::Vector< TwoPowerD, int > getBackupOfAdjacentRanks() const
static void receiveAndPollDanglingMessages(peano4::grid::GridVertex &message, int source, int tag, MPI_Comm communicator=tarch::mpi::Rank::getInstance().getCommunicator())
static void shutdownDatatype()
Free the underlying MPI datatype.
void setLevel(int value)
static void receive(peano4::grid::GridVertex &buffer, int source, int tag, MPI_Comm communicator)
static void sendAndPollDanglingMessages(const peano4::grid::GridVertex &message, int destination, int tag, MPI_Comm communicator=tarch::mpi::Rank::getInstance().getCommunicator())
void setNumberOfAdjacentRefinedLocalCells(int value)
void setIsParentOfSubtreeVertexInCurrentTreeSweep(bool value)
std::string toString() const
static void send(const peano4::grid::GridVertex &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.
bool getIsAntecessorOfRefinedVertexInCurrentTreeSweep() const
void setHasBeenParentOfSubtreeVertexInPreviousTreeSweep(bool value)
GridVertex & operator=(const GridVertex &other)
void setHasBeenAntecessorOfRefinedVertexInPreviousTreeSweep(bool value)
void setState(State value)
void setAdjacentRanks(const tarch::la::Vector< TwoPowerD, int > &value)
bool getHasBeenParentOfSubtreeVertexInPreviousTreeSweep() const
peano4::grid::GridVertex::State getState() const
static void freeGlobalCommunciationDatatype()
static void initDatatype()
Wrapper around getDatatype() to trigger lazy evaluation if we use the lazy initialisation.
Simple vector class.
Definition Vector.h:150