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

daisytuner / sdfglib / 18896739436

28 Oct 2025 03:45PM UTC coverage: 62.202% (-0.1%) from 62.303%
18896739436

push

github

web-flow
Merge pull request #311 from daisytuner/storage-types

Storage types improvements

15 of 48 new or added lines in 3 files covered. (31.25%)

11 existing lines in 2 files now uncovered.

10119 of 16268 relevant lines covered (62.2%)

101.66 hits per line

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

55.9
/src/codegen/code_generators/cpp_code_generator.cpp
1
#include "sdfg/codegen/code_generators/cpp_code_generator.h"
2

3
#include "sdfg/codegen/dispatchers/node_dispatcher_registry.h"
4

5
namespace sdfg {
6
namespace codegen {
7

8
std::string CPPCodeGenerator::function_definition() {
1✔
9
    /********** Arglist **********/
10
    std::vector<std::string> args;
1✔
11
    if (this->sdfg_.name() == "main" && this->sdfg_.arguments().size() != 0) {
1✔
12
        auto& arg1 = this->sdfg_.arguments().at(0);
×
13
        sdfg::types::Scalar arg1_type(sdfg::types::PrimitiveType::Int32);
×
14

15
        auto& arg2 = this->sdfg_.arguments().at(1);
×
16
        sdfg::types::Scalar arg2_base_type(sdfg::types::PrimitiveType::UInt8);
×
17
        sdfg::types::Pointer arg2_ptr_type(arg2_base_type);
×
18
        sdfg::types::Pointer arg2_ptr_ptr_type(static_cast<const sdfg::types::IType&>(arg2_ptr_type));
×
19

20
        args.push_back(language_extension_.declaration(arg1, arg1_type));
×
21
        args.push_back(language_extension_.declaration(arg2, arg2_ptr_ptr_type));
×
22
    } else {
×
23
        for (auto& container : this->sdfg_.arguments()) {
1✔
24
            args.push_back(language_extension_.declaration(container, this->sdfg_.type(container)));
×
25
        }
26
    }
27

28
    std::stringstream arglist;
1✔
29
    arglist << sdfg::helpers::join(args, ", ");
1✔
30
    std::string arglist_str = arglist.str();
1✔
31
    if (arglist_str.empty()) {
1✔
32
        arglist_str = "void";
1✔
33
    }
1✔
34

35
    return "extern \"C\" " + this->language_extension_.declaration("", sdfg_.return_type()) + sdfg_.name() + "(" +
2✔
36
           arglist_str + ")";
1✔
37
};
1✔
38

39
void CPPCodeGenerator::emit_capture_context_init(std::ostream& ofs_source) const {
×
40
    std::string name = sdfg_.name();
×
41
    std::string arg_capture_path = sdfg_.metadata().at("arg_capture_path");
×
42

43
    ofs_source << "static __daisy_capture_t* __capture_ctx;" << std::endl;
×
44
    ofs_source << "static void __attribute__((constructor(1000))) __capture_ctx_init(void) {" << std::endl;
×
45
    ofs_source << "\t__capture_ctx = __daisy_capture_init(\"" << name << "\", \"" << arg_capture_path << "\");"
×
46
               << std::endl;
×
47
    ofs_source << "}" << std::endl;
×
48
    ofs_source << std::endl;
×
49
}
×
50

51
void CPPCodeGenerator::dispatch_includes() {
4✔
52
    this->includes_stream_ << "#include <alloca.h>" << std::endl;
4✔
53
    this->includes_stream_ << "#include <cmath>" << std::endl;
4✔
54
    this->includes_stream_ << "#include <cstdio>" << std::endl;
4✔
55
    this->includes_stream_ << "#include <cstdlib>" << std::endl;
4✔
56
    this->includes_stream_ << "#include <cstring>" << std::endl;
4✔
57
    this->includes_stream_ << "#include <cblas.h>" << std::endl;
4✔
58
    this->includes_stream_ << "#include <daisy_rtl/daisy_rtl.h>" << std::endl;
4✔
59
};
4✔
60

61
void CPPCodeGenerator::dispatch_structures() {
4✔
62
    // Forward declarations
63
    for (auto& structure : sdfg_.structures()) {
8✔
64
        this->classes_stream_ << "struct " << structure << ";" << std::endl;
4✔
65
    }
66

67
    // Generate topology-sorted structure definitions
68
    typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS> structures_graph;
69
    typedef boost::graph_traits<structures_graph>::vertex_descriptor Vertex;
70
    std::vector<std::string> names;
4✔
71
    for (auto& structure : sdfg_.structures()) {
8✔
72
        names.push_back(structure);
4✔
73
    }
74
    structures_graph graph(names.size());
4✔
75

76
    for (auto& structure : names) {
8✔
77
        auto& definition = sdfg_.structure(structure);
4✔
78
        for (size_t i = 0; i < definition.num_members(); i++) {
8✔
79
            auto member_type = &definition.member_type(symbolic::integer(i));
4✔
80
            while (dynamic_cast<const types::Array*>(member_type)) {
4✔
81
                auto array_type = static_cast<const types::Array*>(member_type);
×
82
                member_type = &array_type->element_type();
×
83
            }
84

85
            if (auto member_structure = dynamic_cast<const sdfg::types::Structure*>(member_type)) {
4✔
86
                boost::add_edge(
1✔
87
                    std::find(names.begin(), names.end(), member_structure->name()) - names.begin(),
1✔
88
                    std::find(names.begin(), names.end(), structure) - names.begin(),
1✔
89
                    graph
90
                );
91
            }
1✔
92
        }
4✔
93
    }
94

95
    std::list<Vertex> order;
4✔
96
    std::unordered_map<Vertex, boost::default_color_type> vertex_colors;
4✔
97
    boost::topological_sort(
4✔
98
        graph, std::back_inserter(order), boost::color_map(boost::make_assoc_property_map(vertex_colors))
4✔
99
    );
100
    order.reverse();
4✔
101

102
    for (auto& structure_index : order) {
8✔
103
        std::string structure = names.at(structure_index);
4✔
104
        auto& definition = sdfg_.structure(structure);
4✔
105
        this->classes_stream_ << "struct ";
4✔
106
        if (definition.is_packed()) {
4✔
107
            this->classes_stream_ << "__attribute__((packed)) ";
1✔
108
        }
1✔
109
        this->classes_stream_ << structure << std::endl;
4✔
110
        this->classes_stream_ << "{\n";
4✔
111

112
        for (size_t i = 0; i < definition.num_members(); i++) {
8✔
113
            auto& member_type = definition.member_type(symbolic::integer(i));
4✔
114
            if (dynamic_cast<const sdfg::types::Structure*>(&member_type)) {
4✔
115
                this->classes_stream_ << "struct ";
1✔
116
            }
1✔
117
            this->classes_stream_
8✔
118
                << language_extension_.declaration("member_" + std::to_string(i), member_type, false, true);
4✔
119
            this->classes_stream_ << ";" << std::endl;
4✔
120
        }
4✔
121

122
        this->classes_stream_ << "};" << std::endl;
4✔
123
    }
4✔
124
};
4✔
125

126
void CPPCodeGenerator::dispatch_globals() {
4✔
127
    // Declare globals
128
    for (auto& container : sdfg_.externals()) {
5✔
129
        // Function declarations
130
        if (dynamic_cast<const types::Function*>(&sdfg_.type(container))) {
1✔
131
            this->globals_stream_ << "extern \"C\" ";
×
132
            this->globals_stream_
×
133
                << language_extension_.declaration(this->externals_prefix_ + container, sdfg_.type(container)) << ";"
×
134
                << std::endl;
×
135
            continue;
×
136
        }
137

138
        // Other types must be pointers
139
        auto& type = dynamic_cast<const types::Pointer&>(sdfg_.type(container));
1✔
140
        assert(type.has_pointee_type() && "Externals must have a pointee type");
2✔
141
        auto& base_type = type.pointee_type();
1✔
142

143
        if (sdfg_.linkage_type(container) == LinkageType_External) {
1✔
144
            this->globals_stream_ << "extern "
2✔
145
                                  << language_extension_.declaration(this->externals_prefix_ + container, base_type)
1✔
146
                                  << ";" << std::endl;
1✔
147
        } else {
1✔
148
            this->globals_stream_ << "static "
×
149
                                  << language_extension_.declaration(this->externals_prefix_ + container, base_type);
×
150
            if (!type.initializer().empty()) {
×
151
                this->globals_stream_ << " = " << type.initializer();
×
152
            }
×
153
            this->globals_stream_ << ";" << std::endl;
×
154
        }
155
    }
156
};
4✔
157

158
void CPPCodeGenerator::dispatch_schedule() {
4✔
159
    // Allocate variables
160
    for (auto& container : sdfg_.containers()) {
5✔
161
        if (sdfg_.is_external(container)) {
1✔
162
            continue;
1✔
163
        }
164
        auto& type = sdfg_.type(container);
×
165

166
        // Declare transient
167
        if (sdfg_.is_transient(container)) {
×
168
            std::string val = this->language_extension_.declaration(container, sdfg_.type(container), false, true);
×
169
            if (!val.empty()) {
×
170
                this->main_stream_ << val;
×
171
                this->main_stream_ << ";" << std::endl;
×
172
            }
×
173
        }
×
174

175
        // Allocate if needed
176
        if (type.storage_type().allocation() == types::StorageType::AllocationType::Managed) {
×
177
            assert(
×
178
                !type.storage_type().allocation_size().is_null() &&
179
                "Managed allocations must have a valid allocation size"
180
            );
181
            if (type.storage_type().is_cpu_stack()) {
×
182
                this->main_stream_ << container << " = ";
×
183
                this->main_stream_
×
184
                    << "alloca(" << this->language_extension_.expression(type.storage_type().allocation_size()) << ")";
×
185
                this->main_stream_ << ";" << std::endl;
×
186
            } else if (type.storage_type().is_cpu_heap()) {
×
187
                this->main_stream_ << container << " = ";
×
188
                this->main_stream_ << this->externals_prefix_ << "malloc("
×
189
                                   << this->language_extension_.expression(type.storage_type().allocation_size())
×
190
                                   << ")";
×
191
                this->main_stream_ << ";" << std::endl;
×
NEW
192
            } else if (type.storage_type().is_nv_generic()) {
×
NEW
193
                this->main_stream_ << "cudaSetDevice(0);" << std::endl;
×
NEW
194
                this->main_stream_ << "cudaMalloc(&" << container << ", "
×
NEW
195
                                   << this->language_extension_.expression(type.storage_type().allocation_size())
×
NEW
196
                                   << ");" << std::endl;
×
197
            }
×
198
        }
×
199
    }
200

201
    auto dispatcher =
202
        create_dispatcher(language_extension_, sdfg_, analysis_manager_, sdfg_.root(), instrumentation_plan_);
4✔
203
    dispatcher->dispatch(this->main_stream_, this->globals_stream_, this->library_snippet_factory_);
4✔
204

205
    if (sdfg_.root().size() == 0 ||
4✔
NEW
206
        !dynamic_cast<const structured_control_flow::Return*>(&(sdfg_.root().at(sdfg_.root().size() - 1)).first)) {
×
207
        // Free heap allocations
208
        for (auto& container : sdfg_.containers()) {
5✔
209
            if (sdfg_.is_external(container)) {
1✔
210
                continue;
1✔
211
            }
NEW
212
            auto& type = sdfg_.type(container);
×
213

214
            // Free if needed
NEW
215
            if (type.storage_type().deallocation() == types::StorageType::AllocationType::Managed) {
×
NEW
216
                if (type.storage_type().is_cpu_heap()) {
×
NEW
217
                    this->main_stream_ << this->externals_prefix_ << "free(" << container << ");" << std::endl;
×
NEW
218
                } else if (type.storage_type().is_nv_generic()) {
×
NEW
219
                    this->main_stream_ << "cudaSetDevice(0);" << std::endl;
×
NEW
220
                    this->main_stream_ << "cudaFree(" << container << ");" << std::endl;
×
NEW
221
                }
×
222
            }
×
223
        }
224
    }
4✔
225
};
4✔
226

227
} // namespace codegen
228
} // 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