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

daisytuner / sdfglib / 15852980623

24 Jun 2025 02:16PM UTC coverage: 64.412% (+0.3%) from 64.145%
15852980623

push

github

web-flow
Merge pull request #72 from daisytuner/capture-instrumentation

Capture instrumentation

363 of 446 new or added lines in 19 files covered. (81.39%)

100 existing lines in 5 files now uncovered.

8389 of 13024 relevant lines covered (64.41%)

116.79 hits per line

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

60.14
/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
#include "sdfg/codegen/instrumentation/instrumentation.h"
5
#include "sdfg/codegen/instrumentation/outermost_loops_instrumentation.h"
6

7
namespace sdfg {
8
namespace codegen {
9

10
CPPCodeGenerator::CPPCodeGenerator(StructuredSDFG& sdfg,
12✔
11
                                   InstrumentationStrategy instrumentation_strategy,
12
                                   bool capture_args_results)
13
    : CodeGenerator(sdfg, instrumentation_strategy) {
6✔
14
    if (sdfg.type() != FunctionType_CPU) {
6✔
15
        throw std::runtime_error("CPPCodeGenerator can only be used for CPU SDFGs");
×
16
    }
17
    if (capture_args_results) {
6✔
NEW
18
        std::cerr << "CPPCodeGenerator does not support capturing args/results!";
×
NEW
19
    }
×
20
};
6✔
21

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

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

39
    return "extern \"C\" void " + sdfg_.name() + "(" + arglist.str() + ")";
1✔
40
};
1✔
41

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

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

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

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

65
    ofs_source << "#include \"" << header_path.filename().string() << "\"" << std::endl;
×
66
    ofs_source << this->globals_stream_.str() << std::endl;
×
67
    ofs_source << this->function_definition() << std::endl;
×
68
    ofs_source << "{" << std::endl;
×
69

70
    if (instrumentation_strategy_ != InstrumentationStrategy::NONE) {
×
71
        ofs_source << "__daisy_instrument_init();" << std::endl;
×
72
    }
×
73

74
    ofs_source << this->main_stream_.str() << std::endl;
×
75

76
    if (instrumentation_strategy_ != InstrumentationStrategy::NONE) {
×
77
        ofs_source << "__daisy_instrument_finalize();" << std::endl;
×
78
    }
×
79

80
    ofs_source << "}" << std::endl;
×
81
    ofs_source.close();
×
82

83
    auto library_content = this->library_stream_.str();
×
84
    if (library_content.empty()) {
×
85
        ofs_library.close();
×
86
        return true;
×
87
    }
88

89
    ofs_library << "#include \"" << header_path.filename().string() << "\"" << std::endl;
×
90
    ofs_library << std::endl;
×
91

92
    ofs_library << library_content << std::endl;
×
93
    ofs_library.close();
×
94

95
    return true;
×
96
};
×
97

98
void CPPCodeGenerator::dispatch_includes() {
5✔
99
    this->includes_stream_ << "#include <cmath>" << std::endl;
5✔
100
    if (this->instrumentation_strategy_ != InstrumentationStrategy::NONE)
5✔
101
        this->includes_stream_ << "#include <daisy_rtl.h>" << std::endl;
×
102
    this->includes_stream_ << "#define __daisy_min(a,b) ((a)<(b)?(a):(b))" << std::endl;
5✔
103
    this->includes_stream_ << "#define __daisy_max(a,b) ((a)>(b)?(a):(b))" << std::endl;
5✔
104
    this->includes_stream_ << "#define __daisy_fma(a,b,c) a * b + c" << std::endl;
5✔
105
};
5✔
106

107
void CPPCodeGenerator::dispatch_structures() {
5✔
108
    // Forward declarations
109
    for (auto& structure : sdfg_.structures()) {
9✔
110
        this->classes_stream_ << "struct " << structure << ";" << std::endl;
4✔
111
    }
112

113
    // Generate topology-sorted structure definitions
114
    typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS> structures_graph;
115
    typedef boost::graph_traits<structures_graph>::vertex_descriptor Vertex;
116
    std::vector<std::string> names;
5✔
117
    for (auto& structure : sdfg_.structures()) {
9✔
118
        names.push_back(structure);
4✔
119
    }
120
    structures_graph graph(names.size());
5✔
121

122
    for (auto& structure : names) {
9✔
123
        auto& definition = sdfg_.structure(structure);
4✔
124
        for (size_t i = 0; i < definition.num_members(); i++) {
8✔
125
            auto member_type = &definition.member_type(symbolic::integer(i));
4✔
126
            while (dynamic_cast<const types::Array*>(member_type)) {
4✔
127
                auto array_type = static_cast<const types::Array*>(member_type);
×
128
                member_type = &array_type->element_type();
×
129
            }
130

131
            if (auto member_structure = dynamic_cast<const sdfg::types::Structure*>(member_type)) {
4✔
132
                boost::add_edge(
1✔
133
                    std::find(names.begin(), names.end(), member_structure->name()) - names.begin(),
1✔
134
                    std::find(names.begin(), names.end(), structure) - names.begin(), graph);
1✔
135
            }
1✔
136
        }
4✔
137
    }
138

139
    std::list<Vertex> order;
5✔
140
    std::unordered_map<Vertex, boost::default_color_type> vertex_colors;
5✔
141
    boost::topological_sort(graph, std::back_inserter(order),
10✔
142
                            boost::color_map(boost::make_assoc_property_map(vertex_colors)));
5✔
143
    order.reverse();
5✔
144

145
    for (auto& structure_index : order) {
9✔
146
        std::string structure = names.at(structure_index);
4✔
147
        auto& definition = sdfg_.structure(structure);
4✔
148
        this->classes_stream_ << "struct ";
4✔
149
        if (definition.is_packed()) {
4✔
150
            this->classes_stream_ << "__attribute__((packed)) ";
1✔
151
        }
1✔
152
        this->classes_stream_ << structure << std::endl;
4✔
153
        this->classes_stream_ << "{\n";
4✔
154

155
        for (size_t i = 0; i < definition.num_members(); i++) {
8✔
156
            auto& member_type = definition.member_type(symbolic::integer(i));
4✔
157
            if (dynamic_cast<const sdfg::types::Structure*>(&member_type)) {
4✔
158
                this->classes_stream_ << "struct ";
1✔
159
            }
1✔
160
            this->classes_stream_ << language_extension_.declaration("member_" + std::to_string(i),
4✔
161
                                                                     member_type, false, true);
4✔
162
            this->classes_stream_ << ";" << std::endl;
4✔
163
        }
4✔
164

165
        this->classes_stream_ << "};" << std::endl;
4✔
166
    }
4✔
167
};
5✔
168

169
void CPPCodeGenerator::dispatch_globals() {
5✔
170
    for (auto& container : sdfg_.externals()) {
6✔
171
        this->globals_stream_ << "extern "
2✔
172
                              << language_extension_.declaration(container, sdfg_.type(container))
1✔
173
                              << ";" << std::endl;
1✔
174
    }
175
};
5✔
176

177
void CPPCodeGenerator::dispatch_schedule() {
5✔
178
    // Map external variables to internal variables
179
    for (auto& container : sdfg_.containers()) {
6✔
180
        if (!sdfg_.is_internal(container)) {
1✔
181
            continue;
1✔
182
        }
183
        std::string external_name =
184
            container.substr(0, container.length() - external_suffix.length());
×
185
        this->main_stream_ << language_extension_.declaration(container, sdfg_.type(container));
×
186
        this->main_stream_ << " = "
×
187
                           << language_extension_.type_cast("&" + external_name,
×
188
                                                            sdfg_.type(container));
×
189
        this->main_stream_ << ";" << std::endl;
×
190
    }
×
191

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

198
        std::string val =
199
            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_);
5✔
208

209
    auto dispatcher = create_dispatcher(language_extension_, sdfg_, sdfg_.root(), *instrumentation);
5✔
210
    dispatcher->dispatch(this->main_stream_, this->globals_stream_, this->library_stream_);
5✔
211
};
5✔
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

© 2026 Coveralls, Inc