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.6. Scatter
8 #ifndef BOOST_MPI_SCATTER_HPP
9 #define BOOST_MPI_SCATTER_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 scattering from the root for a type that has an associated MPI
25 // datatype, so we'll use MPI_Scatter to do all of the work.
28 scatter_impl(const communicator
& comm
, const T
* in_values
, T
* out_values
,
29 int n
, int root
, mpl::true_
)
31 MPI_Datatype type
= get_mpi_datatype
<T
>(*in_values
);
32 BOOST_MPI_CHECK_RESULT(MPI_Scatter
,
33 (const_cast<T
*>(in_values
), n
, type
,
34 out_values
, n
, type
, root
, comm
));
37 // We're scattering from a non-root for a type that has an associated MPI
38 // datatype, so we'll use MPI_Scatter to do all of the work.
41 scatter_impl(const communicator
& comm
, T
* out_values
, int n
, int root
,
44 MPI_Datatype type
= get_mpi_datatype
<T
>(*out_values
);
45 BOOST_MPI_CHECK_RESULT(MPI_Scatter
,
51 // We're scattering from the root for a type that does not have an
52 // associated MPI datatype, so we'll need to serialize
53 // it. Unfortunately, this means that we cannot use MPI_Scatter, so
54 // we'll just have the root send individual messages to the other
58 scatter_impl(const communicator
& comm
, const T
* in_values
, T
* out_values
,
59 int n
, int root
, mpl::false_
)
61 int tag
= environment::collectives_tag();
62 int size
= comm
.size();
64 for (int dest
= 0; dest
< size
; ++dest
) {
66 // Our own values will never be transmitted: just copy them.
67 std::copy(in_values
+ dest
* n
, in_values
+ (dest
+ 1) * n
, out_values
);
70 packed_oarchive
oa(comm
);
71 for (int i
= 0; i
< n
; ++i
)
72 oa
<< in_values
[dest
* n
+ i
];
73 detail::packed_archive_send(comm
, dest
, tag
, oa
);
78 // We're scattering to a non-root for a type that does not have an
79 // associated MPI datatype, so we'll need to de-serialize
80 // it. Unfortunately, this means that we cannot use MPI_Scatter, so
81 // we'll just have all of the non-root nodes send individual
82 // messages to the root.
85 scatter_impl(const communicator
& comm
, T
* out_values
, int n
, int root
,
88 int tag
= environment::collectives_tag();
90 packed_iarchive
ia(comm
);
92 detail::packed_archive_recv(comm
, root
, tag
, ia
, status
);
93 for (int i
= 0; i
< n
; ++i
)
96 } // end namespace detail
100 scatter(const communicator
& comm
, const T
* in_values
, T
& out_value
, int root
)
102 if (comm
.rank() == root
)
103 detail::scatter_impl(comm
, in_values
, &out_value
, 1, root
,
104 is_mpi_datatype
<T
>());
106 detail::scatter_impl(comm
, &out_value
, 1, root
, is_mpi_datatype
<T
>());
111 scatter(const communicator
& comm
, const std::vector
<T
>& in_values
, T
& out_value
,
114 if (comm
.rank() == root
)
115 ::boost::mpi::scatter
<T
>(comm
, &in_values
[0], out_value
, root
);
117 ::boost::mpi::scatter
<T
>(comm
, static_cast<const T
*>(0), out_value
,
122 void scatter(const communicator
& comm
, T
& out_value
, int root
)
124 BOOST_ASSERT(comm
.rank() != root
);
125 detail::scatter_impl(comm
, &out_value
, 1, root
, is_mpi_datatype
<T
>());
130 scatter(const communicator
& comm
, const T
* in_values
, T
* out_values
, int n
,
133 if (comm
.rank() == root
)
134 detail::scatter_impl(comm
, in_values
, out_values
, n
, root
,
135 is_mpi_datatype
<T
>());
137 detail::scatter_impl(comm
, out_values
, n
, root
, is_mpi_datatype
<T
>());
142 scatter(const communicator
& comm
, const std::vector
<T
>& in_values
,
143 T
* out_values
, int n
, int root
)
145 if (comm
.rank() == root
)
146 ::boost::mpi::scatter(comm
, &in_values
[0], out_values
, n
, root
);
148 ::boost::mpi::scatter(comm
, static_cast<const T
*>(0), out_values
,
153 void scatter(const communicator
& comm
, T
* out_values
, int n
, int root
)
155 BOOST_ASSERT(comm
.rank() != root
);
156 detail::scatter_impl(comm
, out_values
, n
, root
, is_mpi_datatype
<T
>());
159 } } // end namespace boost::mpi
161 #endif // BOOST_MPI_SCATTER_HPP