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

daisytuner / sdfglib / 17621055299

10 Sep 2025 05:00PM UTC coverage: 59.755% (+0.6%) from 59.145%
17621055299

Pull #210

github

web-flow
Merge 6e7cc1401 into b8fdeb232
Pull Request #210: New debug info

777 of 1111 new or added lines in 46 files covered. (69.94%)

11 existing lines in 11 files now uncovered.

9755 of 16325 relevant lines covered (59.75%)

115.06 hits per line

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

43.88
/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 DebugInfoRegion& debug_info,
15
    const graph::Vertex vertex,
16
    data_flow::DataFlowGraph& parent,
17
    const data_flow::LibraryNodeCode& code,
18
    const std::unordered_map<std::string, std::string>& attributes
19
)
20
    : MathNode(element_id, debug_info, vertex, parent, code, {"Y"}, {"X"}, data_flow::ImplementationType_NONE),
5✔
21
      attributes_(attributes) {}
5✔
22

23
void ElementWiseUnaryNode::validate(const Function& function) const {
6✔
24
    // TODO: Implement
25
}
6✔
26

27
bool ElementWiseUnaryNode::expand(builder::StructuredSDFGBuilder& builder, analysis::AnalysisManager& analysis_manager) {
2✔
28
    auto& dataflow = this->get_parent();
2✔
29
    auto& block = static_cast<structured_control_flow::Block&>(*dataflow.get_parent());
2✔
30
    if (dataflow.in_degree(*this) != 1 || dataflow.out_degree(*this) != 1) {
2✔
31
        return false;
×
32
    }
33

34
    auto& scope_analysis = analysis_manager.get<analysis::ScopeAnalysis>();
2✔
35
    auto& parent = static_cast<structured_control_flow::Sequence&>(*scope_analysis.parent_scope(&block));
2✔
36
    int index = parent.index(block);
2✔
37
    auto& transition = parent.at(index).second;
2✔
38

39
    auto& input = this->inputs_.at(0);
2✔
40
    auto& output = this->outputs_.at(0);
2✔
41

42
    auto& iedge = *dataflow.in_edges(*this).begin();
2✔
43
    auto& oedge = *dataflow.out_edges(*this).begin();
2✔
44

45
    // Checks if legal
46
    auto& input_node = static_cast<data_flow::AccessNode&>(iedge.src());
2✔
47
    auto& output_node = static_cast<data_flow::AccessNode&>(oedge.dst());
2✔
48
    if (dataflow.in_degree(input_node) != 0 || dataflow.out_degree(output_node) != 0) {
2✔
49
        return false;
×
50
    }
51

52
    // Add new graph after the current block
53
    auto& new_sequence = builder.add_sequence_before(
2✔
54
        parent, block, transition.assignments(), builder.debug_info().get_region(block.debug_info().indices())
2✔
55
    );
56

57
    // Add maps
58
    auto& begin_subsets_out = oedge.begin_subset();
2✔
59
    auto& end_subsets_out = oedge.end_subset();
2✔
60
    data_flow::Subset new_subset;
2✔
61
    structured_control_flow::Sequence* last_scope = &new_sequence;
2✔
62
    structured_control_flow::Map* last_map = nullptr;
2✔
63
    for (size_t i = 0; i < begin_subsets_out.size(); i++) {
6✔
64
        auto& dim_begin = begin_subsets_out[i];
4✔
65
        auto& dim_end = end_subsets_out[i];
4✔
66

67
        std::string indvar_str = builder.find_new_name("_i");
4✔
68
        builder.add_container(indvar_str, types::Scalar(types::PrimitiveType::UInt64));
4✔
69

70
        auto indvar = symbolic::symbol(indvar_str);
4✔
71
        auto init = dim_begin;
4✔
72
        auto update = symbolic::add(indvar, symbolic::one());
4✔
73
        auto condition = symbolic::Lt(indvar, symbolic::add(dim_end, symbolic::one()));
4✔
74
        last_map = &builder.add_map(
8✔
75
            *last_scope,
4✔
76
            indvar,
77
            condition,
78
            init,
79
            update,
80
            structured_control_flow::ScheduleType_Sequential::create(),
4✔
81
            {},
4✔
82
            builder.debug_info().get_region(block.debug_info().indices())
4✔
83
        );
84
        last_scope = &last_map->root();
4✔
85

86
        new_subset.push_back(indvar);
4✔
87
    }
4✔
88

89
    bool success = this->expand_operation(
2✔
90
        builder,
2✔
91
        analysis_manager,
2✔
92
        *last_scope,
2✔
93
        input_node.data(),
2✔
94
        output_node.data(),
2✔
95
        iedge.base_type(),
2✔
96
        oedge.base_type(),
2✔
97
        new_subset
98
    );
99
    if (!success) {
2✔
100
        return false;
×
101
    }
102

103
    // Clean up block
104
    builder.remove_memlet(block, iedge);
2✔
105
    builder.remove_memlet(block, oedge);
2✔
106
    builder.remove_node(block, input_node);
2✔
107
    builder.remove_node(block, output_node);
2✔
108
    builder.remove_node(block, *this);
2✔
109
    builder.remove_child(parent, index + 1);
2✔
110

111
    return true;
2✔
112
}
2✔
113

114
ElementWiseBinaryNode::ElementWiseBinaryNode(
×
115
    size_t element_id,
116
    const DebugInfoRegion& debug_info,
117
    const graph::Vertex vertex,
118
    data_flow::DataFlowGraph& parent,
119
    const data_flow::LibraryNodeCode& code,
120
    const std::unordered_map<std::string, std::string>& attributes
121
)
122
    : MathNode(element_id, debug_info, vertex, parent, code, {"C"}, {"A", "B"}, data_flow::ImplementationType_NONE),
×
123
      attributes_(attributes) {}
×
124

125
void ElementWiseBinaryNode::validate(const Function& function) const {
×
126
    // TODO: Implement
127
}
×
128

129
bool ElementWiseBinaryNode::expand(builder::StructuredSDFGBuilder& builder, analysis::AnalysisManager& analysis_manager) {
×
130
    auto& dataflow = this->get_parent();
×
131
    auto& block = static_cast<structured_control_flow::Block&>(*dataflow.get_parent());
×
132
    if (dataflow.in_degree(*this) != 1 || dataflow.out_degree(*this) != 1) {
×
133
        return false;
×
134
    }
135
    auto& scope_analysis = analysis_manager.get<analysis::ScopeAnalysis>();
×
136
    auto& parent = static_cast<structured_control_flow::Sequence&>(*scope_analysis.parent_scope(&block));
×
137
    int index = parent.index(block);
×
138
    auto& transition = parent.at(index).second;
×
139

140
    auto& input_a = this->inputs_.at(0);
×
141
    auto& input_b = this->inputs_.at(1);
×
142
    auto& output = this->outputs_.at(0);
×
143

144
    auto iedge_a = &(*dataflow.in_edges(*this).begin());
×
145
    auto iedge_b = &(*(++dataflow.in_edges(*this).begin()));
×
146
    if (iedge_a->dst_conn() != "A") {
×
147
        std::swap(iedge_a, iedge_b);
×
148
    }
×
149
    auto& oedge = *dataflow.out_edges(*this).begin();
×
150

151
    // Checks if legal
152
    auto& input_node_a = static_cast<data_flow::AccessNode&>(iedge_a->src());
×
153
    auto& input_node_b = static_cast<data_flow::AccessNode&>(iedge_b->src());
×
154
    auto& output_node = static_cast<data_flow::AccessNode&>(oedge.dst());
×
155
    if (dataflow.in_degree(input_node_a) != 0 || dataflow.in_degree(input_node_b) != 0 ||
×
156
        dataflow.out_degree(output_node) != 0) {
×
157
        return false;
×
158
    }
159

160
    // Add new graph after the current block
NEW
161
    auto& new_sequence = builder.add_sequence_before(
×
NEW
162
        parent, block, transition.assignments(), builder.debug_info().get_region(block.debug_info().indices())
×
163
    );
164

165
    // Add maps
166
    auto& begin_subsets_out = oedge.begin_subset();
×
167
    auto& end_subsets_out = oedge.end_subset();
×
168
    data_flow::Subset new_subset;
×
169
    structured_control_flow::Sequence* last_scope = &new_sequence;
×
170
    structured_control_flow::Map* last_map = nullptr;
×
171
    for (size_t i = 0; i < begin_subsets_out.size(); i++) {
×
172
        auto& dim_begin = begin_subsets_out[i];
×
173
        auto& dim_end = end_subsets_out[i];
×
174

175
        std::string indvar_str = builder.find_new_name("_i");
×
176
        builder.add_container(indvar_str, types::Scalar(types::PrimitiveType::UInt64));
×
177

178
        auto indvar = symbolic::symbol(indvar_str);
×
179
        auto init = dim_begin;
×
180
        auto update = symbolic::add(indvar, symbolic::one());
×
181
        auto condition = symbolic::Lt(indvar, symbolic::add(dim_end, symbolic::one()));
×
182
        last_map = &builder.add_map(
×
183
            *last_scope,
×
184
            indvar,
185
            condition,
186
            init,
187
            update,
188
            structured_control_flow::ScheduleType_Sequential::create(),
×
189
            {},
×
NEW
190
            builder.debug_info().get_region(block.debug_info().indices())
×
191
        );
192
        last_scope = &last_map->root();
×
193

194
        new_subset.push_back(indvar);
×
195
    }
×
196

197
    bool success = this->expand_operation(
×
198
        builder,
×
199
        analysis_manager,
×
200
        *last_scope,
×
201
        input_node_a.data(),
×
202
        input_node_b.data(),
×
203
        output_node.data(),
×
204
        iedge_a->base_type(),
×
205
        iedge_b->base_type(),
×
206
        oedge.base_type(),
×
207
        new_subset
208
    );
209
    if (!success) {
×
210
        return false;
×
211
    }
212

213
    // Clean up block
214
    builder.remove_memlet(block, *iedge_a);
×
215
    builder.remove_memlet(block, *iedge_b);
×
216
    builder.remove_memlet(block, oedge);
×
217
    builder.remove_node(block, input_node_a);
×
218
    builder.remove_node(block, input_node_b);
×
219
    builder.remove_node(block, output_node);
×
220
    builder.remove_node(block, *this);
×
221
    builder.remove_child(parent, index + 1);
×
222

223
    return true;
×
224
}
×
225

226
} // namespace ml
227
} // namespace math
228
} // 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