MPIAllToAllCommunicator.cpp

Go to the documentation of this file.
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         // this is the first iteration of a new all-to-all exchange operation so initialize the buffers
00037         inputBuffers.startNewMPIExchange();
00038         outputBuffers.startNewMPIExchange();
00039 
00040         // and initialize the needs to send and needs to receive indicators
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     // do the exchange algorithm
00052     doExchangeAlgorithm();
00053 
00054     // update the needsToReceive and needsToSend array for the next cycle
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     // are we finished with the iterations ?
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 }

Generated on Wed Jul 9 16:34:37 2008 for PCSIM by  doxygen 1.5.5