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

daisytuner / docc / 23906044628

02 Apr 2026 02:40PM UTC coverage: 64.553% (+0.08%) from 64.474%
23906044628

Pull #632

github

web-flow
Merge b2698daab into 3125b927b
Pull Request #632: Separate can_be_applied and apply for GPUTilling during Loop Scheduling

282 of 348 new or added lines in 16 files covered. (81.03%)

29 existing lines in 10 files now uncovered.

28998 of 44921 relevant lines covered (64.55%)

453.01 hits per line

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

80.95
/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/passes/offloading/sync_condition_propagation.h"
9
#include "sdfg/structured_control_flow/for.h"
10
#include "sdfg/structured_control_flow/map.h"
11
#include "sdfg/structured_control_flow/structured_loop.h"
12
#include "sdfg/structured_control_flow/while.h"
13
#include "sdfg/transformations/loop_tiling.h"
14
#include "sdfg/transformations/offloading/kernel_local_storage.h"
15
#include "sdfg/transformations/out_local_storage.h"
16

17

18
namespace sdfg {
19
namespace transformations {
20

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

23
std::string GPUTiling::name() const { return "GPUTiling"; }
3✔
24

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

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

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

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

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

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

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

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

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

49
    std::set<std::string> read_containers;
1✔
50
    for (auto read : users_view.reads()) {
11✔
51
        read_containers.insert(read->container());
11✔
52
    }
11✔
53

54
    if (read_containers.empty()) {
1✔
55
        return false;
×
56
    }
×
57

58
    std::set<std::string> target_containers;
1✔
59
    int i = 0;
1✔
60
    for (const auto& container : read_containers) {
6✔
61
        KernelLocalStorage kls(*inner_loop, outer_loop->indvar(), container);
6✔
62
        if (kls.can_be_applied(builder_local, analysis_manager_local)) {
6✔
63
            target_containers.insert(container);
2✔
64
        }
2✔
65
    }
6✔
66
    if (target_containers.empty()) {
1✔
UNCOV
67
        return false;
×
UNCOV
68
    }
×
69

70
    return true;
1✔
71
}
1✔
72

73
void GPUTiling::apply(builder::StructuredSDFGBuilder& builder, analysis::AnalysisManager& analysis_manager) {
1✔
74
    LoopTiling tiling(loop_, size_);
1✔
75
    tiling.apply(builder, analysis_manager);
1✔
76
    auto inner_loop = tiling.inner_loop();
1✔
77
    auto outer_loop = tiling.outer_loop();
1✔
78

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

81
    std::set<std::string> read_containers;
1✔
82
    for (auto read : users_view.reads()) {
11✔
83
        read_containers.insert(read->container());
11✔
84
    }
11✔
85

86
    for (const auto& container : read_containers) {
6✔
87
        KernelLocalStorage kls(*inner_loop, outer_loop->indvar(), container);
6✔
88
        if (kls.can_be_applied(builder, analysis_manager)) {
6✔
89
            kls.apply(builder, analysis_manager);
2✔
90
        }
2✔
91
    }
6✔
92

93
    passes::SyncConditionPropagation sync_condition_propagation;
1✔
94
    sync_condition_propagation.run_pass(builder, analysis_manager);
1✔
95

96
    applied_ = true;
1✔
97
    inner_loop_ = inner_loop;
1✔
98
    outer_loop_ = outer_loop;
1✔
99

100
    auto& users = analysis_manager.get<analysis::Users>();
1✔
101
    analysis::UsersView users_view_inner_loop(users, inner_loop->root());
1✔
102

103
    std::set<std::string> target_containers;
1✔
104
    for (auto& write : users_view_inner_loop.writes()) {
1✔
105
        target_containers.insert(write->container());
1✔
106
    }
1✔
107

108
    analysis::TypeAnalysis type_analysis(builder.subject(), inner_loop, analysis_manager);
1✔
109
    for (const auto& container : target_containers) {
1✔
110
        if (type_analysis.get_outer_type(container)->type_id() == types::TypeID::Scalar ||
1✔
111
            type_analysis.get_outer_type(container)->type_id() == types::TypeID::Structure) {
1✔
112
            continue;
×
113
        }
×
114
        OutLocalStorage ols(*inner_loop, container);
1✔
115
        if (ols.can_be_applied(builder, analysis_manager)) {
1✔
116
            ols.apply(builder, analysis_manager);
1✔
117
        }
1✔
118
    }
1✔
119
}
1✔
120

121
void GPUTiling::to_json(nlohmann::json& j) const {
1✔
122
    j["transformation_type"] = this->name();
1✔
123

124
    // Determine loop type consistent with GNN feature extractor labelling.
125
    std::string loop_type;
1✔
126
    if (dynamic_cast<structured_control_flow::For*>(&loop_)) {
1✔
127
        loop_type = "for";
1✔
128
    } else if (dynamic_cast<structured_control_flow::While*>(&loop_)) {
1✔
129
        loop_type = "while";
×
130
    } else if (dynamic_cast<structured_control_flow::Map*>(&loop_)) {
×
131
        loop_type = "map";
×
132
    } else {
×
133
        loop_type = "unknown";
×
134
    }
×
135

136
    // Embedding-compatible description used by EmbeddingRecorder/EmbeddingReplayer.
137
    j["subgraph"] = {{"0", {{"element_id", this->loop_.element_id()}, {"type", loop_type}}}};
1✔
138
    j["parameters"] = {{"size", this->size_}};
1✔
139

140
    // Legacy fields for backward compatibility.
141
    j["loop_element_id"] = this->loop_.element_id();
1✔
142
    j["size"] = this->size_;
1✔
143
}
1✔
144

145
GPUTiling GPUTiling::from_json(builder::StructuredSDFGBuilder& builder, const nlohmann::json& j) {
1✔
146
    // Prefer embedding-compatible representation, but support legacy layout.
147
    size_t loop_id;
1✔
148
    if (j.contains("subgraph")) {
1✔
149
        const auto& node_desc = j.at("subgraph").at("0");
1✔
150
        loop_id = node_desc.at("element_id").get<size_t>();
1✔
151
    } else {
1✔
152
        loop_id = j.at("loop_element_id").get<size_t>();
×
153
    }
×
154

155
    auto element = builder.find_element_by_id(loop_id);
1✔
156
    if (!element) {
1✔
157
        throw InvalidTransformationDescriptionException("Element with ID " + std::to_string(loop_id) + " not found.");
×
158
    }
×
159
    auto loop = dynamic_cast<structured_control_flow::StructuredLoop*>(element);
1✔
160

161
    size_t size;
1✔
162
    if (j.contains("parameters") && j.at("parameters").contains("size")) {
1✔
163
        size = j.at("parameters").at("size").get<size_t>();
1✔
164
    } else {
1✔
165
        size = j.at("size").get<size_t>();
×
166
    }
×
167

168
    return GPUTiling(*loop, size);
1✔
169
}
1✔
170

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

176
    return inner_loop_;
1✔
177
}
1✔
178

179
structured_control_flow::StructuredLoop* GPUTiling::outer_loop() {
1✔
180
    if (!applied_) {
1✔
181
        throw InvalidSDFGException("Accessing tiled loop before their creation.");
×
182
    }
×
183

184
    return outer_loop_;
1✔
185
}
1✔
186

187
} // namespace transformations
188
} // 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