]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright 2005 The Trustees of Indiana University. |
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 | // Authors: Douglas Gregor | |
8 | // Andrew Lumsdaine | |
9 | ||
10 | #ifndef BOOST_GRAPH_PARALLEL_INPLACE_ALL_TO_ALL_HPP | |
11 | #define BOOST_GRAPH_PARALLEL_INPLACE_ALL_TO_ALL_HPP | |
12 | ||
13 | #ifndef BOOST_GRAPH_USE_MPI | |
14 | #error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included" | |
15 | #endif | |
16 | ||
17 | // | |
18 | // Implements the inplace all-to-all communication algorithm. | |
19 | // | |
20 | #include <vector> | |
21 | #include <iterator> | |
22 | ||
23 | namespace boost { namespace parallel { | |
24 | ||
25 | template<typename ProcessGroup, typename T> | |
26 | // where {LinearProcessGroup<ProcessGroup>, MessagingProcessGroup<ProcessGroup>} | |
27 | void | |
28 | inplace_all_to_all(ProcessGroup pg, | |
29 | const std::vector<std::vector<T> >& outgoing, | |
30 | std::vector<std::vector<T> >& incoming) | |
31 | { | |
32 | typedef typename std::vector<T>::size_type size_type; | |
33 | ||
34 | typedef typename ProcessGroup::process_size_type process_size_type; | |
35 | typedef typename ProcessGroup::process_id_type process_id_type; | |
36 | ||
37 | process_size_type p = num_processes(pg); | |
38 | ||
39 | // Make sure there are no straggling messages | |
40 | synchronize(pg); | |
41 | ||
42 | // Send along the count (always) and the data (if count > 0) | |
43 | for (process_id_type dest = 0; dest < p; ++dest) { | |
44 | if (dest != process_id(pg)) { | |
45 | send(pg, dest, 0, outgoing[dest].size()); | |
46 | if (!outgoing[dest].empty()) | |
47 | send(pg, dest, 1, &outgoing[dest].front(), outgoing[dest].size()); | |
48 | } | |
49 | } | |
50 | ||
51 | // Make sure all of the data gets transferred | |
52 | synchronize(pg); | |
53 | ||
54 | // Receive the sizes and data | |
55 | for (process_id_type source = 0; source < p; ++source) { | |
56 | if (source != process_id(pg)) { | |
57 | size_type size; | |
58 | receive(pg, source, 0, size); | |
59 | incoming[source].resize(size); | |
60 | if (size > 0) | |
61 | receive(pg, source, 1, &incoming[source].front(), size); | |
62 | } else if (&incoming != &outgoing) { | |
63 | incoming[source] = outgoing[source]; | |
64 | } | |
65 | } | |
66 | } | |
67 | ||
68 | template<typename ProcessGroup, typename T> | |
69 | // where {LinearProcessGroup<ProcessGroup>, MessagingProcessGroup<ProcessGroup>} | |
70 | void | |
71 | inplace_all_to_all(ProcessGroup pg, std::vector<std::vector<T> >& data) | |
72 | { | |
73 | inplace_all_to_all(pg, data, data); | |
74 | } | |
75 | ||
76 | } } // end namespace boost::parallel | |
77 | ||
78 | #endif // BOOST_GRAPH_PARALLEL_INPLACE_ALL_TO_ALL_HPP |