1 // Copyright (C) 2004-2006 The Trustees of Indiana University.
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)
7 // Authors: Douglas Gregor
9 #ifndef BOOST_GRAPH_PARALLEL_GRAPHVIZ_HPP
10 #define BOOST_GRAPH_PARALLEL_GRAPHVIZ_HPP
12 #ifndef BOOST_GRAPH_USE_MPI
13 #error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
16 #include <boost/graph/graph_traits.hpp>
17 #include <boost/graph/distributed/concepts.hpp>
18 #include <boost/property_map/property_map.hpp>
19 #include <boost/graph/graphviz.hpp>
20 #include <boost/type_traits/is_base_and_derived.hpp>
21 #include <boost/type_traits/is_same.hpp>
26 #include <boost/graph/parallel/container_traits.hpp>
27 #include <boost/graph/parallel/process_group.hpp>
28 #include <boost/property_map/parallel/global_index_map.hpp>
32 template<typename Graph>
33 struct graph_id_writer
35 explicit graph_id_writer(const Graph& g) : g(g) { }
37 void operator()(std::ostream& out)
39 out << " label=\"p" << process_id(g.process_group()) << "\";\n";
46 template<typename NumberMap>
47 struct paint_by_number_writer
49 explicit paint_by_number_writer(NumberMap number) : number(number) { }
51 template<typename Descriptor>
52 void operator()(std::ostream& out, Descriptor k)
54 static const char* color_names[] = {
80 const int colors = sizeof(color_names) / sizeof(color_names[0]);
81 if (get(number, k) < colors) {
82 out << " [ style=\"filled\", fillcolor=\"" << color_names[get(number, k)]
85 out << " [ label=\"(" << get(number, k) << ")\" ]";
93 template<typename NumberMap>
94 inline paint_by_number_writer<NumberMap>
95 paint_by_number(NumberMap number)
96 { return paint_by_number_writer<NumberMap>(number); }
98 template<typename Graph, typename VertexPropertiesWriter,
99 typename EdgePropertiesWriter, typename GraphPropertiesWriter>
101 write_graphviz(std::ostream& out,
103 VertexPropertiesWriter vpw,
104 EdgePropertiesWriter epw,
105 GraphPropertiesWriter gpw
106 BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
108 typedef typename graph_traits<Graph>::directed_category directed_category;
109 typedef typename boost::graph::parallel::process_group_type<Graph>::type
111 typedef typename property_map<Graph, vertex_index_t>::const_type
113 typedef typename property_map<Graph, vertex_global_t>::const_type
116 static const bool is_undirected
117 = (is_base_and_derived<undirected_tag, directed_category>::value
118 || is_same<undirected_tag, directed_category>::value);
119 static const char* graph_kind = is_undirected? "graph" : "digraph";
120 static const char* edge_kind = is_undirected? "--" : "->";
122 using boost::graph::parallel::process_group;
123 process_group_type pg = process_group(g);
125 parallel::global_index_map<VertexIndexMap, VertexGlobalMap>
126 global_index(pg, num_vertices(g), get(vertex_index, g),
127 get(vertex_global, g));
129 std::ostringstream local_graph_out;
131 local_graph_out << " subgraph cluster_" << process_id(pg) << " {\n";
132 gpw(local_graph_out);
134 typename graph_traits<Graph>::vertex_iterator vi, vi_end;
135 for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
137 int global_idx = get(global_index, *vi);
138 local_graph_out << " n" << global_idx;
139 vpw(local_graph_out, *vi);
140 local_graph_out << ";\n";
142 local_graph_out << " }\n\n";
145 typename graph_traits<Graph>::edge_iterator ei, ei_end;
146 for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
147 int source_idx = get(global_index, source(*ei, g));
148 int target_idx = get(global_index, target(*ei, g));
149 local_graph_out << " n" << source_idx << " " << edge_kind << " n"
151 epw(local_graph_out, *ei);
152 local_graph_out << ";\n";
155 if (process_id(pg) == 0) {
156 out << graph_kind << " g {\n";
157 out << local_graph_out.str();
160 for (int i = 1; i < num_processes(pg); ++i) {
162 receive(pg, i, 0, len);
163 char* data = new char [len+1];
165 receive(pg, i, 1, data, len);
166 out << std::endl << data;
171 std::string result_str = local_graph_out.str();
172 const char* data = result_str.c_str();
174 int len = result_str.length();
176 send(pg, 0, 1, data, len);
184 template<typename Graph, typename VertexPropertiesWriter,
185 typename EdgePropertiesWriter>
187 write_graphviz(std::ostream& out,
189 VertexPropertiesWriter vpw,
190 EdgePropertiesWriter epw
191 BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
193 write_graphviz(out, g, vpw, epw, graph_id_writer<Graph>(g));
196 template<typename Graph, typename VertexPropertiesWriter>
198 write_graphviz(std::ostream& out,
200 VertexPropertiesWriter vpw
201 BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
203 write_graphviz(out, g, vpw, default_writer());
206 template<typename Graph>
208 write_graphviz(std::ostream& out, const Graph& g
209 BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
211 write_graphviz(out, g, default_writer());
214 template<typename Graph, typename VertexPropertiesWriter,
215 typename EdgePropertiesWriter, typename GraphPropertiesWriter>
217 write_graphviz(const std::string& filename,
219 VertexPropertiesWriter vpw,
220 EdgePropertiesWriter epw,
221 GraphPropertiesWriter gpw
222 BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
224 if (process_id(g.process_group()) == 0) {
225 std::ofstream out(filename.c_str());
226 write_graphviz(out, g, vpw, epw, gpw);
228 write_graphviz(std::cout, g, vpw, epw, gpw);
232 template<typename Graph, typename VertexPropertiesWriter,
233 typename EdgePropertiesWriter>
235 write_graphviz(const std::string& filename,
237 VertexPropertiesWriter vpw,
238 EdgePropertiesWriter epw
239 BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
241 if (process_id(g.process_group()) == 0) {
242 std::ofstream out(filename.c_str());
243 write_graphviz(out, g, vpw, epw);
245 write_graphviz(std::cout, g, vpw, epw);
249 template<typename Graph, typename VertexPropertiesWriter>
251 write_graphviz(const std::string& filename,
253 VertexPropertiesWriter vpw
254 BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
256 if (process_id(g.process_group()) == 0) {
257 std::ofstream out(filename.c_str());
258 write_graphviz(out, g, vpw);
260 write_graphviz(std::cout, g, vpw);
264 template<typename Graph>
266 write_graphviz(const std::string& filename, const Graph& g
267 BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
269 if (process_id(g.process_group()) == 0) {
270 std::ofstream out(filename.c_str());
271 write_graphviz(out, g);
273 write_graphviz(std::cout, g);
277 template<typename Graph>
279 write_graphviz(std::ostream& out, const Graph& g,
280 const dynamic_properties& dp,
281 const std::string& node_id = "node_id"
282 BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
286 /*vertex_writer=*/dynamic_vertex_properties_writer(dp, node_id),
287 /*edge_writer=*/dynamic_properties_writer(dp));
290 } // end namespace boost
292 #endif // BOOST_GRAPH_PARALLEL_GRAPHVIZ_HPP