• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

daisytuner / sdfglib / 15852980623

24 Jun 2025 02:16PM UTC coverage: 64.412% (+0.3%) from 64.145%
15852980623

push

github

web-flow
Merge pull request #72 from daisytuner/capture-instrumentation

Capture instrumentation

363 of 446 new or added lines in 19 files covered. (81.39%)

100 existing lines in 5 files now uncovered.

8389 of 13024 relevant lines covered (64.41%)

116.79 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.27
/src/visualizer/dot_visualizer.cpp
1
#include "sdfg/visualizer/dot_visualizer.h"
2

3
#include <cstddef>
4
#include <string>
5
#include <utility>
6

7
#include "sdfg/data_flow/access_node.h"
8
#include "sdfg/data_flow/memlet.h"
9
#include "sdfg/structured_control_flow/control_flow_node.h"
10
#include "sdfg/structured_control_flow/sequence.h"
11
#include "sdfg/structured_sdfg.h"
12
#include <regex>
13

14
namespace sdfg {
15
namespace visualizer {
16

17
static std::regex dotIdBadChars("[^a-zA-Z0-9_]+");
2✔
18

19
static std::string escapeDotId(size_t id, const std::string& prefix = "") {
776✔
20
    return prefix + std::to_string(id);
776✔
NEW
21
}
×
22

23
static std::string escapeDotId(const std::string& id, const std::string& prefix = "") {
346✔
24
    return prefix + std::regex_replace(id, dotIdBadChars, "_");
346✔
NEW
25
}
×
26

27
void DotVisualizer::visualizeBlock(const StructuredSDFG& sdfg, const structured_control_flow::Block& block) {
217✔
28
    auto id = escapeDotId(block.element_id(), "block_");
217✔
29
    this->stream_ << "subgraph cluster_" << id << " {" << std::endl;
217✔
30
    this->stream_.setIndent(this->stream_.indent() + 4);
181✔
31
    this->stream_ << "style=filled;shape=box;fillcolor=white;color=black;label=\"\";" << std::endl;
181✔
32
    this->last_comp_name_cluster_ = "cluster_" + id;
181✔
33
    if (block.dataflow().nodes().empty()) {
181✔
34
        this->stream_ << id << " [shape=point,style=invis,label=\"\"];"
2✔
35
                      << std::endl;
2✔
36
        this->stream_.setIndent(this->stream_.indent() - 4);
2✔
37
        this->stream_ << "}" << std::endl;
2✔
38
        this->last_comp_name_ = id;
2✔
39
        return;
2✔
40
    }
41
    this->last_comp_name_.clear();
179✔
42
    std::list<const data_flow::DataFlowNode*> nodes = block.dataflow().topological_sort();
179✔
43
    for (const data_flow::DataFlowNode* node : nodes) {
557✔
44
        auto nodeId = escapeDotId(node->element_id(), "n_");
378✔
45
        if (this->last_comp_name_.empty()) this->last_comp_name_ = nodeId;
378✔
46
        if (const data_flow::Tasklet* tasklet = dynamic_cast<const data_flow::Tasklet*>(node)) {
378✔
47
            
48
            this->stream_ << nodeId << " [shape=octagon,label=\""
181✔
49
                          << tasklet->output().first << " = ";
181✔
50
            this->visualizeTasklet(*tasklet);
181✔
51
            this->stream_ << "\"];" << std::endl;
181✔
52
        } else if (const data_flow::AccessNode* access_node = dynamic_cast<const data_flow::AccessNode*>(node)) {
378✔
53
            this->stream_ << nodeId << " [";
197✔
54
            if (!sdfg.is_internal(access_node->data())) this->stream_ << "penwidth=3.0,";
197✔
55
            if (sdfg.is_transient(access_node->data())) this->stream_ << "style=\"dashed,filled\",";
197✔
56
            this->stream_ << "label=\"" << access_node->data() << "\"];" << std::endl;
197✔
57
        } else if (const data_flow::LibraryNode* libnode = dynamic_cast<const data_flow::LibraryNode*>(node)) {
197✔
NEW
58
            this->stream_ << nodeId << " [shape=doubleoctagon,label=\""
×
NEW
59
                << libnode->toStr() << "\"];" << std::endl;
×
NEW
60
            this->stream_ << "\"];" << std::endl;
×
NEW
61
        }
×
62
        for (const data_flow::Memlet& iedge : block.dataflow().in_edges(*node)) {
577✔
63
            auto& src = iedge.src();
199✔
64

65
            this->stream_ << escapeDotId(src.element_id(), "n_") << " -> " << nodeId
398✔
66
                            << " [label=\"   ";
199✔
67
            auto& dst_conn = iedge.dst_conn();
199✔
68
            bool dstIsVoid = dst_conn == "void";
199✔
69
            bool dstIsRef = dst_conn == "refs";
199✔
70
            auto& src_conn = iedge.src_conn();
199✔
71
            bool srcIsVoid = src_conn == "void";
199✔
72
            bool srcIsRef = src_conn == "refs";
199✔
73

74
            if (dstIsVoid || dstIsRef) {
199✔
75
                auto& dstVar = dynamic_cast<data_flow::AccessNode const&>(iedge.dst()).data();
181✔
76
                this->stream_ << dstVar;
181✔
77
                if (dstIsVoid) {
181✔
78
                    types::IType const* dstTypePtr = sdfg.exists(dstVar)? &sdfg.type(dstVar) : nullptr;
181✔
79
                    this->visualizeSubset(sdfg, iedge.subset(), dstTypePtr);
181✔
80
                }
181✔
81
            } else {
181✔
82
                this->stream_ << dst_conn;
18✔
83
            }
84
            
85
            this->stream_ << " = ";
199✔
86

87
            if (srcIsVoid) {
199✔
88
                auto& srcVar = dynamic_cast<data_flow::AccessNode const&>(src).data();
18✔
89
                if (srcIsRef || dstIsRef) {
18✔
90
                    this->stream_ << "&";
18✔
NEW
91
                }
×
NEW
92
                this->stream_ << srcVar;
×
93
                if (srcIsVoid) {
18✔
94
                    types::IType const* srcTypePtr = sdfg.exists(srcVar)? &sdfg.type(srcVar) : nullptr;
18✔
95
                    this->visualizeSubset(sdfg, iedge.subset(), srcTypePtr);
18✔
96
                }
18✔
97
            } else {
18✔
98
                this->stream_ << src_conn;
181✔
99
            }
100
            this->stream_ << "   \"];" << std::endl;
199✔
101
        }
102
    }
342✔
103
    this->stream_.setIndent(this->stream_.indent() - 4);
179✔
104
    this->stream_ << "}" << std::endl;
179✔
105
}
325✔
106

107
void DotVisualizer::visualizeSequence(const StructuredSDFG& sdfg,
191✔
108
                                      const structured_control_flow::Sequence& sequence) {
109
    std::string last_comp_name_tmp, last_comp_name_cluster_tmp;
191✔
110
    for (size_t i = 0; i < sequence.size(); ++i) {
390✔
111
        std::pair<const structured_control_flow::ControlFlowNode&, const structured_control_flow::Transition&>
112
            child = sequence.at(i);
199✔
113
        this->visualizeNode(sdfg, child.first);
199✔
114
        if ((i > 0) && !last_comp_name_tmp.empty() && !this->last_comp_name_.empty()) {
199✔
115
            this->stream_ << last_comp_name_tmp << " -> " << this->last_comp_name_ << " [";
8✔
116
            if (!last_comp_name_cluster_tmp.empty())
8✔
117
                this->stream_ << "ltail=\"" << last_comp_name_cluster_tmp << "\",";
8✔
118
            if (!this->last_comp_name_cluster_.empty())
8✔
119
                this->stream_ << "lhead=\"" << this->last_comp_name_cluster_ << "\",";
6✔
120
            this->stream_ << "minlen=3]"
8✔
121
                          << ";" << std::endl;
8✔
122
        }
8✔
123
        last_comp_name_tmp = this->last_comp_name_;
199✔
124
        this->last_comp_name_.clear();
199✔
125
        last_comp_name_cluster_tmp = this->last_comp_name_cluster_;
199✔
126
        this->last_comp_name_cluster_.clear();
199✔
127
    }
199✔
128
}
191✔
129

130
void DotVisualizer::visualizeIfElse(const StructuredSDFG& sdfg,
3✔
131
                                    const structured_control_flow::IfElse& if_else) {
132
    auto id = escapeDotId(if_else.element_id(), "if_");
3✔
133
    this->stream_ << "subgraph cluster_" << id << " {" << std::endl;
3✔
134
    this->stream_.setIndent(this->stream_.indent() + 4);
3✔
135
    this->stream_ << "style=filled;shape=box;fillcolor=white;color=black;label=\"if:\";"
3✔
136
                  << std::endl
3✔
137
                  << id << " [shape=point,style=invis,label=\"\"];" << std::endl;
3✔
138
    for (size_t i = 0; i < if_else.size(); ++i) {
9✔
139
        this->stream_ << "subgraph cluster_" << id << "_" << std::to_string(i)
12✔
140
                      << " {" << std::endl;
6✔
141
        this->stream_.setIndent(this->stream_.indent() + 4);
6✔
142
        this->stream_ << "style=filled;shape=box;fillcolor=white;color=black;label=\""
12✔
143
                      << this->expression(if_else.at(i).second->__str__()) << "\";" << std::endl;
6✔
144
        this->visualizeSequence(sdfg, if_else.at(i).first);
6✔
145
        this->stream_.setIndent(this->stream_.indent() - 4);
6✔
146
        this->stream_ << "}" << std::endl;
6✔
147
    }
6✔
148
    this->stream_.setIndent(this->stream_.indent() - 4);
3✔
149
    this->stream_ << "}" << std::endl;
3✔
150
    this->last_comp_name_ = id;
3✔
151
    this->last_comp_name_cluster_ = "cluster_" + id;
3✔
152
}
3✔
153

154
void DotVisualizer::visualizeWhile(const StructuredSDFG& sdfg,
2✔
155
                                   const structured_control_flow::While& while_loop) {
156

157
    auto id = escapeDotId(while_loop.element_id(), "while_");
2✔
158
    this->stream_ << "subgraph cluster_" << id << " {" << std::endl;
2✔
159
    this->stream_.setIndent(this->stream_.indent() + 4);
2✔
160
    this->stream_ << "style=filled;shape=box;fillcolor=white;color=black;label=\"while:\";"
2✔
161
                  << std::endl
2✔
162
                  << id << " [shape=point,style=invis,label=\"\"];"
2✔
163
                  << std::endl;
2✔
164
    this->visualizeSequence(sdfg, while_loop.root());
2✔
165
    this->stream_.setIndent(this->stream_.indent() - 4);
2✔
166
    this->stream_ << "}" << std::endl;
2✔
167
    this->last_comp_name_ = id;
2✔
168
    this->last_comp_name_cluster_ = "cluster_" + id;
2✔
169
}
2✔
170

171
void DotVisualizer::visualizeFor(const StructuredSDFG& sdfg, const structured_control_flow::For& loop) {
10✔
172
    auto id = escapeDotId(loop.element_id(), "for_");
10✔
173
    this->stream_ << "subgraph cluster_" << id << " {" << std::endl;
10✔
174
    this->stream_.setIndent(this->stream_.indent() + 4);
10✔
175
    this->stream_ << "style=filled;shape=box;fillcolor=white;color=black;label=\"for: ";
10✔
176
    this->visualizeForBounds(loop.indvar(), loop.init(), loop.condition(), loop.update());
10✔
177
    this->stream_ << "\";" << std::endl
10✔
178
                  << id << " [shape=point,style=invis,label=\"\"];" << std::endl;
10✔
179
    this->visualizeSequence(sdfg, loop.root());
10✔
180
    this->stream_.setIndent(this->stream_.indent() - 4);
10✔
181
    this->stream_ << "}" << std::endl;
10✔
182
    this->last_comp_name_ = id;
10✔
183
    this->last_comp_name_cluster_ = "cluster_" + id;
10✔
184
}
10✔
185

186
void DotVisualizer::visualizeReturn(const StructuredSDFG& sdfg,
1✔
187
                                    const structured_control_flow::Return& return_node) {
188
    auto id = escapeDotId(return_node.element_id(), "return_");
1✔
189
    this->stream_ << id << " [shape=cds,label=\" return  \"];" << std::endl;
1✔
190
    this->last_comp_name_ = id;
1✔
191
    this->last_comp_name_cluster_.clear();
1✔
192
}
1✔
193
void DotVisualizer::visualizeBreak(const StructuredSDFG& sdfg,
1✔
194
                                   const structured_control_flow::Break& break_node) {
195
    auto id = escapeDotId(break_node.element_id(), "break_");
1✔
196
    this->stream_ << id << " [shape=cds,label=\" break  \"];" << std::endl;
1✔
197
    this->last_comp_name_ = id;
1✔
198
    this->last_comp_name_cluster_.clear();
1✔
199
}
1✔
200

201
void DotVisualizer::visualizeContinue(const StructuredSDFG& sdfg,
1✔
202
                                      const structured_control_flow::Continue& continue_node) {
203
    auto id = escapeDotId(continue_node.element_id(), "cont_");
1✔
204
    this->stream_ << id << " [shape=cds,label=\" continue  \"];"
1✔
205
                  << std::endl;
1✔
206
    this->last_comp_name_ = id;
1✔
207
    this->last_comp_name_cluster_.clear();
1✔
208
}
1✔
209

NEW
210
void DotVisualizer::visualizeMap(const StructuredSDFG& sdfg, const structured_control_flow::Map& map_node) {
×
NEW
211
    auto id = escapeDotId(map_node.element_id(), "map_");
×
NEW
212
    this->stream_ << "subgraph cluster_" << id << " {" << std::endl;
×
213
    this->stream_.setIndent(this->stream_.indent() + 4);
×
214
    this->stream_ << "style=filled;shape=box;fillcolor=white;color=black;label=\"map: ";
×
215
    this->visualizeForBounds(map_node.indvar(), map_node.init(), map_node.condition(),
×
216
                             map_node.update());
×
217
    this->stream_ << "\";" << std::endl
×
NEW
218
                  << id << " [shape=point,style=invis,label=\"\"];" << std::endl;
×
219
    this->visualizeSequence(sdfg, map_node.root());
×
220
    this->stream_.setIndent(this->stream_.indent() - 4);
×
221
    this->stream_ << "}" << std::endl;
×
NEW
222
    this->last_comp_name_ = id;
×
NEW
223
    this->last_comp_name_cluster_ = "cluster_" + id;
×
UNCOV
224
}
×
225

226
void DotVisualizer::visualize() {
173✔
227
    this->stream_.clear();
173✔
228
    this->stream_ << "digraph " << escapeDotId(this->sdfg_.name()) << " {" << std::endl;
173✔
229
    this->stream_.setIndent(4);
173✔
230
    this->stream_ << "graph [compound=true];" << std::endl;
173✔
231
    this->stream_ << "subgraph cluster_" << escapeDotId(this->sdfg_.name()) << " {" << std::endl;
173✔
232
    this->stream_.setIndent(8);
173✔
233
    this->stream_ << "node [style=filled,fillcolor=white];" << std::endl
173✔
234
                  << "style=filled;color=lightblue;label=\"\";" << std::endl;
173✔
235
    this->visualizeSequence(this->sdfg_, this->sdfg_.root());
173✔
236
    this->stream_.setIndent(4);
173✔
237
    this->stream_ << "}" << std::endl;
173✔
238
    this->stream_.setIndent(0);
173✔
239
    this->stream_ << "}" << std::endl;
173✔
240
}
173✔
241

242
}  // namespace visualizer
243
}  // namespace sdfg
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc