laplacien_mpi_1.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // mpic++ -std=c++11 -Wall -Wextra -o laplacien_mpi_1.out laplacien_mpi_1.cpp
  2. // mpirun -n 4 ./laplacien_mpi_1.out canyon.pgm canyon_mpi_1.pgm
  3. // mix master code and slave code
  4. #include "image.hpp"
  5. #include <algorithm>
  6. #include <mpi.h>
  7. int main(int argc, char ** argv)
  8. {
  9. // init MPI
  10. MPI_Init(&argc, &argv);
  11. int worldSize;
  12. MPI_Comm_size(MPI_COMM_WORLD, &worldSize);
  13. int worldRank;
  14. MPI_Comm_rank(MPI_COMM_WORLD, &worldRank);
  15. double t0 = MPI_Wtime();
  16. if (argc != 5)
  17. {
  18. std::cout << "usage: " << argv[0]
  19. << " <input> <output> <scaling> <nb fakes>\n";
  20. exit(-1);
  21. }
  22. const char * INPUT = argv[1];
  23. const char * OUTPUT = argv[2];
  24. const float SCALING = atof(argv[3]);
  25. const int NB_FAKES = atoi(argv[4]);
  26. // read image (master node)
  27. image_t data0;
  28. int width, height;
  29. if (worldRank == 0)
  30. {
  31. std::string readError = readPgm(INPUT, width, height, data0);
  32. if (readError != "")
  33. {
  34. std::cout << readError << std::endl;
  35. exit(-1);
  36. }
  37. }
  38. // broadcast image sizes
  39. MPI_Bcast(&width, 1, MPI_INT, 0, MPI_COMM_WORLD);
  40. MPI_Bcast(&height, 1, MPI_INT, 0, MPI_COMM_WORLD);
  41. int heightN = (height+worldSize-1) / worldSize;
  42. int sizeN = heightN * width;
  43. int height2 = heightN * worldSize;
  44. int size2 = height2 * width;
  45. // ensure height of data is a multiple of worldSize (master node)
  46. image_t data1(size2);
  47. if (worldRank == 0)
  48. {
  49. std::copy_n(data0.begin(), width*height, data1.begin());
  50. }
  51. // send data to nodes
  52. image_t nodeData(sizeN);
  53. MPI_Scatter(data1.data(), sizeN, MPI_UNSIGNED_CHAR,
  54. nodeData.data(), sizeN, MPI_UNSIGNED_CHAR,
  55. 0, MPI_COMM_WORLD);
  56. // compute on each node
  57. image_t nodeResult = computeLaplacian(nodeData, width, heightN, SCALING);
  58. for (int k=0; k<NB_FAKES; ++k)
  59. nodeResult = computeLaplacian(nodeData, width, heightN, SCALING);
  60. // receive results from nodes
  61. image_t data2(size2);
  62. MPI_Gather(nodeResult.data(), sizeN, MPI_UNSIGNED_CHAR,
  63. data2.data(), sizeN, MPI_UNSIGNED_CHAR,
  64. 0, MPI_COMM_WORLD);
  65. // write output image (master node)
  66. if (worldRank == 0)
  67. {
  68. writePgm(OUTPUT, width, height, data2);
  69. double t1 = MPI_Wtime();
  70. std::cout << t1 - t0;
  71. }
  72. MPI_Finalize();
  73. return 0;
  74. }