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

daisytuner / sdfglib / 15455990921

05 Jun 2025 01:03AM UTC coverage: 57.883% (-0.4%) from 58.236%
15455990921

push

github

web-flow
Merge pull request #56 from daisytuner/allocations

removes allocation handling

15 of 36 new or added lines in 4 files covered. (41.67%)

27 existing lines in 4 files now uncovered.

8018 of 13852 relevant lines covered (57.88%)

107.95 hits per line

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

62.42
/src/codegen/code_generators/cuda_code_generator.cpp
1
#include "sdfg/codegen/code_generators/cuda_code_generator.h"
2

3
#include "sdfg/codegen/dispatchers/node_dispatcher_factory.h"
4
#include "sdfg/codegen/instrumentation/instrumentation.h"
5
#include "sdfg/codegen/instrumentation/outermost_loops_instrumentation.h"
6

7
namespace sdfg {
8
namespace codegen {
9

10
CUDACodeGenerator::CUDACodeGenerator(ConditionalSchedule& schedule)
10✔
11
    : CodeGenerator(schedule, InstrumentationStrategy::NONE) {
5✔
12

13
      };
5✔
14

NEW
15
CUDACodeGenerator::CUDACodeGenerator(ConditionalSchedule& schedule,
×
16
                                     InstrumentationStrategy instrumentation_strategy)
NEW
17
    : CodeGenerator(schedule, instrumentation_strategy) {
×
18

19
      };
×
20

21
bool CUDACodeGenerator::generate() {
4✔
22
    this->dispatch_includes();
4✔
23
    this->dispatch_structures();
4✔
24
    this->dispatch_globals();
4✔
25
    this->dispatch_schedule();
4✔
26
    return true;
4✔
27
};
28

29
std::string CUDACodeGenerator::function_definition() {
1✔
30
    // Define SDFG as a function
31
    auto& function = this->schedule_.schedule(0).sdfg();
1✔
32

33
    /********** Arglist **********/
34
    std::vector<std::string> args;
1✔
35
    for (auto& container : function.arguments()) {
1✔
36
        args.push_back(language_extension_.declaration(container, function.type(container)));
×
37
    }
38
    std::stringstream arglist;
1✔
39
    arglist << sdfg::helpers::join(args, ", ");
1✔
40

41
    return "extern \"C\" __global__ void " + function.name() + "(" + arglist.str() + ")";
1✔
42
};
1✔
43

44
bool CUDACodeGenerator::as_source(const std::filesystem::path& header_path,
×
45
                                  const std::filesystem::path& source_path,
46
                                  const std::filesystem::path& library_path) {
47
    std::ofstream ofs_header(header_path, std::ofstream::out);
×
48
    if (!ofs_header.is_open()) {
×
49
        return false;
×
50
    }
51

52
    std::ofstream ofs_source(source_path, std::ofstream::out);
×
53
    if (!ofs_source.is_open()) {
×
54
        return false;
×
55
    }
56

57
    std::ofstream ofs_library(library_path, std::ofstream::out);
×
58
    if (!ofs_library.is_open()) {
×
59
        return false;
×
60
    }
61

62
    ofs_header << "#pragma once" << std::endl;
×
63
    ofs_header << this->includes_stream_.str() << std::endl;
×
64
    ofs_header << this->classes_stream_.str() << std::endl;
×
65
    ofs_header.close();
×
66

67
    ofs_source << "#include \"" << header_path.filename().string() << "\"" << std::endl;
×
68
    ofs_source << this->globals_stream_.str() << std::endl;
×
69
    ofs_source << this->function_definition() << std::endl;
×
70
    ofs_source << "{" << std::endl;
×
71
    ofs_source << this->main_stream_.str() << std::endl;
×
72
    ofs_source << "}" << std::endl;
×
73
    ofs_source.close();
×
74

75
    auto library_content = this->library_stream_.str();
×
76
    if (library_content.empty()) {
×
77
        ofs_library.close();
×
78
        return true;
×
79
    }
80

81
    ofs_library << "#include \"" << header_path.filename().string() << "\"" << std::endl;
×
82
    ofs_library << library_content << std::endl;
×
83
    ofs_library.close();
×
84

85
    return true;
×
86
};
×
87

88
void CUDACodeGenerator::dispatch_includes() {
4✔
89
    this->includes_stream_ << "#define "
4✔
90
                           << "__DAISY_NVVM__" << std::endl;
4✔
91
    this->includes_stream_ << "#include "
4✔
92
                           << "\"daisyrtl.h\"" << std::endl;
4✔
93
    if (instrumentation_strategy_ != InstrumentationStrategy::NONE)
4✔
NEW
94
        this->includes_stream_ << "#include <daisy_rtl.h>" << std::endl;
×
95

96
    this->includes_stream_ << "#define __daisy_min(a,b) ((a)<(b)?(a):(b))" << std::endl;
4✔
97
    this->includes_stream_ << "#define __daisy_max(a,b) ((a)>(b)?(a):(b))" << std::endl;
4✔
98
    this->includes_stream_ << "#define __daisy_fma(a,b,c) a * b + c" << std::endl;
4✔
99
};
4✔
100

101
void CUDACodeGenerator::dispatch_structures() {
4✔
102
    auto& function = this->schedule_.schedule(0).sdfg();
4✔
103

104
    // Forward declarations
105
    for (auto& structure : function.structures()) {
7✔
106
        this->classes_stream_ << "struct " << structure << ";" << std::endl;
3✔
107
    }
108

109
    // Generate topology-sorted structure definitions
110
    typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS> structures_graph;
111
    typedef boost::graph_traits<structures_graph>::vertex_descriptor Vertex;
112
    std::vector<std::string> names;
4✔
113
    for (auto& structure : function.structures()) {
7✔
114
        names.push_back(structure);
3✔
115
    }
116
    structures_graph graph(names.size());
4✔
117

118
    for (auto& structure : names) {
7✔
119
        auto& definition = function.structure(structure);
3✔
120
        for (size_t i = 0; i < definition.num_members(); i++) {
6✔
121
            auto member_type = &definition.member_type(symbolic::integer(i));
3✔
122
            while (dynamic_cast<const types::Array*>(member_type)) {
3✔
123
                auto array_type = static_cast<const types::Array*>(member_type);
×
124
                member_type = &array_type->element_type();
×
125
            }
126

127
            if (auto member_structure = dynamic_cast<const sdfg::types::Structure*>(member_type)) {
3✔
128
                boost::add_edge(
1✔
129
                    std::find(names.begin(), names.end(), member_structure->name()) - names.begin(),
1✔
130
                    std::find(names.begin(), names.end(), structure) - names.begin(), graph);
1✔
131
            }
1✔
132
        }
3✔
133
    }
134

135
    std::list<Vertex> order;
4✔
136
    std::unordered_map<Vertex, boost::default_color_type> vertex_colors;
4✔
137
    boost::topological_sort(graph, std::back_inserter(order),
8✔
138
                            boost::color_map(boost::make_assoc_property_map(vertex_colors)));
4✔
139
    order.reverse();
4✔
140

141
    for (auto& structure_index : order) {
7✔
142
        std::string structure = names.at(structure_index);
3✔
143
        auto& definition = function.structure(structure);
3✔
144
        this->classes_stream_ << "struct ";
3✔
145
        if (definition.is_packed()) {
3✔
146
            this->classes_stream_ << "__attribute__((packed)) ";
×
147
        }
×
148
        this->classes_stream_ << structure << std::endl;
3✔
149
        this->classes_stream_ << "{\n";
3✔
150

151
        for (size_t i = 0; i < definition.num_members(); i++) {
6✔
152
            auto& member_type = definition.member_type(symbolic::integer(i));
3✔
153
            if (dynamic_cast<const sdfg::types::Structure*>(&member_type)) {
3✔
154
                this->classes_stream_ << "struct ";
1✔
155
            }
1✔
156
            this->classes_stream_ << language_extension_.declaration("member_" + std::to_string(i),
3✔
157
                                                                     member_type);
3✔
158
            this->classes_stream_ << ";" << std::endl;
3✔
159
        }
3✔
160

161
        this->classes_stream_ << "};" << std::endl;
3✔
162
    }
3✔
163
};
4✔
164

165
void CUDACodeGenerator::dispatch_globals() {
4✔
166
    auto& function = schedule_.schedule(0).sdfg();
4✔
167
    for (auto& container : function.externals()) {
5✔
168
        auto& type = function.type(container);
1✔
169
        if (type.address_space() != 3 && type.address_space() != 4) {
1✔
170
            this->globals_stream_ << "extern " << language_extension_.declaration(container, type)
2✔
171
                                  << ";" << std::endl;
1✔
172
        }
1✔
173
        if (type.address_space() == 4) {
1✔
174
            assert(type.initializer().empty());
×
175
            this->globals_stream_ << "__constant__ "
×
176
                                  << language_extension_.declaration(container, type, true) << ";"
×
177
                                  << std::endl;
×
178
        }
×
179
    }
180
};
4✔
181

182
void CUDACodeGenerator::dispatch_schedule() {
4✔
183
    auto& function = schedule_.schedule(0).sdfg();
4✔
184

185
    // Declare shared memory
186
    for (auto& container : function.externals()) {
5✔
187
        auto& type = function.type(container);
1✔
188
        if (type.address_space() == 3) {
1✔
189
            this->main_stream_ << language_extension_.declaration(container,
×
190
                                                                  function.type(container))
×
191
                               << ";" << std::endl;
×
192
        }
×
193
    }
194

195
    // Map external variables to internal variables
196
    for (auto& container : function.containers()) {
5✔
197
        if (!function.is_internal(container)) {
1✔
198
            continue;
1✔
199
        }
200

201
        std::string external_name =
202
            container.substr(0, container.length() - external_suffix.length());
×
203
        this->main_stream_ << language_extension_.declaration(container, function.type(container));
×
204
        this->main_stream_ << " = "
×
205
                           << "&" << external_name;
×
206
        this->main_stream_ << ";" << std::endl;
×
207
    }
×
208

209
    // Declare transient containers
210
    for (auto& container : function.containers()) {
5✔
211
        if (!function.is_transient(container)) {
1✔
212
            continue;
1✔
213
        }
214

215
        std::string val =
NEW
216
            this->language_extension_.declaration(container, function.type(container));
×
NEW
217
        if (!val.empty()) {
×
NEW
218
            this->main_stream_ << val;
×
NEW
219
            this->main_stream_ << ";" << std::endl;
×
NEW
220
        }
×
NEW
221
    }
×
222

223
    for (size_t i = 0; i < schedule_.size(); i++) {
8✔
224
        auto& schedule = schedule_.schedule(i);
4✔
225
        auto condition = schedule_.condition(i);
4✔
226

227
        // Add instrumentation
228
        auto instrumentation = create_instrumentation(instrumentation_strategy_, schedule);
4✔
229

230
        if (i > 0) {
4✔
231
            this->main_stream_ << "else ";
×
232
        }
×
233

234
        this->main_stream_ << "if (" << language_extension_.expression(condition) << ") {\n";
4✔
235

236
        auto& function_i = schedule.builder().subject();
4✔
237
        auto dispatcher =
238
            create_dispatcher(language_extension_, schedule, function_i.root(), *instrumentation);
4✔
239
        dispatcher->dispatch(this->main_stream_, this->globals_stream_, this->library_stream_);
4✔
240

241
        this->main_stream_ << "}\n";
4✔
242
    }
4✔
243
};
4✔
244

245
}  // namespace codegen
246
}  // 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