1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- // mpic++ -std=c++11 -Wall -Wextra -o laplacien_mpi_1.out laplacien_mpi_1.cpp
- // mpirun -n 4 ./laplacien_mpi_1.out
- #include "image.hpp"
- #include <algorithm>
- #include <mpi.h>
- int main(int argc, char ** argv)
- {
- // init MPI
- MPI_Init(&argc, &argv);
- int nbNodes;
- MPI_Comm_size(MPI_COMM_WORLD, &nbNodes);
- int iNode;
- MPI_Comm_rank(MPI_COMM_WORLD, &iNode);
- // read image (master node)
- image_t data0;
- int width, height;
- if (iNode == 0)
- {
- std::string readError = readPgm("backloop.pgm", width, height, data0);
- if (readError != "")
- {
- std::cout << readError << std::endl;
- exit(-1);
- }
- }
- // broadcast image sizes
- MPI_Bcast(&width, 1, MPI_INT, 0, MPI_COMM_WORLD);
- MPI_Bcast(&height, 1, MPI_INT, 0, MPI_COMM_WORLD);
- int heightN = (height+nbNodes-1) / nbNodes;
- int sizeN = heightN * width;
- int height2 = heightN * nbNodes;
- int size2 = height2 * width;
- // ensure height of data is a multiple of nbNodes (master node)
- image_t data1(size2);
- if (iNode == 0)
- {
- std::copy_n(data0.begin(), width*height, data1.begin());
- }
- // send data to nodes
- image_t nodeData(sizeN);
- MPI_Scatter(data1.data(), sizeN, MPI_UNSIGNED_CHAR,
- nodeData.data(), sizeN, MPI_UNSIGNED_CHAR,
- 0, MPI_COMM_WORLD);
- // compute on each node
- image_t nodeResult = computeLaplacian(nodeData, width, heightN, 10.0);
- // receive results from nodes
- image_t data2(size2);
- MPI_Gather(nodeResult.data(), sizeN, MPI_UNSIGNED_CHAR,
- data2.data(), sizeN, MPI_UNSIGNED_CHAR,
- 0, MPI_COMM_WORLD);
- // write output image (master node)
- if (iNode == 0)
- {
- writePgm("output_1.pgm", width, height, data2);
- std::cout << "walltime = " << MPI_Wtime() << std::endl;
- }
- MPI_Finalize();
- return 0;
- }
|