annotate DEPENDENCIES/generic/include/boost/mpi/collectives/gather.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Copyright (C) 2005, 2006 Douglas Gregor.
Chris@16 2
Chris@16 3 // Use, modification and distribution is subject to the Boost Software
Chris@16 4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 5 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6
Chris@16 7 // Message Passing Interface 1.1 -- Section 4.5. Gather
Chris@16 8 #ifndef BOOST_MPI_GATHER_HPP
Chris@16 9 #define BOOST_MPI_GATHER_HPP
Chris@16 10
Chris@16 11 #include <boost/mpi/exception.hpp>
Chris@16 12 #include <boost/mpi/datatype.hpp>
Chris@16 13 #include <vector>
Chris@16 14 #include <boost/mpi/packed_oarchive.hpp>
Chris@16 15 #include <boost/mpi/packed_iarchive.hpp>
Chris@16 16 #include <boost/mpi/detail/point_to_point.hpp>
Chris@16 17 #include <boost/mpi/communicator.hpp>
Chris@16 18 #include <boost/mpi/environment.hpp>
Chris@16 19 #include <boost/assert.hpp>
Chris@16 20
Chris@16 21 namespace boost { namespace mpi {
Chris@16 22
Chris@16 23 namespace detail {
Chris@16 24 // We're gathering at the root for a type that has an associated MPI
Chris@16 25 // datatype, so we'll use MPI_Gather to do all of the work.
Chris@16 26 template<typename T>
Chris@16 27 void
Chris@16 28 gather_impl(const communicator& comm, const T* in_values, int n,
Chris@16 29 T* out_values, int root, mpl::true_)
Chris@16 30 {
Chris@16 31 MPI_Datatype type = get_mpi_datatype<T>(*in_values);
Chris@16 32 BOOST_MPI_CHECK_RESULT(MPI_Gather,
Chris@16 33 (const_cast<T*>(in_values), n, type,
Chris@16 34 out_values, n, type, root, comm));
Chris@16 35 }
Chris@16 36
Chris@16 37 // We're gathering from a non-root for a type that has an associated MPI
Chris@16 38 // datatype, so we'll use MPI_Gather to do all of the work.
Chris@16 39 template<typename T>
Chris@16 40 void
Chris@16 41 gather_impl(const communicator& comm, const T* in_values, int n, int root,
Chris@16 42 mpl::true_)
Chris@16 43 {
Chris@16 44 MPI_Datatype type = get_mpi_datatype<T>(*in_values);
Chris@16 45 BOOST_MPI_CHECK_RESULT(MPI_Gather,
Chris@16 46 (const_cast<T*>(in_values), n, type,
Chris@16 47 0, n, type, root, comm));
Chris@16 48 }
Chris@16 49
Chris@16 50 // We're gathering at the root for a type that does not have an
Chris@16 51 // associated MPI datatype, so we'll need to serialize
Chris@16 52 // it. Unfortunately, this means that we cannot use MPI_Gather, so
Chris@16 53 // we'll just have all of the non-root nodes send individual
Chris@16 54 // messages to the root.
Chris@16 55 template<typename T>
Chris@16 56 void
Chris@16 57 gather_impl(const communicator& comm, const T* in_values, int n,
Chris@16 58 T* out_values, int root, mpl::false_)
Chris@16 59 {
Chris@16 60 int tag = environment::collectives_tag();
Chris@16 61 int size = comm.size();
Chris@16 62
Chris@16 63 for (int src = 0; src < size; ++src) {
Chris@16 64 if (src == root)
Chris@16 65 std::copy(in_values, in_values + n, out_values + n * src);
Chris@16 66 else
Chris@16 67 comm.recv(src, tag, out_values + n * src, n);
Chris@16 68 }
Chris@16 69 }
Chris@16 70
Chris@16 71 // We're gathering at a non-root for a type that does not have an
Chris@16 72 // associated MPI datatype, so we'll need to serialize
Chris@16 73 // it. Unfortunately, this means that we cannot use MPI_Gather, so
Chris@16 74 // we'll just have all of the non-root nodes send individual
Chris@16 75 // messages to the root.
Chris@16 76 template<typename T>
Chris@16 77 void
Chris@16 78 gather_impl(const communicator& comm, const T* in_values, int n, int root,
Chris@16 79 mpl::false_)
Chris@16 80 {
Chris@16 81 int tag = environment::collectives_tag();
Chris@16 82 comm.send(root, tag, in_values, n);
Chris@16 83 }
Chris@16 84 } // end namespace detail
Chris@16 85
Chris@16 86 template<typename T>
Chris@16 87 void
Chris@16 88 gather(const communicator& comm, const T& in_value, T* out_values, int root)
Chris@16 89 {
Chris@16 90 if (comm.rank() == root)
Chris@16 91 detail::gather_impl(comm, &in_value, 1, out_values, root,
Chris@16 92 is_mpi_datatype<T>());
Chris@16 93 else
Chris@16 94 detail::gather_impl(comm, &in_value, 1, root, is_mpi_datatype<T>());
Chris@16 95 }
Chris@16 96
Chris@16 97 template<typename T>
Chris@16 98 void gather(const communicator& comm, const T& in_value, int root)
Chris@16 99 {
Chris@16 100 BOOST_ASSERT(comm.rank() != root);
Chris@16 101 detail::gather_impl(comm, &in_value, 1, root, is_mpi_datatype<T>());
Chris@16 102 }
Chris@16 103
Chris@16 104 template<typename T>
Chris@16 105 void
Chris@16 106 gather(const communicator& comm, const T& in_value, std::vector<T>& out_values,
Chris@16 107 int root)
Chris@16 108 {
Chris@16 109 if (comm.rank() == root) {
Chris@16 110 out_values.resize(comm.size());
Chris@16 111 ::boost::mpi::gather(comm, in_value, &out_values[0], root);
Chris@16 112 } else {
Chris@16 113 ::boost::mpi::gather(comm, in_value, root);
Chris@16 114 }
Chris@16 115 }
Chris@16 116
Chris@16 117 template<typename T>
Chris@16 118 void
Chris@16 119 gather(const communicator& comm, const T* in_values, int n, T* out_values,
Chris@16 120 int root)
Chris@16 121 {
Chris@16 122 if (comm.rank() == root)
Chris@16 123 detail::gather_impl(comm, in_values, n, out_values, root,
Chris@16 124 is_mpi_datatype<T>());
Chris@16 125 else
Chris@16 126 detail::gather_impl(comm, in_values, n, root, is_mpi_datatype<T>());
Chris@16 127 }
Chris@16 128
Chris@16 129 template<typename T>
Chris@16 130 void
Chris@16 131 gather(const communicator& comm, const T* in_values, int n,
Chris@16 132 std::vector<T>& out_values, int root)
Chris@16 133 {
Chris@16 134 if (comm.rank() == root) {
Chris@16 135 out_values.resize(comm.size() * n);
Chris@16 136 ::boost::mpi::gather(comm, in_values, n, &out_values[0], root);
Chris@16 137 }
Chris@16 138 else
Chris@16 139 ::boost::mpi::gather(comm, in_values, n, root);
Chris@16 140 }
Chris@16 141
Chris@16 142 template<typename T>
Chris@16 143 void gather(const communicator& comm, const T* in_values, int n, int root)
Chris@16 144 {
Chris@16 145 BOOST_ASSERT(comm.rank() != root);
Chris@16 146 detail::gather_impl(comm, in_values, n, root, is_mpi_datatype<T>());
Chris@16 147 }
Chris@16 148
Chris@16 149
Chris@16 150 } } // end namespace boost::mpi
Chris@16 151
Chris@16 152 #endif // BOOST_MPI_GATHER_HPP