dispenso 1.6.2
A library for task parallelism
Loading...
Searching...
No Matches
graph_dot.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
14#pragma once
15
16#include <cstdint>
17#include <fstream>
18#include <string>
19#include <type_traits>
20#include <unordered_map>
21
22#include <dispenso/graph.h>
23
24namespace dispenso {
25namespace detail {
26inline std::string getName(
27 const void* ptr,
28 const size_t index,
29 const std::unordered_map<uintptr_t, std::string>* nodeNames) {
30 const uintptr_t key = reinterpret_cast<uintptr_t>(ptr);
31 if (nodeNames) {
32 auto it = nodeNames->find(key);
33 if (it != nodeNames->end()) {
34 return it->second;
35 }
36 }
37 return std::to_string(index);
38}
39} // namespace detail
40
52template <typename G>
54 const char* filename,
55 const G& graph,
56 const std::unordered_map<uintptr_t, std::string>* nodeNames) {
57 using SubgraphType = typename G::SubgraphType;
58 using NodeType = typename G::NodeType;
59 std::ofstream datfile(filename);
60 datfile << R"dot(digraph {
61 rankdir = LR
62 node [shape = rectangle, style = filled, colorscheme=pastel19]
63 graph [style = filled, color = Gray95]
64
65 subgraph cluster_l { label = "Legend"; style=solid; color=black
66 empty1 [style = invis, shape=point]
67 empty2 [style = invis, shape=point]
68 incomplete [color = 1]
69 completed [color = 2]
70 incomplete -> empty1 [label = "normal"]
71 completed -> empty2 [arrowhead = onormal,label = "bidirectional\lpropagation"]
72 }
73)dot";
74
75 const size_t numSubgraphs = graph.numSubgraphs();
76 for (size_t i = 0; i < numSubgraphs; ++i) {
77 const SubgraphType& s = graph.subgraph(i);
78 if (i != 0) {
79 datfile << " " << "subgraph cluster_" << i << " { label = \""
80 << detail::getName(&s, i, nodeNames) << "\"\n";
81 }
82 const size_t numNodes = s.numNodes();
83 for (size_t j = 0; j < numNodes; ++j) {
84 const NodeType& node = s.node(j);
85 datfile << " " << reinterpret_cast<uintptr_t>(&node)
86 << " [color = " << (node.isCompleted() ? 2 : 1);
87 datfile << " label = \"" << detail::getName(&node, j, nodeNames) << "\"]\n";
88 }
89
90 if (i != 0) {
91 datfile << " }\n";
92 }
93 }
94
95 graph.forEachNode([&](const NodeType& node) {
96 node.forEachDependent([&](const dispenso::Node& d) {
97 datfile << " " << reinterpret_cast<uintptr_t>(&node) << " -> "
98 << reinterpret_cast<uintptr_t>(&d);
99
100 if (std::is_same<dispenso::BiPropNode, NodeType>::value) {
101 const auto& node1 = static_cast<const dispenso::BiPropNode&>(node);
102 const auto& node2 = static_cast<const dispenso::BiPropNode&>(d);
103 datfile << (node1.isSameSet(node2) ? "[arrowhead=onormal]" : "");
104 }
105 datfile << '\n';
106 });
107 });
108
109 datfile << "}";
110 datfile.close();
111}
112} // namespace dispenso
void graphsToDot(const char *filename, const G &graph, const std::unordered_map< uintptr_t, std::string > *nodeNames)
Definition graph_dot.h:53