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

daisytuner / docc / 26812260585

02 Jun 2026 08:49AM UTC coverage: 60.823% (-0.05%) from 60.869%
26812260585

Pull #725

github

web-flow
Merge eceff48b9 into cd25c9278
Pull Request #725: Tensor node backport

599 of 1255 new or added lines in 51 files covered. (47.73%)

541 existing lines in 46 files now uncovered.

35094 of 57699 relevant lines covered (60.82%)

11078.43 hits per line

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

18.28
/sdfg/src/data_flow/library_nodes/math/tensor/spatial_tensor_node.cpp
1
#include "sdfg/data_flow/library_nodes/math/tensor/spatial_tensor_node.h"
2

3
namespace sdfg::math::tensor {
4

5

6
SpatialTensorNode::SpatialTensorNode(
7
    size_t element_id,
8
    const DebugInfo& debug_info,
9
    const graph::Vertex vertex,
10
    data_flow::DataFlowGraph& parent,
11
    const data_flow::LibraryNodeCode& code,
12
    const std::vector<std::string>& outputs,
13
    const std::vector<std::string>& inputs,
14
    const data_flow::ImplementationType& impl_type,
15
    QuantizationType quantization,
16
    const std::vector<symbolic::Expression>& shape,
17
    const std::vector<symbolic::Expression>& kernel_shape,
18
    const std::vector<symbolic::Expression>& strides,
19
    const std::vector<symbolic::Expression>& pads,
20
    const std::vector<symbolic::Expression>& dilations
21
)
22
    : TensorNode(element_id, debug_info, vertex, parent, code, outputs, inputs, impl_type), shape_(shape),
48✔
23
      kernel_shape_(kernel_shape), strides_(strides), pads_(pads), dilations_(dilations), quantization_(quantization) {}
48✔
24

NEW
25
QuantizationType SpatialTensorNode::quantization() const { return quantization_; }
×
26

NEW
27
void SpatialTensorNode::set_quantization(const QuantizationType quant) { quantization_ = quant; }
×
28

29
symbolic::SymbolSet SpatialTensorNode::symbols() const {
16✔
30
    symbolic::SymbolSet syms;
16✔
31
    for (auto& expr : shape_) {
64✔
32
        for (auto& atom : symbolic::atoms(expr)) {
64✔
33
            syms.insert(atom);
6✔
34
        }
6✔
35
    }
64✔
36
    for (auto& expr : kernel_shape_) {
32✔
37
        for (auto& atom : symbolic::atoms(expr)) {
32✔
NEW
38
            syms.insert(atom);
×
NEW
39
        }
×
40
    }
32✔
41
    for (auto& expr : strides_) {
28✔
42
        for (auto& atom : symbolic::atoms(expr)) {
28✔
NEW
43
            syms.insert(atom);
×
NEW
44
        }
×
45
    }
28✔
46
    for (auto& expr : pads_) {
52✔
47
        for (auto& atom : symbolic::atoms(expr)) {
52✔
NEW
48
            syms.insert(atom);
×
NEW
49
        }
×
50
    }
52✔
51
    for (auto& expr : dilations_) {
26✔
52
        for (auto& atom : symbolic::atoms(expr)) {
26✔
NEW
53
            syms.insert(atom);
×
NEW
54
        }
×
55
    }
26✔
56
    return syms;
16✔
57
}
16✔
58

59
void SpatialTensorNode::replace(const symbolic::Expression old_expression, const symbolic::Expression new_expression) {
1✔
60
    for (auto& expr : shape_) {
4✔
61
        expr = symbolic::subs(expr, old_expression, new_expression);
4✔
62
    }
4✔
63
    for (auto& expr : kernel_shape_) {
2✔
64
        expr = symbolic::subs(expr, old_expression, new_expression);
2✔
65
    }
2✔
66
    for (auto& expr : strides_) {
1✔
NEW
67
        expr = symbolic::subs(expr, old_expression, new_expression);
×
NEW
68
    }
×
69
    for (auto& expr : pads_) {
1✔
NEW
70
        expr = symbolic::subs(expr, old_expression, new_expression);
×
NEW
71
    }
×
72
    for (auto& expr : dilations_) {
1✔
NEW
73
        expr = symbolic::subs(expr, old_expression, new_expression);
×
NEW
74
    }
×
75
}
1✔
76

NEW
77
size_t SpatialTensorNode::num_spatial_dims() const {
×
NEW
78
    auto& s = shape_;
×
NEW
79
    assert(s.size() >= 2);
×
NEW
80
    return s.size() - 2;
×
NEW
81
}
×
82

NEW
83
symbolic::Expression SpatialTensorNode::output_spatial_dim(size_t i) const {
×
NEW
84
    size_t n_spatial = num_spatial_dims();
×
NEW
85
    assert(i < n_spatial);
×
86

NEW
87
    auto& s = shape_;
×
NEW
88
    auto& ks = kernel_shape_;
×
NEW
89
    auto& st = strides_;
×
NEW
90
    auto& pa = pads_;
×
NEW
91
    auto& di = dilations_;
×
92

NEW
93
    auto d_in = s[2 + i];
×
NEW
94
    auto k = ks[i];
×
95

NEW
96
    symbolic::Expression stride = st.empty() ? symbolic::Expression(symbolic::one()) : st[i];
×
NEW
97
    symbolic::Expression dilation = di.empty() ? symbolic::Expression(symbolic::one()) : di[i];
×
98

99
    // pads layout: [begin_d0, begin_d1, …, end_d0, end_d1, …]
NEW
100
    symbolic::Expression pad_begin = pa.empty() ? symbolic::Expression(symbolic::zero()) : pa[i];
×
NEW
101
    symbolic::Expression pad_end = pa.empty() ? symbolic::Expression(symbolic::zero()) : pa[n_spatial + i];
×
102

103
    // numerator = D_i + pad_begin + pad_end - dilation * (k - 1) - 1
NEW
104
    auto numerator = symbolic::
×
NEW
105
        sub(symbolic::add(symbolic::add(d_in, pad_begin), pad_end),
×
NEW
106
            symbolic::add(symbolic::mul(dilation, symbolic::sub(k, symbolic::one())), symbolic::one()));
×
107

NEW
108
    return symbolic::add(symbolic::div(numerator, stride), symbolic::one());
×
NEW
109
}
×
110

NEW
111
symbolic::Expression SpatialTensorNode::output_spatial_volume() const {
×
NEW
112
    size_t n_spatial = num_spatial_dims();
×
NEW
113
    symbolic::Expression result = symbolic::Expression(symbolic::one());
×
NEW
114
    for (size_t i = 0; i < n_spatial; ++i) {
×
NEW
115
        result = symbolic::mul(result, output_spatial_dim(i));
×
NEW
116
    }
×
NEW
117
    return result;
×
NEW
118
}
×
119

NEW
120
symbolic::Expression SpatialTensorNode::kernel_volume() const {
×
NEW
121
    auto& ks = kernel_shape_;
×
NEW
122
    return SymEngine::mul(ks);
×
NEW
123
}
×
124

NEW
125
std::basic_ostream<char>& SpatialTensorNode::operator<<(std::basic_ostream<char>& os) const {
×
NEW
126
    os << "shape=[";
×
NEW
127
    for (size_t i = 0; i < shape_.size(); ++i) {
×
NEW
128
        if (i > 0) os << ", ";
×
NEW
129
        os << shape_[i]->__str__();
×
NEW
130
    }
×
NEW
131
    os << "], kernel_shape=[";
×
NEW
132
    for (size_t i = 0; i < kernel_shape_.size(); ++i) {
×
NEW
133
        if (i > 0) os << ", ";
×
NEW
134
        os << kernel_shape_[i]->__str__();
×
NEW
135
    }
×
NEW
136
    os << "], strides=[";
×
NEW
137
    for (size_t i = 0; i < strides_.size(); ++i) {
×
NEW
138
        if (i > 0) os << ", ";
×
NEW
139
        os << strides_[i]->__str__();
×
NEW
140
    }
×
NEW
141
    os << "], pads=[";
×
NEW
142
    for (size_t i = 0; i < pads_.size(); ++i) {
×
NEW
143
        if (i > 0) os << ", ";
×
NEW
144
        os << pads_[i]->__str__();
×
NEW
145
    }
×
NEW
146
    os << "], dilations=[";
×
NEW
147
    for (size_t i = 0; i < dilations_.size(); ++i) {
×
NEW
148
        if (i > 0) os << ", ";
×
NEW
149
        os << dilations_[i]->__str__();
×
NEW
150
    }
×
NEW
151
    os << "], ";
×
NEW
152
    os << "quant=" << types::primitive_type_to_string(quantization_);
×
NEW
153
    return os;
×
NEW
154
}
×
155

NEW
156
void SpatialTensorNodeBaseSerializer::fill_base_values(const SpatialTensorNode& node, nlohmann::json& j) {
×
NEW
157
    j["code"] = node.code().value();
×
158

NEW
159
    serializer::JSONSerializer serializer;
×
160

NEW
161
    j["shape"] = nlohmann::json::array();
×
NEW
162
    for (auto& dim : node.shape()) {
×
NEW
163
        j["shape"].push_back(serializer.expression(dim));
×
NEW
164
    }
×
165

NEW
166
    j["kernel_shape"] = nlohmann::json::array();
×
NEW
167
    for (auto& dim : node.kernel_shape()) {
×
NEW
168
        j["kernel_shape"].push_back(serializer.expression(dim));
×
NEW
169
    }
×
170

NEW
171
    j["strides"] = nlohmann::json::array();
×
NEW
172
    for (auto& stride : node.strides()) {
×
NEW
173
        j["strides"].push_back(serializer.expression(stride));
×
NEW
174
    }
×
175

NEW
176
    j["pads"] = nlohmann::json::array();
×
NEW
177
    for (auto& pad : node.pads()) {
×
NEW
178
        j["pads"].push_back(serializer.expression(pad));
×
NEW
179
    }
×
180

NEW
181
    j["dilations"] = nlohmann::json::array();
×
NEW
182
    for (auto& dilation : node.dilations()) {
×
NEW
183
        j["dilations"].push_back(serializer.expression(dilation));
×
NEW
184
    }
×
185

NEW
186
    j["result_quant"] = node.quantization();
×
NEW
187
}
×
188

189
SpatialTensorNodeBaseSerializer::BaseDeser SpatialTensorNodeBaseSerializer::deserialize_base_values(const nlohmann::json&
NEW
190
                                                                                                        j) {
×
NEW
191
    assert(j.contains("element_id"));
×
NEW
192
    assert(j.contains("code"));
×
NEW
193
    assert(j.contains("debug_info"));
×
NEW
194
    assert(j.contains("kernel_shape"));
×
195

NEW
196
    std::vector<symbolic::Expression> shape;
×
NEW
197
    if (j.contains("shape")) {
×
NEW
198
        for (const auto& dim : j["shape"]) {
×
NEW
199
            shape.push_back(symbolic::parse(dim.get<std::string>()));
×
NEW
200
        }
×
NEW
201
    }
×
202

NEW
203
    std::vector<symbolic::Expression> kernel_shape;
×
NEW
204
    for (const auto& dim : j["kernel_shape"]) {
×
NEW
205
        kernel_shape.push_back(symbolic::parse(dim.get<std::string>()));
×
NEW
206
    }
×
207

NEW
208
    std::vector<symbolic::Expression> strides;
×
NEW
209
    if (j.contains("strides")) {
×
NEW
210
        for (const auto& stride : j["strides"]) {
×
NEW
211
            strides.push_back(symbolic::parse(stride.get<std::string>()));
×
NEW
212
        }
×
NEW
213
    }
×
214

NEW
215
    std::vector<symbolic::Expression> pads;
×
NEW
216
    if (j.contains("pads")) {
×
NEW
217
        for (const auto& pad : j["pads"]) {
×
NEW
218
            pads.push_back(symbolic::parse(pad.get<std::string>()));
×
NEW
219
        }
×
NEW
220
    }
×
221

NEW
222
    std::vector<symbolic::Expression> dilations;
×
NEW
223
    if (j.contains("dilations")) {
×
NEW
224
        for (const auto& dilation : j["dilations"]) {
×
NEW
225
            dilations.push_back(symbolic::parse(dilation.get<std::string>()));
×
NEW
226
        }
×
NEW
227
    }
×
228

NEW
229
    sdfg::serializer::JSONSerializer serializer;
×
NEW
230
    DebugInfo debug_info = serializer.json_to_debug_info(j["debug_info"]);
×
231

NEW
232
    return {
×
NEW
233
        .shape = shape,
×
NEW
234
        .kernel_shape = kernel_shape,
×
NEW
235
        .strides = strides,
×
NEW
236
        .pads = pads,
×
NEW
237
        .dilations = dilations,
×
NEW
238
        .quantization = deserialize_quantization(j, "result_quant", QUANTIZATION_MATCH_INPUTS),
×
NEW
239
        .debug_info = debug_info
×
NEW
240
    };
×
NEW
241
}
×
242

243
} // namespace sdfg::math::tensor
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