* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
#include "dvpp_optimizer.h"
#include "common/dvpp_ops_checker.h"
#include "common/dvpp_ops_lib.h"
#include "util/dvpp_constexpr.h"
#include "util/dvpp_define.h"
#include "util/dvpp_error_code.h"
#include "util/dvpp_log.h"
#include "util/util.h"
#include "graph/debug/ge_attr_define.h"
#include "graph/utils/graph_utils.h"
#include "graph/utils/op_desc_utils.h"
namespace dvpp {
bool DvppOptimizer::EnableDvppEngine(ge::OpDescPtr& op_desc_ptr) const {
bool performance_prior = false;
bool ret = ge::AttrUtils::GetBool(
op_desc_ptr, ATTR_NAME_PERFORMANCE_PRIOR, performance_prior);
DVPP_CHECK_IF_THEN_DO(!ret, return false);
return performance_prior;
}
bool DvppOptimizer::CheckSupportedSingleOpGraph(ge::ComputeGraph& graph)
const {
for (auto& node : graph.GetDirectNode()) {
DVPP_CHECK_IF_THEN_DO((node->GetType() == kNodeData) ||
(node->GetType() == kNodeNetOutput) ||
(node->GetType() == kNodeConst) || (node->GetType() == kNodeConstant),
continue);
auto op_desc_ptr = node->GetOpDesc();
bool enable_dvpp_engine = EnableDvppEngine(op_desc_ptr);
DVPP_CHECK_IF_THEN_DO(!enable_dvpp_engine, return false);
DVPP_ENGINE_LOG_DEBUG("dvpp engine is enable to op[%s].",
op_desc_ptr->GetType().c_str());
std::string unsupported_reason;
return DvppOpsChecker::CheckSupported(node, unsupported_reason);
}
return false;
}
在Pytorch单算子场景下,把所有data节点输入、输出shape设置为动态shape
1)常规算子,将data节点的根据dim num的设置shape为dim num个 -1
2)特殊算子(Decode算子),DT_STRING类型,将data节点shape设置为 {-2}
*/
DvppErrorCode DvppOptimizer::SetGraphDynamicShape(ge::ComputeGraph& graph) {
DVPP_ENGINE_LOG_DEBUG("dvpp optimizer SetGraphDynamicShape start.");
for (auto& node : graph.GetDirectNode()) {
DVPP_CHECK_IF_THEN_DO(node->GetType() != kNodeData, continue);
auto op_desc_ptr = node->GetOpDesc();
DVPP_CHECK_NOTNULL(op_desc_ptr);
auto input = op_desc_ptr->MutableInputDesc(0);
DVPP_CHECK_NOTNULL(input);
auto output = op_desc_ptr->MutableOutputDesc(0);
DVPP_CHECK_NOTNULL(output);
ge::GeShape dynamic_shape;
if (input->GetDataType() == ge::DT_STRING) {
dynamic_shape = ge::GeShape({kDynamicShape});
} else {
std::vector<int64_t> dims = input->GetShape().GetDims();
dynamic_shape = ge::GeShape(std::vector<int64_t>(dims.size(),
kDynamicDim));
std::vector<std::pair<int64_t, int64_t>> range;
GetShapeRangeByDataFormat(range, dims, input->GetFormat());
input->SetShapeRange(range);
input->SetOriginShapeRange(range);
output->SetShapeRange(range);
output->SetOriginShapeRange(range);
}
input->SetOriginShape(ge::GeShape(dynamic_shape));
input->SetShape(ge::GeShape(dynamic_shape));
output->SetOriginShape(ge::GeShape(dynamic_shape));
output->SetShape(ge::GeShape(dynamic_shape));
}
DVPP_ENGINE_LOG_DEBUG("dvpp optimizer SetGraphDynamicShape success.");
return DvppErrorCode::kSuccess;
}
DvppErrorCode DvppOptimizer::OptimizeGraphPrepare(ge::ComputeGraph& graph) {
DVPP_ENGINE_LOG_DEBUG("dvpp optimizer OptimizeGraphPrepare start.");
bool is_single_op = false;
(void)ge::AttrUtils::GetBool(graph, ge::ATTR_SINGLE_OP_SCENE, is_single_op);
DVPP_CHECK_IF_THEN_DO(!is_single_op, return DvppErrorCode::kSuccess);
DVPP_ENGINE_LOG_DEBUG("this graph is single op graph.");
bool is_support = CheckSupportedSingleOpGraph(graph);
DVPP_CHECK_IF_THEN_DO(!is_support, return DvppErrorCode::kSuccess);
DVPP_ENGINE_LOG_DEBUG("dvpp support this single op graph.");
auto error = SetGraphDynamicShape(graph);
DVPP_CHECK_IF_THEN_DO(error != DvppErrorCode::kSuccess,
DVPP_REPORT_INNER_ERR_MSG("set graph dynamic shape failed");
return error);
DVPP_ENGINE_LOG_DEBUG("dvpp optimizer OptimizeGraphPrepare success.");
return DvppErrorCode::kSuccess;
}
DvppErrorCode DvppOptimizer::SubAndMulFusedIntoNormalizeV2(
ge::ComputeGraph& graph, ge::NodePtr& mul_node) const {
auto sub_node = mul_node->GetInDataNodes().at(kNum0);
auto const_2_node = mul_node->GetInDataNodes().at(kNum1);
auto const_1_node = sub_node->GetInDataNodes().at(kNum1);
ge::ComputeGraphPtr graph_ptr = graph.shared_from_this();
ge::NodePtr normalize_v2_node = InsertGraphNodeBefore(
graph_ptr, mul_node, kDvppOpNormalizeV2);
DVPP_CHECK_IF_THEN_DO(normalize_v2_node == nullptr,
DVPP_REPORT_INNER_ERR_MSG("insert NormalizeV2 node failed");
return DvppErrorCode::kFailed);
auto op_desc = normalize_v2_node->GetOpDesc();
auto ret = SetDvppOpAttr(op_desc);
DVPP_CHECK_IF_THEN_DO(ret != DvppErrorCode::kSuccess,
DVPP_REPORT_INNER_ERR_MSG("NormalizeV2 set dvpp op attr failed");
return DvppErrorCode::kFailed);
auto const_1_anchor = const_1_node->GetOutDataAnchor(kNum0);
auto normalize_v2_anchor = normalize_v2_node->GetInDataAnchor(kNum1);
auto error = ge::GraphUtils::AddEdge(const_1_anchor, normalize_v2_anchor);
DVPP_CHECK_IF_THEN_DO(error != ge::GRAPH_SUCCESS,
DVPP_REPORT_INNER_ERR_MSG("add edge Const1 and NormalizeV2 failed,%d.",
error);
return DvppErrorCode::kFailed);
auto const_2_anchor = const_2_node->GetOutDataAnchor(kNum0);
normalize_v2_anchor = normalize_v2_node->GetInDataAnchor(kNum2);
error = ge::GraphUtils::AddEdge(const_2_anchor, normalize_v2_anchor);
DVPP_CHECK_IF_THEN_DO(error != ge::GRAPH_SUCCESS,
DVPP_REPORT_INNER_ERR_MSG("add edge Const2 and NormalizeV2 failed, %d",
error);
return DvppErrorCode::kFailed);
error = graph.RemoveNode(sub_node);
DVPP_CHECK_IF_THEN_DO(error != ge::GRAPH_SUCCESS,
DVPP_REPORT_INNER_ERR_MSG("remove Sub node failed, error:%d", error);
return DvppErrorCode::kFailed);
error = graph.RemoveNode(mul_node);
DVPP_CHECK_IF_THEN_DO(error != ge::GRAPH_SUCCESS,
DVPP_REPORT_INNER_ERR_MSG("remove Mul node failed, error:%d", error);
return DvppErrorCode::kFailed);
return DvppErrorCode::kSuccess;
}
DvppErrorCode DvppOptimizer::SpecialOptimize(
ge::ComputeGraph& graph, ge::NodePtr& node) const {
bool ret = DvppOpsChecker::CheckSubAndMulFusedIntoNormalizeV2(node);
DVPP_CHECK_IF_THEN_DO(!ret, return DvppErrorCode::kFailed);
DVPP_ENGINE_LOG_DEBUG("dvpp support Sub and Mul fused into NormalizeV2");
auto error = SubAndMulFusedIntoNormalizeV2(graph, node);
DVPP_CHECK_IF_THEN_DO(error != DvppErrorCode::kSuccess, return error);
DVPP_ENGINE_LOG_DEBUG("Sub and Mul fused into NormalizeV2 success");
return DvppErrorCode::kSuccess;
}
DvppErrorCode DvppOptimizer::SetMemoryType(ge::OpDescPtr& op_desc_ptr) const {
std::string op_type = op_desc_ptr->GetType();
DvppOpInfo dvpp_op_info;
bool ret = DvppOpsLib::Instance().GetDvppOpInfo(op_type, dvpp_op_info);
DVPP_CHECK_IF_THEN_DO(!ret,
DVPP_REPORT_INNER_ERR_MSG("can not find op[%s] in dvpp info store.",
op_type.c_str());
return DvppErrorCode::kFailed);
int64_t memory_type = 2;
DVPP_CHECK_IF_THEN_DO(memory_type == 2, return DvppErrorCode::kSuccess);
size_t inputs_size = op_desc_ptr->GetInputsSize();
std::vector<int64_t> inputs_memory_type(inputs_size, memory_type);
ret = ge::AttrUtils::SetListInt(
op_desc_ptr, ge::ATTR_NAME_INPUT_MEM_TYPE_LIST, inputs_memory_type);
DVPP_CHECK_IF_THEN_DO(!ret,
DVPP_REPORT_INNER_ERR_MSG("op[%s] set input memory type failed",
op_type.c_str());
return DvppErrorCode::kFailed);
size_t outputs_size = op_desc_ptr->GetOutputsSize();
std::vector<int64_t> outputs_memory_type(outputs_size, memory_type);
ret = ge::AttrUtils::SetListInt(
op_desc_ptr, ge::ATTR_NAME_OUTPUT_MEM_TYPE_LIST, outputs_memory_type);
DVPP_CHECK_IF_THEN_DO(!ret,
DVPP_REPORT_INNER_ERR_MSG("op[%s] set output memory type failed",
op_type.c_str());
return DvppErrorCode::kFailed);
return DvppErrorCode::kSuccess;
}
DvppErrorCode DvppOptimizer::SetDvppOpAttr(ge::OpDescPtr& op_desc_ptr) const {
DVPP_CHECK_NOTNULL(op_desc_ptr);
bool ret = ge::AttrUtils::SetStr(
op_desc_ptr, ge::ATTR_NAME_OP_SPECIFIED_ENGINE_NAME, kDvppEngineName);
DVPP_CHECK_IF_THEN_DO(!ret,
DVPP_REPORT_INNER_ERR_MSG("op[%s] set op specified engine name failed",
op_desc_ptr->GetType().c_str());
return DvppErrorCode::kFailed);
ret = ge::AttrUtils::SetStr(op_desc_ptr,
ge::ATTR_NAME_OP_SPECIFIED_KERNEL_LIB_NAME, kDvppOpsKernel);
DVPP_CHECK_IF_THEN_DO(!ret,
DVPP_REPORT_INNER_ERR_MSG("op[%s] set op specified kernel lib name failed",
op_desc_ptr->GetType().c_str());
return DvppErrorCode::kFailed);
ret = ge::AttrUtils::SetBool(
op_desc_ptr, ge::ATTR_NAME_FORCE_UNKNOWN_SHAPE, true);
DVPP_CHECK_IF_THEN_DO(!ret,
DVPP_REPORT_INNER_ERR_MSG("op[%s] set force unknown shape failed",
op_desc_ptr->GetType().c_str());
return DvppErrorCode::kFailed);
auto error = SetMemoryType(op_desc_ptr);
DVPP_CHECK_IF_THEN_DO(error != DvppErrorCode::kSuccess,
DVPP_REPORT_INNER_ERR_MSG("op[%s] set memory type failed",
op_desc_ptr->GetType().c_str());
return error);
return DvppErrorCode::kSuccess;
}
DvppErrorCode DvppOptimizer::SetAiCpuOpAttr(ge::OpDescPtr& op_desc_ptr) const {
DVPP_CHECK_NOTNULL(op_desc_ptr);
bool ret = ge::AttrUtils::SetStr(
op_desc_ptr, ge::ATTR_NAME_OP_SPECIFIED_ENGINE_NAME, kAiCpuEngineName);
DVPP_CHECK_IF_THEN_DO(!ret,
DVPP_REPORT_INNER_ERR_MSG("op[%s] set op specified engine name failed.",
op_desc_ptr->GetType().c_str());
return DvppErrorCode::kFailed);
ret = ge::AttrUtils::SetStr(op_desc_ptr,
ge::ATTR_NAME_OP_SPECIFIED_KERNEL_LIB_NAME, kAiCpuDecodeOpsKernel);
DVPP_CHECK_IF_THEN_DO(!ret,
DVPP_REPORT_INNER_ERR_MSG("op[%s] set op specified kernel lib name failed.",
op_desc_ptr->GetType().c_str());
return DvppErrorCode::kFailed);
ret = ge::AttrUtils::SetBool(
op_desc_ptr, ge::ATTR_NAME_FORCE_UNKNOWN_SHAPE, true);
DVPP_CHECK_IF_THEN_DO(!ret,
DVPP_REPORT_INNER_ERR_MSG("op[%s] set force unknown shape failed",
op_desc_ptr->GetType().c_str());
return DvppErrorCode::kFailed);
return DvppErrorCode::kSuccess;
}
DvppErrorCode DvppOptimizer::GetParentGraphSessionId(
ge::ComputeGraphPtr graph,
std::string& parent_graph_session_id) const {
bool ret = ge::AttrUtils::GetStr(graph, ge::ATTR_NAME_SESSION_GRAPH_ID,
parent_graph_session_id);
DVPP_CHECK_IF_THEN_DO(!ret,
DVPP_REPORT_INNER_ERR_MSG("get parent graph session id failed.");
return DvppErrorCode::kFailed);
return DvppErrorCode::kSuccess;
}
DvppErrorCode DvppOptimizer::SetSubgraphParentSessionId(
ge::ComputeGraphPtr& then_graph, ge::ComputeGraphPtr& else_graph,
std::string& parent_graph_session_id) const {
bool ret = ge::AttrUtils::SetStr(then_graph, ge::ATTR_NAME_SESSION_GRAPH_ID,
parent_graph_session_id);
DVPP_CHECK_IF_THEN_DO(!ret,
DVPP_REPORT_INNER_ERR_MSG("set then_graph parent graph session id failed.");
return DvppErrorCode::kFailed);
ret = ge::AttrUtils::SetStr(else_graph, ge::ATTR_NAME_SESSION_GRAPH_ID,
parent_graph_session_id);
DVPP_CHECK_IF_THEN_DO(!ret,
DVPP_REPORT_INNER_ERR_MSG("set else_graph parent graph session id failed.");
return DvppErrorCode::kFailed);
return DvppErrorCode::kSuccess;
}
ge::NodePtr DvppOptimizer::InsertGraphNodeBefore(ge::ComputeGraphPtr& graph,
ge::NodePtr& node, const std::string& op_type) const {
ge::OpDescPtr op_desc_ptr = nullptr;
auto ret = DvppErrorCode::kFailed;
if (op_type == kDvppOpIf) {
ret = DvppOpsLib::Instance().CreateIfOpDesc(node->GetType(), op_desc_ptr);
} else {
ret = DvppOpsLib::Instance().CreateDvppOpDesc(op_type, op_desc_ptr);
}
DVPP_CHECK_IF_THEN_DO(ret != DvppErrorCode::kSuccess,
DVPP_REPORT_INNER_ERR_MSG("create op[%s] failed.", op_type.c_str());
return nullptr);
ge::NodePtr insert_node = graph->AddNode(op_desc_ptr);
DVPP_CHECK_IF_THEN_DO(insert_node == nullptr,
DVPP_REPORT_INNER_ERR_MSG("create node[%s] failed.", op_type.c_str());
return nullptr);
auto in_data_anchor = node->GetInDataAnchor(0);
auto error = ge::GraphUtils::InsertNodeBefore(in_data_anchor, insert_node);
DVPP_CHECK_IF_THEN_DO(error != ge::GRAPH_SUCCESS,
DVPP_REPORT_INNER_ERR_MSG("insert node[%s] before node[%s] failed.",
op_type.c_str(), node->GetType().c_str());
return nullptr);
return insert_node;
}
DvppErrorCode DvppOptimizer::InsertNodeAfter(ge::NodePtr& node,
ge::NodePtr& insert_node) const {
auto out_anchor = node->GetOutDataAnchor(0);
DVPP_CHECK_NOTNULL(out_anchor);
auto peer_in_anchors = out_anchor->GetPeerInDataAnchors();
std::vector<ge::InDataAnchorPtr> in_anchors(peer_in_anchors.begin(),
peer_in_anchors.end());
auto error = ge::GraphUtils::InsertNodeAfter(out_anchor, in_anchors,
insert_node);
DVPP_CHECK_IF_THEN_DO(error != ge::GRAPH_SUCCESS,
DVPP_REPORT_INNER_ERR_MSG("insert node[%s] after node[%s] failed",
insert_node->GetType().c_str(),
node->GetType().c_str());
return DvppErrorCode::kFailed);
return DvppErrorCode::kSuccess;
}
ge::NodePtr DvppOptimizer::InsertGraphNodeAfter(ge::ComputeGraphPtr& graph,
ge::NodePtr& node, const std::string& op_type) const {
auto insert_node = GraphAddNode(graph, op_type);
DVPP_CHECK_IF_THEN_DO(insert_node == nullptr, return nullptr);
auto ret = InsertNodeAfter(node, insert_node);
DVPP_CHECK_IF_THEN_DO(ret != DvppErrorCode::kSuccess, return nullptr);
return insert_node;
}
DvppErrorCode DvppOptimizer::SetSubgraphDataIndex(ge::NodePtr& data_node,
uint32_t data_index, ge::NodePtr& output_node,
uint32_t output_index) const {
bool ret = ge::AttrUtils::SetInt(data_node->GetOpDesc(),
ge::ATTR_NAME_PARENT_NODE_INDEX, data_index);
DVPP_CHECK_IF_THEN_DO(!ret,
DVPP_REPORT_INNER_ERR_MSG("set node[%s] subgraph index[%u] failed.",
data_node->GetType().c_str(), data_index);
return DvppErrorCode::kFailed);
ret = ge::AttrUtils::SetInt(
output_node->GetOpDesc()->MutableInputDesc(output_index),
ge::ATTR_NAME_PARENT_NODE_INDEX, output_index);
DVPP_CHECK_IF_THEN_DO(!ret,
DVPP_REPORT_INNER_ERR_MSG("set node[%s] subgraph index[%u] failed.",
output_node->GetType().c_str(), output_index);
return DvppErrorCode::kFailed);
return DvppErrorCode::kSuccess;
}
DvppErrorCode DvppOptimizer::InsertDataNodeInIfSubgraph(
ge::ComputeGraphPtr& subgraph, ge::NodePtr& node) const {
ge::OpDescPtr op_desc_ptr = nullptr;
auto ret = DvppOpsLib::Instance().CreateDvppOpDesc(kNodeData, op_desc_ptr);
DVPP_CHECK_IF_THEN_DO(ret != DvppErrorCode::kSuccess,
DVPP_REPORT_INNER_ERR_MSG("create op[%s] failed.", kNodeData.c_str());
return DvppErrorCode::kFailed);
auto input_desc = op_desc_ptr->MutableInputDesc("x");
input_desc->SetDataType(ge::DT_INT32);
input_desc->SetShape(ge::GeShape(std::vector<int64_t>{kNum4}));
auto output_desc = op_desc_ptr->MutableOutputDesc("y");
output_desc->SetDataType(ge::DT_INT32);
output_desc->SetShape(ge::GeShape(std::vector<int64_t>{kNum4}));
ge::NodePtr insert_node = subgraph->AddNode(op_desc_ptr);
DVPP_CHECK_IF_THEN_DO(insert_node == nullptr,
DVPP_REPORT_INNER_ERR_MSG("create insert node[%s] failed.",
kNodeData.c_str());
return DvppErrorCode::kFailed);
auto insert_node_out_anchor = insert_node->GetOutDataAnchor(0);
auto node_in_anchor = node->GetInDataAnchor(kNum1);
auto error = ge::GraphUtils::AddEdge(insert_node_out_anchor, node_in_anchor);
DVPP_CHECK_IF_THEN_DO(error != ge::GRAPH_SUCCESS,
DVPP_REPORT_INNER_ERR_MSG("add edge between node[%s] and node[%s] failed.",
kNodeData.c_str(), node->GetType().c_str());
return DvppErrorCode::kFailed);
bool result = ge::AttrUtils::SetInt(insert_node->GetOpDesc(),
ge::ATTR_NAME_PARENT_NODE_INDEX, kNum2);
DVPP_CHECK_IF_THEN_DO(!result,
DVPP_REPORT_INNER_ERR_MSG("set node[%s] subgraph index[2] failed.",
insert_node->GetType().c_str());
return DvppErrorCode::kFailed);
return DvppErrorCode::kSuccess;
}
DvppErrorCode DvppOptimizer::BuildIfThenGraph(
ge::ComputeGraphPtr& then_graph, ge::NodePtr& node) const {
ge::OpDescPtr data_op_desc_ptr = nullptr;
auto ret = DvppOpsLib::Instance().CreateDvppOpDesc(kNodeData,
data_op_desc_ptr);
DVPP_CHECK_IF_THEN_DO(ret != DvppErrorCode::kSuccess,
DVPP_REPORT_INNER_ERR_MSG("create op[%s] failed", kNodeData.c_str());
return DvppErrorCode::kFailed);
ge::NodePtr data_node = then_graph->AddNode(data_op_desc_ptr);
DVPP_CHECK_NOTNULL(data_node);
ge::NodePtr decode_node = then_graph->AddNode(node);
DVPP_CHECK_NOTNULL(decode_node);
decode_node->SetOwnerComputeGraph(then_graph);
ret = InsertNodeAfter(data_node, decode_node);
DVPP_CHECK_IF_THEN_DO(ret != DvppErrorCode::kSuccess,
return DvppErrorCode::kFailed);
auto op_desc = decode_node->GetOpDesc();
ret = SetDvppOpAttr(op_desc);
DVPP_CHECK_IF_THEN_DO(ret != DvppErrorCode::kSuccess,
DVPP_REPORT_INNER_ERR_MSG("op[%s] set dvpp op attr failed",
op_desc->GetType().c_str());
return DvppErrorCode::kFailed);
bool result = ge::AttrUtils::SetBool(op_desc, ge::NEED_INFER, true);
DVPP_CHECK_IF_THEN_DO(!result,
DVPP_REPORT_INNER_ERR_MSG("set op[%s] need infer attr failed.",
op_desc->GetType().c_str());
return DvppErrorCode::kFailed);
ge::NodePtr output_node = InsertGraphNodeAfter(then_graph, decode_node,
kNodeNetOutput);
DVPP_CHECK_NOTNULL(output_node);
ret = SetSubgraphDataIndex(data_node, 1, output_node, 0);
DVPP_CHECK_IF_THEN_DO(ret != DvppErrorCode::kSuccess,
DVPP_REPORT_INNER_ERR_MSG("set then subgraph data index failed.");
return DvppErrorCode::kFailed);
if (decode_node->GetType() == kDvppOpDecodeAndCropJpeg) {
return InsertDataNodeInIfSubgraph(then_graph, decode_node);
}
return DvppErrorCode::kSuccess;
}
DvppErrorCode DvppOptimizer::BuildIfElseGraph(
ge::ComputeGraphPtr& else_graph, ge::OpDescPtr& op_desc) const {
ge::OpDescPtr data_op_desc_ptr = nullptr;
auto ret = DvppOpsLib::Instance().CreateDvppOpDesc(kNodeData,
data_op_desc_ptr);
DVPP_CHECK_IF_THEN_DO(ret != DvppErrorCode::kSuccess,
DVPP_REPORT_INNER_ERR_MSG("create op[%s] failed", kNodeData.c_str());
return DvppErrorCode::kFailed);
ge::NodePtr data_node = else_graph->AddNode(data_op_desc_ptr);
DVPP_CHECK_NOTNULL(data_node);
ge::NodePtr decode_node = else_graph->AddNode(op_desc);
DVPP_CHECK_NOTNULL(decode_node);
decode_node->SetOwnerComputeGraph(else_graph);
ret = InsertNodeAfter(data_node, decode_node);
DVPP_CHECK_IF_THEN_DO(ret != DvppErrorCode::kSuccess,
return DvppErrorCode::kFailed);
auto decode_op_desc = decode_node->GetOpDesc();
ret = SetAiCpuOpAttr(decode_op_desc);
DVPP_CHECK_IF_THEN_DO(ret != DvppErrorCode::kSuccess,
DVPP_REPORT_INNER_ERR_MSG("op[%s] set dvpp op attr failed",
decode_op_desc->GetType().c_str());
return DvppErrorCode::kFailed);
bool result = ge::AttrUtils::SetBool(decode_op_desc, ge::NEED_INFER, true);
DVPP_CHECK_IF_THEN_DO(!result,
DVPP_REPORT_INNER_ERR_MSG("set op[%s] need infer attr failed.",
decode_op_desc->GetType().c_str());
return DvppErrorCode::kFailed);
ge::NodePtr output_node = InsertGraphNodeAfter(else_graph, decode_node,
kNodeNetOutput);
DVPP_CHECK_NOTNULL(output_node);
ret = SetSubgraphDataIndex(data_node, 1, output_node, 0);
DVPP_CHECK_IF_THEN_DO(ret != DvppErrorCode::kSuccess,
DVPP_REPORT_INNER_ERR_MSG("set else subgraph data index failed.");
return DvppErrorCode::kFailed);
if (decode_node->GetType() == kDvppOpDecodeAndCropJpeg) {
return InsertDataNodeInIfSubgraph(else_graph, decode_node);
}
return DvppErrorCode::kSuccess;
}
* Data
* |
* Data DecodeJpeg
* | then_subgraph |
* DecodeJpegPre / NetOutput
* Data | /
* | If -----
* DecodeJpeg ===> | \ Data
* | | \ |
* NetOutput NetOutput else_subgraph DecodeJpeg
* |
* NetOutput
*/
DvppErrorCode DvppOptimizer::InsertIfGraph(
ge::ComputeGraph& graph, ge::NodePtr& node) const {
ge::ComputeGraphPtr graph_ptr = graph.shared_from_this();
auto node_input_desc = node->GetOpDesc()->GetInputDesc("contents");
auto node_output_desc = node->GetOpDesc()->GetOutputDesc("image");
ge::NodePtr pre_node = InsertGraphNodeBefore(graph_ptr, node,
kDvppOpDecodeJpegPre);
DVPP_CHECK_NOTNULL(pre_node);
ge::NodePtr if_node = InsertGraphNodeBefore(graph_ptr, node, kDvppOpIf);
DVPP_CHECK_NOTNULL(if_node);
auto input0_anchor = pre_node->GetInDataAnchor(0);
DVPP_CHECK_NOTNULL(input0_anchor);
auto input0_peer_anchor = input0_anchor->GetFirstPeerAnchor();
auto input1_anchor = if_node->GetInDataAnchor(1);
auto error = ge::GraphUtils::AddEdge(input0_peer_anchor, input1_anchor);
DVPP_CHECK_IF_THEN_DO(error != ge::GRAPH_SUCCESS,
DVPP_REPORT_INNER_ERR_MSG("add edge DecodeJpegPre input0 and If input1");
return DvppErrorCode::kFailed);
if (node->GetType() == kDvppOpDecodeAndCropJpeg) {
auto data1_anchor = node->GetInDataAnchor(1);
DVPP_CHECK_NOTNULL(data1_anchor);
auto data1_peer_anchor = data1_anchor->GetFirstPeerAnchor();
auto data2_anchor = if_node->GetInDataAnchor(kNum2);
error = ge::GraphUtils::AddEdge(data1_peer_anchor, data2_anchor);
DVPP_CHECK_IF_THEN_DO(error != ge::GRAPH_SUCCESS,
DVPP_REPORT_INNER_ERR_MSG("add edge Data node input0 and If input2");
return DvppErrorCode::kFailed);
}
error = graph.RemoveNode(node);
DVPP_CHECK_IF_THEN_DO(error != ge::GRAPH_SUCCESS,
DVPP_REPORT_INNER_ERR_MSG("remove node failed, error:%d", error);
return DvppErrorCode::kFailed);
ge::OpDescPtr new_op_desc = ge::AttrUtils::CopyOpDesc(node->GetOpDesc());
DVPP_CHECK_NOTNULL(new_op_desc);
const std::string then_name = "dvpp_decode_if_then";
ge::ComputeGraphPtr then_graph = nullptr;
DVPP_TRY_CATCH(then_graph = std::make_shared<ge::ComputeGraph>(then_name),
DVPP_REPORT_INNER_ERR_MSG("make shared then subgraph failed.");
return DvppErrorCode::kFailed);
auto ret = BuildIfThenGraph(then_graph, node);
DVPP_CHECK_IF_THEN_DO(ret != DvppErrorCode::kSuccess,
DVPP_REPORT_INNER_ERR_MSG("build then graph failed.");
return DvppErrorCode::kFailed);
then_graph->SetParentNode(if_node);
then_graph->SetParentGraph(graph.shared_from_this());
if_node->GetOpDesc()->AddSubgraphName(then_name);
if_node->GetOpDesc()->SetSubgraphInstanceName(0, then_name);
ge::ComputeGraphPtr root_graph =
ge::GraphUtils::FindRootGraph(graph.shared_from_this());
DVPP_CHECK_NOTNULL(root_graph);
error = root_graph->AddSubgraph(then_graph);
DVPP_CHECK_IF_THEN_DO(error != ge::GRAPH_SUCCESS,
DVPP_REPORT_INNER_ERR_MSG("add then subgraph failed, error:%d", error);
return DvppErrorCode::kFailed);
const std::string else_name = "dvpp_decode_if_else";
ge::ComputeGraphPtr else_graph = nullptr;
DVPP_TRY_CATCH(else_graph = std::make_shared<ge::ComputeGraph>(else_name),
DVPP_REPORT_INNER_ERR_MSG("make shared else subgraph failed.");
return DvppErrorCode::kFailed);
ret = BuildIfElseGraph(else_graph, new_op_desc);
DVPP_CHECK_IF_THEN_DO(ret != DvppErrorCode::kSuccess,
DVPP_REPORT_INNER_ERR_MSG("build then graph failed.");
return DvppErrorCode::kFailed);
else_graph->SetParentNode(if_node);
else_graph->SetParentGraph(graph.shared_from_this());
if_node->GetOpDesc()->AddSubgraphName(else_name);
if_node->GetOpDesc()->SetSubgraphInstanceName(1, else_name);
if_node->GetOpDesc()->UpdateInputDesc(1, node_input_desc);
if_node->GetOpDesc()->UpdateOutputDesc(0, node_output_desc);
error = root_graph->AddSubgraph(else_graph);
DVPP_CHECK_IF_THEN_DO(error != ge::GRAPH_SUCCESS,
DVPP_REPORT_INNER_ERR_MSG("add else subgraph failed, error:%d", error);
return DvppErrorCode::kFailed);
std::string parent_graph_session_id{};
ret = GetParentGraphSessionId(graph.shared_from_this(),
parent_graph_session_id);
DVPP_CHECK_IF_THEN_DO(ret != DvppErrorCode::kSuccess,
return DvppErrorCode::kFailed);
ret = SetSubgraphParentSessionId(then_graph, else_graph,
parent_graph_session_id);
DVPP_CHECK_IF_THEN_DO(ret != DvppErrorCode::kSuccess,
return DvppErrorCode::kFailed);
return DvppErrorCode::kSuccess;
}
ge::NodePtr DvppOptimizer::GraphAddNode(ge::ComputeGraphPtr& graph,
const std::string& op_type) const {
ge::OpDescPtr op_desc_ptr = nullptr;
auto ret = DvppOpsLib::Instance().CreateDvppOpDesc(op_type, op_desc_ptr);
DVPP_CHECK_IF_THEN_DO(ret != DvppErrorCode::kSuccess,
DVPP_REPORT_INNER_ERR_MSG("create op[%s] failed.", op_type.c_str());
return nullptr);
ge::NodePtr insert_node = graph->AddNode(op_desc_ptr);
DVPP_CHECK_IF_THEN_DO(insert_node == nullptr,
DVPP_REPORT_INNER_ERR_MSG("create insert node[%s] failed.",
op_type.c_str());
return nullptr);
return insert_node;
}
ge::NodePtr DvppOptimizer::GraphAddAICpuReduceMeanNode(
ge::ComputeGraphPtr& graph) const {
ge::OpDescPtr op_desc_ptr = nullptr;
auto ret = DvppOpsLib::Instance().CreateAICpuReduceMeanDesc(op_desc_ptr);
DVPP_CHECK_IF_THEN_DO(ret != DvppErrorCode::kSuccess,
DVPP_REPORT_INNER_ERR_MSG("create op[%s] failed.", kAICpuOpReduceMean.c_str());
return nullptr);
ge::NodePtr new_node = graph->AddNode(op_desc_ptr);
DVPP_CHECK_IF_THEN_DO(new_node == nullptr,
DVPP_REPORT_INNER_ERR_MSG("create insert node[%s] failed.",
kAICpuOpReduceMean.c_str());
return nullptr);
return new_node;
}
DvppErrorCode DvppOptimizer::AddAdujustContrastWithMeanEdge(
ge::NodePtr& contrast_with_mean_node, ge::NodePtr& contrast_node) const {
auto contrast_node_out_anchor_0 = contrast_node->GetOutDataAnchor(kNum0);
DVPP_CHECK_NOTNULL(contrast_node_out_anchor_0);
auto contrast_with_mean_node_out_anchor_0 =
contrast_with_mean_node->GetOutDataAnchor(kNum0);
auto output_in_anchors =
contrast_node_out_anchor_0->GetPeerInDataAnchors();
DVPP_CHECK_IF_THEN_DO(output_in_anchors.size() == 0,
DVPP_REPORT_INNER_ERR_MSG("output_in_anchors is empty.");
return DvppErrorCode::kFailed);
DVPP_CHECK_IF_THEN_DO(
(ge::GraphUtils::RemoveEdge(contrast_node_out_anchor_0,
output_in_anchors.at(kNum0)) != ge::GRAPH_SUCCESS) ||
(ge::GraphUtils::AddEdge(contrast_with_mean_node_out_anchor_0,
output_in_anchors.at(kNum0)) != ge::GRAPH_SUCCESS),
DVPP_REPORT_INNER_ERR_MSG(
"replace output edge between node[%s] and node[%s] failed.",
kDvppOpAdjustContrastWithMean.c_str(), contrast_node->GetType().c_str());
return DvppErrorCode::kFailed);
auto contrast_node_in_anchor_0 = contrast_node->GetInDataAnchor(kNum0);
DVPP_CHECK_NOTNULL(contrast_node_in_anchor_0);
auto contrast_with_mean_node_in_anchor_0 =
contrast_with_mean_node->GetInDataAnchor(kNum0);
auto contrast_with_mean_node_in_anchor_1 =
contrast_with_mean_node->GetInDataAnchor(kNum1);
auto data_out_anchor = contrast_node_in_anchor_0->GetPeerOutAnchor();
DVPP_CHECK_IF_THEN_DO(
(ge::GraphUtils::RemoveEdge(data_out_anchor,
contrast_node_in_anchor_0) != ge::GRAPH_SUCCESS) ||
(ge::GraphUtils::AddEdge(data_out_anchor,
contrast_with_mean_node_in_anchor_0) != ge::GRAPH_SUCCESS) ||
(ge::GraphUtils::AddEdge(data_out_anchor,
contrast_with_mean_node_in_anchor_1) != ge::GRAPH_SUCCESS),
DVPP_REPORT_INNER_ERR_MSG(
"replace input image edge between node[%s] and node[%s] failed.",
kDvppOpAdjustContrastWithMean.c_str(), contrast_node->GetType().c_str());
return DvppErrorCode::kFailed);
auto contrast_node_in_anchor_1 = contrast_node->GetInDataAnchor(kNum1);
DVPP_CHECK_NOTNULL(contrast_node_in_anchor_1);
auto contrast_with_mean_node_in_anchor_2 =
contrast_with_mean_node->GetInDataAnchor(kNum2);
auto factor_out_anchor = contrast_node_in_anchor_1->GetPeerOutAnchor();
DVPP_CHECK_IF_THEN_DO(
(ge::GraphUtils::RemoveEdge(factor_out_anchor,
contrast_node_in_anchor_1) != ge::GRAPH_SUCCESS) ||
(ge::GraphUtils::AddEdge(factor_out_anchor,
contrast_with_mean_node_in_anchor_2) != ge::GRAPH_SUCCESS),
DVPP_REPORT_INNER_ERR_MSG(
"replace input factor edge between node[%s] and node[%s] failed.",
kDvppOpAdjustContrastWithMean.c_str(),
contrast_node->GetType().c_str());
return DvppErrorCode::kFailed);
return DvppErrorCode::kSuccess;
}
ge::NodePtr DvppOptimizer::InsertAdujustContrastWithMean(
ge::ComputeGraphPtr graph_ptr, ge::NodePtr& contrast_node) const {
ge::NodePtr contrast_with_mean_node = GraphAddNode(graph_ptr,
kDvppOpAdjustContrastWithMean);
DVPP_CHECK_IF_THEN_DO(contrast_with_mean_node == nullptr, return nullptr);
DVPP_CHECK_IF_THEN_DO(AddAdujustContrastWithMeanEdge(
contrast_with_mean_node, contrast_node) == DvppErrorCode::kFailed,
return nullptr);
auto contrast_node_op_desc_ptr = contrast_node->GetOpDesc();
auto contrast_with_mean_op_desc_ptr = contrast_with_mean_node->GetOpDesc();
std::string attr_data_format_value = "";
DVPP_CHECK_IF_THEN_DO(!ge::AttrUtils::GetStr(
contrast_node_op_desc_ptr, "data_format", attr_data_format_value),
DVPP_REPORT_INNER_ERR_MSG("get op[%s] data format failed.",
contrast_node_op_desc_ptr->GetType().c_str());
return nullptr);
if (!attr_data_format_value.empty()) {
DVPP_CHECK_IF_THEN_DO(!ge::AttrUtils::SetStr(
contrast_with_mean_op_desc_ptr, "data_format", attr_data_format_value),
DVPP_REPORT_INNER_ERR_MSG("set op[%s] data format failed.",
contrast_with_mean_op_desc_ptr->GetType().c_str());
return nullptr);
}
DVPP_CHECK_IF_THEN_DO(
(contrast_with_mean_op_desc_ptr->UpdateInputDesc(kNum0,
contrast_node_op_desc_ptr->GetInputDesc(kNum0)) != ge::GRAPH_SUCCESS) ||
(contrast_with_mean_op_desc_ptr->UpdateInputDesc(kNum1,
contrast_with_mean_op_desc_ptr->GetInputDesc(kNum0)) !=
ge::GRAPH_SUCCESS) ||
(contrast_with_mean_op_desc_ptr->UpdateInputDesc(kNum2,
contrast_node_op_desc_ptr->GetInputDesc(kNum1)) != ge::GRAPH_SUCCESS) ||
(contrast_with_mean_op_desc_ptr->UpdateOutputDesc(kNum0,
contrast_with_mean_op_desc_ptr->GetInputDesc(kNum0)) !=
ge::GRAPH_SUCCESS),
DVPP_REPORT_INNER_ERR_MSG("set node[%s] input or output description failed.",
contrast_with_mean_node->GetType().c_str());
return nullptr);
return contrast_with_mean_node;
}
ge::NodePtr DvppOptimizer::InsertAICpuReduceMean(ge::ComputeGraphPtr graph_ptr,
ge::NodePtr& contrast_node, ge::NodePtr& contrast_with_mean_node) const {
ge::NodePtr reduce_mean_node = GraphAddAICpuReduceMeanNode(graph_ptr);
DVPP_CHECK_IF_THEN_DO(reduce_mean_node == nullptr,
DVPP_REPORT_INNER_ERR_MSG("add node[%s] to graph failed.",
kAICpuOpReduceMean.c_str());
return nullptr);
auto contrast_with_mean_node_in_anchor_1 = contrast_with_mean_node->
GetInDataAnchor(kNum1);
DVPP_CHECK_IF_THEN_DO(
ge::GraphUtils::InsertNodeBefore(contrast_with_mean_node_in_anchor_1,
reduce_mean_node) != ge::GRAPH_SUCCESS,
DVPP_REPORT_INNER_ERR_MSG("insert node[%s] before node[%s] failed.",
reduce_mean_node->GetType().c_str(),
contrast_with_mean_node->GetType().c_str());
return nullptr);
auto reduce_mean_op_desc_ptr = reduce_mean_node->GetOpDesc();
DVPP_CHECK_IF_THEN_DO(SetAiCpuOpAttr(reduce_mean_op_desc_ptr) !=
DvppErrorCode::kSuccess,
DVPP_REPORT_INNER_ERR_MSG("op[%s] set dvpp op attr failed",
reduce_mean_node->GetType().c_str());
return nullptr);
DVPP_CHECK_IF_THEN_DO(!ge::AttrUtils::SetBool(
reduce_mean_op_desc_ptr, ge::NEED_INFER, true),
DVPP_REPORT_INNER_ERR_MSG("set op[%s] need infer attr failed.",
reduce_mean_node->GetType().c_str());
return nullptr);
ge::AttrUtils::SetBool(reduce_mean_op_desc_ptr, "keep_dims", false);
std::string attr_data_format_value = "";
auto contrast_node_op_desc_ptr = contrast_node->GetOpDesc();
DVPP_CHECK_IF_THEN_DO(!ge::AttrUtils::GetStr(
contrast_node_op_desc_ptr, "data_format", attr_data_format_value),
DVPP_REPORT_INNER_ERR_MSG("get op[%s] data format failed.",
contrast_node_op_desc_ptr->GetType().c_str());
return nullptr);
if (!attr_data_format_value.empty()) {
DVPP_CHECK_IF_THEN_DO(!ge::AttrUtils::SetStr(
reduce_mean_op_desc_ptr, "data_format", attr_data_format_value),
DVPP_REPORT_INNER_ERR_MSG("set op[%s] data format attr failed.",
reduce_mean_node->GetType().c_str());
return nullptr);
}
DVPP_CHECK_IF_THEN_DO(
(reduce_mean_op_desc_ptr->UpdateInputDesc(kNum0,
contrast_node_op_desc_ptr->GetOutputDesc(kNum0)) != ge::GRAPH_SUCCESS) ||
(reduce_mean_op_desc_ptr->UpdateOutputDesc(kNum0,
reduce_mean_op_desc_ptr->GetInputDesc(kNum0)) != ge::GRAPH_SUCCESS),
DVPP_REPORT_INNER_ERR_MSG("set node[%s] input or output desc failed.",
reduce_mean_node->GetType().c_str());
return nullptr);
return reduce_mean_node;
}
ge::GeTensorPtr DvppOptimizer::GetConstTensorForReduceMean(
ge::NodePtr& contrast_node) const{
int32_t n_index = 0, h_index = 0, w_index = 0;
auto contrast_node_op_desc_ptr = contrast_node->GetOpDesc();
auto tensor_data_format = contrast_node_op_desc_ptr->
GetInputDesc(kNum0).GetFormat();
std::string attr_data_format_value = "";
DVPP_CHECK_IF_THEN_DO(!ge::AttrUtils::GetStr(
contrast_node_op_desc_ptr, "data_format", attr_data_format_value),
DVPP_REPORT_INNER_ERR_MSG("get op[%s] data format failed.",
contrast_node_op_desc_ptr->GetType().c_str());
return nullptr);
if (attr_data_format_value == "HWC" ||
tensor_data_format == ge::FORMAT_NHWC) {
h_index = 1;
w_index = 2;
} else {
h_index = 2;
w_index = 3;
}
std::vector<int32_t> reduce_mean_axes_tensor_value =
{n_index, h_index, w_index};
constexpr int64_t reduceMeanDim = 3;
ge::GeTensorPtr reduce_mean_axes_tensor = MakeShared<ge::GeTensor>();
auto reduce_mean_axes_shape =
ge::GeShape(std::vector<int64_t>({reduceMeanDim}));
reduce_mean_axes_tensor->MutableTensorDesc().SetDataType(ge::DT_INT32);
reduce_mean_axes_tensor->MutableTensorDesc().SetFormat(ge::FORMAT_ND);
reduce_mean_axes_tensor->MutableTensorDesc().SetShape(reduce_mean_axes_shape);
reduce_mean_axes_tensor->MutableTensorDesc().SetOriginDataType(ge::DT_INT32);
reduce_mean_axes_tensor->MutableTensorDesc().SetOriginFormat(ge::FORMAT_ND);
reduce_mean_axes_tensor->
MutableTensorDesc().SetOriginShape(reduce_mean_axes_shape);
DVPP_CHECK_IF_THEN_DO((reduce_mean_axes_tensor->
SetData(reinterpret_cast<uint8_t *>(reduce_mean_axes_tensor_value.data()),
reduceMeanDim * sizeof(int32_t))) != ge::GRAPH_SUCCESS,
DVPP_REPORT_INNER_ERR_MSG("set reduce mean axes data failed.");
return nullptr);
return reduce_mean_axes_tensor;
}
ge::NodePtr DvppOptimizer::InsertConstForReduceMean(ge::ComputeGraphPtr graph_ptr,
ge::NodePtr& contrast_node, ge::NodePtr& reduce_mean_node) const{
auto reduce_mean_axes_tensor = GetConstTensorForReduceMean(contrast_node);
DVPP_CHECK_IF_THEN_DO(reduce_mean_axes_tensor == nullptr,
return nullptr);
ge::OpDescPtr reduce_mean_axes_const_desc_ptr =
ge::OpDescUtils::CreateConstOp(reduce_mean_axes_tensor);
DVPP_CHECK_IF_THEN_DO(reduce_mean_axes_const_desc_ptr == nullptr,
DVPP_REPORT_INNER_ERR_MSG("create reduce mean axes description failed.");
return nullptr);
auto reduce_mean_axes_const_node = graph_ptr->
AddNode(reduce_mean_axes_const_desc_ptr);
DVPP_CHECK_IF_THEN_DO(reduce_mean_axes_const_node == nullptr,
DVPP_REPORT_INNER_ERR_MSG("create reduce mean axes node failed.");
return nullptr);
auto reduce_mean_axes_const_node_out_anchor_0 =
reduce_mean_axes_const_node->GetOutDataAnchor(kNum0);
auto reduce_mean_in_anchor_1 = reduce_mean_node->GetInDataAnchor(kNum1);
DVPP_CHECK_IF_THEN_DO(
(ge::GraphUtils::AddEdge(reduce_mean_axes_const_node_out_anchor_0,
reduce_mean_in_anchor_1) != ge::GRAPH_SUCCESS),
DVPP_REPORT_INNER_ERR_MSG("add edge between node[%s] and node[%s] failed.",
reduce_mean_axes_const_node->GetType().c_str(),
reduce_mean_node->GetType().c_str());
return nullptr);
auto reduce_mean_op_desc_ptr = reduce_mean_node->GetOpDesc();
DVPP_CHECK_IF_THEN_DO(
(reduce_mean_op_desc_ptr->UpdateInputDesc(1,
reduce_mean_axes_const_desc_ptr->
GetOutputDesc(kNum0)) != ge::GRAPH_SUCCESS),
DVPP_REPORT_INNER_ERR_MSG("set node[%s] input 1 description failed.",
reduce_mean_node->GetType().c_str()); return nullptr);
return reduce_mean_axes_const_node;
}
ge::NodePtr DvppOptimizer::InsertRgbToGrayscale(ge::ComputeGraphPtr graph_ptr,
ge::NodePtr& contrast_node, ge::NodePtr& reduce_mean_node) const{
ge::NodePtr rgb_to_gray_scale_node =
InsertGraphNodeBefore(graph_ptr, reduce_mean_node, kDvppOpRgbToGrayscale);
DVPP_CHECK_IF_THEN_DO(rgb_to_gray_scale_node == nullptr,
DVPP_REPORT_INNER_ERR_MSG("insert RgbToGrayscale node failed");
return nullptr);
auto rgb_to_gray_scale_op_desc_ptr = rgb_to_gray_scale_node->GetOpDesc();
DVPP_CHECK_IF_THEN_DO(rgb_to_gray_scale_op_desc_ptr == nullptr,
DVPP_REPORT_INNER_ERR_MSG("get RgbToGrayscale op description failed");
return nullptr);
auto contrast_node_op_desc_ptr = contrast_node->GetOpDesc();
DVPP_CHECK_IF_THEN_DO(contrast_node_op_desc_ptr == nullptr,
DVPP_REPORT_INNER_ERR_MSG("get contrast_node desc failed");
return nullptr);
DVPP_CHECK_IF_THEN_DO(
(rgb_to_gray_scale_op_desc_ptr->UpdateInputDesc(kNum0,
contrast_node_op_desc_ptr->GetOutputDesc(kNum0)) != ge::GRAPH_SUCCESS) ||
(rgb_to_gray_scale_op_desc_ptr->UpdateOutputDesc(kNum0,
rgb_to_gray_scale_op_desc_ptr->GetInputDesc(kNum0)) != ge::GRAPH_SUCCESS),
DVPP_REPORT_INNER_ERR_MSG(
"set node[%s] input or output description failed.",
rgb_to_gray_scale_node->GetType().c_str());
return nullptr);
constexpr int64_t outputChannels = 3;
ge::AttrUtils::SetInt(rgb_to_gray_scale_op_desc_ptr,
"output_channels", outputChannels);
std::string attr_data_format_value = "";
DVPP_CHECK_IF_THEN_DO(!ge::AttrUtils::GetStr(
contrast_node_op_desc_ptr, "data_format", attr_data_format_value),
DVPP_REPORT_INNER_ERR_MSG("get op[%s] data format failed.",
contrast_node_op_desc_ptr->GetType().c_str());
return nullptr);
if (!attr_data_format_value.empty()) {
DVPP_CHECK_IF_THEN_DO(!ge::AttrUtils::SetStr(
rgb_to_gray_scale_op_desc_ptr, "data_format", attr_data_format_value),
DVPP_REPORT_INNER_ERR_MSG("set op[%s] data format attr failed.",
kAICpuOpReduceMean.c_str());
return nullptr);
}
return rgb_to_gray_scale_node;
}
* Data
* / \
* Data factor / R2G const factor
* \ / / \ / /
* AdjustContrast ===> / ReduceMean /
* | / \ /
* NetOutput AdjustContrastWithMean
* |
* NetOutput
* 将adjust contrast算子替换为右边的图结构,用于实现adjust
* contrast功能。通过data计算出均值,输入到blend输入2可以
* 消除值依赖。R2G代表RgbToGrayscale,会根据attr判断是否插
* 入
*/
DvppErrorCode DvppOptimizer::InsertAdjustContrastGraph(
ge::ComputeGraph& graph, ge::NodePtr& contrast_node) const {
ge::ComputeGraphPtr graph_ptr = graph.shared_from_this();
ge::NodePtr contrast_with_mean_node =
InsertAdujustContrastWithMean(graph_ptr, contrast_node);
DVPP_CHECK_IF_THEN_DO(contrast_with_mean_node == nullptr,
return DvppErrorCode::kFailed);
ge::NodePtr reduce_mean_node =
InsertAICpuReduceMean(graph_ptr, contrast_node, contrast_with_mean_node);
DVPP_CHECK_IF_THEN_DO(reduce_mean_node == nullptr,
return DvppErrorCode::kFailed);
ge::NodePtr reduce_mean_axes_const_node =
InsertConstForReduceMean(graph_ptr, contrast_node, reduce_mean_node);
DVPP_CHECK_IF_THEN_DO(reduce_mean_axes_const_node == nullptr,
return DvppErrorCode::kFailed);
std::string mean_mode_value = "";
auto contrast_node_op_desc_ptr = contrast_node->GetOpDesc();
DVPP_CHECK_IF_THEN_DO(!ge::AttrUtils::GetStr(contrast_node_op_desc_ptr,
"mean_mode", mean_mode_value),
DVPP_REPORT_INNER_ERR_MSG("set op[%s] mean mode attr failed.",
kAICpuOpReduceMean.c_str());
return DvppErrorCode::kFailed);
if (mean_mode_value == "chn_y") {
auto rgb_to_gray_scale_node = InsertRgbToGrayscale(graph_ptr,
contrast_node, reduce_mean_node);
DVPP_CHECK_IF_THEN_DO(rgb_to_gray_scale_node == nullptr,
return DvppErrorCode::kFailed);
}
DVPP_ENGINE_LOG_DEBUG("mean mode : %s", mean_mode_value.c_str());
DVPP_CHECK_IF_THEN_DO(graph.RemoveNode(contrast_node) != ge::GRAPH_SUCCESS,
DVPP_REPORT_INNER_ERR_MSG("remove contrast node failed");
return DvppErrorCode::kFailed);
return DvppErrorCode::kSuccess;
}
DvppErrorCode DvppOptimizer::InsertNode(
ge::ComputeGraph& graph, ge::NodePtr& node) {
std::string op_type = node->GetType();
if (op_type == kDvppOpDecodeJpeg || op_type == kDvppOpDecodeAndCropJpeg) {
auto ret = InsertIfGraph(graph, node);
DVPP_CHECK_IF_THEN_DO(ret != DvppErrorCode::kSuccess,
DVPP_REPORT_INNER_ERR_MSG("insert if graph before node[%s] failed",
node->GetType().c_str());
return ret);
} else if (op_type == kDvppOpAdjustContrast) {
auto ret = InsertAdjustContrastGraph(graph, node);
DVPP_CHECK_IF_THEN_DO(ret != DvppErrorCode::kSuccess,
DVPP_REPORT_INNER_ERR_MSG("insert if graph before node[%s] failed",
node->GetType().c_str());
return ret);
}
return DvppErrorCode::kSuccess;
}
DvppErrorCode DvppOptimizer::OptimizeOriginalGraph(ge::ComputeGraph& graph) {
for (auto& node : graph.GetDirectNode()) {
DVPP_CHECK_NOTNULL(node);
auto op_desc_ptr = node->GetOpDesc();
DVPP_CHECK_NOTNULL(op_desc_ptr);
bool enable_dvpp_engine = EnableDvppEngine(op_desc_ptr);
DVPP_CHECK_IF_THEN_DO(!enable_dvpp_engine, continue);
DVPP_ENGINE_LOG_DEBUG("dvpp engine is enable to op[%s].",
op_desc_ptr->GetType().c_str());
auto error = SpecialOptimize(graph, node);
DVPP_CHECK_IF_THEN_DO(error == DvppErrorCode::kSuccess, continue);
std::string unsupported_reason;
bool ret = DvppOpsChecker::CheckSupported(node, unsupported_reason);
DVPP_CHECK_IF_THEN_DO(!ret, continue);
DVPP_ENGINE_LOG_DEBUG("op[%s] CheckSupported success.",
op_desc_ptr->GetType().c_str());
error = SetDvppOpAttr(op_desc_ptr);
DVPP_CHECK_IF_THEN_DO(error != DvppErrorCode::kSuccess,
DVPP_REPORT_INNER_ERR_MSG("op[%s] set dvpp op attr failed",
op_desc_ptr->GetType().c_str());
return DvppErrorCode::kFailed);
DVPP_ENGINE_LOG_DEBUG("op[%s] set dvpp op attr success.",
op_desc_ptr->GetType().c_str());
error = InsertNode(graph, node);
DVPP_CHECK_IF_THEN_DO(error != DvppErrorCode::kSuccess,
DVPP_REPORT_INNER_ERR_MSG("op[%s] insert node failed",
op_desc_ptr->GetType().c_str());
return error);
DVPP_ENGINE_LOG_DEBUG("op[%s] insert node success.",
op_desc_ptr->GetType().c_str());
}
return DvppErrorCode::kSuccess;
}
DvppErrorCode DvppOptimizer::OptimizeOriginalGraphJudgeInsert(
ge::ComputeGraph& graph) {
(void)graph;
return DvppErrorCode::kSuccess;
}
DvppErrorCode DvppOptimizer::OptimizeFusedGraph(ge::ComputeGraph& graph) const {
(void)graph;
return DvppErrorCode::kSuccess;
}
DvppErrorCode DvppOptimizer::OptimizeWholeGraph(ge::ComputeGraph& graph) const {
(void)graph;
return DvppErrorCode::kSuccess;
}
}