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

daisytuner / sdfglib / 16345126205

17 Jul 2025 12:29PM UTC coverage: 64.863% (-0.3%) from 65.184%
16345126205

Pull #147

github

web-flow
Merge 28b2c5314 into 56ea48e3e
Pull Request #147: Adds metadata library node

106 of 200 new or added lines in 9 files covered. (53.0%)

1 existing line in 1 file now uncovered.

8717 of 13439 relevant lines covered (64.86%)

176.14 hits per line

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

63.04
/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(
1✔
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}) {}
1✔
21

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

32
    auto& input = this->inputs_.at(0);
1✔
33
    auto& output = this->outputs_.at(0);
1✔
34

35
    auto& type = sdfg.type(input);
1✔
36
    types::Scalar scalar_type(type.primitive_type());
1✔
37

38
    auto& iedge = *dataflow.in_edges(*this).begin();
1✔
39
    auto& oedge = *dataflow.out_edges(*this).begin();
1✔
40

41
    // Checks if legal
42
    auto& input_node = iedge.src();
1✔
43
    auto& output_node = oedge.dst();
1✔
44
    if (dataflow.in_degree(input_node) != 0 || dataflow.out_degree(output_node) != 0) {
1✔
45
        return false;
×
46
    }
47

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

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

61
        std::string indvar_str = builder.find_new_name("_i");
2✔
62
        builder.add_container(indvar_str, types::Scalar(types::PrimitiveType::UInt64));
2✔
63

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

80
        new_subset.push_back(indvar);
2✔
81
    }
2✔
82

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

97
    // Clean up block
98
    builder.remove_memlet(block, iedge);
1✔
99
    builder.remove_memlet(block, oedge);
1✔
100
    builder.remove_node(block, input_node);
1✔
101
    builder.remove_node(block, output_node);
1✔
102
    builder.remove_node(block, *this);
1✔
103
    builder.remove_child(parent, block);
1✔
104

105
    return true;
1✔
106
}
1✔
107

108
std::unique_ptr<data_flow::DataFlowNode> ReLUNode::
109
    clone(size_t element_id, const graph::Vertex vertex, data_flow::DataFlowGraph& parent) const {
×
110
    return std::unique_ptr<data_flow::DataFlowNode>(
×
111
        new ReLUNode(element_id, this->debug_info(), vertex, parent, this->outputs_.at(0), this->inputs_.at(0))
×
112
    );
113
}
×
114

NEW
115
nlohmann::json ReLUNodeSerializer::serialize(const data_flow::LibraryNode& library_node) {
×
NEW
116
    const ReLUNode& relu_node = static_cast<const ReLUNode&>(library_node);
×
NEW
117
    nlohmann::json j;
×
118

NEW
119
    j["code"] = relu_node.code().value();
×
NEW
120
    j["outputs"] = relu_node.outputs();
×
NEW
121
    j["inputs"] = relu_node.inputs();
×
122

NEW
123
    return j;
×
NEW
124
}
×
125

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

NEW
136
    auto code = j["code"].get<std::string>();
×
NEW
137
    if (code != LibraryNodeType_ReLU.value()) {
×
NEW
138
        throw std::runtime_error("Invalid library node code");
×
139
    }
140

141
    // Extract debug info using JSONSerializer
NEW
142
    sdfg::serializer::JSONSerializer serializer;
×
NEW
143
    DebugInfo debug_info = serializer.json_to_debug_info(j["debug_info"]);
×
144

145
    // Extract properties
NEW
146
    auto outputs = j.at("outputs").get<std::vector<std::string>>();
×
NEW
147
    auto inputs = j.at("inputs").get<std::vector<std::string>>();
×
148

NEW
149
    return builder.add_library_node<ReLUNode>(parent, debug_info, outputs.at(0), inputs.at(0));
×
NEW
150
}
×
151

NEW
152
ReLUNodeDispatcher::ReLUNodeDispatcher(
×
153
    codegen::LanguageExtension& language_extension,
154
    const Function& function,
155
    const data_flow::DataFlowGraph& data_flow_graph,
156
    const ReLUNode& node
157
)
NEW
158
    : codegen::LibraryNodeDispatcher(language_extension, function, data_flow_graph, node) {}
×
159

NEW
160
void ReLUNodeDispatcher::dispatch(codegen::PrettyPrinter& stream) {
×
NEW
161
    throw std::runtime_error("ReLUNode not implemented");
×
NEW
162
}
×
163

164

165
} // namespace ml
166
} // namespace math
167
} // 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