|
|
@@ -239,6 +239,10 @@ bool MemoryBlock::IsSameBatchLabel() { |
|
|
return all_same_label; |
|
|
return all_same_label; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool MemoryBlock::CanReuse(int32_t thread_scope_id) const { |
|
|
|
|
|
return (thread_scope_id_.find(thread_scope_id) == thread_scope_id_.end()); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
bool CanNotLifeReuse(MemoryBlock *block) { |
|
|
bool CanNotLifeReuse(MemoryBlock *block) { |
|
|
if ((block == nullptr) || !block->reuse_mem_ || block->deleted_block_) { |
|
|
if ((block == nullptr) || !block->reuse_mem_ || block->deleted_block_) { |
|
|
return true; |
|
|
return true; |
|
|
@@ -283,6 +287,14 @@ void MemoryBlock::AddLifeReuseBlock(MemoryBlock *block, DependStreamLife &total_ |
|
|
if (CanNotLifeReuse(this) || CanNotLifeReuse(block) || (batch_label_ != block->batch_label_)) { |
|
|
if (CanNotLifeReuse(this) || CanNotLifeReuse(block) || (batch_label_ != block->batch_label_)) { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// not same thread scode id can reuse |
|
|
|
|
|
for (auto thread_scope_id : ThreadScopeId()) { |
|
|
|
|
|
if (!block->CanReuse(thread_scope_id)) { |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (block->continuous_block_) { |
|
|
if (block->continuous_block_) { |
|
|
AddContinuousLifeReuseBlock(block, total_node_depend_stream_life); |
|
|
AddContinuousLifeReuseBlock(block, total_node_depend_stream_life); |
|
|
return; |
|
|
return; |
|
|
@@ -659,7 +671,12 @@ bool IsDirectOutputNode(const NodePtr &node, int idx) { |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool CanReuseBlock(size_t continuous_life_begin, const MemoryBlock &reusable_block, size_t block_size) { |
|
|
|
|
|
|
|
|
bool CanReuseBlock(int32_t thread_scope_id, size_t continuous_life_begin, const MemoryBlock &reusable_block, |
|
|
|
|
|
size_t block_size) { |
|
|
|
|
|
if (!reusable_block.CanReuse(thread_scope_id)) { |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
bool can_reuse = false; |
|
|
bool can_reuse = false; |
|
|
if (reusable_block.Size() == block_size) { |
|
|
if (reusable_block.Size() == block_size) { |
|
|
// in some continuous input case, continuous first input node's is not same as topo first node. |
|
|
// in some continuous input case, continuous first input node's is not same as topo first node. |
|
|
@@ -1122,6 +1139,8 @@ MemoryBlock *BlockMemAssigner::ApplyMemory(size_t block_size, size_t real_size, |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool is_reuse_memory = false; |
|
|
bool is_reuse_memory = false; |
|
|
|
|
|
int32_t thread_scope_id = kInvalidThreadScopeId; |
|
|
|
|
|
(void)ge::AttrUtils::GetInt(node_op_desc, ATTR_NAME_THREAD_SCOPE_ID, thread_scope_id); |
|
|
if (ge_disable_reuse_mem_env_ != "1") { |
|
|
if (ge_disable_reuse_mem_env_ != "1") { |
|
|
bool reuse_mem_flag = (mem_type == kOutput) ? IsPreReuse(n, out_index) : |
|
|
bool reuse_mem_flag = (mem_type == kOutput) ? IsPreReuse(n, out_index) : |
|
|
!((workspace_reuse_flag.size() > out_index) && !workspace_reuse_flag[out_index]); |
|
|
!((workspace_reuse_flag.size() > out_index) && !workspace_reuse_flag[out_index]); |
|
|
@@ -1141,8 +1160,8 @@ MemoryBlock *BlockMemAssigner::ApplyMemory(size_t block_size, size_t real_size, |
|
|
GE_IF_BOOL_EXEC(reusable_block->batch_label_ != batch_label, continue); |
|
|
GE_IF_BOOL_EXEC(reusable_block->batch_label_ != batch_label, continue); |
|
|
|
|
|
|
|
|
// A node can reuse blocks of the same stream and preorder streams |
|
|
// A node can reuse blocks of the same stream and preorder streams |
|
|
if (CanReuseBlock(continuous_life_begin_, *reusable_block, block_size)) { |
|
|
|
|
|
reusable_block->AddNodeTypeIndex({n, mem_type, out_index, false, continuous_life_begin_}, |
|
|
|
|
|
|
|
|
if (CanReuseBlock(thread_scope_id, continuous_life_begin_, *reusable_block, block_size)) { |
|
|
|
|
|
reusable_block->AddNodeTypeIndex({n, mem_type, out_index, false, continuous_life_begin_, thread_scope_id}, |
|
|
real_size, no_align_size); |
|
|
real_size, no_align_size); |
|
|
if (mem_type == kOutput) { |
|
|
if (mem_type == kOutput) { |
|
|
auto iter = anchor_to_symbol_.find(NodeIndexIO(n, out_index, kOut).ToString()); |
|
|
auto iter = anchor_to_symbol_.find(NodeIndexIO(n, out_index, kOut).ToString()); |
|
|
@@ -1168,7 +1187,8 @@ MemoryBlock *BlockMemAssigner::ApplyMemory(size_t block_size, size_t real_size, |
|
|
|
|
|
|
|
|
// Data and netoutput need zero copy block |
|
|
// Data and netoutput need zero copy block |
|
|
block->is_zero_copy_ = IsZeroCopyBlock(n, continuous); |
|
|
block->is_zero_copy_ = IsZeroCopyBlock(n, continuous); |
|
|
block->AddNodeTypeIndex({n, mem_type, out_index, false, continuous_life_begin_}, real_size, no_align_size); |
|
|
|
|
|
|
|
|
block->AddNodeTypeIndex({n, mem_type, out_index, false, continuous_life_begin_, thread_scope_id}, |
|
|
|
|
|
real_size, no_align_size); |
|
|
block->stream_id_ = node_op_desc->GetStreamId(); |
|
|
block->stream_id_ = node_op_desc->GetStreamId(); |
|
|
block->continuous_block_ = continuous; |
|
|
block->continuous_block_ = continuous; |
|
|
block->batch_label_ = batch_label; |
|
|
block->batch_label_ = batch_label; |
|
|
@@ -2062,7 +2082,13 @@ void SetOffsetSize(const NodeTypeIndex &node_type, const MemoryBlock *block, |
|
|
size_t real_size, size_t no_align_size, int32_t child_block_level) { |
|
|
size_t real_size, size_t no_align_size, int32_t child_block_level) { |
|
|
ge::OpDescPtr op_desc = node_type.node->GetOpDesc(); |
|
|
ge::OpDescPtr op_desc = node_type.node->GetOpDesc(); |
|
|
GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(op_desc == nullptr, return, "op_desc is null."); |
|
|
GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(op_desc == nullptr, return, "op_desc is null."); |
|
|
string graph_name = node_type.node->GetOwnerComputeGraph()->GetName(); |
|
|
|
|
|
|
|
|
auto owner_graph = node_type.node->GetOwnerComputeGraph(); |
|
|
|
|
|
GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(owner_graph == nullptr, return, "owner_graph is null."); |
|
|
|
|
|
string graph_name = owner_graph->GetName(); |
|
|
|
|
|
if (owner_graph->GetParentGraph() != nullptr) { |
|
|
|
|
|
graph_name = owner_graph->GetParentGraph()->GetName(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
vector<int64_t> memorys_type; |
|
|
vector<int64_t> memorys_type; |
|
|
int64_t offset = block->HeadOffset(); |
|
|
int64_t offset = block->HeadOffset(); |
|
|
size_t end = node_type.life_time_end; |
|
|
size_t end = node_type.life_time_end; |
|
|
@@ -2108,12 +2134,12 @@ void SetOffsetSize(const NodeTypeIndex &node_type, const MemoryBlock *block, |
|
|
op_desc->SetWorkspace(workspace_list); |
|
|
op_desc->SetWorkspace(workspace_list); |
|
|
} |
|
|
} |
|
|
GELOGI("[IMAS]Set %s name[%s] optype[%s] %s[%u] offset to [%ld] streamid[%ld] memtype[%ld] size[%zu] realsize[%zu] " |
|
|
GELOGI("[IMAS]Set %s name[%s] optype[%s] %s[%u] offset to [%ld] streamid[%ld] memtype[%ld] size[%zu] realsize[%zu] " |
|
|
"noalignsize[%zu] life time begin[%s] life time end[%zu] child[%d:%d:%d:%d:%d] isref[%d] batch[%s]", |
|
|
|
|
|
|
|
|
"noalignsize[%zu] life time begin[%s] life time end[%zu] child[%d:%d:%d:%d:%d] isref[%d] batch[%s] scope[%d]", |
|
|
graph_name.c_str(), op_desc->GetName().c_str(), node_type.node->GetType().c_str(), |
|
|
graph_name.c_str(), op_desc->GetName().c_str(), node_type.node->GetType().c_str(), |
|
|
node_type.GetMemType().c_str(), node_type.index, offset, op_desc->GetStreamId(),block->memory_type_, |
|
|
node_type.GetMemType().c_str(), node_type.index, offset, op_desc->GetStreamId(),block->memory_type_, |
|
|
block->Size(), real_size, no_align_size, node_type.GetLifeBeginDesc().c_str(), end, child_block_level, |
|
|
block->Size(), real_size, no_align_size, node_type.GetLifeBeginDesc().c_str(), end, child_block_level, |
|
|
block->reuse_mem_, block->continuous_block_, block->is_zero_copy_, block->same_stream_, node_type.ref_input, |
|
|
block->reuse_mem_, block->continuous_block_, block->is_zero_copy_, block->same_stream_, node_type.ref_input, |
|
|
block->batch_label_.c_str()); |
|
|
|
|
|
|
|
|
block->batch_label_.c_str(), node_type.thread_scope_id); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void SetBlockOpMemOffset(MemoryBlock *block, int32_t child_block_level) { |
|
|
void SetBlockOpMemOffset(MemoryBlock *block, int32_t child_block_level) { |
|
|
@@ -2176,8 +2202,7 @@ Status BlockMemAssigner::Assign() { |
|
|
|
|
|
|
|
|
bool BlockMemAssigner::CheckIsZeroMemNodeType(const string &node_type) const { |
|
|
bool BlockMemAssigner::CheckIsZeroMemNodeType(const string &node_type) const { |
|
|
return (node_type == VARIABLE) || (node_type == CONSTANT) || (node_type == MULTISHAPE) || |
|
|
return (node_type == VARIABLE) || (node_type == CONSTANT) || (node_type == MULTISHAPE) || |
|
|
(node_type == CONSTANTOP) || (node_type == ASSIGNADD) || (node_type == ASSIGNSUB) || |
|
|
|
|
|
(node_type == ASSIGN) || (node_type == HVDWAIT); |
|
|
|
|
|
|
|
|
(node_type == CONSTANTOP) || (node_type == HVDWAIT); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool BlockMemAssigner::GetWorkSpaceMemoryType(const NodePtr &node, size_t index, int64_t &memory_type) { |
|
|
bool BlockMemAssigner::GetWorkSpaceMemoryType(const NodePtr &node, size_t index, int64_t &memory_type) { |
|
|
|