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

daisytuner / docc / 26556322966

27 May 2026 03:45PM UTC coverage: 60.869% (-0.02%) from 60.886%
26556322966

push

github

web-flow
Libnode ptr edges (#719)

Migrating SDFGs to treat pointers as inputs to libNodes / Calls as scalars.
A pointer will only appear in an output edge if its actually returned from the function (like malloc).

* Stdlib, Blas and Tensor Matmul nodes were migrated to this new format. Other, currently transitory Tensor Nodes are not yet migrated.
* DOCC version was bumped to incorporate previous docc-llvm versions (up to 0.4.0) that had been counted separately.
! Until all passes consider the use / leak of pointers as uncertainty / hiding potential writes, TensorNodes are declared as general side-effect.
* Lots of utility functions to centralize the creation (and edges) of various libNodes that needed to be changed.
* Fixed & unified docc paths across python and llvm front-ends.
* Skip BlockFusion test that fails to its libNodes currently having side effects
~ Prevent a crash in DotViz when using symbolic offsets into structs
* Removing old ConstProp pass, it is not safe for the new pointer representation and should not be all too critical

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

87 existing lines in 28 files now uncovered.

35225 of 57870 relevant lines covered (60.87%)

11046.32 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