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

daisytuner / sdfglib / 16903021653

12 Aug 2025 08:12AM UTC coverage: 65.353% (-0.1%) from 65.452%
16903021653

push

github

web-flow
Merge pull request #187 from daisytuner/arg-capture-things

Extends arg-capturing to opaque pointers (on the first level)

11 of 35 new or added lines in 1 file covered. (31.43%)

1 existing line in 1 file now uncovered.

9169 of 14030 relevant lines covered (65.35%)

128.27 hits per line

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

57.73
/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/codegen/instrumentation/capture_var_plan.h"
8
#include "sdfg/symbolic/symbolic.h"
9
#include "sdfg/types/structure.h"
10
#include "sdfg/types/utils.h"
11

12
namespace sdfg {
13
namespace codegen {
14

15
std::tuple<int, types::PrimitiveType> CodeGenerator::analyze_type_rec(
7✔
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) {
7✔
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)) {
7✔
33
        return std::make_tuple(dimIdx, scalarType->primitive_type());
4✔
34
    } else if (auto structureType = dynamic_cast<const sdfg::types::Structure*>(&type)) {
3✔
UNCOV
35
        return std::make_tuple(dimIdx, types::Void);
×
36
    } else if (auto* arrayType = dynamic_cast<const types::Array*>(&type)) {
3✔
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)) {
2✔
42
        if (range && !range->is_undefined()) {
2✔
43
            const auto& dim = range->dims()[dimIdx];
2✔
44

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

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

98
bool CodeGenerator::add_capture_plan(
4✔
99
    const std::string& varName,
100
    int argIdx,
101
    bool isExternal,
102
    std::vector<CaptureVarPlan>& plan,
103
    const analysis::MemAccessRanges& ranges
104
) {
105
    auto& type = sdfg_.type(varName);
4✔
106

107
    const auto* range = ranges.get(varName);
4✔
108

109
    analysis::AnalysisManager analysis_manager(sdfg_);
4✔
110

111
    symbolic::Expression dims[3];
12✔
112

113
    int dimCount = 0;
4✔
114
    types::PrimitiveType innerPrim;
115

116
    std::tie(dimCount, innerPrim) = analyze_type_rec(dims, 3, 0, type, argIdx, range, analysis_manager, sdfg_, varName);
4✔
117

118
    bool isRead = range ? range->saw_read() : true;
4✔
119
    bool isWritten = range ? range->saw_write() : true;
4✔
120

121
    if (dimCount == 0) {
4✔
122
        plan.emplace_back(isRead, false, CaptureVarType::CapRaw, argIdx, isExternal, innerPrim);
2✔
123
    } else if (dimCount == 1) {
4✔
124
        plan.emplace_back(isRead, isWritten, CaptureVarType::Cap1D, argIdx, isExternal, innerPrim, dims[0]);
1✔
125
    } else if (dimCount == 2) {
2✔
126
        plan.emplace_back(isRead, isWritten, CaptureVarType::Cap2D, argIdx, isExternal, innerPrim, dims[0], dims[1]);
1✔
127
    } else if (dimCount == 3) {
1✔
128
        plan.emplace_back(
×
129
            isRead, isWritten, CaptureVarType::Cap3D, argIdx, isExternal, innerPrim, dims[0], dims[1], dims[2]
×
130
        );
131
    } else {
×
132
        return false;
×
133
    }
134

135
    return true;
4✔
136
}
4✔
137

138
std::unique_ptr<std::vector<CaptureVarPlan>> CodeGenerator::create_capture_plans() {
1✔
139
    auto name = sdfg_.name();
1✔
140

141
    analysis::AnalysisManager analysis_manager(sdfg_);
1✔
142
    const auto& args = sdfg_.arguments();
1✔
143
    auto& exts = sdfg_.externals();
1✔
144
    const auto& ranges = analysis_manager.get<analysis::MemAccessRanges>();
1✔
145

146
    auto plan = std::make_unique<std::vector<CaptureVarPlan>>();
1✔
147

148
    bool working = true;
1✔
149

150
    int argIdx = -1;
1✔
151
    for (auto& argName : args) {
3✔
152
        ++argIdx;
2✔
153

154
        working &= add_capture_plan(argName, argIdx, false, *plan.get(), ranges);
2✔
155
    }
156

157
    for (auto& argName : exts) {
3✔
158
        ++argIdx;
2✔
159

160
        working &= add_capture_plan(argName, argIdx, true, *plan.get(), ranges);
2✔
161
    }
162

163
    if (!working) {
1✔
NEW
164
        std::cerr << "In '" << name << "': could not create capture plan, returning empty plan" << std::endl;
×
NEW
165
        return std::make_unique<std::vector<CaptureVarPlan>>();
×
166
    }
167

168
    return plan;
1✔
169
}
1✔
170

171
} // namespace codegen
172
} // 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