mirror of
https://github.com/boostorg/mpi.git
synced 2026-02-26 04:42:23 +00:00
Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41369]
This commit is contained in:
@@ -1,322 +0,0 @@
|
||||
// Copyright (C) 2005, 2006 Douglas Gregor.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#include <boost/mpi/communicator.hpp>
|
||||
#include <boost/mpi/group.hpp>
|
||||
#include <boost/mpi/intercommunicator.hpp>
|
||||
#include <boost/mpi/graph_communicator.hpp>
|
||||
#include <boost/mpi/skeleton_and_content.hpp>
|
||||
#include <boost/mpi/detail/point_to_point.hpp>
|
||||
|
||||
namespace boost { namespace mpi {
|
||||
|
||||
/***************************************************************************
|
||||
* status *
|
||||
***************************************************************************/
|
||||
bool status::cancelled() const
|
||||
{
|
||||
int flag = 0;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Test_cancelled, (&m_status, &flag));
|
||||
return flag != 0;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* communicator *
|
||||
***************************************************************************/
|
||||
|
||||
communicator::communicator()
|
||||
{
|
||||
comm_ptr.reset(new MPI_Comm(MPI_COMM_WORLD));
|
||||
}
|
||||
|
||||
communicator::communicator(const MPI_Comm& comm, comm_create_kind kind)
|
||||
{
|
||||
if (comm == MPI_COMM_NULL)
|
||||
/* MPI_COMM_NULL indicates that the communicator is not usable. */
|
||||
return;
|
||||
|
||||
switch (kind) {
|
||||
case comm_duplicate:
|
||||
{
|
||||
MPI_Comm newcomm;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Comm_dup, (comm, &newcomm));
|
||||
comm_ptr.reset(new MPI_Comm(newcomm), comm_free());
|
||||
MPI_Errhandler_set(newcomm, MPI_ERRORS_RETURN);
|
||||
break;
|
||||
}
|
||||
|
||||
case comm_take_ownership:
|
||||
comm_ptr.reset(new MPI_Comm(comm), comm_free());
|
||||
break;
|
||||
|
||||
case comm_attach:
|
||||
comm_ptr.reset(new MPI_Comm(comm));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
communicator::communicator(const communicator& comm,
|
||||
const boost::mpi::group& subgroup)
|
||||
{
|
||||
MPI_Comm newcomm;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Comm_create,
|
||||
((MPI_Comm)comm, (MPI_Group)subgroup, &newcomm));
|
||||
comm_ptr.reset(new MPI_Comm(newcomm), comm_free());
|
||||
}
|
||||
|
||||
int communicator::size() const
|
||||
{
|
||||
int size_;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Comm_size, (MPI_Comm(*this), &size_));
|
||||
return size_;
|
||||
}
|
||||
|
||||
int communicator::rank() const
|
||||
{
|
||||
int rank_;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Comm_rank, (MPI_Comm(*this), &rank_));
|
||||
return rank_;
|
||||
}
|
||||
|
||||
boost::mpi::group communicator::group() const
|
||||
{
|
||||
MPI_Group gr;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Comm_group, ((MPI_Comm)*this, &gr));
|
||||
return boost::mpi::group(gr, /*adopt=*/true);
|
||||
}
|
||||
|
||||
void communicator::send(int dest, int tag) const
|
||||
{
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Send,
|
||||
(MPI_BOTTOM, 0, MPI_PACKED,
|
||||
dest, tag, MPI_Comm(*this)));
|
||||
}
|
||||
|
||||
status communicator::recv(int source, int tag) const
|
||||
{
|
||||
status stat;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Recv,
|
||||
(MPI_BOTTOM, 0, MPI_PACKED,
|
||||
source, tag, MPI_Comm(*this), &stat.m_status));
|
||||
return stat;
|
||||
}
|
||||
|
||||
optional<status> communicator::iprobe(int source, int tag) const
|
||||
{
|
||||
typedef optional<status> result_type;
|
||||
|
||||
status stat;
|
||||
int flag;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Iprobe,
|
||||
(source, tag, MPI_Comm(*this), &flag,
|
||||
&stat.m_status));
|
||||
if (flag) return stat;
|
||||
else return result_type();
|
||||
}
|
||||
|
||||
status communicator::probe(int source, int tag) const
|
||||
{
|
||||
typedef optional<status> result_type;
|
||||
|
||||
status stat;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Probe,
|
||||
(source, tag, MPI_Comm(*this), &stat.m_status));
|
||||
return stat;
|
||||
}
|
||||
|
||||
void (communicator::barrier)() const
|
||||
{
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Barrier, (MPI_Comm(*this)));
|
||||
}
|
||||
|
||||
|
||||
communicator::operator MPI_Comm() const
|
||||
{
|
||||
if (comm_ptr) return *comm_ptr;
|
||||
else return MPI_COMM_NULL;
|
||||
}
|
||||
|
||||
communicator communicator::split(int color) const
|
||||
{
|
||||
return split(color, rank());
|
||||
}
|
||||
|
||||
communicator communicator::split(int color, int key) const
|
||||
{
|
||||
MPI_Comm newcomm;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Comm_split,
|
||||
(MPI_Comm(*this), color, key, &newcomm));
|
||||
return communicator(newcomm, comm_take_ownership);
|
||||
}
|
||||
|
||||
optional<intercommunicator> communicator::as_intercommunicator() const
|
||||
{
|
||||
int flag;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Comm_test_inter, ((MPI_Comm)*this, &flag));
|
||||
if (flag)
|
||||
return intercommunicator(comm_ptr);
|
||||
else
|
||||
return optional<intercommunicator>();
|
||||
}
|
||||
|
||||
optional<graph_communicator> communicator::as_graph_communicator() const
|
||||
{
|
||||
int status;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Topo_test, ((MPI_Comm)*this, &status));
|
||||
if (status == MPI_GRAPH)
|
||||
return graph_communicator(comm_ptr);
|
||||
else
|
||||
return optional<graph_communicator>();
|
||||
}
|
||||
|
||||
bool communicator::has_cartesian_topology() const
|
||||
{
|
||||
int status;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Topo_test, ((MPI_Comm)*this, &status));
|
||||
|
||||
return status == MPI_CART;
|
||||
}
|
||||
|
||||
void communicator::abort(int errcode) const
|
||||
{
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Abort, (MPI_Comm(*this), errcode));
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* archived send/recv *
|
||||
*************************************************************/
|
||||
template<>
|
||||
void
|
||||
communicator::send<packed_oarchive>(int dest, int tag,
|
||||
const packed_oarchive& ar) const
|
||||
{
|
||||
detail::packed_archive_send(MPI_Comm(*this), dest, tag, ar);
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
communicator::send<packed_skeleton_oarchive>
|
||||
(int dest, int tag, const packed_skeleton_oarchive& ar) const
|
||||
{
|
||||
this->send(dest, tag, ar.get_skeleton());
|
||||
}
|
||||
|
||||
template<>
|
||||
void communicator::send<content>(int dest, int tag, const content& c) const
|
||||
{
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Send,
|
||||
(MPI_BOTTOM, 1, c.get_mpi_datatype(),
|
||||
dest, tag, MPI_Comm(*this)));
|
||||
}
|
||||
|
||||
template<>
|
||||
status
|
||||
communicator::recv<packed_iarchive>(int source, int tag,
|
||||
packed_iarchive& ar) const
|
||||
{
|
||||
status stat;
|
||||
detail::packed_archive_recv(MPI_Comm(*this), source, tag, ar,
|
||||
stat.m_status);
|
||||
return stat;
|
||||
}
|
||||
|
||||
template<>
|
||||
status
|
||||
communicator::recv<packed_skeleton_iarchive>
|
||||
(int source, int tag, packed_skeleton_iarchive& ar) const
|
||||
{
|
||||
return this->recv(source, tag, ar.get_skeleton());
|
||||
}
|
||||
|
||||
template<>
|
||||
status
|
||||
communicator::recv<const content>(int source, int tag, const content& c) const
|
||||
{
|
||||
status stat;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Recv,
|
||||
(MPI_BOTTOM, 1, c.get_mpi_datatype(),
|
||||
source, tag, MPI_Comm(*this), &stat.m_status));
|
||||
return stat;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* non-blocking send/recv *
|
||||
*************************************************************/
|
||||
template<>
|
||||
request
|
||||
communicator::isend<packed_oarchive>(int dest, int tag,
|
||||
const packed_oarchive& ar) const
|
||||
{
|
||||
request req;
|
||||
detail::packed_archive_isend(MPI_Comm(*this), dest, tag, ar,
|
||||
&req.m_requests[0] ,2);
|
||||
return req;
|
||||
}
|
||||
|
||||
template<>
|
||||
request
|
||||
communicator::isend<packed_skeleton_oarchive>
|
||||
(int dest, int tag, const packed_skeleton_oarchive& ar) const
|
||||
{
|
||||
return this->isend(dest, tag, ar.get_skeleton());
|
||||
}
|
||||
|
||||
template<>
|
||||
request communicator::isend<content>(int dest, int tag, const content& c) const
|
||||
{
|
||||
request req;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Isend,
|
||||
(MPI_BOTTOM, 1, c.get_mpi_datatype(),
|
||||
dest, tag, MPI_Comm(*this), &req.m_requests[0]));
|
||||
return req;
|
||||
}
|
||||
|
||||
request communicator::isend(int dest, int tag) const
|
||||
{
|
||||
request req;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Isend,
|
||||
(MPI_BOTTOM, 0, MPI_PACKED,
|
||||
dest, tag, MPI_Comm(*this), &req.m_requests[0]));
|
||||
return req;
|
||||
}
|
||||
|
||||
template<>
|
||||
request
|
||||
communicator::irecv<packed_skeleton_iarchive>
|
||||
(int source, int tag, packed_skeleton_iarchive& ar) const
|
||||
{
|
||||
return this->irecv(source, tag, ar.get_skeleton());
|
||||
}
|
||||
|
||||
template<>
|
||||
request
|
||||
communicator::irecv<const content>(int source, int tag,
|
||||
const content& c) const
|
||||
{
|
||||
request req;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Irecv,
|
||||
(MPI_BOTTOM, 1, c.get_mpi_datatype(),
|
||||
source, tag, MPI_Comm(*this), &req.m_requests[0]));
|
||||
return req;
|
||||
}
|
||||
|
||||
request communicator::irecv(int source, int tag) const
|
||||
{
|
||||
request req;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Irecv,
|
||||
(MPI_BOTTOM, 0, MPI_PACKED,
|
||||
source, tag, MPI_Comm(*this), &req.m_requests[0]));
|
||||
return req;
|
||||
}
|
||||
|
||||
bool operator==(const communicator& comm1, const communicator& comm2)
|
||||
{
|
||||
int result;
|
||||
BOOST_MPI_CHECK_RESULT(MPI_Comm_compare,
|
||||
((MPI_Comm)comm1, (MPI_Comm)comm2, &result));
|
||||
return result == MPI_IDENT;
|
||||
}
|
||||
|
||||
} } // end namespace boost::mpi
|
||||
Reference in New Issue
Block a user