broadcast.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 152 行

CPP
152
字号
// Copyright 2005 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)// Message Passing Interface 1.1 -- Section 4.4. Broadcast#include <boost/mpi/collectives/broadcast.hpp>#include <boost/mpi/skeleton_and_content.hpp>#include <boost/mpi/detail/point_to_point.hpp>#include <boost/mpi/environment.hpp>namespace boost { namespace mpi {template<>voidbroadcast<const packed_oarchive>(const communicator& comm,                                 const packed_oarchive& oa,                                 int root){  // Only the root can broadcast the packed_oarchive  assert(comm.rank() == root);  int size = comm.size();  if (size < 2) return;  // Determine maximum tag value  int tag = environment::collectives_tag();  // Broadcast data to all nodes  std::vector<MPI_Request> requests(size * 2);  int num_requests = 0;  for (int dest = 0; dest < size; ++dest) {    if (dest != root) {      // Build up send requests for each child send.      num_requests += detail::packed_archive_isend(comm, dest, tag, oa,                                                   &requests[num_requests], 2);    }  }  // Complete all of the sends  BOOST_MPI_CHECK_RESULT(MPI_Waitall,                         (num_requests, &requests[0], MPI_STATUSES_IGNORE));}template<>voidbroadcast<packed_oarchive>(const communicator& comm, packed_oarchive& oa,                           int root){  broadcast(comm, const_cast<const packed_oarchive&>(oa), root);}template<>voidbroadcast<packed_iarchive>(const communicator& comm, packed_iarchive& ia,                           int root){  int size = comm.size();  if (size < 2) return;  // Determine maximum tag value  int tag = environment::collectives_tag();  // Receive data from the root.  if (comm.rank() != root) {    MPI_Status status;    detail::packed_archive_recv(comm, root, tag, ia, status);  } else {    // Broadcast data to all nodes    std::vector<MPI_Request> requests(size * 2);    int num_requests = 0;    for (int dest = 0; dest < size; ++dest) {      if (dest != root) {        // Build up send requests for each child send.        num_requests += detail::packed_archive_isend(comm, dest, tag, ia,                                                     &requests[num_requests],                                                     2);      }    }    // Complete all of the sends    BOOST_MPI_CHECK_RESULT(MPI_Waitall,                           (num_requests, &requests[0], MPI_STATUSES_IGNORE));  }}template<>voidbroadcast<const packed_skeleton_oarchive>(const communicator& comm,                                          const packed_skeleton_oarchive& oa,                                          int root){  broadcast(comm, oa.get_skeleton(), root);}template<>voidbroadcast<packed_skeleton_oarchive>(const communicator& comm,                                    packed_skeleton_oarchive& oa, int root){  broadcast(comm, oa.get_skeleton(), root);}template<>voidbroadcast<packed_skeleton_iarchive>(const communicator& comm,                                    packed_skeleton_iarchive& ia, int root){  broadcast(comm, ia.get_skeleton(), root);}template<>void broadcast<content>(const communicator& comm, content& c, int root){  broadcast(comm, const_cast<const content&>(c), root);}template<>void broadcast<const content>(const communicator& comm, const content& c,                              int root){#ifdef LAM_MPI  if (comm.size() < 2)    return;  // Some versions of LAM/MPI behave badly when broadcasting using  // MPI_BOTTOM, so we'll instead use manual send/recv operations.  if (comm.rank() == root) {    for (int p = 0; p < comm.size(); ++p) {      if (p != root) {        BOOST_MPI_CHECK_RESULT(MPI_Send,                               (MPI_BOTTOM, 1, c.get_mpi_datatype(),                                p, environment::collectives_tag(), comm));      }    }  } else {    BOOST_MPI_CHECK_RESULT(MPI_Recv,                           (MPI_BOTTOM, 1, c.get_mpi_datatype(),                            root, environment::collectives_tag(),                            comm, MPI_STATUS_IGNORE));  }#else  BOOST_MPI_CHECK_RESULT(MPI_Bcast,                         (MPI_BOTTOM, 1, c.get_mpi_datatype(),                          root, comm));#endif}} } // end namespace boost::mpi

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?