]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright (C) 2005, 2006 Douglas Gregor <doug.gregor -at- gmail.com>. |
2 | ||
3 | // Use, modification and distribution is subject to the Boost Software | |
4 | // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
5 | // http://www.boost.org/LICENSE_1_0.txt) | |
6 | ||
7 | // Message Passing Interface 1.1 -- Section 4.4. Broadcast | |
8 | #ifndef BOOST_MPI_BROADCAST_HPP | |
9 | #define BOOST_MPI_BROADCAST_HPP | |
10 | ||
11 | #include <boost/mpi/collectives_fwd.hpp> | |
12 | #include <boost/mpi/exception.hpp> | |
13 | #include <boost/mpi/datatype.hpp> | |
14 | #include <boost/mpi/communicator.hpp> | |
15 | ||
16 | namespace boost { namespace mpi { | |
17 | ||
18 | /************************************************************************ | |
19 | * Specializations * | |
20 | ************************************************************************/ | |
21 | ||
22 | /** | |
23 | * INTERNAL ONLY | |
24 | */ | |
25 | template<> | |
26 | BOOST_MPI_DECL void | |
27 | broadcast<const packed_oarchive>(const communicator& comm, | |
28 | const packed_oarchive& oa, | |
29 | int root); | |
30 | ||
31 | /** | |
32 | * INTERNAL ONLY | |
33 | */ | |
34 | template<> | |
35 | BOOST_MPI_DECL void | |
36 | broadcast<packed_oarchive>(const communicator& comm, packed_oarchive& oa, | |
37 | int root); | |
38 | ||
39 | /** | |
40 | * INTERNAL ONLY | |
41 | */ | |
42 | template<> | |
43 | BOOST_MPI_DECL void | |
44 | broadcast<packed_iarchive>(const communicator& comm, packed_iarchive& ia, | |
45 | int root); | |
46 | ||
47 | /** | |
48 | * INTERNAL ONLY | |
49 | */ | |
50 | template<> | |
51 | BOOST_MPI_DECL void | |
52 | broadcast<const packed_skeleton_oarchive>(const communicator& comm, | |
53 | const packed_skeleton_oarchive& oa, | |
54 | int root); | |
55 | ||
56 | /** | |
57 | * INTERNAL ONLY | |
58 | */ | |
59 | template<> | |
60 | void | |
61 | broadcast<packed_skeleton_oarchive>(const communicator& comm, | |
62 | packed_skeleton_oarchive& oa, int root); | |
63 | ||
64 | /** | |
65 | * INTERNAL ONLY | |
66 | */ | |
67 | template<> | |
68 | void | |
69 | broadcast<packed_skeleton_iarchive>(const communicator& comm, | |
70 | packed_skeleton_iarchive& ia, int root); | |
71 | ||
72 | /** | |
73 | * INTERNAL ONLY | |
74 | */ | |
75 | template<> | |
76 | void broadcast<content>(const communicator& comm, content& c, int root); | |
77 | ||
78 | /** | |
79 | * INTERNAL ONLY | |
80 | */ | |
81 | template<> | |
82 | void broadcast<const content>(const communicator& comm, const content& c, | |
83 | int root); | |
84 | ||
85 | /************************************************************************ | |
86 | * broadcast() implementation * | |
87 | ************************************************************************/ | |
88 | namespace detail { | |
89 | // We're sending a type that has an associated MPI datatype, so | |
90 | // we'll use MPI_Bcast to do all of the work. | |
91 | template<typename T> | |
92 | void | |
93 | broadcast_impl(const communicator& comm, T* values, int n, int root, | |
94 | mpl::true_) | |
95 | { | |
96 | BOOST_MPI_CHECK_RESULT(MPI_Bcast, | |
97 | (values, n, | |
98 | boost::mpi::get_mpi_datatype<T>(*values), | |
99 | root, MPI_Comm(comm))); | |
100 | } | |
101 | ||
102 | // We're sending a type that does not have an associated MPI | |
103 | // datatype, so we'll need to serialize it. Unfortunately, this | |
104 | // means that we cannot use MPI_Bcast, so we'll just send from the | |
105 | // root to everyone else. | |
106 | template<typename T> | |
107 | void | |
108 | broadcast_impl(const communicator& comm, T* values, int n, int root, | |
109 | mpl::false_) | |
110 | { | |
111 | if (comm.rank() == root) { | |
112 | packed_oarchive oa(comm); | |
113 | for (int i = 0; i < n; ++i) | |
114 | oa << values[i]; | |
115 | broadcast(comm, oa, root); | |
116 | } else { | |
117 | packed_iarchive ia(comm); | |
118 | broadcast(comm, ia, root); | |
119 | for (int i = 0; i < n; ++i) | |
120 | ia >> values[i]; | |
121 | } | |
122 | } | |
123 | } // end namespace detail | |
124 | ||
125 | template<typename T> | |
126 | void broadcast(const communicator& comm, T& value, int root) | |
127 | { | |
128 | detail::broadcast_impl(comm, &value, 1, root, is_mpi_datatype<T>()); | |
129 | } | |
130 | ||
131 | template<typename T> | |
132 | void broadcast(const communicator& comm, T* values, int n, int root) | |
133 | { | |
134 | detail::broadcast_impl(comm, values, n, root, is_mpi_datatype<T>()); | |
135 | } | |
136 | ||
137 | } } // end namespace boost::mpi | |
138 | ||
139 | // If the user has already included skeleton_and_content.hpp, include | |
140 | // the code to broadcast skeletons and content. | |
141 | #ifdef BOOST_MPI_SKELETON_AND_CONTENT_HPP | |
142 | # include <boost/mpi/detail/broadcast_sc.hpp> | |
143 | #endif | |
144 | ||
145 | #endif // BOOST_MPI_BROADCAST_HPP |