inplace_all_to_all.hpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // Copyright 2005 The Trustees of Indiana University.
  2. // Use, modification and distribution is subject to the Boost Software
  3. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // Authors: Douglas Gregor
  6. // Andrew Lumsdaine
  7. #ifndef BOOST_GRAPH_PARALLEL_INPLACE_ALL_TO_ALL_HPP
  8. #define BOOST_GRAPH_PARALLEL_INPLACE_ALL_TO_ALL_HPP
  9. #ifndef BOOST_GRAPH_USE_MPI
  10. #error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
  11. #endif
  12. //
  13. // Implements the inplace all-to-all communication algorithm.
  14. //
  15. #include <vector>
  16. #include <iterator>
  17. namespace boost { namespace parallel {
  18. template<typename ProcessGroup, typename T>
  19. // where {LinearProcessGroup<ProcessGroup>, MessagingProcessGroup<ProcessGroup>}
  20. void
  21. inplace_all_to_all(ProcessGroup pg,
  22. const std::vector<std::vector<T> >& outgoing,
  23. std::vector<std::vector<T> >& incoming)
  24. {
  25. typedef typename std::vector<T>::size_type size_type;
  26. typedef typename ProcessGroup::process_size_type process_size_type;
  27. typedef typename ProcessGroup::process_id_type process_id_type;
  28. process_size_type p = num_processes(pg);
  29. // Make sure there are no straggling messages
  30. synchronize(pg);
  31. // Send along the count (always) and the data (if count > 0)
  32. for (process_id_type dest = 0; dest < p; ++dest) {
  33. if (dest != process_id(pg)) {
  34. send(pg, dest, 0, outgoing[dest].size());
  35. if (!outgoing[dest].empty())
  36. send(pg, dest, 1, &outgoing[dest].front(), outgoing[dest].size());
  37. }
  38. }
  39. // Make sure all of the data gets transferred
  40. synchronize(pg);
  41. // Receive the sizes and data
  42. for (process_id_type source = 0; source < p; ++source) {
  43. if (source != process_id(pg)) {
  44. size_type size;
  45. receive(pg, source, 0, size);
  46. incoming[source].resize(size);
  47. if (size > 0)
  48. receive(pg, source, 1, &incoming[source].front(), size);
  49. } else if (&incoming != &outgoing) {
  50. incoming[source] = outgoing[source];
  51. }
  52. }
  53. }
  54. template<typename ProcessGroup, typename T>
  55. // where {LinearProcessGroup<ProcessGroup>, MessagingProcessGroup<ProcessGroup>}
  56. void
  57. inplace_all_to_all(ProcessGroup pg, std::vector<std::vector<T> >& data)
  58. {
  59. inplace_all_to_all(pg, data, data);
  60. }
  61. } } // end namespace boost::parallel
  62. #endif // BOOST_GRAPH_PARALLEL_INPLACE_ALL_TO_ALL_HPP