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

daisytuner / docc / 28106147644

24 Jun 2026 02:32PM UTC coverage: 61.922% (+0.1%) from 61.779%
28106147644

Pull #806

github

web-flow
Merge 2be414d54 into 57cc1db99
Pull Request #806: Map Collapse for Multiple targets in a neste sequence

165 of 185 new or added lines in 2 files covered. (89.19%)

419 existing lines in 30 files now uncovered.

37705 of 60891 relevant lines covered (61.92%)

1004.4 hits per line

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

84.75
/opt/src/transformations/offloading/gpu_tiling.cpp
1
#include "sdfg/transformations/offloading/gpu_tiling.h"
2
#include <set>
3

4
#include "sdfg/analysis/analysis.h"
5
#include "sdfg/analysis/type_analysis.h"
6
#include "sdfg/analysis/users.h"
7
#include "sdfg/builder/structured_sdfg_builder.h"
8
#include "sdfg/data_flow/access_node.h"
9
#include "sdfg/passes/offloading/sync_condition_propagation.h"
10
#include "sdfg/structured_control_flow/for.h"
11
#include "sdfg/structured_control_flow/map.h"
12
#include "sdfg/structured_control_flow/structured_loop.h"
13
#include "sdfg/structured_control_flow/while.h"
14
#include "sdfg/transformations/loop_tiling.h"
15
#include "sdfg/transformations/offloading/kernel_local_storage.h"
16
#include "sdfg/transformations/out_local_storage.h"
17

18

19
namespace sdfg {
20
namespace transformations {
21

22
GPUTiling::GPUTiling(structured_control_flow::StructuredLoop& loop, size_t size) : loop_(loop), size_(size) {}
5✔
23

24
std::string GPUTiling::name() const { return "GPUTiling"; }
6✔
25

26
bool GPUTiling::can_be_applied(builder::StructuredSDFGBuilder& builder, analysis::AnalysisManager& analysis_manager) {
1✔
27
    auto sdfg = builder.subject().clone();
1✔
28
    builder::StructuredSDFGBuilder builder_local(sdfg);
1✔
29
    analysis::AnalysisManager analysis_manager_local(builder_local.subject());
1✔
30

31
    auto test_loop = builder_local.find_element_by_id(loop_.element_id());
1✔
32

33
    auto& loop_local = static_cast<structured_control_flow::StructuredLoop&>(*test_loop);
1✔
34

35
    LoopTiling tiling(loop_local, size_);
1✔
36

37
    if (!tiling.can_be_applied(builder_local, analysis_manager_local)) {
1✔
38
        return false;
×
39
    }
×
40

41
    tiling.apply(builder_local, analysis_manager_local);
1✔
42

43
    auto& users = analysis_manager_local.get<analysis::Users>();
1✔
44

45
    auto inner_loop = tiling.inner_loop();
1✔
46
    auto outer_loop = tiling.outer_loop();
1✔
47

48
    analysis::UsersView users_view(users, inner_loop->root());
1✔
49

50
    std::set<data_flow::AccessNode*> read_accesses;
1✔
51
    std::set<std::string> read_container_names;
1✔
52

53
    for (auto read : users_view.reads()) {
11✔
54
        if (!dynamic_cast<data_flow::AccessNode*>(read->element())) {
11✔
55
            continue;
8✔
56
        }
8✔
57
        if (read_container_names.find(read->container()) != read_container_names.end()) {
3✔
58
            continue;
×
59
        }
×
60
        auto access_node = dynamic_cast<data_flow::AccessNode*>(read->element());
3✔
61
        read_container_names.insert(read->container());
3✔
62
        read_accesses.insert(std::move(access_node));
3✔
63
    }
3✔
64

65
    if (read_accesses.empty()) {
1✔
66
        return false;
×
67
    }
×
68

69
    for (auto& access : read_accesses) {
3✔
70
        KernelLocalStorage kls(*inner_loop, outer_loop->indvar(), *access);
3✔
71
        if (kls.can_be_applied(builder_local, analysis_manager_local)) {
3✔
72
            target_containers_.insert(access->data());
2✔
73
        }
2✔
74
    }
3✔
75
    if (target_containers_.empty()) {
1✔
76
        return false;
×
77
    }
×
78

79
    return true;
1✔
80
}
1✔
81

82
void GPUTiling::apply(builder::StructuredSDFGBuilder& builder, analysis::AnalysisManager& analysis_manager) {
1✔
83
    LoopTiling tiling(loop_, size_);
1✔
84
    tiling.apply(builder, analysis_manager);
1✔
85
    auto inner_loop = tiling.inner_loop();
1✔
86
    auto outer_loop = tiling.outer_loop();
1✔
87

88
    analysis::UsersView users_view(analysis_manager.get<analysis::Users>(), inner_loop->root());
1✔
89

90
    for (const auto& container_name : target_containers_) {
2✔
91
        auto& users = analysis_manager.get<analysis::Users>();
2✔
92
        analysis::UsersView users_view(users, inner_loop->root());
2✔
93

94
        auto reads = users_view.reads(container_name);
2✔
95
        if (reads.empty()) continue;
2✔
96

97
        auto* access = dynamic_cast<data_flow::AccessNode*>(reads.front()->element());
2✔
98
        if (!access) continue;
2✔
99

100
        KernelLocalStorage kls(*inner_loop, outer_loop->indvar(), *access);
2✔
101
        if (kls.can_be_applied(builder, analysis_manager)) {
2✔
102
            kls.apply(builder, analysis_manager);
2✔
103
        }
2✔
104
    }
2✔
105

106
    passes::SyncConditionPropagation sync_condition_propagation;
1✔
107
    sync_condition_propagation.run_pass(builder, analysis_manager);
1✔
108

109
    applied_ = true;
1✔
110
    inner_loop_ = inner_loop;
1✔
111
    outer_loop_ = outer_loop;
1✔
112

113
    auto& users = analysis_manager.get<analysis::Users>();
1✔
114
    analysis::UsersView users_view_inner_loop(users, inner_loop->root());
1✔
115

116
    analysis::TypeAnalysis type_analysis(builder.subject(), inner_loop, analysis_manager);
1✔
117
    for (const auto& write : users_view_inner_loop.writes()) {
1✔
118
        if (!dynamic_cast<data_flow::AccessNode*>(write->element())) {
1✔
119
            continue;
×
120
        }
×
121
        if (type_analysis.get_outer_type(write->container())->type_id() == types::TypeID::Scalar ||
1✔
122
            type_analysis.get_outer_type(write->container())->type_id() == types::TypeID::Structure) {
1✔
123
            continue;
×
124
        }
×
125
        auto access_node = dynamic_cast<data_flow::AccessNode*>(write->element());
1✔
126
        OutLocalStorage ols(*inner_loop, *access_node);
1✔
127
        if (ols.can_be_applied(builder, analysis_manager)) {
1✔
128
            ols.apply(builder, analysis_manager);
1✔
129
        }
1✔
130
    }
1✔
131
}
1✔
132

133
void GPUTiling::to_json(nlohmann::json& j) const {
2✔
134
    j["transformation_type"] = this->name();
2✔
135
    j["parameters"] = nlohmann::json::object();
2✔
136
    j["parameters"]["size"] = size_;
2✔
137

138
    serializer::JSONSerializer ser_flat(false);
2✔
139
    j["subgraph"] = nlohmann::json::object();
2✔
140
    j["subgraph"]["0"] = nlohmann::json::object();
2✔
141
    ser_flat.serialize_node(j["subgraph"]["0"], loop_);
2✔
142
}
2✔
143

144
GPUTiling GPUTiling::from_json(builder::StructuredSDFGBuilder& builder, const nlohmann::json& j) {
2✔
145
    // Prefer embedding-compatible representation, but support legacy layout.
146
    size_t loop_id;
2✔
147
    const auto& node_desc = j.at("subgraph").at("0");
2✔
148
    loop_id = node_desc.at("element_id").get<size_t>();
2✔
149

150
    auto element = builder.find_element_by_id(loop_id);
2✔
151
    if (!element) {
2✔
UNCOV
152
        throw InvalidTransformationDescriptionException("Element with ID " + std::to_string(loop_id) + " not found.");
×
UNCOV
153
    }
×
154
    auto loop = dynamic_cast<structured_control_flow::StructuredLoop*>(element);
2✔
155

156
    size_t size = j.at("parameters").at("size").get<size_t>();
2✔
157

158
    return GPUTiling(*loop, size);
2✔
159
}
2✔
160

161
structured_control_flow::StructuredLoop* GPUTiling::inner_loop() {
1✔
162
    if (!applied_) {
1✔
UNCOV
163
        throw InvalidSDFGException("Accessing tiled loop before their creation.");
×
164
    }
×
165

166
    return inner_loop_;
1✔
167
}
1✔
168

169
structured_control_flow::StructuredLoop* GPUTiling::outer_loop() {
1✔
170
    if (!applied_) {
1✔
UNCOV
171
        throw InvalidSDFGException("Accessing tiled loop before their creation.");
×
UNCOV
172
    }
×
173

174
    return outer_loop_;
1✔
175
}
1✔
176

177
} // namespace transformations
178
} // 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