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

daisytuner / docc / 23249128422

18 Mar 2026 02:12PM UTC coverage: 63.938% (+0.3%) from 63.617%
23249128422

Pull #584

github

web-flow
Merge 0fcde60dc into 64d54d7de
Pull Request #584: adds diamond tiling test

18 of 20 new or added lines in 1 file covered. (90.0%)

1180 existing lines in 28 files now uncovered.

26122 of 40855 relevant lines covered (63.94%)

407.69 hits per line

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

98.94
/sdfg/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); };
254✔
7

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

17
    boost::graph_traits<Graph>::vertex_iterator vi, vend;
2,494✔
18
    for (boost::tie(vi, vend) = boost::vertices(graph); vi != vend; ++vi) {
10,643✔
19
        auto new_vertex = boost::add_vertex(*undirected_graph);
8,149✔
20
        mapping.emplace(*vi, new_vertex);
8,149✔
21
        reverse_mapping.emplace(new_vertex, *vi);
8,149✔
22
    }
8,149✔
23

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

32
    return {std::move(undirected_graph), mapping, reverse_mapping};
2,494✔
33
};
2,494✔
34

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

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

43
    return nodes;
1✔
44
};
1✔
45

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

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

58
    size_t num_ccs = boost::strong_components(graph, boost_component_map, 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(const Graph& graph) {
2,493✔
64
    const auto& undirected_graph = undirected(graph);
2,493✔
65

66
    IndexMap vertex_index_map;
2,493✔
67
    boost::associative_property_map<IndexMap> boost_index_map(vertex_index_map);
2,493✔
68
    boost::graph_traits<UndirectedGraph>::vertex_iterator vi, vend;
2,493✔
69
    size_t i = 0;
2,493✔
70
    for (boost::tie(vi, vend) = boost::vertices(*std::get<0>(undirected_graph)); vi != vend; ++vi, ++i) {
10,640✔
71
        boost::put(boost_index_map, *vi, i);
8,147✔
72
    }
8,147✔
73

74
    std::unordered_map<Vertex, size_t> undirected_component_map;
2,493✔
75
    boost::associative_property_map<std::unordered_map<Vertex, size_t>> boost_component_map(undirected_component_map);
2,493✔
76

77
    size_t num_ccs = boost::connected_components(
2,493✔
78
        *std::get<0>(undirected_graph), boost_component_map, boost::vertex_index_map(boost_index_map)
2,493✔
79
    );
2,493✔
80

81
    std::unordered_map<Vertex, size_t> component_map;
2,493✔
82
    for (const auto& entry : undirected_component_map) {
8,147✔
83
        component_map.emplace(std::get<2>(undirected_graph).at(entry.first), entry.second);
8,147✔
84
    }
8,147✔
85

86
    return {num_ccs, component_map};
2,493✔
87
};
2,493✔
88

89
const std::unordered_map<Vertex, Vertex> dominator_tree(const Graph& graph, const Vertex src) {
250✔
90
    std::unordered_map<Vertex, Vertex> dom_tree;
250✔
91

92
    IndexMap vertex_index_map;
250✔
93
    boost::associative_property_map<IndexMap> boost_index_map(vertex_index_map);
250✔
94
    boost::graph_traits<Graph>::vertex_iterator vi, vend;
250✔
95
    size_t i = 0;
250✔
96
    for (boost::tie(vi, vend) = boost::vertices(graph); vi != vend; ++vi, ++i) {
8,454✔
97
        boost::put(boost_index_map, *vi, i);
8,204✔
98
    }
8,204✔
99

100
    std::vector<size_t> df_num(num_vertices(graph), 0);
250✔
101
    auto df_num_map(boost::make_iterator_property_map(df_num.begin(), boost_index_map));
250✔
102

103
    std::vector<Vertex> parent(num_vertices(graph), boost::graph_traits<Graph>::null_vertex());
250✔
104
    auto parent_map(boost::make_iterator_property_map(parent.begin(), boost_index_map));
250✔
105

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

109
    std::vector<Vertex> vertices_by_df_num(parent);
250✔
110

111
    boost::lengauer_tarjan_dominator_tree(
250✔
112
        graph, src, boost_index_map, df_num_map, parent_map, vertices_by_df_num, dom_tree_pred_map
250✔
113
    );
250✔
114

115
    for (const auto& entry : vertex_index_map) {
8,204✔
116
        dom_tree.insert({entry.first, dom_tree_vec[entry.second]});
8,204✔
117
    }
8,204✔
118

119
    return dom_tree;
250✔
120
};
250✔
121

122
const std::unordered_map<Vertex, Vertex> post_dominator_tree(Graph& graph) {
253✔
123
    // Determine terminal vertices
124
    std::unordered_set<Vertex> terminal_vertices;
253✔
125
    for (auto [vb, ve] = boost::vertices(graph); vb != ve; ++vb) {
8,460✔
126
        if (boost::out_degree(*vb, graph) == 0) {
8,207✔
127
            terminal_vertices.insert(*vb);
254✔
128
        }
254✔
129
    }
8,207✔
130

131
    // add synthetic super-terminal if needed
132
    bool modified = false;
253✔
133
    graph::Vertex src;
253✔
134
    if (terminal_vertices.size() == 1) {
253✔
135
        src = *terminal_vertices.begin();
252✔
136
        modified = false;
252✔
137
    } else {
252✔
138
        src = boost::add_vertex(graph);
1✔
139
        for (const auto& v : terminal_vertices) {
2✔
140
            boost::add_edge(v, src, graph);
2✔
141
        }
2✔
142
        modified = true;
1✔
143
    }
1✔
144

145
    auto& rgraph = reverse(graph);
253✔
146

147
    std::unordered_map<Vertex, Vertex> pdom_tree;
253✔
148

149
    IndexMap vertex_index_map;
253✔
150
    boost::associative_property_map<IndexMap> boost_index_map(vertex_index_map);
253✔
151
    boost::graph_traits<Graph>::vertex_iterator vi, vend;
253✔
152
    size_t i = 0;
253✔
153
    for (boost::tie(vi, vend) = boost::vertices(rgraph); vi != vend; ++vi, ++i) {
8,461✔
154
        boost::put(boost_index_map, *vi, i);
8,208✔
155
    }
8,208✔
156

157
    std::vector<size_t> df_num(num_vertices(rgraph), 0);
253✔
158
    auto df_num_map(boost::make_iterator_property_map(df_num.begin(), boost_index_map));
253✔
159

160
    std::vector<Vertex> parent(num_vertices(rgraph), boost::graph_traits<Graph>::null_vertex());
253✔
161
    auto parent_map(boost::make_iterator_property_map(parent.begin(), boost_index_map));
253✔
162

163
    std::vector<Vertex> pdom_tree_vec(num_vertices(rgraph), boost::graph_traits<Graph>::null_vertex());
253✔
164
    auto pdom_tree_pred_map(boost::make_iterator_property_map(pdom_tree_vec.begin(), boost_index_map));
253✔
165

166
    std::vector<Vertex> vertices_by_df_num(parent);
253✔
167

168
    boost::lengauer_tarjan_dominator_tree(
253✔
169
        rgraph, src, boost_index_map, df_num_map, parent_map, vertices_by_df_num, pdom_tree_pred_map
253✔
170
    );
253✔
171

172
    for (const auto& entry : vertex_index_map) {
8,208✔
173
        pdom_tree.insert({entry.first, pdom_tree_vec[entry.second]});
8,208✔
174
    }
8,208✔
175

176
    // Remove synthetic super-terminal if added
177
    if (modified) {
253✔
178
        boost::clear_vertex(src, graph);
1✔
179
    }
1✔
180

181
    return pdom_tree;
253✔
182
};
253✔
183

184
const std::list<graph::Vertex> topological_sort(const Graph& graph) {
3✔
185
    std::unordered_map<graph::Vertex, boost::default_color_type> vertex_colors;
3✔
186
    std::list<graph::Vertex> order;
3✔
187
    boost::topological_sort(
3✔
188
        graph, std::back_inserter(order), boost::color_map(boost::make_assoc_property_map(vertex_colors))
3✔
189
    );
3✔
190
    order.reverse();
3✔
191
    return order;
3✔
192
};
3✔
193

194
bool is_acyclic(const Graph& graph) {
2✔
195
    try {
2✔
196
        topological_sort(graph);
2✔
197
        return true;
2✔
198
    } catch (boost::not_a_dag e) {
2✔
199
        return false;
1✔
200
    }
1✔
201
};
2✔
202

203
const std::list<Edge> back_edges(const Graph& graph, const graph::Vertex start) {
17✔
204
    std::list<Vertex> nodes;
17✔
205
    std::list<Edge> back_edges;
17✔
206
    DFSVisitor visitor(back_edges, nodes);
17✔
207

208
    std::unordered_map<graph::Vertex, boost::default_color_type> vertex_colors;
17✔
209
    boost::depth_first_search(graph, visitor, boost::make_assoc_property_map(vertex_colors), start);
17✔
210

211
    return back_edges;
17✔
212
};
17✔
213

214
void all_simple_paths_dfs(
215
    const Graph& graph,
216
    const Edge edge,
217
    const Vertex v,
218
    std::list<std::list<Edge>>& all_paths,
219
    std::list<Edge>& current_path,
220
    std::set<Vertex>& visited
221
) {
12✔
222
    const Vertex u = boost::target(edge, graph);
12✔
223
    if (visited.find(u) != visited.end()) {
12✔
UNCOV
224
        return;
×
225
    }
×
226

227
    current_path.push_back(edge);
12✔
228
    visited.insert(u);
12✔
229

230
    if (u == v) {
12✔
231
        all_paths.push_back(std::list<Edge>(current_path));
4✔
232

233
        current_path.pop_back();
4✔
234
        visited.erase(u);
4✔
235
        return;
4✔
236
    }
4✔
237

238
    auto [eb, ee] = boost::out_edges(u, graph);
8✔
239
    auto edges = std::ranges::subrange(eb, ee);
8✔
240
    for (auto next_edge : edges) {
8✔
241
        all_simple_paths_dfs(graph, next_edge, v, all_paths, current_path, visited);
8✔
242
    }
8✔
243

244
    current_path.pop_back();
8✔
245
    visited.erase(u);
8✔
246
};
8✔
247

248
const std::list<std::list<Edge>> all_simple_paths(const Graph& graph, const Vertex src, const Vertex dst) {
2✔
249
    std::list<std::list<Edge>> all_paths;
2✔
250

251
    std::set<Vertex> visited;
2✔
252
    std::list<Edge> current_path;
2✔
253

254
    auto [eb, ee] = boost::out_edges(src, graph);
2✔
255
    auto edges = std::ranges::subrange(eb, ee);
2✔
256
    for (auto edge : edges) {
4✔
257
        all_simple_paths_dfs(graph, edge, dst, all_paths, current_path, visited);
4✔
258
    }
4✔
259

260
    return all_paths;
2✔
261
};
2✔
262

263
} // namespace graph
264
} // 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