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

daisytuner / sdfglib / 16779684622

06 Aug 2025 02:21PM UTC coverage: 64.3% (-1.0%) from 65.266%
16779684622

push

github

web-flow
Merge pull request #172 from daisytuner/opaque-pointers

Opaque pointers, typed memlets, untyped tasklet connectors

330 of 462 new or added lines in 38 files covered. (71.43%)

382 existing lines in 30 files now uncovered.

8865 of 13787 relevant lines covered (64.3%)

116.73 hits per line

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

50.68
/src/transformations/loop_tiling.cpp
1
#include "sdfg/transformations/loop_tiling.h"
2

3
#include "sdfg/analysis/assumptions_analysis.h"
4
#include "sdfg/analysis/loop_analysis.h"
5
#include "sdfg/analysis/scope_analysis.h"
6
#include "sdfg/builder/structured_sdfg_builder.h"
7
#include "sdfg/structured_control_flow/structured_loop.h"
8
#include "sdfg/symbolic/symbolic.h"
9

10
namespace sdfg {
11
namespace transformations {
12

13
LoopTiling::LoopTiling(structured_control_flow::StructuredLoop& loop, size_t tile_size)
1✔
14
    : loop_(loop), tile_size_(tile_size) {};
1✔
15

UNCOV
16
std::string LoopTiling::name() const { return "LoopTiling"; };
×
17

18
bool LoopTiling::can_be_applied(builder::StructuredSDFGBuilder& builder, analysis::AnalysisManager& analysis_manager) {
1✔
19
    if (this->tile_size_ <= 1) {
1✔
UNCOV
20
        return false;
×
21
    }
22
    // Criterion contiguous loop
23
    auto& assumptions_analysis = analysis_manager.get<analysis::AssumptionsAnalysis>();
1✔
24
    return analysis::LoopAnalysis::is_contiguous(&loop_, assumptions_analysis);
1✔
25
};
1✔
26

27
void LoopTiling::apply(builder::StructuredSDFGBuilder& builder, analysis::AnalysisManager& analysis_manager) {
1✔
28
    auto& sdfg = builder.subject();
1✔
29

30
    auto& scope_analysis = analysis_manager.get<analysis::ScopeAnalysis>();
1✔
31
    auto parent = static_cast<structured_control_flow::Sequence*>(scope_analysis.parent_scope(&loop_));
1✔
32

33
    auto indvar = loop_.indvar();
1✔
34

35
    // Step 1: Define new outer loop
36
    auto outer_indvar_str = builder.find_new_name(indvar->get_name() + "_tile");
1✔
37
    builder.add_container(outer_indvar_str, sdfg.type(loop_.indvar()->get_name()));
1✔
38

39
    auto outer_indvar = symbolic::symbol(outer_indvar_str);
1✔
40
    auto outer_condition = symbolic::subs(loop_.condition(), indvar, outer_indvar);
1✔
41
    auto outer_update = symbolic::add(outer_indvar, symbolic::integer(this->tile_size_));
1✔
42

43
    structured_control_flow::StructuredLoop* outer_loop = nullptr;
1✔
44
    if (auto map = dynamic_cast<structured_control_flow::Map*>(&loop_)) {
1✔
UNCOV
45
        outer_loop =
×
UNCOV
46
            &builder
×
UNCOV
47
                 .add_map_before(
×
UNCOV
48
                     *parent, loop_, outer_indvar, outer_condition, loop_.init(), outer_update, map->schedule_type()
×
49
                 )
UNCOV
50
                 .first;
×
UNCOV
51
    } else {
×
52
        outer_loop =
1✔
53
            &builder.add_for_before(*parent, loop_, outer_indvar, outer_condition, loop_.init(), outer_update).first;
1✔
54
    }
55

56
    // Step 2: Redefine inner loop
57
    auto inner_indvar = indvar;
1✔
58
    auto inner_init = outer_indvar;
1✔
59
    auto inner_condition_tile =
60
        symbolic::Lt(inner_indvar, symbolic::add(outer_indvar, symbolic::integer(this->tile_size_)));
1✔
61

62
    auto& assumptions_analysis = analysis_manager.get<analysis::AssumptionsAnalysis>();
1✔
63
    auto old_bound = analysis::LoopAnalysis::canonical_bound(&loop_, assumptions_analysis);
1✔
64

65
    symbolic::Condition inner_condition = inner_condition_tile;
1✔
66
    if (old_bound == SymEngine::null) {
1✔
67
        inner_condition = symbolic::And(inner_condition_tile, loop_.condition());
×
68
    } else if (SymEngine::is_a<SymEngine::Integer>(*old_bound)) {
1✔
69
        size_t old_bound_int = SymEngine::rcp_static_cast<const SymEngine::Integer>(old_bound)->as_uint();
×
70
        if ((old_bound_int % this->tile_size_) == 0) {
×
71
            inner_condition = inner_condition_tile;
×
72
        } else {
×
73
            inner_condition = symbolic::And(inner_condition_tile, loop_.condition());
×
74
        }
75
    } else {
×
76
        inner_condition = symbolic::And(inner_condition_tile, loop_.condition());
1✔
77
    }
78
    auto inner_update = symbolic::add(inner_indvar, symbolic::integer(1));
1✔
79
    loop_.update() = inner_update;
1✔
80
    loop_.condition() = inner_condition;
1✔
81
    loop_.init() = inner_init;
1✔
82

83
    // Step 3: Move inner loop body to outer loop body
84
    builder.insert(loop_, *parent, outer_loop->root(), loop_.debug_info());
1✔
85

86
    analysis_manager.invalidate_all();
1✔
87
};
1✔
88

UNCOV
89
void LoopTiling::to_json(nlohmann::json& j) const {
×
UNCOV
90
    std::string loop_type;
×
UNCOV
91
    if (dynamic_cast<structured_control_flow::For*>(&loop_)) {
×
UNCOV
92
        loop_type = "for";
×
UNCOV
93
    } else if (dynamic_cast<structured_control_flow::Map*>(&loop_)) {
×
UNCOV
94
        loop_type = "map";
×
UNCOV
95
    } else {
×
96
        throw std::runtime_error("Unsupported loop type for serialization of loop: " + loop_.indvar()->get_name());
×
97
    }
98

UNCOV
99
    j["transformation_type"] = this->name();
×
UNCOV
100
    j["subgraph"] = {{"0", {{"element_id", this->loop_.element_id()}, {"type", loop_type}}}};
×
UNCOV
101
    j["tile_size"] = tile_size_;
×
UNCOV
102
};
×
103

UNCOV
104
LoopTiling LoopTiling::from_json(builder::StructuredSDFGBuilder& builder, const nlohmann::json& desc) {
×
UNCOV
105
    auto loop_id = desc["subgraph"]["0"]["element_id"].get<size_t>();
×
UNCOV
106
    size_t tile_size = desc["tile_size"].get<size_t>();
×
UNCOV
107
    auto element = builder.find_element_by_id(loop_id);
×
UNCOV
108
    if (!element) {
×
109
        throw InvalidTransformationDescriptionException("Element with ID " + std::to_string(loop_id) + " not found.");
×
110
    }
UNCOV
111
    auto loop = dynamic_cast<structured_control_flow::StructuredLoop*>(element);
×
112

UNCOV
113
    return LoopTiling(*loop, tile_size);
×
114
};
×
115

116
} // namespace transformations
117
} // 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