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

daisytuner / sdfglib / 16454139884

22 Jul 2025 07:52PM UTC coverage: 65.338% (-0.7%) from 66.011%
16454139884

Pull #156

github

web-flow
Merge cf357586f into 4c085404b
Pull Request #156: adds draft for GEMM node

0 of 130 new or added lines in 1 file covered. (0.0%)

110 existing lines in 10 files now uncovered.

8326 of 12743 relevant lines covered (65.34%)

132.57 hits per line

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

67.02
/src/data_flow/library_nodes/math/ml/relu.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
ReLUNode::ReLUNode(
4✔
13
    size_t element_id,
14
    const DebugInfo& debug_info,
15
    const graph::Vertex vertex,
16
    data_flow::DataFlowGraph& parent,
17
    const std::string& output,
18
    const std::string& input
19
)
20
    : MathNode(element_id, debug_info, vertex, parent, LibraryNodeType_ReLU, {output}, {input}) {}
4✔
21

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

26
bool ReLUNode::expand(builder::StructuredSDFGBuilder& builder, analysis::AnalysisManager& analysis_manager) {
1✔
27
    auto& sdfg = builder.subject();
1✔
28
    auto& dataflow = this->get_parent();
1✔
29
    auto& block = static_cast<structured_control_flow::Block&>(*dataflow.get_parent());
1✔
30
    if (dataflow.in_degree(*this) != 1 || dataflow.out_degree(*this) != 1) {
1✔
UNCOV
31
        return false;
×
32
    }
33
    auto& scope_analyisis = analysis_manager.get<analysis::ScopeAnalysis>();
1✔
34
    auto& parent = static_cast<structured_control_flow::Sequence&>(*scope_analyisis.parent_scope(&block));
1✔
35

36
    auto& input = this->inputs_.at(0);
1✔
37
    auto& output = this->outputs_.at(0);
1✔
38

39
    auto& type = sdfg.type(input);
1✔
40
    types::Scalar scalar_type(type.primitive_type());
1✔
41

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

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

52
    // Add new graph after the current block
53
    auto& new_sequence = builder.add_sequence_before(parent, block, block.debug_info()).first;
1✔
54

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

65
        std::string indvar_str = builder.find_new_name("_i");
2✔
66
        builder.add_container(indvar_str, types::Scalar(types::PrimitiveType::UInt64));
2✔
67

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

84
        new_subset.push_back(indvar);
2✔
85
    }
2✔
86

87
    // Add code
88
    auto& code_block = builder.add_block(*last_scope, {}, block.debug_info());
1✔
89
    auto& input_node_new = builder.add_access(code_block, input, input_node.debug_info());
1✔
90
    auto& output_node_new = builder.add_access(code_block, output, output_node.debug_info());
1✔
91
    auto& tasklet = builder.add_tasklet(
2✔
92
        code_block,
1✔
93
        data_flow::TaskletCode::max,
94
        {"_out", scalar_type},
1✔
95
        {{"0", scalar_type}, {"_in", scalar_type}},
1✔
96
        block.debug_info()
1✔
97
    );
98
    builder.add_memlet(code_block, input_node_new, "void", tasklet, "_in", new_subset, block.debug_info());
1✔
99
    builder.add_memlet(code_block, tasklet, "_out", output_node_new, "void", new_subset, block.debug_info());
1✔
100

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

109
    return true;
1✔
110
}
1✔
111

112
std::unique_ptr<data_flow::DataFlowNode> ReLUNode::
113
    clone(size_t element_id, const graph::Vertex vertex, data_flow::DataFlowGraph& parent) const {
1✔
114
    return std::unique_ptr<data_flow::DataFlowNode>(
1✔
115
        new ReLUNode(element_id, this->debug_info(), vertex, parent, this->outputs_.at(0), this->inputs_.at(0))
1✔
116
    );
UNCOV
117
}
×
118

UNCOV
119
nlohmann::json ReLUNodeSerializer::serialize(const data_flow::LibraryNode& library_node) {
×
UNCOV
120
    const ReLUNode& relu_node = static_cast<const ReLUNode&>(library_node);
×
UNCOV
121
    nlohmann::json j;
×
122

UNCOV
123
    j["code"] = relu_node.code().value();
×
UNCOV
124
    j["outputs"] = relu_node.outputs();
×
UNCOV
125
    j["inputs"] = relu_node.inputs();
×
126

UNCOV
127
    return j;
×
128
}
×
129

130
data_flow::LibraryNode& ReLUNodeSerializer::deserialize(
×
131
    const nlohmann::json& j, builder::StructuredSDFGBuilder& builder, structured_control_flow::Block& parent
132
) {
133
    // Assertions for required fields
134
    assert(j.contains("element_id"));
×
UNCOV
135
    assert(j.contains("code"));
×
136
    assert(j.contains("outputs"));
×
137
    assert(j.contains("inputs"));
×
UNCOV
138
    assert(j.contains("debug_info"));
×
139

UNCOV
140
    auto code = j["code"].get<std::string>();
×
UNCOV
141
    if (code != LibraryNodeType_ReLU.value()) {
×
UNCOV
142
        throw std::runtime_error("Invalid library node code");
×
143
    }
144

145
    // Extract debug info using JSONSerializer
146
    sdfg::serializer::JSONSerializer serializer;
×
147
    DebugInfo debug_info = serializer.json_to_debug_info(j["debug_info"]);
×
148

149
    // Extract properties
150
    auto outputs = j.at("outputs").get<std::vector<std::string>>();
×
151
    auto inputs = j.at("inputs").get<std::vector<std::string>>();
×
152

UNCOV
153
    return builder.add_library_node<ReLUNode>(parent, debug_info, outputs.at(0), inputs.at(0));
×
UNCOV
154
}
×
155

156
ReLUNodeDispatcher::ReLUNodeDispatcher(
×
157
    codegen::LanguageExtension& language_extension,
158
    const Function& function,
159
    const data_flow::DataFlowGraph& data_flow_graph,
160
    const ReLUNode& node
161
)
162
    : codegen::LibraryNodeDispatcher(language_extension, function, data_flow_graph, node) {}
×
163

UNCOV
164
void ReLUNodeDispatcher::dispatch(codegen::PrettyPrinter& stream) {
×
165
    throw std::runtime_error("ReLUNode not implemented");
×
UNCOV
166
}
×
167

168

169
} // namespace ml
170
} // namespace math
171
} // 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