communicator.cpp
来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 323 行
CPP
323 行
// 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<>voidcommunicator::send<packed_oarchive>(int dest, int tag, const packed_oarchive& ar) const{ detail::packed_archive_send(MPI_Comm(*this), dest, tag, ar);}template<>voidcommunicator::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<>statuscommunicator::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<>statuscommunicator::recv<packed_skeleton_iarchive> (int source, int tag, packed_skeleton_iarchive& ar) const{ return this->recv(source, tag, ar.get_skeleton());}template<>statuscommunicator::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<>requestcommunicator::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<>requestcommunicator::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<>requestcommunicator::irecv<packed_skeleton_iarchive> (int source, int tag, packed_skeleton_iarchive& ar) const{ return this->irecv(source, tag, ar.get_skeleton());}template<>requestcommunicator::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
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?