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

daisytuner / docc / 23978459061

04 Apr 2026 12:00PM UTC coverage: 64.742%. First build
23978459061

Pull #644

github

web-flow
Merge 6d8b19c63 into 811a5c32e
Pull Request #644: adapts new loop analysis api

39 of 44 new or added lines in 16 files covered. (88.64%)

29101 of 44949 relevant lines covered (64.74%)

532.86 hits per line

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

80.36
/opt/src/targets/gpu/gpu_map_utils.cpp
1
#include "sdfg/targets/gpu/gpu_map_utils.h"
2

3
#include "sdfg/analysis/assumptions_analysis.h"
4
#include "sdfg/analysis/loop_analysis.h"
5
#include "sdfg/targets/cuda/cuda.h"
6
#include "sdfg/targets/rocm/rocm.h"
7

8
namespace sdfg {
9
namespace gpu {
10

11
template<typename ScheduleT>
12
symbolic::Expression find_nested_gpu_blocksize(
13
    structured_control_flow::Map& node, analysis::AnalysisManager& analysis_manager, GPUDimension dimension
14
) {
24✔
15
    auto& loop_analysis = analysis_manager.get<analysis::LoopAnalysis>();
24✔
16
    auto loops = loop_analysis.descendants(&node);
24✔
17
    loops.insert(&node);
24✔
18

19
    // Check for repeated dimensions in loop tree paths
20
    auto loop_tree_paths = loop_analysis.loop_tree_paths(&node);
24✔
21
    for (auto& path : loop_tree_paths) {
24✔
22
        bool foundX = false;
24✔
23
        bool foundY = false;
24✔
24
        bool foundZ = false;
24✔
25
        for (auto& loop : path) {
39✔
26
            if (auto map = dynamic_cast<structured_control_flow::Map*>(loop)) {
39✔
27
                if (map->schedule_type().value() == ScheduleT::value()) {
39✔
28
                    auto dim = ScheduleT::dimension(map->schedule_type());
39✔
29
                    if (dim == GPUDimension::X) {
39✔
30
                        if (foundX) {
12✔
31
                            throw InvalidSDFGException("Nested map in GPU kernel has repeated X dimension");
×
32
                        }
×
33
                        foundX = true;
12✔
34
                    } else if (dim == GPUDimension::Y) {
27✔
35
                        if (foundY) {
12✔
36
                            throw InvalidSDFGException("Nested map in GPU kernel has repeated Y dimension");
×
37
                        }
×
38
                        foundY = true;
12✔
39
                    } else if (dim == GPUDimension::Z) {
15✔
40
                        if (foundZ) {
15✔
41
                            throw InvalidSDFGException("Nested map in GPU kernel has repeated Z dimension");
×
42
                        }
×
43
                        foundZ = true;
15✔
44
                    }
15✔
45
                }
39✔
46
            }
39✔
47
        }
39✔
48
    }
24✔
49

50
    // Find block size for the requested dimension
51
    for (auto loop : loops) {
33✔
52
        if (auto map = dynamic_cast<structured_control_flow::Map*>(loop)) {
33✔
53
            if (map->schedule_type().value() != ScheduleT::value() &&
33✔
54
                map->schedule_type().value() != structured_control_flow::ScheduleType_Sequential::value()) {
33✔
55
                throw InvalidSDFGException("Nested map in GPU kernel not GPU or Sequential");
×
56
            }
×
57

58
            if (map->schedule_type().value() == structured_control_flow::ScheduleType_Sequential::value()) {
33✔
59
                continue;
×
60
            }
×
61

62
            if (ScheduleT::dimension(map->schedule_type()) == dimension) {
33✔
63
                return ScheduleT::block_size(map->schedule_type());
13✔
64
            }
13✔
65
        }
33✔
66
    }
33✔
67
    return symbolic::one();
11✔
68
}
24✔
69

70
template<typename ScheduleT>
71
symbolic::Expression find_nested_gpu_iterations(
72
    structured_control_flow::Map& node, analysis::AnalysisManager& analysis_manager, GPUDimension dimension
73
) {
24✔
74
    auto& loop_analysis = analysis_manager.get<analysis::LoopAnalysis>();
24✔
75
    auto loops = loop_analysis.descendants(&node);
24✔
76
    loops.insert(&node);
24✔
77

78
    for (auto loop : loops) {
33✔
79
        if (auto map = dynamic_cast<structured_control_flow::Map*>(loop)) {
33✔
80
            if (map->schedule_type().value() != ScheduleT::value() &&
33✔
81
                map->schedule_type().value() != structured_control_flow::ScheduleType_Sequential::value()) {
33✔
82
                throw InvalidSDFGException("Nested map in GPU kernel not GPU or Sequential");
×
83
            }
×
84
            if (map->schedule_type().value() == structured_control_flow::ScheduleType_Sequential::value()) {
33✔
85
                continue;
×
86
            }
×
87
            if (ScheduleT::dimension(map->schedule_type()) != dimension) {
33✔
88
                continue;
20✔
89
            }
20✔
90

91
            auto init = map->init();
13✔
92
            if (!symbolic::eq(init, symbolic::zero())) {
13✔
93
                throw InvalidSDFGException("Init is not zero");
×
94
            }
×
95

96
            auto stride = map->stride();
13✔
97
            if (!symbolic::eq(stride, symbolic::one())) {
13✔
98
                throw InvalidSDFGException("Stride is not one");
×
99
            }
×
100

101
            auto num_iterations = map->num_iterations();
13✔
102
            if (num_iterations.is_null()) {
13✔
NEW
103
                throw InvalidSDFGException("Cannot determine number of iterations for nested map in GPU kernel");
×
104
            }
×
105
            return num_iterations;
13✔
106
        }
13✔
107
    }
33✔
108
    return symbolic::one();
11✔
109
}
24✔
110

111
template<typename ScheduleT>
112
bool is_outermost_gpu_map(structured_control_flow::Map& node, analysis::AnalysisManager& analysis_manager) {
16✔
113
    auto& loop_analysis = analysis_manager.get<analysis::LoopAnalysis>();
16✔
114
    auto& loop_tree = loop_analysis.loop_tree();
16✔
115
    structured_control_flow::ControlFlowNode* ancestor = loop_tree.at(&node);
16✔
116
    while (ancestor != nullptr) {
16✔
117
        if (auto map = dynamic_cast<structured_control_flow::Map*>(ancestor)) {
8✔
118
            if (map->schedule_type().value() == ScheduleT::value()) {
8✔
119
                return false;
8✔
120
            }
8✔
121
        }
8✔
122
        ancestor = loop_tree.at(ancestor);
×
123
    }
×
124
    return true;
8✔
125
}
16✔
126

127
template<typename ScheduleT>
128
symbolic::SymbolSet get_gpu_indvars(
129
    structured_control_flow::Map& node, analysis::AnalysisManager& analysis_manager, GPUDimension dimension
130
) {
24✔
131
    auto& loop_analysis = analysis_manager.get<analysis::LoopAnalysis>();
24✔
132
    auto loops = loop_analysis.descendants(&node);
24✔
133
    loops.insert(&node);
24✔
134
    symbolic::SymbolSet indvars;
24✔
135
    for (const auto& loop : loops) {
39✔
136
        if (auto map = dynamic_cast<structured_control_flow::Map*>(loop)) {
39✔
137
            if (map->schedule_type().value() == ScheduleT::value()) {
39✔
138
                if (ScheduleT::dimension(map->schedule_type()) == dimension) {
39✔
139
                    indvars.insert(map->indvar());
13✔
140
                }
13✔
141
            }
39✔
142
        }
39✔
143
    }
39✔
144
    return indvars;
24✔
145
}
24✔
146

147
// Explicit template instantiations for CUDA
148
template symbolic::Expression find_nested_gpu_blocksize<cuda::ScheduleType_CUDA>(
149
    structured_control_flow::Map& node, analysis::AnalysisManager& analysis_manager, GPUDimension dimension
150
);
151

152
template symbolic::Expression find_nested_gpu_iterations<cuda::ScheduleType_CUDA>(
153
    structured_control_flow::Map& node, analysis::AnalysisManager& analysis_manager, GPUDimension dimension
154
);
155

156
template bool is_outermost_gpu_map<
157
    cuda::ScheduleType_CUDA>(structured_control_flow::Map& node, analysis::AnalysisManager& analysis_manager);
158

159
template symbolic::SymbolSet get_gpu_indvars<cuda::ScheduleType_CUDA>(
160
    structured_control_flow::Map& node, analysis::AnalysisManager& analysis_manager, GPUDimension dimension
161
);
162

163
// Explicit template instantiations for ROCM
164
template symbolic::Expression find_nested_gpu_blocksize<rocm::ScheduleType_ROCM>(
165
    structured_control_flow::Map& node, analysis::AnalysisManager& analysis_manager, GPUDimension dimension
166
);
167

168
template symbolic::Expression find_nested_gpu_iterations<rocm::ScheduleType_ROCM>(
169
    structured_control_flow::Map& node, analysis::AnalysisManager& analysis_manager, GPUDimension dimension
170
);
171

172
template bool is_outermost_gpu_map<
173
    rocm::ScheduleType_ROCM>(structured_control_flow::Map& node, analysis::AnalysisManager& analysis_manager);
174

175
template symbolic::SymbolSet get_gpu_indvars<rocm::ScheduleType_ROCM>(
176
    structured_control_flow::Map& node, analysis::AnalysisManager& analysis_manager, GPUDimension dimension
177
);
178

179
} // namespace gpu
180
} // 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