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

daisytuner / docc / 30634500673

31 Jul 2026 01:27PM UTC coverage: 64.806% (+0.1%) from 64.71%
30634500673

push

github

web-flow
Merge pull request #920 from daisytuner/pytorch-any-where

Big & small stuff to get segformer working

486 of 604 new or added lines in 13 files covered. (80.46%)

24 existing lines in 2 files now uncovered.

45593 of 70353 relevant lines covered (64.81%)

723.15 hits per line

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

60.36
/sdfg/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/tasklet.h"
11
#include "sdfg/helpers/helpers.h"
12
#include "sdfg/structured_control_flow/block.h"
13
#include "sdfg/structured_control_flow/control_flow_node.h"
14
#include "sdfg/structured_control_flow/for.h"
15
#include "sdfg/structured_control_flow/if_else.h"
16
#include "sdfg/structured_control_flow/return.h"
17
#include "sdfg/structured_control_flow/sequence.h"
18
#include "sdfg/structured_control_flow/while.h"
19
#include "sdfg/structured_sdfg.h"
20
#include "sdfg/symbolic/symbolic.h"
21
#include "sdfg/types/type.h"
22
#include "symengine/basic.h"
23

24
namespace sdfg {
25
namespace visualizer {
26

27
constexpr const char* code_to_string(data_flow::TaskletCode c) {
18✔
28
    switch (c) {
18✔
29
        case data_flow::TaskletCode::assign:
7✔
30
            return "=";
7✔
31
        case data_flow::TaskletCode::int_add:
1✔
32
        case data_flow::TaskletCode::fp_add:
4✔
33
            return "+";
4✔
34
        case data_flow::TaskletCode::int_sub:
1✔
35
        case data_flow::TaskletCode::fp_sub:
2✔
36
            return "-";
2✔
37
        case data_flow::TaskletCode::int_mul:
×
38
        case data_flow::TaskletCode::fp_mul:
4✔
39
            return "*";
4✔
40
        case data_flow::TaskletCode::int_udiv:
×
41
        case data_flow::TaskletCode::int_sdiv:
×
42
        case data_flow::TaskletCode::fp_div:
×
43
            return "/";
×
44
        case data_flow::TaskletCode::int_urem:
×
45
        case data_flow::TaskletCode::int_srem:
×
46
        case data_flow::TaskletCode::fp_rem:
×
47
            return "%";
×
48
        case data_flow::TaskletCode::fp_fma:
1✔
49
            return "fma";
1✔
50
        case data_flow::TaskletCode::fp_one:
×
51
            return "of!=";
×
NEW
52
        case data_flow::TaskletCode::int_smax:
×
NEW
53
            return "smax";
×
NEW
54
        case data_flow::TaskletCode::int_umax:
×
NEW
55
            return "umax";
×
NEW
56
        case data_flow::TaskletCode::int_smin:
×
NEW
57
            return "smin";
×
NEW
58
        case data_flow::TaskletCode::int_umin:
×
NEW
59
            return "umin";
×
60
        default:
×
61
            return "?";
×
62
    };
18✔
63
};
×
64

65
std::string Visualizer::expression(const std::string expr) {
84✔
66
    if (this->replacements_.empty()) return expr;
84✔
67
    std::string res = expr;
×
68
    size_t pos1 = 0, pos2 = 0;
×
69
    for (std::pair<const std::string, const std::string> replace : this->replacements_) {
×
70
        pos2 = res.find(replace.first);
×
71
        if (pos2 == res.npos) continue;
×
72
        pos1 = 0;
×
73
        std::stringstream res_tmp;
×
74
        while (pos2 < res.npos) {
×
75
            res_tmp << res.substr(pos1, pos2 - pos1) << replace.second;
×
76
            pos1 = pos2 + replace.first.size();
×
77
            pos2 = res.find(replace.first, pos1);
×
78
        }
×
79
        if (pos1 < res.npos) res_tmp << res.substr(pos1);
×
80
        res = res_tmp.str();
×
81
    }
×
82
    return res;
×
83
}
84✔
84

85
void Visualizer::visualizeNode(const StructuredSDFG& sdfg, const structured_control_flow::ControlFlowNode& node) {
35✔
86
    if (auto block = dyn_cast<const structured_control_flow::Block*>(&node)) {
35✔
87
        this->visualizeBlock(sdfg, *block);
17✔
88
    } else if (auto assign_block = dyn_cast<const structured_control_flow::AssignmentBlock*>(&node)) {
18✔
89
        this->visualizeAssignmentBlock(sdfg, *assign_block);
2✔
90
    } else if (auto sequence = dyn_cast<const structured_control_flow::Sequence*>(&node)) {
16✔
91
        this->visualizeSequence(sdfg, *sequence);
×
92
    } else if (auto if_else = dyn_cast<const structured_control_flow::IfElse*>(&node)) {
16✔
93
        this->visualizeIfElse(sdfg, *if_else);
3✔
94
    } else if (auto while_loop = dyn_cast<const structured_control_flow::While*>(&node)) {
13✔
95
        this->visualizeWhile(sdfg, *while_loop);
2✔
96
    } else if (auto loop = dyn_cast<const structured_control_flow::For*>(&node)) {
11✔
97
        this->visualizeFor(sdfg, *loop);
6✔
98
    } else if (auto return_node = dyn_cast<const structured_control_flow::Return*>(&node)) {
6✔
99
        this->visualizeReturn(sdfg, *return_node);
2✔
100
    } else if (auto break_node = dyn_cast<const structured_control_flow::Break*>(&node)) {
3✔
101
        this->visualizeBreak(sdfg, *break_node);
1✔
102
    } else if (auto continue_node = dyn_cast<const structured_control_flow::Continue*>(&node)) {
2✔
103
        this->visualizeContinue(sdfg, *continue_node);
1✔
104
    } else if (auto reduce_node = dyn_cast<const structured_control_flow::Reduce*>(&node)) {
1✔
105
        this->visualizeReduce(sdfg, *reduce_node);
1✔
106
    } else if (auto map_node = dyn_cast<const structured_control_flow::Map*>(&node)) {
1✔
107
        this->visualizeMap(sdfg, *map_node);
×
108
    } else {
×
109
        throw std::runtime_error("Unsupported control flow node");
×
110
    }
×
111
}
35✔
112

113
void Visualizer::visualizeTasklet(data_flow::Tasklet const& tasklet) {
18✔
114
    std::string op = code_to_string(tasklet.code());
18✔
115
    std::vector<std::string> arguments;
18✔
116
    for (size_t i = 0; i < tasklet.inputs().size(); ++i) {
48✔
117
        arguments.push_back(this->expression(tasklet.input(i)));
30✔
118
    }
30✔
119

120
    if (tasklet.code() == data_flow::TaskletCode::assign) {
18✔
121
        this->stream_ << arguments.at(0);
7✔
122
    } else if (tasklet.code() == data_flow::TaskletCode::fp_fma) {
11✔
123
        if (arguments.size() != 3) throw std::runtime_error("FMA requires 3 arguments");
1✔
124
        this->stream_ << arguments.at(0) << " * " << arguments.at(1) << " + " << arguments.at(2);
1✔
125
    } else {
10✔
126
        this->stream_ << op << "(" << helpers::join(arguments, ", ") << ")";
10✔
127
    }
10✔
128
}
18✔
129

130
void Visualizer::visualizeForBounds(
131
    symbolic::Symbol const& indvar,
132
    symbolic::Expression const& init,
133
    symbolic::Condition const& condition,
134
    symbolic::Expression const& update
135
) {
7✔
136
    this->stream_ << indvar->get_name() << " = " << this->expression(init->__str__()) << "; "
7✔
137
                  << this->expression(condition->__str__()) << "; " << indvar->get_name() << " = "
7✔
138
                  << this->expression(update->__str__());
7✔
139
}
7✔
140

141
std::string Visualizer::subsetRangeString(data_flow::Subset const& subset, int subIdx) {
27✔
142
    auto& dim = subset.at(subIdx);
27✔
143
    return this->expression(dim->__str__());
27✔
144
}
27✔
145

146
/// @brief If known, use the type to better visualize structures. Then track the type as far as it goes.
147
void Visualizer::visualizeSubset(data_flow::Subset const& sub, types::IType const* type, int subIdx) {
69✔
148
    if (static_cast<int>(sub.size()) <= subIdx) {
69✔
149
        return;
42✔
150
    }
42✔
151
    if (auto structure_type = dynamic_cast<const types::Structure*>(type)) {
27✔
152
        types::StructureDefinition const& definition = this->sdfg_.structure(structure_type->name());
×
153

154
        auto& memberIdx = sub.at(subIdx);
×
155
        if (!memberIdx.is_null() && SymEngine::is_a<SymEngine::Integer>(*memberIdx)) {
×
156
            this->stream_ << ".member_" << this->expression(memberIdx->__str__());
×
157
            auto& member_type = definition.member_type(SymEngine::rcp_dynamic_cast<const SymEngine::Integer>(memberIdx)
×
158
            );
×
159
            this->visualizeSubset(sub, &member_type, subIdx + 1);
×
160
        } else {
×
161
            this->stream_ << ".member[" << subsetRangeString(sub, subIdx) << "]";
×
162
            this->visualizeSubset(sub, nullptr, subIdx + 1);
×
163
        }
×
164
    } else if (auto tensor_type = dynamic_cast<const types::Tensor*>(type)) {
27✔
165
        auto& shape = tensor_type->shape();
×
166
        int tensor_dims = shape.size();
×
167
        int i = 0;
×
168
        while (i < tensor_dims && subIdx < sub.size()) {
×
169
            this->stream_ << "[" << subsetRangeString(sub, i) << ":" << subsetRangeString(shape, i) << "]";
×
170
            ++subIdx;
×
171
            ++i;
×
172
        }
×
173
        if (subIdx < sub.size()) {
×
174
            this->visualizeSubset(sub, &tensor_type->element_type(), subIdx);
×
175
        }
×
176
    } else if (auto array_type = dynamic_cast<const types::Array*>(type)) {
27✔
177
        this->stream_ << "[" << subsetRangeString(sub, subIdx) << "]";
14✔
178
        types::IType const& element_type = array_type->element_type();
14✔
179
        this->visualizeSubset(sub, &element_type, subIdx + 1);
14✔
180
    } else if (auto pointer_type = dynamic_cast<const types::Pointer*>(type)) {
14✔
181
        this->stream_ << "[" << subsetRangeString(sub, subIdx) << "]";
12✔
182
        const types::IType* pointee_type;
12✔
183
        if (pointer_type->has_pointee_type()) {
12✔
184
            pointee_type = &pointer_type->pointee_type();
9✔
185
        } else {
9✔
186
            auto z = symbolic::zero();
3✔
187
            if (!symbolic::eq(sub.at(subIdx), z)) {
3✔
188
                this->stream_ << "#illgl";
1✔
189
            }
1✔
190
            pointee_type = nullptr;
3✔
191
        }
3✔
192
        this->visualizeSubset(sub, pointee_type, subIdx + 1);
12✔
193
    } else {
12✔
194
        if (type == nullptr) {
1✔
195
            this->stream_ << "(rogue)";
1✔
196
        }
1✔
197
        this->stream_ << "[" << subsetRangeString(sub, subIdx) << "]";
1✔
198
        visualizeSubset(sub, nullptr, subIdx + 1);
1✔
199
    }
1✔
200
}
27✔
201

202
void Visualizer::visualize() {
14✔
203
    if (const auto* unstructured_sdfg = dynamic_cast<const SDFG*>(&this->sdfg_)) {
14✔
204
        this->visualizeSDFG(*unstructured_sdfg);
1✔
205
    } else if (const auto* structured_sdfg = dynamic_cast<const StructuredSDFG*>(&this->sdfg_)) {
13✔
206
        this->visualizeStructuredSDFG(*structured_sdfg);
13✔
207
    } else {
13✔
208
        throw InvalidSDFGException("Visualizer: Invalid SDFG type");
×
209
    }
×
210
}
14✔
211

212
} // namespace visualizer
213
} // 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