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

daisytuner / docc / 29936384397

22 Jul 2026 04:04PM UTC coverage: 64.072% (+0.3%) from 63.782%
29936384397

Pull #868

github

web-flow
Merge 67eee0fe8 into d833d292d
Pull Request #868: Add tensor concatenation to PyTorch frontend (and MLIR frontend)

352 of 454 new or added lines in 19 files covered. (77.53%)

4 existing lines in 2 files now uncovered.

42634 of 66541 relevant lines covered (64.07%)

739.99 hits per line

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

63.94
/sdfg/src/builder/function_builder.cpp
1
#include "sdfg/builder/function_builder.h"
2

3
namespace sdfg {
4
namespace builder {
5

6
void check_name(const std::string& name) {
8,845✔
7
    if (name.find(".") != std::string::npos) {
8,845✔
8
        throw InvalidSDFGException("Container name " + name + " contains a dot");
×
9
    } else if (name.find(" ") != std::string::npos) {
8,845✔
10
        throw InvalidSDFGException("Container name " + name + " contains a space");
×
11
    } else if (name.find("(") != std::string::npos) {
8,845✔
12
        throw InvalidSDFGException("Container name " + name + " contains a parenthesis");
×
13
    } else if (name.find(")") != std::string::npos) {
8,845✔
14
        throw InvalidSDFGException("Container name " + name + " contains a parenthesis");
×
15
    } else if (name.find("[") != std::string::npos) {
8,845✔
16
        throw InvalidSDFGException("Container name " + name + " contains a bracket");
×
17
    } else if (name.find("]") != std::string::npos) {
8,845✔
18
        throw InvalidSDFGException("Container name " + name + " contains a bracket");
×
19
    } else if (name.find("*") != std::string::npos) {
8,845✔
20
        throw InvalidSDFGException("Container name " + name + " contains a star");
×
21
    } else if (name.find("&") != std::string::npos) {
8,845✔
22
        throw InvalidSDFGException("Container name " + name + " contains a ampersand");
×
23
    } else if (name.find("!") != std::string::npos) {
8,845✔
24
        throw InvalidSDFGException("Container name " + name + " contains a bang");
×
25
    } else if (name.find("~") != std::string::npos) {
8,845✔
26
        throw InvalidSDFGException("Container name " + name + " contains a tilde");
×
27
    } else if (name.find("`") != std::string::npos) {
8,845✔
28
        throw InvalidSDFGException("Container name " + name + " contains a backtick");
×
29
    } else if (name.find("\"") != std::string::npos) {
8,845✔
30
        throw InvalidSDFGException("Container name " + name + " contains a quote");
×
31
    } else if (name.find("'") != std::string::npos) {
8,845✔
32
        throw InvalidSDFGException("Container name " + name + " contains a single quote");
×
33
    } else if (name.find(";") != std::string::npos) {
8,845✔
34
        throw InvalidSDFGException("Container name " + name + " contains a semicolon");
×
35
    } else if (name.find(":") != std::string::npos) {
8,845✔
36
        throw InvalidSDFGException("Container name " + name + " contains a colon");
×
37
    } else if (name.find(",") != std::string::npos) {
8,845✔
38
        throw InvalidSDFGException("Container name " + name + " contains a comma");
×
39
    } else if (name.find("=") != std::string::npos) {
8,845✔
40
        throw InvalidSDFGException("Container name " + name + " contains a equal sign");
×
41
    } else if (name.find("+") != std::string::npos) {
8,845✔
42
        throw InvalidSDFGException("Container name " + name + " contains a plus sign");
×
43
    } else if (name.find("-") != std::string::npos) {
8,845✔
44
        throw InvalidSDFGException("Container name " + name + " contains a minus sign");
×
45
    } else if (name.find("/") != std::string::npos) {
8,845✔
46
        throw InvalidSDFGException("Container name " + name + " contains a slash");
×
47
    } else if (name.find("%") != std::string::npos) {
8,845✔
48
        throw InvalidSDFGException("Container name " + name + " contains a percent sign");
×
49
    } else if (name.find("^") != std::string::npos) {
8,845✔
50
        throw InvalidSDFGException("Container name " + name + " contains a caret");
×
51
    } else if (name.find("|") != std::string::npos) {
8,845✔
52
        throw InvalidSDFGException("Container name " + name + " contains a pipe");
×
53
    }
×
54
};
8,845✔
55

56
size_t FunctionBuilder::new_element_id() const { return ++this->function().element_counter_; };
29,899✔
57

58
size_t FunctionBuilder::new_element_id_batch(size_t batch) const {
8,667✔
59
    auto& count = this->function().element_counter_;
8,667✔
60
    auto prev = count;
8,667✔
61
    count += batch;
8,667✔
62

63
    return prev + 1;
8,667✔
64
}
8,667✔
65

66
void FunctionBuilder::set_element_counter(size_t element_counter) {
60✔
67
    this->function().element_counter_ = element_counter;
60✔
68
};
60✔
69

70
void FunctionBuilder::replace_symbols(const symbolic::Expression old_expression, const symbolic::Expression new_expression) {
1✔
71
    this->function().return_type_->replace_symbols(old_expression, new_expression);
1✔
72
    for (auto& container : this->function().containers_) {
8✔
73
        container.second->replace_symbols(old_expression, new_expression);
8✔
74
    }
8✔
75
    for (auto& structure : this->function().structures_) {
1✔
NEW
76
        structure.second->replace_symbols(old_expression, new_expression);
×
NEW
77
    }
×
78
}
1✔
79

80
void FunctionBuilder::replace_symbols(const symbolic::ExpressionMapping& replacements) {
1✔
81
    this->function().return_type_->replace_symbols(replacements);
1✔
82
    for (auto& container : this->function().containers_) {
8✔
83
        container.second->replace_symbols(replacements);
8✔
84
    }
8✔
85
    for (auto& structure : this->function().structures_) {
1✔
NEW
86
        structure.second->replace_symbols(replacements);
×
NEW
87
    }
×
88
}
1✔
89

UNCOV
90
void FunctionBuilder::set_return_type(const types::IType& type) const { this->function().return_type_ = type.clone(); };
×
91

92
const types::IType& FunctionBuilder::
93
    add_container(const std::string& name, const types::IType& type, bool is_argument, bool is_external) const {
8,826✔
94
    if (type.type_id() == types::TypeID::Tensor) {
8,826✔
95
        throw InvalidSDFGException(
×
96
            "Tensor types are virtual types, add a pointer instead and use the tensor type on memlets"
×
97
        );
×
98
    }
×
99

100
    if (is_argument && is_external) {
8,826✔
101
        throw InvalidSDFGException("Container " + name + " cannot be both an argument and an external");
×
102
    }
×
103
    // Legal name
104
    check_name(name);
8,826✔
105

106
    auto res = this->function().containers_.insert({name, type.clone()});
8,826✔
107
    if (!res.second) {
8,826✔
108
        throw InvalidSDFGException("Container " + name + " already exists");
×
109
    }
×
110

111
    if (is_argument) {
8,826✔
112
        this->function().arguments_.push_back(name);
3,016✔
113
    }
3,016✔
114
    if (is_external) {
8,826✔
115
        this->function().externals_.push_back(name);
14✔
116
        this->function().externals_linkage_types_[name] = LinkageType_External;
14✔
117
    }
14✔
118
    if (type.is_symbol()) {
8,826✔
119
        auto sym = symbolic::symbol(name);
7,592✔
120
        this->function().assumptions_.insert({sym, symbolic::Assumption::create(sym, type)});
7,592✔
121
    }
7,592✔
122

123
    return *(*res.first).second;
8,826✔
124
};
8,826✔
125

126
const types::IType& FunctionBuilder::
127
    add_external(const std::string& name, const types::IType& type, LinkageType linkage_type) const {
19✔
128
    check_name(name);
19✔
129

130
    auto res = this->function().containers_.insert({name, type.clone()});
19✔
131
    if (!res.second) {
19✔
132
        throw InvalidSDFGException("Container " + name + " already exists");
×
133
    }
×
134

135
    this->function().externals_.push_back(name);
19✔
136
    this->function().externals_linkage_types_[name] = linkage_type;
19✔
137

138
    return *(*res.first).second;
19✔
139
};
19✔
140

141
void FunctionBuilder::remove_container(const std::string& name) const {
27✔
142
    auto& function = this->function();
27✔
143
    if (!function.is_transient(name)) {
27✔
144
        throw InvalidSDFGException("Container " + name + " is not transient");
2✔
145
    }
2✔
146
    if (this->function().containers_.find(name) == this->function().containers_.end()) {
25✔
147
        throw InvalidSDFGException("Container " + name + " does not exist");
×
148
    }
×
149

150
    auto& type = function.containers_[name];
25✔
151
    if (type->is_symbol() && dynamic_cast<const types::Scalar*>(type.get())) {
25✔
152
        function.assumptions_.erase(symbolic::symbol(name));
19✔
153
    }
19✔
154

155
    function.containers_.erase(name);
25✔
156
};
25✔
157

158
void FunctionBuilder::rename_container(const std::string& old_name, const std::string& new_name) const {
26✔
159
    auto& function = this->function();
26✔
160
    if (!function.exists(old_name)) {
26✔
161
        throw InvalidSDFGException("Container " + old_name + " does not exist");
×
162
    }
×
163

164
    // Move type
165
    function.containers_[new_name] = std::move(function.containers_[old_name]);
26✔
166
    function.containers_.erase(old_name);
26✔
167

168
    // Handling of argument
169
    if (function.is_argument(old_name)) {
26✔
170
        auto it = std::find(function.arguments_.begin(), function.arguments_.end(), old_name);
×
171
        assert(it != function.arguments_.end());
×
172
        *it = new_name;
×
173
    }
×
174
    // Handling of external
175
    if (function.is_external(old_name)) {
26✔
176
        auto it = std::find(function.externals_.begin(), function.externals_.end(), old_name);
×
177
        assert(it != function.externals_.end());
×
178
        *it = new_name;
×
179
        function.externals_linkage_types_[new_name] = function.externals_linkage_types_[old_name];
×
180
        function.externals_linkage_types_.erase(old_name);
×
181
    }
×
182
    // Handling of assumption
183
    if (function.assumptions().find(symbolic::symbol(old_name)) != function.assumptions().end()) {
26✔
184
        auto assumption = function.assumption(symbolic::symbol(old_name));
26✔
185

186
        symbolic::Assumption new_assumption(symbolic::symbol(new_name));
26✔
187
        new_assumption.tight_lower_bound(assumption.tight_lower_bound());
26✔
188
        new_assumption.tight_upper_bound(assumption.tight_upper_bound());
26✔
189
        for (auto& lb : assumption.lower_bounds()) {
26✔
190
            new_assumption.add_lower_bound(lb);
26✔
191
        }
26✔
192
        for (auto& ub : assumption.upper_bounds()) {
26✔
193
            new_assumption.add_upper_bound(ub);
26✔
194
        }
26✔
195

196
        new_assumption.constant(assumption.constant());
26✔
197
        new_assumption.map(assumption.map());
26✔
198

199
        function.assumptions_.erase(symbolic::symbol(old_name));
26✔
200
        function.assumptions_.insert({new_assumption.symbol(), new_assumption});
26✔
201
    }
26✔
202
};
26✔
203

204
void FunctionBuilder::change_type(const std::string& name, const types::IType& type) const {
19✔
205
    auto& function = this->function();
19✔
206
    if (function.containers_.find(name) == function.containers_.end()) {
19✔
207
        throw InvalidSDFGException("Container " + name + " does not exist");
×
208
    }
×
209

210
    function.containers_[name] = type.clone();
19✔
211
};
19✔
212

213
types::StructureDefinition& FunctionBuilder::add_structure(const std::string& name, bool is_packed) const {
20✔
214
    if (this->function().structures_.find(name) != this->function().structures_.end()) {
20✔
215
        throw InvalidSDFGException("Structure " + name + " already exists");
×
216
    }
×
217

218
    auto res = this->function().structures_.insert({name, std::make_unique<types::StructureDefinition>(name, is_packed)}
20✔
219
    );
20✔
220
    if (!res.second) {
20✔
221
        throw InvalidSDFGException("Structure " + name + " already exists");
×
222
    }
×
223

224
    return *(*res.first).second;
20✔
225
};
20✔
226

227
std::string FunctionBuilder::find_new_name(std::string prefix) const {
2,045✔
228
    size_t i = 0;
2,045✔
229
    std::string new_name = prefix + std::to_string(i);
2,045✔
230
    while (this->function().exists(new_name)) {
3,444✔
231
        i++;
1,399✔
232
        new_name = prefix + std::to_string(i);
1,399✔
233
    }
1,399✔
234
    return new_name;
2,045✔
235
};
2,045✔
236

237
void FunctionBuilder::update_tasklet(data_flow::Tasklet& tasklet, const data_flow::TaskletCode code) {
×
238
    tasklet.code_ = code;
×
239
}
×
240

241
std::unique_ptr<types::Structure> FunctionBuilder::
242
    create_vector_type(const types::Scalar& element_type, size_t vector_size) {
×
243
    std::string struct_name = "__daisy_vec_" + std::to_string(element_type.primitive_type()) + "_" +
×
244
                              std::to_string(vector_size);
×
245
    auto defined_structures = this->function().structures();
×
246
    if (std::find(defined_structures.begin(), defined_structures.end(), struct_name) != defined_structures.end()) {
×
247
        return std::make_unique<types::Structure>(struct_name);
×
248
    }
×
249

250
    auto& struct_def = this->add_structure(struct_name, true);
×
251
    for (size_t i = 0; i < vector_size; i++) {
×
252
        struct_def.add_member(element_type);
×
253
    }
×
254

255
    return std::make_unique<types::Structure>(struct_name);
×
256
}
×
257

258
} // namespace builder
259
} // 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