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

daisytuner / sdfglib / 17653942017

11 Sep 2025 06:34PM UTC coverage: 59.145% (-0.6%) from 59.755%
17653942017

push

github

web-flow
Merge pull request #224 from daisytuner/revert-210-NewDebugInfo

Revert "New debug info"

313 of 466 new or added lines in 44 files covered. (67.17%)

21 existing lines in 4 files now uncovered.

9274 of 15680 relevant lines covered (59.15%)

115.92 hits per line

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

64.97
/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_); };
233✔
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)
51✔
16
    : FunctionBuilder(), sdfg_(new SDFG(name, type)) {
51✔
17

18
      };
51✔
19

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

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

27
    return std::move(this->sdfg_);
33✔
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✔
UNCOV
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
    for (auto& entry : assignments) {
55✔
126
        auto& lhs = entry.first;
4✔
127
        auto& type = this->function().type(lhs->get_name());
4✔
128
        if (type.type_id() != types::TypeID::Scalar) {
4✔
129
            throw InvalidSDFGException("Assignment - LHS: must be integer type");
×
130
        }
131

132
        auto& rhs = entry.second;
4✔
133
        for (auto& atom : symbolic::atoms(rhs)) {
5✔
134
            if (symbolic::is_nullptr(atom)) {
1✔
135
                throw InvalidSDFGException("Assignment - RHS: must be integer type, but is nullptr");
×
136
            }
137
            auto& atom_type = this->function().type(atom->get_name());
1✔
138
            if (atom_type.type_id() != types::TypeID::Scalar) {
1✔
139
                throw InvalidSDFGException("Assignment - RHS: must be integer type");
×
140
            }
141
        }
142
    }
143

144
    for (auto& atom : symbolic::atoms(condition)) {
59✔
145
        if (symbolic::is_nullptr(atom)) {
8✔
146
            continue;
×
147
        }
148
        auto& atom_type = this->function().type(atom->get_name());
8✔
149
        if (atom_type.type_id() != types::TypeID::Scalar && atom_type.type_id() != types::TypeID::Pointer) {
8✔
150
            throw InvalidSDFGException("Condition: must be integer type or pointer type");
×
151
        }
152
    }
153

154
    auto edge = boost::add_edge(src.vertex_, dst.vertex_, this->sdfg_->graph_);
51✔
155
    assert(edge.second);
51✔
156

157
    auto res = this->sdfg_->edges_.insert(
102✔
158
        {edge.first,
102✔
159
         std::unique_ptr<control_flow::InterstateEdge>(new control_flow::InterstateEdge(
51✔
160
             this->new_element_id(), debug_info, edge.first, src, dst, condition, assignments
51✔
161
         ))}
162
    );
163

164
    assert(res.second);
51✔
165

166
    return *(*res.first).second;
51✔
167
};
×
168

169
void SDFGBuilder::remove_edge(const control_flow::InterstateEdge& edge) {
×
170
    auto desc = edge.edge();
×
171
    this->sdfg_->edges_.erase(desc);
×
172

173
    boost::remove_edge(desc, this->sdfg_->graph_);
×
174
};
×
175

176
std::tuple<control_flow::State&, control_flow::State&, control_flow::State&> SDFGBuilder::add_loop(
1✔
177
    const control_flow::State& state,
178
    sdfg::symbolic::Symbol iterator,
179
    sdfg::symbolic::Expression init,
180
    sdfg::symbolic::Condition cond,
181
    sdfg::symbolic::Expression update,
182
    const DebugInfo& debug_info
183
) {
184
    // Init: iterator = init
185
    auto& init_state = this->add_state_after(state, true, debug_info);
1✔
186
    const graph::Edge init_edge_desc = (*this->sdfg_->in_edges(init_state).begin()).edge_;
1✔
187
    auto& init_edge = this->sdfg_->edges_[init_edge_desc];
1✔
188
    init_edge->assignments_.insert({iterator, init});
1✔
189

190
    // Final state
191
    auto& final_state = this->add_state_after(init_state, false, debug_info);
1✔
192

193
    // Init -> early_exit -> final
194
    auto& early_exit_state = this->add_state(false, debug_info);
1✔
195
    this->add_edge(init_state, early_exit_state, symbolic::Not(cond));
1✔
196
    this->add_edge(early_exit_state, final_state);
1✔
197

198
    // Init -> header -> body
199
    auto& header_state = this->add_state(false, debug_info);
1✔
200
    this->add_edge(init_state, header_state, cond);
1✔
201

202
    auto& body_state = this->add_state(false, debug_info);
1✔
203
    this->add_edge(header_state, body_state);
1✔
204

205
    auto& update_state = this->add_state(false, debug_info);
1✔
206
    this->add_edge(body_state, update_state, {{iterator, update}});
1✔
207

208
    // Back edge and exit edge
209
    this->add_edge(update_state, header_state, cond);
1✔
210
    this->add_edge(update_state, final_state, symbolic::Not(cond));
1✔
211

212
    return {init_state, body_state, final_state};
1✔
213
};
×
214

215
/***** Section: Dataflow Graph *****/
216

217
data_flow::AccessNode& SDFGBuilder::
218
    add_access(control_flow::State& state, const std::string& data, const DebugInfo& debug_info) {
6✔
219
    auto& dataflow = state.dataflow();
6✔
220
    auto vertex = boost::add_vertex(dataflow.graph_);
6✔
221
    auto res = dataflow.nodes_.insert(
12✔
222
        {vertex,
6✔
223
         std::unique_ptr<
6✔
224
             data_flow::AccessNode>(new data_flow::AccessNode(this->new_element_id(), debug_info, vertex, dataflow, data)
6✔
225
         )}
226
    );
227

228
    return dynamic_cast<data_flow::AccessNode&>(*(res.first->second));
6✔
229
};
×
230

231
data_flow::Tasklet& SDFGBuilder::add_tasklet(
3✔
232
    control_flow::State& state,
233
    const data_flow::TaskletCode code,
234
    const std::string& output,
235
    const std::vector<std::string>& inputs,
236
    const DebugInfo& debug_info
237
) {
238
    auto& dataflow = state.dataflow();
3✔
239
    auto vertex = boost::add_vertex(dataflow.graph_);
3✔
240
    auto res = dataflow.nodes_.insert(
6✔
241
        {vertex,
3✔
242
         std::unique_ptr<data_flow::Tasklet>(new data_flow::Tasklet(
6✔
243
             this->new_element_id(), debug_info, vertex, dataflow, code, output, inputs, symbolic::__true__()
3✔
244
         ))}
245
    );
246

247
    return dynamic_cast<data_flow::Tasklet&>(*(res.first->second));
3✔
248
};
×
249

250
data_flow::Memlet& SDFGBuilder::add_memlet(
6✔
251
    control_flow::State& state,
252
    data_flow::DataFlowNode& src,
253
    const std::string& src_conn,
254
    data_flow::DataFlowNode& dst,
255
    const std::string& dst_conn,
256
    const data_flow::Subset& subset,
257
    const types::IType& base_type,
258
    const DebugInfo& debug_info
259
) {
260
    auto& dataflow = state.dataflow();
6✔
261
    auto edge = boost::add_edge(src.vertex_, dst.vertex_, dataflow.graph_);
6✔
262
    auto res = dataflow.edges_.insert(
12✔
263
        {edge.first,
12✔
264
         std::unique_ptr<data_flow::Memlet>(new data_flow::Memlet(
6✔
265
             this->new_element_id(), debug_info, edge.first, dataflow, src, src_conn, dst, dst_conn, subset, base_type
6✔
266
         ))}
267
    );
268

269
    auto& memlet = dynamic_cast<data_flow::Memlet&>(*(res.first->second));
6✔
270
#ifndef NDEBUG
271
    memlet.validate(*this->sdfg_);
6✔
272
#endif
273

274
    return memlet;
6✔
275
};
×
276

277
data_flow::Memlet& SDFGBuilder::add_memlet(
×
278
    control_flow::State& state,
279
    data_flow::DataFlowNode& src,
280
    const std::string& src_conn,
281
    data_flow::DataFlowNode& dst,
282
    const std::string& dst_conn,
283
    const data_flow::Subset& begin_subset,
284
    const data_flow::Subset& end_subset,
285
    const types::IType& base_type,
286
    const DebugInfo& debug_info
287
) {
288
    auto& dataflow = state.dataflow();
×
289
    auto edge = boost::add_edge(src.vertex_, dst.vertex_, dataflow.graph_);
×
290
    auto res = dataflow.edges_.insert(
×
291
        {edge.first,
×
292
         std::unique_ptr<data_flow::Memlet>(new data_flow::Memlet(
×
293
             this->new_element_id(),
×
NEW
294
             debug_info,
×
295
             edge.first,
×
296
             dataflow,
×
297
             src,
×
298
             src_conn,
×
299
             dst,
×
300
             dst_conn,
×
301
             begin_subset,
×
302
             end_subset,
×
303
             base_type
×
304
         ))}
305
    );
306
    auto& memlet = dynamic_cast<data_flow::Memlet&>(*(res.first->second));
×
307
#ifndef NDEBUG
308
    memlet.validate(*this->sdfg_);
×
309
#endif
310

311
    return memlet;
×
312
};
×
313

314
data_flow::Memlet& SDFGBuilder::add_computational_memlet(
×
315
    control_flow::State& state,
316
    data_flow::AccessNode& src,
317
    data_flow::Tasklet& dst,
318
    const std::string& dst_conn,
319
    const data_flow::Subset& subset,
320
    const types::IType& base_type,
321
    const DebugInfo& debug_info
322
) {
NEW
323
    return this->add_memlet(state, src, "void", dst, dst_conn, subset, base_type, debug_info);
×
324
};
×
325

326
data_flow::Memlet& SDFGBuilder::add_computational_memlet(
×
327
    control_flow::State& state,
328
    data_flow::Tasklet& src,
329
    const std::string& src_conn,
330
    data_flow::AccessNode& dst,
331
    const data_flow::Subset& subset,
332
    const types::IType& base_type,
333
    const DebugInfo& debug_info
334
) {
NEW
335
    return this->add_memlet(state, src, src_conn, dst, "void", subset, base_type, debug_info);
×
336
};
×
337

338
data_flow::Memlet& SDFGBuilder::add_computational_memlet(
3✔
339
    control_flow::State& state,
340
    data_flow::AccessNode& src,
341
    data_flow::Tasklet& dst,
342
    const std::string& dst_conn,
343
    const data_flow::Subset& subset,
344
    const DebugInfo& debug_info
345
) {
346
    auto& src_type = this->function().type(src.data());
3✔
347
    auto& base_type = types::infer_type(this->function(), src_type, subset);
3✔
348
    if (base_type.type_id() != types::TypeID::Scalar) {
3✔
349
        throw InvalidSDFGException("Computational memlet must have a scalar type");
×
350
    }
351
    return this->add_memlet(state, src, "void", dst, dst_conn, subset, src_type, debug_info);
3✔
352
};
×
353

354
data_flow::Memlet& SDFGBuilder::add_computational_memlet(
3✔
355
    control_flow::State& state,
356
    data_flow::Tasklet& src,
357
    const std::string& src_conn,
358
    data_flow::AccessNode& dst,
359
    const data_flow::Subset& subset,
360
    const DebugInfo& debug_info
361
) {
362
    auto& dst_type = this->function().type(dst.data());
3✔
363
    auto& base_type = types::infer_type(this->function(), dst_type, subset);
3✔
364
    if (base_type.type_id() != types::TypeID::Scalar) {
3✔
365
        throw InvalidSDFGException("Computational memlet must have a scalar type");
×
366
    }
367
    return this->add_memlet(state, src, src_conn, dst, "void", subset, dst_type, debug_info);
3✔
368
};
×
369

370
data_flow::Memlet& SDFGBuilder::add_computational_memlet(
×
371
    control_flow::State& state,
372
    data_flow::AccessNode& src,
373
    data_flow::LibraryNode& dst,
374
    const std::string& dst_conn,
375
    const data_flow::Subset& begin_subset,
376
    const data_flow::Subset& end_subset,
377
    const types::IType& base_type,
378
    const DebugInfo& debug_info
379
) {
NEW
380
    return this->add_memlet(state, src, "void", dst, dst_conn, begin_subset, end_subset, base_type, debug_info);
×
381
};
×
382

383
data_flow::Memlet& SDFGBuilder::add_computational_memlet(
×
384
    control_flow::State& state,
385
    data_flow::LibraryNode& src,
386
    const std::string& src_conn,
387
    data_flow::AccessNode& dst,
388
    const data_flow::Subset& begin_subset,
389
    const data_flow::Subset& end_subset,
390
    const types::IType& base_type,
391
    const DebugInfo& debug_info
392
) {
NEW
393
    return this->add_memlet(state, src, src_conn, dst, "void", begin_subset, end_subset, base_type, debug_info);
×
394
};
×
395

396
data_flow::Memlet& SDFGBuilder::add_reference_memlet(
×
397
    control_flow::State& state,
398
    data_flow::AccessNode& src,
399
    data_flow::AccessNode& dst,
400
    const data_flow::Subset& subset,
401
    const types::IType& base_type,
402
    const DebugInfo& debug_info
403
) {
NEW
404
    return this->add_memlet(state, src, "void", dst, "ref", subset, base_type, debug_info);
×
405
};
×
406

407
data_flow::Memlet& SDFGBuilder::add_dereference_memlet(
×
408
    control_flow::State& state,
409
    data_flow::AccessNode& src,
410
    data_flow::AccessNode& dst,
411
    bool derefs_src,
412
    const types::IType& base_type,
413
    const DebugInfo& debug_info
414
) {
415
    if (derefs_src) {
×
NEW
416
        return this->add_memlet(state, src, "void", dst, "deref", {symbolic::zero()}, base_type, debug_info);
×
417
    } else {
NEW
418
        return this->add_memlet(state, src, "deref", dst, "void", {symbolic::zero()}, base_type, debug_info);
×
419
    }
420
};
×
421

422
} // namespace builder
423
} // 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