123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- #ifndef BOOST_GRAPH_DISTRIBUTED_RMAT_GENERATOR_HPP
- #define BOOST_GRAPH_DISTRIBUTED_RMAT_GENERATOR_HPP
- #ifndef BOOST_GRAPH_USE_MPI
- #error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
- #endif
- #include <boost/assert.hpp>
- #include <boost/graph/parallel/algorithm.hpp>
- #include <boost/graph/parallel/process_group.hpp>
- #include <math.h>
- namespace boost {
-
-
-
-
-
- template<typename ProcessGroup, typename Distribution,
- typename RandomGenerator, typename Graph>
- class scalable_rmat_iterator
- {
- typedef typename graph_traits<Graph>::directed_category directed_category;
- typedef typename graph_traits<Graph>::vertices_size_type vertices_size_type;
- typedef typename graph_traits<Graph>::edges_size_type edges_size_type;
- public:
- typedef std::input_iterator_tag iterator_category;
- typedef std::pair<vertices_size_type, vertices_size_type> value_type;
- typedef const value_type& reference;
- typedef const value_type* pointer;
- typedef void difference_type;
-
- scalable_rmat_iterator()
- : gen(), done(true)
- { }
-
- scalable_rmat_iterator(ProcessGroup pg, Distribution distrib,
- RandomGenerator& gen, vertices_size_type n,
- edges_size_type m, double a, double b, double c,
- double d, bool permute_vertices = true)
- : gen(), done(false)
- {
- BOOST_ASSERT(a + b + c + d == 1);
- int id = process_id(pg);
- this->gen.reset(new uniform_01<RandomGenerator>(gen));
- std::vector<vertices_size_type> vertexPermutation;
- if (permute_vertices)
- generate_permutation_vector(gen, vertexPermutation, n);
- int SCALE = int(floor(log(double(n))/log(2.)));
- boost::uniform_01<RandomGenerator> prob(gen);
-
- std::map<value_type, bool> edge_map;
- edges_size_type generated = 0, local_edges = 0;
- do {
- edges_size_type tossed = 0;
- do {
- vertices_size_type u, v;
- boost::tie(u, v) = generate_edge(this->gen, n, SCALE, a, b, c, d);
- if (permute_vertices) {
- u = vertexPermutation[u];
- v = vertexPermutation[v];
- }
-
-
-
- if (u > v && is_same<directed_category, undirected_tag>::value)
- std::swap(u, v);
- if (distrib(u) == id || distrib(v) == id) {
- if (edge_map.find(std::make_pair(u, v)) == edge_map.end()) {
- edge_map[std::make_pair(u, v)] = true;
- local_edges++;
- } else {
- tossed++;
-
-
-
- if (distrib(u) == id && distrib(v) == id)
- tossed++;
- }
- }
- generated++;
- } while (generated < m);
- tossed = all_reduce(pg, tossed, boost::parallel::sum<vertices_size_type>());
- generated -= (tossed / 2);
- } while (generated < m);
-
-
- values.reserve(local_edges);
- typename std::map<value_type, bool>::reverse_iterator em_end = edge_map.rend();
- for (typename std::map<value_type, bool>::reverse_iterator em_i = edge_map.rbegin();
- em_i != em_end ;
- ++em_i) {
- values.push_back(em_i->first);
- }
- current = values.back();
- values.pop_back();
- }
- reference operator*() const { return current; }
- pointer operator->() const { return ¤t; }
-
- scalable_rmat_iterator& operator++()
- {
- if (!values.empty()) {
- current = values.back();
- values.pop_back();
- } else
- done = true;
- return *this;
- }
- scalable_rmat_iterator operator++(int)
- {
- scalable_rmat_iterator temp(*this);
- ++(*this);
- return temp;
- }
- bool operator==(const scalable_rmat_iterator& other) const
- {
- return values.empty() && other.values.empty() && done && other.done;
- }
- bool operator!=(const scalable_rmat_iterator& other) const
- { return !(*this == other); }
- private:
-
- shared_ptr<uniform_01<RandomGenerator> > gen;
-
- std::vector<value_type> values;
- value_type current;
- bool done;
- };
- }
- #endif
|