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
inplace_all_to_all(ProcessGroup pg,const std::vector<std::vector<T>> & outgoing,std::vector<std::vector<T>> & incoming)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
inplace_all_to_all(ProcessGroup pg,std::vector<std::vector<T>> & data)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
79