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

daisytuner / docc / 22963489578

11 Mar 2026 04:36PM UTC coverage: 63.494% (-0.001%) from 63.495%
22963489578

Pull #579

github

web-flow
Merge 986a5904a into 1cb8d452f
Pull Request #579: Skip nested GPU tiling on the same container to avoid redefinitions o…

3 of 5 new or added lines in 1 file covered. (60.0%)

101 existing lines in 2 files now uncovered.

24712 of 38920 relevant lines covered (63.49%)

369.37 hits per line

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

0.0
/sdfg/src/data_flow/library_nodes/math/tensor/elementwise_ops/fill_node.cpp
1
#include "sdfg/data_flow/library_nodes/math/tensor/elementwise_ops/fill_node.h"
2

3
#include "sdfg/analysis/analysis.h"
4
#include "sdfg/analysis/scope_analysis.h"
5
#include "sdfg/builder/structured_sdfg_builder.h"
6
#include "sdfg/data_flow/access_node.h"
7
#include "sdfg/data_flow/library_nodes/math/math_node.h"
8
#include "sdfg/types/type.h"
9

10
namespace sdfg {
11
namespace math {
12
namespace tensor {
13

14
FillNode::FillNode(
15
    size_t element_id,
16
    const DebugInfo& debug_info,
17
    const graph::Vertex vertex,
18
    data_flow::DataFlowGraph& parent,
19
    const std::vector<symbolic::Expression>& shape
20
)
21
    : ElementWiseUnaryNode(element_id, debug_info, vertex, parent, LibraryNodeType_Fill, shape) {}
×
22

23
bool FillNode::expand_operation(
24
    builder::StructuredSDFGBuilder& builder,
25
    analysis::AnalysisManager& analysis_manager,
26
    structured_control_flow::Sequence& body,
27
    const std::string& input_name,
28
    const std::string& output_name,
29
    const types::Tensor& input_type,
30
    const types::Tensor& output_type,
31
    const data_flow::Subset& subset
32
) {
×
33
    // Add code
34
    auto& code_block = builder.add_block(body);
×
35

36
    auto& input_node_new = builder.add_access(code_block, input_name);
×
37
    auto& output_node_new = builder.add_access(code_block, output_name);
×
38

39
    auto& tasklet = builder.add_tasklet(code_block, data_flow::TaskletCode::assign, "_out", {"_in"});
×
40
    builder.add_computational_memlet(code_block, input_node_new, tasklet, "_in", subset, input_type);
×
41
    builder.add_computational_memlet(code_block, tasklet, "_out", output_node_new, subset, output_type);
×
42

43
    return true;
×
44
}
×
45

46
std::unique_ptr<data_flow::DataFlowNode> FillNode::
47
    clone(size_t element_id, const graph::Vertex vertex, data_flow::DataFlowGraph& parent) const {
×
48
    return std::unique_ptr<
×
49
        data_flow::DataFlowNode>(new FillNode(element_id, this->debug_info(), vertex, parent, this->shape_));
×
50
}
×
51

52
bool FillNode::expand(builder::StructuredSDFGBuilder& builder, analysis::AnalysisManager& analysis_manager) {
×
53
    std::cerr << "expand" << std::endl;
×
54
    auto& dataflow = this->get_parent();
×
55
    auto& block = static_cast<structured_control_flow::Block&>(*dataflow.get_parent());
×
56
    if (dataflow.in_degree(*this) != 1 || dataflow.out_degree(*this) != 1) {
×
57
        return false;
×
UNCOV
58
    }
×
59

60
    auto& scope_analysis = analysis_manager.get<analysis::ScopeAnalysis>();
×
61
    auto& parent = static_cast<structured_control_flow::Sequence&>(*scope_analysis.parent_scope(&block));
×
62
    int index = parent.index(block);
×
UNCOV
63
    auto& transition = parent.at(index).second;
×
64

65
    auto& iedge = *dataflow.in_edges(*this).begin();
×
UNCOV
66
    auto& oedge = *dataflow.out_edges(*this).begin();
×
67

68
    auto input_node_const = dynamic_cast<data_flow::ConstantNode*>(&iedge.src());
×
69
    auto input_access = dynamic_cast<data_flow::AccessNode*>(&iedge.src());
×
70
    auto output_node = dynamic_cast<data_flow::AccessNode*>(&oedge.dst());
×
71
    if (dataflow.out_degree(*output_node) != 0) {
×
72
        return false;
×
73
    }
×
74
    if (input_access) {
×
75
        if (dataflow.in_degree(*input_access) != 0) {
×
76
            return false;
×
77
        }
×
UNCOV
78
    }
×
79

80
    // Add new graph after the current block
UNCOV
81
    auto& new_sequence = builder.add_sequence_before(parent, block, transition.assignments(), block.debug_info());
×
82

83
    // Add maps over output shape
84
    data_flow::Subset new_subset;
×
85
    structured_control_flow::Sequence* last_scope = &new_sequence;
×
86
    structured_control_flow::Map* last_map = nullptr;
×
UNCOV
87
    std::vector<symbolic::Expression> loop_vars;
×
88

89
    for (size_t i = 0; i < this->shape_.size(); i++) {
×
90
        std::string indvar_str = builder.find_new_name("_i");
×
UNCOV
91
        builder.add_container(indvar_str, types::Scalar(types::PrimitiveType::UInt64));
×
92

93
        auto indvar = symbolic::symbol(indvar_str);
×
94
        auto init = symbolic::zero();
×
95
        auto update = symbolic::add(indvar, symbolic::one());
×
96
        auto condition = symbolic::Lt(indvar, this->shape_[i]);
×
97
        last_map = &builder.add_map(
×
98
            *last_scope,
×
99
            indvar,
×
100
            condition,
×
101
            init,
×
102
            update,
×
103
            structured_control_flow::ScheduleType_Sequential::create(),
×
104
            {},
×
105
            block.debug_info()
×
106
        );
×
UNCOV
107
        last_scope = &last_map->root();
×
108

109
        loop_vars.push_back(indvar);
×
UNCOV
110
    }
×
111

112
    // Add the fill operation: read scalar input, write to each output element
UNCOV
113
    auto& code_block = builder.add_block(*last_scope);
×
114

UNCOV
115
    auto& tasklet = builder.add_tasklet(code_block, data_flow::TaskletCode::assign, "_out", {"_in"});
×
116

117
    if (input_node_const) {
×
118
        auto& input_node_new = builder.add_constant(code_block, input_node_const->data(), input_node_const->type());
×
119
        builder.add_computational_memlet(code_block, input_node_new, tasklet, "_in", {}, input_node_const->type());
×
120
    } else {
×
121
        auto& input_node_new = builder.add_access(code_block, input_access->data());
×
122
        builder.add_computational_memlet(code_block, input_node_new, tasklet, "_in", {}, iedge.base_type());
×
UNCOV
123
    }
×
124

125
    auto& output_node_new = builder.add_access(code_block, output_node->data());
×
126
    builder.add_computational_memlet(
×
127
        code_block, tasklet, "_out", output_node_new, loop_vars, static_cast<const types::Tensor&>(oedge.base_type())
×
UNCOV
128
    );
×
129

130
    // Clean up block
131
    builder.remove_memlet(block, iedge);
×
132
    builder.remove_memlet(block, oedge);
×
133
    if (input_node_const) {
×
134
        builder.remove_node(block, *input_node_const);
×
135
    } else {
×
136
        builder.remove_node(block, *input_access);
×
137
    }
×
138
    builder.remove_node(block, *output_node);
×
139
    builder.remove_node(block, *this);
×
UNCOV
140
    builder.remove_child(parent, index + 1);
×
141

142
    return true;
×
UNCOV
143
}
×
144

145
void FillNode::validate(const Function& function) const {
×
UNCOV
146
    MathNode::validate(function);
×
147

148
    // Validate that the input is a scalar
149
    auto& graph = this->get_parent();
×
150
    for (auto& iedge : graph.in_edges(*this)) {
×
151
        if (iedge.base_type().type_id() != types::TypeID::Scalar) {
×
152
            throw InvalidSDFGException(
×
153
                "FillNode: Input memlet must be of scalar type. Found type: " + iedge.base_type().print()
×
154
            );
×
155
        }
×
UNCOV
156
    }
×
157

158
    // Check that all output memlets are tensor of scalar
159
    for (auto& oedge : graph.out_edges(*this)) {
×
160
        if (oedge.base_type().type_id() != types::TypeID::Tensor) {
×
161
            throw InvalidSDFGException(
×
162
                "TensorNode: Output memlet must be of tensor type. Found type: " + oedge.base_type().print()
×
163
            );
×
164
        }
×
UNCOV
165
    }
×
166

167
    // Validate that all memlets have the same primitive type
UNCOV
168
    types::PrimitiveType prim_type = primitive_type(graph);
×
169

170
    // Check if this operation supports integer types
171
    if (!supports_integer_types() && types::is_integer(prim_type)) {
×
172
        throw InvalidSDFGException(
×
173
            "TensorNode: This operation does not support integer types. Found type: " +
×
174
            std::string(types::primitive_type_to_string(prim_type))
×
175
        );
×
176
    }
×
UNCOV
177
}
×
178

179
} // namespace tensor
180
} // namespace math
181
} // 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