annotate DEPENDENCIES/generic/include/boost/graph/distributed/rmat_graph_generator.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // Copyright 2004, 2005 The Trustees of Indiana University.
Chris@16 2
Chris@16 3 // Use, modification and distribution is subject to the Boost Software
Chris@16 4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 5 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6
Chris@16 7 // Authors: Nick Edmonds
Chris@16 8 // Andrew Lumsdaine
Chris@16 9 #ifndef BOOST_GRAPH_DISTRIBUTED_RMAT_GENERATOR_HPP
Chris@16 10 #define BOOST_GRAPH_DISTRIBUTED_RMAT_GENERATOR_HPP
Chris@16 11
Chris@16 12 #ifndef BOOST_GRAPH_USE_MPI
Chris@16 13 #error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
Chris@16 14 #endif
Chris@16 15
Chris@16 16 #include <boost/assert.hpp>
Chris@16 17 #include <boost/graph/parallel/algorithm.hpp>
Chris@16 18 #include <boost/graph/parallel/process_group.hpp>
Chris@16 19 #include <math.h>
Chris@16 20
Chris@16 21 namespace boost {
Chris@16 22
Chris@16 23 // Memory-scalable (amount of memory required will scale down
Chris@16 24 // linearly as the number of processes increases) generator, which
Chris@16 25 // requires an MPI process group. Run-time is slightly worse than
Chris@16 26 // the unique rmat generator. Edge list generated is sorted and
Chris@16 27 // unique.
Chris@16 28 template<typename ProcessGroup, typename Distribution,
Chris@16 29 typename RandomGenerator, typename Graph>
Chris@16 30 class scalable_rmat_iterator
Chris@16 31 {
Chris@16 32 typedef typename graph_traits<Graph>::directed_category directed_category;
Chris@16 33 typedef typename graph_traits<Graph>::vertices_size_type vertices_size_type;
Chris@16 34 typedef typename graph_traits<Graph>::edges_size_type edges_size_type;
Chris@16 35
Chris@16 36 public:
Chris@16 37 typedef std::input_iterator_tag iterator_category;
Chris@16 38 typedef std::pair<vertices_size_type, vertices_size_type> value_type;
Chris@16 39 typedef const value_type& reference;
Chris@16 40 typedef const value_type* pointer;
Chris@16 41 typedef void difference_type;
Chris@16 42
Chris@16 43 // No argument constructor, set to terminating condition
Chris@16 44 scalable_rmat_iterator()
Chris@16 45 : gen(), done(true)
Chris@16 46 { }
Chris@16 47
Chris@16 48 // Initialize for edge generation
Chris@16 49 scalable_rmat_iterator(ProcessGroup pg, Distribution distrib,
Chris@16 50 RandomGenerator& gen, vertices_size_type n,
Chris@16 51 edges_size_type m, double a, double b, double c,
Chris@16 52 double d, bool permute_vertices = true)
Chris@16 53 : gen(), done(false)
Chris@16 54 {
Chris@16 55 BOOST_ASSERT(a + b + c + d == 1);
Chris@16 56 int id = process_id(pg);
Chris@16 57
Chris@16 58 this->gen.reset(new uniform_01<RandomGenerator>(gen));
Chris@16 59
Chris@16 60 std::vector<vertices_size_type> vertexPermutation;
Chris@16 61 if (permute_vertices)
Chris@16 62 generate_permutation_vector(gen, vertexPermutation, n);
Chris@16 63
Chris@16 64 int SCALE = int(floor(log(double(n))/log(2.)));
Chris@16 65 boost::uniform_01<RandomGenerator> prob(gen);
Chris@16 66
Chris@16 67 std::map<value_type, bool> edge_map;
Chris@16 68
Chris@16 69 edges_size_type generated = 0, local_edges = 0;
Chris@16 70 do {
Chris@16 71 edges_size_type tossed = 0;
Chris@16 72 do {
Chris@16 73 vertices_size_type u, v;
Chris@16 74 boost::tie(u, v) = generate_edge(this->gen, n, SCALE, a, b, c, d);
Chris@16 75
Chris@16 76 if (permute_vertices) {
Chris@16 77 u = vertexPermutation[u];
Chris@16 78 v = vertexPermutation[v];
Chris@16 79 }
Chris@16 80
Chris@16 81 // Lowest vertex number always comes first (this
Chris@16 82 // means we don't have to worry about i->j and j->i
Chris@16 83 // being in the edge list)
Chris@16 84 if (u > v && is_same<directed_category, undirected_tag>::value)
Chris@16 85 std::swap(u, v);
Chris@16 86
Chris@16 87 if (distrib(u) == id || distrib(v) == id) {
Chris@16 88 if (edge_map.find(std::make_pair(u, v)) == edge_map.end()) {
Chris@16 89 edge_map[std::make_pair(u, v)] = true;
Chris@16 90 local_edges++;
Chris@16 91 } else {
Chris@16 92 tossed++;
Chris@16 93
Chris@16 94 // special case - if both u and v are on same
Chris@16 95 // proc, ++ twice, since we divide by two (to
Chris@16 96 // cover the two process case)
Chris@16 97 if (distrib(u) == id && distrib(v) == id)
Chris@16 98 tossed++;
Chris@16 99 }
Chris@16 100 }
Chris@16 101 generated++;
Chris@16 102
Chris@16 103 } while (generated < m);
Chris@16 104 tossed = all_reduce(pg, tossed, boost::parallel::sum<vertices_size_type>());
Chris@16 105 generated -= (tossed / 2);
Chris@16 106 } while (generated < m);
Chris@16 107 // NGE - Asking for more than n^2 edges will result in an infinite loop here
Chris@16 108 // Asking for a value too close to n^2 edges may as well
Chris@16 109
Chris@16 110 values.reserve(local_edges);
Chris@16 111 typename std::map<value_type, bool>::reverse_iterator em_end = edge_map.rend();
Chris@16 112 for (typename std::map<value_type, bool>::reverse_iterator em_i = edge_map.rbegin();
Chris@16 113 em_i != em_end ;
Chris@16 114 ++em_i) {
Chris@16 115 values.push_back(em_i->first);
Chris@16 116 }
Chris@16 117
Chris@16 118 current = values.back();
Chris@16 119 values.pop_back();
Chris@16 120 }
Chris@16 121
Chris@16 122 reference operator*() const { return current; }
Chris@16 123 pointer operator->() const { return &current; }
Chris@16 124
Chris@16 125 scalable_rmat_iterator& operator++()
Chris@16 126 {
Chris@16 127 if (!values.empty()) {
Chris@16 128 current = values.back();
Chris@16 129 values.pop_back();
Chris@16 130 } else
Chris@16 131 done = true;
Chris@16 132
Chris@16 133 return *this;
Chris@16 134 }
Chris@16 135
Chris@16 136 scalable_rmat_iterator operator++(int)
Chris@16 137 {
Chris@16 138 scalable_rmat_iterator temp(*this);
Chris@16 139 ++(*this);
Chris@16 140 return temp;
Chris@16 141 }
Chris@16 142
Chris@16 143 bool operator==(const scalable_rmat_iterator& other) const
Chris@16 144 {
Chris@16 145 return values.empty() && other.values.empty() && done && other.done;
Chris@16 146 }
Chris@16 147
Chris@16 148 bool operator!=(const scalable_rmat_iterator& other) const
Chris@16 149 { return !(*this == other); }
Chris@16 150
Chris@16 151 private:
Chris@16 152
Chris@16 153 // Parameters
Chris@16 154 shared_ptr<uniform_01<RandomGenerator> > gen;
Chris@16 155
Chris@16 156 // Internal data structures
Chris@16 157 std::vector<value_type> values;
Chris@16 158 value_type current;
Chris@16 159 bool done;
Chris@16 160 };
Chris@16 161
Chris@16 162 } // end namespace boost
Chris@16 163
Chris@16 164 #endif // BOOST_GRAPH_DISTRIBUTED_RMAT_GENERATOR_HPP