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

daisytuner / sdfglib / 17656823807

11 Sep 2025 08:42PM UTC coverage: 60.447% (+1.1%) from 59.335%
17656823807

Pull #219

github

web-flow
Merge d5416236f into 6c1992b40
Pull Request #219: stdlib Library Nodes and ConstantNodes

460 of 1635 new or added lines in 81 files covered. (28.13%)

93 existing lines in 35 files now uncovered.

9385 of 15526 relevant lines covered (60.45%)

107.21 hits per line

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

37.09
/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(
5✔
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
    const std::unordered_map<std::string, std::string>& attributes
20
)
21
    : MathNode(element_id, debug_info, vertex, parent, code, {"Y"}, {"X"}, data_flow::ImplementationType_NONE),
5✔
22
      shape_(shape), attributes_(attributes) {}
5✔
23

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

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

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

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

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

54
    auto& input = this->inputs_.at(0);
2✔
55
    auto& output = this->outputs_.at(0);
2✔
56

57
    auto& iedge = *dataflow.in_edges(*this).begin();
2✔
58
    auto& oedge = *dataflow.out_edges(*this).begin();
2✔
59

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

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

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

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

94
        new_subset.push_back(indvar);
4✔
95
    }
4✔
96

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

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

119
    return true;
2✔
120
}
2✔
121

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

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

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

NEW
150
void ElementWiseBinaryNode::validate(const Function& function) const {}
×
151

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

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

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

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

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

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

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

210
        new_subset.push_back(indvar);
×
211
    }
×
212

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

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

239
    return true;
×
240
}
×
241

242
} // namespace ml
243
} // namespace math
244
} // 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

© 2025 Coveralls, Inc