123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- // Copyright (C) 2004-2006 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
- #ifndef BOOST_GRAPH_PARALLEL_GRAPHVIZ_HPP
- #define BOOST_GRAPH_PARALLEL_GRAPHVIZ_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/graph/graph_traits.hpp>
- #include <boost/graph/distributed/concepts.hpp>
- #include <boost/property_map/property_map.hpp>
- #include <boost/graph/graphviz.hpp>
- #include <boost/type_traits/is_base_and_derived.hpp>
- #include <boost/type_traits/is_same.hpp>
- #include <fstream>
- #include <sstream>
- #include <iostream>
- #include <string>
- #include <boost/graph/parallel/container_traits.hpp>
- #include <boost/graph/parallel/process_group.hpp>
- #include <boost/property_map/parallel/global_index_map.hpp>
- namespace boost {
- template<typename Graph>
- struct graph_id_writer
- {
- explicit graph_id_writer(const Graph& g) : g(g) { }
- void operator()(std::ostream& out)
- {
- out << " label=\"p" << process_id(g.process_group()) << "\";\n";
- }
- private:
- const Graph& g;
- };
- template<typename NumberMap>
- struct paint_by_number_writer
- {
- explicit paint_by_number_writer(NumberMap number) : number(number) { }
- template<typename Descriptor>
- void operator()(std::ostream& out, Descriptor k)
- {
- static const char* color_names[] = {
- "blue",
- "brown",
- "cyan",
- "darkgreen",
- "darkorchid",
- "darksalmon",
- "darkviolet",
- "deeppink",
- "gold3",
- "green",
- "magenta",
- "navy",
- "red",
- "yellow",
- "palegreen",
- "gray65",
- "gray21",
- "bisque2",
- "greenyellow",
- "indianred4",
- "lightblue2",
- "mediumspringgreen",
- "orangered",
- "orange"
- };
- const int colors = sizeof(color_names) / sizeof(color_names[0]);
- if (get(number, k) < colors) {
- out << " [ style=\"filled\", fillcolor=\"" << color_names[get(number, k)]
- << "\" ]";
- } else {
- out << " [ label=\"(" << get(number, k) << ")\" ]";
- }
- }
- private:
- NumberMap number;
- };
- template<typename NumberMap>
- inline paint_by_number_writer<NumberMap>
- paint_by_number(NumberMap number)
- { return paint_by_number_writer<NumberMap>(number); }
- template<typename Graph, typename VertexPropertiesWriter,
- typename EdgePropertiesWriter, typename GraphPropertiesWriter>
- void
- write_graphviz(std::ostream& out,
- const Graph& g,
- VertexPropertiesWriter vpw,
- EdgePropertiesWriter epw,
- GraphPropertiesWriter gpw
- BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
- {
- typedef typename graph_traits<Graph>::directed_category directed_category;
- typedef typename boost::graph::parallel::process_group_type<Graph>::type
- process_group_type;
- typedef typename property_map<Graph, vertex_index_t>::const_type
- VertexIndexMap;
- typedef typename property_map<Graph, vertex_global_t>::const_type
- VertexGlobalMap;
- static const bool is_undirected
- = (is_base_and_derived<undirected_tag, directed_category>::value
- || is_same<undirected_tag, directed_category>::value);
- static const char* graph_kind = is_undirected? "graph" : "digraph";
- static const char* edge_kind = is_undirected? "--" : "->";
- using boost::graph::parallel::process_group;
- process_group_type pg = process_group(g);
- parallel::global_index_map<VertexIndexMap, VertexGlobalMap>
- global_index(pg, num_vertices(g), get(vertex_index, g),
- get(vertex_global, g));
- std::ostringstream local_graph_out;
- local_graph_out << " subgraph cluster_" << process_id(pg) << " {\n";
- gpw(local_graph_out);
- typename graph_traits<Graph>::vertex_iterator vi, vi_end;
- for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
- int global_idx = get(global_index, *vi);
- local_graph_out << " n" << global_idx;
- vpw(local_graph_out, *vi);
- local_graph_out << ";\n";
- }
- local_graph_out << " }\n\n";
-
- typename graph_traits<Graph>::edge_iterator ei, ei_end;
- for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
- int source_idx = get(global_index, source(*ei, g));
- int target_idx = get(global_index, target(*ei, g));
- local_graph_out << " n" << source_idx << " " << edge_kind << " n"
- << target_idx;
- epw(local_graph_out, *ei);
- local_graph_out << ";\n";
- }
- if (process_id(pg) == 0) {
- out << graph_kind << " g {\n";
- out << local_graph_out.str();
- synchronize(pg);
- for (int i = 1; i < num_processes(pg); ++i) {
- int len;
- receive(pg, i, 0, len);
- char* data = new char [len+1];
- data[len] = 0;
- receive(pg, i, 1, data, len);
- out << std::endl << data;
- delete [] data;
- }
- out << "}\n";
- } else {
- std::string result_str = local_graph_out.str();
- const char* data = result_str.c_str();
- int len = result_str.length();
- send(pg, 0, 0, len);
- send(pg, 0, 1, data, len);
- synchronize(pg);
- }
- synchronize(pg);
- synchronize(pg);
- synchronize(pg);
- }
- template<typename Graph, typename VertexPropertiesWriter,
- typename EdgePropertiesWriter>
- inline void
- write_graphviz(std::ostream& out,
- const Graph& g,
- VertexPropertiesWriter vpw,
- EdgePropertiesWriter epw
- BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
- {
- write_graphviz(out, g, vpw, epw, graph_id_writer<Graph>(g));
- }
- template<typename Graph, typename VertexPropertiesWriter>
- inline void
- write_graphviz(std::ostream& out,
- const Graph& g,
- VertexPropertiesWriter vpw
- BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
- {
- write_graphviz(out, g, vpw, default_writer());
- }
- template<typename Graph>
- inline void
- write_graphviz(std::ostream& out, const Graph& g
- BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
- {
- write_graphviz(out, g, default_writer());
- }
- template<typename Graph, typename VertexPropertiesWriter,
- typename EdgePropertiesWriter, typename GraphPropertiesWriter>
- void
- write_graphviz(const std::string& filename,
- const Graph& g,
- VertexPropertiesWriter vpw,
- EdgePropertiesWriter epw,
- GraphPropertiesWriter gpw
- BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
- {
- if (process_id(g.process_group()) == 0) {
- std::ofstream out(filename.c_str());
- write_graphviz(out, g, vpw, epw, gpw);
- } else {
- write_graphviz(std::cout, g, vpw, epw, gpw);
- }
- }
- template<typename Graph, typename VertexPropertiesWriter,
- typename EdgePropertiesWriter>
- void
- write_graphviz(const std::string& filename,
- const Graph& g,
- VertexPropertiesWriter vpw,
- EdgePropertiesWriter epw
- BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
- {
- if (process_id(g.process_group()) == 0) {
- std::ofstream out(filename.c_str());
- write_graphviz(out, g, vpw, epw);
- } else {
- write_graphviz(std::cout, g, vpw, epw);
- }
- }
- template<typename Graph, typename VertexPropertiesWriter>
- void
- write_graphviz(const std::string& filename,
- const Graph& g,
- VertexPropertiesWriter vpw
- BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
- {
- if (process_id(g.process_group()) == 0) {
- std::ofstream out(filename.c_str());
- write_graphviz(out, g, vpw);
- } else {
- write_graphviz(std::cout, g, vpw);
- }
- }
- template<typename Graph>
- void
- write_graphviz(const std::string& filename, const Graph& g
- BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
- {
- if (process_id(g.process_group()) == 0) {
- std::ofstream out(filename.c_str());
- write_graphviz(out, g);
- } else {
- write_graphviz(std::cout, g);
- }
- }
- template<typename Graph>
- void
- write_graphviz(std::ostream& out, const Graph& g,
- const dynamic_properties& dp,
- const std::string& node_id = "node_id"
- BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
- {
- write_graphviz
- (out, g,
- /*vertex_writer=*/dynamic_vertex_properties_writer(dp, node_id),
- /*edge_writer=*/dynamic_properties_writer(dp));
- }
- } // end namespace boost
- #endif // BOOST_GRAPH_PARALLEL_GRAPHVIZ_HPP
|