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

daisytuner / sdfglib / 15075964231

16 May 2025 07:28PM UTC coverage: 63.623% (+0.1%) from 63.496%
15075964231

push

github

web-flow
Merge pull request #16 from daisytuner/segfaults

Enable Wall, Werror and Wpedantic

98 of 120 new or added lines in 39 files covered. (81.67%)

4 existing lines in 4 files now uncovered.

8633 of 13569 relevant lines covered (63.62%)

483.97 hits per line

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

58.13
/src/codegen/code_generators/c_code_generator.cpp
1
#include "sdfg/codegen/code_generators/c_code_generator.h"
2

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

5
namespace sdfg {
6
namespace codegen {
7

8
CCodeGenerator::CCodeGenerator(ConditionalSchedule& schedule, bool instrumented)
10✔
9
    : CodeGenerator(schedule, instrumented){
5✔
10

11
      };
5✔
12

13
bool CCodeGenerator::generate() {
4✔
14
    this->dispatch_includes();
4✔
15
    this->dispatch_structures();
4✔
16
    this->dispatch_globals();
4✔
17
    this->dispatch_schedule();
4✔
18
    return true;
4✔
19
};
20

21
std::string CCodeGenerator::function_definition() {
1✔
22
    // Define SDFG as a function
23
    auto& function = this->schedule_.schedule(0).sdfg();
1✔
24

25
    /********** Arglist **********/
26
    std::vector<std::string> args;
1✔
27
    for (auto& container : function.arguments()) {
1✔
28
        args.push_back(language_extension_.declaration(container, function.type(container)));
×
29
    }
30
    std::stringstream arglist;
1✔
31
    arglist << sdfg::helpers::join(args, ", ");
1✔
32

33
    return "extern void " + function.name() + "(" + arglist.str() + ")";
1✔
34
};
1✔
35

36
bool CCodeGenerator::as_source(const std::filesystem::path& header_path,
×
37
                               const std::filesystem::path& source_path,
38
                               const std::filesystem::path& library_path) {
39
    std::ofstream ofs_header(header_path, std::ofstream::out);
×
40
    if (!ofs_header.is_open()) {
×
41
        return false;
×
42
    }
43

44
    std::ofstream ofs_source(source_path, std::ofstream::out);
×
45
    if (!ofs_source.is_open()) {
×
46
        return false;
×
47
    }
48

49
    std::ofstream ofs_library(library_path, std::ofstream::out);
×
50
    if (!ofs_library.is_open()) {
×
51
        return false;
×
52
    }
53

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

59
    ofs_source << "#include \"" << header_path.filename().string() << "\"" << std::endl;
×
60
    ofs_source << this->globals_stream_.str() << std::endl;
×
61
    ofs_source << this->function_definition() << std::endl;
×
62
    ofs_source << "{" << std::endl;
×
63

64
    if (instrumented_) {
×
65
        ofs_source << "__daisy_instrument_init();" << std::endl;
×
66
    }
×
67

68
    ofs_source << this->main_stream_.str() << std::endl;
×
69

70
    if (instrumented_) {
×
71
        ofs_source << "__daisy_instrument_finalize();" << std::endl;
×
72
    }
×
73

74
    ofs_source << "}" << std::endl;
×
75
    ofs_source.close();
×
76

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

83
    ofs_library << "#include \"" << header_path.filename().string() << "\"" << std::endl;
×
84
    ofs_library << std::endl;
×
85

86
    ofs_library << "#undef HWY_TARGET_INCLUDE" << std::endl;
×
87
    ofs_library << "#define HWY_TARGET_INCLUDE " << library_path.filename() << std::endl;
×
88
    ofs_library << "#include <hwy/foreach_target.h>" << std::endl;
×
89
    ofs_library << "#include <hwy/highway.h>" << std::endl;
×
90
    ofs_library << "#include <hwy/contrib/math/math-inl.h>" << std::endl;
×
91
    ofs_library << std::endl;
×
92

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

96
    return true;
×
97
};
×
98

99
void CCodeGenerator::dispatch_includes() {
4✔
100
    this->includes_stream_ << "#include <math.h>" << std::endl;
4✔
101
    this->includes_stream_ << "#include <stdbool.h>" << std::endl;
4✔
102
    this->includes_stream_ << "#include <stdlib.h>" << std::endl;
4✔
103
    if (instrumented_) this->includes_stream_ << "#include <daisy_rtl.h>" << std::endl;
4✔
104

105
    this->includes_stream_ << "#define __daisy_min(a,b) ((a)<(b)?(a):(b))" << std::endl;
4✔
106
    this->includes_stream_ << "#define __daisy_max(a,b) ((a)>(b)?(a):(b))" << std::endl;
4✔
107
    this->includes_stream_ << "#define __daisy_fma(a,b,c) a * b + c" << std::endl;
4✔
108
};
4✔
109

110
void CCodeGenerator::dispatch_structures() {
4✔
111
    auto& function = this->schedule_.schedule(0).sdfg();
4✔
112

113
    // Forward declarations
114
    for (auto& structure : function.structures()) {
7✔
115
        this->classes_stream_ << "typedef struct " << structure << " " << structure << ";"
3✔
116
                              << std::endl;
3✔
117
    }
118

119
    // Generate topology-sorted structure definitions
120
    typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS> structures_graph;
121
    typedef boost::graph_traits<structures_graph>::vertex_descriptor Vertex;
122
    std::vector<std::string> names;
4✔
123
    for (auto& structure : function.structures()) {
7✔
124
        names.push_back(structure);
3✔
125
    }
126
    structures_graph graph(names.size());
4✔
127

128
    for (auto& structure : names) {
7✔
129
        auto& definition = function.structure(structure);
3✔
130
        for (size_t i = 0; i < definition.num_members(); i++) {
6✔
131
            auto member_type = &definition.member_type(symbolic::integer(i));
3✔
132
            while (dynamic_cast<const types::Array*>(member_type)) {
3✔
133
                auto array_type = static_cast<const types::Array*>(member_type);
×
134
                member_type = &array_type->element_type();
×
135
            }
136

137
            if (auto member_structure = dynamic_cast<const sdfg::types::Structure*>(member_type)) {
3✔
138
                boost::add_edge(
1✔
139
                    std::find(names.begin(), names.end(), member_structure->name()) - names.begin(),
1✔
140
                    std::find(names.begin(), names.end(), structure) - names.begin(), graph);
1✔
141
            }
1✔
142
        }
3✔
143
    }
144

145
    std::list<Vertex> order;
4✔
146
    std::unordered_map<Vertex, boost::default_color_type> vertex_colors;
4✔
147
    boost::topological_sort(graph, std::back_inserter(order),
8✔
148
                            boost::color_map(boost::make_assoc_property_map(vertex_colors)));
4✔
149
    order.reverse();
4✔
150

151
    for (auto& structure_index : order) {
7✔
152
        std::string structure = names.at(structure_index);
3✔
153
        auto& definition = function.structure(structure);
3✔
154
        this->classes_stream_ << "typedef struct ";
3✔
155
        if (definition.is_packed()) {
3✔
156
            this->classes_stream_ << "__attribute__((packed)) ";
×
157
        }
×
158
        this->classes_stream_ << structure << std::endl;
3✔
159
        this->classes_stream_ << "{\n";
3✔
160

161
        for (size_t i = 0; i < definition.num_members(); i++) {
6✔
162
            auto& member_type = definition.member_type(symbolic::integer(i));
3✔
163
            if (auto pointer_type = dynamic_cast<const sdfg::types::Pointer*>(&member_type)) {
3✔
NEW
164
                if (dynamic_cast<const sdfg::types::Structure*>(
×
165
                        &pointer_type->pointee_type())) {
×
166
                    this->classes_stream_ << "struct ";
×
167
                }
×
168
            }
×
169
            this->classes_stream_ << language_extension_.declaration("member_" + std::to_string(i),
3✔
170
                                                                     member_type);
3✔
171
            this->classes_stream_ << ";" << std::endl;
3✔
172
        }
3✔
173

174
        this->classes_stream_ << "} " << structure << ";" << std::endl;
3✔
175
    }
3✔
176
};
4✔
177

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

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

203
    for (size_t i = 0; i < schedule_.size(); i++) {
8✔
204
        if (i == 0) {
4✔
205
            this->main_stream_ << "if (" << language_extension_.expression(schedule_.condition(i))
8✔
206
                               << ") {\n";
4✔
207

208
            auto& function_i = schedule_.schedule(i).builder().subject();
4✔
209
            auto dispatcher = create_dispatcher(language_extension_, schedule_.schedule(i),
8✔
210
                                                function_i.root(), this->instrumented_);
4✔
211
            dispatcher->dispatch(this->main_stream_, this->globals_stream_, this->library_stream_);
4✔
212

213
            this->main_stream_ << "}\n";
4✔
214
        } else {
4✔
215
            this->main_stream_ << "else if ("
×
216
                               << language_extension_.expression(schedule_.condition(i)) << ") {\n";
×
217

218
            auto& function_i = schedule_.schedule(i).builder().subject();
×
219
            auto dispatcher = create_dispatcher(language_extension_, schedule_.schedule(i),
×
220
                                                function_i.root(), this->instrumented_);
×
221
            dispatcher->dispatch(this->main_stream_, this->globals_stream_, this->library_stream_);
×
222

223
            this->main_stream_ << "}\n";
×
224
        }
×
225
    }
4✔
226
};
4✔
227

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