1 // Copyright (C) 2004-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 // Authors: Douglas Gregor
8 // Andrew Lumsdaine
9
10 #include <boost/graph/use_mpi.hpp>
11 #include <boost/config.hpp>
12 #include <boost/throw_exception.hpp>
13 #include <boost/graph/mesh_graph_generator.hpp>
14 #include <boost/test/minimal.hpp>
15 #include <boost/graph/distributed/adjacency_list.hpp>
16 #include <boost/graph/distributed/mpi_process_group.hpp>
17 #include <boost/graph/distributed/graphviz.hpp>
18 #include <boost/graph/iteration_macros.hpp>
19 #include <iostream>
20 #include <sstream>
21 #include <iomanip>
22 #include <string>
23 #include <boost/test/minimal.hpp>
24
25 #ifdef BOOST_NO_EXCEPTIONS
26 void
throw_exception(std::exception const & ex)27 boost::throw_exception(std::exception const& ex)
28 {
29 std::cout << ex.what() << std::endl;
30 abort();
31 }
32 #endif
33
34 using namespace boost;
35 using boost::graph::distributed::mpi_process_group;
36
37 /****************************************************************************
38 * Timing
39 ****************************************************************************/
40 typedef double time_type;
41
get_time()42 inline time_type get_time()
43 {
44 return MPI_Wtime();
45 }
46
print_time(time_type t)47 std::string print_time(time_type t)
48 {
49 std::ostringstream out;
50 out << std::setiosflags(std::ios::fixed) << std::setprecision(2) << t;
51 return out.str();
52 }
53
54 /****************************************************************************
55 * Edge weight generator iterator *
56 ****************************************************************************/
57 template<typename F>
58 class generator_iterator
59 {
60 public:
61 typedef std::input_iterator_tag iterator_category;
62 typedef typename F::result_type value_type;
63 typedef const value_type& reference;
64 typedef const value_type* pointer;
65 typedef void difference_type;
66
generator_iterator(const F & f=F ())67 explicit generator_iterator(const F& f = F()) : f(f) { value = this->f(); }
68
operator *() const69 reference operator*() const { return value; }
operator ->() const70 pointer operator->() const { return &value; }
71
operator ++()72 generator_iterator& operator++()
73 {
74 value = f();
75 return *this;
76 }
77
operator ++(int)78 generator_iterator operator++(int)
79 {
80 generator_iterator temp(*this);
81 ++(*this);
82 return temp;
83 }
84
operator ==(const generator_iterator & other) const85 bool operator==(const generator_iterator& other) const
86 { return f == other.f; }
87
operator !=(const generator_iterator & other) const88 bool operator!=(const generator_iterator& other) const
89 { return !(*this == other); }
90
91 private:
92 F f;
93 value_type value;
94 };
95
96 template<typename F>
make_generator_iterator(const F & f)97 inline generator_iterator<F> make_generator_iterator(const F& f)
98 { return generator_iterator<F>(f); }
99
test_main(int argc,char * argv[])100 int test_main(int argc, char* argv[])
101 {
102 mpi::environment env(argc, argv);
103
104 if (argc < 5) {
105 std::cerr << "Usage: mesh_generator_test <x> <y> <toroidal> <emit dot file>\n";
106 exit(-1);
107 }
108
109 int x(atoi(argv[1])), y(atoi(argv[2]));
110 bool toroidal(argv[3] == std::string("true"));
111 bool emit_dot_file(argv[4] == std::string("true"));
112
113 typedef adjacency_list<listS,
114 distributedS<mpi_process_group, vecS>,
115 undirectedS> Graph;
116
117 Graph g(mesh_iterator<Graph>(x, y, toroidal),
118 mesh_iterator<Graph>(),
119 x*y);
120
121 synchronize(g);
122
123 BGL_FORALL_VERTICES(v, g, Graph)
124 if (toroidal)
125 assert(out_degree(v, g) == 4);
126 else
127 assert(out_degree(v, g) >= 2 && out_degree(v, g) <= 4);
128
129 if ( emit_dot_file )
130 write_graphviz("mesh.dot", g);
131
132 return 0;
133 }
134