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

daisytuner / sdfglib / 20498791379

24 Dec 2025 12:27PM UTC coverage: 39.109% (+0.05%) from 39.061%
20498791379

push

github

web-flow
Merge pull request #406 from daisytuner/loop-info-inst

move loopnest index into loop info

13537 of 44946 branches covered (30.12%)

Branch coverage included in aggregate %.

15 of 46 new or added lines in 9 files covered. (32.61%)

1 existing line in 1 file now uncovered.

11669 of 19504 relevant lines covered (59.83%)

84.09 hits per line

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

33.33
/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
SchedTypeMapDispatcher::SchedTypeMapDispatcher(
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 SchedTypeMapDispatcher::
27
    dispatch(PrettyPrinter& main_stream, PrettyPrinter& globals_stream, CodeSnippetFactory& library_snippet_factory) {
1✔
28
    auto dispatcher = MapDispatcherRegistry::instance().get_map_dispatcher(node_.schedule_type().value());
1!
29
    if (dispatcher) {
1!
30
        auto dispatcher_ptr =
31
            dispatcher(language_extension_, sdfg_, analysis_manager_, node_, instrumentation_plan_, arg_capture_plan_);
1!
32
        dispatcher_ptr->dispatch(main_stream, globals_stream, library_snippet_factory);
1!
33
    } else {
1✔
34
        throw std::runtime_error("Unsupported map schedule type: " + std::string(node_.schedule_type().value()));
×
35
    }
36
};
1✔
37

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

49
      };
1✔
50

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

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

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

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

89
      };
3✔
90

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

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

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

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

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

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

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

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

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

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

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

197
InstrumentationInfo SequentialMapDispatcher::instrumentation_info() const {
×
NEW
198
    auto& loop_analysis = analysis_manager_.get<analysis::LoopAnalysis>();
×
NEW
199
    analysis::LoopInfo loop_info = loop_analysis.loop_info(&node_);
×
200

201
    // Perform FlopAnalysis
202
    std::unordered_map<std::string, std::string> metrics;
×
203
    auto& flop_analysis = analysis_manager_.get<analysis::FlopAnalysis>();
×
204
    auto flop = flop_analysis.get_if_available_for_codegen(&node_);
×
205
    if (!flop.is_null()) {
×
206
        std::string flop_str = language_extension_.expression(flop);
×
207
        metrics.insert({"flop", flop_str});
×
208
    }
×
209

NEW
210
    return InstrumentationInfo(node_.element_id(), ElementType_Map, TargetType_SEQUENTIAL, loop_info, metrics);
×
211
};
×
212

213
InstrumentationInfo CPUParallelMapDispatcher::instrumentation_info() const {
×
NEW
214
    auto& loop_analysis = analysis_manager_.get<analysis::LoopAnalysis>();
×
NEW
215
    analysis::LoopInfo loop_info = loop_analysis.loop_info(&node_);
×
216

217
    // Perform FlopAnalysis
218
    std::unordered_map<std::string, std::string> metrics;
×
219
    auto& flop_analysis = analysis_manager_.get<analysis::FlopAnalysis>();
×
220
    auto flop = flop_analysis.get_if_available_for_codegen(&node_);
×
221
    if (!flop.is_null()) {
×
222
        std::string flop_str = language_extension_.expression(flop);
×
223
        metrics.insert({"flop", flop_str});
×
224
    }
×
225

NEW
226
    return InstrumentationInfo(node_.element_id(), ElementType_Map, TargetType_CPU_PARALLEL, loop_info, metrics);
×
227
};
×
228

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

© 2025 Coveralls, Inc