]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/mpi/src/communicator.cpp
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)
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>
10 #include <boost/mpi/skeleton_and_content.hpp>
11 #include <boost/mpi/detail/point_to_point.hpp>
13 namespace boost
{ namespace mpi
{
15 /***************************************************************************
17 ***************************************************************************/
18 bool status::cancelled() const
21 BOOST_MPI_CHECK_RESULT(MPI_Test_cancelled
, (&m_status
, &flag
));
25 /***************************************************************************
27 ***************************************************************************/
29 communicator::communicator()
31 comm_ptr
.reset(new MPI_Comm(MPI_COMM_WORLD
));
34 communicator::communicator(const MPI_Comm
& comm
, comm_create_kind kind
)
36 if (comm
== MPI_COMM_NULL
)
37 /* MPI_COMM_NULL indicates that the communicator is not usable. */
44 BOOST_MPI_CHECK_RESULT(MPI_Comm_dup
, (comm
, &newcomm
));
45 comm_ptr
.reset(new MPI_Comm(newcomm
), comm_free());
46 MPI_Comm_set_errhandler(newcomm
, MPI_ERRORS_RETURN
);
50 case comm_take_ownership
:
51 comm_ptr
.reset(new MPI_Comm(comm
), comm_free());
55 comm_ptr
.reset(new MPI_Comm(comm
));
60 communicator::communicator(const communicator
& comm
,
61 const boost::mpi::group
& subgroup
)
64 BOOST_MPI_CHECK_RESULT(MPI_Comm_create
,
65 ((MPI_Comm
)comm
, (MPI_Group
)subgroup
, &newcomm
));
66 if(newcomm
!= MPI_COMM_NULL
)
67 comm_ptr
.reset(new MPI_Comm(newcomm
), comm_free());
70 int communicator::size() const
73 BOOST_MPI_CHECK_RESULT(MPI_Comm_size
, (MPI_Comm(*this), &size_
));
77 int communicator::rank() const
80 BOOST_MPI_CHECK_RESULT(MPI_Comm_rank
, (MPI_Comm(*this), &rank_
));
84 boost::mpi::group
communicator::group() const
87 BOOST_MPI_CHECK_RESULT(MPI_Comm_group
, ((MPI_Comm
)*this, &gr
));
88 return boost::mpi::group(gr
, /*adopt=*/true);
91 void communicator::send(int dest
, int tag
) const
93 BOOST_MPI_CHECK_RESULT(MPI_Send
,
94 (MPI_BOTTOM
, 0, MPI_PACKED
,
95 dest
, tag
, MPI_Comm(*this)));
98 status
communicator::recv(int source
, int tag
) const
101 BOOST_MPI_CHECK_RESULT(MPI_Recv
,
102 (MPI_BOTTOM
, 0, MPI_PACKED
,
103 source
, tag
, MPI_Comm(*this), &stat
.m_status
));
107 optional
<status
> communicator::iprobe(int source
, int tag
) const
109 typedef optional
<status
> result_type
;
113 BOOST_MPI_CHECK_RESULT(MPI_Iprobe
,
114 (source
, tag
, MPI_Comm(*this), &flag
,
116 if (flag
) return stat
;
117 else return result_type();
120 status
communicator::probe(int source
, int tag
) const
123 BOOST_MPI_CHECK_RESULT(MPI_Probe
,
124 (source
, tag
, MPI_Comm(*this), &stat
.m_status
));
128 void (communicator::barrier
)() const
130 BOOST_MPI_CHECK_RESULT(MPI_Barrier
, (MPI_Comm(*this)));
134 communicator::operator MPI_Comm() const
136 if (comm_ptr
) return *comm_ptr
;
137 else return MPI_COMM_NULL
;
140 communicator
communicator::split(int color
) const
142 return split(color
, rank());
145 communicator
communicator::split(int color
, int key
) const
148 BOOST_MPI_CHECK_RESULT(MPI_Comm_split
,
149 (MPI_Comm(*this), color
, key
, &newcomm
));
150 return communicator(newcomm
, comm_take_ownership
);
153 optional
<intercommunicator
> communicator::as_intercommunicator() const
156 BOOST_MPI_CHECK_RESULT(MPI_Comm_test_inter
, ((MPI_Comm
)*this, &flag
));
158 return intercommunicator(comm_ptr
);
160 return optional
<intercommunicator
>();
163 optional
<graph_communicator
> communicator::as_graph_communicator() const
165 optional
<graph_communicator
> graph
;
166 // topology test not allowed on MPI_NULL_COMM
169 BOOST_MPI_CHECK_RESULT(MPI_Topo_test
, ((MPI_Comm
)*this, &status
));
170 if (status
== MPI_GRAPH
)
171 graph
= graph_communicator(comm_ptr
);
176 bool communicator::has_cartesian_topology() const
178 // topology test not allowed on MPI_NULL_COM
183 BOOST_MPI_CHECK_RESULT(MPI_Topo_test
, ((MPI_Comm
)*this, &status
));
184 return status
== MPI_CART
;
188 void communicator::abort(int errcode
) const
190 BOOST_MPI_CHECK_RESULT(MPI_Abort
, (MPI_Comm(*this), errcode
));
193 /*************************************************************
194 * archived send/recv *
195 *************************************************************/
198 communicator::send
<packed_oarchive
>(int dest
, int tag
,
199 const packed_oarchive
& ar
) const
201 detail::packed_archive_send(MPI_Comm(*this), dest
, tag
, ar
);
206 communicator::send
<packed_skeleton_oarchive
>
207 (int dest
, int tag
, const packed_skeleton_oarchive
& ar
) const
209 this->send(dest
, tag
, ar
.get_skeleton());
213 void communicator::send
<content
>(int dest
, int tag
, const content
& c
) const
215 BOOST_MPI_CHECK_RESULT(MPI_Send
,
216 (MPI_BOTTOM
, 1, c
.get_mpi_datatype(),
217 dest
, tag
, MPI_Comm(*this)));
222 communicator::recv
<packed_iarchive
>(int source
, int tag
,
223 packed_iarchive
& ar
) const
226 detail::packed_archive_recv(MPI_Comm(*this), source
, tag
, ar
,
233 communicator::recv
<packed_skeleton_iarchive
>
234 (int source
, int tag
, packed_skeleton_iarchive
& ar
) const
236 return this->recv(source
, tag
, ar
.get_skeleton());
241 communicator::recv
<const content
>(int source
, int tag
, const content
& c
) const
244 BOOST_MPI_CHECK_RESULT(MPI_Recv
,
245 (MPI_BOTTOM
, 1, c
.get_mpi_datatype(),
246 source
, tag
, MPI_Comm(*this), &stat
.m_status
));
250 /*************************************************************
251 * non-blocking send/recv *
252 *************************************************************/
255 communicator::isend
<packed_oarchive
>(int dest
, int tag
,
256 const packed_oarchive
& ar
) const
259 detail::packed_archive_isend(MPI_Comm(*this), dest
, tag
, ar
,
260 &req
.m_requests
[0] ,2);
266 communicator::isend
<packed_skeleton_oarchive
>
267 (int dest
, int tag
, const packed_skeleton_oarchive
& ar
) const
269 return this->isend(dest
, tag
, ar
.get_skeleton());
273 request
communicator::isend
<content
>(int dest
, int tag
, const content
& c
) const
276 BOOST_MPI_CHECK_RESULT(MPI_Isend
,
277 (MPI_BOTTOM
, 1, c
.get_mpi_datatype(),
278 dest
, tag
, MPI_Comm(*this), &req
.m_requests
[0]));
282 request
communicator::isend(int dest
, int tag
) const
285 BOOST_MPI_CHECK_RESULT(MPI_Isend
,
286 (MPI_BOTTOM
, 0, MPI_PACKED
,
287 dest
, tag
, MPI_Comm(*this), &req
.m_requests
[0]));
293 communicator::irecv
<packed_skeleton_iarchive
>
294 (int source
, int tag
, packed_skeleton_iarchive
& ar
) const
296 return this->irecv(source
, tag
, ar
.get_skeleton());
301 communicator::irecv
<const content
>(int source
, int tag
,
302 const content
& c
) const
305 BOOST_MPI_CHECK_RESULT(MPI_Irecv
,
306 (MPI_BOTTOM
, 1, c
.get_mpi_datatype(),
307 source
, tag
, MPI_Comm(*this), &req
.m_requests
[0]));
311 request
communicator::irecv(int source
, int tag
) const
314 BOOST_MPI_CHECK_RESULT(MPI_Irecv
,
315 (MPI_BOTTOM
, 0, MPI_PACKED
,
316 source
, tag
, MPI_Comm(*this), &req
.m_requests
[0]));
320 bool operator==(const communicator
& comm1
, const communicator
& comm2
)
323 BOOST_MPI_CHECK_RESULT(MPI_Comm_compare
,
324 ((MPI_Comm
)comm1
, (MPI_Comm
)comm2
, &result
));
325 return result
== MPI_IDENT
;
328 } } // end namespace boost::mpi