2
0
mirror of https://github.com/boostorg/mpi.git synced 2026-02-26 04:42:23 +00:00

Move MPI library to the top level

[SVN r36741]
This commit is contained in:
Douglas Gregor
2007-01-17 02:48:51 +00:00
parent 5cbf8330a2
commit 28d9c668cb
104 changed files with 3393 additions and 744 deletions

267
src/communicator.cpp Normal file
View File

@@ -0,0 +1,267 @@
// 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/skeleton_and_content.hpp>
#include <boost/mpi/detail/point_to_point.hpp>
namespace boost { namespace mpi {
/***************************************************************************
* status *
***************************************************************************/
bool status::cancelled()
{
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;
}
}
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_;
}
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);
}
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;
}
} } // end namespace boost::mpi