@@ -142,6 +142,7 @@ set(TRAIN_SRC_LIST | |||||
"graph/passes/atomic_addr_clean_pass.cc" | "graph/passes/atomic_addr_clean_pass.cc" | ||||
"graph/passes/mark_same_addr_pass.cc" | "graph/passes/mark_same_addr_pass.cc" | ||||
"graph/passes/mark_graph_unknown_status_pass.cc" | "graph/passes/mark_graph_unknown_status_pass.cc" | ||||
"graph/passes/dynamic_single_op_reset_shape_pass.cc" | |||||
"graph/passes/mark_agnostic_pass.cc" | "graph/passes/mark_agnostic_pass.cc" | ||||
"graph/partition/dynamic_shape_partition.cc" | "graph/partition/dynamic_shape_partition.cc" | ||||
"graph/partition/stage_partition.cc" | "graph/partition/stage_partition.cc" | ||||
@@ -433,6 +434,7 @@ set(INFER_SRC_LIST | |||||
"graph/passes/atomic_addr_clean_pass.cc" | "graph/passes/atomic_addr_clean_pass.cc" | ||||
"graph/passes/mark_same_addr_pass.cc" | "graph/passes/mark_same_addr_pass.cc" | ||||
"graph/passes/mark_graph_unknown_status_pass.cc" | "graph/passes/mark_graph_unknown_status_pass.cc" | ||||
"graph/passes/dynamic_single_op_reset_shape_pass.cc" | |||||
"graph/passes/mark_agnostic_pass.cc" | "graph/passes/mark_agnostic_pass.cc" | ||||
"graph/common/omg_util.cc" | "graph/common/omg_util.cc" | ||||
"graph/common/bcast.cc" | "graph/common/bcast.cc" | ||||
@@ -109,6 +109,7 @@ OMG_HOST_SRC_FILES := \ | |||||
graph/passes/atomic_addr_clean_pass.cc \ | graph/passes/atomic_addr_clean_pass.cc \ | ||||
graph/passes/mark_same_addr_pass.cc \ | graph/passes/mark_same_addr_pass.cc \ | ||||
graph/passes/mark_graph_unknown_status_pass.cc \ | graph/passes/mark_graph_unknown_status_pass.cc \ | ||||
graph/passes/dynamic_single_op_reset_shape_pass.cc \ | |||||
graph/passes/mark_agnostic_pass.cc \ | graph/passes/mark_agnostic_pass.cc \ | ||||
graph/common/omg_util.cc \ | graph/common/omg_util.cc \ | ||||
graph/common/bcast.cc \ | graph/common/bcast.cc \ | ||||
@@ -111,6 +111,7 @@ LIBGE_LOCAL_SRC_FILES := \ | |||||
graph/passes/atomic_addr_clean_pass.cc \ | graph/passes/atomic_addr_clean_pass.cc \ | ||||
graph/passes/mark_same_addr_pass.cc \ | graph/passes/mark_same_addr_pass.cc \ | ||||
graph/passes/mark_graph_unknown_status_pass.cc \ | graph/passes/mark_graph_unknown_status_pass.cc \ | ||||
graph/passes/dynamic_single_op_reset_shape_pass.cc \ | |||||
graph/passes/mark_agnostic_pass.cc \ | graph/passes/mark_agnostic_pass.cc \ | ||||
graph/partition/dynamic_shape_partition.cc \ | graph/partition/dynamic_shape_partition.cc \ | ||||
graph/partition/stage_partition.cc \ | graph/partition/stage_partition.cc \ | ||||
@@ -47,6 +47,8 @@ const char *const kEngineNameDefault = "default"; | |||||
const char *const kVectorEngine = "VectorEngine"; | const char *const kVectorEngine = "VectorEngine"; | ||||
const char *const kAIcoreEngine = "AIcoreEngine"; | const char *const kAIcoreEngine = "AIcoreEngine"; | ||||
const char *const kFileNameSuffix = "online"; | const char *const kFileNameSuffix = "online"; | ||||
const int kDynamicDimSize = 1; | |||||
const int64_t kDynamicDimValue = -2; | |||||
std::map<ge::OpEngineType, std::string> engine_type_map{ | std::map<ge::OpEngineType, std::string> engine_type_map{ | ||||
{ge::ENGINE_SYS, kEngineNameDefault}, {ge::ENGINE_AICORE, kAIcoreEngine}, {ge::ENGINE_VECTOR, kVectorEngine}}; | {ge::ENGINE_SYS, kEngineNameDefault}, {ge::ENGINE_AICORE, kAIcoreEngine}, {ge::ENGINE_VECTOR, kVectorEngine}}; | ||||
@@ -231,6 +233,42 @@ static void GetOpsProtoPath(string &opsproto_path) { | |||||
opsproto_path = (path_base + "ops/op_proto/custom/" + ":") + (path_base + "ops/op_proto/built-in/"); | opsproto_path = (path_base + "ops/op_proto/custom/" + ":") + (path_base + "ops/op_proto/built-in/"); | ||||
} | } | ||||
static Status CheckShapeReset(const OpDescPtr &op_desc, bool &change_shape_flag) { | |||||
GE_CHECK_NOTNULL_EXEC(op_desc, return PARAM_INVALID); | |||||
change_shape_flag = false; | |||||
for (size_t i = 0; i < op_desc->GetAllInputsDesc().size(); i++) { | |||||
auto input_desc = op_desc->MutableInputDesc(static_cast<uint32_t>(i)); | |||||
GE_CHECK_NOTNULL(input_desc); | |||||
// pass scalar input desc | |||||
auto dims = input_desc->GetShape().GetDims(); | |||||
if (dims.size() == kDynamicDimSize && dims[0] == kDynamicDimValue) { | |||||
change_shape_flag = true; | |||||
} | |||||
} | |||||
return SUCCESS; | |||||
} | |||||
static void ResetInputShape(const vector<GeTensor> &inputs, vector<GeTensor> &inputs_dynamic) { | |||||
for (auto input : inputs) { | |||||
auto input_desc = input.GetTensorDesc(); | |||||
GeShape shape_ori = input_desc.GetShape(); | |||||
Format format_ori = input_desc.GetFormat(); | |||||
DataType type_ori = input_desc.GetDataType(); | |||||
std::vector<int64_t> dynamic_shape_dims = {kDynamicDimValue}; | |||||
GeShape dynamic_shape(dynamic_shape_dims); | |||||
ge::GeTensor inputTensor; | |||||
ge::GeTensorDesc desc(shape_ori, format_ori, type_ori); | |||||
if (shape_ori.GetDims().size() > 0) { | |||||
desc.SetShape(dynamic_shape); | |||||
} | |||||
inputTensor.SetTensorDesc(desc); | |||||
inputs_dynamic.push_back(inputTensor); | |||||
} | |||||
} | |||||
class GeGenerator::Impl { | class GeGenerator::Impl { | ||||
public: | public: | ||||
Impl(OmgContext &omg_context) : omg_context_(omg_context) {} | Impl(OmgContext &omg_context) : omg_context_(omg_context) {} | ||||
@@ -557,7 +595,9 @@ Status GeGenerator::CheckForSingleOp(OpDescPtr &op_desc, const vector<GeTensor> | |||||
Status GeGenerator::BuildSingleOp(OpDescPtr &op_desc, const vector<GeTensor> &inputs, const vector<GeTensor> &outputs, | Status GeGenerator::BuildSingleOp(OpDescPtr &op_desc, const vector<GeTensor> &inputs, const vector<GeTensor> &outputs, | ||||
const string &model_file_name, OpEngineType engine_type, ModelBufferData &model_buff, | const string &model_file_name, OpEngineType engine_type, ModelBufferData &model_buff, | ||||
bool is_offline) { | bool is_offline) { | ||||
if (is_offline) { | |||||
(void)AttrUtils::SetBool(op_desc, ATTR_DYNAMIC_SHAPE_SINGLE_AICPU, true); | |||||
} | |||||
if (CheckForSingleOp(op_desc, inputs, outputs) != SUCCESS) { | if (CheckForSingleOp(op_desc, inputs, outputs) != SUCCESS) { | ||||
GELOGE(PARAM_INVALID, "input param is invalid when build single op!"); | GELOGE(PARAM_INVALID, "input param is invalid when build single op!"); | ||||
return PARAM_INVALID; | return PARAM_INVALID; | ||||
@@ -634,7 +674,15 @@ Status GeGenerator::BuildSingleOp(OpDescPtr &op_desc, const vector<GeTensor> &in | |||||
} | } | ||||
GeModelPtr &ge_model = name_to_ge_model.begin()->second; | GeModelPtr &ge_model = name_to_ge_model.begin()->second; | ||||
GELOGD("The opType in op_desc_tmp is [%s]", op_desc_tmp->GetType().c_str()); | GELOGD("The opType in op_desc_tmp is [%s]", op_desc_tmp->GetType().c_str()); | ||||
GE_CHK_STATUS_RET_NOLOG(impl_->SaveParams(ge_model, op_desc_tmp->GetType(), op_attrs, inputs, outputs)); | |||||
bool dynamic_flag = false; | |||||
if (CheckShapeReset(op_desc, dynamic_flag) == SUCCESS && dynamic_flag) { | |||||
vector<GeTensor> inputs_dynamic; | |||||
ResetInputShape(inputs, inputs_dynamic); | |||||
GE_CHK_STATUS_RET_NOLOG(impl_->SaveParams(ge_model, op_desc_tmp->GetType(), op_attrs, inputs_dynamic, outputs)); | |||||
} else { | |||||
GE_CHK_STATUS_RET_NOLOG(impl_->SaveParams(ge_model, op_desc_tmp->GetType(), op_attrs, inputs, outputs)); | |||||
} | |||||
GE_CHK_STATUS_RET_NOLOG(impl_->SaveModel(model_file_name, ge_model, model_buff)); | GE_CHK_STATUS_RET_NOLOG(impl_->SaveModel(model_file_name, ge_model, model_buff)); | ||||
return SUCCESS; | return SUCCESS; | ||||
} | } | ||||
@@ -69,6 +69,7 @@ | |||||
#include "graph/passes/iterator_op_pass.h" | #include "graph/passes/iterator_op_pass.h" | ||||
#include "graph/passes/link_gen_mask_nodes_pass.h" | #include "graph/passes/link_gen_mask_nodes_pass.h" | ||||
#include "graph/passes/mark_graph_unknown_status_pass.h" | #include "graph/passes/mark_graph_unknown_status_pass.h" | ||||
#include "graph/passes/dynamic_single_op_reset_shape_pass.h" | |||||
#include "graph/passes/merge_pass.h" | #include "graph/passes/merge_pass.h" | ||||
#include "graph/passes/merge_input_memcpy_pass.h" | #include "graph/passes/merge_input_memcpy_pass.h" | ||||
#include "graph/passes/merge_to_stream_merge_pass.h" | #include "graph/passes/merge_to_stream_merge_pass.h" | ||||
@@ -2280,6 +2281,9 @@ Status GraphManager::OptimizeStage2(ge::ComputeGraphPtr &compute_graph) { | |||||
new (std::nothrow) VariableRefDeleteOpPass)) | new (std::nothrow) VariableRefDeleteOpPass)) | ||||
GE_CHK_STATUS_RET(pass_for_control_attr_optimize.AddPass("OptimizeStage2::ControlAttrOptimize::CompileNodesPass", | GE_CHK_STATUS_RET(pass_for_control_attr_optimize.AddPass("OptimizeStage2::ControlAttrOptimize::CompileNodesPass", | ||||
new (std::nothrow) CompileNodesPass)) | new (std::nothrow) CompileNodesPass)) | ||||
GE_CHK_STATUS_RET( | |||||
pass_for_control_attr_optimize.AddPass("OptimizeStage2::AfterMergePasses::DynamicSingleOpResetShapePass", | |||||
new (std::nothrow) DynamicSingleOpResetShapePass)) | |||||
GE_CHK_STATUS_RET(pass_for_control_attr_optimize.AddPass( | GE_CHK_STATUS_RET(pass_for_control_attr_optimize.AddPass( | ||||
"OptimizeStage2::AfterMergePasses::MarkGraphUnknownStatusPass", new(std::nothrow) MarkGraphUnknownStatusPass)) | "OptimizeStage2::AfterMergePasses::MarkGraphUnknownStatusPass", new(std::nothrow) MarkGraphUnknownStatusPass)) | ||||
GE_CHK_STATUS_RET( | GE_CHK_STATUS_RET( | ||||
@@ -0,0 +1,153 @@ | |||||
/** | |||||
* Copyright 2020 Huawei Technologies Co., Ltd | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
#include "graph/passes/dynamic_single_op_reset_shape_pass.h" | |||||
#include "common/ge_inner_error_codes.h" | |||||
#include "graph/utils/node_utils.h" | |||||
#include "graph/utils/graph_utils.h" | |||||
#include "graph/utils/tensor_utils.h" | |||||
#include "graph/utils/op_desc_utils.h" | |||||
#include "graph/utils/type_utils.h" | |||||
#include "graph/debug/ge_attr_define.h" | |||||
namespace ge { | |||||
namespace { | |||||
const int64_t kDynamicShapeDim = -2; | |||||
const char *const kAICPUKernelLibName = "aicpu_tf_kernel"; | |||||
} // namespace | |||||
Status DynamicSingleOpResetShapePass::Run(ComputeGraphPtr graph) { | |||||
GE_CHECK_NOTNULL(graph); | |||||
std::shared_ptr<GELib> instance = ge::GELib::GetInstance(); | |||||
if (instance == nullptr || !instance->InitFlag()) { | |||||
GELOGE(ge::GE_CLI_GE_NOT_INITIALIZED, "Run CompileNodesPass failed."); | |||||
return ge::GE_CLI_GE_NOT_INITIALIZED; | |||||
} | |||||
for (const auto &node : graph->GetDirectNode()) { | |||||
GE_CHECK_NOTNULL(node->GetOpDesc()); | |||||
// pass input node | |||||
if (node->GetType() == DATA || node->GetType() == CONSTANT || node->GetType() == CONSTANTOP) { | |||||
continue; | |||||
} | |||||
// pass output node | |||||
if (node->GetType() == NETOUTPUT) { | |||||
continue; | |||||
} | |||||
bool single_aicpu_unknown = false; | |||||
if (!AttrUtils::GetBool(node->GetOpDesc(), ATTR_DYNAMIC_SHAPE_SINGLE_AICPU, single_aicpu_unknown) || | |||||
!single_aicpu_unknown) { | |||||
continue; | |||||
} | |||||
// pass node aicpu node. | |||||
string kernel_lib_name; | |||||
if (GetSupportedKernel(node, instance, kernel_lib_name) != GRAPH_SUCCESS) { | |||||
GELOGE(GRAPH_FAILED, "Get kernel lib failed of node[%s].", node->GetName().c_str()); | |||||
return GRAPH_FAILED; | |||||
} | |||||
if (kernel_lib_name != kAICPUKernelLibName) { | |||||
continue; | |||||
} | |||||
// reset aicpu shape to unknown shape | |||||
auto op_desc = node->GetOpDesc(); | |||||
std::vector<int64_t> dynamic_shape_dims = {kDynamicShapeDim}; | |||||
GeShape dynamic_shape(dynamic_shape_dims); | |||||
for (size_t i = 0; i < op_desc->GetAllInputsDesc().size(); i++) { | |||||
auto input_desc = op_desc->MutableInputDesc(static_cast<uint32_t>(i)); | |||||
GE_CHECK_NOTNULL(input_desc); | |||||
// pass scalar input desc | |||||
auto dims_ori = input_desc->GetShape().GetDims(); | |||||
if (dims_ori.size() == 0) { | |||||
continue; | |||||
} | |||||
input_desc->SetShape(dynamic_shape); | |||||
} | |||||
GELOGD("Reset dynamic aicpu node [%s] shape success!", node->GetName().c_str()); | |||||
} | |||||
GELOGD("Reset dynamic aicpu nodes shape of graph [%s] success!", graph->GetName().c_str()); | |||||
return SUCCESS; | |||||
} | |||||
graphStatus DynamicSingleOpResetShapePass::GetSupportedKernel(const NodePtr &node, | |||||
const std::shared_ptr<GELib> instance, | |||||
string &kernel_lib_name) { | |||||
auto op_desc = node->GetOpDesc(); | |||||
if (op_desc == nullptr) { | |||||
GELOGE(ge::GE_GRAPH_PARAM_NULLPTR, "Get op %s opdesc failed", node->GetName().c_str()); | |||||
return ge::GE_GRAPH_PARAM_NULLPTR; | |||||
} | |||||
// reset op kernel lib, find supported kernel | |||||
kernel_lib_name = op_desc->GetOpKernelLibName(); | |||||
if (kernel_lib_name.empty()) { | |||||
(void)instance->DNNEngineManagerObj().GetDNNEngineName(node); | |||||
kernel_lib_name = op_desc->GetOpKernelLibName(); | |||||
if (kernel_lib_name.empty()) { | |||||
GELOGE(GRAPH_FAILED, "Get node:%s, type:%s kernel lib failed.", node->GetName().c_str(), | |||||
op_desc->GetType().c_str()); | |||||
return GRAPH_FAILED; | |||||
} | |||||
} | |||||
OpsKernelInfoStorePtr kernel_info = instance->OpsKernelManagerObj().GetOpsKernelInfoStore(kernel_lib_name); | |||||
if (kernel_info == nullptr) { | |||||
GELOGE(ge::GE_GRAPH_PARAM_NULLPTR, "Get op %s ops kernel info store failed", node->GetName().c_str()); | |||||
return ge::GE_GRAPH_PARAM_NULLPTR; | |||||
} | |||||
// begin accuracy supported check | |||||
if (!CheckAccuracySupport(kernel_info, instance, op_desc)) { | |||||
// if check accuracy support failed , try to go to other engine. | |||||
GELOGD("Check Accuracy Supported return not support, node name is %s. Try to go to other engine.", | |||||
op_desc->GetName().c_str()); | |||||
string kernel_name_origin = kernel_lib_name; | |||||
OpsKernelManager &ops_kernel_manager = instance->OpsKernelManagerObj(); | |||||
auto kernel_map = ops_kernel_manager.GetAllOpsKernelInfoStores(); | |||||
for (auto it = kernel_map.begin(); it != kernel_map.end(); ++it) { | |||||
string tmp_kernel_name = it->first; | |||||
if (tmp_kernel_name == kernel_name_origin) { | |||||
continue; | |||||
} | |||||
OpsKernelInfoStorePtr tmp_kernel_info = it->second; | |||||
if (CheckAccuracySupport(tmp_kernel_info, instance, op_desc)) { | |||||
kernel_lib_name = tmp_kernel_name; | |||||
GELOGD("Find kernel lib %s support node:%s, type:%s , get kernel lib success.", tmp_kernel_name.c_str(), | |||||
node->GetName().c_str(), op_desc->GetType().c_str()); | |||||
return GRAPH_SUCCESS; | |||||
} | |||||
} | |||||
GELOGE(GRAPH_FAILED, "Cannot find kernel lib support node:%s, type:%s , get kernel lib failed.", | |||||
node->GetName().c_str(), op_desc->GetType().c_str()); | |||||
return GRAPH_FAILED; | |||||
} | |||||
return GRAPH_SUCCESS; | |||||
} | |||||
bool DynamicSingleOpResetShapePass::CheckAccuracySupport(const OpsKernelInfoStorePtr &kernel_info, | |||||
const std::shared_ptr<GELib> instance, OpDescPtr &op_desc) { | |||||
auto ge_desc = MakeShared<ge::OpDescPtr>(op_desc); | |||||
if (ge_desc == nullptr) { | |||||
GELOGE(GE_GRAPH_MEMORY_ALLOC_FAILED, "Fail to malloc op desc."); | |||||
return false; | |||||
} | |||||
string reason; | |||||
if (!(kernel_info->CheckAccuracySupported(*ge_desc, reason, true))) { | |||||
return false; | |||||
} | |||||
return true; | |||||
} | |||||
} // namespace ge |
@@ -0,0 +1,34 @@ | |||||
/** | |||||
* Copyright 2020 Huawei Technologies Co., Ltd | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
*/ | |||||
#ifndef GE_GRAPH_PASSES_DYNAMIC_SINGLE_OP_RESET_SHAPE_PASS_H_ | |||||
#define GE_GRAPH_PASSES_DYNAMIC_SINGLE_OP_RESET_SHAPE_PASS_H_ | |||||
#include "graph/graph.h" | |||||
#include "inc/graph_pass.h" | |||||
#include "init/gelib.h" | |||||
namespace ge { | |||||
class DynamicSingleOpResetShapePass : public GraphPass { | |||||
public: | |||||
Status Run(ComputeGraphPtr graph) override; | |||||
private: | |||||
graphStatus GetSupportedKernel(const NodePtr &node, const std::shared_ptr<GELib> instance, string &kernel_lib_name); | |||||
bool CheckAccuracySupport(const OpsKernelInfoStorePtr &kernel_info, const std::shared_ptr<GELib> instance, | |||||
OpDescPtr &op_desc); | |||||
}; | |||||
} // namespace ge | |||||
#endif // GE_GRAPH_PASSES_DYNAMIC_SINGLE_OP_RESET_SHAPE_PASS_H_ |
@@ -1 +1 @@ | |||||
Subproject commit 7472245fcaed273b7cff99a1f6e6bab3313be684 | |||||
Subproject commit 0aee977581117ca5c8df5d5ccdf7333c6ea33834 |
@@ -182,6 +182,7 @@ set(COMMON_SRC_FILES | |||||
"${GE_CODE_DIR}/ge/graph/passes/atomic_addr_clean_pass.cc" | "${GE_CODE_DIR}/ge/graph/passes/atomic_addr_clean_pass.cc" | ||||
"${GE_CODE_DIR}/ge/graph/passes/mark_same_addr_pass.cc" | "${GE_CODE_DIR}/ge/graph/passes/mark_same_addr_pass.cc" | ||||
"${GE_CODE_DIR}/ge/graph/passes/mark_graph_unknown_status_pass.cc" | "${GE_CODE_DIR}/ge/graph/passes/mark_graph_unknown_status_pass.cc" | ||||
"${GE_CODE_DIR}/ge/graph/passes/dynamic_single_op_reset_shape_pass.cc" | |||||
"${GE_CODE_DIR}/ge/graph/passes/mark_agnostic_pass.cc" | "${GE_CODE_DIR}/ge/graph/passes/mark_agnostic_pass.cc" | ||||
"${GE_CODE_DIR}/ge/graph/passes/dimension_compute_pass.cc" | "${GE_CODE_DIR}/ge/graph/passes/dimension_compute_pass.cc" | ||||
"${GE_CODE_DIR}/ge/graph/passes/dimension_adjust_pass.cc" | "${GE_CODE_DIR}/ge/graph/passes/dimension_adjust_pass.cc" | ||||