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

daisytuner / sdfglib / 15744620952

18 Jun 2025 10:07PM UTC coverage: 64.591% (+0.005%) from 64.586%
15744620952

push

github

web-flow
Merge pull request #86 from daisytuner/add-optimizer

Add optimizer functionality

122 of 201 new or added lines in 9 files covered. (60.7%)

2 existing lines in 1 file now uncovered.

8141 of 12604 relevant lines covered (64.59%)

153.84 hits per line

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

69.62
/src/transformations/loop_interchange.cpp
1
#include "sdfg/transformations/loop_interchange.h"
2

3
#include "sdfg/analysis/data_parallelism_analysis.h"
4
#include "sdfg/structured_control_flow/structured_loop.h"
5

6
namespace sdfg {
7
namespace transformations {
8

9
LoopInterchange::LoopInterchange(structured_control_flow::StructuredLoop& outer_loop,
5✔
10
                                 structured_control_flow::StructuredLoop& inner_loop)
11
    : outer_loop_(outer_loop), inner_loop_(inner_loop) {
5✔
12

13
      };
5✔
14

15
std::string LoopInterchange::name() const { return "LoopInterchange"; };
2✔
16

17
bool LoopInterchange::can_be_applied(builder::StructuredSDFGBuilder& builder,
5✔
18
                                     analysis::AnalysisManager& analysis_manager) {
19
    auto& outer_indvar = this->outer_loop_.indvar();
5✔
20

21
    // Criterion: Inner loop must not depend on outer loop
22
    auto& inner_loop_init = this->inner_loop_.init();
5✔
23
    auto& inner_loop_condition = this->inner_loop_.condition();
5✔
24
    auto& inner_loop_update = this->inner_loop_.update();
5✔
25
    if (symbolic::uses(inner_loop_init, outer_indvar->get_name()) ||
10✔
26
        symbolic::uses(inner_loop_condition, outer_indvar->get_name()) ||
10✔
27
        symbolic::uses(inner_loop_update, outer_indvar->get_name())) {
5✔
28
        return false;
×
29
    }
30

31
    // Criterion: Outer loop must not have any outer blocks
32
    if (outer_loop_.root().size() > 1) {
5✔
33
        return false;
×
34
    }
35
    if (outer_loop_.root().at(0).second.assignments().size() > 0) {
5✔
36
        return false;
×
37
    }
38
    if (&outer_loop_.root().at(0).first != &inner_loop_) {
5✔
39
        return false;
×
40
    }
41
    // Criterion: Any of both loops is a map
42
    auto& analysis = analysis_manager.get<analysis::DataParallelismAnalysis>();
5✔
43

44
    auto& outer_dependencies = analysis.get(this->outer_loop_);
5✔
45
    if (outer_dependencies.size() > 0) {
5✔
46
        bool is_map = true;
5✔
47
        for (auto& dep : outer_dependencies) {
24✔
48
            auto& dep_type = dep.second;
19✔
49
            if (dep_type < analysis::Parallelism::PARALLEL) {
19✔
50
                is_map = false;
×
51
                break;
×
52
            }
53
        }
54
        if (is_map) {
5✔
55
            return true;
5✔
56
        }
57
    }
×
58
    auto& inner_dependencies = analysis.get(this->inner_loop_);
×
59
    if (inner_dependencies.size() > 0) {
×
60
        bool is_map = true;
×
61
        for (auto& dep : inner_dependencies) {
×
62
            auto& dep_type = dep.second;
×
63
            if (dep_type < analysis::Parallelism::PARALLEL) {
×
64
                is_map = false;
×
65
                break;
×
66
            }
67
        }
68
        if (is_map) {
×
69
            return true;
×
70
        }
71
    }
×
72

73
    return false;
×
74
};
5✔
75

76
void LoopInterchange::apply(builder::StructuredSDFGBuilder& builder,
5✔
77
                            analysis::AnalysisManager& analysis_manager) {
78
    auto new_inner_loop = builder.add_for_after(
10✔
79
        builder.parent(inner_loop_), this->inner_loop_, this->outer_loop_.indvar(),
5✔
80
        this->outer_loop_.condition(), this->outer_loop_.init(), this->outer_loop_.update());
5✔
81
    auto& inner_body = this->inner_loop_.root();
5✔
82

83
    builder.insert_children(new_inner_loop.first.root(), inner_body, 0);
5✔
84

85
    auto new_outer_loop = builder.add_for_after(
10✔
86
        builder.parent(outer_loop_), this->outer_loop_, this->inner_loop_.indvar(),
5✔
87
        this->inner_loop_.condition(), this->inner_loop_.init(), this->inner_loop_.update());
5✔
88

89
    auto& outer_body = this->outer_loop_.root();
5✔
90
    builder.insert_children(new_outer_loop.first.root(), outer_body, 0);
5✔
91
    builder.remove_child(builder.parent(inner_loop_), this->inner_loop_);
5✔
92
    builder.remove_child(builder.parent(outer_loop_), this->outer_loop_);
5✔
93

94
    analysis_manager.invalidate_all();
5✔
95
};
5✔
96

97
void LoopInterchange::to_json(nlohmann::json& j) const {
2✔
98
    j["transformation_type"] = this->name();
2✔
99
    j["outer_loop_element_id"] = this->outer_loop_.element_id();
2✔
100
    j["inner_loop_element_id"] = this->inner_loop_.element_id();
2✔
101
};
2✔
102

103
LoopInterchange LoopInterchange::from_json(builder::StructuredSDFGBuilder& builder,
1✔
104
                                           const nlohmann::json& desc) {
105
    auto outer_loop_id = desc["outer_loop_element_id"].get<size_t>();
1✔
106
    auto inner_loop_id = desc["inner_loop_element_id"].get<size_t>();
1✔
107
    auto outer_element = builder.find_element_by_id(outer_loop_id);
1✔
108
    auto inner_element = builder.find_element_by_id(inner_loop_id);
1✔
109
    if (!outer_element) {
1✔
NEW
110
        throw InvalidTransformationDescriptionException(
×
NEW
111
            "Element with ID " + std::to_string(outer_loop_id) + " not found.");
×
112
    }
113
    if (!inner_element) {
1✔
NEW
114
        throw InvalidTransformationDescriptionException(
×
NEW
115
            "Element with ID " + std::to_string(inner_loop_id) + " not found.");
×
116
    }
117
    auto outer_loop = dynamic_cast<structured_control_flow::For*>(outer_element);
1✔
118
    auto inner_loop = dynamic_cast<structured_control_flow::For*>(inner_element);
1✔
119

120
    return LoopInterchange(*outer_loop, *inner_loop);
1✔
NEW
121
};
×
122

123
}  // namespace transformations
124
}  // 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