1 // Copyright (C) 2005, 2006 Douglas Gregor.
3 // Use, modification and distribution is subject to the Boost Software
4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
7 // Message Passing Interface 1.1 -- Section 4.5. Gather
8 #ifndef BOOST_MPI_GATHER_HPP
9 #define BOOST_MPI_GATHER_HPP
11 #include <boost/mpi/exception.hpp>
12 #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/assert.hpp>
21 namespace boost
{ namespace mpi
{
24 // We're gathering at the root for a type that has an associated MPI
25 // datatype, so we'll use MPI_Gather to do all of the work.
28 gather_impl(const communicator
& comm
, const T
* in_values
, int n
,
29 T
* out_values
, int root
, mpl::true_
)
31 MPI_Datatype type
= get_mpi_datatype
<T
>(*in_values
);
32 BOOST_MPI_CHECK_RESULT(MPI_Gather
,
33 (const_cast<T
*>(in_values
), n
, type
,
34 out_values
, n
, type
, root
, comm
));
37 // We're gathering from a non-root for a type that has an associated MPI
38 // datatype, so we'll use MPI_Gather to do all of the work.
41 gather_impl(const communicator
& comm
, const T
* in_values
, int n
, int root
,
44 MPI_Datatype type
= get_mpi_datatype
<T
>(*in_values
);
45 BOOST_MPI_CHECK_RESULT(MPI_Gather
,
46 (const_cast<T
*>(in_values
), n
, type
,
47 0, n
, type
, root
, comm
));
50 // We're gathering at the root for a type that does not have an
51 // associated MPI datatype, so we'll need to serialize
52 // it. Unfortunately, this means that we cannot use MPI_Gather, so
53 // we'll just have all of the non-root nodes send individual
54 // messages to the root.
57 gather_impl(const communicator
& comm
, const T
* in_values
, int n
,
58 T
* out_values
, int root
, mpl::false_
)
60 int tag
= environment::collectives_tag();
61 int size
= comm
.size();
63 for (int src
= 0; src
< size
; ++src
) {
65 std::copy(in_values
, in_values
+ n
, out_values
+ n
* src
);
67 comm
.recv(src
, tag
, out_values
+ n
* src
, n
);
71 // We're gathering at a non-root for a type that does not have an
72 // associated MPI datatype, so we'll need to serialize
73 // it. Unfortunately, this means that we cannot use MPI_Gather, so
74 // we'll just have all of the non-root nodes send individual
75 // messages to the root.
78 gather_impl(const communicator
& comm
, const T
* in_values
, int n
, int root
,
81 int tag
= environment::collectives_tag();
82 comm
.send(root
, tag
, in_values
, n
);
84 } // end namespace detail
88 gather(const communicator
& comm
, const T
& in_value
, T
* out_values
, int root
)
90 if (comm
.rank() == root
)
91 detail::gather_impl(comm
, &in_value
, 1, out_values
, root
,
92 is_mpi_datatype
<T
>());
94 detail::gather_impl(comm
, &in_value
, 1, root
, is_mpi_datatype
<T
>());
98 void gather(const communicator
& comm
, const T
& in_value
, int root
)
100 BOOST_ASSERT(comm
.rank() != root
);
101 detail::gather_impl(comm
, &in_value
, 1, root
, is_mpi_datatype
<T
>());
106 gather(const communicator
& comm
, const T
& in_value
, std::vector
<T
>& out_values
,
109 if (comm
.rank() == root
) {
110 out_values
.resize(comm
.size());
111 ::boost::mpi::gather(comm
, in_value
, &out_values
[0], root
);
113 ::boost::mpi::gather(comm
, in_value
, root
);
119 gather(const communicator
& comm
, const T
* in_values
, int n
, T
* out_values
,
122 if (comm
.rank() == root
)
123 detail::gather_impl(comm
, in_values
, n
, out_values
, root
,
124 is_mpi_datatype
<T
>());
126 detail::gather_impl(comm
, in_values
, n
, root
, is_mpi_datatype
<T
>());
131 gather(const communicator
& comm
, const T
* in_values
, int n
,
132 std::vector
<T
>& out_values
, int root
)
134 ::boost::mpi::gather(comm
, in_values
, n
, &out_values
[0], root
);
138 void gather(const communicator
& comm
, const T
* in_values
, int n
, int root
)
140 BOOST_ASSERT(comm
.rank() != root
);
141 detail::gather_impl(comm
, in_values
, n
, root
, is_mpi_datatype
<T
>());
145 } } // end namespace boost::mpi
147 #endif // BOOST_MPI_GATHER_HPP