#include #include #include #include #undef min /** Processes the current node, as the member of the given communicator. * If the rank is 0, this process is the leader (the root of the sub-tree): in that case, the 'input' argument contains the data to be processed * and the function returns the result (the sum of elements in the input vector, for this problem). * Otherwise, this function acts as a worker * * Implementation: * - if the rank is 0, this function splits the input, sends it to children, processes its own part (by doing a recursive call), * receives the part results from children, combines them and, finally, returns the result. * - if the rank in 1, this acts as a worker, receives the data from the parent, processes its own part (by a recursive call), and sends back the result * - otherwise, this does nothing at this level, but still calls itself recursively for the next level * - in all cases, this splits the communicator * */ int sumVector2(MPI_Comm comm, int const* pInput, int inputSize) { int me; int nrProcs; MPI_Comm_size(comm, &nrProcs); MPI_Comm_rank(comm, &me); if(nrProcs == 1) { int s = 0; for(int i=0 ; i data(sizeToRecv); MPI_Recv(data.data(), sizeToRecv, MPI_INT, 0, 2, comm, &status); int localSum = sumVector2(subComm, data.data(), sizeToRecv); MPI_Ssend(&localSum, 1, MPI_INT, 0, 3, comm); } else { sumVector2(subComm, nullptr, 0); } MPI_Comm_free(&subComm); return 0; } /** Processes the current node, as the member of the given communicator. * If the rank is 0, this process is the leader (the root of the sub-tree): in that case, the 'input' argument contains the data to be processed * and the function returns the result (the sum of elements in the input vector, for this problem). * Otherwise, this function acts as a worker * * Implementation: * - if the rank is 0, this function splits the input, sends it to children, processes its own part (by doing a recursive call), * receives the part results from children, combines them and, finally, returns the result. * - if the rank in 1 through `nrBranches`-1, this acts as a worker, receives the data from the parent, processes its own part (by a recursive call), and sends back the result * - otherwise, this does nothing at this level, but still calls itself recursively for the next level * - in all cases, this splits the communicator * */ int sumVectorN(MPI_Comm comm, int nrBranches, int const* pInput, int inputSize) { int me; int nrProcs; MPI_Comm_size(comm, &nrProcs); MPI_Comm_rank(comm, &me); if(nrProcs == 1) { int s = 0; for(int i=0 ; i data(sizeToRecv); MPI_Recv(data.data(), sizeToRecv, MPI_INT, 0, 2, comm, &status); int localSum = sumVectorN(subComm, nrBranches, data.data(), sizeToRecv); MPI_Ssend(&localSum, 1, MPI_INT, 0, 3, comm); } else { sumVectorN(subComm, nrBranches, nullptr, 0); } MPI_Comm_free(&subComm); return 0; } #define NR_BRANCHES 5 int main() { MPI_Init(0, 0); int me; MPI_Comm_rank(MPI_COMM_WORLD, &me); if(me == 0) { int nrElements = 1000; std::vector input(nrElements); for(int i=0 ; i