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

daisytuner / sdfglib / 15044057891

15 May 2025 11:42AM UTC coverage: 59.37% (+1.8%) from 57.525%
15044057891

push

github

web-flow
Merge pull request #14 from daisytuner/sanitizers

enables sanitizer on unit tests

63 of 67 new or added lines in 47 files covered. (94.03%)

570 existing lines in 62 files now uncovered.

7356 of 12390 relevant lines covered (59.37%)

505.93 hits per line

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

42.94
/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
DataFlowGraph::DataFlowGraph(Element& parent)
600✔
7
    : parent_(&parent) {
600✔
8

9
      };
600✔
10

11
const Element& DataFlowGraph::get_parent() const { return *this->parent_; };
×
12

13
Element& DataFlowGraph::get_parent() { return *this->parent_; };
1✔
14

15
size_t DataFlowGraph::in_degree(const data_flow::DataFlowNode& node) const {
5,045✔
16
    return boost::in_degree(node.vertex(), this->graph_);
5,045✔
17
};
18

19
size_t DataFlowGraph::out_degree(const data_flow::DataFlowNode& node) const {
5,039✔
20
    return boost::out_degree(node.vertex(), this->graph_);
5,039✔
21
};
22

23
void DataFlowGraph::replace(const symbolic::Expression& old_expression,
89✔
24
                            const symbolic::Expression& new_expression) {
25
    for (auto& node : this->nodes_) {
393✔
26
        node.second->replace(old_expression, new_expression);
304✔
27
    }
28

29
    for (auto& edge : this->edges_) {
312✔
30
        edge.second->replace(old_expression, new_expression);
223✔
31
    }
32
};
89✔
33

34
/***** Section: Analysis *****/
35

36
std::unordered_set<const data_flow::Tasklet*> DataFlowGraph::tasklets() const {
31✔
37
    std::unordered_set<const data_flow::Tasklet*> ts;
31✔
38
    for (auto& node : this->nodes_) {
123✔
39
        if (auto tasklet = dynamic_cast<const data_flow::Tasklet*>(node.second.get())) {
92✔
40
            ts.insert(tasklet);
32✔
41
        }
32✔
42
    }
43

44
    return ts;
31✔
45
};
31✔
46

47
std::unordered_set<const data_flow::AccessNode*> DataFlowGraph::data_nodes() const {
×
48
    std::unordered_set<const data_flow::AccessNode*> dnodes;
×
49
    for (auto& node : this->nodes_) {
×
50
        if (auto access_node = dynamic_cast<const data_flow::AccessNode*>(node.second.get())) {
×
51
            dnodes.insert(access_node);
×
UNCOV
52
        }
×
53
    }
54

55
    return dnodes;
×
56
};
×
57

58
std::unordered_set<data_flow::AccessNode*> DataFlowGraph::data_nodes() {
3✔
59
    std::unordered_set<data_flow::AccessNode*> dnodes;
3✔
60
    for (auto& node : this->nodes_) {
16✔
61
        if (auto access_node = dynamic_cast<data_flow::AccessNode*>(node.second.get())) {
13✔
62
            dnodes.insert(access_node);
9✔
63
        }
9✔
64
    }
65

66
    return dnodes;
3✔
67
};
3✔
68

69
std::unordered_set<const data_flow::AccessNode*> DataFlowGraph::reads() const {
×
70
    std::unordered_set<const data_flow::AccessNode*> rs;
×
71
    for (auto& node : this->nodes_) {
×
72
        if (auto access_node = dynamic_cast<const data_flow::AccessNode*>(node.second.get())) {
×
73
            if (this->out_degree(*access_node) > 0) {
×
74
                rs.insert(access_node);
×
UNCOV
75
            }
×
UNCOV
76
        }
×
77
    }
78

79
    return rs;
×
80
};
×
81

82
std::unordered_set<const data_flow::AccessNode*> DataFlowGraph::writes() const {
×
83
    std::unordered_set<const data_flow::AccessNode*> ws;
×
84
    for (auto& node : this->nodes_) {
×
85
        if (auto access_node = dynamic_cast<const data_flow::AccessNode*>(node.second.get())) {
×
86
            if (this->in_degree(*access_node) > 0) {
×
87
                ws.insert(access_node);
×
UNCOV
88
            }
×
UNCOV
89
        }
×
90
    }
91

92
    return ws;
×
93
};
×
94

95
std::unordered_set<const data_flow::DataFlowNode*> DataFlowGraph::sources() const {
×
96
    std::unordered_set<const data_flow::DataFlowNode*> ss;
×
97
    for (auto& node : this->nodes_) {
×
98
        if (this->in_degree(*node.second) == 0) {
×
99
            ss.insert(node.second.get());
×
UNCOV
100
        }
×
101
    }
102

103
    return ss;
×
104
};
×
105

106
std::unordered_set<data_flow::DataFlowNode*> DataFlowGraph::sources() {
3✔
107
    std::unordered_set<data_flow::DataFlowNode*> ss;
3✔
108
    for (auto& node : this->nodes_) {
12✔
109
        if (this->in_degree(*node.second) == 0) {
9✔
110
            ss.insert(node.second.get());
3✔
111
        }
3✔
112
    }
113

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

117
std::unordered_set<const data_flow::DataFlowNode*> DataFlowGraph::sinks() const {
×
118
    std::unordered_set<const data_flow::DataFlowNode*> ss;
×
119
    for (auto& node : this->nodes_) {
×
120
        if (this->out_degree(*node.second) == 0) {
×
121
            ss.insert(node.second.get());
×
UNCOV
122
        }
×
123
    }
124

125
    return ss;
×
126
};
×
127

128
std::unordered_set<data_flow::DataFlowNode*> DataFlowGraph::sinks() {
×
129
    std::unordered_set<data_flow::DataFlowNode*> ss;
×
130
    for (auto& node : this->nodes_) {
×
131
        if (this->out_degree(*node.second) == 0) {
×
132
            ss.insert(node.second.get());
×
UNCOV
133
        }
×
134
    }
135

136
    return ss;
×
137
};
×
138

139
std::unordered_set<const data_flow::DataFlowNode*> DataFlowGraph::predecessors(
×
140
    const data_flow::DataFlowNode& node) const {
141
    std::unordered_set<const data_flow::DataFlowNode*> ss;
×
142
    for (auto& edge : this->in_edges(node)) {
×
143
        ss.insert(&edge.src());
×
144
    }
145

146
    return ss;
×
147
};
×
148

149
std::unordered_set<const data_flow::DataFlowNode*> DataFlowGraph::successors(
×
150
    const data_flow::DataFlowNode& node) const {
151
    std::unordered_set<const data_flow::DataFlowNode*> ss;
×
152
    for (auto& edge : this->out_edges(node)) {
×
153
        ss.insert(&edge.dst());
×
154
    }
155

156
    return ss;
×
157
};
×
158

159
std::list<const data_flow::DataFlowNode*> DataFlowGraph::topological_sort() const {
3✔
160
    std::list<graph::Vertex> order = graph::topological_sort(this->graph_);
3✔
161

162
    std::list<const data_flow::DataFlowNode*> topo_nodes;
3✔
163
    for (auto& vertex : order) {
12✔
164
        topo_nodes.push_back(this->nodes_.at(vertex).get());
9✔
165
    }
166

167
    return topo_nodes;
3✔
168
};
3✔
169

170
std::list<data_flow::DataFlowNode*> DataFlowGraph::topological_sort() {
1,981✔
171
    std::list<graph::Vertex> order = graph::topological_sort(this->graph_);
1,981✔
172

173
    std::list<data_flow::DataFlowNode*> topo_nodes;
1,981✔
174
    for (auto& vertex : order) {
9,154✔
175
        topo_nodes.push_back(this->nodes_.at(vertex).get());
7,173✔
176
    }
177

178
    return topo_nodes;
1,981✔
179
};
1,981✔
180

181
std::unordered_map<std::string, const data_flow::AccessNode*> DataFlowGraph::dominators() const {
×
182
    std::unordered_map<std::string, const data_flow::AccessNode*> frontier;
×
183
    for (auto& node : this->topological_sort()) {
×
184
        if (auto access_node = dynamic_cast<const data_flow::AccessNode*>(node)) {
×
185
            if (frontier.find(access_node->data()) == frontier.end()) {
×
186
                frontier[access_node->data()] = access_node;
×
UNCOV
187
            }
×
UNCOV
188
        }
×
189
    }
190

191
    return frontier;
×
192
};
×
193

194
std::unordered_map<std::string, const data_flow::AccessNode*> DataFlowGraph::post_dominators()
×
195
    const {
196
    std::unordered_map<std::string, const data_flow::AccessNode*> frontier;
×
197
    for (auto& node : this->topological_sort()) {
×
198
        if (auto access_node = dynamic_cast<const data_flow::AccessNode*>(node)) {
×
199
            frontier[access_node->data()] = access_node;
×
UNCOV
200
        }
×
201
    }
202

203
    return frontier;
×
204
};
×
205

206
std::unordered_map<std::string, data_flow::AccessNode*> DataFlowGraph::post_dominators() {
3✔
207
    std::unordered_map<std::string, data_flow::AccessNode*> frontier;
3✔
208
    for (auto& node : this->topological_sort()) {
12✔
209
        if (auto access_node = dynamic_cast<data_flow::AccessNode*>(node)) {
9✔
210
            frontier[access_node->data()] = access_node;
6✔
211
        }
6✔
212
    }
213

214
    return frontier;
3✔
215
};
3✔
216

217
auto DataFlowGraph::all_simple_paths(const data_flow::DataFlowNode& src,
×
218
                                     const data_flow::DataFlowNode& dst) const {
219
    std::list<std::list<graph::Edge>> all_paths_raw =
220
        graph::all_simple_paths(this->graph_, src.vertex(), dst.vertex());
×
221

222
    std::list<std::list<std::reference_wrapper<data_flow::Memlet>>> all_paths;
×
223
    for (auto& path_raw : all_paths_raw) {
×
224
        std::list<std::reference_wrapper<data_flow::Memlet>> path;
×
225
        for (auto& edge : path_raw) {
×
226
            path.push_back(*this->edges_.at(edge));
×
227
        }
228
        all_paths.push_back(path);
×
229
    }
×
230

231
    return all_paths;
×
232
};
×
233

234
const std::pair<size_t, const std::unordered_map<const data_flow::DataFlowNode*, size_t>>
235
DataFlowGraph::weakly_connected_components() const {
×
236
    auto ccs_vertex = graph::weakly_connected_components(this->graph_);
×
237

238
    std::unordered_map<const data_flow::DataFlowNode*, size_t> ccs;
×
239
    for (auto& entry : ccs_vertex.second) {
×
240
        ccs[this->nodes_.at(entry.first).get()] = entry.second;
×
241
    }
242

243
    return {ccs_vertex.first, ccs};
×
244
};
×
245

246
/***** Section: Serialization *****/
247

248
std::unique_ptr<DataFlowGraph> DataFlowGraph::clone(Element& parent) const {
82✔
249
    auto new_graph = std::make_unique<DataFlowGraph>(parent);
82✔
250

251
    std::unordered_map<graph::Vertex, graph::Vertex> node_mapping;
82✔
252
    for (auto& entry : this->nodes_) {
303✔
253
        auto vertex = boost::add_vertex(new_graph->graph_);
221✔
254
        auto res = new_graph->nodes_.insert({vertex, entry.second->clone(vertex, *new_graph)});
221✔
255
        node_mapping.insert({entry.first, vertex});
221✔
256
    }
257

258
    for (auto& entry : this->edges_) {
248✔
259
        auto src = node_mapping[entry.second->src().vertex()];
166✔
260
        auto dst = node_mapping[entry.second->dst().vertex()];
166✔
261

262
        auto edge = boost::add_edge(src, dst, new_graph->graph_);
166✔
263

264
        auto res = new_graph->edges_.insert(
332✔
265
            {edge.first, entry.second->clone(edge.first, *new_graph, *new_graph->nodes_[src],
166✔
266
                                             *new_graph->nodes_[dst])});
166✔
267
    }
268

269
    return std::move(new_graph);
82✔
270
};
82✔
271

272
}  // namespace data_flow
273
}  // 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