laplacien_mpi.cpp 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // mpic++ -std=c++11 -Wall -Wextra -lboost_mpi -lboost_serialization -o laplacien_mpi.out laplacien_mpi.cpp
  2. // mpirun -n 50 --hostfile mpi_file ./laplacien_mpi.out
  3. #include "image.hpp"
  4. #include <boost/mpi.hpp>
  5. namespace mpi = boost::mpi;
  6. #include <algorithm>
  7. int main(int argc, char ** argv)
  8. {
  9. mpi::environment env(argc, argv);
  10. mpi::communicator world;
  11. int rank = world.rank();
  12. int size = world.size();
  13. int Nj = size;
  14. if (rank == 0) // master node
  15. {
  16. // read image
  17. image_t data0;
  18. int width, height;
  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. int heightN = (height+Nj-1) / Nj;
  26. int height2 = heightN * Nj;
  27. int sizeN = heightN * width;
  28. // copy data0 in data1
  29. // ensure the height of data1 is a multiple of Nj
  30. image_t data1(width*height2);
  31. std::copy_n(data0.begin(), width*height,
  32. std::inserter(data1, data1.begin()));
  33. // some data for MPI transfers
  34. image_t data(sizeN);
  35. std::vector<image_t> allData(Nj, data);
  36. std::vector<image_t> allResults(Nj, data);
  37. // decompose image
  38. for (int j=0; j<Nj; j++)
  39. std::copy_n(data1.begin()+(j*sizeN), sizeN,
  40. std::inserter(allData[j], allData[j].begin()));
  41. // send subimage sizes to slave nodes
  42. mpi::broadcast(world, width, 0);
  43. mpi::broadcast(world, heightN, 0);
  44. // send data to slave nodes
  45. image_t nodeData;
  46. mpi::scatter(world, allData, nodeData, 0);
  47. // compute master data
  48. image_t nodeResult = computeLaplacian(nodeData, width, heightN, 10.0);
  49. // receive results from slave nodes
  50. mpi::gather(world, nodeResult, allResults, 0);
  51. // recompose image
  52. image_t data2(width*height2);
  53. for (int j=0; j<Nj; j++)
  54. std::copy_n(allResults[j].begin(), sizeN,
  55. std::inserter(data2, data2.begin()+(j*sizeN)));
  56. // write output image
  57. writePgm("output.pgm", width, height, data2);
  58. }
  59. else // slave nodes
  60. {
  61. // receive subimage sizes
  62. int width;
  63. mpi::broadcast(world, width, 0);
  64. int heightN;
  65. mpi::broadcast(world, heightN, 0);
  66. // receive data from master node
  67. image_t nodeData(width,heightN);
  68. mpi::scatter(world, nodeData, 0);
  69. // compute node data
  70. image_t nodeResult = computeLaplacian(nodeData, width, heightN, 10.0);
  71. // send results to master node
  72. mpi::gather(world, nodeResult, 0);
  73. }
  74. return 0;
  75. }