• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2007 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/graph/distributed/adjacency_list.hpp>
11 #include <boost/graph/distributed/mpi_process_group.hpp>
12 #include <boost/graph/iteration_macros.hpp>
13 #include <boost/test/minimal.hpp>
14 #include <string>
15 #include <iostream>
16 
17 #ifdef BOOST_NO_EXCEPTIONS
18 void
throw_exception(std::exception const & ex)19 boost::throw_exception(std::exception const& ex)
20 {
21     std::cout << ex.what() << std::endl;
22     abort();
23 }
24 #endif
25 
26 using namespace boost;
27 using boost::graph::distributed::mpi_process_group;
28 
29 /// City structure to be attached to each vertex
30 struct City {
CityCity31   City() {}
32 
CityCity33   City(const std::string& name, int population = -1)
34     : name(name), population(population) { }
35 
36   template<typename Archiver>
serializeCity37   void serialize(Archiver& ar, const unsigned int /*version*/)
38   {
39     ar & name & population;
40   }
41 
42   std::string name;
43   int population;
44 };
45 
46 namespace boost { namespace graph {
47 
48 /// Use the City name as a key for indexing cities in a graph
49 template<>
50 struct internal_vertex_name<City>
51 {
52   typedef multi_index::member<City, std::string, &City::name> type;
53 };
54 
55 /// Allow the graph to build cities given only their names (filling in
56 /// the defaults for fields).
57 template<>
58 struct internal_vertex_constructor<City>
59 {
60   typedef vertex_from_name<City> type;
61 };
62 
63 } } // end namespace boost::graph
64 
65 /// Our road map, where each of the vertices are cities
66 typedef boost::adjacency_list<vecS, distributedS<mpi_process_group, vecS>,
67                        bidirectionalS, City> RoadMap;
68 typedef graph_traits<RoadMap>::vertex_descriptor Vertex;
69 
test_main(int argc,char ** argv)70 int test_main(int argc, char** argv)
71 {
72   boost::mpi::environment env(argc, argv);
73 
74   RoadMap map;
75 
76   int rank = process_id(mpi_process_group());
77   bool i_am_root = rank == 0;
78 
79   /// Create vertices for Bloomington, Indianapolis, Chicago. Everyone will
80   /// try to do this, but only one of each vertex will be added.
81   Vertex bloomington = add_vertex(City("Bloomington", 69291), map);
82   Vertex chicago = add_vertex(City("Chicago", 9500000), map);
83   Vertex indianapolis = add_vertex(City("Indianapolis", 791926), map);
84 
85   BGL_FORALL_VERTICES(city, map, RoadMap)
86     std::cout << rank << ": " << map[city].name << ", population "
87               << map[city].population << std::endl;
88 
89   BOOST_CHECK(*find_vertex("Bloomington", map) == bloomington);
90   BOOST_CHECK(*find_vertex("Indianapolis", map) == indianapolis);
91   BOOST_CHECK(*find_vertex("Chicago", map) == chicago);
92 
93   if (i_am_root) {
94     add_edge(bloomington, "Indianapolis", map);
95     add_edge("Indianapolis", chicago, map);
96     add_edge("Indianapolis", "Cincinnati", map);
97   }
98 
99   synchronize(map);
100 
101   {
102     property_map<RoadMap, std::string City::*>::type
103       city_name = get(&City::name, map);
104 
105     BGL_FORALL_EDGES(road, map, RoadMap)
106       std::cout << rank << ": " << get(city_name, source(road, map)) << " -> "
107                 << get(city_name, target(road, map)) << std::endl;
108 
109     synchronize(map);
110   }
111 
112   // Make sure the vertex for "Cincinnati" was created implicitly
113   Vertex cincinnati = *find_vertex("Cincinnati", map);
114   if (get(vertex_owner, map, cincinnati)
115         == process_id(map.process_group()))
116     BOOST_CHECK(map[cincinnati].population == -1);
117 
118   synchronize(map);
119 
120   return 0;
121 }
122