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

daisytuner / docc / 26520678771

27 May 2026 03:22PM UTC coverage: 60.864% (-0.02%) from 60.886%
26520678771

Pull #719

github

web-flow
Merge 99c5e4f9d into 707dadcf8
Pull Request #719: Libnode ptr edges

961 of 1749 new or added lines in 52 files covered. (54.95%)

90 existing lines in 29 files now uncovered.

35222 of 57870 relevant lines covered (60.86%)

11043.61 hits per line

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

80.85
/opt/src/transformations/offloading/rocm_stdlib_data_transfer_extraction.cpp
1
#include "sdfg/transformations/offloading/rocm_stdlib_data_transfer_extraction.h"
2

3
#include <cassert>
4
#include <string>
5
#include <unordered_map>
6

7
#include "sdfg/analysis/analysis.h"
8
#include "sdfg/analysis/scope_analysis.h"
9
#include "sdfg/builder/structured_sdfg_builder.h"
10
#include "sdfg/data_flow/access_node.h"
11
#include "sdfg/data_flow/library_nodes/stdlib/memset.h"
12
#include "sdfg/exceptions.h"
13
#include "sdfg/structured_control_flow/block.h"
14
#include "sdfg/structured_control_flow/sequence.h"
15
#include "sdfg/symbolic/symbolic.h"
16
#include "sdfg/targets/rocm/rocm.h"
17
#include "sdfg/targets/rocm/rocm_data_offloading_node.h"
18
#include "sdfg/types/type.h"
19
#include "sdfg/types/utils.h"
20
#include "symengine/symengine_rcp.h"
21

22
namespace sdfg {
23
namespace rocm {
24

25
std::string ROCMStdlibDataTransferExtraction::create_device_container(
26
    builder::StructuredSDFGBuilder& builder, const types::Pointer& type, const symbolic::Expression& size
27
) {
2✔
28
    auto new_type = type.clone();
2✔
29
    new_type->storage_type(types::StorageType(
2✔
30
        "AMD_Generic", size, types::StorageType::AllocationType::Unmanaged, types::StorageType::AllocationType::Unmanaged
2✔
31
    ));
2✔
32
    auto device_container = builder.find_new_name(ROCM_DEVICE_PREFIX);
2✔
33
    builder.add_container(device_container, *new_type);
2✔
34
    return device_container;
2✔
35
}
2✔
36

37
void ROCMStdlibDataTransferExtraction::create_allocate(
38
    builder::StructuredSDFGBuilder& builder,
39
    structured_control_flow::Sequence& sequence,
40
    structured_control_flow::Block& block,
41
    const std::string& device_container,
42
    const symbolic::Expression& size,
43
    const types::Pointer& type
44
) {
2✔
45
    auto& alloc_block = builder.add_block_before(sequence, block, {}, block.debug_info());
2✔
46
    offloading::add_offloading_node<ROCMDataOffloadingNode>(
2✔
47
        builder,
2✔
48
        alloc_block,
2✔
49
        device_container,
2✔
50
        device_container,
2✔
51
        offloading::DataTransferDirection::NONE,
2✔
52
        offloading::BufferLifecycle::ALLOC,
2✔
53
        type,
2✔
54
        type,
2✔
55
        this->memset_node_.debug_info(),
2✔
56
        size,
2✔
57
        symbolic::zero()
2✔
58
    );
2✔
59
}
2✔
60

61
void ROCMStdlibDataTransferExtraction::create_deallocate(
62
    builder::StructuredSDFGBuilder& builder,
63
    structured_control_flow::Sequence& sequence,
64
    structured_control_flow::Block& block,
65
    const std::string& device_container,
66
    const types::Pointer& type
67
) {
×
68
    auto& dealloc_block = builder.add_block_after(sequence, block, {}, block.debug_info());
×
NEW
69
    offloading::add_offloading_node<ROCMDataOffloadingNode>(
×
NEW
70
        builder,
×
71
        dealloc_block,
×
NEW
72
        device_container,
×
NEW
73
        device_container,
×
NEW
74
        offloading::DataTransferDirection::NONE,
×
NEW
75
        offloading::BufferLifecycle::FREE,
×
NEW
76
        type,
×
NEW
77
        type,
×
78
        this->memset_node_.debug_info(),
×
79
        SymEngine::null,
×
NEW
80
        symbolic::zero()
×
81
    );
×
82
}
×
83

84
void ROCMStdlibDataTransferExtraction::create_copy_from_device_with_deallocation(
85
    builder::StructuredSDFGBuilder& builder,
86
    structured_control_flow::Sequence& sequence,
87
    structured_control_flow::Block& block,
88
    const std::string& host_container,
89
    const std::string& device_container,
90
    const symbolic::Expression& size,
91
    const types::Pointer& type
92
) {
2✔
93
    auto& copy_block = builder.add_block_after(sequence, block, {}, block.debug_info());
2✔
94
    offloading::add_offloading_node<ROCMDataOffloadingNode>(
2✔
95
        builder,
2✔
96
        copy_block,
2✔
97
        host_container,
2✔
98
        device_container,
2✔
99
        offloading::DataTransferDirection::D2H,
2✔
100
        offloading::BufferLifecycle::FREE,
2✔
101
        type,
2✔
102
        type,
2✔
103
        this->memset_node_.debug_info(),
2✔
104
        size,
2✔
105
        symbolic::zero()
2✔
106
    );
2✔
107
}
2✔
108

109
ROCMStdlibDataTransferExtraction::ROCMStdlibDataTransferExtraction(::sdfg::stdlib::MemsetNode& memset_node)
110
    : memset_node_(memset_node) {}
8✔
111

112
std::string ROCMStdlibDataTransferExtraction::name() const { return "ROCMStdlibDataTransferExtraction"; }
1✔
113

114
bool ROCMStdlibDataTransferExtraction::
115
    can_be_applied(builder::StructuredSDFGBuilder& builder, analysis::AnalysisManager& analysis_manager) {
7✔
116
    if (this->memset_node_.implementation_type().value() != rocm::ImplementationType_ROCMWithTransfers.value()) {
7✔
117
        return false;
4✔
118
    }
4✔
119

120
    // Restrict to memset nodes in their own block
121
    auto& dfg = this->memset_node_.get_parent();
3✔
122
    if (dfg.nodes().size() != dfg.in_degree(this->memset_node_) + dfg.out_degree(this->memset_node_) + 1) {
3✔
123
        return false;
×
124
    }
×
125

126
    return true;
3✔
127
}
3✔
128

129
void ROCMStdlibDataTransferExtraction::
130
    apply(builder::StructuredSDFGBuilder& builder, analysis::AnalysisManager& analysis_manager) {
2✔
131
    // Get data flow graph and block
132
    auto& dfg = this->memset_node_.get_parent();
2✔
133
    auto* block = dynamic_cast<structured_control_flow::Block*>(dfg.get_parent());
2✔
134
    assert(block);
2✔
135

136
    // Get sequence
137
    auto& scope_analysis = analysis_manager.get<analysis::ScopeAnalysis>();
2✔
138
    auto* sequence = dynamic_cast<structured_control_flow::Sequence*>(scope_analysis.parent_scope(block));
2✔
139
    assert(sequence);
2✔
140

141
    // Capture output accesses
142
    auto ptr_edge = dfg.in_edge_for_connector(this->memset_node_, "_ptr");
2✔
143
    auto& host_access_node =
2✔
144
        const_cast<data_flow::AccessNode&>(static_cast<const data_flow::AccessNode&>(ptr_edge->src()));
2✔
145
    auto& host_container_name = host_access_node.data();
2✔
146

147
    // Use the host container's actual type to avoid type mismatches
148
    auto& host_type = builder.subject().type(host_container_name);
2✔
149
    auto& type = static_cast<const types::Pointer&>(host_type);
2✔
150

151
    auto ptr_size = this->memset_node_.num();
2✔
152
    auto dPtr = this->create_device_container(builder, type, ptr_size);
2✔
153

154
    // Allocate device buffer
155
    this->create_allocate(builder, *sequence, *block, dPtr, ptr_size, type);
2✔
156

157
    // Copy from device to host and deallocate
158
    this->create_copy_from_device_with_deallocation(builder, *sequence, *block, host_container_name, dPtr, ptr_size, type);
2✔
159

160
    // Redirect output to device container
161
    host_access_node.data(dPtr);
2✔
162

163
    // Change the implementation type to without transfers
164
    this->memset_node_.implementation_type() = rocm::ImplementationType_ROCMWithoutTransfers;
2✔
165
}
2✔
166

167
void ROCMStdlibDataTransferExtraction::to_json(nlohmann::json& j) const {
1✔
168
    j["transformation_type"] = this->name();
1✔
169
    j["subgraph"] = {{"0", {{"element_id", this->memset_node_.element_id()}, {"type", "unknown"}}}};
1✔
170
    j["memset_node_element_id"] = this->memset_node_.element_id();
1✔
171
}
1✔
172

173
} // namespace rocm
174
} // 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