00001 #include "MPIAllToAllCommunicator.h"
00002
00003 #include <functional>
00004 #include <numeric>
00005 #include <algorithm>
00006 using std::logical_or;
00007 using std::accumulate;
00008 using std::copy;
00009
00010 MPIAllToAllCommunicator::MPIAllToAllCommunicator(MPIInputBufferVector & mpiInputBuffers,
00011 MPIOutputBufferVector & mpiOutputBuffers,
00012 MPI::Intracomm & comm,
00013 vector<bool> &incomingConnections,
00014 vector<bool> &outgoingConnections) :
00015 inputBuffers(mpiInputBuffers), outputBuffers(mpiOutputBuffers),
00016 incoming_connections(incomingConnections), outgoing_connections(outgoingConnections),
00017 mpi_comm(comm)
00018 {
00019 numNodes = mpi_comm.Get_size();
00020 finished = true;
00021 hasNextToSend.resize(numNodes);
00022
00023 }
00024
00025 MPIAllToAllCommunicator::~MPIAllToAllCommunicator()
00026 {}
00027
00028 int MPIAllToAllCommunicator::getRank()
00029 {
00030 return mpi_comm.Get_rank();
00031 }
00032
00033 bool MPIAllToAllCommunicator::doAllToAllExchange()
00034 {
00035 if (finished) {
00036
00037 inputBuffers.startNewMPIExchange();
00038 outputBuffers.startNewMPIExchange();
00039
00040
00041 prepare();
00042 finished = false;
00043 }
00044
00045 outputBuffers.prepareNextBufferSlices();
00046 inputBuffers.prepareNextBufferSlices();
00047
00048 for (int i = 0 ; i < numNodes ; ++i)
00049 hasNextToSend[i] = hasNextToSend[i] && outputBuffers[i].hasNextBufferSlice();
00050
00051
00052 doExchangeAlgorithm();
00053
00054
00055 for (int i = 0 ; i < numNodes ; ++i ) {
00056 needsToSend[i] = hasNextToSend[i];
00057 if (mpi_comm.Get_rank() != i) {
00058 inputBuffers[i].setHasNewContent(needsToReceive[i]);
00059 needsToReceive[i] = needsToReceive[i] && inputBuffers[i].hasNextBufferSlice();
00060 }
00061 }
00062
00063
00064 finished = !(accumulate(needsToReceive.begin(), needsToReceive.end(), false, logical_or<bool>())
00065 || accumulate(needsToSend.begin(), needsToSend.end(), false, logical_or<bool>()));
00066
00067 if (finished)
00068 outputBuffers.nextCycle();
00069 return finished;
00070 }