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

daisytuner / docc / 30307893616

27 Jul 2026 09:41PM UTC coverage: 64.157% (+0.02%) from 64.141%
30307893616

Pull #892

github

web-flow
Merge 52d98a7a3 into 080bf880c
Pull Request #892: adds aten.eq.scalar/tensor -> sdfg

12 of 12 new or added lines in 2 files covered. (100.0%)

1 existing line in 1 file now uncovered.

42863 of 66810 relevant lines covered (64.16%)

731.4 hits per line

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

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

3
#include <cstddef>
4
#include <memory>
5
#include <nlohmann/json_fwd.hpp>
6
#include <sstream>
7
#include <string>
8
#include <unordered_map>
9
#include <unordered_set>
10
#include <vector>
11

12
#include "sdfg/analysis/analysis.h"
13
#include "sdfg/builder/structured_sdfg_builder.h"
14
#include "sdfg/data_flow/access_node.h"
15
#include "sdfg/data_flow/data_flow_graph.h"
16
#include "sdfg/data_flow/data_flow_node.h"
17
#include "sdfg/data_flow/library_node.h"
18
#include "sdfg/data_flow/library_nodes/math/tensor/elementwise_node.h"
19
#include "sdfg/data_flow/library_nodes/math/tensor/tensor_node.h"
20
#include "sdfg/data_flow/tasklet.h"
21
#include "sdfg/element.h"
22
#include "sdfg/exceptions.h"
23
#include "sdfg/graph/graph.h"
24
#include "sdfg/serializer/json_serializer.h"
25
#include "sdfg/structured_control_flow/block.h"
26
#include "sdfg/structured_control_flow/sequence.h"
27
#include "sdfg/symbolic/symbolic.h"
28
#include "sdfg/types/scalar.h"
29
#include "sdfg/types/tensor.h"
30
#include "sdfg/types/type.h"
31

32
namespace sdfg {
33
namespace math {
34
namespace tensor {
35

36
TaskletTensorNode::TaskletTensorNode(
37
    size_t element_id,
38
    const DebugInfo& debug_info,
39
    const graph::Vertex vertex,
40
    data_flow::DataFlowGraph& parent,
41
    const data_flow::TaskletCode tasklet_code,
42
    const std::string& modified_tensor_conn,
43
    const std::vector<std::string>& tensor_inputs,
44
    const std::vector<symbolic::Expression>& shape,
45
    QuantizationType quantization,
46
    const data_flow::ImplementationType& impl_type
47
)
48
    : ElementWiseDataflowTensorNode(
208✔
49
          element_id,
208✔
50
          debug_info,
208✔
51
          vertex,
208✔
52
          parent,
208✔
53
          LibraryNodeType_TensorTasklet,
208✔
54
          shape,
208✔
55
          modified_tensor_conn,
208✔
56
          tensor_inputs,
208✔
57
          quantization,
208✔
58
          impl_type
208✔
59
      ),
208✔
60
      tasklet_code_(tasklet_code) {}
208✔
61

62
void TaskletTensorNode::validate(const Function& function) const {
208✔
63
    auto& graph = this->get_parent();
208✔
64
    this->validate_target_tensor(graph);
208✔
65
    this->validate_all_input_tensors(graph);
208✔
66
    this->validate_non_tensor_inputs(graph);
208✔
67

68
    // Validate: inputs match arity
69
    auto actual_inputs = this->inputs_.size() - 1;
208✔
70
    if (data_flow::arity(this->tasklet_code()) != actual_inputs) {
208✔
71
        throw InvalidSDFGException(
×
72
            "TaskletTensorNode #" + std::to_string(element_id_) + ": (Code: " + std::to_string(this->tasklet_code()) +
×
73
            "): Invalid number of inputs. Expected " + std::to_string(data_flow::arity(this->tasklet_code())) +
×
74
            ", got " + std::to_string(actual_inputs)
×
75
        );
×
76
    }
×
77

78
    // Validate: inputs match type of operation (check A and B operands, skipping C)
79
    for (int i = 1; i < tensor_input_count(); ++i) {
616✔
80
        auto* iedge = graph.in_edge_for_connector(*this, inputs_.at(i));
408✔
81
        if (!iedge) continue;
408✔
82
        auto input_type = iedge->result_type(function);
408✔
83
        if (data_flow::is_integer(this->tasklet_code()) && !types::is_integer(input_type->primitive_type())) {
408✔
84
            throw InvalidSDFGException(
×
85
                "TaskletTensorNode #" + std::to_string(element_id_) +
×
86
                ": (Code: " + std::to_string(this->tasklet_code()) + "): Integer operation with non-integer input type"
×
87
            );
×
88
        }
×
89
        if (data_flow::is_floating_point(this->tasklet_code()) &&
408✔
90
            !types::is_floating_point(input_type->primitive_type())) {
408✔
91
            throw InvalidSDFGException(
×
92
                "TaskletTensorNode #" + std::to_string(element_id_) + ": (Code: " +
×
93
                std::to_string(this->tasklet_code()) + "): Floating point operation with integer input type"
×
94
            );
×
95
        }
×
96
    }
408✔
97
}
208✔
98

99
data_flow::TaskletCode TaskletTensorNode::tasklet_code() const { return this->tasklet_code_; }
1,232✔
100

UNCOV
101
bool TaskletTensorNode::supports_integer_types() const { return data_flow::is_integer(this->tasklet_code()); }
×
102

103
ElementWiseDataflowTensorNode::ElementOutput TaskletTensorNode::expand_operation_dataflow(
104
    builder::StructuredSDFGBuilder& builder,
105
    Block& block,
106
    std::vector<ElementInput>& needed_inputs,
107
    types::PrimitiveType expected_type
108
) {
208✔
109
    auto code = this->tasklet_code();
208✔
110
    auto code_arity = data_flow::arity(code);
208✔
111
    if (code_arity > needed_inputs.size()) {
208✔
112
        return {}; // not mappable, probably invalid
×
113
    }
×
114

115
    auto prim_type = needed_inputs.at(0).required_type;
208✔
116
    std::vector<std::string> tasklet_inputs;
208✔
117
    tasklet_inputs.reserve(code_arity);
208✔
118
    for (int i = 0; i < code_arity; ++i) {
616✔
119
        tasklet_inputs.push_back(inputs_.at(1 + i));
408✔
120
    }
408✔
121

122
    auto& tasklet = builder.add_tasklet(block, code, "_out", tasklet_inputs, debug_info_);
208✔
123
    auto& inputs = tasklet.inputs();
208✔
124
    for (size_t i = 0; i < code_arity; i++) {
616✔
125
        auto& tensor_input = needed_inputs.at(i);
408✔
126
        tensor_input.consumer = &tasklet;
408✔
127
        tensor_input.input_conn_index = i;
408✔
128
    }
408✔
129

130
    // validate that expected_type is also output by tasklet function
131

132
    return {.producer = &tasklet, .output_conn_index = 0, .type = expected_type};
208✔
133
}
208✔
134

135
std::unique_ptr<data_flow::DataFlowNode> TaskletTensorNode::
136
    clone(size_t element_id, const graph::Vertex vertex, data_flow::DataFlowGraph& parent) const {
×
137
    return std::unique_ptr<data_flow::DataFlowNode>(new TaskletTensorNode(
×
138
        element_id,
×
139
        this->debug_info(),
×
140
        vertex,
×
141
        parent,
×
142
        this->tasklet_code(),
×
143
        inputs_.at(0),
×
144
        std::vector<std::string>(inputs_.cbegin() + 1, inputs_.cend()),
×
145
        this->shape(),
×
146
        fixed_quantization_,
×
147
        implementation_type_
×
148
    ));
×
149
}
×
150

151
std::string TaskletTensorNode::toStr() const {
×
152
    std::stringstream stream;
×
153

154
    stream << this->code().value() << ": " << std::to_string(this->tasklet_code()) << ", [";
×
155
    for (size_t i = 0; i < this->shape().size(); i++) {
×
156
        if (i > 0) {
×
157
            stream << ", ";
×
158
        }
×
159
        stream << this->shape().at(i)->__str__();
×
160
    }
×
161
    stream << "]";
×
162

163
    return stream.str();
×
164
}
×
165

166
nlohmann::json TaskletTensorNodeSerializer::serialize(const data_flow::LibraryNode& library_node) {
×
167
    const auto& elem_node = static_cast<const TaskletTensorNode&>(library_node);
×
168
    nlohmann::json j = BaseElementWiseDataflowTensorNodeSerializer::serialize(library_node);
×
169

170
    auto input_arr = nlohmann::json::array();
×
171
    for (auto& input : elem_node.inputs()) {
×
172
        input_arr.push_back(input);
×
173
    }
×
174
    j["inputs"] = input_arr;
×
175

176
    j["tasklet_code"] = elem_node.tasklet_code();
×
177

178
    return j;
×
179
}
×
180

181
data_flow::LibraryNode& TaskletTensorNodeSerializer::deserialize(
182
    const nlohmann::json& j, builder::StructuredSDFGBuilder& builder, structured_control_flow::Block& parent
183
) {
×
184
    auto base = deserialize_base_values(j);
×
185

186
    // Assertions for required fields
187
    assert(j.contains("inputs"));
×
188
    assert(j.contains("tasklet_code"));
×
189

190
    std::vector<std::string> inputs;
×
191
    for (const auto& input : j["inputs"]) {
×
192
        inputs.push_back(input.get<std::string>());
×
193
    }
×
194

195
    auto tasklet_code = static_cast<data_flow::TaskletCode>(j["tasklet_code"].get<int>());
×
196

197
    std::vector<std::string> tensor_inputs(inputs.cbegin() + 1, inputs.cend());
×
198

199
    return static_cast<TaskletTensorNode&>(builder.add_library_node<TaskletTensorNode>(
×
200
        parent, base.debug_info, tasklet_code, inputs.at(0), tensor_inputs, base.shape, base.quantization
×
201
    ));
×
202
}
×
203

204
} // namespace tensor
205
} // namespace math
206
} // namespace sdfg
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc