all_gatherv.hpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Copyright (C) 2005, 2006 Douglas Gregor.
  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. // Message Passing Interface 1.1 -- Section 4.5. Gatherv
  6. #ifndef BOOST_MPI_ALLGATHERV_HPP
  7. #define BOOST_MPI_ALLGATHERV_HPP
  8. #include <cassert>
  9. #include <cstddef>
  10. #include <numeric>
  11. #include <vector>
  12. #include <boost/mpi/exception.hpp>
  13. #include <boost/mpi/datatype.hpp>
  14. #include <boost/mpi/packed_oarchive.hpp>
  15. #include <boost/mpi/packed_iarchive.hpp>
  16. #include <boost/mpi/detail/point_to_point.hpp>
  17. #include <boost/mpi/communicator.hpp>
  18. #include <boost/mpi/environment.hpp>
  19. #include <boost/mpi/detail/offsets.hpp>
  20. #include <boost/mpi/detail/antiques.hpp>
  21. #include <boost/assert.hpp>
  22. #include <boost/scoped_array.hpp>
  23. namespace boost { namespace mpi {
  24. namespace detail {
  25. // We're all-gathering for a type that has an associated MPI
  26. // datatype, so we'll use MPI_Gather to do all of the work.
  27. template<typename T>
  28. void
  29. all_gatherv_impl(const communicator& comm, const T* in_values,
  30. T* out_values, int const* sizes, int const* displs, mpl::true_)
  31. {
  32. // Make displacements if not provided
  33. scoped_array<int> new_offsets_mem(make_offsets(comm, sizes, displs, -1));
  34. if (new_offsets_mem) displs = new_offsets_mem.get();
  35. MPI_Datatype type = get_mpi_datatype<T>(*in_values);
  36. BOOST_MPI_CHECK_RESULT(MPI_Allgatherv,
  37. (const_cast<T*>(in_values), sizes[comm.rank()], type,
  38. out_values,
  39. const_cast<int*>(sizes),
  40. const_cast<int*>(displs),
  41. type,
  42. comm));
  43. }
  44. // We're all-gathering for a type that does not have an
  45. // associated MPI datatype, so we'll need to serialize
  46. // it.
  47. template<typename T>
  48. void
  49. all_gatherv_impl(const communicator& comm, const T* in_values,
  50. T* out_values, int const* sizes, int const* displs,
  51. mpl::false_ isnt_mpi_type)
  52. {
  53. // convert displacement to offsets to skip
  54. scoped_array<int> skipped(make_skipped_slots(comm, sizes, displs));
  55. all_gather_impl(comm, in_values, sizes[comm.rank()], out_values,
  56. sizes, skipped.get(), isnt_mpi_type);
  57. }
  58. } // end namespace detail
  59. template<typename T>
  60. void
  61. all_gatherv(const communicator& comm, const T& in_value, T* out_values,
  62. const std::vector<int>& sizes)
  63. {
  64. using detail::c_data;
  65. assert(sizes.size() == comm.size());
  66. assert(sizes[comm.rank()] == 1);
  67. detail::all_gatherv_impl(comm, &in_value, out_values, c_data(sizes), 0, is_mpi_datatype<T>());
  68. }
  69. template<typename T>
  70. void
  71. all_gatherv(const communicator& comm, const T* in_values, T* out_values,
  72. const std::vector<int>& sizes)
  73. {
  74. using detail::c_data;
  75. assert(int(sizes.size()) == comm.size());
  76. detail::all_gatherv_impl(comm, in_values, out_values, c_data(sizes), 0, is_mpi_datatype<T>());
  77. }
  78. template<typename T>
  79. void
  80. all_gatherv(const communicator& comm, std::vector<T> const& in_values, std::vector<T>& out_values,
  81. const std::vector<int>& sizes)
  82. {
  83. using detail::c_data;
  84. assert(int(sizes.size()) == comm.size());
  85. assert(int(in_values.size()) == sizes[comm.rank()]);
  86. out_values.resize(std::accumulate(sizes.begin(), sizes.end(), 0));
  87. ::boost::mpi::all_gatherv(comm, c_data(in_values), c_data(out_values), sizes);
  88. }
  89. template<typename T>
  90. void
  91. all_gatherv(const communicator& comm, const T& in_value, T* out_values,
  92. const std::vector<int>& sizes, const std::vector<int>& displs)
  93. {
  94. using detail::c_data;
  95. assert(sizes.size() == comm.size());
  96. assert(displs.size() == comm.size());
  97. detail::all_gatherv_impl(comm, &in_value, 1, out_values,
  98. c_data(sizes), c_data(displs), is_mpi_datatype<T>());
  99. }
  100. template<typename T>
  101. void
  102. all_gatherv(const communicator& comm, const T* in_values, T* out_values,
  103. const std::vector<int>& sizes, const std::vector<int>& displs)
  104. {
  105. using detail::c_data;
  106. assert(sizes.size() == comm.size());
  107. assert(displs.size() == comm.size());
  108. detail::all_gatherv_impl(comm, in_values, out_values,
  109. c_data(sizes), c_data(displs), is_mpi_datatype<T>());
  110. }
  111. template<typename T>
  112. void
  113. all_gatherv(const communicator& comm, std::vector<T> const& in_values, std::vector<T>& out_values,
  114. const std::vector<int>& sizes, const std::vector<int>& displs)
  115. {
  116. using detail::c_data;
  117. assert(sizes.size() == comm.size());
  118. assert(displs.size() == comm.size());
  119. assert(in_values.size() == sizes[comm.rank()]);
  120. out_values.resize(std::accumulate(sizes.begin(), sizes.end(), 0));
  121. ::boost::mpi::all_gatherv(comm, c_data(in_values), c_data(out_values), sizes, displs);
  122. }
  123. } } // end namespace boost::mpi
  124. #endif // BOOST_MPI_ALL_GATHERV_HPP