diff --git a/src/core/mpi/BufferSystem.h b/src/core/mpi/BufferSystem.h index 8be65ea4a355644a39381eb29944375010fbc4f5..e37c3a76a087a758201ee9a160eb4cda1ef99398 100644 --- a/src/core/mpi/BufferSystem.h +++ b/src/core/mpi/BufferSystem.h @@ -129,6 +129,7 @@ public: template<typename RankIter> void setReceiverInfo( RankIter begin, RankIter end, bool changingSize ); template<typename Range> void setReceiverInfo( const Range & range, bool changingSize ); void setReceiverInfo( const std::set<MPIRank> & ranksToRecvFrom, bool changingSize ); + void setReceiverInfo( const int numReceives ); void setReceiverInfo( const std::map<MPIRank,MPISize> & ranksToRecvFrom ); void setReceiverInfoFromSendBufferState( bool useSizeFromSendBuffers, bool changingSize ); diff --git a/src/core/mpi/BufferSystem.impl.h b/src/core/mpi/BufferSystem.impl.h index f3d7539865e2d8894cda86492f67463006fe0513..242df47c80ea7506155e42f4036e6c9d7838b8b2 100644 --- a/src/core/mpi/BufferSystem.impl.h +++ b/src/core/mpi/BufferSystem.impl.h @@ -219,6 +219,20 @@ void GenericBufferSystem<Rb, Sb>::setReceiverInfo( const std::set<MPIRank> & ran +//********************************************************************************************************************** +/*! Sets receiver information, when the number of receives is known but the ranks are unknown +* +* \param numReceives number of expected messages +*/ +//********************************************************************************************************************** +template< typename Rb, typename Sb> +void GenericBufferSystem<Rb, Sb>::setReceiverInfo( const int numReceives ) +{ + WALBERLA_ABORT("NOT IMPLEMENTED!"); +} + + + //********************************************************************************************************************** /*! Sets receiver information, when message sizes are known * diff --git a/tests/core/mpi/BufferSystemTest.cpp b/tests/core/mpi/BufferSystemTest.cpp index a2e95dc63686763c3bfe28a329c0712ab4aa1acf..fab4340bfeb88f28b03357e1a135d4d698e7cc60 100644 --- a/tests/core/mpi/BufferSystemTest.cpp +++ b/tests/core/mpi/BufferSystemTest.cpp @@ -301,6 +301,90 @@ void gatherUsingAsymmetricCommunication(const bool useIProbe) } +/** + * Test for communication when only the number of receives is known but not the ranks. + */ + +void unknownRanksAllToAll() +{ + const int rank = MPIManager::instance()->worldRank(); + const int numProcesses = MPIManager::instance()->numProcesses(); + + WALBERLA_CHECK_GREATER_EQUAL(numProcesses, 3); + + BufferSystem bs(MPI_COMM_WORLD, 42); + + for (auto targetRank = 0; targetRank < numProcesses; ++targetRank) + { + auto& sb = bs.sendBuffer(targetRank); + for (int i = 0; i < rank + 1; ++i) + sb << rank; + } + + //we await numProcesses messages on every rank + bs.setReceiverInfo(numProcesses); + //equivalent to + //bs.setReceiverInfoFromSendBufferState(false, true); + + bs.sendAll(); + + auto numReceives = 0; + for (auto it = bs.begin(); it != bs.end(); ++it) + { + WALBERLA_CHECK_EQUAL(it.buffer().size(), (it.rank() + 1) * 4); + for (int i = 0; i < it.rank() + 1; ++i) + { + int received = -1; + it.buffer() >> received; + WALBERLA_CHECK_EQUAL(received, it.rank()); + } + ++numReceives; + } + WALBERLA_CHECK_EQUAL(numReceives, numProcesses); +} +void unknownRanksAllToLower() +{ + const int rank = MPIManager::instance()->worldRank(); + const int numProcesses = MPIManager::instance()->numProcesses(); + + WALBERLA_CHECK_GREATER_EQUAL(numProcesses, 3); + + BufferSystem bs(MPI_COMM_WORLD, 42); + + for (auto targetRank = 0; targetRank < rank + 1; ++targetRank) + { + auto& sb = bs.sendBuffer(targetRank); + for (int i = 0; i < rank + 1; ++i) + sb << rank; + } + + //we await numProcesses messages on every rank + bs.setReceiverInfo(numProcesses); + //equivalent to + //std::set<mpi::MPIRank> recvs; + //for (auto targetRank = numProcesses - 1; targetRank >=rank; --targetRank) + //{ + // recvs.emplace(targetRank); + //} + //bs.setReceiverInfo(recvs, true); + + bs.sendAll(); + + auto numReceives = 0; + for (auto it = bs.begin(); it != bs.end(); ++it) + { + WALBERLA_CHECK_EQUAL(it.buffer().size(), (it.rank() + 1) * 4); + for (int i = 0; i < it.rank() + 1; ++i) + { + int received = -1; + it.buffer() >> received; + WALBERLA_CHECK_EQUAL(received, it.rank()); + } + ++numReceives; + } + WALBERLA_CHECK_EQUAL(numReceives, numProcesses - rank); +} + void selfSend() { int rank = MPIManager::instance()->worldRank(); @@ -395,6 +479,12 @@ int main(int argc, char**argv) gatherUsingAsymmetricCommunication(false); gatherUsingAsymmetricCommunication(true); + WALBERLA_LOG_INFO_ON_ROOT("Testing Unknown Sender Ranks..."); + WALBERLA_LOG_INFO_ON_ROOT("AllToAll..."); + unknownRanksAllToAll(); + WALBERLA_LOG_INFO_ON_ROOT("AllToLower..."); + unknownRanksAllToLower(); + WALBERLA_LOG_INFO_ON_ROOT("Testing self-send..."); selfSend();