• 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

99.37
/src/graph/graph.cpp
1
#include "sdfg/graph/graph.h"
2

3
namespace sdfg {
4
namespace graph {
5

6
const ReverseGraph reverse(const Graph& graph) { return boost::reverse_graph<Graph>(graph); };
164✔
7

8
const std::tuple<std::unique_ptr<const UndirectedGraph>, const std::unordered_map<Vertex, Vertex>,
9
                 const std::unordered_map<Vertex, Vertex>>
10
undirected(const Graph& graph) {
2✔
11
    auto undirected_graph = std::make_unique<UndirectedGraph>();
2✔
12
    std::unordered_map<Vertex, Vertex> mapping;
2✔
13
    std::unordered_map<Vertex, Vertex> reverse_mapping;
2✔
14

15
    boost::graph_traits<Graph>::vertex_iterator vi, vend;
2✔
16
    for (boost::tie(vi, vend) = boost::vertices(graph); vi != vend; ++vi) {
7✔
17
        auto new_vertex = boost::add_vertex(*undirected_graph);
5✔
18
        mapping.emplace(*vi, new_vertex);
5✔
19
        reverse_mapping.emplace(new_vertex, *vi);
5✔
20
    }
5✔
21

22
    auto [eb, ee] = boost::edges(graph);
2✔
23
    auto edges = std::ranges::subrange(eb, ee);
4✔
24
    for (const auto& edge : edges) {
4✔
25
        const auto& u = boost::source(edge, graph);
2✔
26
        const auto& v = boost::target(edge, graph);
2✔
27
        boost::add_edge(mapping.at(u), mapping.at(v), *undirected_graph);
2✔
28
    }
29

30
    return {std::move(undirected_graph), mapping, reverse_mapping};
2✔
31
};
2✔
32

33
const std::list<Vertex> depth_first_search(const Graph& graph, const graph::Vertex start) {
1✔
34
    std::list<Vertex> nodes;
1✔
35
    std::list<Edge> back_edges;
1✔
36
    DFSVisitor visitor(back_edges, nodes);
1✔
37

38
    std::unordered_map<graph::Vertex, boost::default_color_type> vertex_colors;
1✔
39
    boost::depth_first_search(graph, visitor, boost::make_assoc_property_map(vertex_colors), start);
1✔
40

41
    return nodes;
1✔
42
};
1✔
43

44
std::pair<int, std::unordered_map<Vertex, size_t>> strongly_connected_components(
1✔
45
    const Graph& graph) {
46
    IndexMap vertex_index_map;
1✔
47
    boost::associative_property_map<IndexMap> boost_index_map(vertex_index_map);
1✔
48
    boost::graph_traits<Graph>::vertex_iterator vi, vend;
1✔
49
    size_t i = 0;
1✔
50
    for (boost::tie(vi, vend) = boost::vertices(graph); vi != vend; ++vi, ++i) {
4✔
51
        boost::put(boost_index_map, *vi, i);
3✔
52
    }
3✔
53

54
    std::unordered_map<Vertex, size_t> component_map;
1✔
55
    boost::associative_property_map<IndexMap> boost_component_map(component_map);
1✔
56

57
    size_t num_ccs = boost::strong_components(graph, boost_component_map,
1✔
58
                                              boost::vertex_index_map(boost_index_map));
1✔
59

60
    return {num_ccs, component_map};
1✔
61
};
1✔
62

63
std::pair<size_t, const std::unordered_map<Vertex, size_t>> weakly_connected_components(
1✔
64
    const Graph& graph) {
65
    const auto& undirected_graph = undirected(graph);
1✔
66

67
    IndexMap vertex_index_map;
1✔
68
    boost::associative_property_map<IndexMap> boost_index_map(vertex_index_map);
1✔
69
    boost::graph_traits<UndirectedGraph>::vertex_iterator vi, vend;
1✔
70
    size_t i = 0;
1✔
71
    for (boost::tie(vi, vend) = boost::vertices(*std::get<0>(undirected_graph)); vi != vend;
4✔
72
         ++vi, ++i) {
3✔
73
        boost::put(boost_index_map, *vi, i);
3✔
74
    }
3✔
75

76
    std::unordered_map<Vertex, size_t> undirected_component_map;
1✔
77
    boost::associative_property_map<std::unordered_map<Vertex, size_t>> boost_component_map(
1✔
78
        undirected_component_map);
79

80
    size_t num_ccs =
1✔
81
        boost::connected_components(*std::get<0>(undirected_graph), boost_component_map,
1✔
82
                                    boost::vertex_index_map(boost_index_map));
1✔
83

84
    std::unordered_map<Vertex, size_t> component_map;
1✔
85
    for (const auto& entry : undirected_component_map) {
4✔
86
        component_map.emplace(std::get<2>(undirected_graph).at(entry.first), entry.second);
3✔
87
    }
88

89
    return {num_ccs, component_map};
1✔
90
};
1✔
91

92
const std::unordered_map<Vertex, Vertex> dominator_tree(const Graph& graph, const Vertex src) {
159✔
93
    std::unordered_map<Vertex, Vertex> dom_tree;
159✔
94

95
    IndexMap vertex_index_map;
159✔
96
    boost::associative_property_map<IndexMap> boost_index_map(vertex_index_map);
159✔
97
    boost::graph_traits<Graph>::vertex_iterator vi, vend;
159✔
98
    size_t i = 0;
159✔
99
    for (boost::tie(vi, vend) = boost::vertices(graph); vi != vend; ++vi, ++i) {
8,811✔
100
        boost::put(boost_index_map, *vi, i);
8,652✔
101
    }
8,652✔
102

103
    std::vector<size_t> df_num(num_vertices(graph), 0);
159✔
104
    auto df_num_map(boost::make_iterator_property_map(df_num.begin(), boost_index_map));
159✔
105

106
    std::vector<Vertex> parent(num_vertices(graph), boost::graph_traits<Graph>::null_vertex());
159✔
107
    auto parent_map(boost::make_iterator_property_map(parent.begin(), boost_index_map));
159✔
108

109
    std::vector<Vertex> dom_tree_vec(num_vertices(graph),
318✔
110
                                     boost::graph_traits<Graph>::null_vertex());
159✔
111
    auto dom_tree_pred_map(
112
        boost::make_iterator_property_map(dom_tree_vec.begin(), boost_index_map));
159✔
113

114
    std::vector<Vertex> vertices_by_df_num(parent);
159✔
115

116
    boost::lengauer_tarjan_dominator_tree(graph, src, boost_index_map, df_num_map, parent_map,
318✔
117
                                          vertices_by_df_num, dom_tree_pred_map);
159✔
118

119
    for (const auto& entry : vertex_index_map) {
8,811✔
120
        dom_tree.insert({entry.first, dom_tree_vec[entry.second]});
8,652✔
121
    }
122

123
    return dom_tree;
159✔
124
};
159✔
125

126
const std::unordered_map<Vertex, Vertex> post_dominator_tree(const Graph& graph, const Vertex src) {
163✔
127
    auto& rgraph = reverse(graph);
163✔
128

129
    std::unordered_map<Vertex, Vertex> pdom_tree;
163✔
130

131
    IndexMap vertex_index_map;
163✔
132
    boost::associative_property_map<IndexMap> boost_index_map(vertex_index_map);
163✔
133
    boost::graph_traits<Graph>::vertex_iterator vi, vend;
163✔
134
    size_t i = 0;
163✔
135
    for (boost::tie(vi, vend) = boost::vertices(rgraph); vi != vend; ++vi, ++i) {
8,830✔
136
        boost::put(boost_index_map, *vi, i);
8,667✔
137
    }
8,667✔
138

139
    std::vector<size_t> df_num(num_vertices(rgraph), 0);
163✔
140
    auto df_num_map(boost::make_iterator_property_map(df_num.begin(), boost_index_map));
163✔
141

142
    std::vector<Vertex> parent(num_vertices(rgraph), boost::graph_traits<Graph>::null_vertex());
163✔
143
    auto parent_map(boost::make_iterator_property_map(parent.begin(), boost_index_map));
163✔
144

145
    std::vector<Vertex> pdom_tree_vec(num_vertices(rgraph),
326✔
146
                                      boost::graph_traits<Graph>::null_vertex());
163✔
147
    auto pdom_tree_pred_map(
148
        boost::make_iterator_property_map(pdom_tree_vec.begin(), boost_index_map));
163✔
149

150
    std::vector<Vertex> vertices_by_df_num(parent);
163✔
151

152
    boost::lengauer_tarjan_dominator_tree(rgraph, src, boost_index_map, df_num_map, parent_map,
326✔
153
                                          vertices_by_df_num, pdom_tree_pred_map);
163✔
154

155
    for (const auto& entry : vertex_index_map) {
8,830✔
156
        pdom_tree.insert({entry.first, pdom_tree_vec[entry.second]});
8,667✔
157
    }
158

159
    return pdom_tree;
163✔
160
};
163✔
161

162
const std::list<graph::Vertex> topological_sort(const Graph& graph) {
1,987✔
163
    std::unordered_map<graph::Vertex, boost::default_color_type> vertex_colors;
1,987✔
164
    std::list<graph::Vertex> order;
1,987✔
165
    boost::topological_sort(graph, std::back_inserter(order),
3,974✔
166
                            boost::color_map(boost::make_assoc_property_map(vertex_colors)));
1,987✔
167
    order.reverse();
1,986✔
168
    return order;
1,986✔
169
};
1,987✔
170

171
bool is_acyclic(const Graph& graph) {
2✔
172
    try {
173
        topological_sort(graph);
2✔
174
        return true;
1✔
175
    } catch (boost::not_a_dag e) {
1✔
176
        return false;
1✔
177
    }
1✔
178
};
3✔
179

180
const std::list<Edge> back_edges(const Graph& graph, const graph::Vertex start) {
5✔
181
    std::list<Vertex> nodes;
5✔
182
    std::list<Edge> back_edges;
5✔
183
    DFSVisitor visitor(back_edges, nodes);
5✔
184

185
    std::unordered_map<graph::Vertex, boost::default_color_type> vertex_colors;
5✔
186
    boost::depth_first_search(graph, visitor, boost::make_assoc_property_map(vertex_colors), start);
5✔
187

188
    return back_edges;
5✔
189
};
5✔
190

191
void all_simple_paths_dfs(const Graph& graph, const Edge edge, const Vertex v,
12✔
192
                          std::list<std::list<Edge>>& all_paths, std::list<Edge>& current_path,
193
                          std::set<Vertex>& visited) {
194
    const Vertex u = boost::target(edge, graph);
12✔
195
    if (visited.find(u) != visited.end()) {
12✔
UNCOV
196
        return;
×
197
    }
198

199
    current_path.push_back(edge);
12✔
200
    visited.insert(u);
12✔
201

202
    if (u == v) {
12✔
203
        all_paths.push_back(std::list<Edge>(current_path));
4✔
204

205
        current_path.pop_back();
4✔
206
        visited.erase(u);
4✔
207
        return;
4✔
208
    }
209

210
    auto [eb, ee] = boost::out_edges(u, graph);
16✔
211
    auto edges = std::ranges::subrange(eb, ee);
16✔
212
    for (auto next_edge : edges) {
16✔
213
        all_simple_paths_dfs(graph, next_edge, v, all_paths, current_path, visited);
8✔
214
    }
215

216
    current_path.pop_back();
8✔
217
    visited.erase(u);
8✔
218
};
12✔
219

220
const std::list<std::list<Edge>> all_simple_paths(const Graph& graph, const Vertex src,
2✔
221
                                                  const Vertex dst) {
222
    std::list<std::list<Edge>> all_paths;
2✔
223

224
    std::set<Vertex> visited;
2✔
225
    std::list<Edge> current_path;
2✔
226

227
    auto [eb, ee] = boost::out_edges(src, graph);
2✔
228
    auto edges = std::ranges::subrange(eb, ee);
4✔
229
    for (auto edge : edges) {
6✔
230
        all_simple_paths_dfs(graph, edge, dst, all_paths, current_path, visited);
4✔
231
    }
232

233
    return all_paths;
2✔
234
};
2✔
235

236
}  // namespace graph
237
}  // 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