00001 #include "MPIDefaultAllToAllCommunicator.h"
00002
00003 #include <numeric>
00004 #include <functional>
00005 #include <algorithm>
00006
00007 using std::logical_or;
00008 using std::accumulate;
00009 using std::fill;
00010
00011 using std::cerr;
00012
00013 MPIDefaultAllToAllCommunicator::MPIDefaultAllToAllCommunicator(
00014 MPIInputBufferVector & mpiInputBuffers,
00015 MPIOutputBufferVector & mpiOutputBuffers,
00016 MPI::Intracomm & comm,
00017 vector<bool> &incomingConnections,
00018 vector<bool> &outgoingConnections) :
00019 MPIAllToAllCommunicator(mpiInputBuffers, mpiOutputBuffers, comm, incomingConnections, outgoingConnections)
00020 {
00021 needsToSend.resize(comm.Get_size(), true);
00022 needsToReceive.resize(comm.Get_size(), true);
00023 }
00024
00025 void MPIDefaultAllToAllCommunicator::prepare()
00026 {
00027 fill(needsToSend.begin(), needsToSend.end(), true);
00028 fill(needsToReceive.begin(), needsToReceive.end(), true);
00029 fill(hasNextToSend.begin(), hasNextToSend.end(), true);
00030 hasNextToSend[mpi_comm.Get_rank()] = false;
00031 needsToSend[mpi_comm.Get_rank()] = false;
00032 needsToReceive[mpi_comm.Get_rank()] = false;
00033 }
00034
00035
00036 void MPIDefaultAllToAllCommunicator::doExchangeAlgorithm()
00037 {
00038
00039 outputBuffers.setFinishedFlag(!accumulate(hasNextToSend.begin(), hasNextToSend.end(), false, logical_or<bool>()));
00040
00041 MPIExchangeBlocksInfo & input_blocks = inputBuffers.getMPIExchangeBlocksInfo();
00042
00043 MPIExchangeBlocksInfo &output_blocks = outputBuffers.getMPIExchangeBlocksInfo();
00044
00045
00046 mpi_comm.Alltoallw((void *)outputBuffers.getBaseBufferPtr(),
00047 output_blocks.counts, output_blocks.displs, output_blocks.datatypes,
00048 (void *)inputBuffers.getBaseBufferPtr(),
00049 input_blocks.counts, input_blocks.displs, input_blocks.datatypes);
00050 }