docc 0.8.3 (0d44999b)
C++ API Reference
Loading...
Searching...
No Matches
data_offloading_node.h
Go to the documentation of this file.
1#pragma once
2
3#include <cstddef>
4#include <string>
5#include <vector>
6
9#include "sdfg/element.h"
10#include "sdfg/graph/graph.h"
13
14namespace sdfg {
15namespace offloading {
16
17enum class DataTransferDirection : int8_t { D2H = -1, NONE = 0, H2D = 1 };
18
19constexpr bool is_D2H(const DataTransferDirection& transfer_direction) {
20 return (transfer_direction == DataTransferDirection::D2H);
21}
22
23constexpr bool is_NONE(const DataTransferDirection& transfer_direction) {
24 return (transfer_direction == DataTransferDirection::NONE);
25}
26
27constexpr bool is_H2D(const DataTransferDirection& transfer_direction) {
28 return (transfer_direction == DataTransferDirection::H2D);
29}
30
31enum class BufferLifecycle : int8_t { FREE = -1, NO_CHANGE = 0, ALLOC = 1 };
32
33constexpr bool is_FREE(const BufferLifecycle& buffer_lifecycle) {
34 return (buffer_lifecycle == BufferLifecycle::FREE);
35}
36
37constexpr bool is_NO_CHANGE(const BufferLifecycle& buffer_lifecycle) {
38 return (buffer_lifecycle == BufferLifecycle::NO_CHANGE);
39}
40
41constexpr bool is_ALLOC(const BufferLifecycle& buffer_lifecycle) {
42 return (buffer_lifecycle == BufferLifecycle::ALLOC);
43}
44
50protected:
55
56 static std::vector<std::string>
59
60public:
62 size_t element_id,
63 const DebugInfo& debug_info,
70 );
71
77 size_t element_id,
78 const DebugInfo& debug_info,
82 const std::vector<std::string>& outputs,
83 const std::vector<std::string>& inputs,
87 );
88
91
92 int host_ptr_input_idx() const;
93 int dev_ptr_input_idx() const;
94 int dev_ptr_output_idx() const;
95
96 const std::string& dev_in_conn() const;
97 const std::string& dev_out_conn() const;
98 const std::string& host_in_conn() const;
99
102
103 virtual const symbolic::Expression alloc_size() const;
104
105 symbolic::SymbolSet symbols() const override;
106
107 void replace(const symbolic::Expression old_expression, const symbolic::Expression new_expression) override;
108
109 virtual symbolic::Expression flop() const override;
110
111 virtual std::string toStr() const override;
112
116 virtual bool is_compatible_with(const DataOffloadingNode& other) const;
117
121 virtual bool redundant_with(const DataOffloadingNode& other) const;
122
126 virtual bool equal_with(const DataOffloadingNode& other) const;
127
128 virtual bool is_same_target(const DataOffloadingNode& other) const = 0;
129
130 virtual bool blocking() const = 0;
131
132 bool is_d2h() const;
133 bool is_h2d() const;
134 bool has_transfer() const;
135
136 bool is_free() const;
137 bool is_alloc() const;
138
140
143
145
148
151
152 bool update_edge_removed(const std::string& out_conn) override;
153};
154
155template<typename NodeT, typename... Args>
158 Block& block,
159 const std::string& host_container,
160 const std::string& dev_container,
161 DataTransferDirection direction,
162 BufferLifecycle lifecycle,
163 const types::IType& host_type,
164 const types::IType& dev_type,
165 DebugInfo debug_info = DebugInfo(),
166 Args&&... args
167) {
168 std::optional<std::string> host_input_container;
169 std::optional<std::string> dev_input_container;
170 std::optional<std::string> output_container;
171
172 if (is_H2D(direction) && !is_ALLOC(lifecycle)) {
173 host_input_container = host_container;
174 dev_input_container = dev_container;
175 } else if (is_H2D(direction) && is_ALLOC(lifecycle)) {
176 host_input_container = host_container;
177 } else if (!is_NONE(direction)) {
178 host_input_container = host_container;
179 dev_input_container = dev_container;
180 } else if (is_FREE(lifecycle)) {
181 dev_input_container = dev_container;
182 }
183
184 if (is_ALLOC(lifecycle)) {
185 output_container = dev_container;
186 }
187
188 data_flow::AccessNode* host_in_access = nullptr;
189 if (host_input_container) {
190 host_in_access = &builder.add_access(block, host_input_container.value());
191 }
192 data_flow::AccessNode* dev_in_access = nullptr;
193 if (dev_input_container) {
194 dev_in_access = &builder.add_access(block, dev_input_container.value());
195 }
196 data_flow::AccessNode* out_access = nullptr;
197 if (output_container) {
198 out_access = &builder.add_access(block, output_container.value());
199 }
200 auto& libnode =
201 builder.template add_library_node<NodeT>(block, debug_info, direction, lifecycle, std::forward<Args>(args)...);
202
203 if (host_in_access) {
204 builder.add_computational_memlet(block, *host_in_access, libnode, "_hst", {}, host_type);
205 }
206 if (dev_in_access) {
207 builder.add_computational_memlet(block, *dev_in_access, libnode, "_dev", {}, dev_type);
208 }
209 if (out_access) {
210 builder.add_computational_memlet(block, libnode, "_dev", *out_access, {}, dev_type);
211 }
212
213 return libnode;
214}
215
216template<typename NodeT, typename... Args>
217std::tuple<structured_control_flow::Block&, data_flow::LibraryNode&> add_offloading_block(
219 Sequence& parent,
220 const std::string& host_container,
221 const std::string& dev_container,
222 DataTransferDirection direction,
223 BufferLifecycle lifecycle,
224 const types::IType& data_type,
225 DebugInfo debug_info = DebugInfo(),
226 Args&&... args
227) {
228 auto& block = builder.add_block(parent);
229
230 auto& libnode = add_offloading_node<NodeT>(
231 builder,
232 block,
233 host_container,
234 dev_container,
235 direction,
236 lifecycle,
237 data_type,
238 data_type,
239 debug_info,
240 std::forward<Args>(args)...
241 );
242
243 return {block, libnode};
244}
245
247public:
248 nlohmann::json serialize(const sdfg::data_flow::LibraryNode& library_node) override;
249
250 template<typename NodeT, typename BuilderT, typename... Args>
252 const nlohmann::json& j, BuilderT& builder, structured_control_flow::Block& parent, Args&&... args
253 ) {
255 DebugInfo debug_info = serializer.json_to_debug_info(j["debug_info"]);
256
258 if (!j.contains("size") || j.at("size").is_null()) {
259 size = SymEngine::null;
260 } else {
261 size = symbolic::parse(j.at("size"));
262 }
263 auto transfer_direction = static_cast<offloading::DataTransferDirection>(j["transfer_direction"].get<int8_t>());
264 auto buffer_lifecycle = static_cast<offloading::BufferLifecycle>(j["buffer_lifecycle"].get<int8_t>());
265
266 return builder.template add_library_node<
267 NodeT>(parent, debug_info, transfer_direction, buffer_lifecycle, size, std::forward<Args>(args)...);
268 }
269};
270
271} // namespace offloading
272} // namespace sdfg
Definition element.h:30
size_t element_id() const
const DebugInfo & debug_info() const
Note: Even though the class references unique_ptr, it will never delete an SDFG it has a reference to...
Definition structured_sdfg_builder.h:44
Node representing access to a data container in the dataflow graph.
Definition access_node.h:84
const std::vector< std::string > & outputs() const
Get output connector names (const).
const std::vector< std::string > & inputs() const
Get input connector names (const).
Definition data_flow_graph.h:29
graph::Vertex vertex() const
Get the graph vertex for this node.
Base class for all library nodes in the dataflow graph.
Definition library_node.h:106
const LibraryNodeCode & code() const
Get the operation code.
Edge in the dataflow graph representing data movement.
Definition memlet.h:131
Definition data_offloading_node.h:246
static data_flow::LibraryNode & deserialize_generic_offload(const nlohmann::json &j, BuilderT &builder, structured_control_flow::Block &parent, Args &&... args)
Definition data_offloading_node.h:251
nlohmann::json serialize(const sdfg::data_flow::LibraryNode &library_node) override
Serialize a library node to JSON.
symbolic::Expression size_
In Bytes.
Definition data_offloading_node.h:54
virtual std::string toStr() const override
Convert node to string representation.
virtual bool redundant_with(const DataOffloadingNode &other) const
The 2 nodes are opposites of each other that could cancel each other out.
virtual const symbolic::Expression alloc_size() const
void replace(const symbolic::Expression old_expression, const symbolic::Expression new_expression) override
BufferLifecycle buffer_lifecycle_
Definition data_offloading_node.h:52
void set_size(const symbolic::Expression &size)
const symbolic::Expression size() const
static std::vector< std::string > input_conns(DataTransferDirection transfer_direction, BufferLifecycle buffer_lifecycle)
DataOffloadingNode(size_t element_id, const DebugInfo &debug_info, const graph::Vertex vertex, data_flow::DataFlowGraph &parent, const data_flow::LibraryNodeCode code, DataTransferDirection transfer_direction, BufferLifecycle buffer_lifecycle, symbolic::Expression size)
DataOffloadingNode(size_t element_id, const DebugInfo &debug_info, const graph::Vertex vertex, data_flow::DataFlowGraph &parent, const data_flow::LibraryNodeCode code, const std::vector< std::string > &outputs, const std::vector< std::string > &inputs, DataTransferDirection transfer_direction, BufferLifecycle buffer_lifecycle, symbolic::Expression size)
Allows to manually override the connector names for subclasses.
data_flow::EdgeRemoveOption can_remove_out_edge(const data_flow::DataFlowGraph &graph, const data_flow::Memlet *memlet) const override
Is the edge in question removable, or will this make the node its an output on invalid?
virtual bool is_same_target(const DataOffloadingNode &other) const =0
virtual symbolic::Expression flop() const override
Calculate floating point operations for this node.
const std::string & dev_in_conn() const
bool update_edge_removed(const std::string &out_conn) override
virtual bool is_compatible_with(const DataOffloadingNode &other) const
Checks that the nodes operate on the same device and compatible data.
const std::string & host_in_conn() const
const std::string & dev_out_conn() const
virtual bool equal_with(const DataOffloadingNode &other) const
The 2 nodes do the same thing.
DataTransferDirection transfer_direction() const
BufferLifecycle buffer_lifecycle() const
data_flow::EdgeRemoveOption can_remove_in_edge(const data_flow::DataFlowGraph &graph, const data_flow::Memlet *memlet) const override
DataTransferDirection transfer_direction_
Definition data_offloading_node.h:51
virtual bool blocking() const =0
symbolic::SymbolSet symbols() const override
Get all symbols used in this node.
static std::vector< std::string > output_conns(DataTransferDirection transfer_direction, BufferLifecycle buffer_lifecycle)
data_flow::PointerAccessType pointer_access_type(int input_idx) const override
Describes what a pointer is used for.
Definition json_serializer.h:22
Base class for library node serialization.
Definition json_serializer.h:195
A control flow node representing a basic block with dataflow computations.
Definition block.h:42
A sequential container of control flow nodes.
Definition sequence.h:52
Abstract base interface for all types in the sdfglib type system.
Definition type.h:625
Expression parse(const std::string &expr_str)
Parses a string into a symbolic expression.
SymEngine::RCP< const SymEngine::Basic > Expression
Reference-counted pointer to a symbolic expression (SymEngine Basic).
Definition symbolic.h:83
std::set< Symbol, SymEngine::RCPBasicKeyLess > SymbolSet
Ordered set of symbols.
Definition symbolic.h:95
Library node definitions for calling functions beyond simple instructions.
Definition function_builder.h:10
EdgeRemoveOption
Definition data_flow_node.h:71
StringEnum LibraryNodeCode
Definition library_node.h:65
std::unique_ptr< PointerAccessMeta, PtrAccessDeleter > PointerAccessType
Definition pointer_metadata.h:32
Definition graph.h:22
boost::graph_traits< Graph >::vertex_descriptor Vertex
Definition graph.h:25
Definition data_offloading_node.h:15
constexpr bool is_NO_CHANGE(const BufferLifecycle &buffer_lifecycle)
Definition data_offloading_node.h:37
constexpr bool is_FREE(const BufferLifecycle &buffer_lifecycle)
Definition data_offloading_node.h:33
constexpr bool is_H2D(const DataTransferDirection &transfer_direction)
Definition data_offloading_node.h:27
data_flow::LibraryNode & add_offloading_node(builder::StructuredSDFGBuilder &builder, Block &block, const std::string &host_container, const std::string &dev_container, DataTransferDirection direction, BufferLifecycle lifecycle, const types::IType &host_type, const types::IType &dev_type, DebugInfo debug_info=DebugInfo(), Args &&... args)
Definition data_offloading_node.h:156
constexpr bool is_D2H(const DataTransferDirection &transfer_direction)
Definition data_offloading_node.h:19
DataTransferDirection
Definition data_offloading_node.h:17
@ D2H
Definition data_offloading_node.h:17
@ H2D
Definition data_offloading_node.h:17
@ NONE
Definition data_offloading_node.h:17
constexpr bool is_ALLOC(const BufferLifecycle &buffer_lifecycle)
Definition data_offloading_node.h:41
BufferLifecycle
Definition data_offloading_node.h:31
@ NO_CHANGE
Definition data_offloading_node.h:31
@ ALLOC
Definition data_offloading_node.h:31
@ FREE
Definition data_offloading_node.h:31
constexpr bool is_NONE(const DataTransferDirection &transfer_direction)
Definition data_offloading_node.h:23
std::tuple< structured_control_flow::Block &, data_flow::LibraryNode & > add_offloading_block(builder::StructuredSDFGBuilder &builder, Sequence &parent, const std::string &host_container, const std::string &dev_container, DataTransferDirection direction, BufferLifecycle lifecycle, const types::IType &data_type, DebugInfo debug_info=DebugInfo(), Args &&... args)
Definition data_offloading_node.h:217
Definition cutout_serializer.h:13
Definition analysis.h:7
Symbolic system for integer-based symbol analysis.