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

daisytuner / sdfglib / 19418025893

16 Nov 2025 09:55PM UTC coverage: 62.083% (-0.009%) from 62.092%
19418025893

push

github

web-flow
Merge pull request #348 from daisytuner/fixes-assums

adds minor fixes for handling of dynamic symbols

8 of 11 new or added lines in 4 files covered. (72.73%)

12 existing lines in 2 files now uncovered.

11049 of 17797 relevant lines covered (62.08%)

112.43 hits per line

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

50.6
/src/codegen/dispatchers/map_dispatcher.cpp
1
#include "sdfg/codegen/dispatchers/map_dispatcher.h"
2

3
#include "sdfg/analysis/loop_analysis.h"
4
#include "sdfg/analysis/users.h"
5
#include "sdfg/codegen/dispatchers/node_dispatcher_registry.h"
6
#include "sdfg/codegen/dispatchers/sequence_dispatcher.h"
7
#include "sdfg/codegen/instrumentation/instrumentation_info.h"
8
#include "sdfg/structured_control_flow/map.h"
9

10
namespace sdfg {
11
namespace codegen {
12

13
MapDispatcher::MapDispatcher(
1✔
14
    LanguageExtension& language_extension,
15
    StructuredSDFG& sdfg,
16
    analysis::AnalysisManager& analysis_manager,
17
    structured_control_flow::Map& node,
18
    InstrumentationPlan& instrumentation_plan,
19
    ArgCapturePlan& arg_capture_plan
20
)
21
    : NodeDispatcher(language_extension, sdfg, analysis_manager, node, instrumentation_plan, arg_capture_plan),
1✔
22
      node_(node) {
1✔
23

24
      };
1✔
25

26
void MapDispatcher::dispatch_node(
1✔
27
    PrettyPrinter& main_stream, PrettyPrinter& globals_stream, CodeSnippetFactory& library_snippet_factory
28
) {
29
    auto dispatcher = MapDispatcherRegistry::instance().get_map_dispatcher(node_.schedule_type().value());
1✔
30
    if (dispatcher) {
1✔
31
        auto dispatcher_ptr =
32
            dispatcher(language_extension_, sdfg_, analysis_manager_, node_, instrumentation_plan_, arg_capture_plan_);
1✔
33
        dispatcher_ptr->dispatch_node(main_stream, globals_stream, library_snippet_factory);
1✔
34
    } else {
1✔
35
        throw std::runtime_error("Unsupported map schedule type: " + std::string(node_.schedule_type().value()));
×
36
    }
37
};
1✔
38

39
SequentialMapDispatcher::SequentialMapDispatcher(
1✔
40
    LanguageExtension& language_extension,
41
    StructuredSDFG& sdfg,
42
    analysis::AnalysisManager& analysis_manager,
43
    structured_control_flow::Map& node,
44
    InstrumentationPlan& instrumentation_plan,
45
    ArgCapturePlan& arg_capture_plan
46
)
47
    : NodeDispatcher(language_extension, sdfg, analysis_manager, node, instrumentation_plan, arg_capture_plan),
1✔
48
      node_(node) {
1✔
49

50
      };
1✔
51

52
void SequentialMapDispatcher::dispatch_node(
1✔
53
    PrettyPrinter& main_stream, PrettyPrinter& globals_stream, CodeSnippetFactory& library_snippet_factory
54
) {
55
    main_stream << "// Map" << std::endl;
1✔
56
    main_stream << "for";
1✔
57
    main_stream << "(";
1✔
58
    main_stream << node_.indvar()->get_name();
1✔
59
    main_stream << " = ";
1✔
60
    main_stream << language_extension_.expression(node_.init());
1✔
61
    main_stream << ";";
1✔
62
    main_stream << language_extension_.expression(node_.condition());
1✔
63
    main_stream << ";";
1✔
64
    main_stream << node_.indvar()->get_name();
1✔
65
    main_stream << " = ";
1✔
66
    main_stream << language_extension_.expression(node_.update());
1✔
67
    main_stream << ")" << std::endl;
1✔
68
    main_stream << "{" << std::endl;
1✔
69

70
    main_stream.setIndent(main_stream.indent() + 4);
1✔
71
    SequenceDispatcher
72
        dispatcher(language_extension_, sdfg_, analysis_manager_, node_.root(), instrumentation_plan_, arg_capture_plan_);
1✔
73
    dispatcher.dispatch(main_stream, globals_stream, library_snippet_factory);
1✔
74
    main_stream.setIndent(main_stream.indent() - 4);
1✔
75

76
    main_stream << "}" << std::endl;
1✔
77
};
1✔
78

79
CPUParallelMapDispatcher::CPUParallelMapDispatcher(
3✔
80
    LanguageExtension& language_extension,
81
    StructuredSDFG& sdfg,
82
    analysis::AnalysisManager& analysis_manager,
83
    structured_control_flow::Map& node,
84
    InstrumentationPlan& instrumentation_plan,
85
    ArgCapturePlan& arg_capture_plan
86
)
87
    : NodeDispatcher(language_extension, sdfg, analysis_manager, node, instrumentation_plan, arg_capture_plan),
3✔
88
      node_(node) {
3✔
89

90
      };
3✔
91

92
void CPUParallelMapDispatcher::dispatch_node(
3✔
93
    PrettyPrinter& main_stream, PrettyPrinter& globals_stream, CodeSnippetFactory& library_snippet_factory
94
) {
95
    // Mark written locals as private
96
    analysis::AnalysisManager analysis_manager(sdfg_);
3✔
97
    auto& users = analysis_manager.get<analysis::Users>();
3✔
98
    analysis::UsersView users_view(users, node_.root());
3✔
99

100
    std::vector<std::string> locals;
3✔
101
    for (auto& entry : users.locals(node_.root())) {
3✔
102
        if (users_view.writes(entry).size() > 0 || users_view.moves(entry).size() > 0) {
×
103
            locals.push_back(entry);
×
104
        }
×
105
    }
106

107
    // Generate code
108
    main_stream << "// Map" << std::endl;
3✔
109
    main_stream << "#pragma omp parallel for";
3✔
110

111
    main_stream << " schedule(";
3✔
112
    if (structured_control_flow::ScheduleType_CPU_Parallel::omp_schedule(node_.schedule_type()) ==
3✔
113
        structured_control_flow::OpenMPSchedule::Static) {
114
        main_stream << "static)";
1✔
115
    } else if (structured_control_flow::ScheduleType_CPU_Parallel::omp_schedule(node_.schedule_type()) ==
3✔
116
               structured_control_flow::OpenMPSchedule::Dynamic) {
117
        main_stream << "dynamic)";
2✔
118
    } else if (structured_control_flow::ScheduleType_CPU_Parallel::omp_schedule(node_.schedule_type()) ==
2✔
119
               structured_control_flow::OpenMPSchedule::Guided) {
120
        main_stream << "guided)";
×
121
    } else {
×
122
        throw std::runtime_error("Unsupported OpenMP schedule type");
×
123
    }
124

125
    if (!structured_control_flow::ScheduleType_CPU_Parallel::num_threads(node_.schedule_type()).is_null()) {
3✔
126
        main_stream << " num_threads(";
1✔
127
        main_stream
2✔
128
            << language_extension_
2✔
129
                   .expression(structured_control_flow::ScheduleType_CPU_Parallel::num_threads(node_.schedule_type()));
1✔
130
        main_stream << ")";
1✔
131
    }
1✔
132

133
    if (locals.size() > 0) {
3✔
134
        main_stream << " private(" << helpers::join(locals, ", ") << ")";
×
135
    }
×
136
    main_stream << std::endl;
3✔
137
    main_stream << "for";
3✔
138
    main_stream << "(";
3✔
139
    main_stream << node_.indvar()->get_name();
3✔
140
    main_stream << " = ";
3✔
141
    main_stream << language_extension_.expression(node_.init());
3✔
142
    main_stream << ";";
3✔
143
    main_stream << language_extension_.expression(node_.condition());
3✔
144
    main_stream << ";";
3✔
145
    main_stream << node_.indvar()->get_name();
3✔
146
    main_stream << " = ";
3✔
147
    main_stream << language_extension_.expression(node_.update());
3✔
148
    main_stream << ")" << std::endl;
3✔
149
    main_stream << "{" << std::endl;
3✔
150

151
    for (auto& local : locals) {
3✔
152
        auto& type = sdfg_.type(local);
×
153
        if (type.storage_type().allocation() == types::StorageType::AllocationType::Managed) {
×
154
            if (type.storage_type().is_cpu_stack()) {
×
155
                main_stream << local << " = ";
×
156
                main_stream << "alloca(" << language_extension_.expression(type.storage_type().allocation_size())
×
157
                            << ")";
×
158
                main_stream << ";" << std::endl;
×
159
            } else if (type.storage_type().is_cpu_heap()) {
×
160
                main_stream << local << " = ";
×
161
                main_stream << language_extension_.external_prefix() << "malloc("
×
162
                            << language_extension_.expression(type.storage_type().allocation_size()) << ")";
×
163
                main_stream << ";" << std::endl;
×
164
            }
×
165
        }
×
166
    }
167

168
    main_stream.setIndent(main_stream.indent() + 4);
3✔
169
    SequenceDispatcher
170
        dispatcher(language_extension_, sdfg_, analysis_manager_, node_.root(), instrumentation_plan_, arg_capture_plan_);
3✔
171
    dispatcher.dispatch(main_stream, globals_stream, library_snippet_factory);
3✔
172
    main_stream.setIndent(main_stream.indent() - 4);
3✔
173

174
    for (auto& local : locals) {
3✔
175
        auto& type = sdfg_.type(local);
×
176
        if (type.storage_type().deallocation() == types::StorageType::AllocationType::Managed) {
×
177
            if (type.storage_type().is_cpu_heap()) {
×
178
                main_stream << language_extension_.external_prefix() << "free(" << local << ");" << std::endl;
×
179
            }
×
180
        }
×
181
    }
182

183
    main_stream << "}" << std::endl;
3✔
184
};
3✔
185

186
InstrumentationInfo MapDispatcher::instrumentation_info() const {
×
187
    auto dispatcher = MapDispatcherRegistry::instance().get_map_dispatcher(node_.schedule_type().value());
×
188
    if (dispatcher) {
×
189
        auto dispatcher_ptr =
190
            dispatcher(language_extension_, sdfg_, analysis_manager_, node_, instrumentation_plan_, arg_capture_plan_);
×
191
        auto map_dispatcher_ptr = static_cast<MapDispatcher*>(dispatcher_ptr.get());
×
192
        return map_dispatcher_ptr->instrumentation_info();
×
193
    } else {
×
194
        throw std::runtime_error("Unsupported map schedule type: " + std::string(node_.schedule_type().value()));
×
195
    }
196
};
×
197

198
InstrumentationInfo SequentialMapDispatcher::instrumentation_info() const {
×
199
    size_t loopnest_index = -1;
×
200
    auto& loop_tree_analysis = analysis_manager_.get<analysis::LoopAnalysis>();
×
201

202
    auto outermost_loops = loop_tree_analysis.outermost_loops();
×
203
    for (size_t i = 0; i < outermost_loops.size(); i++) {
×
204
        if (outermost_loops[i] == &node_) {
×
205
            loopnest_index = i;
×
206
            break;
×
207
        }
208
    }
×
209

210
    // Perform FlopAnalysis
211
    std::unordered_map<std::string, std::string> metrics;
×
212
    auto& flop_analysis = analysis_manager_.get<analysis::FlopAnalysis>();
×
213
    if (flop_analysis.contains(&node_)) {
×
214
        auto flop = flop_analysis.get(&node_);
×
215
        if (!flop.is_null()) {
×
NEW
216
            if (!symbolic::has_dynamic_sizeof(flop)) {
×
217
                std::string flop_str = language_extension_.expression(flop);
×
218
                metrics.insert({"flop", flop_str});
×
219
            }
×
220
        }
×
221
    }
×
222

223
    return InstrumentationInfo(ElementType_Map, TargetType_SEQUENTIAL, loopnest_index, node_.element_id(), metrics);
×
224
};
×
225

226
InstrumentationInfo CPUParallelMapDispatcher::instrumentation_info() const {
×
227
    size_t loopnest_index = -1;
×
228
    auto& loop_tree_analysis = analysis_manager_.get<analysis::LoopAnalysis>();
×
229

230
    auto outermost_loops = loop_tree_analysis.outermost_loops();
×
231
    for (size_t i = 0; i < outermost_loops.size(); i++) {
×
232
        if (outermost_loops[i] == &node_) {
×
233
            loopnest_index = i;
×
234
            break;
×
235
        }
236
    }
×
237

238
    // Perform FlopAnalysis
239
    std::unordered_map<std::string, std::string> metrics;
×
240
    auto& flop_analysis = analysis_manager_.get<analysis::FlopAnalysis>();
×
241
    if (flop_analysis.contains(&node_)) {
×
242
        auto flop = flop_analysis.get(&node_);
×
243
        if (!flop.is_null()) {
×
NEW
244
            if (!symbolic::has_dynamic_sizeof(flop)) {
×
245
                std::string flop_str = language_extension_.expression(flop);
×
246
                metrics.insert({"flop", flop_str});
×
247
            }
×
248
        }
×
249
    }
×
250

251
    return InstrumentationInfo(ElementType_Map, TargetType_CPU_PARALLEL, loopnest_index, node_.element_id(), metrics);
×
252
};
×
253

254
} // namespace codegen
255
} // 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