From 15c03ba5c6d880f78273731199890ca7c00a2923 Mon Sep 17 00:00:00 2001 From: "gengchao4@huawei.com" Date: Fri, 11 Dec 2020 18:28:40 +0800 Subject: [PATCH] add aclgrphGenerateForOp --- ge/generator/ge_generator.cc | 77 +++++++++++++++----------- ge/ir_build/ge_ir_build.cc | 48 ++++++++++++++++ inc/external/ge/ge_ir_build.h | 15 +++++ inc/framework/generator/ge_generator.h | 15 ++++- 4 files changed, 120 insertions(+), 35 deletions(-) diff --git a/ge/generator/ge_generator.cc b/ge/generator/ge_generator.cc index dc64aac1..a1a45028 100644 --- a/ge/generator/ge_generator.cc +++ b/ge/generator/ge_generator.cc @@ -584,40 +584,11 @@ Status GeGenerator::BuildSingleOp(OpDescPtr &op_desc, const vector &in // 2. Create ComputeGraph. string name = ge::CurrentTimeInStr() + "_" + model_file_name; - ge::ComputeGraphPtr compute_graph = MakeShared(name); - GE_CHECK_NOTNULL_EXEC(compute_graph, return INTERNAL_ERROR); - - // 3. Add Node to ComputeGraph. - NodePtr op_node = compute_graph->AddNode(op_desc); - GE_CHECK_NOTNULL_EXEC(op_node, return INTERNAL_ERROR); - - // 4. Create InputData node. - int32_t arg_index = 0; - if (inputs.empty()) { - for (const auto &input_desc : op_desc->GetAllInputsDescPtr()) { - GE_CHECK_NOTNULL_EXEC(input_desc, return INTERNAL_ERROR); - if (!IsNeedConnectInputOpForSingleOp(*input_desc)) { - continue; - } - GE_CHK_STATUS_RET_NOLOG(AddInputs(compute_graph, op_node, *input_desc, arg_index, false)); - arg_index++; - } - } else { - for (const auto &in_desc : inputs) { - GeTensorDesc input_desc = in_desc.GetTensorDesc(); - GE_CHK_STATUS_RET_NOLOG(AddInputs(compute_graph, op_node, input_desc, arg_index, true)); - arg_index++; - } + Graph graph; + if (BuildSingleOpGraph(op_desc, inputs, outputs, name, graph) != ge::SUCCESS) { + GELOGE(GRAPH_FAILED, "make graph fail."); + return GRAPH_FAILED; } - - // 5. Create Output node. - if (!outputs.empty()) { - GE_CHK_STATUS_RET_NOLOG(AddOutputs(compute_graph, op_node, outputs)); - } - - // dump ComputeGraph. - compute_graph->Dump(); - Graph graph = ge::GraphUtils::CreateGraphFromComputeGraph(compute_graph); GELOGI("ATC parser success in single op build."); GeRootModelPtr ge_root_model = nullptr; @@ -673,6 +644,46 @@ Status GeGenerator::BuildSingleOpModel(OpDescPtr &op_desc, const vector &inputs, + const vector &outputs, std::string graph_name, Graph &graph) { + ge::ComputeGraphPtr compute_graph = MakeShared(graph_name); + GE_CHECK_NOTNULL_EXEC(compute_graph, return INTERNAL_ERROR); + + // 1. Add Node to ComputeGraph. + NodePtr op_node = compute_graph->AddNode(op_desc); + GE_CHECK_NOTNULL_EXEC(op_node, return INTERNAL_ERROR); + + // 2. Create InputData node. + int32_t arg_index = 0; + if (inputs.empty()) { + for (const auto &input_desc : op_desc->GetAllInputsDescPtr()) { + GE_CHECK_NOTNULL_EXEC(input_desc, return INTERNAL_ERROR); + if (!IsNeedConnectInputOpForSingleOp(*input_desc)) { + continue; + } + GE_CHK_STATUS_RET_NOLOG(AddInputs(compute_graph, op_node, *input_desc, arg_index, false)); + arg_index++; + } + } else { + for (const auto &in_desc : inputs) { + GeTensorDesc input_desc = in_desc.GetTensorDesc(); + GE_CHK_STATUS_RET_NOLOG(AddInputs(compute_graph, op_node, input_desc, arg_index, true)); + arg_index++; + } + } + + // 3. Create Output node. + if (!outputs.empty()) { + GE_CHK_STATUS_RET_NOLOG(AddOutputs(compute_graph, op_node, outputs)); + } + + // dump ComputeGraph node. + compute_graph->Dump(); + graph = ge::GraphUtils::CreateGraphFromComputeGraph(compute_graph); + + return SUCCESS; +} + Status GeGenerator::Impl::SaveParams(GeModelPtr &ge_model, const string &type, const map &attrs, const vector &inputs, const vector &outputs) { GE_CHECK_NOTNULL_EXEC(ge_model, return PARAM_INVALID); diff --git a/ge/ir_build/ge_ir_build.cc b/ge/ir_build/ge_ir_build.cc index c010a690..01c8c558 100644 --- a/ge/ir_build/ge_ir_build.cc +++ b/ge/ir_build/ge_ir_build.cc @@ -710,4 +710,52 @@ graphStatus aclgrphDumpGraph(const ge::Graph &graph, const char *file, const siz return GRAPH_SUCCESS; } +graphStatus aclgrphGenerateForOp(const AscendString &op_type, const vector &inputs, + const vector &outputs, Graph &graph) { + auto op_type_str = std::string(op_type.GetString()); + auto op_name = op_type_str + "_" + std::to_string(ge::GetCurrentTimestamp()); + auto op_desc = ge::MakeShared(op_name, op_type_str); + GE_CHECK_NOTNULL(op_desc); + + // convert input tensordesc to getensor + std::vector input_tensors; + for (const auto &input : inputs) { + ge::GeTensorDesc tensor_desc(ge::GeShape(input.GetShape().GetDims()), input.GetFormat(), input.GetDataType()); + + tensor_desc.SetOriginFormat(input.GetFormat()); + ge::TensorUtils::SetRealDimCnt(tensor_desc, static_cast(input.GetShape().GetDims().size())); + ge::TensorUtils::SetInputTensor(tensor_desc, true); + ge::TensorUtils::SetOutputTensor(tensor_desc, false); + + if (op_desc->AddInputDesc(tensor_desc) != ge::GRAPH_SUCCESS) { + GELOGE(ge::FAILED, "AddInputDesc fail."); + return ge::FAILED; + } + input_tensors.emplace_back(tensor_desc); + } + + // convert output tensordesc to getensor + std::vector output_tensors; + for (const auto &output : outputs) { + ge::GeTensorDesc tensor_desc(ge::GeShape(output.GetShape().GetDims()), output.GetFormat(), output.GetDataType()); + + tensor_desc.SetOriginFormat(output.GetFormat()); + ge::TensorUtils::SetRealDimCnt(tensor_desc, static_cast(output.GetShape().GetDims().size())); + ge::TensorUtils::SetInputTensor(tensor_desc, false); + ge::TensorUtils::SetOutputTensor(tensor_desc, true); + + (void)op_desc->AddOutputDesc(tensor_desc); + output_tensors.emplace_back(tensor_desc); + } + + // call api to get graph + ge::GeGenerator generator; + std::string graph_name = ge::CurrentTimeInStr() + "_graph"; + if (generator.BuildSingleOpGraph(op_desc, input_tensors, output_tensors, graph_name, graph) != ge::SUCCESS) { + GELOGE(GRAPH_FAILED, "make graph fail."); + return GRAPH_FAILED; + } + return GRAPH_SUCCESS; +} + } // namespace ge diff --git a/inc/external/ge/ge_ir_build.h b/inc/external/ge/ge_ir_build.h index 778ec21d..19821e1a 100644 --- a/inc/external/ge/ge_ir_build.h +++ b/inc/external/ge/ge_ir_build.h @@ -121,5 +121,20 @@ graphStatus aclgrphInferShapeAndType(ge::Graph &graph); * @retval OtherValues Failure */ graphStatus aclgrphDumpGraph(const ge::Graph &graph, const char *file, const size_t len); + +/** + * @ingroup AscendCL + * @brief create single op graph + * + * @param op_type[IN] the op_type + * @param inputs[IN] the inputdesc + * @param outputs[IN] the outputdesc + * @param graph[OUT] the graph + * @retval GRAPH_SUCCESS The function is successfully executed. + * @retval OtherValues Failure + */ +graphStatus aclgrphGenerateForOp(const AscendString &op_type, const std::vector &inputs, + const std::vector &outputs, Graph &graph); + }; // namespace ge #endif // INC_EXTERNAL_GE_IR_BUILD_H_ diff --git a/inc/framework/generator/ge_generator.h b/inc/framework/generator/ge_generator.h index c446b983..e0904965 100644 --- a/inc/framework/generator/ge_generator.h +++ b/inc/framework/generator/ge_generator.h @@ -74,11 +74,22 @@ class GeGenerator { /// @param [in] op_desc: the OP description. /// @param [in] inputs: input tensors. /// @param [in] outputs: output tensors. - /// @param [in] engine_type: specific engine. - /// @param [out] model_buff: model buff of single op. + /// @param [in] engine_type: engine type. + /// @param [out] model_buff: model buff of op. /// @return SUCCESS or FAILED Status BuildSingleOpModel(OpDescPtr &op_desc, const vector &inputs, const vector &outputs, OpEngineType engine_type, ModelBufferData &model_buff); + /// + /// @ingroup ge + /// @brief: Build single Op into model buff. + /// @param [in] op_desc: the OP description. + /// @param [in] inputs: input tensors. + /// @param [in] outputs: output tensors. + /// @param [in] graph_name: graph name. + /// @param [out] graph: graph of single op. + /// @return SUCCESS or FAILED + Status BuildSingleOpGraph(OpDescPtr &op_desc, const vector &inputs, const vector &outputs, + std::string graph_name, Graph &graph); private: Status GenerateModel(const Graph &graph, const string &file_name_prefix, const vector &inputs,