Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:40:56

0001 // Copyright (C) 2005, 2006 Douglas Gregor <doug.gregor -at- gmail.com>.
0002 
0003 // Use, modification and distribution is subject to the Boost Software
0004 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 // Message Passing Interface 1.1 -- Section 4.4. Broadcast
0008 #ifndef BOOST_MPI_BROADCAST_HPP
0009 #define BOOST_MPI_BROADCAST_HPP
0010 
0011 #include <boost/mpi/collectives_fwd.hpp>
0012 #include <boost/mpi/exception.hpp>
0013 #include <boost/mpi/datatype.hpp>
0014 #include <boost/mpi/communicator.hpp>
0015 
0016 namespace boost { namespace mpi {
0017 
0018 /************************************************************************
0019  * Specializations                                                      *
0020  ************************************************************************/
0021 
0022 /**
0023  * INTERNAL ONLY
0024  */
0025 template<>
0026 BOOST_MPI_DECL void
0027 broadcast<const packed_oarchive>(const communicator& comm,
0028                                  const packed_oarchive& oa,
0029                                  int root);
0030 
0031 /**
0032  * INTERNAL ONLY
0033  */
0034 template<>
0035 BOOST_MPI_DECL void
0036 broadcast<packed_oarchive>(const communicator& comm, packed_oarchive& oa,
0037                            int root);
0038 
0039 /**
0040  * INTERNAL ONLY
0041  */
0042 template<>
0043 BOOST_MPI_DECL void
0044 broadcast<packed_iarchive>(const communicator& comm, packed_iarchive& ia,
0045                            int root);
0046 
0047 /**
0048  * INTERNAL ONLY
0049  */
0050 template<>
0051 BOOST_MPI_DECL void
0052 broadcast<const packed_skeleton_oarchive>(const communicator& comm,
0053                                           const packed_skeleton_oarchive& oa,
0054                                           int root);
0055 
0056 /**
0057  * INTERNAL ONLY
0058  */
0059 template<>
0060 void
0061 broadcast<packed_skeleton_oarchive>(const communicator& comm,
0062                                     packed_skeleton_oarchive& oa, int root);
0063 
0064 /**
0065  * INTERNAL ONLY
0066  */
0067 template<>
0068 void
0069 broadcast<packed_skeleton_iarchive>(const communicator& comm,
0070                                     packed_skeleton_iarchive& ia, int root);
0071 
0072 /**
0073  * INTERNAL ONLY
0074  */
0075 template<>
0076 void broadcast<content>(const communicator& comm, content& c, int root);
0077 
0078 /**
0079  * INTERNAL ONLY
0080  */
0081 template<>
0082 void broadcast<const content>(const communicator& comm, const content& c,
0083                               int root);
0084 
0085 /************************************************************************
0086  * broadcast() implementation                                           *
0087  ************************************************************************/
0088 namespace detail {
0089   // We're sending a type that has an associated MPI datatype, so
0090   // we'll use MPI_Bcast to do all of the work.
0091   template<typename T>
0092   void 
0093   broadcast_impl(const communicator& comm, T* values, int n, int root, 
0094                  mpl::true_)
0095   {
0096     BOOST_MPI_CHECK_RESULT(MPI_Bcast,
0097                            (values, n,
0098                             boost::mpi::get_mpi_datatype<T>(*values),
0099                             root, MPI_Comm(comm)));
0100   }
0101 
0102   // We're sending a type that does not have an associated MPI
0103   // datatype, so we'll need to serialize it.
0104   template<typename T>
0105   void
0106   broadcast_impl(const communicator& comm, T* values, int n, int root, 
0107                  mpl::false_ non_mpi_datatype)
0108   {
0109     // Implementation proposed by Lorenz Hübschle-Schneider
0110     if (comm.rank() == root) {
0111       packed_oarchive oa(comm);
0112       for (int i = 0; i < n; ++i) {
0113         oa << values[i];
0114       }
0115       std::size_t asize = oa.size();
0116       broadcast(comm, asize, root);
0117       void const* aptr = oa.address();
0118       BOOST_MPI_CHECK_RESULT(MPI_Bcast,
0119                              (const_cast<void*>(aptr), asize,
0120                               MPI_BYTE,
0121                               root, MPI_Comm(comm)));
0122     } else {
0123       packed_iarchive ia(comm);
0124       std::size_t asize;
0125       broadcast(comm, asize, root);
0126       ia.resize(asize);
0127       void* aptr = ia.address();
0128       BOOST_MPI_CHECK_RESULT(MPI_Bcast,
0129                              (aptr, asize,
0130                               MPI_BYTE,
0131                               root, MPI_Comm(comm)));
0132       for (int i = 0; i < n; ++i)
0133         ia >> values[i];
0134     }
0135   }
0136 } // end namespace detail
0137 
0138 template<typename T>
0139 void broadcast(const communicator& comm, T& value, int root)
0140 {
0141   detail::broadcast_impl(comm, &value, 1, root, is_mpi_datatype<T>());
0142 }
0143 
0144 template<typename T>
0145 void broadcast(const communicator& comm, T* values, int n, int root)
0146 {
0147   detail::broadcast_impl(comm, values, n, root, is_mpi_datatype<T>());
0148 }
0149 
0150 } } // end namespace boost::mpi
0151 
0152 // If the user has already included skeleton_and_content.hpp, include
0153 // the code to broadcast skeletons and content.
0154 #ifdef BOOST_MPI_SKELETON_AND_CONTENT_HPP
0155 #  include <boost/mpi/detail/broadcast_sc.hpp>
0156 #endif
0157 
0158 #endif // BOOST_MPI_BROADCAST_HPP