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

daisytuner / docc / 27449564918

12 Jun 2026 11:46PM UTC coverage: 61.331% (-0.02%) from 61.354%
27449564918

push

github

web-flow
adds support for polybench-style pointers in local storage (#757)

* adds support for polybench-style pointers in local storage

* local storage handles containers with opaque pointers

* adds more corner case handling for local storage

* disables flaky softmax

79 of 109 new or added lines in 3 files covered. (72.48%)

11 existing lines in 1 file now uncovered.

36336 of 59246 relevant lines covered (61.33%)

1121.62 hits per line

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

68.3
/sdfg/src/data_flow/tasklet.cpp
1
#include "sdfg/data_flow/tasklet.h"
2

3
#include "sdfg/data_flow/data_flow_graph.h"
4
#include "sdfg/symbolic/symbolic.h"
5

6
namespace sdfg {
7
namespace data_flow {
8

9
Tasklet::Tasklet(
10
    size_t element_id,
11
    const DebugInfo& debug_info,
12
    const graph::Vertex vertex,
13
    DataFlowGraph& parent,
14
    const TaskletCode code,
15
    const std::string& output,
16
    const std::vector<std::string>& inputs
17
)
18
    : CodeNode(element_id, debug_info, vertex, parent, {output}, inputs), code_(code) {};
1,594✔
19

20
void Tasklet::validate(const Function& function) const {
3,102✔
21
    auto& graph = this->get_parent();
3,102✔
22

23
    // Validate: inputs match arity
24
    if (arity(this->code_) != this->inputs_.size()) {
3,102✔
25
        throw InvalidSDFGException(
×
26
            "Tasklet (Code: " + std::to_string(this->code_) + "): Invalid number of inputs. Expected " +
×
27
            std::to_string(arity(this->code_)) + ", got " + std::to_string(this->inputs_.size())
×
28
        );
×
29
    }
×
30

31
    // Validate: inputs match type of operation
32
    for (auto& iedge : graph.in_edges(*this)) {
5,590✔
33
        auto input_type = iedge.result_type(function);
5,590✔
34
        if (is_integer(this->code_) && !types::is_integer(input_type->primitive_type())) {
5,590✔
35
            throw InvalidSDFGException(
×
NEW
36
                "Tasklet (Code: " + std::to_string(this->code_) +
×
NEW
37
                "): Integer operation with non-integer input type: " + input_type->print()
×
38
            );
×
39
        }
×
40
        if (is_floating_point(this->code_) && !types::is_floating_point(input_type->primitive_type())) {
5,590✔
41
            throw InvalidSDFGException(
×
NEW
42
                "Tasklet (Code: " + std::to_string(this->code_) +
×
NEW
43
                "): Floating point operation with integer input type: " + input_type->print()
×
44
            );
×
45
        }
×
46
    }
5,590✔
47

48
    // Validate: Edges
49
    if (graph.in_degree(*this) != this->inputs_.size()) {
3,102✔
50
        throw InvalidSDFGException(
×
51
            "Tasklet (Code: " + std::to_string(this->code_) +
×
52
            "): Number of input edges does not match number of inputs."
×
53
        );
×
54
    }
×
55
    if (graph.out_degree(*this) != this->outputs_.size()) {
3,102✔
56
        throw InvalidSDFGException(
×
57
            "Tasklet (Code: " + std::to_string(this->code_) +
×
58
            "): Number of output edges does not match number of outputs."
×
59
        );
×
60
    }
×
61
}
3,102✔
62

63
TaskletCode Tasklet::code() const { return this->code_; };
3,744✔
64

65

66
bool Tasklet::is_assign() const { return this->code_ == TaskletCode::assign; }
54✔
67

68
bool Tasklet::is_trivial(const Function& function) const {
1✔
69
    if (!this->is_assign()) {
1✔
70
        return false;
×
71
    }
×
72

73
    auto& graph = this->get_parent();
1✔
74
    auto& iedge = *graph.in_edges(*this).begin();
1✔
75
    auto& oedge = *graph.out_edges(*this).begin();
1✔
76
    auto input_type = iedge.result_type(function);
1✔
77
    auto output_type = oedge.result_type(function);
1✔
78

79
    return input_type->primitive_type() == output_type->primitive_type();
1✔
80
}
1✔
81

82
bool Tasklet::is_cast(const Function& function) const {
10✔
83
    if (!this->is_assign()) {
10✔
84
        return false;
×
85
    }
×
86

87
    auto& graph = this->get_parent();
10✔
88
    auto& iedge = *graph.in_edges(*this).begin();
10✔
89
    auto& oedge = *graph.out_edges(*this).begin();
10✔
90
    auto input_type = iedge.result_type(function);
10✔
91
    auto output_type = oedge.result_type(function);
10✔
92

93
    return input_type->primitive_type() != output_type->primitive_type();
10✔
94
}
10✔
95

96
bool Tasklet::is_zext(const Function& function) const {
13✔
97
    if (!this->is_assign()) {
13✔
98
        return false;
×
99
    }
×
100

101
    auto& graph = this->get_parent();
13✔
102
    auto& iedge = *graph.in_edges(*this).begin();
13✔
103
    auto& oedge = *graph.out_edges(*this).begin();
13✔
104
    auto input_type = iedge.result_type(function);
13✔
105
    auto output_type = oedge.result_type(function);
13✔
106

107
    if (!types::is_unsigned(input_type->primitive_type()) || !types::is_unsigned(output_type->primitive_type())) {
13✔
108
        return false;
7✔
109
    }
7✔
110
    if (types::bit_width(output_type->primitive_type()) <= types::bit_width(input_type->primitive_type())) {
6✔
111
        return false;
3✔
112
    }
3✔
113

114
    return true;
3✔
115
}
6✔
116

117
bool Tasklet::is_sext(const Function& function) const {
1✔
118
    if (!this->is_assign()) {
1✔
119
        return false;
×
120
    }
×
121

122
    auto& graph = this->get_parent();
1✔
123
    auto& iedge = *graph.in_edges(*this).begin();
1✔
124
    auto& oedge = *graph.out_edges(*this).begin();
1✔
125
    auto input_type = iedge.result_type(function);
1✔
126
    auto output_type = oedge.result_type(function);
1✔
127

128
    if (types::is_unsigned(input_type->primitive_type()) || types::is_unsigned(output_type->primitive_type())) {
1✔
129
        return false;
×
130
    }
×
131
    if (types::bit_width(output_type->primitive_type()) <= types::bit_width(input_type->primitive_type())) {
1✔
132
        return false;
×
133
    }
×
134

135
    return true;
1✔
136
}
1✔
137

138
bool Tasklet::is_trunc(const Function& function) const {
13✔
139
    if (!this->is_assign()) {
13✔
140
        return false;
×
141
    }
×
142

143
    auto& graph = this->get_parent();
13✔
144
    auto& iedge = *graph.in_edges(*this).begin();
13✔
145
    auto& oedge = *graph.out_edges(*this).begin();
13✔
146
    auto input_type = iedge.result_type(function);
13✔
147
    auto output_type = oedge.result_type(function);
13✔
148

149
    if (!types::is_integer(input_type->primitive_type()) || !types::is_integer(output_type->primitive_type())) {
13✔
150
        return false;
1✔
151
    }
1✔
152
    if (types::is_unsigned(input_type->primitive_type()) != types::is_unsigned(output_type->primitive_type())) {
12✔
153
        return false;
2✔
154
    }
2✔
155
    if (types::bit_width(output_type->primitive_type()) >= types::bit_width(input_type->primitive_type())) {
10✔
156
        return false;
7✔
157
    }
7✔
158

159
    return true;
3✔
160
}
10✔
161

162
bool Tasklet::is_fptoui(const Function& function) const {
1✔
163
    if (!this->is_assign()) {
1✔
164
        return false;
×
165
    }
×
166

167
    auto& graph = this->get_parent();
1✔
168
    auto& iedge = *graph.in_edges(*this).begin();
1✔
169
    auto& oedge = *graph.out_edges(*this).begin();
1✔
170
    auto input_type = iedge.result_type(function);
1✔
171
    auto output_type = oedge.result_type(function);
1✔
172

173
    if (!types::is_floating_point(input_type->primitive_type()) || !types::is_unsigned(output_type->primitive_type())) {
1✔
174
        return false;
×
175
    }
×
176

177
    return true;
1✔
178
}
1✔
179

180
bool Tasklet::is_fptosi(const Function& function) const {
1✔
181
    if (!this->is_assign()) {
1✔
182
        return false;
×
183
    }
×
184

185
    auto& graph = this->get_parent();
1✔
186
    auto& iedge = *graph.in_edges(*this).begin();
1✔
187
    auto& oedge = *graph.out_edges(*this).begin();
1✔
188
    auto input_type = iedge.result_type(function);
1✔
189
    auto output_type = oedge.result_type(function);
1✔
190

191
    if (!types::is_floating_point(input_type->primitive_type()) || !types::is_signed(output_type->primitive_type())) {
1✔
192
        return false;
×
193
    }
×
194

195
    return true;
1✔
196
}
1✔
197

198
bool Tasklet::is_uitofp(const Function& function) const {
1✔
199
    if (!this->is_assign()) {
1✔
200
        return false;
×
201
    }
×
202

203
    auto& graph = this->get_parent();
1✔
204
    auto& iedge = *graph.in_edges(*this).begin();
1✔
205
    auto& oedge = *graph.out_edges(*this).begin();
1✔
206
    auto input_type = iedge.result_type(function);
1✔
207
    auto output_type = oedge.result_type(function);
1✔
208

209
    if (!types::is_unsigned(input_type->primitive_type()) || !types::is_floating_point(output_type->primitive_type())) {
1✔
210
        return false;
×
211
    }
×
212

213
    return true;
1✔
214
}
1✔
215

216
bool Tasklet::is_sitofp(const Function& function) const {
1✔
217
    if (!this->is_assign()) {
1✔
218
        return false;
×
219
    }
×
220

221
    auto& graph = this->get_parent();
1✔
222
    auto& iedge = *graph.in_edges(*this).begin();
1✔
223
    auto& oedge = *graph.out_edges(*this).begin();
1✔
224
    auto input_type = iedge.result_type(function);
1✔
225
    auto output_type = oedge.result_type(function);
1✔
226

227
    if (!types::is_signed(input_type->primitive_type()) || !types::is_floating_point(output_type->primitive_type())) {
1✔
228
        return false;
×
229
    }
×
230

231
    return true;
1✔
232
}
1✔
233

234
bool Tasklet::is_fpext(const Function& function) const {
1✔
235
    if (!this->is_assign()) {
1✔
236
        return false;
×
237
    }
×
238

239
    auto& graph = this->get_parent();
1✔
240
    auto& iedge = *graph.in_edges(*this).begin();
1✔
241
    auto& oedge = *graph.out_edges(*this).begin();
1✔
242
    auto input_type = iedge.result_type(function);
1✔
243
    auto output_type = oedge.result_type(function);
1✔
244

245
    if (!types::is_floating_point(input_type->primitive_type()) ||
1✔
246
        !types::is_floating_point(output_type->primitive_type())) {
1✔
247
        return false;
×
248
    }
×
249
    if (types::bit_width(output_type->primitive_type()) <= types::bit_width(input_type->primitive_type())) {
1✔
250
        return false;
×
251
    }
×
252

253
    return true;
1✔
254
}
1✔
255

256
bool Tasklet::is_fptrunc(const Function& function) const {
1✔
257
    if (!this->is_assign()) {
1✔
258
        return false;
×
259
    }
×
260

261
    auto& graph = this->get_parent();
1✔
262
    auto& iedge = *graph.in_edges(*this).begin();
1✔
263
    auto& oedge = *graph.out_edges(*this).begin();
1✔
264
    auto input_type = iedge.result_type(function);
1✔
265
    auto output_type = oedge.result_type(function);
1✔
266

267
    if (!types::is_floating_point(input_type->primitive_type()) ||
1✔
268
        !types::is_floating_point(output_type->primitive_type())) {
1✔
269
        return false;
×
270
    }
×
271
    if (types::bit_width(output_type->primitive_type()) >= types::bit_width(input_type->primitive_type())) {
1✔
272
        return false;
×
273
    }
×
274

275
    return true;
1✔
276
}
1✔
277

278
const std::string& Tasklet::output() const { return this->outputs_[0]; };
105✔
279

280
std::unique_ptr<DataFlowNode> Tasklet::clone(size_t element_id, const graph::Vertex vertex, DataFlowGraph& parent)
281
    const {
30✔
282
    return std::unique_ptr<Tasklet>(
30✔
283
        new Tasklet(element_id, this->debug_info_, vertex, parent, this->code_, this->outputs_.at(0), this->inputs_)
30✔
284
    );
30✔
285
};
30✔
286

287
void Tasklet::replace(const symbolic::Expression old_expression, const symbolic::Expression new_expression) {}
197✔
288

289
EdgeRemoveOption Tasklet::can_remove_out_edge(const data_flow::DataFlowGraph& graph, const Memlet* memlet) const {
7✔
290
    if (graph.out_edges_for_connector(*this, memlet->src_conn()).size() > 1) {
7✔
291
        return EdgeRemoveOption::Trivially;
×
292
    } else {
7✔
293
        // trick to allow removal of Tasklets, without having general mark-and-sweep logic to checkl tha that all
294
        // outputs are
295
        return EdgeRemoveOption::RemoveNodeAfter;
7✔
296
    }
7✔
297
}
7✔
298

299
EdgeRemoveOption Tasklet::can_remove_in_edge(const data_flow::DataFlowGraph& graph, const Memlet* memlet) const {
×
300
    return EdgeRemoveOption::NotRemovable;
×
301
}
×
302

303
} // namespace data_flow
304
} // 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