laplacien_mpi_1.cpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // mpic++ -std=c++11 -Wall -Wextra -o laplacien_mpi_1.out laplacien_mpi_1.cpp
  2. // mpirun -n 4 ./laplacien_mpi_1.out
  3. #include "image.hpp"
  4. #include <algorithm>
  5. #include <mpi.h>
  6. int main(int argc, char ** argv)
  7. {
  8. // init MPI
  9. MPI_Init(&argc, &argv);
  10. int nbNodes;
  11. MPI_Comm_size(MPI_COMM_WORLD, &nbNodes);
  12. int iNode;
  13. MPI_Comm_rank(MPI_COMM_WORLD, &iNode);
  14. // read image (master node)
  15. image_t data0;
  16. int width, height;
  17. if (iNode == 0)
  18. {
  19. std::string readError = readPgm("backloop.pgm", width, height, data0);
  20. if (readError != "")
  21. {
  22. std::cout << readError << std::endl;
  23. exit(-1);
  24. }
  25. }
  26. // broadcast image sizes
  27. MPI_Bcast(&width, 1, MPI_INT, 0, MPI_COMM_WORLD);
  28. MPI_Bcast(&height, 1, MPI_INT, 0, MPI_COMM_WORLD);
  29. int heightN = (height+nbNodes-1) / nbNodes;
  30. int sizeN = heightN * width;
  31. int height2 = heightN * nbNodes;
  32. int size2 = height2 * width;
  33. // ensure height of data is a multiple of nbNodes (master node)
  34. image_t data1(size2);
  35. if (iNode == 0)
  36. {
  37. std::copy_n(data0.begin(), width*height, data1.begin());
  38. }
  39. // send data to nodes
  40. image_t nodeData(sizeN);
  41. MPI_Scatter(data1.data(), sizeN, MPI_UNSIGNED_CHAR,
  42. nodeData.data(), sizeN, MPI_UNSIGNED_CHAR,
  43. 0, MPI_COMM_WORLD);
  44. // compute on each node
  45. image_t nodeResult = computeLaplacian(nodeData, width, heightN, 10.0);
  46. // receive results from nodes
  47. image_t data2(size2);
  48. MPI_Gather(nodeResult.data(), sizeN, MPI_UNSIGNED_CHAR,
  49. data2.data(), sizeN, MPI_UNSIGNED_CHAR,
  50. 0, MPI_COMM_WORLD);
  51. // write output image (master node)
  52. if (iNode == 0)
  53. {
  54. writePgm("output_1.pgm", width, height, data2);
  55. std::cout << "walltime = " << MPI_Wtime() << std::endl;
  56. }
  57. MPI_Finalize();
  58. return 0;
  59. }