Ticket #8250: pbgl_in_edges.cpp

File pbgl_in_edges.cpp, 6.4 KB (added by Borja Miñano <bminyano@…>, 10 years ago)

Parallel bgl in_egdes code

Line 
1// Copyright (C) 2007-2008 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#include <boost/graph/use_mpi.hpp>
8#include <boost/config.hpp>
9#include <boost/throw_exception.hpp>
10#include <boost/mpl/print.hpp>
11#include <boost/graph/distributed/adjacency_list.hpp>
12#include <boost/graph/distributed/mpi_process_group.hpp>
13#include <boost/graph/iteration_macros.hpp>
14#include <boost/test/minimal.hpp>
15#include <boost/graph/graphviz.hpp>
16#include <boost/graph/graphml.hpp>
17#include <boost/graph/erdos_renyi_generator.hpp>
18#include <boost/graph/random.hpp>
19#include <boost/random/uniform_real.hpp>
20#include <boost/random/mersenne_twister.hpp>
21#include <boost/property_map/property_map.hpp>
22#include <string>
23#include <iostream>
24
25#include <boost/graph/iteration_macros.hpp>
26#include <boost/graph/rmat_graph_generator.hpp>
27#include <boost/random/linear_congruential.hpp>
28
29#include <boost/graph/metis.hpp>
30
31#ifdef BOOST_NO_EXCEPTIONS
32void
33boost::throw_exception(std::exception const& ex)
34{
35 std::cout << ex.what() << std::endl;
36 abort();
37}
38#endif
39
40using namespace boost;
41using namespace std;
42using boost::graph::distributed::mpi_process_group;
43
44/// VertexProperties structure to be attached to each vertex
45struct VertexProperties {
46 VertexProperties() {
47 cash = 100;
48 goods = 10;
49 price = 0.1;
50 }
51
52/* VertexProperties(double cash = 100, double goods = 10, double price = 0.1)
53 : cash(cash), goods(goods), price(price) { }*/
54
55 template<typename Archiver>
56 void serialize(Archiver& ar, const unsigned int /*version*/)
57 {
58 ar & cash & goods & price;
59 }
60
61 double cash;
62 double goods;
63 double price;
64
65};
66
67struct EdgeProperties {
68
69 EdgeProperties() {
70 cash = 0;
71 goods = 0;
72 index = 0;
73 }
74
75 EdgeProperties(size_t i, double c, double g) : index(i), cash(c), goods(g) { }
76
77public:
78 std::size_t index;
79 double cash;
80 double goods;
81
82 friend class serialization::access;
83 template<class Archive>
84 void serialize(Archive & ar, const unsigned int version)
85 {
86 ar & index & cash & goods;
87 }
88
89};
90
91
92 double lambda = 0.2;
93 double mu = 0.3;
94 double tau = 10;
95 double eps = 0.01;
96
97typedef boost::adjacency_list<vecS,
98 distributedS<mpi_process_group, vecS>,
99 bidirectionalS, VertexProperties, EdgeProperties> Graph;
100
101
102typedef graph_traits<Graph>::vertex_descriptor Vertex;
103typedef graph_traits<Graph>::edge_descriptor Edge;
104
105struct remote_key_e
106{
107 remote_key_e(int p = -1, Edge l = Edge()) : processor(p){local_key = &l; }
108
109 int processor;
110 Edge* local_key;
111
112 template<typename Archiver>
113 void serialize(Archiver& ar, const unsigned int /*version*/)
114 {
115 ar & processor & local_key;
116 }
117};
118
119namespace boost {
120
121template<>
122struct hash<remote_key_e>
123{
124 std::size_t operator()(const remote_key_e& key) const
125 {
126 std::size_t hash = hash_value(key.processor);
127
128 hash_combine(hash, key.local_key);
129
130 return hash;
131 }
132};
133}
134
135inline bool operator==(const remote_key_e& x, const remote_key_e& y)
136{
137return x.processor == y.processor && (*(x.local_key)) == (*(y.local_key));
138}
139
140struct remote_key_to_global_e
141{
142 typedef readable_property_map_tag category;
143 typedef remote_key_e key_type;
144 typedef std::pair<int, Edge> value_type;
145 typedef value_type reference;
146};
147
148inline std::pair<int, Edge>
149get(remote_key_to_global_e, const remote_key_e& key)
150{
151 return std::make_pair(key.processor, *(key.local_key));
152}
153
154template<typename GMap, typename PMap, typename Graph>
155class Remover
156{
157public:
158 Remover(const double min, const GMap& egoods, const PMap& price, const Graph& graph)
159 : m_min(min), m_egoods(egoods), m_price(price), m_graph(graph) {}
160
161 template<typename ED>
162 bool operator()(ED w) const {
163 return m_price[target(w, m_graph)] > tau * m_min || m_egoods[w] < eps;
164 }
165
166private:
167 const Graph& m_graph;
168 const GMap& m_egoods;
169 const PMap& m_price;
170 const double m_min;
171};
172
173template<typename Graph>
174class Remover_1
175{
176public:
177 Remover_1(const Graph& graph)
178 : m_graph(graph) {}
179
180 template<typename ED>
181 bool operator()(ED w) const {
182 return target(w, m_graph) == source(w, m_graph);
183 }
184
185private:
186 const Graph& m_graph;
187};
188
189template<typename T>
190struct rank_accumulate_reducer {
191 static const bool non_default_resolver = false;
192
193 // The default rank of an unknown node
194 template<typename K>
195 T operator()(const K&) const {return T(0); }
196
197 template<typename K>
198 T operator()(const K&, const T& x, const T& y) const { return x; }
199};
200
201int test_main(int argc, char** argv)
202{
203 boost::mpi::environment env(argc, argv);
204
205
206
207//Random scale-free
208typedef boost::unique_rmat_iterator<boost::minstd_rand, Graph> RMATGen;
209boost::minstd_rand gen;
210 Graph g(RMATGen(gen, 100, 1000, 0.57, 0.19, 0.19, 0.05),
211 RMATGen(), 100);
212
213 mpi_process_group pg = g.process_group();
214
215
216 synchronize(g);
217
218
219 property_map<Graph, vertex_index_t>::type
220 index_map = get(vertex_index, g);
221
222
223 typedef property_map<Graph, double EdgeProperties::*>::type egoods_map;
224 typedef property_map<Graph, double EdgeProperties::*>::type ecash_map;
225 typedef property_map<Graph, double VertexProperties::*>::type price_map;
226
227 //Vertex iterator distributed property maps
228 typedef property_map<Graph, vertex_index_t>::const_type VertexIndexMap;
229 typedef iterator_property_map<std::vector<size_t>::iterator, VertexIndexMap>
230 d_index_map;
231
232 std::vector<size_t> index_S(num_vertices(g), std::numeric_limits<size_t>::max());
233 d_index_map d_index(index_S.begin(), get(vertex_index, g));
234 d_index.set_reduce(rank_accumulate_reducer<size_t>());
235
236
237
238synchronize(g);
239
240
241 //Delete self-edges
242 Remover_1<Graph> r(g);
243 remove_edge_if(r, g);
244
245 synchronize(g);
246
247 boost::graph_traits<Graph>::vertex_iterator vit, vit_end;
248 boost::graph_traits<Graph>::in_edge_iterator it, it_end;
249 boost::graph_traits<Graph>::out_edge_iterator oit, oit_end;
250
251 for(boost::tie(vit,vit_end) = vertices(g); vit != vit_end; ++vit) {
252 cout << index_map[*vit] << " --> ";
253 for (boost::tie(oit,oit_end) = out_edges(*vit, g); oit != oit_end; ++oit)
254 cout << index_map[target(*oit, g)] << " ";
255 cout << endl;
256 }
257
258 for(boost::tie(vit,vit_end) = vertices(g); vit != vit_end; ++vit) {
259 cout << index_map[*vit] << " <-- ";
260 for (boost::tie(it,it_end) = in_edges(*vit, g); it != it_end; ++it)
261 cout << index_map[source(*it, g)] << " ";
262 cout << endl;
263 }
264
265
266 return 0;
267}