Commit 0c8dad94 authored by Martin Bauer's avatar Martin Bauer
Browse files

[Bugfix] BufferSystem was not copied correctly

- Bug occurred if a BufferSystem (or communication scheme) was copied
  and the first object went out of scope.
- Internally a pointer was kept which was still pointing to the original
  BufferSystem

Fixes #16
parent e72d6586
...@@ -92,6 +92,50 @@ BufferSystem::BufferSystem( const MPI_Comm & communicator, int tag ) ...@@ -92,6 +92,50 @@ BufferSystem::BufferSystem( const MPI_Comm & communicator, int tag )
{ {
} }
BufferSystem::BufferSystem( const BufferSystem &other )
: knownSizeComm_ ( other.knownSizeComm_.getCommunicator(), other.knownSizeComm_.getTag() ),
unknownSizeComm_( other.knownSizeComm_.getCommunicator(), other.knownSizeComm_.getTag() ),
noMPIComm_ ( other.knownSizeComm_.getCommunicator(), other.knownSizeComm_.getTag() ),
currentComm_ ( NULL ),
sizeChangesEverytime_( other.sizeChangesEverytime_ ),
communicationRunning_( other.communicationRunning_ ),
recvInfos_( other.recvInfos_ ),
sendInfos_( other.sendInfos_ )
{
WALBERLA_ASSERT( !communicationRunning_, "Can't copy BufferSystem while communication is running" );
if( other.currentComm_ == &other.knownSizeComm_ )
currentComm_ = &knownSizeComm_;
else if ( other.currentComm_ == &other.unknownSizeComm_ )
currentComm_ = &unknownSizeComm_;
else if ( other.currentComm_ == &other.noMPIComm_ )
currentComm_ = &noMPIComm_;
else
currentComm_ = NULL; // receiver information not yet set
}
BufferSystem & BufferSystem::operator=( const BufferSystem & other )
{
WALBERLA_ASSERT( !communicationRunning_, "Can't copy BufferSystem while communication is running" );
sizeChangesEverytime_ = other.sizeChangesEverytime_;
communicationRunning_ = other.communicationRunning_;
recvInfos_ = other.recvInfos_;
sendInfos_ = other.sendInfos_;
if( other.currentComm_ == &other.knownSizeComm_ )
currentComm_ = &knownSizeComm_;
else if ( other.currentComm_ == &other.unknownSizeComm_ )
currentComm_ = &unknownSizeComm_;
else if ( other.currentComm_ == &other.noMPIComm_ )
currentComm_ = &noMPIComm_;
else
currentComm_ = NULL; // receiver information not yet set
return *this;
}
//====================================================================================================================== //======================================================================================================================
// //
// Receive Information Setup // Receive Information Setup
......
...@@ -115,6 +115,8 @@ public: ...@@ -115,6 +115,8 @@ public:
/*!\name Constructors */ /*!\name Constructors */
//@{ //@{
explicit BufferSystem( const MPI_Comm & communicator, int tag = 0 ); explicit BufferSystem( const MPI_Comm & communicator, int tag = 0 );
BufferSystem( const BufferSystem & other );
BufferSystem & operator=( const BufferSystem & other );
~BufferSystem() {} ~BufferSystem() {}
//@} //@}
//******************************************************************************************************************* //*******************************************************************************************************************
......
...@@ -90,7 +90,9 @@ namespace internal { ...@@ -90,7 +90,9 @@ namespace internal {
virtual MPIRank waitForNextReceive( std::map<MPIRank, ReceiveInfo> & recvInfos ) = 0; virtual MPIRank waitForNextReceive( std::map<MPIRank, ReceiveInfo> & recvInfos ) = 0;
virtual int getTag() const { return tag_; } virtual int getTag() const { return tag_; }
virtual MPI_Comm getCommunicator() const { return communicator_; }
protected: protected:
MPI_Comm communicator_; MPI_Comm communicator_;
...@@ -99,7 +101,6 @@ namespace internal { ...@@ -99,7 +101,6 @@ namespace internal {
class KnownSizeCommunication : public AbstractCommunication class KnownSizeCommunication : public AbstractCommunication
{ {
public: public:
...@@ -126,7 +127,6 @@ namespace internal { ...@@ -126,7 +127,6 @@ namespace internal {
class UnknownSizeCommunication : public AbstractCommunication class UnknownSizeCommunication : public AbstractCommunication
{ {
public: public:
...@@ -138,7 +138,7 @@ namespace internal { ...@@ -138,7 +138,7 @@ namespace internal {
virtual void send( MPIRank receiver, const SendBuffer & sendBuffer ); virtual void send( MPIRank receiver, const SendBuffer & sendBuffer );
virtual void waitForSends(); virtual void waitForSends();
virtual void scheduleReceives ( std::map<MPIRank, ReceiveInfo> & recvInfos ); virtual void scheduleReceives( std::map<MPIRank, ReceiveInfo> & recvInfos );
/// size field of recvInfos can be invalid, is filled in with the actual message size /// size field of recvInfos can be invalid, is filled in with the actual message size
virtual MPIRank waitForNextReceive( std::map<MPIRank, ReceiveInfo> & recvInfos ); virtual MPIRank waitForNextReceive( std::map<MPIRank, ReceiveInfo> & recvInfos );
...@@ -156,6 +156,7 @@ namespace internal { ...@@ -156,6 +156,7 @@ namespace internal {
}; };
class NoMPICommunication : public AbstractCommunication class NoMPICommunication : public AbstractCommunication
{ {
public: public:
...@@ -167,7 +168,7 @@ namespace internal { ...@@ -167,7 +168,7 @@ namespace internal {
virtual void send( MPIRank receiver, const SendBuffer & sendBuffer ); virtual void send( MPIRank receiver, const SendBuffer & sendBuffer );
virtual void waitForSends(); virtual void waitForSends();
virtual void scheduleReceives( std::map<MPIRank, ReceiveInfo> & recvInfos ); virtual void scheduleReceives( std::map<MPIRank, ReceiveInfo> & recvInfos );
/// size field of recvInfos can be invalid, is filled in with the actual message size /// size field of recvInfos can be invalid, is filled in with the actual message size
virtual MPIRank waitForNextReceive( std::map<MPIRank, ReceiveInfo> & recvInfos ); virtual MPIRank waitForNextReceive( std::map<MPIRank, ReceiveInfo> & recvInfos );
......
...@@ -325,6 +325,38 @@ void selfSend() ...@@ -325,6 +325,38 @@ void selfSend()
} }
} }
void copyTest()
{
int rank = MPIManager::instance()->worldRank();
BufferSystem bs1( MPI_COMM_WORLD, 3 );
{
BufferSystem bs2( MPI_COMM_WORLD, 7 );
bs2.sendBuffer(rank) << int(42);
bs2.setReceiverInfoFromSendBufferState( true, false );
bs2.sendAll();
for ( auto i = bs2.begin(); i != bs2.end(); ++i )
{
int messageContent;
i.buffer() >> messageContent;
WALBERLA_CHECK_EQUAL(messageContent, 42);
}
bs1 = bs2;
}
bs1.sendBuffer(rank) << int(42);
bs1.sendAll();
for ( auto i = bs1.begin(); i != bs1.end(); ++i )
{
int messageContent;
i.buffer() >> messageContent;
WALBERLA_CHECK_EQUAL(messageContent, 42);
}
}
int main(int argc, char**argv) int main(int argc, char**argv)
{ {
...@@ -340,21 +372,23 @@ int main(int argc, char**argv) ...@@ -340,21 +372,23 @@ int main(int argc, char**argv)
return 1; return 1;
} }
WALBERLA_ROOT_SECTION() { WALBERLA_LOG_INFO("Testing Symmetric Communication..." ); } WALBERLA_LOG_INFO_ON_ROOT("Testing Symmetric Communication...");
symmetricCommunication(); symmetricCommunication();
WALBERLA_ROOT_SECTION() { WALBERLA_LOG_INFO("Testing Asymmetric Communication..."); } WALBERLA_LOG_INFO_ON_ROOT("Testing Asymmetric Communication...");
asymmetricCommunication(); asymmetricCommunication();
WALBERLA_ROOT_SECTION() { WALBERLA_LOG_INFO("Testing time-varying Communication..."); } WALBERLA_LOG_INFO_ON_ROOT("Testing time-varying Communication...");
timeVaryingCommunication(); timeVaryingCommunication();
WALBERLA_ROOT_SECTION() { WALBERLA_LOG_INFO("Testing Gather Operation..."); } WALBERLA_LOG_INFO_ON_ROOT("Testing Gather Operation...");
gatherUsingAsymmetricCommunication(); gatherUsingAsymmetricCommunication();
WALBERLA_ROOT_SECTION() { WALBERLA_LOG_INFO("Testing selfsend..."); } WALBERLA_LOG_INFO_ON_ROOT("Testing self-send...");
selfSend(); selfSend();
WALBERLA_LOG_INFO_ON_ROOT("Testing Buffer System copy...");
copyTest();
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment