From 3c36c8a526035b25cf6eba49bcfff8b7cc89d717 Mon Sep 17 00:00:00 2001 From: lichun Date: Sun, 25 Apr 2021 09:21:54 +0800 Subject: [PATCH 1/5] mark attr distance --- ge/graph/build/memory/block_mem_assigner.cc | 15 +- ge/graph/build/memory/block_mem_assigner.h | 2 + ge/graph/build/memory/graph_mem_assigner.cc | 251 ++++++++++++++++++++++++++++ ge/graph/build/memory/graph_mem_assigner.h | 7 + ge/graph/build/memory/memory_assigner.cc | 2 + 5 files changed, 275 insertions(+), 2 deletions(-) diff --git a/ge/graph/build/memory/block_mem_assigner.cc b/ge/graph/build/memory/block_mem_assigner.cc index 9825d1ed..23d53118 100755 --- a/ge/graph/build/memory/block_mem_assigner.cc +++ b/ge/graph/build/memory/block_mem_assigner.cc @@ -431,7 +431,7 @@ void SetLastUsedInputMemAttr(NodePtr &node, int input_index) { auto node_op_desc = node->GetOpDesc(); if (node_op_desc != nullptr) { auto input_desc = node_op_desc->MutableInputDesc(input_index); - if (!ge::AttrUtils::SetInt(*input_desc, ATTR_NAME_IS_END_OF_INPUTMEM_LIFECYCLE, true)) { + if (!ge::AttrUtils::SetBool(*input_desc, ATTR_NAME_IS_END_OF_INPUTMEM_LIFECYCLE, true)) { GELOGW("Set %s input[%d] ATTR_NAME_IS_END_OF_INPUTMEM_LIFECYCLE to true failed.", node_op_desc->GetName().c_str(), input_index); return; @@ -1493,8 +1493,8 @@ void BlockMemAssigner::ReleaseMemory(MemoryBlock *to_release, vectorref_count_ <= 0, return, "Release memory"); - GE_CHK_TRUE_EXEC_INFO(!to_release->reuse_mem_, return, "doesn't reuse memory"); --to_release->ref_count_; + GE_CHK_TRUE_EXEC_INFO(!to_release->reuse_mem_, return, "doesn't reuse memory"); if (!same_stream) { to_release->same_stream_ = false; } @@ -2160,6 +2160,17 @@ void BlockMemAssigner::SetOpMemOffset(bool is_zero_copy) { } } +size_t BlockMemAssigner::GetAnchorDataOffset(const NodeIndexIO &node_index_io, std::string &symbol) { + MemoryBlock *mem_block = nullptr; + if (IsSymbolExist(node_index_io, symbol)) { + mem_block = symbol_blocks_[symbol]; + if (mem_block != nullptr) { + return mem_block->HeadOffset(); + } + } + return kInvalidOffset; +} + Status BlockMemAssigner::Assign() { vector ranges; if (GetMemoryRanges(ranges) != SUCCESS) { diff --git a/ge/graph/build/memory/block_mem_assigner.h b/ge/graph/build/memory/block_mem_assigner.h index 474db17c..7f23cb89 100755 --- a/ge/graph/build/memory/block_mem_assigner.h +++ b/ge/graph/build/memory/block_mem_assigner.h @@ -239,6 +239,8 @@ class BlockMemAssigner : public MemAssigner { void SetOpMemOffset(bool is_zero_copy); std::string GetMaxBatchLabel() const { return max_batch_label_; } + + size_t GetAnchorDataOffset(const NodeIndexIO &node_index_io, std::string &symbol); protected: /// /// @ingroup domi diff --git a/ge/graph/build/memory/graph_mem_assigner.cc b/ge/graph/build/memory/graph_mem_assigner.cc index 1824b913..8a225d50 100755 --- a/ge/graph/build/memory/graph_mem_assigner.cc +++ b/ge/graph/build/memory/graph_mem_assigner.cc @@ -36,6 +36,8 @@ namespace { const int kAllInputAddrIsAtomic = -1; const int kVirtualInputNodeMemoryReuse = 0; const int kVirtualOutputNodeMemoryReuse = 1; +const int64_t kInvalidStream = -1; +const char *const kEngineNameGeLocal = "DNN_VM_GE_LOCAL_OP_STORE"; // One state per bit cannot be repeated enum ContinuousType { kTypeInput = 1, kTypeInputNoPadding = 2, kTypeOutput = 4, kTypeOutputNoPadding = 8 }; @@ -1935,4 +1937,253 @@ Status GraphMemoryAssigner::AssignBufferPoolMemory() { compute_graph_->GetName().c_str(), mem_type, buffer_pool_mem_assigner.GetMemOffset()); return SUCCESS; } + +static bool IsOutputVisitedByMultiStream(const NodePtr &peer_out_node, int64_t out_anchor_index) { + GE_IF_BOOL_EXEC(peer_out_node->GetOpDesc() == nullptr, return true); + int64_t unique_stream_id = peer_out_node->GetOpDesc()->GetStreamId(); + + GE_IF_BOOL_EXEC(peer_out_node->GetOutDataAnchor(out_anchor_index) == nullptr, return true); + for (const auto &in_data_anchor : peer_out_node->GetOutDataAnchor(out_anchor_index)->GetPeerInDataAnchors()) { + auto node = in_data_anchor->GetOwnerNode(); + GE_IF_BOOL_EXEC(node == nullptr || node->GetOpDesc() == nullptr, continue); + if (node->GetOpDesc()->GetStreamId() == kInvalidStream) { + continue; + } + if (unique_stream_id == kInvalidStream) { + unique_stream_id = node->GetOpDesc()->GetStreamId(); + continue; + } + if (node->GetOpDesc()->GetStreamId() != unique_stream_id) { + return true; + } + } + return false; +} + +static void UpdatePrevNodeInputDesc(const NodePtr &prev_node, + const vector &prev_node_input_index_vec, + int64_t distance) { + GE_IF_BOOL_EXEC(prev_node == nullptr, return); + auto prev_node_op_desc = prev_node->GetOpDesc(); + GE_IF_BOOL_EXEC(prev_node_op_desc == nullptr, return); + + for (const auto prev_node_input_index : prev_node_input_index_vec) { + auto input_desc = prev_node_op_desc->GetInputDesc(prev_node_input_index); + vector prev_next_distances; + if (!ge::AttrUtils::GetListInt(input_desc, ATTR_NAME_DATA_VISIT_DISTANCE, prev_next_distances)) { + GELOGW("Get [%s] input [%lld] ATTR_NAME_DATA_VISIT_DISTANCE failed", + prev_node_op_desc->GetName().c_str(), + prev_node_input_index); + continue; + } + + if (prev_next_distances.size() == 2) { + prev_next_distances[1] = distance; + } else { + GELOGW("Size of prev_next_distances is not 2."); + continue; + } + if (!ge::AttrUtils::SetListInt(input_desc, ATTR_NAME_DATA_VISIT_DISTANCE, prev_next_distances)) { + GELOGW("Set [%s] input [%lld] ATTR_NAME_DATA_VISIT_DISTANCE failed.", + prev_node_op_desc->GetName().c_str(), + prev_node_input_index); + continue; + } + + if (prev_node_op_desc->UpdateInputDesc(prev_node_input_index, input_desc) != GRAPH_SUCCESS) { + GELOGW("Update [%s] input [%lld] ATTR_NAME_DATA_VISIT_DISTANCE failed.", + prev_node_op_desc->GetName().c_str(), + prev_node_input_index); + continue; + } + GELOGD("Set the next distance[%lld] to node[%s], input index[%lld]", + distance, + prev_node->GetName().c_str(), + prev_node_input_index); + } +} + +static void UpdateCurNodeInputIndex(const NodePtr &cur_node, int64_t cur_node_input_index, int64_t distance) { + GE_IF_BOOL_EXEC(cur_node == nullptr, return); + GE_IF_BOOL_EXEC(cur_node->GetOpDesc() == nullptr, return); + auto input_desc = cur_node->GetOpDesc()->GetInputDesc(cur_node_input_index); + vector prev_next_distances{distance, -1}; + + if (!ge::AttrUtils::SetListInt(input_desc, ATTR_NAME_DATA_VISIT_DISTANCE, prev_next_distances)) { + GELOGW("Update[%s] input[%lld] ATTR_NAME_DATA_VISIT_DISTANCE failed.", + cur_node->GetOpDesc()->GetName().c_str(), + cur_node_input_index); + return; + } + if (cur_node->GetOpDesc()->UpdateInputDesc(cur_node_input_index, input_desc) != GRAPH_SUCCESS) { + GELOGW("Update[%s] input[%lld] ATTR_NAME_DATA_VISIT_DISTANCE failed.", + cur_node->GetOpDesc()->GetName().c_str(), + cur_node_input_index); + return; + } + GELOGD("Set the prev distance[%lld] to node[%s], input index[%lld]", + distance, + cur_node->GetName().c_str(), + cur_node_input_index); + return; +} + +void GraphMemoryAssigner::MarkNodeDistanceAttr(const ComputeGraphPtr &compute_graph, + NodePtr &node, + map>> &mem_block_visit_info, + const map &node_index_in_stream) { + GELOGD("cur node name is [%s]", node->GetName().c_str()); + GE_IF_BOOL_EXEC(node == nullptr, return); + for (const auto &in_data_anchor : node->GetAllInDataAnchors()) { + auto peer_out_anchor = in_data_anchor->GetPeerOutAnchor(); + GE_IF_BOOL_EXEC(peer_out_anchor == nullptr, continue); + auto peer_out_node = peer_out_anchor->GetOwnerNode(); + GE_IF_BOOL_EXEC(peer_out_node == nullptr, continue); + GELOGD("cur node[%s], cur in_data_anchor[%d], peer_out_node[%s]", + node->GetName().c_str(), + in_data_anchor->GetIdx(), + peer_out_node->GetName().c_str()); + + // find cur peer_out_node's peer_out_anchor->GetIdx()-th mem_offset(start mem offset) + NodeIndexIO node_index_io(peer_out_node, peer_out_anchor->GetIdx(), kOut); + std::string symbol; + size_t matched_mem_offset = mem_assigner_->GetPriorityAssinger()->GetAnchorDataOffset(node_index_io, symbol); + if (matched_mem_offset != kInvalidOffset) { + GELOGD("matched_mem_offset is [%zu], and new method's matched_mem_offset is [%zu], peer_out_node is [%s]", + matched_mem_offset, + peer_out_node->GetOpDesc()->GetOutputOffset().at(peer_out_anchor->GetIdx()), + peer_out_node->GetName().c_str()); + } else { // peer_out_anchor not assign MemoryBlock, we search the peer_out_anchor's data in continous memory + matched_mem_offset = peer_out_node->GetOpDesc()->GetOutputOffset().at(peer_out_anchor->GetIdx()); + } + GELOGD("final matched_mem_offset is [%zu]", matched_mem_offset); + + auto iter = mem_block_visit_info.find(matched_mem_offset); + if (iter == mem_block_visit_info.end()) { // cannot find visit info, peer_out_node must be a producer and this data is the first time to be visited. + GELOGD("iter == mem_block_visit_info.end() !!!"); + if (IsOutputVisitedByMultiStream(peer_out_node, peer_out_anchor->GetIdx())) { // 生产者的输出多流访问或者生产者在某条流上,但是不在cur_node所在的这条流上 + vector temp; + mem_block_visit_info.insert(std::make_pair(matched_mem_offset, std::make_pair(nullptr, temp))); + GELOGD("IsOutputVistedByMultiStream is true, peer_out_node is [%s], stream_id [%d], cur node is [%s], in_data_anchor_index is[%zu], stream_id[%d]", + peer_out_node->GetName().c_str(), + peer_out_node->GetOpDesc()->GetStreamId(), + node->GetName().c_str(), + in_data_anchor->GetIdx(), + node->GetOpDesc()->GetStreamId()); + continue; + } else { // 生产者和消费者都在同一条流上,或者所有消费者都在同一条流上且生产者未分配流 + GELOGD("IsOutputVisitedByMultiStream is false."); + vector temp = {-1}; + mem_block_visit_info.insert(std::make_pair(matched_mem_offset, std::make_pair(peer_out_node, temp))); //数据生产者的prev_node_index设置成-1 + } + } else { // 如果在访问信息中找到了对应的offset,此时需要判断当前的输出节点和访问信息中的那个节点是否在同一个stream上,如果不在同一个stream上就不计算距离 + if (mem_block_visit_info[matched_mem_offset].first == nullptr) { + continue; + } + if (peer_out_node->GetOpDesc()->GetStreamId() != mem_block_visit_info[matched_mem_offset].first->GetOpDesc()->GetStreamId()) { + GELOGD("lckey, cur node[%s], peer_out_node[%s] not in the same stream with node[%s] in visit info.", + node->GetName().c_str(), + peer_out_node->GetName().c_str(), + mem_block_visit_info[matched_mem_offset].first->GetName().c_str()); + continue; + } + } + + // now mem_block_visit_info must contains that memory_block + // 1. calculate distance, update visit info, update prev_node input desc, update cur node input desc + int64_t distance = -1; + auto prev_node = mem_block_visit_info[matched_mem_offset].first; + auto prev_node_input_index_vec = mem_block_visit_info[matched_mem_offset].second; + GE_IF_BOOL_EXEC(prev_node == nullptr, continue); // 生产者的输出多流访问或者生产者在某条流上,但是不在cur node所在的这条流上 + if (prev_node_input_index_vec.size() == 1 && prev_node_input_index_vec[0] == -1) { // prev_node是生产者且数据刚刚被生产出来(还没被其他节点访问过) + GE_IF_BOOL_EXEC(prev_node->GetOpDesc() == nullptr, continue); + if (prev_node->GetOpDesc()->GetStreamId() == -1) { // 生产者未分配stream + distance = 0; + } else if (node_index_in_stream.find(prev_node->GetName()) == node_index_in_stream.end()) { + distance = 0; + } else { + distance = node_index_in_stream.at(node->GetName()) - node_index_in_stream.at(prev_node->GetName()) - 1; + } + // 不需要更新prev_node的input desc(因为prev_node设定的input index=-1, 设也设不上去),只需要后面刷一把自己的input_desc即可 + // 更新访问信息 + mem_block_visit_info[matched_mem_offset].first = node; + mem_block_visit_info[matched_mem_offset].second.clear(); + mem_block_visit_info[matched_mem_offset].second.push_back(in_data_anchor->GetIdx()); + } else { + if (prev_node_input_index_vec.empty()) { + GELOGW("Missing prev node[%s] input index.", prev_node->GetName().c_str()); + continue; + } + + if (prev_node == node) { // scene: multiple anchors of a node access the same data + vector prev_next_distances; + // 1. do not need to update prev_node's input desc, because it must be updated when the first anchor visit it. + // 2. we use the same distance of previous anchor to keep this value the same. + // 3. update visit info's prev_node_input_index_vec + if (prev_node->GetOpDesc() == nullptr) { + continue; + } + auto input_desc = prev_node->GetOpDesc()->GetInputDesc(prev_node_input_index_vec[0]); + if (!ge::AttrUtils::GetListInt(input_desc, ATTR_NAME_DATA_VISIT_DISTANCE, prev_next_distances)) { + GELOGW("Get ATTR_NAME_DATA_VISIT_DISTANCE failed."); + continue; + } + if (prev_next_distances.size() != 2) { + GELOGW("Size of prev_next_distance is not 2."); + continue; + } else { + distance = prev_next_distances[0]; //use the same prev_distance of previous anchor + } + mem_block_visit_info[matched_mem_offset].second.push_back(in_data_anchor->GetIdx()); + } else { + // 走到此处,prev_node必然是访问者,如果cur node和prev node这两个访问者不在同一条流上,那么之前在IsOutputVisitedByMultiStream是就应该continue了,而不会走到这 + distance = node_index_in_stream.at(node->GetName()) - node_index_in_stream.at(prev_node->GetName()) - 1; + UpdatePrevNodeInputDesc(prev_node, prev_node_input_index_vec, distance); + mem_block_visit_info[matched_mem_offset].first = node; + mem_block_visit_info[matched_mem_offset].second.clear(); + mem_block_visit_info[matched_mem_offset].second.push_back(in_data_anchor->GetIdx()); + } + } + UpdateCurNodeInputIndex(node, in_data_anchor->GetIdx(), distance); + + auto input_desc = node->GetOpDesc()->GetInputDesc(in_data_anchor->GetIdx()); + bool is_end_of_inputmem_lifecycle = false; + + // if is_end_of_inputmem_lifecycle is true, indicating that cur node is the last customer of this data, + // then we need to delete the visit info of the block in case that the memblock be reused and visited. + if (ge::AttrUtils::GetBool(input_desc, ATTR_NAME_IS_END_OF_INPUTMEM_LIFECYCLE, is_end_of_inputmem_lifecycle) && + is_end_of_inputmem_lifecycle) { + GELOGD("ATTR_NAME_IS_END_OF_INPUTMEM_LIFECYCLE is true"); + auto iter2 = mem_block_visit_info.find(matched_mem_offset); + if (iter2 != mem_block_visit_info.end()) { + mem_block_visit_info.erase(iter2); + } + } + } +} + +void GraphMemoryAssigner::MarkDistanceAttr() { + map>> mem_block_visit_info; // key: mem_offset of the memory which we visited. value: node we visited and input index of this node + map node_index_in_stream; // key: node name, value: topo order of node in it's belonged stream(exclude ge_local_op) + map stream_nodes_num; // key: stream id, value: cur nodes num in that stream + + for (auto &node : compute_graph_->GetAllNodes()) { + auto node_op_desc = node->GetOpDesc(); + GE_IF_BOOL_EXEC(node_op_desc == nullptr, return); + + int64_t stream_id = node_op_desc->GetStreamId(); + if (node_op_desc->GetOpKernelLibName() != kEngineNameGeLocal) { + if (stream_nodes_num.find(stream_id) == stream_nodes_num.end()) { + stream_nodes_num.insert(std::make_pair(stream_id, 1)); + } else { + ++stream_nodes_num[stream_id]; + } + node_index_in_stream.insert(std::make_pair(node->GetName(), stream_nodes_num[stream_id] - 1)); + + MarkNodeDistanceAttr(compute_graph_, node, mem_block_visit_info, node_index_in_stream); + } else { + GELOGD("in GraphMemoryAssigner::MarkDistanceAttr, node[%s] is ge_local_op", node->GetName().c_str()); + } + } +} } // namespace ge diff --git a/ge/graph/build/memory/graph_mem_assigner.h b/ge/graph/build/memory/graph_mem_assigner.h index 33a5b6d3..04c21a3f 100755 --- a/ge/graph/build/memory/graph_mem_assigner.h +++ b/ge/graph/build/memory/graph_mem_assigner.h @@ -118,6 +118,13 @@ class GraphMemoryAssigner { ge::Status AssignReferenceMemory(); + void MarkDistanceAttr(); + + void MarkNodeDistanceAttr(const ComputeGraphPtr &compute_graph, + NodePtr &node, + map>> &mem_block_visit_info, + const map &node_index_in_stream); + private: /// /// @ingroup ge_graph diff --git a/ge/graph/build/memory/memory_assigner.cc b/ge/graph/build/memory/memory_assigner.cc index 0f58a040..d074fce0 100755 --- a/ge/graph/build/memory/memory_assigner.cc +++ b/ge/graph/build/memory/memory_assigner.cc @@ -65,6 +65,8 @@ Status MemoryAssigner::AssignMemory(bool is_loop_graph, map &me GELOGE(FAILED, "CheckOffset Fail!"); return FAILED; } + + graph_mem_assigner.MarkDistanceAttr(); return SUCCESS; } } // namespace ge From a023b0c465c1659d28005f499f8e1802b11d3fd1 Mon Sep 17 00:00:00 2001 From: lichun Date: Sun, 25 Apr 2021 15:35:57 +0800 Subject: [PATCH 2/5] mark attr distance --- ge/graph/build/memory/graph_mem_assigner.cc | 91 +++++++++++++---------------- 1 file changed, 40 insertions(+), 51 deletions(-) diff --git a/ge/graph/build/memory/graph_mem_assigner.cc b/ge/graph/build/memory/graph_mem_assigner.cc index 8a225d50..732a4a59 100755 --- a/ge/graph/build/memory/graph_mem_assigner.cc +++ b/ge/graph/build/memory/graph_mem_assigner.cc @@ -1938,6 +1938,8 @@ Status GraphMemoryAssigner::AssignBufferPoolMemory() { return SUCCESS; } +// if producer and customers in the same stream, or customers on the same stream when producer not assign a stream, +// then return false. static bool IsOutputVisitedByMultiStream(const NodePtr &peer_out_node, int64_t out_anchor_index) { GE_IF_BOOL_EXEC(peer_out_node->GetOpDesc() == nullptr, return true); int64_t unique_stream_id = peer_out_node->GetOpDesc()->GetStreamId(); @@ -1949,7 +1951,7 @@ static bool IsOutputVisitedByMultiStream(const NodePtr &peer_out_node, int64_t o if (node->GetOpDesc()->GetStreamId() == kInvalidStream) { continue; } - if (unique_stream_id == kInvalidStream) { + if (unique_stream_id == kInvalidStream) { // peer_out_node not belong to any stream unique_stream_id = node->GetOpDesc()->GetStreamId(); continue; } @@ -2001,22 +2003,23 @@ static void UpdatePrevNodeInputDesc(const NodePtr &prev_node, prev_node->GetName().c_str(), prev_node_input_index); } + return; } -static void UpdateCurNodeInputIndex(const NodePtr &cur_node, int64_t cur_node_input_index, int64_t distance) { +static void UpdateCurNodeInputDesc(const NodePtr &cur_node, int64_t cur_node_input_index, int64_t distance) { GE_IF_BOOL_EXEC(cur_node == nullptr, return); GE_IF_BOOL_EXEC(cur_node->GetOpDesc() == nullptr, return); auto input_desc = cur_node->GetOpDesc()->GetInputDesc(cur_node_input_index); vector prev_next_distances{distance, -1}; if (!ge::AttrUtils::SetListInt(input_desc, ATTR_NAME_DATA_VISIT_DISTANCE, prev_next_distances)) { - GELOGW("Update[%s] input[%lld] ATTR_NAME_DATA_VISIT_DISTANCE failed.", + GELOGW("Set [%s] input[%lld] ATTR_NAME_DATA_VISIT_DISTANCE failed.", cur_node->GetOpDesc()->GetName().c_str(), cur_node_input_index); return; } if (cur_node->GetOpDesc()->UpdateInputDesc(cur_node_input_index, input_desc) != GRAPH_SUCCESS) { - GELOGW("Update[%s] input[%lld] ATTR_NAME_DATA_VISIT_DISTANCE failed.", + GELOGW("Update [%s] input[%lld] ATTR_NAME_DATA_VISIT_DISTANCE failed.", cur_node->GetOpDesc()->GetName().c_str(), cur_node_input_index); return; @@ -2028,93 +2031,76 @@ static void UpdateCurNodeInputIndex(const NodePtr &cur_node, int64_t cur_node_in return; } + + void GraphMemoryAssigner::MarkNodeDistanceAttr(const ComputeGraphPtr &compute_graph, NodePtr &node, map>> &mem_block_visit_info, const map &node_index_in_stream) { - GELOGD("cur node name is [%s]", node->GetName().c_str()); + GELOGD("Begin to mark node distance attr, node name is [%s]", node->GetName().c_str()); GE_IF_BOOL_EXEC(node == nullptr, return); for (const auto &in_data_anchor : node->GetAllInDataAnchors()) { auto peer_out_anchor = in_data_anchor->GetPeerOutAnchor(); GE_IF_BOOL_EXEC(peer_out_anchor == nullptr, continue); auto peer_out_node = peer_out_anchor->GetOwnerNode(); GE_IF_BOOL_EXEC(peer_out_node == nullptr, continue); - GELOGD("cur node[%s], cur in_data_anchor[%d], peer_out_node[%s]", - node->GetName().c_str(), - in_data_anchor->GetIdx(), - peer_out_node->GetName().c_str()); - // find cur peer_out_node's peer_out_anchor->GetIdx()-th mem_offset(start mem offset) NodeIndexIO node_index_io(peer_out_node, peer_out_anchor->GetIdx(), kOut); std::string symbol; size_t matched_mem_offset = mem_assigner_->GetPriorityAssinger()->GetAnchorDataOffset(node_index_io, symbol); - if (matched_mem_offset != kInvalidOffset) { - GELOGD("matched_mem_offset is [%zu], and new method's matched_mem_offset is [%zu], peer_out_node is [%s]", - matched_mem_offset, - peer_out_node->GetOpDesc()->GetOutputOffset().at(peer_out_anchor->GetIdx()), - peer_out_node->GetName().c_str()); - } else { // peer_out_anchor not assign MemoryBlock, we search the peer_out_anchor's data in continous memory + if (matched_mem_offset == kInvalidOffset) { + // peer_out_anchor not assign MemoryBlock, we search the peer_out_anchor's data in continous memory matched_mem_offset = peer_out_node->GetOpDesc()->GetOutputOffset().at(peer_out_anchor->GetIdx()); } - GELOGD("final matched_mem_offset is [%zu]", matched_mem_offset); auto iter = mem_block_visit_info.find(matched_mem_offset); - if (iter == mem_block_visit_info.end()) { // cannot find visit info, peer_out_node must be a producer and this data is the first time to be visited. - GELOGD("iter == mem_block_visit_info.end() !!!"); - if (IsOutputVisitedByMultiStream(peer_out_node, peer_out_anchor->GetIdx())) { // 生产者的输出多流访问或者生产者在某条流上,但是不在cur_node所在的这条流上 + // cannot find visit info, peer_out_node must be a producer and this data is the first time to be visited. + if (iter == mem_block_visit_info.end()) { + if (IsOutputVisitedByMultiStream(peer_out_node, peer_out_anchor->GetIdx())) { vector temp; mem_block_visit_info.insert(std::make_pair(matched_mem_offset, std::make_pair(nullptr, temp))); - GELOGD("IsOutputVistedByMultiStream is true, peer_out_node is [%s], stream_id [%d], cur node is [%s], in_data_anchor_index is[%zu], stream_id[%d]", - peer_out_node->GetName().c_str(), - peer_out_node->GetOpDesc()->GetStreamId(), - node->GetName().c_str(), - in_data_anchor->GetIdx(), - node->GetOpDesc()->GetStreamId()); continue; - } else { // 生产者和消费者都在同一条流上,或者所有消费者都在同一条流上且生产者未分配流 - GELOGD("IsOutputVisitedByMultiStream is false."); + } else { vector temp = {-1}; - mem_block_visit_info.insert(std::make_pair(matched_mem_offset, std::make_pair(peer_out_node, temp))); //数据生产者的prev_node_index设置成-1 + // producer's prev_node_index set to -1 as default + mem_block_visit_info.insert(std::make_pair(matched_mem_offset, std::make_pair(peer_out_node, temp))); } - } else { // 如果在访问信息中找到了对应的offset,此时需要判断当前的输出节点和访问信息中的那个节点是否在同一个stream上,如果不在同一个stream上就不计算距离 - if (mem_block_visit_info[matched_mem_offset].first == nullptr) { + } else { + if (mem_block_visit_info[matched_mem_offset].first == nullptr) { // multi-stream visit, no need to calculate continue; } - if (peer_out_node->GetOpDesc()->GetStreamId() != mem_block_visit_info[matched_mem_offset].first->GetOpDesc()->GetStreamId()) { - GELOGD("lckey, cur node[%s], peer_out_node[%s] not in the same stream with node[%s] in visit info.", - node->GetName().c_str(), - peer_out_node->GetName().c_str(), - mem_block_visit_info[matched_mem_offset].first->GetName().c_str()); + if (peer_out_node->GetOpDesc()->GetStreamId() != + mem_block_visit_info[matched_mem_offset].first->GetOpDesc()->GetStreamId()) { + // cur node and peer_out_node not in the same stream, no need to calculate continue; } } // now mem_block_visit_info must contains that memory_block - // 1. calculate distance, update visit info, update prev_node input desc, update cur node input desc + // steps: calculate distance, update visit info, update prev_node input desc, update cur node input desc int64_t distance = -1; auto prev_node = mem_block_visit_info[matched_mem_offset].first; auto prev_node_input_index_vec = mem_block_visit_info[matched_mem_offset].second; - GE_IF_BOOL_EXEC(prev_node == nullptr, continue); // 生产者的输出多流访问或者生产者在某条流上,但是不在cur node所在的这条流上 - if (prev_node_input_index_vec.size() == 1 && prev_node_input_index_vec[0] == -1) { // prev_node是生产者且数据刚刚被生产出来(还没被其他节点访问过) + GE_IF_BOOL_EXEC(prev_node == nullptr, continue); + if (prev_node_input_index_vec.size() == 1 && prev_node_input_index_vec[0] == -1) { + // prev_node is producer and the data is just be produced(not visited by other node) GE_IF_BOOL_EXEC(prev_node->GetOpDesc() == nullptr, continue); - if (prev_node->GetOpDesc()->GetStreamId() == -1) { // 生产者未分配stream + if (prev_node->GetOpDesc()->GetStreamId() == -1) { // producer not assigned a stream distance = 0; } else if (node_index_in_stream.find(prev_node->GetName()) == node_index_in_stream.end()) { + // prev_node is ge local op distance = 0; } else { distance = node_index_in_stream.at(node->GetName()) - node_index_in_stream.at(prev_node->GetName()) - 1; } - // 不需要更新prev_node的input desc(因为prev_node设定的input index=-1, 设也设不上去),只需要后面刷一把自己的input_desc即可 - // 更新访问信息 mem_block_visit_info[matched_mem_offset].first = node; mem_block_visit_info[matched_mem_offset].second.clear(); mem_block_visit_info[matched_mem_offset].second.push_back(in_data_anchor->GetIdx()); - } else { + } else { // the data is visit by other customer just before. if (prev_node_input_index_vec.empty()) { GELOGW("Missing prev node[%s] input index.", prev_node->GetName().c_str()); continue; } - if (prev_node == node) { // scene: multiple anchors of a node access the same data vector prev_next_distances; // 1. do not need to update prev_node's input desc, because it must be updated when the first anchor visit it. @@ -2136,7 +2122,8 @@ void GraphMemoryAssigner::MarkNodeDistanceAttr(const ComputeGraphPtr &compute_gr } mem_block_visit_info[matched_mem_offset].second.push_back(in_data_anchor->GetIdx()); } else { - // 走到此处,prev_node必然是访问者,如果cur node和prev node这两个访问者不在同一条流上,那么之前在IsOutputVisitedByMultiStream是就应该continue了,而不会走到这 + // now, prev_node must be customer because if cur node and prev node not on the same stream, then it will be + // continue at IsOutputVisitedByMultiStream. distance = node_index_in_stream.at(node->GetName()) - node_index_in_stream.at(prev_node->GetName()) - 1; UpdatePrevNodeInputDesc(prev_node, prev_node_input_index_vec, distance); mem_block_visit_info[matched_mem_offset].first = node; @@ -2144,7 +2131,7 @@ void GraphMemoryAssigner::MarkNodeDistanceAttr(const ComputeGraphPtr &compute_gr mem_block_visit_info[matched_mem_offset].second.push_back(in_data_anchor->GetIdx()); } } - UpdateCurNodeInputIndex(node, in_data_anchor->GetIdx(), distance); + UpdateCurNodeInputDesc(node, in_data_anchor->GetIdx(), distance); auto input_desc = node->GetOpDesc()->GetInputDesc(in_data_anchor->GetIdx()); bool is_end_of_inputmem_lifecycle = false; @@ -2163,14 +2150,16 @@ void GraphMemoryAssigner::MarkNodeDistanceAttr(const ComputeGraphPtr &compute_gr } void GraphMemoryAssigner::MarkDistanceAttr() { - map>> mem_block_visit_info; // key: mem_offset of the memory which we visited. value: node we visited and input index of this node - map node_index_in_stream; // key: node name, value: topo order of node in it's belonged stream(exclude ge_local_op) - map stream_nodes_num; // key: stream id, value: cur nodes num in that stream + // key: mem_offset of the memory which we visited. value: node we visited and input index of this node + map>> mem_block_visit_info; + // key: node name, value: topo order of node in it's belonged stream(exclude ge_local_op) + map node_index_in_stream; + // key: stream id, value: cur nodes num in that stream + map stream_nodes_num; for (auto &node : compute_graph_->GetAllNodes()) { auto node_op_desc = node->GetOpDesc(); GE_IF_BOOL_EXEC(node_op_desc == nullptr, return); - int64_t stream_id = node_op_desc->GetStreamId(); if (node_op_desc->GetOpKernelLibName() != kEngineNameGeLocal) { if (stream_nodes_num.find(stream_id) == stream_nodes_num.end()) { @@ -2182,7 +2171,7 @@ void GraphMemoryAssigner::MarkDistanceAttr() { MarkNodeDistanceAttr(compute_graph_, node, mem_block_visit_info, node_index_in_stream); } else { - GELOGD("in GraphMemoryAssigner::MarkDistanceAttr, node[%s] is ge_local_op", node->GetName().c_str()); + GELOGD("node[%s] is ge_local_op, no need to calculate distance.", node->GetName().c_str()); } } } From e071d75ba39d8b2cab6d4f4c29e757ea6cdf4ebf Mon Sep 17 00:00:00 2001 From: lichun Date: Sun, 25 Apr 2021 15:39:12 +0800 Subject: [PATCH 3/5] mark attr distance --- ge/graph/build/memory/graph_mem_assigner.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ge/graph/build/memory/graph_mem_assigner.cc b/ge/graph/build/memory/graph_mem_assigner.cc index 732a4a59..7d01dcc3 100755 --- a/ge/graph/build/memory/graph_mem_assigner.cc +++ b/ge/graph/build/memory/graph_mem_assigner.cc @@ -36,6 +36,7 @@ namespace { const int kAllInputAddrIsAtomic = -1; const int kVirtualInputNodeMemoryReuse = 0; const int kVirtualOutputNodeMemoryReuse = 1; +const int kPrevNextDistanceNum = 2; const int64_t kInvalidStream = -1; const char *const kEngineNameGeLocal = "DNN_VM_GE_LOCAL_OP_STORE"; // One state per bit cannot be repeated @@ -1979,7 +1980,7 @@ static void UpdatePrevNodeInputDesc(const NodePtr &prev_node, continue; } - if (prev_next_distances.size() == 2) { + if (prev_next_distances.size() == kPrevNextDistanceNum) { prev_next_distances[1] = distance; } else { GELOGW("Size of prev_next_distances is not 2."); @@ -2114,7 +2115,7 @@ void GraphMemoryAssigner::MarkNodeDistanceAttr(const ComputeGraphPtr &compute_gr GELOGW("Get ATTR_NAME_DATA_VISIT_DISTANCE failed."); continue; } - if (prev_next_distances.size() != 2) { + if (prev_next_distances.size() != kPrevNextDistanceNum) { GELOGW("Size of prev_next_distance is not 2."); continue; } else { From 3425ffea01f6061a03acd7d1f5ae5f5cf15b9173 Mon Sep 17 00:00:00 2001 From: lichun Date: Sun, 25 Apr 2021 20:02:49 +0800 Subject: [PATCH 4/5] mark attr distance --- ge/graph/build/memory/graph_mem_assigner.cc | 219 ++++++++++++++++------------ ge/graph/build/memory/graph_mem_assigner.h | 25 ++++ 2 files changed, 152 insertions(+), 92 deletions(-) diff --git a/ge/graph/build/memory/graph_mem_assigner.cc b/ge/graph/build/memory/graph_mem_assigner.cc index 7d01dcc3..74f8042b 100755 --- a/ge/graph/build/memory/graph_mem_assigner.cc +++ b/ge/graph/build/memory/graph_mem_assigner.cc @@ -1941,7 +1941,7 @@ Status GraphMemoryAssigner::AssignBufferPoolMemory() { // if producer and customers in the same stream, or customers on the same stream when producer not assign a stream, // then return false. -static bool IsOutputVisitedByMultiStream(const NodePtr &peer_out_node, int64_t out_anchor_index) { +bool GraphMemoryAssigner::IsOutputVisitedByMultiStream(const NodePtr &peer_out_node, int64_t out_anchor_index) { GE_IF_BOOL_EXEC(peer_out_node->GetOpDesc() == nullptr, return true); int64_t unique_stream_id = peer_out_node->GetOpDesc()->GetStreamId(); @@ -1963,9 +1963,9 @@ static bool IsOutputVisitedByMultiStream(const NodePtr &peer_out_node, int64_t o return false; } -static void UpdatePrevNodeInputDesc(const NodePtr &prev_node, - const vector &prev_node_input_index_vec, - int64_t distance) { +void GraphMemoryAssigner::UpdatePrevNodeInputDesc(const NodePtr &prev_node, + const vector &prev_node_input_index_vec, + int64_t distance) { GE_IF_BOOL_EXEC(prev_node == nullptr, return); auto prev_node_op_desc = prev_node->GetOpDesc(); GE_IF_BOOL_EXEC(prev_node_op_desc == nullptr, return); @@ -2007,7 +2007,9 @@ static void UpdatePrevNodeInputDesc(const NodePtr &prev_node, return; } -static void UpdateCurNodeInputDesc(const NodePtr &cur_node, int64_t cur_node_input_index, int64_t distance) { +void GraphMemoryAssigner::UpdateCurNodeInputDesc(const NodePtr &cur_node, + int64_t cur_node_input_index, + int64_t distance) { GE_IF_BOOL_EXEC(cur_node == nullptr, return); GE_IF_BOOL_EXEC(cur_node->GetOpDesc() == nullptr, return); auto input_desc = cur_node->GetOpDesc()->GetInputDesc(cur_node_input_index); @@ -2032,7 +2034,113 @@ static void UpdateCurNodeInputDesc(const NodePtr &cur_node, int64_t cur_node_inp return; } +size_t GraphMemoryAssigner::GetMemoryOffset(const HybridMemAssignerPtr &mem_assigner, + const NodePtr &peer_out_node, + const OutDataAnchorPtr &peer_out_anchor) { + NodeIndexIO node_index_io(peer_out_node, peer_out_anchor->GetIdx(), kOut); + string symbol; + size_t matched_mem_offset = mem_assigner->GetPriorityAssinger()->GetAnchorDataOffset(node_index_io, symbol); + if (matched_mem_offset == kInvalidOffset) { + // peer_out_anchor not assign MemoryBlock, we search the peer_out_anchor's data in continous memory + matched_mem_offset = peer_out_node->GetOpDesc()->GetOutputOffset().at(peer_out_anchor->GetIdx()); + } + return matched_mem_offset; +} + +void GraphMemoryAssigner::CheckNeedCalcDistAndUpdateVisitInfo( + map>> &mem_block_visit_info, + size_t matched_mem_offset, + const NodePtr &peer_out_node, + const OutDataAnchorPtr &peer_out_anchor, + bool &is_need_calc_distance) { + auto iter = mem_block_visit_info.find(matched_mem_offset); + // cannot find visit info, peer_out_node must be a producer and this data is the first time to be visited. + if (iter == mem_block_visit_info.end()) { + if (IsOutputVisitedByMultiStream(peer_out_node, peer_out_anchor->GetIdx())) { + vector temp; + mem_block_visit_info.insert(std::make_pair(matched_mem_offset, std::make_pair(nullptr, temp))); + is_need_calc_distance = false; + return; + } else { + vector temp = {-1}; + // producer's prev_node_index set to -1 as default + mem_block_visit_info.insert(std::make_pair(matched_mem_offset, std::make_pair(peer_out_node, temp))); + is_need_calc_distance = true; + return; + } + } else { + if (mem_block_visit_info[matched_mem_offset].first == nullptr) { // multi-stream visit, no need to calculate + is_need_calc_distance = false; + return; + } + if (peer_out_node->GetOpDesc()->GetStreamId() != + mem_block_visit_info[matched_mem_offset].first->GetOpDesc()->GetStreamId()) { + // cur node and peer_out_node not in the same stream, no need to calculate + is_need_calc_distance = false; + return; + } + } + is_need_calc_distance = true; + return; +} +// calculate distance, update visit info, update prev_node input desc, update cur node input desc +void GraphMemoryAssigner::CalcDistanceAndUpdateDesc(map>> &mem_block_visit_info, + size_t matched_mem_offset, + const map &node_index_in_stream, + NodePtr &node, + const InDataAnchorPtr &in_data_anchor, + bool &is_need_skip) { + int64_t distance = -1; + auto prev_node = mem_block_visit_info[matched_mem_offset].first; + auto prev_node_input_index_vec = mem_block_visit_info[matched_mem_offset].second; + GE_IF_BOOL_EXEC(prev_node == nullptr, is_need_skip = true; return); + if (prev_node_input_index_vec.size() == 1 && prev_node_input_index_vec[0] == -1) { + // prev_node is producer and the data is just be produced(not visited by other node) + GE_IF_BOOL_EXEC(prev_node->GetOpDesc() == nullptr, is_need_skip = true; return); + if (prev_node->GetOpDesc()->GetStreamId() == -1) { // producer not assigned a stream + distance = 0; + } else if (node_index_in_stream.find(prev_node->GetName()) == node_index_in_stream.end()) { + distance = 0; + } else { + distance = node_index_in_stream.at(node->GetName()) - node_index_in_stream.at(prev_node->GetName()) - 1; + } + mem_block_visit_info[matched_mem_offset].first = node; + mem_block_visit_info[matched_mem_offset].second.clear(); + mem_block_visit_info[matched_mem_offset].second.push_back(in_data_anchor->GetIdx()); + } else { // the data is visit by other customer just before. + if (prev_node_input_index_vec.empty()) { + GELOGW("Missing prev node[%s] input index.", prev_node->GetName().c_str()); + is_need_skip = true; + return; + } + if (prev_node == node) { // scene: multiple anchors of a node access the same data + vector prev_next_distances; + GE_IF_BOOL_EXEC(prev_node->GetOpDesc() == nullptr, is_need_skip = true; return); + auto input_desc = prev_node->GetOpDesc()->GetInputDesc(prev_node_input_index_vec[0]); + if (!ge::AttrUtils::GetListInt(input_desc, ATTR_NAME_DATA_VISIT_DISTANCE, prev_next_distances)) { + GELOGW("Get ATTR_NAME_DATA_VISIT_DISTANCE failed."); + is_need_skip = true; + return; + } + if (prev_next_distances.size() != kPrevNextDistanceNum) { + GELOGW("Size of prev_next_distance is not 2."); + is_need_skip = true; + return; + } else { + distance = prev_next_distances[0]; //use the same prev_distance of previous anchor + } + mem_block_visit_info[matched_mem_offset].second.push_back(in_data_anchor->GetIdx()); + } else { + distance = node_index_in_stream.at(node->GetName()) - node_index_in_stream.at(prev_node->GetName()) - 1; + UpdatePrevNodeInputDesc(prev_node, prev_node_input_index_vec, distance); + mem_block_visit_info[matched_mem_offset].first = node; + mem_block_visit_info[matched_mem_offset].second.clear(); + mem_block_visit_info[matched_mem_offset].second.push_back(in_data_anchor->GetIdx()); + } + } + UpdateCurNodeInputDesc(node, in_data_anchor->GetIdx(), distance); +} void GraphMemoryAssigner::MarkNodeDistanceAttr(const ComputeGraphPtr &compute_graph, NodePtr &node, @@ -2046,105 +2154,32 @@ void GraphMemoryAssigner::MarkNodeDistanceAttr(const ComputeGraphPtr &compute_gr auto peer_out_node = peer_out_anchor->GetOwnerNode(); GE_IF_BOOL_EXEC(peer_out_node == nullptr, continue); - NodeIndexIO node_index_io(peer_out_node, peer_out_anchor->GetIdx(), kOut); - std::string symbol; - size_t matched_mem_offset = mem_assigner_->GetPriorityAssinger()->GetAnchorDataOffset(node_index_io, symbol); - if (matched_mem_offset == kInvalidOffset) { - // peer_out_anchor not assign MemoryBlock, we search the peer_out_anchor's data in continous memory - matched_mem_offset = peer_out_node->GetOpDesc()->GetOutputOffset().at(peer_out_anchor->GetIdx()); - } + auto matched_mem_offset = GetMemoryOffset(mem_assigner_, peer_out_node, peer_out_anchor); - auto iter = mem_block_visit_info.find(matched_mem_offset); - // cannot find visit info, peer_out_node must be a producer and this data is the first time to be visited. - if (iter == mem_block_visit_info.end()) { - if (IsOutputVisitedByMultiStream(peer_out_node, peer_out_anchor->GetIdx())) { - vector temp; - mem_block_visit_info.insert(std::make_pair(matched_mem_offset, std::make_pair(nullptr, temp))); - continue; - } else { - vector temp = {-1}; - // producer's prev_node_index set to -1 as default - mem_block_visit_info.insert(std::make_pair(matched_mem_offset, std::make_pair(peer_out_node, temp))); - } - } else { - if (mem_block_visit_info[matched_mem_offset].first == nullptr) { // multi-stream visit, no need to calculate - continue; - } - if (peer_out_node->GetOpDesc()->GetStreamId() != - mem_block_visit_info[matched_mem_offset].first->GetOpDesc()->GetStreamId()) { - // cur node and peer_out_node not in the same stream, no need to calculate - continue; - } + bool is_need_calc_distance = false; + CheckNeedCalcDistAndUpdateVisitInfo(mem_block_visit_info, matched_mem_offset, peer_out_node, + peer_out_anchor, is_need_calc_distance); + if (!is_need_calc_distance) { + continue; } - // now mem_block_visit_info must contains that memory_block - // steps: calculate distance, update visit info, update prev_node input desc, update cur node input desc - int64_t distance = -1; - auto prev_node = mem_block_visit_info[matched_mem_offset].first; - auto prev_node_input_index_vec = mem_block_visit_info[matched_mem_offset].second; - GE_IF_BOOL_EXEC(prev_node == nullptr, continue); - if (prev_node_input_index_vec.size() == 1 && prev_node_input_index_vec[0] == -1) { - // prev_node is producer and the data is just be produced(not visited by other node) - GE_IF_BOOL_EXEC(prev_node->GetOpDesc() == nullptr, continue); - if (prev_node->GetOpDesc()->GetStreamId() == -1) { // producer not assigned a stream - distance = 0; - } else if (node_index_in_stream.find(prev_node->GetName()) == node_index_in_stream.end()) { - // prev_node is ge local op - distance = 0; - } else { - distance = node_index_in_stream.at(node->GetName()) - node_index_in_stream.at(prev_node->GetName()) - 1; - } - mem_block_visit_info[matched_mem_offset].first = node; - mem_block_visit_info[matched_mem_offset].second.clear(); - mem_block_visit_info[matched_mem_offset].second.push_back(in_data_anchor->GetIdx()); - } else { // the data is visit by other customer just before. - if (prev_node_input_index_vec.empty()) { - GELOGW("Missing prev node[%s] input index.", prev_node->GetName().c_str()); - continue; - } - if (prev_node == node) { // scene: multiple anchors of a node access the same data - vector prev_next_distances; - // 1. do not need to update prev_node's input desc, because it must be updated when the first anchor visit it. - // 2. we use the same distance of previous anchor to keep this value the same. - // 3. update visit info's prev_node_input_index_vec - if (prev_node->GetOpDesc() == nullptr) { - continue; - } - auto input_desc = prev_node->GetOpDesc()->GetInputDesc(prev_node_input_index_vec[0]); - if (!ge::AttrUtils::GetListInt(input_desc, ATTR_NAME_DATA_VISIT_DISTANCE, prev_next_distances)) { - GELOGW("Get ATTR_NAME_DATA_VISIT_DISTANCE failed."); - continue; - } - if (prev_next_distances.size() != kPrevNextDistanceNum) { - GELOGW("Size of prev_next_distance is not 2."); - continue; - } else { - distance = prev_next_distances[0]; //use the same prev_distance of previous anchor - } - mem_block_visit_info[matched_mem_offset].second.push_back(in_data_anchor->GetIdx()); - } else { - // now, prev_node must be customer because if cur node and prev node not on the same stream, then it will be - // continue at IsOutputVisitedByMultiStream. - distance = node_index_in_stream.at(node->GetName()) - node_index_in_stream.at(prev_node->GetName()) - 1; - UpdatePrevNodeInputDesc(prev_node, prev_node_input_index_vec, distance); - mem_block_visit_info[matched_mem_offset].first = node; - mem_block_visit_info[matched_mem_offset].second.clear(); - mem_block_visit_info[matched_mem_offset].second.push_back(in_data_anchor->GetIdx()); - } + bool is_need_skip = false; + CalcDistanceAndUpdateDesc(mem_block_visit_info, matched_mem_offset, node_index_in_stream, node, + in_data_anchor, is_need_skip); + if (is_need_skip) { + continue; } - UpdateCurNodeInputDesc(node, in_data_anchor->GetIdx(), distance); auto input_desc = node->GetOpDesc()->GetInputDesc(in_data_anchor->GetIdx()); bool is_end_of_inputmem_lifecycle = false; - // if is_end_of_inputmem_lifecycle is true, indicating that cur node is the last customer of this data, // then we need to delete the visit info of the block in case that the memblock be reused and visited. if (ge::AttrUtils::GetBool(input_desc, ATTR_NAME_IS_END_OF_INPUTMEM_LIFECYCLE, is_end_of_inputmem_lifecycle) && is_end_of_inputmem_lifecycle) { GELOGD("ATTR_NAME_IS_END_OF_INPUTMEM_LIFECYCLE is true"); - auto iter2 = mem_block_visit_info.find(matched_mem_offset); - if (iter2 != mem_block_visit_info.end()) { - mem_block_visit_info.erase(iter2); + auto iter = mem_block_visit_info.find(matched_mem_offset); + if (iter != mem_block_visit_info.end()) { + mem_block_visit_info.erase(iter); } } } diff --git a/ge/graph/build/memory/graph_mem_assigner.h b/ge/graph/build/memory/graph_mem_assigner.h index 04c21a3f..b3abefb1 100755 --- a/ge/graph/build/memory/graph_mem_assigner.h +++ b/ge/graph/build/memory/graph_mem_assigner.h @@ -204,6 +204,31 @@ class GraphMemoryAssigner { Status UpdateRefOpOffsetReverse(const NodePtr &node); + bool IsOutputVisitedByMultiStream(const NodePtr &peer_out_node, int64_t out_anchor_index); + + void UpdatePrevNodeInputDesc(const NodePtr &prev_node, + const vector &prev_node_input_index_vec, + int64_t distance); + + void UpdateCurNodeInputDesc(const NodePtr &cur_node, int64_t cur_node_input_index, int64_t distance); + + size_t GetMemoryOffset(const HybridMemAssignerPtr &mem_assigner, + const NodePtr &peer_out_node, + const OutDataAnchorPtr &peer_out_anchor); + + void CheckNeedCalcDistAndUpdateVisitInfo(map>> &mem_block_visit_info, + size_t matched_mem_offset, + const NodePtr &peer_out_node, + const OutDataAnchorPtr &peer_out_anchor, + bool &is_need_calc_distance); + + void CalcDistanceAndUpdateDesc(map>> &mem_block_visit_info, + size_t matched_mem_offset, + const map &node_index_in_stream, + NodePtr &node, + const InDataAnchorPtr &in_data_anchor, + bool &is_need_skip); + MemoryOffsetMap memory_offset_; ge::ComputeGraphPtr compute_graph_; HybridMemAssignerPtr mem_assigner_; From 82a85bc254879bd853b87128edd3b0a39e0eb7de Mon Sep 17 00:00:00 2001 From: lichun Date: Sun, 25 Apr 2021 20:23:27 +0800 Subject: [PATCH 5/5] mark attr distance --- ge/graph/build/memory/graph_mem_assigner.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ge/graph/build/memory/graph_mem_assigner.cc b/ge/graph/build/memory/graph_mem_assigner.cc index 74f8042b..6d55ac79 100755 --- a/ge/graph/build/memory/graph_mem_assigner.cc +++ b/ge/graph/build/memory/graph_mem_assigner.cc @@ -1974,7 +1974,7 @@ void GraphMemoryAssigner::UpdatePrevNodeInputDesc(const NodePtr &prev_node, auto input_desc = prev_node_op_desc->GetInputDesc(prev_node_input_index); vector prev_next_distances; if (!ge::AttrUtils::GetListInt(input_desc, ATTR_NAME_DATA_VISIT_DISTANCE, prev_next_distances)) { - GELOGW("Get [%s] input [%lld] ATTR_NAME_DATA_VISIT_DISTANCE failed", + GELOGW("Get [%s] input [%ld] ATTR_NAME_DATA_VISIT_DISTANCE failed", prev_node_op_desc->GetName().c_str(), prev_node_input_index); continue; @@ -1987,19 +1987,19 @@ void GraphMemoryAssigner::UpdatePrevNodeInputDesc(const NodePtr &prev_node, continue; } if (!ge::AttrUtils::SetListInt(input_desc, ATTR_NAME_DATA_VISIT_DISTANCE, prev_next_distances)) { - GELOGW("Set [%s] input [%lld] ATTR_NAME_DATA_VISIT_DISTANCE failed.", + GELOGW("Set [%s] input [%ld] ATTR_NAME_DATA_VISIT_DISTANCE failed.", prev_node_op_desc->GetName().c_str(), prev_node_input_index); continue; } if (prev_node_op_desc->UpdateInputDesc(prev_node_input_index, input_desc) != GRAPH_SUCCESS) { - GELOGW("Update [%s] input [%lld] ATTR_NAME_DATA_VISIT_DISTANCE failed.", + GELOGW("Update [%s] input [%ld] ATTR_NAME_DATA_VISIT_DISTANCE failed.", prev_node_op_desc->GetName().c_str(), prev_node_input_index); continue; } - GELOGD("Set the next distance[%lld] to node[%s], input index[%lld]", + GELOGD("Set the next distance[%ld] to node[%s], input index[%ld]", distance, prev_node->GetName().c_str(), prev_node_input_index); @@ -2016,18 +2016,18 @@ void GraphMemoryAssigner::UpdateCurNodeInputDesc(const NodePtr &cur_node, vector prev_next_distances{distance, -1}; if (!ge::AttrUtils::SetListInt(input_desc, ATTR_NAME_DATA_VISIT_DISTANCE, prev_next_distances)) { - GELOGW("Set [%s] input[%lld] ATTR_NAME_DATA_VISIT_DISTANCE failed.", + GELOGW("Set [%s] input[%ld] ATTR_NAME_DATA_VISIT_DISTANCE failed.", cur_node->GetOpDesc()->GetName().c_str(), cur_node_input_index); return; } if (cur_node->GetOpDesc()->UpdateInputDesc(cur_node_input_index, input_desc) != GRAPH_SUCCESS) { - GELOGW("Update [%s] input[%lld] ATTR_NAME_DATA_VISIT_DISTANCE failed.", + GELOGW("Update [%s] input[%ld] ATTR_NAME_DATA_VISIT_DISTANCE failed.", cur_node->GetOpDesc()->GetName().c_str(), cur_node_input_index); return; } - GELOGD("Set the prev distance[%lld] to node[%s], input index[%lld]", + GELOGD("Set the prev distance[%ld] to node[%s], input index[%ld]", distance, cur_node->GetName().c_str(), cur_node_input_index);