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

daisytuner / sdfglib / 18651924023

20 Oct 2025 12:26PM UTC coverage: 60.977% (-0.6%) from 61.539%
18651924023

push

github

web-flow
Merge pull request #286 from daisytuner/reserved-names

removes restricted globals filtering in codegen

8 of 20 new or added lines in 2 files covered. (40.0%)

342 existing lines in 17 files now uncovered.

9174 of 15045 relevant lines covered (60.98%)

92.1 hits per line

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

38.78
/src/data_flow/data_flow_graph.cpp
1
#include "sdfg/data_flow/data_flow_graph.h"
2

3
namespace sdfg {
4
namespace data_flow {
5

6
void DataFlowGraph::validate(const Function& function) const {
498✔
7
    for (auto& node : this->nodes_) {
1,217✔
8
        node.second->validate(function);
719✔
9
        if (&node.second->get_parent() != this) {
719✔
UNCOV
10
            throw InvalidSDFGException("DataFlowGraph: Node parent mismatch.");
×
11
        }
12

13
        if (auto code_node = dynamic_cast<const data_flow::CodeNode*>(node.second.get())) {
719✔
14
            if (this->in_degree(*code_node) != code_node->inputs().size()) {
194✔
15
                throw InvalidSDFGException("DataFlowGraph: Number of input edges does not match number of inputs.");
×
16
            }
17
            if (this->out_degree(*code_node) != code_node->outputs().size()) {
194✔
UNCOV
18
                throw InvalidSDFGException("DataFlowGraph: Number of output edges does not match number of outputs.");
×
19
            }
20
        }
194✔
21
    }
22
    for (auto& edge : this->edges_) {
1,009✔
23
        edge.second->validate(function);
511✔
24
    }
25
};
498✔
26

27
const Element* DataFlowGraph::get_parent() const { return this->parent_; };
481✔
28

29
Element* DataFlowGraph::get_parent() { return this->parent_; };
299✔
30

31
size_t DataFlowGraph::in_degree(const data_flow::DataFlowNode& node) const {
1,212✔
32
    return boost::in_degree(node.vertex(), this->graph_);
1,212✔
33
};
34

35
size_t DataFlowGraph::out_degree(const data_flow::DataFlowNode& node) const {
1,059✔
36
    return boost::out_degree(node.vertex(), this->graph_);
1,059✔
37
};
38

39
void DataFlowGraph::replace(const symbolic::Expression old_expression, const symbolic::Expression new_expression) {
2✔
40
    for (auto& node : this->nodes_) {
10✔
41
        node.second->replace(old_expression, new_expression);
8✔
42
    }
43

44
    for (auto& edge : this->edges_) {
8✔
45
        edge.second->replace(old_expression, new_expression);
6✔
46
    }
47
};
2✔
48

49
/***** Section: Analysis *****/
50

51
std::unordered_set<const data_flow::Tasklet*> DataFlowGraph::tasklets() const {
×
52
    std::unordered_set<const data_flow::Tasklet*> ts;
×
53
    for (auto& node : this->nodes_) {
×
UNCOV
54
        if (auto tasklet = dynamic_cast<const data_flow::Tasklet*>(node.second.get())) {
×
UNCOV
55
            ts.insert(tasklet);
×
56
        }
×
57
    }
58

UNCOV
59
    return ts;
×
UNCOV
60
};
×
61

62
std::unordered_set<data_flow::Tasklet*> DataFlowGraph::tasklets() {
53✔
63
    std::unordered_set<data_flow::Tasklet*> ts;
53✔
64
    for (auto& node : this->nodes_) {
244✔
65
        if (auto tasklet = dynamic_cast<data_flow::Tasklet*>(node.second.get())) {
191✔
66
            ts.insert(tasklet);
52✔
67
        }
52✔
68
    }
69

70
    return ts;
53✔
71
};
53✔
72

73
std::unordered_set<const data_flow::LibraryNode*> DataFlowGraph::library_nodes() const {
×
74
    std::unordered_set<const data_flow::LibraryNode*> ls;
×
75
    for (auto& node : this->nodes_) {
×
UNCOV
76
        if (auto lib_node = dynamic_cast<const data_flow::LibraryNode*>(node.second.get())) {
×
UNCOV
77
            ls.insert(lib_node);
×
78
        }
×
79
    }
80

UNCOV
81
    return ls;
×
UNCOV
82
};
×
83

84
std::unordered_set<data_flow::LibraryNode*> DataFlowGraph::library_nodes() {
16✔
85
    std::unordered_set<data_flow::LibraryNode*> ls;
16✔
86
    for (auto& node : this->nodes_) {
69✔
87
        if (auto lib_node = dynamic_cast<data_flow::LibraryNode*>(node.second.get())) {
53✔
88
            ls.insert(lib_node);
1✔
89
        }
1✔
90
    }
91

92
    return ls;
16✔
93
};
16✔
94

95
std::unordered_set<const data_flow::AccessNode*> DataFlowGraph::data_nodes() const {
×
96
    std::unordered_set<const data_flow::AccessNode*> dnodes;
×
97
    for (auto& node : this->nodes_) {
×
UNCOV
98
        if (auto access_node = dynamic_cast<const data_flow::AccessNode*>(node.second.get())) {
×
UNCOV
99
            dnodes.insert(access_node);
×
100
        }
×
101
    }
102

UNCOV
103
    return dnodes;
×
UNCOV
104
};
×
105

106
std::unordered_set<data_flow::AccessNode*> DataFlowGraph::data_nodes() {
3✔
107
    std::unordered_set<data_flow::AccessNode*> dnodes;
3✔
108
    for (auto& node : this->nodes_) {
18✔
109
        if (auto access_node = dynamic_cast<data_flow::AccessNode*>(node.second.get())) {
15✔
110
            dnodes.insert(access_node);
12✔
111
        }
12✔
112
    }
113

114
    return dnodes;
3✔
115
};
3✔
116

117
std::unordered_set<const data_flow::AccessNode*> DataFlowGraph::reads() const {
×
118
    std::unordered_set<const data_flow::AccessNode*> rs;
×
119
    for (auto& node : this->nodes_) {
×
120
        if (auto access_node = dynamic_cast<const data_flow::AccessNode*>(node.second.get())) {
×
121
            if (this->out_degree(*access_node) > 0) {
×
UNCOV
122
                rs.insert(access_node);
×
UNCOV
123
            }
×
124
        }
×
125
    }
126

127
    return rs;
×
128
};
×
129

130
std::unordered_set<const data_flow::AccessNode*> DataFlowGraph::writes() const {
×
131
    std::unordered_set<const data_flow::AccessNode*> ws;
×
132
    for (auto& node : this->nodes_) {
×
133
        if (auto access_node = dynamic_cast<const data_flow::AccessNode*>(node.second.get())) {
×
134
            if (this->in_degree(*access_node) > 0) {
×
UNCOV
135
                ws.insert(access_node);
×
UNCOV
136
            }
×
137
        }
×
138
    }
139

140
    return ws;
×
141
};
×
142

143
std::unordered_set<const data_flow::DataFlowNode*> DataFlowGraph::sources() const {
×
144
    std::unordered_set<const data_flow::DataFlowNode*> ss;
×
145
    for (auto& node : this->nodes_) {
×
UNCOV
146
        if (this->in_degree(*node.second) == 0) {
×
UNCOV
147
            ss.insert(node.second.get());
×
148
        }
×
149
    }
150

151
    return ss;
×
152
};
×
153

154
std::unordered_set<data_flow::DataFlowNode*> DataFlowGraph::sources() {
×
155
    std::unordered_set<data_flow::DataFlowNode*> ss;
×
156
    for (auto& node : this->nodes_) {
×
UNCOV
157
        if (this->in_degree(*node.second) == 0) {
×
UNCOV
158
            ss.insert(node.second.get());
×
159
        }
×
160
    }
161

162
    return ss;
×
163
};
×
164

165
std::unordered_set<const data_flow::DataFlowNode*> DataFlowGraph::sinks() const {
×
166
    std::unordered_set<const data_flow::DataFlowNode*> ss;
×
167
    for (auto& node : this->nodes_) {
×
UNCOV
168
        if (this->out_degree(*node.second) == 0) {
×
UNCOV
169
            ss.insert(node.second.get());
×
170
        }
×
171
    }
172

173
    return ss;
×
174
};
×
175

176
std::unordered_set<data_flow::DataFlowNode*> DataFlowGraph::sinks() {
×
177
    std::unordered_set<data_flow::DataFlowNode*> ss;
×
178
    for (auto& node : this->nodes_) {
×
UNCOV
179
        if (this->out_degree(*node.second) == 0) {
×
UNCOV
180
            ss.insert(node.second.get());
×
181
        }
×
182
    }
183

184
    return ss;
×
UNCOV
185
};
×
186

187
std::unordered_set<const data_flow::DataFlowNode*> DataFlowGraph::predecessors(const data_flow::DataFlowNode& node
×
188
) const {
UNCOV
189
    std::unordered_set<const data_flow::DataFlowNode*> ss;
×
UNCOV
190
    for (auto& edge : this->in_edges(node)) {
×
191
        ss.insert(&edge.src());
×
192
    }
193

194
    return ss;
×
UNCOV
195
};
×
196

197
std::unordered_set<const data_flow::DataFlowNode*> DataFlowGraph::successors(const data_flow::DataFlowNode& node
×
198
) const {
UNCOV
199
    std::unordered_set<const data_flow::DataFlowNode*> ss;
×
UNCOV
200
    for (auto& edge : this->out_edges(node)) {
×
201
        ss.insert(&edge.dst());
×
202
    }
203

UNCOV
204
    return ss;
×
UNCOV
205
};
×
206

207
std::list<const data_flow::DataFlowNode*> DataFlowGraph::topological_sort() const {
34✔
208
    std::list<graph::Vertex> order = graph::topological_sort(this->graph_);
34✔
209

210
    std::list<const data_flow::DataFlowNode*> topo_nodes;
34✔
211
    for (auto& vertex : order) {
136✔
212
        topo_nodes.push_back(this->nodes_.at(vertex).get());
102✔
213
    }
214

215
    return topo_nodes;
34✔
216
};
34✔
217

218
std::list<data_flow::DataFlowNode*> DataFlowGraph::topological_sort() {
413✔
219
    std::list<graph::Vertex> order = graph::topological_sort(this->graph_);
413✔
220

221
    std::list<data_flow::DataFlowNode*> topo_nodes;
413✔
222
    for (auto& vertex : order) {
1,118✔
223
        topo_nodes.push_back(this->nodes_.at(vertex).get());
705✔
224
    }
225

226
    return topo_nodes;
413✔
227
};
413✔
228

229
std::unordered_map<std::string, const data_flow::AccessNode*> DataFlowGraph::dominators() const {
×
230
    std::unordered_map<std::string, const data_flow::AccessNode*> frontier;
×
231
    for (auto& node : this->topological_sort()) {
×
232
        if (auto access_node = dynamic_cast<const data_flow::AccessNode*>(node)) {
×
233
            if (frontier.find(access_node->data()) == frontier.end()) {
×
UNCOV
234
                frontier[access_node->data()] = access_node;
×
UNCOV
235
            }
×
236
        }
×
237
    }
238

239
    return frontier;
×
240
};
×
241

242
std::unordered_map<std::string, const data_flow::AccessNode*> DataFlowGraph::post_dominators() const {
×
243
    std::unordered_map<std::string, const data_flow::AccessNode*> frontier;
×
244
    for (auto& node : this->topological_sort()) {
×
UNCOV
245
        if (auto access_node = dynamic_cast<const data_flow::AccessNode*>(node)) {
×
UNCOV
246
            frontier[access_node->data()] = access_node;
×
247
        }
×
248
    }
249

UNCOV
250
    return frontier;
×
UNCOV
251
};
×
252

253
std::unordered_map<std::string, data_flow::AccessNode*> DataFlowGraph::post_dominators() {
6✔
254
    std::unordered_map<std::string, data_flow::AccessNode*> frontier;
6✔
255
    for (auto& node : this->topological_sort()) {
32✔
256
        if (auto access_node = dynamic_cast<data_flow::AccessNode*>(node)) {
26✔
257
            frontier[access_node->data()] = access_node;
20✔
258
        }
20✔
259
    }
260

261
    return frontier;
6✔
262
};
6✔
263

264
auto DataFlowGraph::all_simple_paths(const data_flow::DataFlowNode& src, const data_flow::DataFlowNode& dst) const {
×
265
    std::list<std::list<graph::Edge>> all_paths_raw = graph::all_simple_paths(this->graph_, src.vertex(), dst.vertex());
×
266

267
    std::list<std::list<std::reference_wrapper<data_flow::Memlet>>> all_paths;
×
268
    for (auto& path_raw : all_paths_raw) {
×
UNCOV
269
        std::list<std::reference_wrapper<data_flow::Memlet>> path;
×
270
        for (auto& edge : path_raw) {
×
271
            path.push_back(*this->edges_.at(edge));
×
272
        }
273
        all_paths.push_back(path);
×
274
    }
×
275

UNCOV
276
    return all_paths;
×
UNCOV
277
};
×
278

279
const std::pair<size_t, const std::unordered_map<const data_flow::DataFlowNode*, size_t>> DataFlowGraph::
280
    weakly_connected_components() const {
2✔
281
    auto ccs_vertex = graph::weakly_connected_components(this->graph_);
2✔
282

283
    std::unordered_map<const data_flow::DataFlowNode*, size_t> ccs;
2✔
284
    for (auto& entry : ccs_vertex.second) {
17✔
285
        ccs[this->nodes_.at(entry.first).get()] = entry.second;
15✔
286
    }
287

288
    return {ccs_vertex.first, ccs};
2✔
289
};
2✔
290

291
} // namespace data_flow
292
} // 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