Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/mpi/collectives/scatter.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // Copyright (C) 2005, 2006 Douglas Gregor. | |
2 | |
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) | |
6 | |
7 // Message Passing Interface 1.1 -- Section 4.6. Scatter | |
8 #ifndef BOOST_MPI_SCATTER_HPP | |
9 #define BOOST_MPI_SCATTER_HPP | |
10 | |
11 #include <boost/mpi/exception.hpp> | |
12 #include <boost/mpi/datatype.hpp> | |
13 #include <vector> | |
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> | |
20 | |
21 namespace boost { namespace mpi { | |
22 | |
23 namespace detail { | |
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. | |
26 template<typename T> | |
27 void | |
28 scatter_impl(const communicator& comm, const T* in_values, T* out_values, | |
29 int n, int root, mpl::true_) | |
30 { | |
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)); | |
35 } | |
36 | |
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. | |
39 template<typename T> | |
40 void | |
41 scatter_impl(const communicator& comm, T* out_values, int n, int root, | |
42 mpl::true_) | |
43 { | |
44 MPI_Datatype type = get_mpi_datatype<T>(*out_values); | |
45 BOOST_MPI_CHECK_RESULT(MPI_Scatter, | |
46 (0, n, type, | |
47 out_values, n, type, | |
48 root, comm)); | |
49 } | |
50 | |
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 | |
55 // processes. | |
56 template<typename T> | |
57 void | |
58 scatter_impl(const communicator& comm, const T* in_values, T* out_values, | |
59 int n, int root, mpl::false_) | |
60 { | |
61 int tag = environment::collectives_tag(); | |
62 int size = comm.size(); | |
63 | |
64 for (int dest = 0; dest < size; ++dest) { | |
65 if (dest == root) { | |
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); | |
68 } else { | |
69 // Send archive | |
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); | |
74 } | |
75 } | |
76 } | |
77 | |
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. | |
83 template<typename T> | |
84 void | |
85 scatter_impl(const communicator& comm, T* out_values, int n, int root, | |
86 mpl::false_) | |
87 { | |
88 int tag = environment::collectives_tag(); | |
89 | |
90 packed_iarchive ia(comm); | |
91 MPI_Status status; | |
92 detail::packed_archive_recv(comm, root, tag, ia, status); | |
93 for (int i = 0; i < n; ++i) | |
94 ia >> out_values[i]; | |
95 } | |
96 } // end namespace detail | |
97 | |
98 template<typename T> | |
99 void | |
100 scatter(const communicator& comm, const T* in_values, T& out_value, int root) | |
101 { | |
102 if (comm.rank() == root) | |
103 detail::scatter_impl(comm, in_values, &out_value, 1, root, | |
104 is_mpi_datatype<T>()); | |
105 else | |
106 detail::scatter_impl(comm, &out_value, 1, root, is_mpi_datatype<T>()); | |
107 } | |
108 | |
109 template<typename T> | |
110 void | |
111 scatter(const communicator& comm, const std::vector<T>& in_values, T& out_value, | |
112 int root) | |
113 { | |
114 if (comm.rank() == root) | |
115 ::boost::mpi::scatter<T>(comm, &in_values[0], out_value, root); | |
116 else | |
117 ::boost::mpi::scatter<T>(comm, static_cast<const T*>(0), out_value, | |
118 root); | |
119 } | |
120 | |
121 template<typename T> | |
122 void scatter(const communicator& comm, T& out_value, int root) | |
123 { | |
124 BOOST_ASSERT(comm.rank() != root); | |
125 detail::scatter_impl(comm, &out_value, 1, root, is_mpi_datatype<T>()); | |
126 } | |
127 | |
128 template<typename T> | |
129 void | |
130 scatter(const communicator& comm, const T* in_values, T* out_values, int n, | |
131 int root) | |
132 { | |
133 if (comm.rank() == root) | |
134 detail::scatter_impl(comm, in_values, out_values, n, root, | |
135 is_mpi_datatype<T>()); | |
136 else | |
137 detail::scatter_impl(comm, out_values, n, root, is_mpi_datatype<T>()); | |
138 } | |
139 | |
140 template<typename T> | |
141 void | |
142 scatter(const communicator& comm, const std::vector<T>& in_values, | |
143 T* out_values, int n, int root) | |
144 { | |
145 if (comm.rank() == root) | |
146 ::boost::mpi::scatter(comm, &in_values[0], out_values, n, root); | |
147 else | |
148 ::boost::mpi::scatter(comm, static_cast<const T*>(0), out_values, | |
149 n, root); | |
150 } | |
151 | |
152 template<typename T> | |
153 void scatter(const communicator& comm, T* out_values, int n, int root) | |
154 { | |
155 BOOST_ASSERT(comm.rank() != root); | |
156 detail::scatter_impl(comm, out_values, n, root, is_mpi_datatype<T>()); | |
157 } | |
158 | |
159 } } // end namespace boost::mpi | |
160 | |
161 #endif // BOOST_MPI_SCATTER_HPP |