]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/mpi/src/communicator.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / mpi / src / communicator.cpp
CommitLineData
7c673cae
FG
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#include <boost/mpi/communicator.hpp>
7#include <boost/mpi/group.hpp>
8#include <boost/mpi/intercommunicator.hpp>
9#include <boost/mpi/graph_communicator.hpp>
11fdf7f2 10#include <boost/mpi/cartesian_communicator.hpp>
7c673cae
FG
11#include <boost/mpi/skeleton_and_content.hpp>
12#include <boost/mpi/detail/point_to_point.hpp>
13
14namespace boost { namespace mpi {
15
16/***************************************************************************
17 * status *
18 ***************************************************************************/
19bool status::cancelled() const
20{
21 int flag = 0;
22 BOOST_MPI_CHECK_RESULT(MPI_Test_cancelled, (&m_status, &flag));
23 return flag != 0;
24}
25
26/***************************************************************************
27 * communicator *
28 ***************************************************************************/
29
30communicator::communicator()
31{
32 comm_ptr.reset(new MPI_Comm(MPI_COMM_WORLD));
33}
34
35communicator::communicator(const MPI_Comm& comm, comm_create_kind kind)
36{
37 if (comm == MPI_COMM_NULL)
38 /* MPI_COMM_NULL indicates that the communicator is not usable. */
39 return;
40
41 switch (kind) {
42 case comm_duplicate:
43 {
44 MPI_Comm newcomm;
45 BOOST_MPI_CHECK_RESULT(MPI_Comm_dup, (comm, &newcomm));
46 comm_ptr.reset(new MPI_Comm(newcomm), comm_free());
47 MPI_Comm_set_errhandler(newcomm, MPI_ERRORS_RETURN);
48 break;
49 }
50
51 case comm_take_ownership:
52 comm_ptr.reset(new MPI_Comm(comm), comm_free());
53 break;
54
55 case comm_attach:
56 comm_ptr.reset(new MPI_Comm(comm));
57 break;
58 }
59}
60
61communicator::communicator(const communicator& comm,
62 const boost::mpi::group& subgroup)
63{
64 MPI_Comm newcomm;
65 BOOST_MPI_CHECK_RESULT(MPI_Comm_create,
66 ((MPI_Comm)comm, (MPI_Group)subgroup, &newcomm));
67 if(newcomm != MPI_COMM_NULL)
68 comm_ptr.reset(new MPI_Comm(newcomm), comm_free());
69}
70
71int communicator::size() const
72{
73 int size_;
74 BOOST_MPI_CHECK_RESULT(MPI_Comm_size, (MPI_Comm(*this), &size_));
75 return size_;
76}
77
78int communicator::rank() const
79{
80 int rank_;
81 BOOST_MPI_CHECK_RESULT(MPI_Comm_rank, (MPI_Comm(*this), &rank_));
82 return rank_;
83}
84
85boost::mpi::group communicator::group() const
86{
87 MPI_Group gr;
88 BOOST_MPI_CHECK_RESULT(MPI_Comm_group, ((MPI_Comm)*this, &gr));
89 return boost::mpi::group(gr, /*adopt=*/true);
90}
91
92void communicator::send(int dest, int tag) const
93{
94 BOOST_MPI_CHECK_RESULT(MPI_Send,
95 (MPI_BOTTOM, 0, MPI_PACKED,
96 dest, tag, MPI_Comm(*this)));
97}
98
99status communicator::recv(int source, int tag) const
100{
101 status stat;
102 BOOST_MPI_CHECK_RESULT(MPI_Recv,
103 (MPI_BOTTOM, 0, MPI_PACKED,
104 source, tag, MPI_Comm(*this), &stat.m_status));
105 return stat;
106}
107
108optional<status> communicator::iprobe(int source, int tag) const
109{
110 typedef optional<status> result_type;
111
112 status stat;
113 int flag;
114 BOOST_MPI_CHECK_RESULT(MPI_Iprobe,
115 (source, tag, MPI_Comm(*this), &flag,
116 &stat.m_status));
117 if (flag) return stat;
118 else return result_type();
119}
120
121status communicator::probe(int source, int tag) const
122{
123 status stat;
124 BOOST_MPI_CHECK_RESULT(MPI_Probe,
125 (source, tag, MPI_Comm(*this), &stat.m_status));
126 return stat;
127}
128
129void (communicator::barrier)() const
130{
131 BOOST_MPI_CHECK_RESULT(MPI_Barrier, (MPI_Comm(*this)));
132}
133
134
135communicator::operator MPI_Comm() const
136{
137 if (comm_ptr) return *comm_ptr;
138 else return MPI_COMM_NULL;
139}
140
141communicator communicator::split(int color) const
142{
143 return split(color, rank());
144}
145
146communicator communicator::split(int color, int key) const
147{
148 MPI_Comm newcomm;
149 BOOST_MPI_CHECK_RESULT(MPI_Comm_split,
150 (MPI_Comm(*this), color, key, &newcomm));
151 return communicator(newcomm, comm_take_ownership);
152}
153
154optional<intercommunicator> communicator::as_intercommunicator() const
155{
156 int flag;
157 BOOST_MPI_CHECK_RESULT(MPI_Comm_test_inter, ((MPI_Comm)*this, &flag));
158 if (flag)
159 return intercommunicator(comm_ptr);
160 else
161 return optional<intercommunicator>();
162}
163
11fdf7f2 164bool communicator::has_graph_topology() const
7c673cae 165{
11fdf7f2 166 bool is_graph = false;
7c673cae
FG
167 // topology test not allowed on MPI_NULL_COMM
168 if (bool(*this)) {
169 int status;
170 BOOST_MPI_CHECK_RESULT(MPI_Topo_test, ((MPI_Comm)*this, &status));
11fdf7f2
TL
171 is_graph = status == MPI_GRAPH;
172 }
173 return is_graph;
174}
175
176optional<graph_communicator> communicator::as_graph_communicator() const
177{
178 if (has_graph_topology()) {
179 return graph_communicator(comm_ptr);
180 } else {
181 return optional<graph_communicator>();
7c673cae 182 }
7c673cae
FG
183}
184
185bool communicator::has_cartesian_topology() const
186{
11fdf7f2 187 bool is_cart = false;
7c673cae 188 // topology test not allowed on MPI_NULL_COM
11fdf7f2 189 if (bool(*this)) {
7c673cae
FG
190 int status;
191 BOOST_MPI_CHECK_RESULT(MPI_Topo_test, ((MPI_Comm)*this, &status));
11fdf7f2
TL
192 is_cart = status == MPI_CART;
193 }
194 return is_cart;
195}
196
197optional<cartesian_communicator> communicator::as_cartesian_communicator() const
198{
199 if (has_cartesian_topology()) {
200 return cartesian_communicator(comm_ptr);
201 } else {
202 return optional<cartesian_communicator>();
7c673cae
FG
203 }
204}
205
206void communicator::abort(int errcode) const
207{
208 BOOST_MPI_CHECK_RESULT(MPI_Abort, (MPI_Comm(*this), errcode));
11fdf7f2 209 std::abort();
7c673cae
FG
210}
211
212/*************************************************************
213 * archived send/recv *
214 *************************************************************/
215template<>
216void
217communicator::send<packed_oarchive>(int dest, int tag,
218 const packed_oarchive& ar) const
219{
92f5a8d4 220 detail::packed_archive_send(*this, dest, tag, ar);
7c673cae
FG
221}
222
223template<>
224void
225communicator::send<packed_skeleton_oarchive>
226 (int dest, int tag, const packed_skeleton_oarchive& ar) const
227{
228 this->send(dest, tag, ar.get_skeleton());
229}
230
231template<>
232void communicator::send<content>(int dest, int tag, const content& c) const
233{
234 BOOST_MPI_CHECK_RESULT(MPI_Send,
235 (MPI_BOTTOM, 1, c.get_mpi_datatype(),
236 dest, tag, MPI_Comm(*this)));
237}
238
239template<>
240status
241communicator::recv<packed_iarchive>(int source, int tag,
242 packed_iarchive& ar) const
243{
244 status stat;
92f5a8d4 245 detail::packed_archive_recv(*this, source, tag, ar,
7c673cae
FG
246 stat.m_status);
247 return stat;
248}
249
250template<>
251status
252communicator::recv<packed_skeleton_iarchive>
253 (int source, int tag, packed_skeleton_iarchive& ar) const
254{
255 return this->recv(source, tag, ar.get_skeleton());
256}
257
258template<>
259status
260communicator::recv<const content>(int source, int tag, const content& c) const
261{
262 status stat;
263 BOOST_MPI_CHECK_RESULT(MPI_Recv,
264 (MPI_BOTTOM, 1, c.get_mpi_datatype(),
265 source, tag, MPI_Comm(*this), &stat.m_status));
266 return stat;
267}
268
269/*************************************************************
270 * non-blocking send/recv *
271 *************************************************************/
272template<>
273request
274communicator::isend<packed_oarchive>(int dest, int tag,
275 const packed_oarchive& ar) const
276{
92f5a8d4 277 return detail::packed_archive_isend(*this, dest, tag, ar);
7c673cae
FG
278}
279
280template<>
281request
282communicator::isend<packed_skeleton_oarchive>
283 (int dest, int tag, const packed_skeleton_oarchive& ar) const
284{
285 return this->isend(dest, tag, ar.get_skeleton());
286}
287
288template<>
289request communicator::isend<content>(int dest, int tag, const content& c) const
290{
92f5a8d4 291 return request::make_bottom_send(*this, dest, tag, c.get_mpi_datatype());
7c673cae
FG
292}
293
294request communicator::isend(int dest, int tag) const
295{
92f5a8d4 296 return request::make_empty_send(*this, dest, tag);
7c673cae
FG
297}
298
299template<>
300request
301communicator::irecv<packed_skeleton_iarchive>
302 (int source, int tag, packed_skeleton_iarchive& ar) const
303{
304 return this->irecv(source, tag, ar.get_skeleton());
305}
306
307template<>
308request
309communicator::irecv<const content>(int source, int tag,
310 const content& c) const
311{
92f5a8d4 312 return request::make_bottom_recv(*this, source, tag, c.get_mpi_datatype());
7c673cae
FG
313}
314
315request communicator::irecv(int source, int tag) const
316{
92f5a8d4 317 return request::make_empty_recv(*this, source, tag);
7c673cae
FG
318}
319
320bool operator==(const communicator& comm1, const communicator& comm2)
321{
322 int result;
323 BOOST_MPI_CHECK_RESULT(MPI_Comm_compare,
92f5a8d4 324 (MPI_Comm(comm1), MPI_Comm(comm2), &result));
7c673cae
FG
325 return result == MPI_IDENT;
326}
327
328} } // end namespace boost::mpi