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

daisytuner / sdfglib / 17938601462

23 Sep 2025 07:17AM UTC coverage: 61.149% (-0.02%) from 61.165%
17938601462

Pull #238

github

web-flow
Merge 703773d84 into acf2a7a40
Pull Request #238: Fix arg capturing

10 of 11 new or added lines in 1 file covered. (90.91%)

5 existing lines in 2 files now uncovered.

9513 of 15557 relevant lines covered (61.15%)

108.76 hits per line

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

58.88
/src/codegen/code_generator.cpp
1
#include "sdfg/codegen/code_generator.h"
2
#include <symengine/constants.h>
3
#include <symengine/dict.h>
4
#include <symengine/number.h>
5
#include "sdfg/analysis/analysis.h"
6
#include "sdfg/analysis/mem_access_range_analysis.h"
7
#include "sdfg/analysis/type_analysis.h"
8
#include "sdfg/codegen/instrumentation/capture_var_plan.h"
9
#include "sdfg/symbolic/symbolic.h"
10
#include "sdfg/types/structure.h"
11

12
namespace sdfg {
13
namespace codegen {
14

15
std::tuple<int, types::PrimitiveType> CodeGenerator::analyze_type_rec(
5✔
16
    symbolic::Expression* dims,
17
    int maxDim,
18
    int dimIdx,
19
    const types::IType& type,
20
    int argIdx,
21
    const analysis::MemAccessRange* range,
22
    analysis::AnalysisManager& analysis_manager,
23
    const StructuredSDFG& sdfg,
24
    std::string var_name
25
) {
26
    if (dimIdx > maxDim) {
5✔
27
        std::cerr << "In '" << sdfg_.name() << "', arg" << argIdx << ": data nesting deeper than " << maxDim
×
28
                  << ", ignoring" << std::endl;
×
29
        return std::make_tuple(-1, types::Void);
×
30
    }
31

32
    if (auto* scalarType = dynamic_cast<const types::Scalar*>(&type)) {
5✔
33
        return std::make_tuple(dimIdx, scalarType->primitive_type());
3✔
34
    } else if (auto structureType = dynamic_cast<const sdfg::types::Structure*>(&type)) {
2✔
35
        return std::make_tuple(dimIdx, types::Void);
×
36
    } else if (auto* arrayType = dynamic_cast<const types::Array*>(&type)) {
2✔
37
        dims[dimIdx] = arrayType->num_elements();
1✔
38
        auto& inner = arrayType->element_type();
1✔
39

40
        return analyze_type_rec(dims, maxDim, dimIdx + 1, inner, argIdx, range, analysis_manager, sdfg, var_name);
1✔
41
    } else if (auto* ptrType = dynamic_cast<const types::Pointer*>(&type)) {
1✔
42
        if (range && !range->is_undefined()) {
1✔
43
            const auto& dim = range->dims()[dimIdx];
1✔
44

45
            if (symbolic::eq(symbolic::zero(), dim.first)) {
1✔
46
                dims[dimIdx] = symbolic::add(dim.second, symbolic::one());
1✔
47
                const types::IType* inner = nullptr;
1✔
48
                if (ptrType->has_pointee_type()) {
1✔
49
                    inner = &(ptrType->pointee_type());
1✔
50
                } else {
1✔
51
                    if (dimIdx > 0) {
×
52
                        std::cerr << "In '" << sdfg_.name() << "', arg" << argIdx << " dim" << dimIdx
×
53
                                  << ": missing pointee type for dim > 0, cannot capture!" << std::endl;
×
54
                        return std::make_tuple(-2, types::Void);
×
55
                    } else {
56
                        auto& type_analysis = analysis_manager.get<analysis::TypeAnalysis>();
×
57
                        auto outer = type_analysis.get_outer_type(var_name);
×
58
                        if (outer != nullptr) {
×
59
                            if (auto* ptrType_new = dynamic_cast<const types::Pointer*>(outer)) {
×
60
                                if (ptrType_new->has_pointee_type()) {
×
61
                                    inner = &(ptrType_new->pointee_type());
×
62
                                } else {
×
63
                                    std::cerr << "In '" << sdfg_.name() << "', arg" << argIdx << " dim" << dimIdx
×
64
                                              << ": missing pointee type, cannot capture!" << std::endl;
×
65
                                    return std::make_tuple(-2, types::Void);
×
66
                                }
67
                            }
×
68
                        } else {
×
69
                            std::cerr << "In '" << sdfg_.name() << "', arg" << argIdx << " dim" << dimIdx
×
70
                                      << ": could not infer type from container, cannot capture!" << std::endl;
×
71
                            return std::make_tuple(-2, types::Void);
×
72
                        }
73
                    }
74
                    if (inner == nullptr) {
×
75
                        std::cerr << "In '" << sdfg_.name() << "', arg" << argIdx << " dim" << dimIdx
×
76
                                  << ": could not infer type from container, cannot capture!" << std::endl;
×
77
                        return std::make_tuple(-2, types::Void);
×
78
                    }
79
                }
80

81
                return analyze_type_rec(dims, maxDim, dimIdx + 1, *inner, argIdx, range, analysis_manager, sdfg, var_name);
1✔
82
            } else {
83
                std::cerr << "In '" << sdfg_.name() << "', arg" << argIdx << " dim" << dimIdx << ": has upper bound "
×
84
                          << dim.second->__str__() << ", but does not start at 0, cannot capture" << std::endl;
×
85
                return std::make_tuple(-2, types::Void);
×
86
            }
87
        } else {
88
            std::cerr << "In '" << sdfg_.name() << "', arg" << argIdx << " dim" << dimIdx
×
89
                      << ": missing range, cannot capture!" << std::endl;
×
90
            return std::make_tuple(-2, types::Void);
×
91
        }
92
    } else {
93
        std::cerr << "In '" << sdfg_.name() << "', arg" << argIdx << ": unsupported type " << type.print()
×
94
                  << ", cannot capture!" << std::endl;
×
95
        return std::make_tuple(-1, types::Void);
×
96
    }
97
}
5✔
98

99
bool CodeGenerator::add_capture_plan(
3✔
100
    const std::string& varName,
101
    int argIdx,
102
    bool isExternal,
103
    std::vector<CaptureVarPlan>& plan,
104
    const analysis::MemAccessRanges& ranges
105
) {
106
    const types::IType* type = nullptr;
3✔
107
    if (isExternal) {
3✔
108
        auto& pointer_type = dynamic_cast<const types::Pointer&>(sdfg_.type(varName));
1✔
109
        assert(pointer_type.has_pointee_type() && "Externals must have a pointee type");
2✔
110
        type = &pointer_type.pointee_type();
1✔
111
    } else {
1✔
112
        type = &sdfg_.type(varName);
2✔
113
    }
114

115
    const auto* range = ranges.get(varName);
3✔
116

117
    analysis::AnalysisManager analysis_manager(sdfg_);
3✔
118

119
    symbolic::Expression dims[3];
9✔
120

121
    int dimCount = 0;
3✔
122
    types::PrimitiveType innerPrim;
123

124
    std::tie(dimCount, innerPrim) =
3✔
125
        analyze_type_rec(dims, 3, 0, *type, argIdx, range, analysis_manager, sdfg_, varName);
3✔
126

127
    bool isRead = range ? range->saw_read() : true;
3✔
128
    bool isWritten = range ? range->saw_write() : true;
3✔
129

130
    if (dimCount == 0) {
3✔
131
        plan.emplace_back(isRead, false, CaptureVarType::CapRaw, argIdx, isExternal, innerPrim);
2✔
132
    } else if (dimCount == 1) {
3✔
UNCOV
133
        plan.emplace_back(isRead, isWritten, CaptureVarType::Cap1D, argIdx, isExternal, innerPrim, dims[0]);
×
134
    } else if (dimCount == 2) {
1✔
135
        plan.emplace_back(isRead, isWritten, CaptureVarType::Cap2D, argIdx, isExternal, innerPrim, dims[0], dims[1]);
1✔
136
    } else if (dimCount == 3) {
1✔
137
        plan.emplace_back(
×
138
            isRead, isWritten, CaptureVarType::Cap3D, argIdx, isExternal, innerPrim, dims[0], dims[1], dims[2]
×
139
        );
140
    } else {
×
141
        return false;
×
142
    }
143

144
    return true;
3✔
145
}
3✔
146

147
std::unique_ptr<std::vector<CaptureVarPlan>> CodeGenerator::create_capture_plans() {
1✔
148
    auto name = sdfg_.name();
1✔
149

150
    analysis::AnalysisManager analysis_manager(sdfg_);
1✔
151
    const auto& args = sdfg_.arguments();
1✔
152
    auto& exts = sdfg_.externals();
1✔
153
    const auto& ranges = analysis_manager.get<analysis::MemAccessRanges>();
1✔
154

155
    auto plan = std::make_unique<std::vector<CaptureVarPlan>>();
1✔
156

157
    bool working = true;
1✔
158

159
    int argIdx = -1;
1✔
160
    for (auto& argName : args) {
3✔
161
        ++argIdx;
2✔
162

163
        working &= add_capture_plan(argName, argIdx, false, *plan.get(), ranges);
2✔
164
    }
165

166
    for (auto& argName : exts) {
2✔
167
        if (sdfg_.type(argName).type_id() == types::TypeID::Function) {
1✔
NEW
168
            continue;
×
169
        }
170
        ++argIdx;
1✔
171

172
        working &= add_capture_plan(argName, argIdx, true, *plan.get(), ranges);
1✔
173
    }
174

175
    if (!working) {
1✔
176
        std::cerr << "In '" << name << "': could not create capture plan, returning empty plan" << std::endl;
×
177
        return std::make_unique<std::vector<CaptureVarPlan>>();
×
178
    }
179

180
    return plan;
1✔
181
}
1✔
182

183
} // namespace codegen
184
} // 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