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

daisytuner / sdfglib / 15494289007

06 Jun 2025 03:36PM UTC coverage: 57.304% (-0.4%) from 57.704%
15494289007

push

github

web-flow
Merge pull request #60 from daisytuner/kernels

removes kernel node in favor of function types

78 of 99 new or added lines in 11 files covered. (78.79%)

91 existing lines in 14 files now uncovered.

7583 of 13233 relevant lines covered (57.3%)

116.04 hits per line

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

87.7
/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/schedule.h"
10
#include "sdfg/structured_control_flow/control_flow_node.h"
11
#include "sdfg/structured_control_flow/sequence.h"
12
#include "sdfg/structured_sdfg.h"
13

14
namespace sdfg {
15
namespace visualizer {
16

17
void DotVisualizer::visualizeBlock(Schedule& schedule, structured_control_flow::Block& block) {
176✔
18
    this->stream_ << "subgraph cluster_" << block.element_id() << " {" << std::endl;
176✔
19
    this->stream_.setIndent(this->stream_.indent() + 4);
176✔
20
    this->stream_ << "style=filled;shape=box;fillcolor=white;color=black;label=\"\";" << std::endl;
176✔
21
    this->last_comp_name_cluster_ = "cluster_" + block.element_id();
176✔
22
    if (block.dataflow().nodes().empty()) {
176✔
23
        this->stream_ << block.element_id() << " [shape=point,style=invis,label=\"\"];"
4✔
24
                      << std::endl;
2✔
25
        this->stream_.setIndent(this->stream_.indent() - 4);
2✔
26
        this->stream_ << "}" << std::endl;
2✔
27
        this->last_comp_name_ = block.element_id();
2✔
28
        return;
2✔
29
    }
30
    this->last_comp_name_.clear();
174✔
31
    std::list<data_flow::DataFlowNode*> nodes = block.dataflow().topological_sort();
174✔
32
    for (data_flow::DataFlowNode* node : nodes) {
535✔
33
        if (const data_flow::Tasklet* tasklet = dynamic_cast<data_flow::Tasklet*>(node)) {
361✔
34
            this->stream_ << tasklet->element_id() << " [shape=octagon,label=\""
350✔
35
                          << tasklet->output(0).first << " = ";
175✔
36
            this->visualizeTasklet(*tasklet);
175✔
37
            this->stream_ << "\"];" << std::endl;
175✔
38
            for (data_flow::Memlet& iedge : block.dataflow().in_edges(*tasklet)) {
188✔
39
                data_flow::AccessNode const& src =
13✔
40
                    dynamic_cast<data_flow::AccessNode const&>(iedge.src());
13✔
41
                this->stream_ << src.element_id() << " -> " << tasklet->element_id()
26✔
42
                              << " [label=\"   " << iedge.dst_conn() << " = " << src.data();
13✔
43
                if (!symbolic::is_nv(symbolic::symbol(src.data()))) {
13✔
44
                    types::IType const& type = schedule.sdfg().type(src.data());
13✔
45
                    this->visualizeSubset(schedule.sdfg(), type, iedge.subset());
13✔
46
                }
13✔
47
                this->stream_ << "   \"];" << std::endl;
13✔
48
            }
49
            for (data_flow::Memlet& oedge : block.dataflow().out_edges(*tasklet)) {
350✔
50
                data_flow::AccessNode const& dst =
175✔
51
                    dynamic_cast<data_flow::AccessNode const&>(oedge.dst());
175✔
52
                types::IType const& type = schedule.sdfg().type(dst.data());
175✔
53
                this->stream_ << tasklet->element_id() << " -> " << dst.element_id()
350✔
54
                              << " [label=\"   " << dst.data();
175✔
55
                this->visualizeSubset(schedule.sdfg(), type, oedge.subset());
175✔
56
                this->stream_ << " = " << oedge.src_conn() << "   \"];" << std::endl;
175✔
57
            }
58
            if (this->last_comp_name_.empty()) this->last_comp_name_ = tasklet->element_id();
175✔
59
        } else if (const data_flow::AccessNode* access_node =
361✔
60
                       dynamic_cast<data_flow::AccessNode*>(node)) {
186✔
61
            bool source = false, sink = false;
186✔
62
            for (data_flow::Memlet& edge : block.dataflow().out_edges(*access_node)) {
186✔
63
                if ((source = (edge.src_conn() == "void"))) break;
12✔
64
            }
65
            for (data_flow::Memlet& edge : block.dataflow().in_edges(*access_node)) {
186✔
66
                if ((sink = (edge.dst_conn() == "void"))) break;
175✔
67
            }
68
            if (!source && !sink) continue;
186✔
69
            this->stream_ << access_node->element_id() << " [";
186✔
70
            if (!schedule.sdfg().is_internal(access_node->data())) this->stream_ << "penwidth=3.0,";
186✔
71
            if (schedule.sdfg().is_transient(access_node->data()))
186✔
72
                this->stream_ << "style=\"dashed,filled\",";
176✔
73
            this->stream_ << "label=\"" << access_node->data() << "\"];" << std::endl;
186✔
74
        } else if (const data_flow::LibraryNode* libnode =
186✔
UNCOV
75
                       dynamic_cast<data_flow::LibraryNode*>(node)) {
×
UNCOV
76
            this->stream_ << libnode->element_id() << " [shape=doubleoctagon,label=\"";
×
UNCOV
77
            this->visualizeLibraryNode(libnode->call());
×
UNCOV
78
            this->stream_ << "\"];" << std::endl;
×
UNCOV
79
            if (this->last_comp_name_.empty()) this->last_comp_name_ = libnode->element_id();
×
UNCOV
80
        }
×
81
    }
82
    this->stream_.setIndent(this->stream_.indent() - 4);
174✔
83
    this->stream_ << "}" << std::endl;
174✔
84
}
176✔
85

86
void DotVisualizer::visualizeSequence(Schedule& schedule,
184✔
87
                                      structured_control_flow::Sequence& sequence) {
88
    std::string last_comp_name_tmp, last_comp_name_cluster_tmp;
184✔
89
    for (size_t i = 0; i < sequence.size(); ++i) {
374✔
90
        std::pair<ControlFlowNode&, Transition&> child = sequence.at(i);
190✔
91
        this->visualizeNode(schedule, child.first);
190✔
92
        if ((i > 0) && !last_comp_name_tmp.empty() && !this->last_comp_name_.empty()) {
190✔
93
            this->stream_ << last_comp_name_tmp << " -> " << this->last_comp_name_ << " [";
6✔
94
            if (!last_comp_name_cluster_tmp.empty())
6✔
95
                this->stream_ << "ltail=\"" << last_comp_name_cluster_tmp << "\",";
6✔
96
            if (!this->last_comp_name_cluster_.empty())
6✔
97
                this->stream_ << "lhead=\"" << this->last_comp_name_cluster_ << "\",";
4✔
98
            this->stream_ << "minlen=3]"
6✔
99
                          << ";" << std::endl;
6✔
100
        }
6✔
101
        last_comp_name_tmp = this->last_comp_name_;
190✔
102
        this->last_comp_name_.clear();
190✔
103
        last_comp_name_cluster_tmp = this->last_comp_name_cluster_;
190✔
104
        this->last_comp_name_cluster_.clear();
190✔
105
    }
190✔
106
}
184✔
107

108
void DotVisualizer::visualizeIfElse(Schedule& schedule, structured_control_flow::IfElse& if_else) {
3✔
109
    this->stream_ << "subgraph cluster_" << if_else.element_id() << " {" << std::endl;
3✔
110
    this->stream_.setIndent(this->stream_.indent() + 4);
3✔
111
    this->stream_ << "style=filled;shape=box;fillcolor=white;color=black;label=\"if:\";"
6✔
112
                  << std::endl
3✔
113
                  << if_else.element_id() << " [shape=point,style=invis,label=\"\"];" << std::endl;
3✔
114
    for (size_t i = 0; i < if_else.size(); ++i) {
9✔
115
        this->stream_ << "subgraph cluster_" << if_else.element_id() << "_" << std::to_string(i)
12✔
116
                      << " {" << std::endl;
6✔
117
        this->stream_.setIndent(this->stream_.indent() + 4);
6✔
118
        this->stream_ << "style=filled;shape=box;fillcolor=white;color=black;label=\""
12✔
119
                      << this->expression(if_else.at(i).second->__str__()) << "\";" << std::endl;
6✔
120
        this->visualizeSequence(schedule, if_else.at(i).first);
6✔
121
        this->stream_.setIndent(this->stream_.indent() - 4);
6✔
122
        this->stream_ << "}" << std::endl;
6✔
123
    }
6✔
124
    this->stream_.setIndent(this->stream_.indent() - 4);
3✔
125
    this->stream_ << "}" << std::endl;
3✔
126
    this->last_comp_name_ = if_else.element_id();
3✔
127
    this->last_comp_name_cluster_ = "cluster_" + if_else.element_id();
3✔
128
}
3✔
129

130
void DotVisualizer::visualizeWhile(Schedule& schedule, structured_control_flow::While& while_loop) {
2✔
131
    this->stream_ << "subgraph cluster_" << while_loop.element_id() << " {" << std::endl;
2✔
132
    this->stream_.setIndent(this->stream_.indent() + 4);
2✔
133
    this->stream_ << "style=filled;shape=box;fillcolor=white;color=black;label=\"while:\";"
4✔
134
                  << std::endl
2✔
135
                  << while_loop.element_id() << " [shape=point,style=invis,label=\"\"];"
2✔
136
                  << std::endl;
2✔
137
    this->visualizeSequence(schedule, while_loop.root());
2✔
138
    this->stream_.setIndent(this->stream_.indent() - 4);
2✔
139
    this->stream_ << "}" << std::endl;
2✔
140
    this->last_comp_name_ = while_loop.element_id();
2✔
141
    this->last_comp_name_cluster_ = "cluster_" + while_loop.element_id();
2✔
142
}
2✔
143

144
void DotVisualizer::visualizeFor(Schedule& schedule, structured_control_flow::For& loop) {
6✔
145
    this->stream_ << "subgraph cluster_" << loop.element_id() << " {" << std::endl;
6✔
146
    this->stream_.setIndent(this->stream_.indent() + 4);
6✔
147
    this->stream_ << "style=filled;shape=box;fillcolor=white;color=black;label=\"for: ";
6✔
148
    this->visualizeForBounds(loop.indvar(), loop.init(), loop.condition(), loop.update());
6✔
149
    LoopSchedule loop_schedule = schedule.loop_schedule(&loop);
6✔
150
    if (loop_schedule == LoopSchedule::VECTORIZATION) this->stream_ << " (vectorized)";
6✔
151
    if (loop_schedule == LoopSchedule::MULTICORE) this->stream_ << " (parallelized)";
6✔
152
    this->stream_ << "\";" << std::endl
12✔
153
                  << loop.element_id() << " [shape=point,style=invis,label=\"\"];" << std::endl;
6✔
154
    this->visualizeSequence(schedule, loop.root());
6✔
155
    this->stream_.setIndent(this->stream_.indent() - 4);
6✔
156
    this->stream_ << "}" << std::endl;
6✔
157
    this->last_comp_name_ = loop.element_id();
6✔
158
    this->last_comp_name_cluster_ = "cluster_" + loop.element_id();
6✔
159
}
6✔
160

161
void DotVisualizer::visualizeReturn(Schedule& schedule,
1✔
162
                                    structured_control_flow::Return& return_node) {
163
    this->stream_ << return_node.element_id() << " [shape=cds,label=\" return  \"];" << std::endl;
1✔
164
    this->last_comp_name_ = return_node.element_id();
1✔
165
    this->last_comp_name_cluster_.clear();
1✔
166
}
1✔
167
void DotVisualizer::visualizeBreak(Schedule& schedule, structured_control_flow::Break& break_node) {
1✔
168
    this->stream_ << break_node.element_id() << " [shape=cds,label=\" break  \"];" << std::endl;
1✔
169
    this->last_comp_name_ = break_node.element_id();
1✔
170
    this->last_comp_name_cluster_.clear();
1✔
171
}
1✔
172

173
void DotVisualizer::visualizeContinue(Schedule& schedule,
1✔
174
                                      structured_control_flow::Continue& continue_node) {
175
    this->stream_ << continue_node.element_id() << " [shape=cds,label=\" continue  \"];"
2✔
176
                  << std::endl;
1✔
177
    this->last_comp_name_ = continue_node.element_id();
1✔
178
    this->last_comp_name_cluster_.clear();
1✔
179
}
1✔
180

UNCOV
181
void DotVisualizer::visualizeMap(Schedule& schedule, structured_control_flow::Map& map_node) {
×
UNCOV
182
    this->stream_ << "subgraph cluster_" << map_node.element_id() << " {" << std::endl;
×
183
    this->stream_.setIndent(this->stream_.indent() + 4);
×
184
    this->stream_ << "style=filled;shape=box;fillcolor=white;color=black;label=\"map: ";
×
185
    this->stream_ << map_node.indvar()->get_name() << "[0:";
×
186
    this->stream_ << map_node.num_iterations()->__str__() << "];";
×
187
    LoopSchedule loop_schedule = schedule.loop_schedule(&map_node);
×
188
    if (loop_schedule == LoopSchedule::VECTORIZATION) this->stream_ << " (vectorized)";
×
189
    if (loop_schedule == LoopSchedule::MULTICORE) this->stream_ << " (parallelized)";
×
190
    this->stream_ << "\";" << std::endl
×
191
                  << map_node.element_id() << " [shape=point,style=invis,label=\"\"];" << std::endl;
×
192
    this->visualizeSequence(schedule, map_node.root());
×
193
    this->stream_.setIndent(this->stream_.indent() - 4);
×
194
    this->stream_ << "}" << std::endl;
×
195
    this->last_comp_name_ = map_node.element_id();
×
196
    this->last_comp_name_cluster_ = "cluster_" + map_node.element_id();
×
197
}
×
198

199
void DotVisualizer::visualize() {
170✔
200
    this->stream_.clear();
170✔
201
    this->stream_ << "digraph " << this->schedule_.name() << " {" << std::endl;
170✔
202
    this->stream_.setIndent(4);
170✔
203
    this->stream_ << "graph [compound=true];" << std::endl;
170✔
204
    for (size_t i = 0; i < schedule_.size(); ++i) {
340✔
205
        StructuredSDFG const& sdfg = this->schedule_.schedule(i).sdfg();
170✔
206
        StructuredSDFG& function = this->schedule_.schedule(i).builder().subject();
170✔
207
        this->stream_ << "subgraph cluster_" << sdfg.name() << " {" << std::endl;
170✔
208
        this->stream_.setIndent(8);
170✔
209
        this->stream_ << "node [style=filled,fillcolor=white];" << std::endl
170✔
210
                      << "style=filled;color=lightblue;label=\"";
170✔
211
        std::string condition = this->expression(this->schedule_.condition(i)->__str__());
170✔
212
        if (condition != "True") this->stream_ << condition;
170✔
213
        this->stream_ << "\";" << std::endl;
170✔
214
        this->visualizeSequence(this->schedule_.schedule(i), function.root());
170✔
215
        this->stream_.setIndent(4);
170✔
216
        this->stream_ << "}" << std::endl;
170✔
217
    }
170✔
218
    this->stream_.setIndent(0);
170✔
219
    this->stream_ << "}" << std::endl;
170✔
220
}
170✔
221

222
}  // namespace visualizer
223
}  // 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