docc 0.8.3 (0d44999b)
C++ API Reference
Loading...
Searching...
No Matches
data_transfer_elimination_analysis.h
Go to the documentation of this file.
1#pragma once
2
9
10namespace sdfg::analysis {
11
13protected:
14
15public:
16 virtual void on_escape(const std::string& container, const ControlFlowNode* node, const Element* user) = 0;
17 virtual void on_write_via(const std::string& container, const ControlFlowNode* node, const data_flow::Memlet* user) = 0;
18 virtual void on_read_via(const std::string& container, const ControlFlowNode* node, const data_flow::Memlet* user) = 0;
19};
20
58
68
79
81protected:
82 std::vector<std::pair<ExposedOffload, OffloadHolder&>> transfer_reuse_candidates_;
83 std::vector<std::pair<ExposedOffload, OffloadHolder&>> empty_malloc_candidates_;
84 std::vector<std::pair<ExposedOffload, OffloadHolder&>> redundant_d2h_candidates_;
85 std::unordered_map<std::string, std::vector<DeviceFreeSite>> device_free_sites_;
86
87public:
89 transfer_reuse_candidates_.emplace_back(src, dst);
90 }
91
93 const std::string& container, structured_control_flow::Block* block, offloading::DataOffloadingNode* node
94 ) {
95 auto& sites = device_free_sites_[container];
96 for (const auto& site : sites) {
97 if (site.node == node) {
98 return; // deduplicate: the collecting visitor may see a node more than once
99 }
100 }
101 sites.push_back({block, node});
102 }
103
105 const std::vector<DeviceFreeSite>* device_frees(const std::string& container) const {
106 auto it = device_free_sites_.find(container);
107 return it == device_free_sites_.end() ? nullptr : &it->second;
108 }
109
110 void found_empty_host_malloc(const ExposedOffload& malloc, OffloadHolder& h2d_transfer) {
111 empty_malloc_candidates_.emplace_back(malloc, h2d_transfer);
112 }
113
115 redundant_d2h_candidates_.emplace_back(h2d, d2h);
116 }
117
118 const std::vector<std::pair<ExposedOffload, OffloadHolder&>>& transfer_reuse_candidates() const {
120 }
121 const std::vector<std::pair<ExposedOffload, OffloadHolder&>>& empty_malloc_candidates() const {
123 }
124 const std::vector<std::pair<ExposedOffload, OffloadHolder&>>& redundant_d2h_candidates() const {
126 }
127};
128
129struct OffloadState : public ElementIdMapDataFlowState<ExposedOffload, OffloadHolder> {
130protected:
136 std::unordered_set<std::string> kills_containers_;
141 std::unordered_map<ElementId, std::unique_ptr<OffloadHolder>> h2d_nodes_;
142 std::unordered_map<ElementId, std::unique_ptr<OffloadHolder>> generated_;
143 std::unordered_map<std::string, std::vector<const data_flow::Memlet*>> reads_;
144 bool full_kill_ = false;
146
147 enum class KillingType {
148 // No match
150 // kill the current node from live-set
152 // the killing node is a H2D after a D2H of same data -> can elide H2D
154 // the killing node is a H2D with alloc that is the first use of host malloc. Can elide H2D
156 // the killing node is a device free of a device alloc of clean data -> can treat it similar to D2H
158 // the killing node is a D2H matching a H2D, but the on-device data has not changed in between: the host data is
159 // already up-to-date
161 };
162
163public:
165 void apply_kills_and_changes(ExposedType& exposed) const override;
166
167 void found_escape(const std::string& container);
170 void found_ptr_read(const std::string& container, const data_flow::Memlet* memlet);
171 void found_ptr_write(const std::string& container, const data_flow::Memlet* memlet);
172 void found_malloc(Block& block, stdlib::MallocNode& malloc);
173
174 void add_h2d_entry(const OffloadHolder& entry);
175
176 std::pair<KillingType, OffloadHolder*> find_killing_entry_node(const ExposedOffload& in_flight) const;
177};
178
180 public ForwardStructuredDataFlowAnalysis<OffloadState>,
181 PointerEscapeAnalyzer<ForwardingEscapePolicy>,
182 PointerUsedAnalyzer<ForwardingEscapePolicy>,
185private:
186 StructuredSDFG& sdfg_;
187 AnalysisManager& ana_;
188
189public:
193
194 void handle_lib_node(Block& block, data_flow::LibraryNode& node) override;
195
197
198 void on_escape(const std::string& container, const ControlFlowNode* node, const Element* user) override;
199 void on_write_via(const std::string& container, const ControlFlowNode* node, const data_flow::Memlet* user) override;
200 void on_read_via(const std::string& container, const ControlFlowNode* node, const data_flow::Memlet* user) override;
201
202 void use_as_return_src(const std::string& container, const Return& ret) override {
205 }
207 const std::string& container,
208 const ControlFlowNode* node,
209 const Element* user,
211 int loc_index,
213 ) override {
214 PointerEscapeAnalyzer::use_as_symbol_read(container, node, user, loc, loc_index, expr);
215 PointerUsedAnalyzer::use_as_symbol_read(container, node, user, loc, loc_index, expr);
216 }
218 const std::string& container,
219 const data_flow::AccessNode& node,
220 const data_flow::Memlet& edge,
221 const Block& block
222 ) override {
223 PointerEscapeAnalyzer::use_as_src_node(container, node, edge, block);
224 PointerUsedAnalyzer::use_as_src_node(container, node, edge, block);
225 }
227 const std::string& container,
228 const data_flow::AccessNode& node,
229 const data_flow::Memlet& edge,
230 const Block& block
231 ) override {
232 PointerEscapeAnalyzer::use_as_dst_node(container, node, edge, block);
233 PointerUsedAnalyzer::use_as_dst_node(container, node, edge, block);
234 }
236 const symbolic::Symbol& container, const ControlFlowNode* node, const Element* user, SymbolWriteLocation loc
237 ) override {
238 PointerEscapeAnalyzer::use_as_symbol_write(container, node, user, loc);
239 PointerUsedAnalyzer::use_as_symbol_write(container, node, user, loc);
240 }
241
242 std::unique_ptr<OffloadState> create_initial_state(const structured_control_flow::ControlFlowNode& node) override;
243
244 void run();
245};
246
247} // namespace sdfg::analysis
Definition element.h:159
Definition structured_sdfg.h:30
Definition analysis.h:53
void handle_structured_loop_before_body(StructuredLoop &loop) override
std::unique_ptr< OffloadState > create_initial_state(const structured_control_flow::ControlFlowNode &node) override
void on_read_via(const std::string &container, const ControlFlowNode *node, const data_flow::Memlet *user) override
void use_as_return_src(const std::string &container, const Return &ret) override
Definition data_transfer_elimination_analysis.h:202
void use_as_symbol_read(const std::string &container, const ControlFlowNode *node, const Element *user, SymbolReadLocation loc, int loc_index, symbolic::Expression expr) override
Definition data_transfer_elimination_analysis.h:206
void use_as_src_node(const std::string &container, const data_flow::AccessNode &node, const data_flow::Memlet &edge, const Block &block) override
Definition data_transfer_elimination_analysis.h:217
void on_escape(const std::string &container, const ControlFlowNode *node, const Element *user) override
void on_write_via(const std::string &container, const ControlFlowNode *node, const data_flow::Memlet *user) override
DataTransferEliminationAnalysis(StructuredSDFG &sdfg, AnalysisManager &ana)
Definition data_transfer_elimination_analysis.h:190
void use_as_symbol_write(const symbolic::Symbol &container, const ControlFlowNode *node, const Element *user, SymbolWriteLocation loc) override
Definition data_transfer_elimination_analysis.h:235
void handle_lib_node(Block &block, data_flow::LibraryNode &node) override
void use_as_dst_node(const std::string &container, const data_flow::AccessNode &node, const data_flow::Memlet &edge, const Block &block) override
Definition data_transfer_elimination_analysis.h:226
Definition data_transfer_elimination_analysis.h:80
void register_device_free(const std::string &container, structured_control_flow::Block *block, offloading::DataOffloadingNode *node)
Definition data_transfer_elimination_analysis.h:92
void found_redundant_d2h_pair(const ExposedOffload &h2d, OffloadHolder &d2h)
Definition data_transfer_elimination_analysis.h:114
void found_empty_host_malloc(const ExposedOffload &malloc, OffloadHolder &h2d_transfer)
Definition data_transfer_elimination_analysis.h:110
const std::vector< std::pair< ExposedOffload, OffloadHolder & > > & redundant_d2h_candidates() const
Definition data_transfer_elimination_analysis.h:124
std::vector< std::pair< ExposedOffload, OffloadHolder & > > empty_malloc_candidates_
Definition data_transfer_elimination_analysis.h:83
const std::vector< DeviceFreeSite > * device_frees(const std::string &container) const
All device-buffer free sites for container, or nullptr if it is never freed on device.
Definition data_transfer_elimination_analysis.h:105
const std::vector< std::pair< ExposedOffload, OffloadHolder & > > & transfer_reuse_candidates() const
Definition data_transfer_elimination_analysis.h:118
std::vector< std::pair< ExposedOffload, OffloadHolder & > > redundant_d2h_candidates_
Definition data_transfer_elimination_analysis.h:84
std::vector< std::pair< ExposedOffload, OffloadHolder & > > transfer_reuse_candidates_
Definition data_transfer_elimination_analysis.h:82
const std::vector< std::pair< ExposedOffload, OffloadHolder & > > & empty_malloc_candidates() const
Definition data_transfer_elimination_analysis.h:121
std::unordered_map< std::string, std::vector< DeviceFreeSite > > device_free_sites_
Definition data_transfer_elimination_analysis.h:85
void found_transfer_reuse_pair(const ExposedOffload &src, OffloadHolder &dst)
Definition data_transfer_elimination_analysis.h:88
Base class for forward data-flow analysis over structured control flow.
Definition structured_data_flow_analysis.h:165
Definition data_transfer_elimination_analysis.h:12
virtual void on_read_via(const std::string &container, const ControlFlowNode *node, const data_flow::Memlet *user)=0
virtual void on_write_via(const std::string &container, const ControlFlowNode *node, const data_flow::Memlet *user)=0
virtual void on_escape(const std::string &container, const ControlFlowNode *node, const Element *user)=0
PointerEscapeAnalyzer(const StructuredSDFG &sdfg, Policy &policy)
Definition pointer_analyzers.h:66
void use_as_symbol_read(const std::string &container, const ControlFlowNode *node, const Element *user, SymbolReadLocation loc, int loc_index, symbolic::Expression expr) override
Definition pointer_analyzers.h:79
void use_as_symbol_write(const symbolic::Symbol &container, const ControlFlowNode *node, const Element *user, SymbolWriteLocation loc) override
Definition pointer_analyzers.h:128
void use_as_src_node(const std::string &container, const data_flow::AccessNode &node, const data_flow::Memlet &edge, const Block &block) override
Definition pointer_analyzers.h:93
void use_as_dst_node(const std::string &container, const data_flow::AccessNode &node, const data_flow::Memlet &edge, const Block &block) override
Definition pointer_analyzers.h:121
void use_as_return_src(const std::string &container, const Return &ret) override
Definition pointer_analyzers.h:69
void use_as_return_src(const std::string &container, const Return &ret) override
Definition pointer_analyzers.h:250
PointerUsedAnalyzer(const StructuredSDFG &sdfg, Policy &policy)
Definition pointer_analyzers.h:220
void use_as_src_node(const std::string &container, const data_flow::AccessNode &node, const data_flow::Memlet &edge, const Block &block) override
Definition pointer_analyzers.h:223
void use_as_symbol_write(const symbolic::Symbol &container, const ControlFlowNode *node, const Element *user, SymbolWriteLocation loc) override
Definition pointer_analyzers.h:245
void use_as_symbol_read(const std::string &container, const ControlFlowNode *node, const Element *user, SymbolReadLocation loc, int loc_index, symbolic::Expression expr) override
Definition pointer_analyzers.h:253
void use_as_dst_node(const std::string &container, const data_flow::AccessNode &node, const data_flow::Memlet &edge, const Block &block) override
Definition pointer_analyzers.h:234
Node representing access to a data container in the dataflow graph.
Definition access_node.h:84
Base class for all library nodes in the dataflow graph.
Definition library_node.h:106
Edge in the dataflow graph representing data movement.
Definition memlet.h:131
Name does not match current function.
Definition data_offloading_node.h:49
Definition malloc.h:14
A control flow node representing a basic block with dataflow computations.
Definition block.h:42
Base class for all structured control flow nodes in a StructuredSDFG.
Definition control_flow_node.h:44
Represents a return statement that exits the function with a value.
Definition return.h:32
Base class for structured loop constructs.
Definition structured_loop.h:244
SymbolReadLocation
Definition base_user_visitor.h:13
SymbolWriteLocation
Definition base_user_visitor.h:21
Finds uses of containers.
Definition base_user_visitor.h:58
SymEngine::RCP< const SymEngine::Basic > Expression
Reference-counted pointer to a symbolic expression (SymEngine Basic).
Definition symbolic.h:83
SymEngine::RCP< const SymEngine::Symbol > Symbol
Reference-counted pointer to a SymEngine Symbol.
Definition symbolic.h:71
Library node definitions for calling functions beyond simple instructions.
Definition analysis.h:8
Definition analysis.h:7
A device-buffer deallocation site: the FREE-lifecycle offloading node together with the block it live...
Definition data_transfer_elimination_analysis.h:75
offloading::DataOffloadingNode * node
Definition data_transfer_elimination_analysis.h:77
structured_control_flow::Block * block
Definition data_transfer_elimination_analysis.h:76
Definition structured_data_flow_analysis.h:62
DataFlowState< std::unordered_map< ElementId, ExposedOffload > >::ExposedType ExposedType
Definition structured_data_flow_analysis.h:63
Definition data_transfer_elimination_analysis.h:59
ExposedOffload(OffloadHolder *offload, std::string container, int read_count=0)
Definition data_transfer_elimination_analysis.h:64
std::string container
Definition data_transfer_elimination_analysis.h:61
OffloadHolder * offload
Definition data_transfer_elimination_analysis.h:60
int read_count
Definition data_transfer_elimination_analysis.h:62
Definition data_transfer_elimination_analysis.h:21
offloading::DataOffloadingNode * offload_node
Definition data_transfer_elimination_analysis.h:22
const data_flow::AccessNode * dev_data
Definition data_transfer_elimination_analysis.h:26
OffloadHolder(offloading::DataOffloadingNode *offload_node, const data_flow::AccessNode *host_data, const data_flow::Memlet *host_access, const data_flow::AccessNode *dev_data, bool starts_dev_lifetime, bool ends_dev_lifetime, bool updates_on_dev, bool updates_on_host)
Definition data_transfer_elimination_analysis.h:32
bool updates_on_dev
Definition data_transfer_elimination_analysis.h:29
bool updates_on_host
Definition data_transfer_elimination_analysis.h:30
const data_flow::Memlet * host_access
Definition data_transfer_elimination_analysis.h:25
bool ends_dev_lifetime
Definition data_transfer_elimination_analysis.h:28
OffloadHolder(stdlib::MallocNode *malloc_node, const data_flow::AccessNode *host_data, const data_flow::Memlet *host_access)
Definition data_transfer_elimination_analysis.h:47
bool starts_dev_lifetime
Definition data_transfer_elimination_analysis.h:27
stdlib::MallocNode * malloc_node
Definition data_transfer_elimination_analysis.h:23
const data_flow::AccessNode * host_data
Definition data_transfer_elimination_analysis.h:24
std::unordered_map< ElementId, std::unique_ptr< OffloadHolder > > h2d_nodes_
All H2D offload needs.
Definition data_transfer_elimination_analysis.h:141
std::unordered_set< std::string > kills_containers_
These containers are used in a way that makes us lose track of their contents (pointer-leaks & aliasi...
Definition data_transfer_elimination_analysis.h:136
void found_offload_node(Block &block, offloading::DataOffloadingNode &offload)
void apply_kills_and_changes(ExposedType &exposed) const override
std::unordered_map< ElementId, std::unique_ptr< OffloadHolder > > generated_
Definition data_transfer_elimination_analysis.h:142
KillingType
Definition data_transfer_elimination_analysis.h:147
@ DeviceReuse
Definition data_transfer_elimination_analysis.h:153
@ EmptyHostMalloc
Definition data_transfer_elimination_analysis.h:155
@ DeviceCleanFree
Definition data_transfer_elimination_analysis.h:157
@ None
Definition data_transfer_elimination_analysis.h:149
@ RedundantD2H
Definition data_transfer_elimination_analysis.h:160
@ Basic
Definition data_transfer_elimination_analysis.h:151
OffloadState(DataTransferEliminationCandidateCollector &collector)
void found_malloc(Block &block, stdlib::MallocNode &malloc)
void found_escape(const std::string &container)
bool full_kill_
Definition data_transfer_elimination_analysis.h:144
void found_ptr_read(const std::string &container, const data_flow::Memlet *memlet)
DataTransferEliminationCandidateCollector & collector_
Definition data_transfer_elimination_analysis.h:145
void found_ptr_write(const std::string &container, const data_flow::Memlet *memlet)
void found_full_barrier(ControlFlowNode &node)
void add_h2d_entry(const OffloadHolder &entry)
std::unordered_map< std::string, std::vector< const data_flow::Memlet * > > reads_
Definition data_transfer_elimination_analysis.h:143
std::pair< KillingType, OffloadHolder * > find_killing_entry_node(const ExposedOffload &in_flight) const