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

daisytuner / sdfglib / 18625138218

16 Oct 2025 02:58PM UTC coverage: 61.539% (+0.3%) from 61.233%
18625138218

push

github

web-flow
FlopAnalysis on SDFGs to create an expression of used FLOPs (#280)

* Added FlopAnalysis to create an expression of used FLOPs

* Added FlopAnalysis to instrumentation codegen

* Better test cases & explore children of while loops

* Format fix

* Replace loop indvars by assumptions (upper_bound - lower_bound) / 2

* Use assumption analysis instead of loop analysis

* Safe instrumentation for -O0

122 of 157 new or added lines in 6 files covered. (77.71%)

1 existing line in 1 file now uncovered.

9117 of 14815 relevant lines covered (61.54%)

99.5 hits per line

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

5.43
/src/codegen/instrumentation/instrumentation_plan.cpp
1
#include "sdfg/codegen/instrumentation/instrumentation_plan.h"
2
#include <memory>
3
#include <string>
4

5
#include "sdfg/analysis/analysis.h"
6
#include "sdfg/analysis/loop_analysis.h"
7
#include "sdfg/codegen/language_extension.h"
8

9
namespace sdfg {
10
namespace codegen {
11

12
void InstrumentationPlan::update(const structured_control_flow::ControlFlowNode& node, InstrumentationEventType event_type) {
×
13
    this->nodes_[&node] = event_type;
×
14
}
×
15

16
bool InstrumentationPlan::should_instrument(const structured_control_flow::ControlFlowNode& node) const {
46✔
17
    return this->nodes_.count(&node);
46✔
18
}
19

NEW
20
void InstrumentationPlan::begin_instrumentation(
×
21
    const structured_control_flow::ControlFlowNode& node, PrettyPrinter& stream, LanguageExtension& language_extension
22
) const {
23
    auto& metadata = sdfg_.metadata();
×
24
    std::string sdfg_name = sdfg_.name();
×
25
    std::string sdfg_file = metadata.at("sdfg_file");
×
26
    std::string arg_capture_path = metadata.at("arg_capture_path");
×
27
    std::string features_file = metadata.at("features_file");
×
28
    std::string opt_report_file = metadata.at("opt_report_file");
×
29

30
    std::string region_uuid = sdfg_name + "_" + std::to_string(node.element_id());
×
31

32
    // Create region id variable
33
    std::string region_id_var = sdfg_name + "_" + std::to_string(node.element_id()) + "_id";
×
34

35
    // Create metadata variable
36
    std::string metadata_var = sdfg_name + "_" + std::to_string(node.element_id()) + "_md";
×
37
    stream << "__daisy_metadata_t " << metadata_var << ";" << std::endl;
×
38

39
    // Source metadata
40
    auto& dbg_info = node.debug_info();
×
41
    stream << metadata_var << ".file_name = \"" << dbg_info.filename() << "\";" << std::endl;
×
42
    stream << metadata_var << ".function_name = \"" << dbg_info.function() << "\";" << std::endl;
×
43
    stream << metadata_var << ".line_begin = " << dbg_info.start_line() << ";" << std::endl;
×
44
    stream << metadata_var << ".line_end = " << dbg_info.end_line() << ";" << std::endl;
×
45
    stream << metadata_var << ".column_begin = " << dbg_info.start_column() << ";" << std::endl;
×
46
    stream << metadata_var << ".column_end = " << dbg_info.end_column() << ";" << std::endl;
×
47

48
    // Docc metadata
49
    stream << metadata_var << ".sdfg_name = \"" << sdfg_name << "\";" << std::endl;
×
50
    stream << metadata_var << ".sdfg_file = \"" << sdfg_file << "\";" << std::endl;
×
51
    stream << metadata_var << ".arg_capture_path = \"" << arg_capture_path << "\";" << std::endl;
×
52
    stream << metadata_var << ".features_file = \"" << features_file << "\";" << std::endl;
×
53
    stream << metadata_var << ".opt_report_file = \"" << opt_report_file << "\";" << std::endl;
×
54
    stream << metadata_var << ".element_id = " << node.element_id() << ";" << std::endl;
×
55
    if (auto map_node = dynamic_cast<const structured_control_flow::Map*>(&node)) {
×
56
        stream << metadata_var << ".element_type = \"map\";" << std::endl;
×
57
        stream << metadata_var << ".target_type = \"" << map_node->schedule_type().value() << "\";" << std::endl;
×
58
    } else if (dynamic_cast<const structured_control_flow::For*>(&node)) {
×
59
        stream << metadata_var << ".element_type = \"for\";" << std::endl;
×
60
        stream << metadata_var << ".target_type = \"SEQUENTIAL\";" << std::endl;
×
61
    } else if (dynamic_cast<const structured_control_flow::While*>(&node)) {
×
62
        stream << metadata_var << ".element_type = \"while\";" << std::endl;
×
63
        stream << metadata_var << ".target_type = \"SEQUENTIAL\";" << std::endl;
×
64
    } else {
×
65
        stream << metadata_var << ".element_type = \"\";" << std::endl;
×
66
        stream << metadata_var << ".target_type = \"\";" << std::endl;
×
67
    }
68
    if (!this->loopnest_indices_.empty()) {
×
69
        stream << metadata_var << ".loopnest_index = " << this->loopnest_indices_.at(&node) << ";" << std::endl;
×
70
    } else {
×
71
        stream << metadata_var << ".loopnest_index = -1;" << std::endl;
×
72
    }
73
    stream << metadata_var << ".region_uuid = \"" << region_uuid << "\";" << std::endl;
×
74

75
    // Initialize region
76
    if (this->nodes_.at(&node) == InstrumentationEventType::CPU) {
×
77
        stream << "long long " << region_id_var << " = __daisy_instrumentation_init(&" << metadata_var
×
78
               << ", __DAISY_EVENT_SET_CPU);" << std::endl;
×
79
    } else {
×
80
        stream << "long long " << region_id_var << " = __daisy_instrumentation_init(&" << metadata_var
×
81
               << ", __DAISY_EVENT_SET_CUDA);" << std::endl;
×
82
    }
83

84
    // Enter region
85
    stream << "__daisy_instrumentation_enter(" << region_id_var << ");" << std::endl;
×
86
}
×
87

NEW
88
void InstrumentationPlan::end_instrumentation(
×
89
    const structured_control_flow::ControlFlowNode& node, PrettyPrinter& stream, LanguageExtension& language_extension
90
) const {
UNCOV
91
    std::string region_id_var = sdfg_.name() + "_" + std::to_string(node.element_id()) + "_id";
×
92

93
    // Exit region
94
    if (this->nodes_.at(&node) == InstrumentationEventType::CPU) {
×
95
        stream << "__daisy_instrumentation_exit(" << region_id_var << ");" << std::endl;
×
96
    } else {
×
97
        stream << "__daisy_instrumentation_exit(" << region_id_var << ");" << std::endl;
×
98
    }
99

100
    // Perform FlopAnalysis
NEW
101
    if (this->flops_.contains(&node)) {
×
NEW
102
        auto flop = this->flops_.at(&node);
×
NEW
103
        if (!flop.is_null()) {
×
NEW
104
            std::string flop_str = language_extension.expression(flop);
×
NEW
105
            stream << "__daisy_instrumentation_increment(" << region_id_var << ", \"flop\", " << flop_str << ");"
×
NEW
106
                   << std::endl;
×
NEW
107
        }
×
NEW
108
    }
×
109

110
    // Finalize region
111
    stream << "__daisy_instrumentation_finalize(" << region_id_var << ");" << std::endl;
×
112
}
×
113

114
std::unique_ptr<InstrumentationPlan> InstrumentationPlan::none(StructuredSDFG& sdfg) {
42✔
115
    return std::make_unique<InstrumentationPlan>(
42✔
116
        sdfg, std::unordered_map<const structured_control_flow::ControlFlowNode*, InstrumentationEventType>{}
42✔
117
    );
118
}
×
119

120
std::unique_ptr<InstrumentationPlan> InstrumentationPlan::outermost_loops_plan(StructuredSDFG& sdfg) {
×
121
    analysis::AnalysisManager analysis_manager(sdfg);
×
122
    auto& loop_tree_analysis = analysis_manager.get<analysis::LoopAnalysis>();
×
123
    auto ols = loop_tree_analysis.outermost_loops();
×
124

125
    std::unordered_map<const structured_control_flow::ControlFlowNode*, InstrumentationEventType> nodes;
×
126
    std::unordered_map<const structured_control_flow::ControlFlowNode*, size_t> loopnest_indices;
×
127
    for (size_t i = 0; i < ols.size(); i++) {
×
128
        auto& loop = ols[i];
×
129
        loopnest_indices[loop] = i;
×
130
        if (auto map_node = dynamic_cast<const structured_control_flow::Map*>(loop)) {
×
131
            if (map_node->schedule_type().value() == "CUDA") {
×
132
                nodes.insert({loop, InstrumentationEventType::CUDA});
×
133
                continue;
×
134
            }
135
        }
×
136
        nodes.insert({loop, InstrumentationEventType::CPU}); // Default to CPU if not CUDA
×
137
    }
×
138
    return std::make_unique<InstrumentationPlan>(sdfg, nodes, loopnest_indices);
×
139
}
×
140

141
} // namespace codegen
142
} // 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