/* A distributed program, using MPI, that sums up the elements in a vector of integers. - The main process splits the vector into equal size chunks and distributes them to all processes (including to itself), - each process sums the numbers in its chunk and sends the sum back to the main process - the main process gets the sums of the chunks, sums them and prints the result This example uses MPI_scatter() to split the vector and send the chunks to the workers. */ #include #include #include #include #include #include using namespace std; // generates a random vector, to be used as input void generate(vector& v, size_t n) { v.reserve(n); for(size_t i=0 ; i &v, int sum) { int _sum = 0; for(auto it : v) { _sum += it; } return _sum == sum; } // The actual work, to be executed both by the master and the workers. The input vector v and the value nrProcs are ignored on workers. int process(vector const& v, int me, int nrProcs) { int chunkSize = v.size()/nrProcs; MPI_Bcast(&chunkSize, 1, MPI_INT, 0, MPI_COMM_WORLD); vector chunk(chunkSize, 0); MPI_Scatter(v.data(), chunkSize, MPI_INT, chunk.data(), chunk.size(), MPI_INT, 0, MPI_COMM_WORLD); cerr<<"Process "< sums; if(me == 0) { sums.resize(nrProcs); } MPI_Gather(&s, 1, MPI_INT, sums.data(), 1, MPI_INT, 0, MPI_COMM_WORLD); if(me == 0) { s = 0; for(auto v : sums) { s+=v; } return s; } else { return 0; } } int vectorSum(vector v, int nrProcs) { v.resize(((v.size()+nrProcs-1)/nrProcs)*nrProcs, 0); return process(v, 0, nrProcs); } int main(int argc, char** argv) { MPI_Init(0, 0); int me; int nrProcs; MPI_Comm_size(MPI_COMM_WORLD, &nrProcs); MPI_Comm_rank(MPI_COMM_WORLD, &me); unsigned n; vector v; if(argc != 2 || 1!=sscanf(argv[1], "%u", &n) ){ fprintf(stderr, "usage: sum-mpi \n"); return 1; } if(me == 0) { generate(v, n); fprintf(stderr, "generated\n"); chrono::high_resolution_clock::time_point const beginTime = chrono::high_resolution_clock::now(); int sum = vectorSum(v, nrProcs); chrono::high_resolution_clock::time_point const endTime = chrono::high_resolution_clock::now(); printf("Result %s, time=%ldms\n", (checkSum(v, sum) ? "ok" : "FAIL"), (chrono::duration_cast(endTime-beginTime)).count()); } else { // worker chrono::high_resolution_clock::time_point const beginTime = chrono::high_resolution_clock::now(); process(vector(), me, nrProcs); chrono::high_resolution_clock::time_point const endTime = chrono::high_resolution_clock::now(); printf("(worker %d): time=%ldms\n", me, (chrono::duration_cast(endTime-beginTime)).count()); } MPI_Finalize(); }