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

daisytuner / sdfglib / 16779684622

06 Aug 2025 02:21PM UTC coverage: 64.3% (-1.0%) from 65.266%
16779684622

push

github

web-flow
Merge pull request #172 from daisytuner/opaque-pointers

Opaque pointers, typed memlets, untyped tasklet connectors

330 of 462 new or added lines in 38 files covered. (71.43%)

382 existing lines in 30 files now uncovered.

8865 of 13787 relevant lines covered (64.3%)

116.73 hits per line

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

64.25
/src/builder/sdfg_builder.cpp
1
#include "sdfg/builder/sdfg_builder.h"
2

3
#include "sdfg/types/utils.h"
4

5
namespace sdfg {
6
namespace builder {
7

8
Function& SDFGBuilder::function() const { return static_cast<Function&>(*this->sdfg_); };
211✔
9

10
SDFGBuilder::SDFGBuilder(std::unique_ptr<SDFG>& sdfg)
×
11
    : FunctionBuilder(), sdfg_(std::move(sdfg)) {
×
12

13
      };
×
14

15
SDFGBuilder::SDFGBuilder(const std::string& name, FunctionType type)
49✔
16
    : FunctionBuilder(), sdfg_(new SDFG(name, type)) {
49✔
17

18
      };
49✔
19

20
SDFG& SDFGBuilder::subject() const { return *this->sdfg_; };
14✔
21

22
std::unique_ptr<SDFG> SDFGBuilder::move() {
31✔
23
#ifndef NDEBUG
24
    this->sdfg_->validate();
31✔
25
#endif
26

27
    return std::move(this->sdfg_);
31✔
28
};
29

30
/***** Section: Control-Flow Graph *****/
31

32
control_flow::State& SDFGBuilder::add_state(bool is_start_state, const DebugInfo& debug_info) {
61✔
33
    auto vertex = boost::add_vertex(this->sdfg_->graph_);
61✔
34
    auto res = this->sdfg_->states_.insert(
122✔
35
        {vertex,
61✔
36
         std::unique_ptr<control_flow::State>(new control_flow::State(this->new_element_id(), debug_info, vertex))}
61✔
37
    );
38

39
    assert(res.second);
61✔
40
    (*res.first).second->dataflow_->parent_ = (*res.first).second.get();
61✔
41

42
    if (is_start_state) {
61✔
43
        this->sdfg_->start_state_ = (*res.first).second.get();
12✔
44
    }
12✔
45

46
    return *(*res.first).second;
61✔
47
};
×
48

49
control_flow::State& SDFGBuilder::
50
    add_state_before(const control_flow::State& state, bool is_start_state, const DebugInfo& debug_info) {
1✔
51
    auto& new_state = this->add_state(false, debug_info);
1✔
52

53
    std::vector<const control_flow::InterstateEdge*> to_redirect;
1✔
54
    for (auto& e : this->sdfg_->in_edges(state)) to_redirect.push_back(&e);
2✔
55

56
    // Redirect control-flow
57
    for (auto edge : to_redirect) {
2✔
58
        this->add_edge(edge->src(), new_state, edge->condition());
1✔
59

60
        auto desc = edge->edge();
1✔
61
        this->sdfg_->edges_.erase(desc);
1✔
62
        boost::remove_edge(desc, this->sdfg_->graph_);
1✔
63
    }
64
    this->add_edge(new_state, state);
1✔
65

66
    if (is_start_state) {
1✔
67
        this->sdfg_->start_state_ = &new_state;
×
68
    }
×
69

70
    return new_state;
1✔
71
};
1✔
72

73
control_flow::State& SDFGBuilder::
74
    add_state_after(const control_flow::State& state, bool connect_states, const DebugInfo& debug_info) {
5✔
75
    auto& new_state = this->add_state(false, debug_info);
5✔
76

77
    std::vector<const control_flow::InterstateEdge*> to_redirect;
5✔
78
    for (auto& e : this->sdfg_->out_edges(state)) to_redirect.push_back(&e);
6✔
79

80
    // Redirect control-flow
81
    for (auto& edge : to_redirect) {
6✔
82
        this->add_edge(new_state, edge->dst(), edge->condition());
1✔
83

84
        auto desc = edge->edge();
1✔
85
        this->sdfg_->edges_.erase(desc);
1✔
86
        boost::remove_edge(desc, this->sdfg_->graph_);
1✔
87
    }
88
    if (connect_states) {
5✔
89
        this->add_edge(state, new_state);
4✔
90
    }
4✔
91

92
    return new_state;
5✔
93
};
5✔
94

95
control_flow::InterstateEdge& SDFGBuilder::
96
    add_edge(const control_flow::State& src, const control_flow::State& dst, const DebugInfo& debug_info) {
39✔
97
    return this->add_edge(src, dst, control_flow::Assignments{}, SymEngine::boolTrue, debug_info);
39✔
98
};
×
99

100
control_flow::InterstateEdge& SDFGBuilder::add_edge(
8✔
101
    const control_flow::State& src,
102
    const control_flow::State& dst,
103
    const symbolic::Condition condition,
104
    const DebugInfo& debug_info
105
) {
106
    return this->add_edge(src, dst, control_flow::Assignments{}, condition, debug_info);
8✔
107
};
×
108

109
control_flow::InterstateEdge& SDFGBuilder::add_edge(
2✔
110
    const control_flow::State& src,
111
    const control_flow::State& dst,
112
    const control_flow::Assignments& assignments,
113
    const DebugInfo& debug_info
114
) {
115
    return this->add_edge(src, dst, assignments, SymEngine::boolTrue, debug_info);
2✔
116
};
×
117

118
control_flow::InterstateEdge& SDFGBuilder::add_edge(
51✔
119
    const control_flow::State& src,
120
    const control_flow::State& dst,
121
    const control_flow::Assignments& assignments,
122
    const symbolic::Condition condition,
123
    const DebugInfo& debug_info
124
) {
125
    auto edge = boost::add_edge(src.vertex_, dst.vertex_, this->sdfg_->graph_);
51✔
126
    assert(edge.second);
51✔
127

128
    auto res = this->sdfg_->edges_.insert(
102✔
129
        {edge.first,
102✔
130
         std::unique_ptr<control_flow::InterstateEdge>(new control_flow::InterstateEdge(
51✔
131
             this->new_element_id(), debug_info, edge.first, src, dst, condition, assignments
51✔
132
         ))}
133
    );
134

135
    assert(res.second);
51✔
136

137
    return *(*res.first).second;
51✔
138
};
×
139

140
void SDFGBuilder::remove_edge(const control_flow::InterstateEdge& edge) {
×
141
    auto desc = edge.edge();
×
142
    this->sdfg_->edges_.erase(desc);
×
143

144
    boost::remove_edge(desc, this->sdfg_->graph_);
×
145
};
×
146

147
std::tuple<control_flow::State&, control_flow::State&, control_flow::State&> SDFGBuilder::add_loop(
1✔
148
    const control_flow::State& state,
149
    sdfg::symbolic::Symbol iterator,
150
    sdfg::symbolic::Expression init,
151
    sdfg::symbolic::Condition cond,
152
    sdfg::symbolic::Expression update,
153
    const DebugInfo& debug_info
154
) {
155
    // Init: iterator = init
156
    auto& init_state = this->add_state_after(state, true, debug_info);
1✔
157
    const graph::Edge init_edge_desc = (*this->sdfg_->in_edges(init_state).begin()).edge_;
1✔
158
    auto& init_edge = this->sdfg_->edges_[init_edge_desc];
1✔
159
    init_edge->assignments_.insert({iterator, init});
1✔
160

161
    // Final state
162
    auto& final_state = this->add_state_after(init_state, false, debug_info);
1✔
163

164
    // Init -> early_exit -> final
165
    auto& early_exit_state = this->add_state(false, debug_info);
1✔
166
    this->add_edge(init_state, early_exit_state, symbolic::Not(cond));
1✔
167
    this->add_edge(early_exit_state, final_state);
1✔
168

169
    // Init -> header -> body
170
    auto& header_state = this->add_state(false, debug_info);
1✔
171
    this->add_edge(init_state, header_state, cond);
1✔
172

173
    auto& body_state = this->add_state(false, debug_info);
1✔
174
    this->add_edge(header_state, body_state);
1✔
175

176
    auto& update_state = this->add_state(false, debug_info);
1✔
177
    this->add_edge(body_state, update_state, {{iterator, update}});
1✔
178

179
    // Back edge and exit edge
180
    this->add_edge(update_state, header_state, cond);
1✔
181
    this->add_edge(update_state, final_state, symbolic::Not(cond));
1✔
182

183
    return {init_state, body_state, final_state};
1✔
184
};
×
185

186
/***** Section: Dataflow Graph *****/
187

188
data_flow::AccessNode& SDFGBuilder::
189
    add_access(control_flow::State& state, const std::string& data, const DebugInfo& debug_info) {
6✔
190
    auto& dataflow = state.dataflow();
6✔
191
    auto vertex = boost::add_vertex(dataflow.graph_);
6✔
192
    auto res = dataflow.nodes_.insert(
12✔
193
        {vertex,
6✔
194
         std::unique_ptr<
6✔
195
             data_flow::AccessNode>(new data_flow::AccessNode(this->new_element_id(), debug_info, vertex, dataflow, data)
6✔
196
         )}
197
    );
198

199
    return dynamic_cast<data_flow::AccessNode&>(*(res.first->second));
6✔
200
};
×
201

202
data_flow::Tasklet& SDFGBuilder::add_tasklet(
3✔
203
    control_flow::State& state,
204
    const data_flow::TaskletCode code,
205
    const std::string& output,
206
    const std::vector<std::string>& inputs,
207
    const DebugInfo& debug_info
208
) {
209
    auto& dataflow = state.dataflow();
3✔
210
    auto vertex = boost::add_vertex(dataflow.graph_);
3✔
211
    auto res = dataflow.nodes_.insert(
6✔
212
        {vertex,
3✔
213
         std::unique_ptr<data_flow::Tasklet>(new data_flow::Tasklet(
6✔
214
             this->new_element_id(), debug_info, vertex, dataflow, code, output, inputs, symbolic::__true__()
3✔
215
         ))}
216
    );
217

218
    return dynamic_cast<data_flow::Tasklet&>(*(res.first->second));
3✔
219
};
×
220

221
data_flow::Memlet& SDFGBuilder::add_memlet(
6✔
222
    control_flow::State& state,
223
    data_flow::DataFlowNode& src,
224
    const std::string& src_conn,
225
    data_flow::DataFlowNode& dst,
226
    const std::string& dst_conn,
227
    const data_flow::Subset& subset,
228
    const types::IType& base_type,
229
    const DebugInfo& debug_info
230
) {
231
    auto& dataflow = state.dataflow();
6✔
232
    auto edge = boost::add_edge(src.vertex_, dst.vertex_, dataflow.graph_);
6✔
233
    auto res = dataflow.edges_.insert(
12✔
234
        {edge.first,
12✔
235
         std::unique_ptr<data_flow::Memlet>(new data_flow::Memlet(
6✔
236
             this->new_element_id(), debug_info, edge.first, dataflow, src, src_conn, dst, dst_conn, subset, base_type
6✔
237
         ))}
238
    );
239

240
    auto& memlet = dynamic_cast<data_flow::Memlet&>(*(res.first->second));
6✔
241
#ifndef NDEBUG
242
    memlet.validate(*this->sdfg_);
6✔
243
#endif
244

245
    return memlet;
6✔
246
};
×
247

248
data_flow::Memlet& SDFGBuilder::add_memlet(
×
249
    control_flow::State& state,
250
    data_flow::DataFlowNode& src,
251
    const std::string& src_conn,
252
    data_flow::DataFlowNode& dst,
253
    const std::string& dst_conn,
254
    const data_flow::Subset& begin_subset,
255
    const data_flow::Subset& end_subset,
256
    const types::IType& base_type,
257
    const DebugInfo& debug_info
258
) {
259
    auto& dataflow = state.dataflow();
×
260
    auto edge = boost::add_edge(src.vertex_, dst.vertex_, dataflow.graph_);
×
261
    auto res = dataflow.edges_.insert(
×
262
        {edge.first,
×
263
         std::unique_ptr<data_flow::Memlet>(new data_flow::Memlet(
×
NEW
264
             this->new_element_id(),
×
NEW
265
             debug_info,
×
NEW
266
             edge.first,
×
NEW
267
             dataflow,
×
NEW
268
             src,
×
NEW
269
             src_conn,
×
NEW
270
             dst,
×
NEW
271
             dst_conn,
×
NEW
272
             begin_subset,
×
NEW
273
             end_subset,
×
NEW
274
             base_type
×
275
         ))}
276
    );
277
    auto& memlet = dynamic_cast<data_flow::Memlet&>(*(res.first->second));
×
278
#ifndef NDEBUG
279
    memlet.validate(*this->sdfg_);
×
280
#endif
281

282
    return memlet;
×
283
};
×
284

285
data_flow::Memlet& SDFGBuilder::add_computational_memlet(
×
286
    control_flow::State& state,
287
    data_flow::AccessNode& src,
288
    data_flow::Tasklet& dst,
289
    const std::string& dst_conn,
290
    const data_flow::Subset& subset,
291
    const types::IType& base_type,
292
    const DebugInfo& debug_info
293
) {
NEW
294
    return this->add_memlet(state, src, "void", dst, dst_conn, subset, base_type, debug_info);
×
295
};
×
296

297
data_flow::Memlet& SDFGBuilder::add_computational_memlet(
×
298
    control_flow::State& state,
299
    data_flow::Tasklet& src,
300
    const std::string& src_conn,
301
    data_flow::AccessNode& dst,
302
    const data_flow::Subset& subset,
303
    const types::IType& base_type,
304
    const DebugInfo& debug_info
305
) {
NEW
306
    return this->add_memlet(state, src, src_conn, dst, "void", subset, base_type, debug_info);
×
NEW
307
};
×
308

309
data_flow::Memlet& SDFGBuilder::add_computational_memlet(
3✔
310
    control_flow::State& state,
311
    data_flow::AccessNode& src,
312
    data_flow::Tasklet& dst,
313
    const std::string& dst_conn,
314
    const data_flow::Subset& subset,
315
    const DebugInfo& debug_info
316
) {
317
    auto& src_type = this->function().type(src.data());
3✔
318
    auto& base_type = types::infer_type(this->function(), src_type, subset);
3✔
319
    if (base_type.type_id() != types::TypeID::Scalar) {
3✔
NEW
320
        throw InvalidSDFGException("Computational memlet must have a scalar type");
×
321
    }
322
    return this->add_memlet(state, src, "void", dst, dst_conn, subset, src_type, debug_info);
3✔
NEW
323
};
×
324

325
data_flow::Memlet& SDFGBuilder::add_computational_memlet(
3✔
326
    control_flow::State& state,
327
    data_flow::Tasklet& src,
328
    const std::string& src_conn,
329
    data_flow::AccessNode& dst,
330
    const data_flow::Subset& subset,
331
    const DebugInfo& debug_info
332
) {
333
    auto& dst_type = this->function().type(dst.data());
3✔
334
    auto& base_type = types::infer_type(this->function(), dst_type, subset);
3✔
335
    if (base_type.type_id() != types::TypeID::Scalar) {
3✔
NEW
336
        throw InvalidSDFGException("Computational memlet must have a scalar type");
×
337
    }
338
    return this->add_memlet(state, src, src_conn, dst, "void", subset, dst_type, debug_info);
3✔
UNCOV
339
};
×
340

341
data_flow::Memlet& SDFGBuilder::add_computational_memlet(
×
342
    control_flow::State& state,
343
    data_flow::AccessNode& src,
344
    data_flow::LibraryNode& dst,
345
    const std::string& dst_conn,
346
    const data_flow::Subset& begin_subset,
347
    const data_flow::Subset& end_subset,
348
    const types::IType& base_type,
349
    const DebugInfo& debug_info
350
) {
NEW
351
    return this->add_memlet(state, src, "void", dst, dst_conn, begin_subset, end_subset, base_type, debug_info);
×
352
};
×
353

354
data_flow::Memlet& SDFGBuilder::add_computational_memlet(
×
355
    control_flow::State& state,
356
    data_flow::LibraryNode& src,
357
    const std::string& src_conn,
358
    data_flow::AccessNode& dst,
359
    const data_flow::Subset& begin_subset,
360
    const data_flow::Subset& end_subset,
361
    const types::IType& base_type,
362
    const DebugInfo& debug_info
363
) {
NEW
364
    return this->add_memlet(state, src, src_conn, dst, "void", begin_subset, end_subset, base_type, debug_info);
×
365
};
×
366

367
data_flow::Memlet& SDFGBuilder::add_reference_memlet(
×
368
    control_flow::State& state,
369
    data_flow::AccessNode& src,
370
    data_flow::AccessNode& dst,
371
    const data_flow::Subset& subset,
372
    const types::IType& base_type,
373
    const DebugInfo& debug_info
374
) {
NEW
375
    return this->add_memlet(state, src, "void", dst, "ref", subset, base_type, debug_info);
×
376
};
×
377

378
data_flow::Memlet& SDFGBuilder::add_dereference_memlet(
×
379
    control_flow::State& state,
380
    data_flow::AccessNode& src,
381
    data_flow::AccessNode& dst,
382
    bool derefs_src,
383
    const types::IType& base_type,
384
    const DebugInfo& debug_info
385
) {
386
    if (derefs_src) {
×
NEW
387
        return this->add_memlet(state, src, "void", dst, "deref", {symbolic::zero()}, base_type, debug_info);
×
388
    } else {
NEW
389
        return this->add_memlet(state, src, "deref", dst, "void", {symbolic::zero()}, base_type, debug_info);
×
390
    }
391
};
×
392

393
} // namespace builder
394
} // 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