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

daisytuner / docc / 28814257460

06 Jul 2026 06:31PM UTC coverage: 62.928% (-0.03%) from 62.96%
28814257460

Pull #843

github

web-flow
Merge b6b7f08d9 into 95ea95f1f
Pull Request #843: adds type_ids for Element classes and a human-readable element_type

457 of 599 new or added lines in 121 files covered. (76.29%)

5 existing lines in 3 files now uncovered.

40598 of 64515 relevant lines covered (62.93%)

977.42 hits per line

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

52.58
/opt/src/targets/omp/codegen/omp_map_dispatcher.cpp
1
#include "sdfg/targets/omp/codegen/omp_map_dispatcher.h"
2

3
#include "sdfg/targets/omp/schedule.h"
4

5
#include <sdfg/analysis/loop_analysis.h>
6
#include <sdfg/analysis/users.h>
7
#include <sdfg/codegen/dispatchers/node_dispatcher_registry.h>
8
#include <sdfg/codegen/dispatchers/sequence_dispatcher.h>
9
#include <sdfg/codegen/instrumentation/instrumentation_info.h>
10
#include <sdfg/structured_control_flow/map.h>
11

12
namespace sdfg {
13
namespace omp {
14

15
OMPMapDispatcher::OMPMapDispatcher(
16
    codegen::LanguageExtension& language_extension,
17
    StructuredSDFG& sdfg,
18
    analysis::AnalysisManager& analysis_manager,
19
    structured_control_flow::Map& node,
20
    codegen::InstrumentationPlan& instrumentation_plan,
21
    codegen::ArgCapturePlan& arg_capture_plan
22
)
23
    : NodeDispatcher(language_extension, sdfg, analysis_manager, node, instrumentation_plan, arg_capture_plan),
4✔
24
      node_(node) {
4✔
25

26
      };
4✔
27

28
void OMPMapDispatcher::dispatch_node(
29
    codegen::PrettyPrinter& main_stream,
30
    codegen::PrettyPrinter& globals_stream,
31
    codegen::CodeSnippetFactory& library_snippet_factory
32
) {
4✔
33
    // Mark written locals as private
34
    analysis::AnalysisManager analysis_manager(sdfg_);
4✔
35
    auto& users = analysis_manager.get<analysis::Users>();
4✔
36
    analysis::UsersView users_view(users, node_.root());
4✔
37

38
    std::vector<std::string> locals;
4✔
39
    for (auto& entry : users.locals(node_.root())) {
4✔
40
        if (users_view.writes(entry).size() > 0 || users_view.moves(entry).size() > 0) {
×
41
            locals.push_back(entry);
×
42
        }
×
43
    }
×
44

45
    // Generate code
46
    main_stream << "// Map" << std::endl;
4✔
47
    main_stream << "#pragma omp parallel for";
4✔
48

49
    main_stream << " schedule(";
4✔
50
    if (ScheduleType_OMP::omp_schedule(node_.schedule_type()) == OpenMPSchedule::Static) {
4✔
51
        main_stream << "static)";
2✔
52
    } else if (ScheduleType_OMP::omp_schedule(node_.schedule_type()) == OpenMPSchedule::Dynamic) {
2✔
53
        main_stream << "dynamic)";
2✔
54
    } else if (ScheduleType_OMP::omp_schedule(node_.schedule_type()) == OpenMPSchedule::Guided) {
2✔
55
        main_stream << "guided)";
×
56
    } else {
×
57
        throw std::runtime_error("Unsupported OpenMP schedule type");
×
58
    }
×
59

60
    if (!ScheduleType_OMP::num_threads(node_.schedule_type()).is_null()) {
4✔
61
        main_stream << " num_threads(";
1✔
62
        main_stream << language_extension_.expression(ScheduleType_OMP::num_threads(node_.schedule_type()));
1✔
63
        main_stream << ")";
1✔
64
    }
1✔
65

66
    if (locals.size() > 0) {
4✔
67
        main_stream << " private(" << helpers::join(locals, ", ") << ")";
×
68
    }
×
69
    main_stream << std::endl;
4✔
70
    main_stream << "for";
4✔
71
    main_stream << "(";
4✔
72
    main_stream << node_.indvar()->get_name();
4✔
73
    main_stream << " = ";
4✔
74
    main_stream << language_extension_.expression(node_.init());
4✔
75
    main_stream << ";";
4✔
76

77
    // Default condition
78
    auto condition = node_.condition();
4✔
79

80
    // OpenMP requires the loop condition to be in a simple form (no && or ||), so we rely on canonical_bound()
81
    auto canonical_bound = node_.canonical_bound_upper();
4✔
82
    if (!canonical_bound.is_null()) {
4✔
83
        condition = symbolic::Lt(node_.indvar(), canonical_bound);
4✔
84
    }
4✔
85
    main_stream << language_extension_.expression(condition);
4✔
86
    main_stream << ";";
4✔
87
    main_stream << node_.indvar()->get_name();
4✔
88
    main_stream << " = ";
4✔
89
    main_stream << language_extension_.expression(node_.update());
4✔
90
    main_stream << ")" << std::endl;
4✔
91
    main_stream << "{" << std::endl;
4✔
92

93
    for (auto& local : locals) {
4✔
94
        auto& type = sdfg_.type(local);
×
95
        if (type.storage_type().allocation() == types::StorageType::AllocationType::Managed) {
×
96
            if (type.storage_type().is_cpu_stack()) {
×
97
                main_stream << local << " = ";
×
98
                main_stream << "alloca(" << language_extension_.expression(type.storage_type().allocation_size())
×
99
                            << ")";
×
100
                main_stream << ";" << std::endl;
×
101
            } else if (type.storage_type().is_cpu_heap()) {
×
102
                main_stream << local << " = ";
×
103
                main_stream << language_extension_.external_prefix() << "malloc("
×
104
                            << language_extension_.expression(type.storage_type().allocation_size()) << ")";
×
105
                main_stream << ";" << std::endl;
×
106
            }
×
107
        }
×
108
    }
×
109

110
    main_stream.setIndent(main_stream.indent() + 4);
4✔
111
    codegen::SequenceDispatcher
4✔
112
        dispatcher(language_extension_, sdfg_, analysis_manager_, node_.root(), instrumentation_plan_, arg_capture_plan_);
4✔
113
    dispatcher.dispatch(main_stream, globals_stream, library_snippet_factory);
4✔
114
    main_stream.setIndent(main_stream.indent() - 4);
4✔
115

116
    for (auto& local : locals) {
4✔
117
        auto& type = sdfg_.type(local);
×
118
        if (type.storage_type().deallocation() == types::StorageType::AllocationType::Managed) {
×
119
            if (type.storage_type().is_cpu_heap()) {
×
120
                main_stream << language_extension_.external_prefix() << "free(" << local << ");" << std::endl;
×
121
            }
×
122
        }
×
123
    }
×
124

125
    main_stream << "}" << std::endl;
4✔
126
};
4✔
127

128
codegen::InstrumentationInfo OMPMapDispatcher::instrumentation_info() const {
×
129
    auto& loop_analysis = analysis_manager_.get<analysis::LoopAnalysis>();
×
130
    analysis::LoopInfo loop_info = loop_analysis.loop_info(&node_);
×
131

132
    // Perform FlopAnalysis
133
    std::unordered_map<std::string, std::string> metrics;
×
134
    auto& flop_analysis = analysis_manager_.get<analysis::FlopAnalysis>();
×
135
    auto flop = flop_analysis.get_if_available_for_codegen(&node_);
×
136
    if (!flop.is_null()) {
×
137
        std::string flop_str = language_extension_.expression(flop);
×
138
        metrics.insert({"flop", flop_str});
×
139
    }
×
140

141
    return codegen::InstrumentationInfo(
×
NEW
142
        node_.element_id(), node_.element_type(), codegen::TargetType_CPU_PARALLEL, loop_info, metrics
×
143
    );
×
144
};
×
145

146
} // namespace omp
147
} // 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