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

daisytuner / sdfglib / 15340968114

30 May 2025 06:47AM UTC coverage: 58.553% (+0.2%) from 58.324%
15340968114

push

github

web-flow
Add parallel Map node

* Introduce Map data structure

* Prepare infrastructure

* implement analysis support

* Add basic infrastructure

* visualizer/serializer

* include fix

* update from main

* remove default

* happens before test + fixes

* builder test

* dispatcher test

* visitor, copy and serializer tests

* for2map structures

* for2map conversion draft

* add tests

* Bug fixes

* small updates from feedback

* Visitor style pass implementation

* cleanup

* fixes linting errors

---------

Co-authored-by: Lukas Truemper <lukas.truemper@outlook.de>

258 of 381 new or added lines in 26 files covered. (67.72%)

17 existing lines in 14 files now uncovered.

8184 of 13977 relevant lines covered (58.55%)

109.83 hits per line

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

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

363
std::string Visualizer::expression(const std::string expr) {
431✔
364
    if (this->replacements_.empty()) return expr;
431✔
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
}
445✔
382

383
void Visualizer::visualizeNode(Schedule& schedule, structured_control_flow::ControlFlowNode& node) {
197✔
384
    if (auto block = dynamic_cast<structured_control_flow::Block*>(&node)) {
197✔
385
        this->visualizeBlock(schedule, *block);
179✔
386
        return;
179✔
387
    }
388
    if (auto sequence = dynamic_cast<structured_control_flow::Sequence*>(&node)) {
18✔
389
        this->visualizeSequence(schedule, *sequence);
×
390
        return;
×
391
    }
392
    if (auto if_else = dynamic_cast<structured_control_flow::IfElse*>(&node)) {
18✔
393
        this->visualizeIfElse(schedule, *if_else);
3✔
394
        return;
3✔
395
    }
396
    if (auto while_loop = dynamic_cast<structured_control_flow::While*>(&node)) {
15✔
397
        this->visualizeWhile(schedule, *while_loop);
2✔
398
        return;
2✔
399
    }
400
    if (auto loop = dynamic_cast<structured_control_flow::For*>(&node)) {
13✔
401
        this->visualizeFor(schedule, *loop);
9✔
402
        return;
9✔
403
    }
404
    if (auto return_node = dynamic_cast<structured_control_flow::Return*>(&node)) {
4✔
405
        this->visualizeReturn(schedule, *return_node);
1✔
406
        return;
1✔
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
    if (auto map_node = dynamic_cast<structured_control_flow::Map*>(&node)) {
×
NEW
421
        this->visualizeMap(schedule, *map_node);
×
NEW
422
        return;
×
423
    }
UNCOV
424
    throw std::runtime_error("Unsupported control flow node");
×
425
}
197✔
426

427
void Visualizer::visualizeTasklet(data_flow::Tasklet const& tasklet) {
177✔
428
    std::string op = code_to_string(tasklet.code());
177✔
429
    std::vector<std::string> arguments;
177✔
430
    for (size_t i = 0; i < tasklet.inputs().size(); ++i) {
397✔
431
        std::string arg = tasklet.input(i).first;
220✔
432
        if (!tasklet.needs_connector(i)) {
220✔
433
            if (arg != "NAN" && arg != "INFINITY") {
205✔
434
                if (tasklet.input(i).second.primitive_type() == types::PrimitiveType::Float)
205✔
435
                    arg += "f";
×
436
            }
205✔
437
        }
205✔
438
        arguments.push_back(this->expression(arg));
220✔
439
    }
220✔
440

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

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

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

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

538
}  // namespace visualizer
539
}  // 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

© 2025 Coveralls, Inc