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

daisytuner / sdfglib / 16317076880

16 Jul 2025 10:31AM UTC coverage: 65.036% (+0.4%) from 64.642%
16317076880

push

github

web-flow
Merge pull request #142 from daisytuner/math

adds ReLU math instrinsic

60 of 69 new or added lines in 3 files covered. (86.96%)

8653 of 13305 relevant lines covered (65.04%)

177.65 hits per line

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

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

115
} // namespace ml
116
} // namespace math
117
} // 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