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

daisytuner / sdfglib / 16188914472

10 Jul 2025 07:30AM UTC coverage: 64.808% (+0.1%) from 64.705%
16188914472

push

github

web-flow
Merge pull request #138 from daisytuner/tenstorrent/trivial

lib_stream -> lib_snippet_factory in code generation

131 of 243 new or added lines in 18 files covered. (53.91%)

3 existing lines in 3 files now uncovered.

8545 of 13185 relevant lines covered (64.81%)

179.13 hits per line

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

64.79
/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_registry.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(
10✔
11
    StructuredSDFG& sdfg,
12
    InstrumentationStrategy instrumentation_strategy,
13
    bool capture_args_results,
14
    const std::pair<std::filesystem::path, std::filesystem::path>* output_and_header_paths
15
)
16
    : CodeGenerator(sdfg, instrumentation_strategy, capture_args_results, output_and_header_paths) {
5✔
17
    if (sdfg.type() != FunctionType_NV_GLOBAL) {
5✔
18
        throw std::runtime_error("CUDACodeGenerator can only be used for GPU SDFGs");
×
19
    }
20
    if (capture_args_results) {
5✔
21
        std::cerr << "CUDACodeGenerator does not support capturing args/results!";
×
22
    }
×
23
};
5✔
24

25
bool CUDACodeGenerator::generate() {
4✔
26
    this->dispatch_includes();
4✔
27
    this->dispatch_structures();
4✔
28
    this->dispatch_globals();
4✔
29
    this->dispatch_schedule();
4✔
30
    return true;
4✔
31
};
32

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

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

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

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

56
    ofs_header << "#pragma once" << std::endl;
×
57
    ofs_header << this->includes_stream_.str() << std::endl;
×
58
    ofs_header << this->classes_stream_.str() << std::endl;
×
59
    ofs_header.close();
×
60

61
    ofs_source << "#include \"" << header_path.filename().string() << "\"" << std::endl;
×
62

63
    ofs_source << this->globals_stream_.str() << std::endl;
×
64

NEW
65
    append_function_source(ofs_source);
×
66

NEW
67
    ofs_source.close();
×
68

69
    return true;
×
70
};
×
71

NEW
72
void CUDACodeGenerator::append_function_source(std::ofstream& ofs_source) {
×
NEW
73
    ofs_source << this->function_definition() << std::endl;
×
NEW
74
    ofs_source << "{" << std::endl;
×
NEW
75
    ofs_source << this->main_stream_.str() << std::endl;
×
NEW
76
    ofs_source << "}" << std::endl;
×
NEW
77
}
×
78

79
void CUDACodeGenerator::dispatch_includes() {
4✔
80
    this->includes_stream_ << "#define "
4✔
81
                           << "__DAISY_NVVM__" << std::endl;
4✔
82
    this->includes_stream_ << "#include "
4✔
83
                           << "\"daisyrtl.h\"" << std::endl;
4✔
84
    if (instrumentation_strategy_ != InstrumentationStrategy::NONE)
4✔
85
        this->includes_stream_ << "#include <daisy_rtl.h>" << std::endl;
×
86

87
    this->includes_stream_ << "#define __daisy_min(a,b) ((a)<(b)?(a):(b))" << std::endl;
4✔
88
    this->includes_stream_ << "#define __daisy_max(a,b) ((a)>(b)?(a):(b))" << std::endl;
4✔
89
    this->includes_stream_ << "#define __daisy_fma(a,b,c) a * b + c" << std::endl;
4✔
90
};
4✔
91

92
void CUDACodeGenerator::dispatch_structures() {
4✔
93
    // Forward declarations
94
    for (auto& structure : sdfg_.structures()) {
7✔
95
        this->classes_stream_ << "struct " << structure << ";" << std::endl;
3✔
96
    }
97

98
    // Generate topology-sorted structure definitions
99
    typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS> structures_graph;
100
    typedef boost::graph_traits<structures_graph>::vertex_descriptor Vertex;
101
    std::vector<std::string> names;
4✔
102
    for (auto& structure : sdfg_.structures()) {
7✔
103
        names.push_back(structure);
3✔
104
    }
105
    structures_graph graph(names.size());
4✔
106

107
    for (auto& structure : names) {
7✔
108
        auto& definition = sdfg_.structure(structure);
3✔
109
        for (size_t i = 0; i < definition.num_members(); i++) {
6✔
110
            auto member_type = &definition.member_type(symbolic::integer(i));
3✔
111
            while (dynamic_cast<const types::Array*>(member_type)) {
3✔
112
                auto array_type = static_cast<const types::Array*>(member_type);
×
113
                member_type = &array_type->element_type();
×
114
            }
115

116
            if (auto member_structure = dynamic_cast<const sdfg::types::Structure*>(member_type)) {
3✔
117
                boost::add_edge(
1✔
118
                    std::find(names.begin(), names.end(), member_structure->name()) - names.begin(),
1✔
119
                    std::find(names.begin(), names.end(), structure) - names.begin(),
1✔
120
                    graph
121
                );
122
            }
1✔
123
        }
3✔
124
    }
125

126
    std::list<Vertex> order;
4✔
127
    std::unordered_map<Vertex, boost::default_color_type> vertex_colors;
4✔
128
    boost::topological_sort(
4✔
129
        graph, std::back_inserter(order), boost::color_map(boost::make_assoc_property_map(vertex_colors))
4✔
130
    );
131
    order.reverse();
4✔
132

133
    for (auto& structure_index : order) {
7✔
134
        std::string structure = names.at(structure_index);
3✔
135
        auto& definition = sdfg_.structure(structure);
3✔
136
        this->classes_stream_ << "struct ";
3✔
137
        if (definition.is_packed()) {
3✔
138
            this->classes_stream_ << "__attribute__((packed)) ";
×
139
        }
×
140
        this->classes_stream_ << structure << std::endl;
3✔
141
        this->classes_stream_ << "{\n";
3✔
142

143
        for (size_t i = 0; i < definition.num_members(); i++) {
6✔
144
            auto& member_type = definition.member_type(symbolic::integer(i));
3✔
145
            if (dynamic_cast<const sdfg::types::Structure*>(&member_type)) {
3✔
146
                this->classes_stream_ << "struct ";
1✔
147
            }
1✔
148
            this->classes_stream_
6✔
149
                << language_extension_.declaration("member_" + std::to_string(i), member_type, false, true);
3✔
150
            this->classes_stream_ << ";" << std::endl;
3✔
151
        }
3✔
152

153
        this->classes_stream_ << "};" << std::endl;
3✔
154
    }
3✔
155
};
4✔
156

157
void CUDACodeGenerator::dispatch_globals() {
4✔
158
    for (auto& container : sdfg_.externals()) {
5✔
159
        auto& type = sdfg_.type(container);
1✔
160
        if (type.storage_type() == types::StorageType_NV_Global) {
1✔
161
            this->globals_stream_ << "extern " << language_extension_.declaration(container, type) << ";" << std::endl;
1✔
162
        }
1✔
163
        if (type.storage_type() == types::StorageType_NV_Constant) {
1✔
164
            assert(type.initializer().empty());
×
NEW
165
            this->globals_stream_ << "__constant__ " << language_extension_.declaration(container, type, true) << ";"
×
166
                                  << std::endl;
×
167
        }
×
168
    }
169
};
4✔
170

171
void CUDACodeGenerator::dispatch_schedule() {
4✔
172
    // Declare shared memory
173
    for (auto& container : sdfg_.externals()) {
5✔
174
        auto& type = sdfg_.type(container);
1✔
175
        if (type.storage_type() == types::StorageType_NV_Shared) {
1✔
NEW
176
            this->main_stream_ << language_extension_.declaration(container, sdfg_.type(container)) << ";" << std::endl;
×
177
        }
×
178
    }
179

180
    // Map external variables to internal variables
181
    for (auto& container : sdfg_.containers()) {
5✔
182
        if (!sdfg_.is_internal(container)) {
1✔
183
            continue;
1✔
184
        }
185

NEW
186
        std::string external_name = container.substr(0, container.length() - external_suffix.length());
×
187
        this->main_stream_ << language_extension_.declaration(container, sdfg_.type(container));
×
188
        this->main_stream_ << " = "
×
189
                           << "&" << external_name;
×
190
        this->main_stream_ << ";" << std::endl;
×
191
    }
×
192

193
    // Declare transient containers
194
    for (auto& container : sdfg_.containers()) {
5✔
195
        if (!sdfg_.is_transient(container)) {
1✔
196
            continue;
1✔
197
        }
198

NEW
199
        std::string val = this->language_extension_.declaration(container, sdfg_.type(container), false, true);
×
200
        if (!val.empty()) {
×
201
            this->main_stream_ << val;
×
202
            this->main_stream_ << ";" << std::endl;
×
203
        }
×
204
    }
×
205

206
    // Add instrumentation
207
    auto instrumentation = create_instrumentation(instrumentation_strategy_, sdfg_);
4✔
208

209
    auto dispatcher = create_dispatcher(language_extension_, sdfg_, sdfg_.root(), *instrumentation);
4✔
210
    dispatcher->dispatch(this->main_stream_, this->globals_stream_, this->library_snippet_factory_);
4✔
211
};
4✔
212

213
} // namespace codegen
214
} // 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