laplacien_mpi_1.cpp 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  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 worldSize;
  11. MPI_Comm_size(MPI_COMM_WORLD, &worldSize);
  12. int worldRank;
  13. MPI_Comm_rank(MPI_COMM_WORLD, &worldRank);
  14. double t0 = MPI_Wtime();
  15. // read image (master node)
  16. image_t data0;
  17. int width, height;
  18. if (worldRank == 0)
  19. {
  20. std::string readError = readPgm("backloop.pgm", width, height, data0);
  21. if (readError != "")
  22. {
  23. std::cout << readError << std::endl;
  24. exit(-1);
  25. }
  26. }
  27. // broadcast image sizes
  28. MPI_Bcast(&width, 1, MPI_INT, 0, MPI_COMM_WORLD);
  29. MPI_Bcast(&height, 1, MPI_INT, 0, MPI_COMM_WORLD);
  30. int heightN = (height+worldSize-1) / worldSize;
  31. int sizeN = heightN * width;
  32. int height2 = heightN * worldSize;
  33. int size2 = height2 * width;
  34. // ensure height of data is a multiple of worldSize (master node)
  35. image_t data1(size2);
  36. if (worldRank == 0)
  37. {
  38. std::copy_n(data0.begin(), width*height, data1.begin());
  39. }
  40. // send data to nodes
  41. image_t nodeData(sizeN);
  42. MPI_Scatter(data1.data(), sizeN, MPI_UNSIGNED_CHAR,
  43. nodeData.data(), sizeN, MPI_UNSIGNED_CHAR,
  44. 0, MPI_COMM_WORLD);
  45. // compute on each node
  46. image_t nodeResult = computeLaplacian(nodeData, width, heightN, 10.0);
  47. // receive results from nodes
  48. image_t data2(size2);
  49. MPI_Gather(nodeResult.data(), sizeN, MPI_UNSIGNED_CHAR,
  50. data2.data(), sizeN, MPI_UNSIGNED_CHAR,
  51. 0, MPI_COMM_WORLD);
  52. // write output image (master node)
  53. if (worldRank == 0)
  54. {
  55. writePgm("output_1.pgm", width, height, data2);
  56. double t1 = MPI_Wtime();
  57. std::cout << "walltime = " << t1 - t0 << std::endl;
  58. }
  59. MPI_Finalize();
  60. return 0;
  61. }