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

daisytuner / sdfglib / 15142284085

20 May 2025 03:58PM UTC coverage: 60.528% (-0.02%) from 60.543%
15142284085

push

github

web-flow
Merge pull request #23 from daisytuner/loops

LoopTrees and Instrumentation Strategies

80 of 182 new or added lines in 17 files covered. (43.96%)

11 existing lines in 6 files now uncovered.

7928 of 13098 relevant lines covered (60.53%)

104.16 hits per line

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

62.75
/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_factory.h"
4

5
#include "sdfg/codegen/instrumentation/instrumentation.h"
6
#include "sdfg/codegen/instrumentation/outermost_loops_instrumentation.h"
7

8
namespace sdfg {
9
namespace codegen {
10

11
CPPCodeGenerator::CPPCodeGenerator(ConditionalSchedule& schedule)
12✔
12
    : CodeGenerator(schedule, InstrumentationStrategy::NONE){
6✔
13

14
      };
6✔
15

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

UNCOV
19
      };
×
20

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

29
std::string CPPCodeGenerator::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\" void " + function.name() + "(" + arglist.str() + ")";
1✔
42
};
1✔
43

44
bool CPPCodeGenerator::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

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

76
    ofs_source << this->main_stream_.str() << std::endl;
×
77
    
NEW
78
    if (instrumentation_strategy_ != InstrumentationStrategy::NONE) {
×
79
        ofs_source << "__daisy_instrument_finalize();" << std::endl;
×
80
    }
×
81
    
82
    ofs_source << "}" << std::endl;
×
83
    ofs_source.close();
×
84

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

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

94
    ofs_library << "#undef HWY_TARGET_INCLUDE" << std::endl;
×
95
    ofs_library << "#define HWY_TARGET_INCLUDE " << library_path.filename() << std::endl;
×
96
    ofs_library << "#include <hwy/foreach_target.h>" << std::endl;
×
97
    ofs_library << "#include <hwy/highway.h>" << std::endl;
×
98
    ofs_library << "#include <hwy/contrib/math/math-inl.h>" << std::endl;
×
99
    ofs_library << std::endl;
×
100

101
    ofs_library << library_content << std::endl;
×
102
    ofs_library.close();
×
103

104
    return true;
×
105
};
×
106

107
void CPPCodeGenerator::dispatch_includes() {
5✔
108
    this->includes_stream_ << "#include <cmath>" << std::endl;
5✔
109
    if (this->instrumentation_strategy_ != InstrumentationStrategy::NONE) this->includes_stream_ << "#include <daisy_rtl.h>" << std::endl;
5✔
110
    this->includes_stream_ << "#define __daisy_min(a,b) ((a)<(b)?(a):(b))" << std::endl;
5✔
111
    this->includes_stream_ << "#define __daisy_max(a,b) ((a)>(b)?(a):(b))" << std::endl;
5✔
112
    this->includes_stream_ << "#define __daisy_fma(a,b,c) a * b + c" << std::endl;
5✔
113
};
5✔
114

115
void CPPCodeGenerator::dispatch_structures() {
5✔
116
    auto& function = this->schedule_.schedule(0).sdfg();
5✔
117

118
    // Forward declarations
119
    for (auto& structure : function.structures()) {
9✔
120
        this->classes_stream_ << "struct " << structure << ";" << std::endl;
4✔
121
    }
122

123
    // Generate topology-sorted structure definitions
124
    typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS> structures_graph;
125
    typedef boost::graph_traits<structures_graph>::vertex_descriptor Vertex;
126
    std::vector<std::string> names;
5✔
127
    for (auto& structure : function.structures()) {
9✔
128
        names.push_back(structure);
4✔
129
    }
130
    structures_graph graph(names.size());
5✔
131

132
    for (auto& structure : names) {
9✔
133
        auto& definition = function.structure(structure);
4✔
134
        for (size_t i = 0; i < definition.num_members(); i++) {
8✔
135
            auto member_type = &definition.member_type(symbolic::integer(i));
4✔
136
            while (dynamic_cast<const types::Array*>(member_type)) {
4✔
137
                auto array_type = static_cast<const types::Array*>(member_type);
×
138
                member_type = &array_type->element_type();
×
139
            }
140

141
            if (auto member_structure = dynamic_cast<const sdfg::types::Structure*>(member_type)) {
4✔
142
                boost::add_edge(
1✔
143
                    std::find(names.begin(), names.end(), member_structure->name()) - names.begin(),
1✔
144
                    std::find(names.begin(), names.end(), structure) - names.begin(), graph);
1✔
145
            }
1✔
146
        }
4✔
147
    }
148

149
    std::list<Vertex> order;
5✔
150
    std::unordered_map<Vertex, boost::default_color_type> vertex_colors;
5✔
151
    boost::topological_sort(graph, std::back_inserter(order),
10✔
152
                            boost::color_map(boost::make_assoc_property_map(vertex_colors)));
5✔
153
    order.reverse();
5✔
154

155
    for (auto& structure_index : order) {
9✔
156
        std::string structure = names.at(structure_index);
4✔
157
        auto& definition = function.structure(structure);
4✔
158
        this->classes_stream_ << "struct ";
4✔
159
        if (definition.is_packed()) {
4✔
160
            this->classes_stream_ << "__attribute__((packed)) ";
1✔
161
        }
1✔
162
        this->classes_stream_ << structure << std::endl;
4✔
163
        this->classes_stream_ << "{\n";
4✔
164

165
        for (size_t i = 0; i < definition.num_members(); i++) {
8✔
166
            auto& member_type = definition.member_type(symbolic::integer(i));
4✔
167
            if (dynamic_cast<const sdfg::types::Structure*>(&member_type)) {
4✔
168
                this->classes_stream_ << "struct ";
1✔
169
            }
1✔
170
            this->classes_stream_ << language_extension_.declaration("member_" + std::to_string(i),
4✔
171
                                                                     member_type);
4✔
172
            this->classes_stream_ << ";" << std::endl;
4✔
173
        }
4✔
174

175
        this->classes_stream_ << "};" << std::endl;
4✔
176
    }
4✔
177
};
5✔
178

179
void CPPCodeGenerator::dispatch_globals() {
5✔
180
    auto& function = this->schedule_.schedule(0).sdfg();
5✔
181
    for (auto& container : function.externals()) {
6✔
182
        this->globals_stream_ << "extern "
2✔
183
                              << language_extension_.declaration(container,
2✔
184
                                                                 function.type(container))
1✔
185
                              << ";" << std::endl;
1✔
186
    }
187
};
5✔
188

189
void CPPCodeGenerator::dispatch_schedule() {
5✔
190
    // Map external variables to internal variables
191
    auto& function = this->schedule_.schedule(0).sdfg();
5✔
192
    for (auto& container : function.containers()) {
6✔
193
        if (!function.is_internal(container)) {
1✔
194
            continue;
1✔
195
        }
196
        std::string external_name =
197
            container.substr(0, container.length() - external_suffix.length());
×
198
        this->main_stream_ << language_extension_.declaration(container, function.type(container));
×
199
        this->main_stream_ << " = "
×
200
                           << "&" << external_name;
×
201
        this->main_stream_ << ";" << std::endl;
×
202
    }
×
203

204
    for (size_t i = 0; i < schedule_.size(); i++) {
10✔
205
        auto& schedule = schedule_.schedule(i);
5✔
206
        auto condition = schedule_.condition(i);
5✔
207
        
208
        // Add instrumentation
209
        auto instrumentation = create_instrumentation(instrumentation_strategy_, schedule);
5✔
210

211
        if (i > 0) {
5✔
NEW
212
            this->main_stream_ << "else ";
×
NEW
213
        }
×
214

215
        this->main_stream_ << "if (" << language_extension_.expression(condition)
10✔
216
                               << ") {\n";
5✔
217

218
        auto& function_i = schedule.builder().subject();
5✔
219
        auto dispatcher = create_dispatcher(language_extension_, schedule,
5✔
220
                                            function_i.root(), *instrumentation);
5✔
221
        dispatcher->dispatch(this->main_stream_, this->globals_stream_, this->library_stream_);
5✔
222

223
        this->main_stream_ << "}\n";
5✔
224
    }
5✔
225
};
5✔
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