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

daisytuner / sdfglib / 15004641901

13 May 2025 07:03PM UTC coverage: 57.368% (-0.2%) from 57.574%
15004641901

Pull #9

github

web-flow
Merge e3aac8e18 into 5df3da500
Pull Request #9: Graphviz DOT Visualizer for SDFGs

347 of 696 new or added lines in 3 files covered. (49.86%)

25 existing lines in 3 files now uncovered.

7521 of 13110 relevant lines covered (57.37%)

498.38 hits per line

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

26.5
/src/visualizer/visualizer.cpp
1
#include "sdfg/visualizer/visualizer.h"
2

3
#include <cassert>
4
#include <sstream>
5
#include <stdexcept>
6
#include <string>
7
#include <utility>
8
#include <vector>
9

10
#include "sdfg/data_flow/library_node.h"
11
#include "sdfg/data_flow/tasklet.h"
12
#include "sdfg/helpers/helpers.h"
13
#include "sdfg/schedule.h"
14
#include "sdfg/structured_control_flow/block.h"
15
#include "sdfg/structured_control_flow/control_flow_node.h"
16
#include "sdfg/structured_control_flow/for.h"
17
#include "sdfg/structured_control_flow/if_else.h"
18
#include "sdfg/structured_control_flow/kernel.h"
19
#include "sdfg/structured_control_flow/return.h"
20
#include "sdfg/structured_control_flow/sequence.h"
21
#include "sdfg/structured_control_flow/while.h"
22
#include "sdfg/symbolic/symbolic.h"
23
#include "sdfg/types/type.h"
24
#include "symengine/basic.h"
25

26
namespace sdfg {
27
namespace visualizer {
28

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

363
std::string Visualizer::expression(const std::string expr) {
59✔
364
    if (this->replacements_.empty()) return expr;
59✔
365
    std::string res = expr;
14✔
366
    size_t pos1 = 0, pos2 = 0;
14✔
367
    for (std::pair<const std::string, const std::string> replace : this->replacements_) {
182✔
368
        pos2 = res.find(replace.first);
168✔
369
        if (pos2 == res.npos) continue;
168✔
370
        pos1 = 0;
8✔
371
        std::stringstream res_tmp;
8✔
372
        while (pos2 < res.npos) {
16✔
373
            res_tmp << res.substr(pos1, pos2 - pos1) << replace.second;
8✔
374
            pos1 = pos2 + replace.first.size();
8✔
375
            pos2 = res.find(replace.first, pos1);
8✔
376
        }
377
        if (pos1 < res.npos) res_tmp << res.substr(pos1);
8✔
378
        res = res_tmp.str();
8✔
379
    }
168✔
380
    return res;
14✔
381
}
14✔
382

383
void Visualizer::visualizeNode(Schedule& schedule, structured_control_flow::ControlFlowNode& node) {
27✔
384
    if (auto block = dynamic_cast<structured_control_flow::Block*>(&node)) {
27✔
385
        this->visualizeBlock(schedule, *block);
12✔
386
        return;
12✔
387
    }
388
    if (auto sequence = dynamic_cast<structured_control_flow::Sequence*>(&node)) {
15✔
NEW
389
        this->visualizeSequence(schedule, *sequence);
×
NEW
390
        return;
×
391
    }
392
    if (auto if_else = dynamic_cast<structured_control_flow::IfElse*>(&node)) {
15✔
393
        this->visualizeIfElse(schedule, *if_else);
2✔
394
        return;
2✔
395
    }
396
    if (auto while_loop = dynamic_cast<structured_control_flow::While*>(&node)) {
13✔
397
        this->visualizeWhile(schedule, *while_loop);
1✔
398
        return;
1✔
399
    }
400
    if (auto loop = dynamic_cast<structured_control_flow::For*>(&node)) {
12✔
401
        this->visualizeFor(schedule, *loop);
9✔
402
        return;
9✔
403
    }
404
    if (auto return_node = dynamic_cast<structured_control_flow::Return*>(&node)) {
3✔
NEW
405
        this->visualizeReturn(schedule, *return_node);
×
NEW
406
        return;
×
407
    }
408
    if (auto break_node = dynamic_cast<structured_control_flow::Break*>(&node)) {
3✔
409
        this->visualizeBreak(schedule, *break_node);
1✔
410
        return;
1✔
411
    }
412
    if (auto continue_node = dynamic_cast<structured_control_flow::Continue*>(&node)) {
2✔
413
        this->visualizeContinue(schedule, *continue_node);
1✔
414
        return;
1✔
415
    }
416
    if (auto kernel_node = dynamic_cast<structured_control_flow::Kernel*>(&node)) {
1✔
417
        this->visualizeKernel(schedule, *kernel_node);
1✔
418
        return;
1✔
419
    }
NEW
420
    throw std::runtime_error("Unsupported control flow node");
×
421
}
422

423
void Visualizer::visualizeTasklet(data_flow::Tasklet const& tasklet) {
10✔
424
    std::string op = code_to_string(tasklet.code());
10✔
425
    std::vector<std::string> arguments;
10✔
426
    for (size_t i = 0; i < tasklet.inputs().size(); ++i) {
27✔
427
        std::string arg = tasklet.input(i).first;
17✔
428
        if (!tasklet.needs_connector(i)) {
17✔
429
            if (arg != "NAN" && arg != "INFINITY") {
4✔
430
                if (tasklet.input(i).second.primitive_type() == types::PrimitiveType::Float)
4✔
NEW
431
                    arg += "f";
×
432
            }
433
        }
434
        arguments.push_back(this->expression(arg));
17✔
435
    }
17✔
436

437
    if (tasklet.code() == data_flow::TaskletCode::assign) {
10✔
438
        this->stream_ << arguments.at(0);
5✔
439
    } else if (tasklet.code() == data_flow::TaskletCode::fma) {
5✔
440
        if (arguments.size() != 3) throw std::runtime_error("FMA requires 3 arguments");
2✔
441
        this->stream_ << arguments.at(0) << " * " << arguments.at(1) << " + " << arguments.at(2);
2✔
442
    } else if (data_flow::is_infix(tasklet.code())) {
3✔
443
        switch (data_flow::arity(tasklet.code())) {
3✔
NEW
444
            case 1:
×
NEW
445
                this->stream_ << op + arguments.at(0);
×
NEW
446
                break;
×
447
            case 2:
3✔
448
                this->stream_ << arguments.at(0) << " " << op << " " << arguments.at(1);
3✔
449
                break;
3✔
NEW
450
            default:
×
NEW
451
                throw std::runtime_error("Unsupported arity");
×
452
        }
453
    } else {
NEW
454
        this->stream_ << op << "(" << helpers::join(arguments, ", ") << ")";
×
455
    }
456
}
10✔
457

458
void Visualizer::visualizeForBounds(symbolic::Symbol const& indvar,
9✔
459
                                    symbolic::Expression const& init,
460
                                    symbolic::Condition const& condition,
461
                                    symbolic::Expression const& update) {
462
    if ((init->get_type_code() == SymEngine::TypeID::SYMENGINE_INTEGER ||
11✔
463
         init->get_type_code() == SymEngine::TypeID::SYMENGINE_SYMBOL) &&
11✔
464
        (condition->get_type_code() == SymEngine::TypeID::SYMENGINE_STRICTLESSTHAN ||
13✔
465
         condition->get_type_code() == SymEngine::TypeID::SYMENGINE_LESSTHAN) &&
11✔
466
        condition->get_args().size() == 2 &&
23✔
467
        condition->get_args().at(0)->__str__() == indvar->__str__() &&
23✔
468
        (condition->get_args().at(1)->get_type_code() == SymEngine::TypeID::SYMENGINE_INTEGER ||
23✔
469
         condition->get_args().at(1)->get_type_code() == SymEngine::TypeID::SYMENGINE_SYMBOL) &&
23✔
470
        update->get_type_code() == SymEngine::TypeID::SYMENGINE_ADD &&
14✔
471
        update->get_args().size() == 2 &&
23✔
472
        (update->get_args().at(0)->__str__() == indvar->__str__() ||
23✔
473
         update->get_args().at(1)->__str__() == indvar->__str__()) &&
43✔
474
        (update->get_args().at(0)->get_type_code() == SymEngine::TypeID::SYMENGINE_INTEGER ||
16✔
475
         update->get_args().at(0)->get_type_code() == SymEngine::TypeID::SYMENGINE_SYMBOL ||
9✔
476
         update->get_args().at(1)->get_type_code() == SymEngine::TypeID::SYMENGINE_INTEGER ||
9✔
477
         update->get_args().at(1)->get_type_code() == SymEngine::TypeID::SYMENGINE_SYMBOL)) {
9✔
478
        this->stream_ << indvar->get_name() << " = " << init->__str__() << ":";
7✔
479
        if (condition->get_type_code() == SymEngine::TypeID::SYMENGINE_STRICTLESSTHAN)
7✔
480
            this->stream_ << "(" << condition->get_args().at(1)->__str__() << "-1)";
5✔
481
        else
482
            this->stream_ << condition->get_args().at(1)->__str__();
2✔
483
        size_t i = (update->get_args().at(0).get() == indvar.get()) ? 1 : 0;
7✔
484
        if (update->get_args().at(i)->__str__() != "1")
7✔
485
            this->stream_ << ":" << update->get_args().at(i)->__str__();
1✔
486
    } else {
487
        this->stream_ << indvar->get_name() << " = " << this->expression(init->__str__()) << "; "
4✔
488
                      << this->expression(condition->__str__()) << "; " << indvar->get_name()
4✔
489
                      << " = " << this->expression(update->__str__());
2✔
490
    }
491
}
9✔
492

493
void Visualizer::visualizeLibraryNode(const data_flow::LibraryNodeType libnode_type) {
1✔
494
    switch (libnode_type) {
1✔
495
        case data_flow::LibraryNodeType::LocalBarrier:
1✔
496
            this->stream_ << "Local Barrier";
1✔
497
            break;
1✔
NEW
498
        default:
×
NEW
499
            throw std::runtime_error("Unsupported library node type");
×
500
    }
501
}
1✔
502

503
void Visualizer::visualizeSubset(Function const& function, types::IType const& type,
43✔
504
                                 data_flow::Subset const& sub) {
505
    if (sub.empty()) return;
43✔
506
    if (auto scalar_type = dynamic_cast<const types::Scalar*>(&type)) {
33✔
507
        return;
7✔
508
    } else if (auto array_type = dynamic_cast<const types::Array*>(&type)) {
26✔
509
        this->stream_ << "[" << this->expression(sub.at(0)->__str__()) << "]";
8✔
510
        if (sub.size() > 1) {
8✔
511
            data_flow::Subset element_subset(sub.begin() + 1, sub.end());
2✔
512
            types::IType const& element_type = array_type->element_type();
2✔
513
            this->visualizeSubset(function, element_type, element_subset);
2✔
514
        }
2✔
515
    } else if (auto pointer_type = dynamic_cast<const types::Pointer*>(&type)) {
18✔
516
        this->stream_ << "[" << this->expression(sub.at(0)->__str__()) << "]";
18✔
517
        data_flow::Subset element_subset(sub.begin() + 1, sub.end());
18✔
518
        types::IType const& pointee_type = pointer_type->pointee_type();
18✔
519
        this->visualizeSubset(function, pointee_type, element_subset);
18✔
520
    } else if (auto structure_type = dynamic_cast<const types::Structure*>(&type)) {
18✔
NEW
521
        types::StructureDefinition const& definition = function.structure(structure_type->name());
×
NEW
522
        this->stream_ << ".member_" << this->expression(sub.at(0)->__str__());
×
NEW
523
        if (sub.size() > 1) {
×
NEW
524
            auto member = SymEngine::rcp_dynamic_cast<const SymEngine::Integer>(sub.at(0));
×
NEW
525
            types::IType const& member_type = definition.member_type(member);
×
NEW
526
            data_flow::Subset element_subset(sub.begin() + 1, sub.end());
×
NEW
527
            this->visualizeSubset(function, member_type, element_subset);
×
NEW
528
        }
×
529
    } else {
NEW
530
        assert(false);
×
531
    }
532
}
533

534
}  // namespace visualizer
535
}  // 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