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

daisytuner / sdfglib / 18318341707

07 Oct 2025 03:48PM UTC coverage: 61.593% (+0.5%) from 61.066%
18318341707

push

github

web-flow
Merge pull request #262 from daisytuner/tasklets

Tasklets, Intrinsics and Library Nodes

84 of 418 new or added lines in 29 files covered. (20.1%)

153 existing lines in 17 files now uncovered.

8979 of 14578 relevant lines covered (61.59%)

103.69 hits per line

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

2.55
/src/data_flow/library_nodes/math/ml/element_wise.cpp
1
#include "sdfg/data_flow/library_nodes/math/ml/relu.h"
2

3
#include "sdfg/analysis/analysis.h"
4
#include "sdfg/builder/structured_sdfg_builder.h"
5

6
#include "sdfg/analysis/scope_analysis.h"
7

8
namespace sdfg {
9
namespace math {
10
namespace ml {
11

12
ElementWiseUnaryNode::ElementWiseUnaryNode(
3✔
13
    size_t element_id,
14
    const DebugInfo& debug_info,
15
    const graph::Vertex vertex,
16
    data_flow::DataFlowGraph& parent,
17
    const data_flow::LibraryNodeCode& code,
18
    const std::vector<symbolic::Expression>& shape
19
)
20
    : MathNode(element_id, debug_info, vertex, parent, code, {"Y"}, {"X"}, data_flow::ImplementationType_NONE),
3✔
21
      shape_(shape) {}
3✔
22

23
symbolic::SymbolSet ElementWiseUnaryNode::symbols() const {
×
24
    symbolic::SymbolSet syms;
×
25
    for (const auto& dim : shape_) {
×
26
        for (auto& atom : symbolic::atoms(dim)) {
×
27
            syms.insert(atom);
×
28
        }
29
    }
30
    return syms;
×
31
}
×
32

33
void ElementWiseUnaryNode::replace(const symbolic::Expression old_expression, const symbolic::Expression new_expression) {
×
34
    for (auto& dim : shape_) {
×
35
        dim = symbolic::subs(dim, old_expression, new_expression);
×
36
    }
37
}
×
38

39
void ElementWiseUnaryNode::validate(const Function& function) const {}
6✔
40

UNCOV
41
bool ElementWiseUnaryNode::expand(builder::StructuredSDFGBuilder& builder, analysis::AnalysisManager& analysis_manager) {
×
UNCOV
42
    auto& dataflow = this->get_parent();
×
UNCOV
43
    auto& block = static_cast<structured_control_flow::Block&>(*dataflow.get_parent());
×
UNCOV
44
    if (dataflow.in_degree(*this) != 1 || dataflow.out_degree(*this) != 1) {
×
45
        return false;
×
46
    }
47

UNCOV
48
    auto& scope_analysis = analysis_manager.get<analysis::ScopeAnalysis>();
×
UNCOV
49
    auto& parent = static_cast<structured_control_flow::Sequence&>(*scope_analysis.parent_scope(&block));
×
UNCOV
50
    int index = parent.index(block);
×
UNCOV
51
    auto& transition = parent.at(index).second;
×
52

UNCOV
53
    auto& input = this->inputs_.at(0);
×
UNCOV
54
    auto& output = this->outputs_.at(0);
×
55

UNCOV
56
    auto& iedge = *dataflow.in_edges(*this).begin();
×
UNCOV
57
    auto& oedge = *dataflow.out_edges(*this).begin();
×
58

59
    // Checks if legal
UNCOV
60
    auto& input_node = static_cast<data_flow::AccessNode&>(iedge.src());
×
UNCOV
61
    auto& output_node = static_cast<data_flow::AccessNode&>(oedge.dst());
×
UNCOV
62
    if (dataflow.in_degree(input_node) != 0 || dataflow.out_degree(output_node) != 0) {
×
63
        return false;
×
64
    }
65

66
    // Add new graph after the current block
UNCOV
67
    auto& new_sequence = builder.add_sequence_before(parent, block, transition.assignments(), block.debug_info());
×
68

69
    // Add maps
UNCOV
70
    data_flow::Subset new_subset;
×
UNCOV
71
    structured_control_flow::Sequence* last_scope = &new_sequence;
×
UNCOV
72
    structured_control_flow::Map* last_map = nullptr;
×
UNCOV
73
    for (size_t i = 0; i < this->shape_.size(); i++) {
×
UNCOV
74
        std::string indvar_str = builder.find_new_name("_i");
×
UNCOV
75
        builder.add_container(indvar_str, types::Scalar(types::PrimitiveType::UInt64));
×
76

UNCOV
77
        auto indvar = symbolic::symbol(indvar_str);
×
UNCOV
78
        auto init = symbolic::zero();
×
UNCOV
79
        auto update = symbolic::add(indvar, symbolic::one());
×
UNCOV
80
        auto condition = symbolic::Lt(indvar, this->shape_[i]);
×
UNCOV
81
        last_map = &builder.add_map(
×
UNCOV
82
            *last_scope,
×
UNCOV
83
            indvar,
×
UNCOV
84
            condition,
×
UNCOV
85
            init,
×
UNCOV
86
            update,
×
UNCOV
87
            structured_control_flow::ScheduleType_Sequential::create(),
×
UNCOV
88
            {},
×
UNCOV
89
            block.debug_info()
×
90
        );
UNCOV
91
        last_scope = &last_map->root();
×
92

UNCOV
93
        new_subset.push_back(indvar);
×
UNCOV
94
    }
×
95

UNCOV
96
    bool success = this->expand_operation(
×
UNCOV
97
        builder,
×
UNCOV
98
        analysis_manager,
×
UNCOV
99
        *last_scope,
×
UNCOV
100
        input_node.data(),
×
UNCOV
101
        output_node.data(),
×
UNCOV
102
        iedge.base_type(),
×
UNCOV
103
        oedge.base_type(),
×
104
        new_subset
105
    );
UNCOV
106
    if (!success) {
×
107
        return false;
×
108
    }
109

110
    // Clean up block
UNCOV
111
    builder.remove_memlet(block, iedge);
×
UNCOV
112
    builder.remove_memlet(block, oedge);
×
UNCOV
113
    builder.remove_node(block, input_node);
×
UNCOV
114
    builder.remove_node(block, output_node);
×
UNCOV
115
    builder.remove_node(block, *this);
×
UNCOV
116
    builder.remove_child(parent, index + 1);
×
117

UNCOV
118
    return true;
×
UNCOV
119
}
×
120

121
ElementWiseBinaryNode::ElementWiseBinaryNode(
×
122
    size_t element_id,
123
    const DebugInfo& debug_info,
124
    const graph::Vertex vertex,
125
    data_flow::DataFlowGraph& parent,
126
    const data_flow::LibraryNodeCode& code,
127
    const std::vector<symbolic::Expression>& shape
128
)
129
    : MathNode(element_id, debug_info, vertex, parent, code, {"C"}, {"A", "B"}, data_flow::ImplementationType_NONE),
×
NEW
130
      shape_(shape) {}
×
131

132
symbolic::SymbolSet ElementWiseBinaryNode::symbols() const {
×
133
    symbolic::SymbolSet syms;
×
134
    for (const auto& dim : shape_) {
×
135
        for (auto& atom : symbolic::atoms(dim)) {
×
136
            syms.insert(atom);
×
137
        }
138
    }
139
    return syms;
×
140
}
×
141

142
void ElementWiseBinaryNode::replace(const symbolic::Expression old_expression, const symbolic::Expression new_expression) {
×
143
    for (auto& dim : shape_) {
×
144
        dim = symbolic::subs(dim, old_expression, new_expression);
×
145
    }
146
}
×
147

148
void ElementWiseBinaryNode::validate(const Function& function) const {}
×
149

150
bool ElementWiseBinaryNode::expand(builder::StructuredSDFGBuilder& builder, analysis::AnalysisManager& analysis_manager) {
×
151
    auto& dataflow = this->get_parent();
×
152
    auto& block = static_cast<structured_control_flow::Block&>(*dataflow.get_parent());
×
153
    if (dataflow.in_degree(*this) != 1 || dataflow.out_degree(*this) != 1) {
×
154
        return false;
×
155
    }
156
    auto& scope_analysis = analysis_manager.get<analysis::ScopeAnalysis>();
×
157
    auto& parent = static_cast<structured_control_flow::Sequence&>(*scope_analysis.parent_scope(&block));
×
158
    int index = parent.index(block);
×
159
    auto& transition = parent.at(index).second;
×
160

161
    auto& input_a = this->inputs_.at(0);
×
162
    auto& input_b = this->inputs_.at(1);
×
163
    auto& output = this->outputs_.at(0);
×
164

165
    auto iedge_a = &(*dataflow.in_edges(*this).begin());
×
166
    auto iedge_b = &(*(++dataflow.in_edges(*this).begin()));
×
167
    if (iedge_a->dst_conn() != "A") {
×
168
        std::swap(iedge_a, iedge_b);
×
169
    }
×
170
    auto& oedge = *dataflow.out_edges(*this).begin();
×
171

172
    // Checks if legal
173
    auto& input_node_a = static_cast<data_flow::AccessNode&>(iedge_a->src());
×
174
    auto& input_node_b = static_cast<data_flow::AccessNode&>(iedge_b->src());
×
175
    auto& output_node = static_cast<data_flow::AccessNode&>(oedge.dst());
×
176
    if (dataflow.in_degree(input_node_a) != 0 || dataflow.in_degree(input_node_b) != 0 ||
×
177
        dataflow.out_degree(output_node) != 0) {
×
178
        return false;
×
179
    }
180

181
    // Add new graph after the current block
182
    auto& new_sequence = builder.add_sequence_before(parent, block, transition.assignments(), block.debug_info());
×
183

184
    // Add maps
185
    data_flow::Subset new_subset;
×
186
    structured_control_flow::Sequence* last_scope = &new_sequence;
×
187
    structured_control_flow::Map* last_map = nullptr;
×
188
    for (size_t i = 0; i < this->shape_.size(); i++) {
×
189
        std::string indvar_str = builder.find_new_name("_i");
×
190
        builder.add_container(indvar_str, types::Scalar(types::PrimitiveType::UInt64));
×
191

192
        auto indvar = symbolic::symbol(indvar_str);
×
193
        auto init = symbolic::zero();
×
194
        auto update = symbolic::add(indvar, symbolic::one());
×
195
        auto condition = symbolic::Lt(indvar, this->shape_[i]);
×
196
        last_map = &builder.add_map(
×
197
            *last_scope,
×
198
            indvar,
×
199
            condition,
×
200
            init,
×
201
            update,
×
202
            structured_control_flow::ScheduleType_Sequential::create(),
×
203
            {},
×
204
            block.debug_info()
×
205
        );
206
        last_scope = &last_map->root();
×
207

208
        new_subset.push_back(indvar);
×
209
    }
×
210

211
    bool success = this->expand_operation(
×
212
        builder,
×
213
        analysis_manager,
×
214
        *last_scope,
×
215
        input_node_a.data(),
×
216
        input_node_b.data(),
×
217
        output_node.data(),
×
218
        iedge_a->base_type(),
×
219
        iedge_b->base_type(),
×
220
        oedge.base_type(),
×
221
        new_subset
222
    );
223
    if (!success) {
×
224
        return false;
×
225
    }
226

227
    // Clean up block
228
    builder.remove_memlet(block, *iedge_a);
×
229
    builder.remove_memlet(block, *iedge_b);
×
230
    builder.remove_memlet(block, oedge);
×
231
    builder.remove_node(block, input_node_a);
×
232
    builder.remove_node(block, input_node_b);
×
233
    builder.remove_node(block, output_node);
×
234
    builder.remove_node(block, *this);
×
235
    builder.remove_child(parent, index + 1);
×
236

237
    return true;
×
238
}
×
239

240
} // namespace ml
241
} // namespace math
242
} // 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