/Src/Dependencies/Boost/boost/graph/distributed/graphviz.hpp

http://hadesmem.googlecode.com/ · C++ Header · 294 lines · 253 code · 35 blank · 6 comment · 23 complexity · b4528ddf17c54ad1d6e98fd4adc27ae7 MD5 · raw file

  1. // Copyright (C) 2004-2006 The Trustees of Indiana University.
  2. // Use, modification and distribution is subject to the Boost Software
  3. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // Authors: Douglas Gregor
  6. // Andrew Lumsdaine
  7. #ifndef BOOST_GRAPH_PARALLEL_GRAPHVIZ_HPP
  8. #define BOOST_GRAPH_PARALLEL_GRAPHVIZ_HPP
  9. #ifndef BOOST_GRAPH_USE_MPI
  10. #error "Parallel BGL files should not be included unless <boost/graph/use_mpi.hpp> has been included"
  11. #endif
  12. #include <boost/graph/graph_traits.hpp>
  13. #include <boost/graph/distributed/concepts.hpp>
  14. #include <boost/property_map/property_map.hpp>
  15. #include <boost/graph/graphviz.hpp>
  16. #include <boost/type_traits/is_base_and_derived.hpp>
  17. #include <boost/type_traits/is_same.hpp>
  18. #include <fstream>
  19. #include <sstream>
  20. #include <iostream>
  21. #include <string>
  22. #include <boost/graph/parallel/container_traits.hpp>
  23. #include <boost/graph/parallel/process_group.hpp>
  24. #include <boost/property_map/parallel/global_index_map.hpp>
  25. namespace boost {
  26. template<typename Graph>
  27. struct graph_id_writer
  28. {
  29. explicit graph_id_writer(const Graph& g) : g(g) { }
  30. void operator()(std::ostream& out)
  31. {
  32. out << " label=\"p" << process_id(g.process_group()) << "\";\n";
  33. }
  34. private:
  35. const Graph& g;
  36. };
  37. template<typename NumberMap>
  38. struct paint_by_number_writer
  39. {
  40. explicit paint_by_number_writer(NumberMap number) : number(number) { }
  41. template<typename Descriptor>
  42. void operator()(std::ostream& out, Descriptor k)
  43. {
  44. static const char* color_names[] = {
  45. "blue",
  46. "brown",
  47. "cyan",
  48. "darkgreen",
  49. "darkorchid",
  50. "darksalmon",
  51. "darkviolet",
  52. "deeppink",
  53. "gold3",
  54. "green",
  55. "magenta",
  56. "navy",
  57. "red",
  58. "yellow",
  59. "palegreen",
  60. "gray65",
  61. "gray21",
  62. "bisque2",
  63. "greenyellow",
  64. "indianred4",
  65. "lightblue2",
  66. "mediumspringgreen",
  67. "orangered",
  68. "orange"
  69. };
  70. const int colors = sizeof(color_names) / sizeof(color_names[0]);
  71. if (get(number, k) < colors) {
  72. out << " [ style=\"filled\", fillcolor=\"" << color_names[get(number, k)]
  73. << "\" ]";
  74. } else {
  75. out << " [ label=\"(" << get(number, k) << ")\" ]";
  76. }
  77. }
  78. private:
  79. NumberMap number;
  80. };
  81. template<typename NumberMap>
  82. inline paint_by_number_writer<NumberMap>
  83. paint_by_number(NumberMap number)
  84. { return paint_by_number_writer<NumberMap>(number); }
  85. template<typename Graph, typename VertexPropertiesWriter,
  86. typename EdgePropertiesWriter, typename GraphPropertiesWriter>
  87. void
  88. write_graphviz(std::ostream& out,
  89. const Graph& g,
  90. VertexPropertiesWriter vpw,
  91. EdgePropertiesWriter epw,
  92. GraphPropertiesWriter gpw
  93. BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
  94. {
  95. typedef typename graph_traits<Graph>::directed_category directed_category;
  96. typedef typename graph_traits<Graph>::vertices_size_type vertices_size_type;
  97. typedef typename boost::graph::parallel::process_group_type<Graph>::type
  98. process_group_type;
  99. typedef typename process_group_type::process_id_type process_id_type;
  100. typedef typename property_map<Graph, vertex_index_t>::const_type
  101. VertexIndexMap;
  102. typedef typename property_map<Graph, vertex_global_t>::const_type
  103. VertexGlobalMap;
  104. static const bool is_undirected
  105. = (is_base_and_derived<undirected_tag, directed_category>::value
  106. || is_same<undirected_tag, directed_category>::value);
  107. static const char* graph_kind = is_undirected? "graph" : "digraph";
  108. static const char* edge_kind = is_undirected? "--" : "->";
  109. using boost::graph::parallel::process_group;
  110. process_group_type pg = process_group(g);
  111. parallel::global_index_map<VertexIndexMap, VertexGlobalMap>
  112. global_index(pg, num_vertices(g), get(vertex_index, g),
  113. get(vertex_global, g));
  114. std::ostringstream local_graph_out;
  115. local_graph_out << " subgraph cluster_" << process_id(pg) << " {\n";
  116. gpw(local_graph_out);
  117. typename graph_traits<Graph>::vertex_iterator vi, vi_end;
  118. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
  119. int global_idx = get(global_index, *vi);
  120. local_graph_out << " n" << global_idx;
  121. vpw(local_graph_out, *vi);
  122. local_graph_out << ";\n";
  123. }
  124. local_graph_out << " }\n\n";
  125. typename graph_traits<Graph>::edge_iterator ei, ei_end;
  126. for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
  127. int source_idx = get(global_index, source(*ei, g));
  128. int target_idx = get(global_index, target(*ei, g));
  129. local_graph_out << " n" << source_idx << " " << edge_kind << " n"
  130. << target_idx;
  131. epw(local_graph_out, *ei);
  132. local_graph_out << ";\n";
  133. }
  134. if (process_id(pg) == 0) {
  135. out << graph_kind << " g {\n";
  136. out << local_graph_out.str();
  137. synchronize(pg);
  138. for (int i = 1; i < num_processes(pg); ++i) {
  139. int len;
  140. receive(pg, i, 0, len);
  141. char* data = new char [len+1];
  142. data[len] = 0;
  143. receive(pg, i, 1, data, len);
  144. out << std::endl << data;
  145. delete [] data;
  146. }
  147. out << "}\n";
  148. } else {
  149. std::string result_str = local_graph_out.str();
  150. const char* data = result_str.c_str();
  151. int len = result_str.length();
  152. send(pg, 0, 0, len);
  153. send(pg, 0, 1, data, len);
  154. synchronize(pg);
  155. }
  156. synchronize(pg);
  157. synchronize(pg);
  158. synchronize(pg);
  159. }
  160. template<typename Graph, typename VertexPropertiesWriter,
  161. typename EdgePropertiesWriter>
  162. inline void
  163. write_graphviz(std::ostream& out,
  164. const Graph& g,
  165. VertexPropertiesWriter vpw,
  166. EdgePropertiesWriter epw
  167. BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
  168. {
  169. write_graphviz(out, g, vpw, epw, graph_id_writer<Graph>(g));
  170. }
  171. template<typename Graph, typename VertexPropertiesWriter>
  172. inline void
  173. write_graphviz(std::ostream& out,
  174. const Graph& g,
  175. VertexPropertiesWriter vpw
  176. BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
  177. {
  178. write_graphviz(out, g, vpw, default_writer());
  179. }
  180. template<typename Graph>
  181. inline void
  182. write_graphviz(std::ostream& out, const Graph& g
  183. BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
  184. {
  185. write_graphviz(out, g, default_writer());
  186. }
  187. template<typename Graph, typename VertexPropertiesWriter,
  188. typename EdgePropertiesWriter, typename GraphPropertiesWriter>
  189. void
  190. write_graphviz(const std::string& filename,
  191. const Graph& g,
  192. VertexPropertiesWriter vpw,
  193. EdgePropertiesWriter epw,
  194. GraphPropertiesWriter gpw
  195. BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
  196. {
  197. if (process_id(g.process_group()) == 0) {
  198. std::ofstream out(filename.c_str());
  199. write_graphviz(out, g, vpw, epw, gpw);
  200. } else {
  201. write_graphviz(std::cout, g, vpw, epw, gpw);
  202. }
  203. }
  204. template<typename Graph, typename VertexPropertiesWriter,
  205. typename EdgePropertiesWriter>
  206. void
  207. write_graphviz(const std::string& filename,
  208. const Graph& g,
  209. VertexPropertiesWriter vpw,
  210. EdgePropertiesWriter epw
  211. BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
  212. {
  213. if (process_id(g.process_group()) == 0) {
  214. std::ofstream out(filename.c_str());
  215. write_graphviz(out, g, vpw, epw);
  216. } else {
  217. write_graphviz(std::cout, g, vpw, epw);
  218. }
  219. }
  220. template<typename Graph, typename VertexPropertiesWriter>
  221. void
  222. write_graphviz(const std::string& filename,
  223. const Graph& g,
  224. VertexPropertiesWriter vpw
  225. BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
  226. {
  227. if (process_id(g.process_group()) == 0) {
  228. std::ofstream out(filename.c_str());
  229. write_graphviz(out, g, vpw);
  230. } else {
  231. write_graphviz(std::cout, g, vpw);
  232. }
  233. }
  234. template<typename Graph>
  235. void
  236. write_graphviz(const std::string& filename, const Graph& g
  237. BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
  238. {
  239. if (process_id(g.process_group()) == 0) {
  240. std::ofstream out(filename.c_str());
  241. write_graphviz(out, g);
  242. } else {
  243. write_graphviz(std::cout, g);
  244. }
  245. }
  246. template<typename Graph>
  247. void
  248. write_graphviz(std::ostream& out, const Graph& g,
  249. const dynamic_properties& dp,
  250. const std::string& node_id = "node_id"
  251. BOOST_GRAPH_ENABLE_IF_MODELS_PARM(Graph,distributed_graph_tag))
  252. {
  253. write_graphviz
  254. (out, g,
  255. /*vertex_writer=*/dynamic_vertex_properties_writer(dp, node_id),
  256. /*edge_writer=*/dynamic_properties_writer(dp));
  257. }
  258. } // end namespace boost
  259. #endif // BOOST_GRAPH_PARALLEL_GRAPHVIZ_HPP