| // Copyright 2004 The Trustees of Indiana University. |
| |
| // Use, modification and distribution is subject to the Boost Software |
| // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
| // http://www.boost.org/LICENSE_1_0.txt) |
| |
| // Authors: Douglas Gregor |
| // Andrew Lumsdaine |
| |
| #include <boost/graph/use_mpi.hpp> |
| #include <boost/config.hpp> |
| #include <boost/throw_exception.hpp> |
| #include <boost/graph/distributed/adjacency_list.hpp> |
| #include <boost/graph/distributed/mpi_process_group.hpp> |
| #include <boost/graph/parallel/distribution.hpp> |
| #include <iostream> |
| #include <cassert> |
| #include <boost/test/minimal.hpp> |
| |
| #ifdef BOOST_NO_EXCEPTIONS |
| void |
| boost::throw_exception(std::exception const& ex) |
| { |
| std::cout << ex.what() << std::endl; |
| abort(); |
| } |
| #endif |
| |
| using namespace boost; |
| using boost::graph::distributed::mpi_process_group; |
| |
| void test_bidirectional_graph() |
| { |
| typedef adjacency_list<listS, distributedS<mpi_process_group, vecS>, |
| bidirectionalS> Graph; |
| typedef graph_traits<Graph>::vertex_descriptor Vertex; |
| typedef graph_traits<Graph>::edge_descriptor Edge; |
| |
| typedef std::pair<std::size_t, std::size_t> E; |
| E edges[3] = { E(0,3), E(1,4), E(2,5) }; |
| |
| Graph g(&edges[0], &edges[0] + 3, 6); |
| assert(num_processes(g.process_group()) == 2); |
| |
| if (process_id(g.process_group()) == 0) |
| std::cerr << "Testing bidirectional graph edge removal..."; |
| synchronize(g.process_group()); |
| |
| graph_traits<Graph>::vertex_iterator vi = vertices(g).first; |
| Vertex u = *vi++; |
| Vertex v = *vi++; |
| Vertex w = *vi++; |
| BOOST_CHECK(vi == vertices(g).second); |
| |
| BOOST_CHECK((process_id(g.process_group()) == 0 && out_degree(u, g) == 1) |
| || (process_id(g.process_group()) == 1 && in_degree(u, g) == 1)); |
| |
| BOOST_CHECK((process_id(g.process_group()) == 0 && out_degree(v, g) == 1) |
| || (process_id(g.process_group()) == 1 && in_degree(v, g) == 1)); |
| |
| BOOST_CHECK((process_id(g.process_group()) == 0 && out_degree(w, g) == 1) |
| || (process_id(g.process_group()) == 1 && in_degree(w, g) == 1)); |
| |
| // Remove edges |
| if (process_id(g.process_group()) == 0) { |
| remove_edge(*out_edges(u, g).first, g); |
| remove_edge(*out_edges(w, g).first, g); |
| } else { |
| remove_edge(*in_edges(v, g).first, g); |
| remove_edge(*in_edges(w, g).first, g); |
| } |
| |
| synchronize(g); |
| |
| BOOST_CHECK(num_edges(g) == 0); |
| BOOST_CHECK(out_degree(u, g) == 0); |
| BOOST_CHECK(out_degree(v, g) == 0); |
| BOOST_CHECK(out_degree(w, g) == 0); |
| BOOST_CHECK(in_degree(u, g) == 0); |
| BOOST_CHECK(in_degree(v, g) == 0); |
| BOOST_CHECK(in_degree(w, g) == 0); |
| |
| if (process_id(g.process_group()) == 0) std::cerr << "OK.\n"; |
| } |
| |
| void test_undirected_graph() |
| { |
| typedef adjacency_list<listS, distributedS<mpi_process_group, vecS>, |
| undirectedS> Graph; |
| typedef graph_traits<Graph>::vertex_descriptor Vertex; |
| typedef graph_traits<Graph>::edge_descriptor Edge; |
| |
| typedef std::pair<std::size_t, std::size_t> E; |
| E the_edges[3] = { E(0,3), E(1,4), E(2,5) }; |
| |
| Graph g(&the_edges[0], &the_edges[0] + 3, 6); |
| assert(num_processes(g.process_group()) == 2); |
| |
| if (process_id(g.process_group()) == 0) |
| std::cerr << "Testing undirected graph edge removal..."; |
| synchronize(g.process_group()); |
| |
| graph_traits<Graph>::vertex_iterator vi = vertices(g).first; |
| Vertex u = *vi++; |
| Vertex v = *vi++; |
| Vertex w = *vi++; |
| BOOST_CHECK(vi == vertices(g).second); |
| BOOST_CHECK(degree(u, g) == 1); |
| BOOST_CHECK(degree(v, g) == 1); |
| BOOST_CHECK(degree(w, g) == 1); |
| |
| // Remove edges |
| if (process_id(g.process_group()) == 0) { |
| BOOST_CHECK(num_edges(g) == 3); |
| remove_edge(*out_edges(u, g).first, g); |
| remove_edge(*out_edges(w, g).first, g); |
| } else { |
| BOOST_CHECK(num_edges(g) == 0); |
| remove_edge(*in_edges(v, g).first, g); |
| remove_edge(*in_edges(w, g).first, g); |
| } |
| |
| synchronize(g); |
| |
| if (num_edges(g) > 0) { |
| Edge e = *edges(g).first; |
| std::cerr << "#" << process_id(g.process_group()) << ": extra edge! (" |
| << local(source(e, g)) << "@" << owner(source(e, g)) |
| << ", " |
| << local(target(e, g)) << "@" << owner(target(e, g)) |
| << ")\n"; |
| } |
| |
| BOOST_CHECK(num_edges(g) == 0); |
| BOOST_CHECK(degree(u, g) == 0); |
| BOOST_CHECK(degree(v, g) == 0); |
| BOOST_CHECK(degree(w, g) == 0); |
| if (process_id(g.process_group()) == 0) std::cerr << "OK.\n"; |
| } |
| |
| int test_main(int argc, char** argv) |
| { |
| boost::mpi::environment env(argc, argv); |
| test_bidirectional_graph(); |
| test_undirected_graph(); |
| return 0; |
| } |