• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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