From a69a72086acd4da0df3b62602e5d23f503e77be1 Mon Sep 17 00:00:00 2001 From: l00444296 Date: Sat, 12 Dec 2020 12:08:30 +0800 Subject: [PATCH 1/3] Feature: reset shape of dynamic single op --- ge/CMakeLists.txt | 2 ++ ge/ge_inference.mk | 1 + ge/ge_runner.mk | 1 + ge/generator/ge_generator.cc | 55 +++++++++++++++++++++++++++++++++++++-- ge/graph/manager/graph_manager.cc | 12 +++++++++ metadef | 2 +- tests/ut/ge/CMakeLists.txt | 1 + 7 files changed, 71 insertions(+), 3 deletions(-) diff --git a/ge/CMakeLists.txt b/ge/CMakeLists.txt index bd0b0c39..744b82a4 100755 --- a/ge/CMakeLists.txt +++ b/ge/CMakeLists.txt @@ -142,6 +142,7 @@ set(TRAIN_SRC_LIST "graph/passes/atomic_addr_clean_pass.cc" "graph/passes/mark_same_addr_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/partition/dynamic_shape_partition.cc" "graph/partition/stage_partition.cc" @@ -433,6 +434,7 @@ set(INFER_SRC_LIST "graph/passes/atomic_addr_clean_pass.cc" "graph/passes/mark_same_addr_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/common/omg_util.cc" "graph/common/bcast.cc" diff --git a/ge/ge_inference.mk b/ge/ge_inference.mk index 80887e8b..bfb612ea 100755 --- a/ge/ge_inference.mk +++ b/ge/ge_inference.mk @@ -109,6 +109,7 @@ OMG_HOST_SRC_FILES := \ graph/passes/atomic_addr_clean_pass.cc \ graph/passes/mark_same_addr_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/common/omg_util.cc \ graph/common/bcast.cc \ diff --git a/ge/ge_runner.mk b/ge/ge_runner.mk index 5205a06c..bb4ec715 100644 --- a/ge/ge_runner.mk +++ b/ge/ge_runner.mk @@ -111,6 +111,7 @@ LIBGE_LOCAL_SRC_FILES := \ graph/passes/atomic_addr_clean_pass.cc \ graph/passes/mark_same_addr_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/partition/dynamic_shape_partition.cc \ graph/partition/stage_partition.cc \ diff --git a/ge/generator/ge_generator.cc b/ge/generator/ge_generator.cc index dc64aac1..8a47cd64 100644 --- a/ge/generator/ge_generator.cc +++ b/ge/generator/ge_generator.cc @@ -47,6 +47,8 @@ const char *const kEngineNameDefault = "default"; const char *const kVectorEngine = "VectorEngine"; const char *const kAIcoreEngine = "AIcoreEngine"; const char *const kFileNameSuffix = "online"; +const int kDynamicDimSize = 1; +const int64_t kDynamicDimValue = -2; std::map engine_type_map{ {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/"); } +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(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 ResetTensorVecShape(const vector &inputs, vector &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 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 { public: Impl(OmgContext &omg_context) : omg_context_(omg_context) {} @@ -557,7 +595,9 @@ Status GeGenerator::CheckForSingleOp(OpDescPtr &op_desc, const vector Status GeGenerator::BuildSingleOp(OpDescPtr &op_desc, const vector &inputs, const vector &outputs, const string &model_file_name, OpEngineType engine_type, ModelBufferData &model_buff, bool is_offline) { - + if (!is_offline) { + (void)AttrUtils::SetBool(op_desc, ATTR_DYNAMIC_SHAPE_SINGLE_AICPU, true); + } if (CheckForSingleOp(op_desc, inputs, outputs) != SUCCESS) { GELOGE(PARAM_INVALID, "input param is invalid when build single op!"); return PARAM_INVALID; @@ -634,7 +674,18 @@ Status GeGenerator::BuildSingleOp(OpDescPtr &op_desc, const vector &in } GeModelPtr &ge_model = name_to_ge_model.begin()->second; 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 inputs_dynamic; + vector outputs_dynamic; + ResetTensorVecShape(inputs, inputs_dynamic); + ResetTensorVecShape(outputs, outputs_dynamic); + GE_CHK_STATUS_RET_NOLOG( + impl_->SaveParams(ge_model, op_desc_tmp->GetType(), op_attrs, inputs_dynamic, outputs_dynamic)); + } 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)); return SUCCESS; } diff --git a/ge/graph/manager/graph_manager.cc b/ge/graph/manager/graph_manager.cc index 364a360f..c8d20ce3 100755 --- a/ge/graph/manager/graph_manager.cc +++ b/ge/graph/manager/graph_manager.cc @@ -68,6 +68,7 @@ #include "graph/passes/iterator_op_pass.h" #include "graph/passes/link_gen_mask_nodes_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_input_memcpy_pass.h" #include "graph/passes/merge_to_stream_merge_pass.h" @@ -655,6 +656,17 @@ Status GraphManager::ReplaceSubgraphWithOriGraph(const ComputeGraphPtr &compute_ Status GraphManager::SetSubgraph(uint64_t session_id, ComputeGraphPtr compute_graph, GraphPartitioner &partitioner) { GE_CHECK_NOTNULL(compute_graph); + PassManager pass_for_dynamic_shape_reset_optimize; + GE_CHK_STATUS_RET(pass_for_dynamic_shape_reset_optimize.AddPass( + "SetSubgraph::AfterSetSubgraph::DynamicSingleOpResetShapePass", new (std::nothrow) DynamicSingleOpResetShapePass)) + GE_TIMESTAMP_START(pass_for_dynamic_shape_reset_optimize); + ret = pass_for_dynamic_shape_reset_optimize.Run(compute_graph); + GE_TIMESTAMP_END(pass_for_dynamic_shape_reset_optimize, "SetSubgraph::AfterSetSubgraph"); + if (ret != SUCCESS && ret != NOT_CHANGED) { + GELOGE(ret, "Run passes when optimize subgraph failed"); + return ret; + } + auto sub_graph_map = partitioner.GetSubGraphMap(); GELOGD("Directly optimize subgraph with build mode:%s, and step:%s.", options_.build_mode.c_str(), diff --git a/metadef b/metadef index bd2cfdfa..a83f6219 160000 --- a/metadef +++ b/metadef @@ -1 +1 @@ -Subproject commit bd2cfdfa85a3d9dcbd7dc825f5759c7f8b3ffa9a +Subproject commit a83f6219922830574b9faad591d9a96ef23cc0f8 diff --git a/tests/ut/ge/CMakeLists.txt b/tests/ut/ge/CMakeLists.txt index e305d281..1dfd8bbc 100755 --- a/tests/ut/ge/CMakeLists.txt +++ b/tests/ut/ge/CMakeLists.txt @@ -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/mark_same_addr_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/dimension_compute_pass.cc" "${GE_CODE_DIR}/ge/graph/passes/dimension_adjust_pass.cc" From 63ff03d4afa9f4ef37fbc4061726c3d1e8e993e4 Mon Sep 17 00:00:00 2001 From: l00444296 Date: Sat, 12 Dec 2020 13:47:27 +0800 Subject: [PATCH 2/3] Feature: reset shape of dynamic single op --- .../passes/dynamic_single_op_reset_shape_pass.cc | 105 +++++++++++++++++++++ .../passes/dynamic_single_op_reset_shape_pass.h | 32 +++++++ 2 files changed, 137 insertions(+) create mode 100644 ge/graph/passes/dynamic_single_op_reset_shape_pass.cc create mode 100644 ge/graph/passes/dynamic_single_op_reset_shape_pass.h diff --git a/ge/graph/passes/dynamic_single_op_reset_shape_pass.cc b/ge/graph/passes/dynamic_single_op_reset_shape_pass.cc new file mode 100644 index 00000000..e543a9a5 --- /dev/null +++ b/ge/graph/passes/dynamic_single_op_reset_shape_pass.cc @@ -0,0 +1,105 @@ +/** + * 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 kEngineNameAiCpu = "aicpu_ascend_kernel"; +const char *const kEngineNameAiCpuTf = "aicpu_tf_kernel"; +} // namespace +Status DynamicSingleOpResetShapePass::Run(ComputeGraphPtr graph) { + GE_CHECK_NOTNULL(graph); + + std::shared_ptr 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 and output node + if (node->GetType() == DATA || node->GetType() == CONSTANT || node->GetType() == CONSTANTOP || + node->GetType() == NETOUTPUT) { + continue; + } + + // pass node without attr: ATTR_DYNAMIC_SHAPE_SINGLE_AICPU + bool single_aicpu_unknown = false; + if (!AttrUtils::GetBool(node->GetOpDesc(), ATTR_DYNAMIC_SHAPE_SINGLE_AICPU, single_aicpu_unknown) || + !single_aicpu_unknown) { + continue; + } + + // pass not aicpu node. + auto op_desc = node->GetOpDesc(); + string engine_name = op_desc->GetOpEngineName(); + if (engine_name.empty()) { + GELOGE(GRAPH_FAILED, "Get engine failed of node[%s].", node->GetName().c_str()); + return GRAPH_FAILED; + } + if (engine_name != kEngineNameAiCpu && engine_name != kEngineNameAiCpuTf) { + continue; + } + + // reset aicpu shape to unknown shape + if (ResetOpShape(op_desc) != SUCCESS) { + GELOGE(ge::GE_CLI_GE_NOT_INITIALIZED, "Reset node[%s] dynamic shapr failed.", node->GetName().c_str()); + return ge::GE_CLI_GE_NOT_INITIALIZED; + } + 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; +} + +Status DynamicSingleOpResetShapePass::ResetOpShape(OpDescPtr &op_desc) { + GE_CHECK_NOTNULL(op_desc); + std::vector 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(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); + } + for (size_t i = 0; i < op_desc->GetAllOutputsDesc().size(); i++) { + auto output_desc = op_desc->MutableOutputDesc(static_cast(i)); + GE_CHECK_NOTNULL(output_desc); + // pass scalar input desc + auto output_dims_ori = output_desc->GetShape().GetDims(); + if (output_dims_ori.size() == 0) { + continue; + } + output_desc->SetShape(dynamic_shape); + } + return SUCCESS; +} +} // namespace ge \ No newline at end of file diff --git a/ge/graph/passes/dynamic_single_op_reset_shape_pass.h b/ge/graph/passes/dynamic_single_op_reset_shape_pass.h new file mode 100644 index 00000000..9dcc7853 --- /dev/null +++ b/ge/graph/passes/dynamic_single_op_reset_shape_pass.h @@ -0,0 +1,32 @@ +/** + * 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: + Status ResetOpShape(OpDescPtr &op_desc); +}; +} // namespace ge +#endif // GE_GRAPH_PASSES_DYNAMIC_SINGLE_OP_RESET_SHAPE_PASS_H_ From d9783243043f7e51e4cf8ce4c91f0daabdb31149 Mon Sep 17 00:00:00 2001 From: l00444296 Date: Sat, 12 Dec 2020 13:55:38 +0800 Subject: [PATCH 3/3] Feature: reset shape of dynamic single op --- ge/graph/manager/graph_manager.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ge/graph/manager/graph_manager.cc b/ge/graph/manager/graph_manager.cc index c8d20ce3..2f490c41 100755 --- a/ge/graph/manager/graph_manager.cc +++ b/ge/graph/manager/graph_manager.cc @@ -660,7 +660,7 @@ Status GraphManager::SetSubgraph(uint64_t session_id, ComputeGraphPtr compute_gr GE_CHK_STATUS_RET(pass_for_dynamic_shape_reset_optimize.AddPass( "SetSubgraph::AfterSetSubgraph::DynamicSingleOpResetShapePass", new (std::nothrow) DynamicSingleOpResetShapePass)) GE_TIMESTAMP_START(pass_for_dynamic_shape_reset_optimize); - ret = pass_for_dynamic_shape_reset_optimize.Run(compute_graph); + Status ret = pass_for_dynamic_shape_reset_optimize.Run(compute_graph); GE_TIMESTAMP_END(pass_for_dynamic_shape_reset_optimize, "SetSubgraph::AfterSetSubgraph"); if (ret != SUCCESS && ret != NOT_CHANGED) { GELOGE(ret, "Run passes when optimize subgraph failed"); @@ -671,7 +671,7 @@ Status GraphManager::SetSubgraph(uint64_t session_id, ComputeGraphPtr compute_gr GELOGD("Directly optimize subgraph with build mode:%s, and step:%s.", options_.build_mode.c_str(), options_.build_step.c_str()); - Status ret = OptimizeSubGraphWithMultiThreads(compute_graph, sub_graph_map, session_id); + ret = OptimizeSubGraphWithMultiThreads(compute_graph, sub_graph_map, session_id); if (ret != SUCCESS) { GELOGE(ret, "Multiply optimize subgraph failed"); return ret;