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

daisytuner / sdfglib / 15731283590

18 Jun 2025 11:12AM UTC coverage: 64.351% (-0.2%) from 64.576%
15731283590

Pull #86

github

web-flow
Merge 99df43790 into 32b5d7ae4
Pull Request #86: Add optimizer functionality

144 of 227 new or added lines in 9 files covered. (63.44%)

453 existing lines in 14 files now uncovered.

8125 of 12626 relevant lines covered (64.35%)

153.57 hits per line

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

24.46
/src/codegen/language_extensions/c_language_extension.cpp
1
#include "sdfg/codegen/language_extensions/c_language_extension.h"
2

3
#include <cstddef>
4
#include <string>
5

6
#include "sdfg/codegen/utils.h"
7
#include "sdfg/data_flow/tasklet.h"
8
#include "sdfg/exceptions.h"
9
#include "sdfg/types/type.h"
10

11
namespace sdfg {
12
namespace codegen {
13

14
constexpr const char* code_to_string(data_flow::TaskletCode c) {
2✔
15
    switch (c) {
2✔
16
        case data_flow::TaskletCode::assign:
UNCOV
17
            return "=";
×
18
        case data_flow::TaskletCode::neg:
UNCOV
19
            return "-";
×
20
        case data_flow::TaskletCode::add:
21
            return "+";
2✔
22
        case data_flow::TaskletCode::sub:
UNCOV
23
            return "-";
×
24
        case data_flow::TaskletCode::mul:
UNCOV
25
            return "*";
×
26
        case data_flow::TaskletCode::div:
UNCOV
27
            return "/";
×
28
        case data_flow::TaskletCode::fma:
UNCOV
29
            return "__daisy_fma";
×
30
        case data_flow::TaskletCode::mod:
UNCOV
31
            return "%";
×
32
        case data_flow::TaskletCode::max:
UNCOV
33
            return "__daisy_max";
×
34
        case data_flow::TaskletCode::min:
UNCOV
35
            return "__daisy_min";
×
36
        case data_flow::TaskletCode::minnum:
UNCOV
37
            return "minnum";
×
38
        case data_flow::TaskletCode::maxnum:
UNCOV
39
            return "maxnum";
×
40
        case data_flow::TaskletCode::minimum:
UNCOV
41
            return "minimum";
×
42
        case data_flow::TaskletCode::maximum:
UNCOV
43
            return "maximum";
×
44
        case data_flow::TaskletCode::trunc:
UNCOV
45
            return "trunc";
×
46
        case data_flow::TaskletCode::logical_and:
UNCOV
47
            return "&&";
×
48
        case data_flow::TaskletCode::logical_or:
UNCOV
49
            return "||";
×
50
        case data_flow::TaskletCode::bitwise_and:
UNCOV
51
            return "&";
×
52
        case data_flow::TaskletCode::bitwise_or:
UNCOV
53
            return "|";
×
54
        case data_flow::TaskletCode::bitwise_xor:
UNCOV
55
            return "^";
×
56
        case data_flow::TaskletCode::bitwise_not:
UNCOV
57
            return "~";
×
58
        case data_flow::TaskletCode::shift_left:
UNCOV
59
            return "<<";
×
60
        case data_flow::TaskletCode::shift_right:
UNCOV
61
            return ">>";
×
62
        case data_flow::TaskletCode::olt:
UNCOV
63
            return "<";
×
64
        case data_flow::TaskletCode::ole:
UNCOV
65
            return "<=";
×
66
        case data_flow::TaskletCode::oeq:
UNCOV
67
            return "==";
×
68
        case data_flow::TaskletCode::one:
UNCOV
69
            return "!=";
×
70
        case data_flow::TaskletCode::oge:
UNCOV
71
            return ">=";
×
72
        case data_flow::TaskletCode::ogt:
UNCOV
73
            return ">";
×
74
        case data_flow::TaskletCode::ord:
UNCOV
75
            return "==";
×
76
        case data_flow::TaskletCode::ult:
UNCOV
77
            return "<";
×
78
        case data_flow::TaskletCode::ule:
UNCOV
79
            return "<=";
×
80
        case data_flow::TaskletCode::ueq:
UNCOV
81
            return "==";
×
82
        case data_flow::TaskletCode::une:
UNCOV
83
            return "!=";
×
84
        case data_flow::TaskletCode::uge:
UNCOV
85
            return ">=";
×
86
        case data_flow::TaskletCode::ugt:
UNCOV
87
            return ">";
×
88
        case data_flow::TaskletCode::uno:
UNCOV
89
            return "!=";
×
90
        case data_flow::TaskletCode::abs:
UNCOV
91
            return "abs";
×
92
        case data_flow::TaskletCode::acos:
UNCOV
93
            return "acos";
×
94
        case data_flow::TaskletCode::acosf:
UNCOV
95
            return "acosf";
×
96
        case data_flow::TaskletCode::acosl:
UNCOV
97
            return "acosl";
×
98
        case data_flow::TaskletCode::acosh:
UNCOV
99
            return "acosh";
×
100
        case data_flow::TaskletCode::acoshf:
UNCOV
101
            return "acoshf";
×
102
        case data_flow::TaskletCode::acoshl:
UNCOV
103
            return "acoshl";
×
104
        case data_flow::TaskletCode::asin:
UNCOV
105
            return "asin";
×
106
        case data_flow::TaskletCode::asinf:
UNCOV
107
            return "asinf";
×
108
        case data_flow::TaskletCode::asinl:
UNCOV
109
            return "asinl";
×
110
        case data_flow::TaskletCode::asinh:
UNCOV
111
            return "asinh";
×
112
        case data_flow::TaskletCode::asinhf:
UNCOV
113
            return "asinhf";
×
114
        case data_flow::TaskletCode::asinhl:
UNCOV
115
            return "asinhl";
×
116
        case data_flow::TaskletCode::atan:
UNCOV
117
            return "atan";
×
118
        case data_flow::TaskletCode::atanf:
UNCOV
119
            return "atanf";
×
120
        case data_flow::TaskletCode::atanl:
UNCOV
121
            return "atanl";
×
122
        case data_flow::TaskletCode::atan2:
UNCOV
123
            return "atan2";
×
124
        case data_flow::TaskletCode::atan2f:
UNCOV
125
            return "atan2f";
×
126
        case data_flow::TaskletCode::atan2l:
UNCOV
127
            return "atan2l";
×
128
        case data_flow::TaskletCode::atanh:
UNCOV
129
            return "atanh";
×
130
        case data_flow::TaskletCode::atanhf:
UNCOV
131
            return "atanhf";
×
132
        case data_flow::TaskletCode::atanhl:
UNCOV
133
            return "atanhl";
×
134
        case data_flow::TaskletCode::cabs:
UNCOV
135
            return "cabs";
×
136
        case data_flow::TaskletCode::cabsf:
UNCOV
137
            return "cabsf";
×
138
        case data_flow::TaskletCode::cabsl:
UNCOV
139
            return "cabsl";
×
140
        case data_flow::TaskletCode::ceil:
UNCOV
141
            return "ceil";
×
142
        case data_flow::TaskletCode::ceilf:
UNCOV
143
            return "ceilf";
×
144
        case data_flow::TaskletCode::ceill:
UNCOV
145
            return "ceill";
×
146
        case data_flow::TaskletCode::copysign:
UNCOV
147
            return "copysign";
×
148
        case data_flow::TaskletCode::copysignf:
UNCOV
149
            return "copysignf";
×
150
        case data_flow::TaskletCode::copysignl:
UNCOV
151
            return "copysignl";
×
152
        case data_flow::TaskletCode::cos:
UNCOV
153
            return "cos";
×
154
        case data_flow::TaskletCode::cosf:
UNCOV
155
            return "cosf";
×
156
        case data_flow::TaskletCode::cosl:
UNCOV
157
            return "cosl";
×
158
        case data_flow::TaskletCode::cosh:
UNCOV
159
            return "cosh";
×
160
        case data_flow::TaskletCode::coshf:
UNCOV
161
            return "coshf";
×
162
        case data_flow::TaskletCode::coshl:
UNCOV
163
            return "coshl";
×
164
        case data_flow::TaskletCode::cbrt:
UNCOV
165
            return "cbrt";
×
166
        case data_flow::TaskletCode::cbrtf:
UNCOV
167
            return "cbrtf";
×
168
        case data_flow::TaskletCode::cbrtl:
UNCOV
169
            return "cbrtl";
×
170
        case data_flow::TaskletCode::exp10:
UNCOV
171
            return "exp10";
×
172
        case data_flow::TaskletCode::exp10f:
UNCOV
173
            return "exp10f";
×
174
        case data_flow::TaskletCode::exp10l:
UNCOV
175
            return "exp10l";
×
176
        case data_flow::TaskletCode::exp2:
UNCOV
177
            return "exp2";
×
178
        case data_flow::TaskletCode::exp2f:
UNCOV
179
            return "exp2f";
×
180
        case data_flow::TaskletCode::exp2l:
UNCOV
181
            return "exp2l";
×
182
        case data_flow::TaskletCode::exp:
UNCOV
183
            return "exp";
×
184
        case data_flow::TaskletCode::expf:
UNCOV
185
            return "expf";
×
186
        case data_flow::TaskletCode::expl:
UNCOV
187
            return "expl";
×
188
        case data_flow::TaskletCode::expm1:
UNCOV
189
            return "expm1";
×
190
        case data_flow::TaskletCode::expm1f:
UNCOV
191
            return "expm1f";
×
192
        case data_flow::TaskletCode::expm1l:
UNCOV
193
            return "expm1l";
×
194
        case data_flow::TaskletCode::fabs:
UNCOV
195
            return "fabs";
×
196
        case data_flow::TaskletCode::fabsf:
UNCOV
197
            return "fabsf";
×
198
        case data_flow::TaskletCode::fabsl:
UNCOV
199
            return "fabsl";
×
200
        case data_flow::TaskletCode::floor:
UNCOV
201
            return "floor";
×
202
        case data_flow::TaskletCode::floorf:
UNCOV
203
            return "floorf";
×
204
        case data_flow::TaskletCode::floorl:
UNCOV
205
            return "floorl";
×
206
        case data_flow::TaskletCode::fls:
UNCOV
207
            return "fls";
×
208
        case data_flow::TaskletCode::flsl:
UNCOV
209
            return "flsl";
×
210
        case data_flow::TaskletCode::fmax:
UNCOV
211
            return "fmax";
×
212
        case data_flow::TaskletCode::fmaxf:
UNCOV
213
            return "fmaxf";
×
214
        case data_flow::TaskletCode::fmaxl:
UNCOV
215
            return "fmaxl";
×
216
        case data_flow::TaskletCode::fmin:
UNCOV
217
            return "fmin";
×
218
        case data_flow::TaskletCode::fminf:
UNCOV
219
            return "fminf";
×
220
        case data_flow::TaskletCode::fminl:
UNCOV
221
            return "fminl";
×
222
        case data_flow::TaskletCode::fmod:
UNCOV
223
            return "fmod";
×
224
        case data_flow::TaskletCode::fmodf:
UNCOV
225
            return "fmodf";
×
226
        case data_flow::TaskletCode::fmodl:
UNCOV
227
            return "fmodl";
×
228
        case data_flow::TaskletCode::frexp:
UNCOV
229
            return "frexp";
×
230
        case data_flow::TaskletCode::frexpf:
UNCOV
231
            return "frexpf";
×
232
        case data_flow::TaskletCode::frexpl:
UNCOV
233
            return "frexpl";
×
234
        case data_flow::TaskletCode::labs:
UNCOV
235
            return "labs";
×
236
        case data_flow::TaskletCode::ldexp:
UNCOV
237
            return "ldexp";
×
238
        case data_flow::TaskletCode::ldexpf:
UNCOV
239
            return "ldexpf";
×
240
        case data_flow::TaskletCode::ldexpl:
UNCOV
241
            return "ldexpl";
×
242
        case data_flow::TaskletCode::log10:
UNCOV
243
            return "log10";
×
244
        case data_flow::TaskletCode::log10f:
UNCOV
245
            return "log10f";
×
246
        case data_flow::TaskletCode::log10l:
UNCOV
247
            return "log10l";
×
248
        case data_flow::TaskletCode::log2:
UNCOV
249
            return "log2";
×
250
        case data_flow::TaskletCode::log2f:
UNCOV
251
            return "log2f";
×
252
        case data_flow::TaskletCode::log2l:
UNCOV
253
            return "log2l";
×
254
        case data_flow::TaskletCode::log:
UNCOV
255
            return "log";
×
256
        case data_flow::TaskletCode::logf:
UNCOV
257
            return "logf";
×
258
        case data_flow::TaskletCode::logl:
UNCOV
259
            return "logl";
×
260
        case data_flow::TaskletCode::logb:
UNCOV
261
            return "logb";
×
262
        case data_flow::TaskletCode::logbf:
UNCOV
263
            return "logbf";
×
264
        case data_flow::TaskletCode::logbl:
UNCOV
265
            return "logbl";
×
266
        case data_flow::TaskletCode::log1p:
UNCOV
267
            return "log1p";
×
268
        case data_flow::TaskletCode::log1pf:
UNCOV
269
            return "log1pf";
×
270
        case data_flow::TaskletCode::log1pl:
UNCOV
271
            return "log1pl";
×
272
        case data_flow::TaskletCode::modf:
UNCOV
273
            return "modf";
×
274
        case data_flow::TaskletCode::modff:
UNCOV
275
            return "modff";
×
276
        case data_flow::TaskletCode::modfl:
UNCOV
277
            return "modfl";
×
278
        case data_flow::TaskletCode::nearbyint:
UNCOV
279
            return "nearbyint";
×
280
        case data_flow::TaskletCode::nearbyintf:
UNCOV
281
            return "nearbyintf";
×
282
        case data_flow::TaskletCode::nearbyintl:
UNCOV
283
            return "nearbyintl";
×
284
        case data_flow::TaskletCode::pow:
UNCOV
285
            return "pow";
×
286
        case data_flow::TaskletCode::powf:
UNCOV
287
            return "powf";
×
288
        case data_flow::TaskletCode::powl:
UNCOV
289
            return "powl";
×
290
        case data_flow::TaskletCode::rint:
UNCOV
291
            return "rint";
×
292
        case data_flow::TaskletCode::rintf:
UNCOV
293
            return "rintf";
×
294
        case data_flow::TaskletCode::rintl:
UNCOV
295
            return "rintl";
×
296
        case data_flow::TaskletCode::round:
UNCOV
297
            return "round";
×
298
        case data_flow::TaskletCode::roundf:
UNCOV
299
            return "roundf";
×
300
        case data_flow::TaskletCode::roundl:
UNCOV
301
            return "roundl";
×
302
        case data_flow::TaskletCode::roundeven:
UNCOV
303
            return "roundeven";
×
304
        case data_flow::TaskletCode::roundevenf:
UNCOV
305
            return "roundevenf";
×
306
        case data_flow::TaskletCode::roundevenl:
UNCOV
307
            return "roundevenl";
×
308
        case data_flow::TaskletCode::sin:
UNCOV
309
            return "sin";
×
310
        case data_flow::TaskletCode::sinf:
UNCOV
311
            return "sinf";
×
312
        case data_flow::TaskletCode::sinl:
UNCOV
313
            return "sinl";
×
314
        case data_flow::TaskletCode::sinh:
UNCOV
315
            return "sinh";
×
316
        case data_flow::TaskletCode::sinhf:
UNCOV
317
            return "sinhf";
×
318
        case data_flow::TaskletCode::sinhl:
UNCOV
319
            return "sinhl";
×
320
        case data_flow::TaskletCode::sqrt:
UNCOV
321
            return "sqrt";
×
322
        case data_flow::TaskletCode::sqrtf:
UNCOV
323
            return "sqrtf";
×
324
        case data_flow::TaskletCode::sqrtl:
UNCOV
325
            return "sqrtl";
×
326
        case data_flow::TaskletCode::tan:
UNCOV
327
            return "tan";
×
328
        case data_flow::TaskletCode::tanf:
UNCOV
329
            return "tanf";
×
330
        case data_flow::TaskletCode::tanl:
UNCOV
331
            return "tanl";
×
332
        case data_flow::TaskletCode::tanh:
UNCOV
333
            return "tanh";
×
334
        case data_flow::TaskletCode::tanhf:
UNCOV
335
            return "tanhf";
×
336
        case data_flow::TaskletCode::tanhl:
UNCOV
337
            return "tanhl";
×
338
    };
UNCOV
339
    throw std::invalid_argument("Invalid tasklet code");
×
340
};
2✔
341

342
std::string CLanguageExtension::primitive_type(const types::PrimitiveType prim_type) {
26✔
343
    switch (prim_type) {
26✔
344
        case types::PrimitiveType::Void:
345
            return "void";
1✔
346
        case types::PrimitiveType::Bool:
347
            return "bool";
1✔
348
        case types::PrimitiveType::Int8:
349
            return "signed char";
1✔
350
        case types::PrimitiveType::Int16:
351
            return "short";
1✔
352
        case types::PrimitiveType::Int32:
353
            return "int";
12✔
354
        case types::PrimitiveType::Int64:
355
            return "long long";
1✔
356
        case types::PrimitiveType::Int128:
UNCOV
357
            return "__int128";
×
358
        case types::PrimitiveType::UInt8:
359
            return "char";
3✔
360
        case types::PrimitiveType::UInt16:
361
            return "unsigned short";
1✔
362
        case types::PrimitiveType::UInt32:
363
            return "unsigned int";
1✔
364
        case types::PrimitiveType::UInt64:
365
            return "unsigned long long";
1✔
366
        case types::PrimitiveType::UInt128:
UNCOV
367
            return "unsigned __int128";
×
368
        case types::PrimitiveType::Half:
UNCOV
369
            return "__fp16";
×
370
        case types::PrimitiveType::BFloat:
UNCOV
371
            return "__bf16";
×
372
        case types::PrimitiveType::Float:
373
            return "float";
2✔
374
        case types::PrimitiveType::Double:
375
            return "double";
1✔
376
        case types::PrimitiveType::X86_FP80:
UNCOV
377
            return "long double";
×
378
        case types::PrimitiveType::FP128:
379
            return "__float128";
×
380
        case types::PrimitiveType::PPC_FP128:
UNCOV
381
            return "__float128";
×
382
    }
383

UNCOV
384
    throw std::runtime_error("Unknown primitive type");
×
385
};
26✔
386

387
std::string CLanguageExtension::declaration(const std::string& name, const types::IType& type,
23✔
388
                                            bool use_initializer, bool use_alignment) {
389
    std::stringstream val;
23✔
390

391
    if (auto scalar_type = dynamic_cast<const types::Scalar*>(&type)) {
23✔
392
        val << primitive_type(scalar_type->primitive_type());
14✔
393
        val << " ";
14✔
394
        val << name;
14✔
395
    } else if (auto array_type = dynamic_cast<const types::Array*>(&type)) {
23✔
396
        auto& element_type = array_type->element_type();
3✔
397
        val << declaration(name + "[" + this->expression(array_type->num_elements()) + "]",
3✔
398
                           element_type);
3✔
399
    } else if (auto pointer_type = dynamic_cast<const types::Pointer*>(&type)) {
9✔
400
        const types::IType& pointee = pointer_type->pointee_type();
3✔
401

402
        const bool pointee_is_function_or_array = dynamic_cast<const types::Function*>(&pointee) ||
6✔
403
                                                  dynamic_cast<const types::Array*>(&pointee);
3✔
404

405
        // Parenthesise *only* when it is needed to bind tighter than [] or ()
406
        std::string decorated = pointee_is_function_or_array ? "(*" + name + ")" : "*" + name;
3✔
407

408
        val << declaration(decorated, pointee);
3✔
409
    } else if (auto ref_type = dynamic_cast<const Reference*>(&type)) {
6✔
UNCOV
410
        val << declaration("&" + name, ref_type->reference_type());
×
411
    } else if (auto structure_type = dynamic_cast<const types::Structure*>(&type)) {
3✔
412
        val << structure_type->name();
3✔
413
        val << " ";
3✔
414
        val << name;
3✔
415
    } else if (auto function_type = dynamic_cast<const types::Function*>(&type)) {
3✔
416
        std::stringstream params;
×
417
        for (size_t i = 0; i < function_type->num_params(); ++i) {
×
418
            params << declaration("", function_type->param_type(symbolic::integer(i)));
×
419
            if (i + 1 < function_type->num_params()) params << ", ";
×
UNCOV
420
        }
×
421
        if (function_type->is_var_arg()) {
×
422
            if (function_type->num_params() > 0) params << ", ";
×
423
            params << "...";
×
424
        }
×
425

UNCOV
426
        const std::string fun_name = name + "(" + params.str() + ")";
×
UNCOV
427
        val << declaration(fun_name, function_type->return_type());
×
428
    } else {
×
429
        throw std::runtime_error("Unknown declaration type");
×
430
    }
431

432
    if (use_alignment && type.alignment() > 0) {
23✔
433
        val << " __attribute__((aligned(" << type.alignment() << ")))";
×
UNCOV
434
    }
×
435

436
    if (use_initializer && !type.initializer().empty()) {
23✔
UNCOV
437
        val << " = " << type.initializer();
×
UNCOV
438
    }
×
439

440
    return val.str();
23✔
441
};
23✔
442

443
std::string CLanguageExtension::type_cast(const std::string& name, const types::IType& type) {
1✔
444
    std::stringstream val;
1✔
445

446
    val << "(";
1✔
447
    val << declaration("", type);
1✔
448
    val << ") ";
1✔
449
    val << name;
1✔
450

451
    return val.str();
1✔
452
};
1✔
453

454
std::string CLanguageExtension::subset(const Function& function, const types::IType& type,
9✔
455
                                       const data_flow::Subset& sub) {
456
    if (sub.empty()) {
9✔
457
        return "";
7✔
458
    }
459

460
    if (dynamic_cast<const types::Scalar*>(&type)) {
2✔
461
        return "";
×
462
    } else if (auto array_type = dynamic_cast<const types::Array*>(&type)) {
2✔
463
        std::string subset_str = "[" + this->expression(sub.at(0)) + "]";
1✔
464

465
        if (sub.size() > 1) {
1✔
UNCOV
466
            data_flow::Subset element_subset(sub.begin() + 1, sub.end());
×
UNCOV
467
            auto& element_type = array_type->element_type();
×
468
            return subset_str + subset(function, element_type, element_subset);
×
UNCOV
469
        } else {
×
470
            return subset_str;
1✔
471
        }
472
    } else if (auto pointer_type = dynamic_cast<const types::Pointer*>(&type)) {
2✔
UNCOV
473
        std::string subset_str = "[" + this->expression(sub.at(0)) + "]";
×
474

UNCOV
475
        data_flow::Subset element_subset(sub.begin() + 1, sub.end());
×
UNCOV
476
        auto& pointee_type = pointer_type->pointee_type();
×
UNCOV
477
        return subset_str + subset(function, pointee_type, element_subset);
×
478
    } else if (auto structure_type = dynamic_cast<const types::Structure*>(&type)) {
1✔
479
        auto& definition = function.structure(structure_type->name());
1✔
480

481
        std::string subset_str = ".member_" + this->expression(sub.at(0));
1✔
482
        if (sub.size() > 1) {
1✔
UNCOV
483
            auto member = SymEngine::rcp_dynamic_cast<const SymEngine::Integer>(sub.at(0));
×
UNCOV
484
            auto& member_type = definition.member_type(member);
×
UNCOV
485
            data_flow::Subset element_subset(sub.begin() + 1, sub.end());
×
UNCOV
486
            return subset_str + subset(function, member_type, element_subset);
×
487
        } else {
×
488
            return subset_str;
1✔
489
        }
490
    }
1✔
491

UNCOV
492
    throw std::invalid_argument("Invalid subset type");
×
493
};
9✔
494

495
std::string CLanguageExtension::expression(const symbolic::Expression& expr) {
789✔
496
    CSymbolicPrinter printer;
789✔
497
    return printer.apply(expr);
789✔
498
};
789✔
499

500
std::string CLanguageExtension::tasklet(const data_flow::Tasklet& tasklet) {
2✔
501
    std::string op = code_to_string(tasklet.code());
2✔
502
    std::vector<std::string> arguments;
2✔
503
    for (size_t i = 0; i < tasklet.inputs().size(); ++i) {
6✔
504
        std::string arg = tasklet.input(i).first;
4✔
505
        if (!tasklet.needs_connector(i)) {
4✔
506
            if (arg != "NAN" && arg != "INFINITY") {
×
UNCOV
507
                if (tasklet.input(i).second.primitive_type() == types::PrimitiveType::Float) {
×
UNCOV
508
                    arg += "f";
×
UNCOV
509
                }
×
UNCOV
510
            }
×
511
        }
×
512
        arguments.push_back(arg);
4✔
513
    }
4✔
514

515
    if (tasklet.code() == data_flow::TaskletCode::assign) {
2✔
UNCOV
516
        return arguments.at(0);
×
517
    } else if (data_flow::is_infix(tasklet.code())) {
2✔
518
        switch (data_flow::arity(tasklet.code())) {
2✔
519
            case 1:
UNCOV
520
                return op + arguments.at(0);
×
521
            case 2:
522
                return arguments.at(0) + " " + op + " " + arguments.at(1);
2✔
523
            default:
UNCOV
524
                throw std::runtime_error("Unsupported arity");
×
525
        }
526
    } else {
527
        return op + "(" + helpers::join(arguments, ", ") + ")";
×
528
    }
529
};
2✔
530

531
std::string CLanguageExtension::zero(const types::PrimitiveType prim_type) {
×
UNCOV
532
    switch (prim_type) {
×
533
        case types::Void:
UNCOV
534
            throw InvalidSDFGException("No zero for void type possible");
×
535
        case types::Bool:
UNCOV
536
            return "false";
×
537
        case types::Int8:
UNCOV
538
            return "0";
×
539
        case types::Int16:
540
            return "0";
×
541
        case types::Int32:
UNCOV
542
            return "0";
×
543
        case types::Int64:
544
            return "0ll";
×
545
        case types::Int128:
UNCOV
546
            return "0";
×
547
        case types::UInt8:
UNCOV
548
            return "0u";
×
549
        case types::UInt16:
550
            return "0u";
×
551
        case types::UInt32:
552
            return "0u";
×
553
        case types::UInt64:
554
            return "0ull";
×
555
        case types::UInt128:
556
            return "0u";
×
557
        case types::Half:
UNCOV
558
            throw InvalidSDFGException("Currently unsupported");
×
559
        case types::BFloat:
560
            throw InvalidSDFGException("Currently unsupported");
×
561
        case types::Float:
562
            return "0.0f";
×
563
        case types::Double:
564
            return "0.0";
×
565
        case types::X86_FP80:
566
            return "0.0l";
×
567
        case types::FP128:
UNCOV
568
            throw InvalidSDFGException("Currently unsupported");
×
569
        case types::PPC_FP128:
570
            throw InvalidSDFGException("Currently unsupported");
×
571
    }
×
572
}
×
573

UNCOV
574
void CSymbolicPrinter::bvisit(const SymEngine::Infty& x) {
×
UNCOV
575
    if (x.is_negative_infinity())
×
UNCOV
576
        str_ = "-INFINITY";
×
UNCOV
577
    else if (x.is_positive_infinity())
×
UNCOV
578
        str_ = "INFINITY";
×
UNCOV
579
};
×
580

581
void CSymbolicPrinter::bvisit(const SymEngine::BooleanAtom& x) {
2✔
582
    str_ = x.get_val() ? "true" : "false";
2✔
583
};
2✔
584

585
void CSymbolicPrinter::bvisit(const SymEngine::Symbol& x) {
592✔
586
    if (symbolic::is_nullptr(symbolic::symbol(x.get_name()))) {
592✔
587
        str_ = "NULL";
×
588
        return;
×
589
    } else if (symbolic::is_memory_address(symbolic::symbol(x.get_name()))) {
592✔
590
        // symbol of form reinterpret_cast<T*>(0x1234)
591
        str_ = x.get_name();
×
UNCOV
592
        return;
×
593
    }
594
    str_ = x.get_name();
592✔
595
};
592✔
596

597
void CSymbolicPrinter::bvisit(const SymEngine::And& x) {
×
598
    std::ostringstream s;
×
599
    auto container = x.get_container();
×
UNCOV
600
    s << apply(*container.begin());
×
601
    for (auto it = ++(container.begin()); it != container.end(); ++it) {
×
602
        s << " && " << apply(*it);
×
UNCOV
603
    }
×
604
    str_ = parenthesize(s.str());
×
605
};
×
606

607
void CSymbolicPrinter::bvisit(const SymEngine::Or& x) {
×
608
    std::ostringstream s;
×
609
    auto container = x.get_container();
×
610
    s << apply(*container.begin());
×
611
    for (auto it = ++(container.begin()); it != container.end(); ++it) {
×
612
        s << " || " << apply(*it);
×
613
    }
×
614
    str_ = parenthesize(s.str());
×
UNCOV
615
};
×
616

617
void CSymbolicPrinter::bvisit(const SymEngine::Not& x) {
×
618
    str_ = "!" + apply(x.get_arg());
×
619
    str_ = parenthesize(str_);
×
620
};
×
621

622
void CSymbolicPrinter::bvisit(const SymEngine::Equality& x) {
1✔
623
    str_ = apply(x.get_args()[0]) + " == " + apply(x.get_args()[1]);
1✔
624
    str_ = parenthesize(str_);
1✔
625
};
1✔
626

627
void CSymbolicPrinter::bvisit(const SymEngine::Unequality& x) {
1✔
628
    str_ = apply(x.get_args()[0]) + " != " + apply(x.get_args()[1]);
1✔
629
    str_ = parenthesize(str_);
1✔
630
};
1✔
631

UNCOV
632
void CSymbolicPrinter::bvisit(const SymEngine::Min& x) {
×
633
    std::ostringstream s;
×
634
    auto container = x.get_args();
×
635
    if (container.size() == 1) {
×
636
        s << apply(*container.begin());
×
637
    } else {
×
638
        s << "__daisy_min(";
×
639
        s << apply(*container.begin());
×
640

641
        // Recursively apply __daisy_min to the arguments
642
        SymEngine::vec_basic subargs;
×
UNCOV
643
        for (auto it = ++(container.begin()); it != container.end(); ++it) {
×
644
            subargs.push_back(*it);
×
UNCOV
645
        }
×
UNCOV
646
        auto submin = SymEngine::min(subargs);
×
UNCOV
647
        s << ", " << apply(submin);
×
648

UNCOV
649
        s << ")";
×
UNCOV
650
    }
×
651

UNCOV
652
    str_ = s.str();
×
UNCOV
653
};
×
654

UNCOV
655
void CSymbolicPrinter::bvisit(const SymEngine::Max& x) {
×
UNCOV
656
    std::ostringstream s;
×
UNCOV
657
    auto container = x.get_args();
×
UNCOV
658
    if (container.size() == 1) {
×
UNCOV
659
        s << apply(*container.begin());
×
UNCOV
660
    } else {
×
UNCOV
661
        s << "__daisy_max(";
×
UNCOV
662
        s << apply(*container.begin());
×
663

664
        // Recursively apply __daisy_max to the arguments
UNCOV
665
        SymEngine::vec_basic subargs;
×
UNCOV
666
        for (auto it = ++(container.begin()); it != container.end(); ++it) {
×
UNCOV
667
            subargs.push_back(*it);
×
UNCOV
668
        }
×
UNCOV
669
        auto submax = SymEngine::max(subargs);
×
UNCOV
670
        s << ", " << apply(submax);
×
671

UNCOV
672
        s << ")";
×
UNCOV
673
    }
×
674

UNCOV
675
    str_ = s.str();
×
UNCOV
676
};
×
677

UNCOV
678
void CSymbolicPrinter::_print_pow(std::ostringstream& o,
×
679
                                  const SymEngine::RCP<const SymEngine::Basic>& a,
680
                                  const SymEngine::RCP<const SymEngine::Basic>& b) {
UNCOV
681
    if (SymEngine::eq(*a, *SymEngine::E)) {
×
UNCOV
682
        o << "exp(" << apply(b) << ")";
×
UNCOV
683
    } else if (SymEngine::eq(*b, *SymEngine::rational(1, 2))) {
×
UNCOV
684
        o << "sqrt(" << apply(a) << ")";
×
UNCOV
685
    } else if (SymEngine::eq(*b, *SymEngine::rational(1, 3))) {
×
UNCOV
686
        o << "cbrt(" << apply(a) << ")";
×
UNCOV
687
    } else if (SymEngine::eq(*b, *SymEngine::integer(2))) {
×
UNCOV
688
        o << apply(a) + " * " + apply(a);
×
UNCOV
689
    } else {
×
UNCOV
690
        o << "pow(" << apply(a) << ", " << apply(b) << ")";
×
691
    }
UNCOV
692
};
×
693

694
}  // namespace codegen
695
}  // 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