|
- /**
- * 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_functiondef.h"
- #include <iostream>
- #include "common/fmk_error_codes.h"
- #include "graph/debug/ge_attr_define.h"
- #include "framework/omg/parser/parser_types.h"
- #include "parser/common/acl_graph_parser_util.h"
- #include "common/types_map.h"
- #include "common/util.h"
- #include "graph/op_desc.h"
- #include "graph/utils/attr_utils.h"
- #include "graph/utils/graph_utils.h"
- #include "framework/common/ge_inner_error_codes.h"
-
- namespace {
- constexpr char UNKNOWN[] = "unknown";
- constexpr char UNDERLINE = '_';
- } // namespace
- namespace ge {
- using AttrValueMap = ::google::protobuf::Map<string, domi::tensorflow::AttrValue>;
- vector<domi::tensorflow::DataType> arg_datetypes_;
- vector<domi::tensorflow::DataType> result_datetypes_;
-
- string NameMapHelper::GetUniqueName(const string &name) {
- if (used_names_.insert(name).second) {
- return name;
- }
- int i = 0;
- while (true) {
- const string candidate = name + "_" + to_string(i);
- if (used_names_.insert(candidate).second) {
- return candidate;
- }
- ++i;
- }
- }
-
- string NameMapHelper::UniqueInputOrOutputName(const string &name) {
- // Normalize first
- string normalized = name;
- if (name.empty()) {
- normalized = UNKNOWN;
- }
- for (auto ch : normalized) {
- if (!isalnum(ch)) {
- ch = UNDERLINE;
- } else if (isupper(ch)) {
- ch = tolower(ch);
- }
- }
- // uniquify
- const string unique_name = GetUniqueName(normalized);
- name_mapping_[name] = unique_name;
- return unique_name;
- }
-
- string NameMapHelper::UniqueNodeName(const string &name) {
- // uniquify
- const string unique_name = GetUniqueName(name);
- name_mapping_[name] = unique_name;
- return unique_name;
- }
-
- string NameMapHelper::Renormalize(const string &name) const {
- const auto iter = name_mapping_.find(name);
- if (iter == name_mapping_.end()) {return string();}
- return iter->second;
- }
-
- domi::Status ComputeArgRange(const domi::tensorflow::NodeDef &node_def, const domi::tensorflow::OpDef::ArgDef &arg_def,
- int *num) {
- GE_CHECK_NOTNULL(num);
- if (!arg_def.number_attr().empty()) {
- // Same type repeated "num" times.
- domi::tensorflow::AttrValue attr_value;
- // Get attribute number_att, if the attribute does not exist, return failure
- GE_IF_BOOL_EXEC(
- !GraphToFunctionDef::FindAttrValue(&node_def, arg_def.number_attr(), attr_value),
- GELOGE(domi::INTERNAL_ERROR, "In NodeDef %s Attr number_attr is not exist.", node_def.name().c_str());
- REPORT_INNER_ERROR("E19999", "Attr:number_attr not exist in node:%s, check invalid", node_def.name().c_str());
- return domi::INTERNAL_ERROR);
- *num = attr_value.i();
- } else if (!arg_def.type_list_attr().empty()) {
- domi::tensorflow::AttrValue attr_value;
- /// Get the attribute type_list_attr, if the attribute does not exist, return
- /// failure
- GE_IF_BOOL_EXEC(
- !GraphToFunctionDef::FindAttrValue(&node_def, arg_def.type_list_attr(), attr_value),
- GELOGE(domi::INTERNAL_ERROR, "In NodeDef %s Attr type_list_attr is not exist.", node_def.name().c_str());
- REPORT_INNER_ERROR("E19999", "Attr:type_list_attr not exist in node:%s, check invalid", node_def.name().c_str());
- return domi::INTERNAL_ERROR);
- *num = attr_value.list().type_size();
- } else if ((!arg_def.type_attr().empty()) || (arg_def.type() != DT_INVALID)) {
- *num = 1;
- } else {
- GELOGE(domi::INTERNAL_ERROR, "In NodeDef %s Attr type_list_attr is not exist.", node_def.name().c_str());
- REPORT_INNER_ERROR("E19999", "arg_def for node:%s is invalid, number_attr type_list_attr type_attr all empty",
- node_def.name().c_str());
- return domi::INTERNAL_ERROR;
- }
- return SUCCESS;
- }
-
- using NameRangeMap = std::map<string, std::pair<int, int>>;
-
- domi::Status NameRangesHelper(const domi::tensorflow::NodeDef &node_def,
- const google::protobuf::RepeatedPtrField<domi::tensorflow::OpDef_ArgDef> &args,
- NameRangeMap *result) {
- GE_CHECK_NOTNULL(result);
- int start = 0;
- int num = 0;
- for (const auto &arg : args) {
- GE_RETURN_IF_ERROR(ComputeArgRange(node_def, arg, &num));
- (*result)[arg.name()] = std::make_pair(start, start + num);
- start += num;
- }
- return SUCCESS;
- }
-
- domi::Status NameRangesForNode(const domi::tensorflow::NodeDef &node_def, const domi::tensorflow::OpDef &op_def,
- NameRangeMap *outputs) {
- GE_IF_BOOL_EXEC(outputs == nullptr, return FAILED);
-
- return NameRangesHelper(node_def, op_def.output_arg(), outputs);
- }
-
- domi::Status RemapFunctionDef(FunctionDef *fdef, const string &name, NameMapHelper &node_names,
- std::map<string, string> &tensor_renaming,
- std::map<string, string> &return_values) {
- GE_CHECK_NOTNULL(fdef);
- // Detect missing function inputs..
- for (int i = 0; i < fdef->signature().input_arg_size(); ++i) {
- const string &input_name = fdef->signature().input_arg(i).name();
- GE_IF_BOOL_EXEC(input_name.empty(),
- REPORT_INNER_ERROR("E19999", "In fdef %s, index:%d input_name is empty, check invalid",
- fdef->signature().name().c_str(), i);
- GELOGE(domi::INTERNAL_ERROR, "In fdef %s input_name null .", fdef->signature().name().c_str());
- return domi::INTERNAL_ERROR);
- }
-
- /// Remap input names. We do this as a second pass to allow the nodes to be in
- /// any order.
- for (int n_index = 0; n_index < fdef->node_def_size(); ++n_index) {
- NodeDef *node_def = fdef->mutable_node_def(n_index);
- for (int i = 0; i < node_def->input_size(); ++i) {
- if (node_def->input(i).find("^") != string::npos) {
- // Control input
- const string normalized = node_names.Renormalize(node_def->input(i).substr(1));
- GE_IF_BOOL_EXEC(normalized.empty(),
- REPORT_INNER_ERROR("E19999", "Could not remap control input %s of node %s in function %s",
- node_def->input(i).c_str(), node_def->name().c_str(), name.c_str());
- GELOGE(domi::INTERNAL_ERROR, "Could not remap control input %s of node %s in function %s .",
- node_def->input(i).c_str(), node_def->name().c_str(), name.c_str());
- return domi::INTERNAL_ERROR);
-
- *node_def->mutable_input(i) = "^" + normalized;
- } else {
- const auto iter = tensor_renaming.find(node_def->input(i));
- GE_IF_BOOL_EXEC(iter == tensor_renaming.end(),
- REPORT_INNER_ERROR("E19999", "Could not remap input %s of node %s in function %s",
- node_def->input(i).c_str(), node_def->name().c_str(), name.c_str());
- GELOGE(domi::INTERNAL_ERROR, "Could not remap input %s of node %s in function %s .",
- node_def->input(i).c_str(), node_def->name().c_str(), name.c_str());
- return domi::INTERNAL_ERROR);
-
- *node_def->mutable_input(i) = iter->second;
- }
- }
- }
-
- // Remap return values.
- for (int r = 0; r < fdef->signature().output_arg_size(); ++r) {
- const string &ret_name = fdef->signature().output_arg(r).name();
- GE_IF_BOOL_EXEC(ret_name.empty(),
- REPORT_INNER_ERROR("E19999", "Missing output %d to function %s", r, name.c_str());
- GELOGE(domi::INTERNAL_ERROR, "Missing output %d to function %s .", r, name.c_str());
- return domi::INTERNAL_ERROR);
-
- const string &return_value = return_values[ret_name];
- GE_IF_BOOL_EXEC(return_value.empty(),
- REPORT_INNER_ERROR("E19999", "Could not remap return value %d ,%s of %s in function %s", r,
- ret_name.c_str(), return_value.c_str(), name.c_str());
- GELOGE(domi::INTERNAL_ERROR, "Could not remap return value %d ,%s of %s in function %s .", r,
- ret_name.c_str(), return_value.c_str(), name.c_str());
- return domi::INTERNAL_ERROR);
-
- const auto iter = tensor_renaming.find(return_value);
- if (iter == tensor_renaming.end()) {
- REPORT_INNER_ERROR("E19999", "can not find value[%s] in tensor_renaming map", return_value.c_str());
- GELOGE(FAILED, "can not find value[%s] in tensor_renaming map.", return_value.c_str());
- return domi::INTERNAL_ERROR;
- }
-
- (*fdef->mutable_ret())[ret_name] = iter->second;
- }
-
- return SUCCESS;
- }
-
- // Add output operator for graph before converting func
- domi::Status GraphToFunctionDef::RecordResult(ge::ComputeGraphPtr graph,
- const vector<ge::OutDataAnchorPtr> &out_anchor) {
- GE_CHECK_NOTNULL(graph);
- int32_t index = 0;
- result_datetypes_.clear();
- for (const auto &anchor : out_anchor) {
- GE_CHECK_NOTNULL(anchor);
- GE_CHECK_NOTNULL(anchor->GetOwnerNode()->GetOpDesc());
- int32_t type = anchor->GetOwnerNode()->GetOpDesc()->GetOutputDesc(anchor->GetIdx()).GetDataType();
- std::map<int32_t, int32_t>::const_iterator iter = GE_TENSORFLOW_DATA_TYPE_MAP.find(type);
- GE_IF_BOOL_EXEC(iter == GE_TENSORFLOW_DATA_TYPE_MAP.end(),
- REPORT_INNER_ERROR("E19999", "datatype:%d of output:%d in node:%s:%s is not supported",
- type, anchor->GetIdx(), anchor->GetOwnerNode()->GetName().c_str(),
- anchor->GetOwnerNode()->GetName().c_str());
- GELOGE(PARAM_INVALID, "data_type %d not supported", type);
- return PARAM_INVALID);
- int32_t dtype = iter->second;
-
- string op_name = anchor->GetOwnerNode()->GetName() + "_" + to_string(anchor->GetIdx()) + "_retval";
- ge::OpDescPtr op = nullptr;
- GE_MAKE_SHARED(op = std::make_shared<ge::OpDesc>(op_name, ge::parser::NETOUTPUT), return FAILED);
- graphStatus status = op->AddInputDesc(ge::GeTensorDesc());
- if (status != GRAPH_SUCCESS) {
- REPORT_CALL_ERROR("E19999", "Add input desc to op:%s(%s) failed", op->GetName().c_str(), op->GetType().c_str());
- GELOGE(FAILED, "Add input desc for op:%s failed.", op->GetName().c_str());
- return FAILED;
- }
- status = op->AddOutputDesc(ge::GeTensorDesc());
- if (status != GRAPH_SUCCESS) {
- REPORT_CALL_ERROR("E19999", "Add output desc to op:%s(%s) failed", op->GetName().c_str(), op->GetType().c_str());
- GELOGE(FAILED, "Add output desc for op:%s failed.", op->GetName().c_str());
- return FAILED;
- }
- (void)ge::AttrUtils::SetInt(op, "T", static_cast<int32_t >(dtype));
- (void)ge::AttrUtils::SetInt(op, "ret_index", static_cast<int32_t >(index));
- ge::NodePtr res_node = graph->AddNode(op);
- GE_CHECK_NOTNULL(res_node);
- bool node_exists = false;
- for (const ge::NodePtr &node : graph->GetDirectNode()) {
- GE_CHECK_NOTNULL(node);
- if (node->GetName() == anchor->GetOwnerNode()->GetName()) {
- ge::OutDataAnchorPtr out_archor_ptr = node->GetOutDataAnchor(anchor->GetIdx());
- GE_CHECK_NOTNULL(out_archor_ptr);
- ge::InDataAnchorPtr in_archor_ptr = res_node->GetInDataAnchor(0);
- GE_CHECK_NOTNULL(in_archor_ptr);
- ge::graphStatus ret = ge::GraphUtils::AddEdge(out_archor_ptr, in_archor_ptr);
- if (ret != ge::GRAPH_SUCCESS) {
- REPORT_CALL_ERROR("E19999", "Add edge between op:%s(%s)(index:%d) and op:%s(%s)(index:%d) failed",
- out_archor_ptr->GetOwnerNode()->GetName().c_str(),
- out_archor_ptr->GetOwnerNode()->GetType().c_str(), out_archor_ptr->GetIdx(),
- in_archor_ptr->GetOwnerNode()->GetName().c_str(),
- in_archor_ptr->GetOwnerNode()->GetType().c_str(), in_archor_ptr->GetIdx());
- GELOGE(domi::INTERNAL_ERROR, "Add edge failed,src op:%s,dst op:%s", node->GetName().c_str(),
- res_node->GetName().c_str());
- return FAILED;
- }
- node_exists = true;
- }
- }
- GE_IF_BOOL_EXEC(!node_exists,
- GELOGE(FAILED, "node not exists!");
- REPORT_CALL_ERROR("E19999", "Node:%s(%s) not found in graph:%s, check invalid",
- anchor->GetOwnerNode()->GetName().c_str(),
- anchor->GetOwnerNode()->GetType().c_str(),
- graph->GetName().c_str());
- return FAILED);
- result_datetypes_.emplace_back(domi::tensorflow::DataType(dtype));
-
- index++;
- }
- return SUCCESS;
- }
-
- /// Add input operator for graph before converting function.
- /// Input operator will generate input parameters during function conversion
- domi::Status GraphToFunctionDef::RecordArg(ge::ComputeGraphPtr graph, const vector<ge::InDataAnchorPtr> &in_anchor) {
- GE_CHECK_NOTNULL(graph);
- int32_t index = 0;
- arg_datetypes_.clear();
- for (const auto &anchor : in_anchor) {
- GE_CHECK_NOTNULL(anchor);
- GE_CHECK_NOTNULL(anchor->GetOwnerNode()->GetOpDesc());
- auto tensor_desc_ptr = anchor->GetOwnerNode()->GetOpDesc()->GetInputDescPtr(anchor->GetIdx());
- GE_CHECK_NOTNULL_EXEC(tensor_desc_ptr, return domi::FAILED);
-
- int32_t type = tensor_desc_ptr->GetDataType();
- std::map<int32_t, int32_t>::const_iterator iter = GE_TENSORFLOW_DATA_TYPE_MAP.find(type);
- GE_IF_BOOL_EXEC(iter == GE_TENSORFLOW_DATA_TYPE_MAP.end(),
- REPORT_INNER_ERROR("E19999", "datatype:%d of input:%d in node:%s:%s is not supported",
- type, anchor->GetIdx(), anchor->GetOwnerNode()->GetName().c_str(),
- anchor->GetOwnerNode()->GetName().c_str());
- GELOGE(PARAM_INVALID, "data_type %d not supported", type);
- return PARAM_INVALID);
- int32_t dtype = iter->second;
-
- GE_CHECK_NOTNULL(anchor->GetPeerOutAnchor());
- string op_name = anchor->GetPeerOutAnchor()->GetOwnerNode()->GetName() + "_" +
- to_string(anchor->GetPeerOutAnchor()->GetIdx()) + "_arg";
- ge::OpDescPtr op = nullptr;
- GE_MAKE_SHARED(op = std::make_shared<ge::OpDesc>(op_name, ge::parser::DATA), return FAILED);
- graphStatus status = op->AddOutputDesc(ge::GeTensorDesc());
- if (status != GRAPH_SUCCESS) {
- REPORT_CALL_ERROR("E19999", "Add output desc to op:%s(%s) failed", op->GetName().c_str(), op->GetType().c_str());
- GELOGE(FAILED, "Add output desc for op:%s failed.", op->GetName().c_str());
- return FAILED;
- }
-
- (void)ge::AttrUtils::SetInt(op, "T", (int32_t)dtype);
- (void)ge::AttrUtils::SetInt(op, "arg_index", (int32_t)index);
- ge::NodePtr arg_node = graph->AddNode(op);
- GE_CHECK_NOTNULL(arg_node);
- bool node_exists = false;
- for (const auto &node : graph->GetDirectNode()) {
- if (node->GetName() == anchor->GetOwnerNode()->GetName()) {
- ge::OutDataAnchorPtr out_archor_ptr = arg_node->GetOutDataAnchor(0);
- GE_CHECK_NOTNULL(out_archor_ptr);
- ge::InDataAnchorPtr in_archor_ptr = node->GetInDataAnchor(anchor->GetPeerOutAnchor()->GetIdx());
- GE_CHECK_NOTNULL(in_archor_ptr);
- (void)ge::GraphUtils::RemoveEdge(in_archor_ptr->GetPeerOutAnchor(), in_archor_ptr);
- ge::graphStatus ret = ge::GraphUtils::AddEdge(out_archor_ptr, in_archor_ptr);
- if (ret != ge::GRAPH_SUCCESS) {
- REPORT_CALL_ERROR("E19999", "Add control edge between op:%s(%s)(index:%d) and op:%s(%s)(index:%d) failed",
- out_archor_ptr->GetOwnerNode()->GetName().c_str(),
- out_archor_ptr->GetOwnerNode()->GetType().c_str(), out_archor_ptr->GetIdx(),
- in_archor_ptr->GetOwnerNode()->GetName().c_str(),
- in_archor_ptr->GetOwnerNode()->GetType().c_str(), in_archor_ptr->GetIdx());
- GELOGE(domi::INTERNAL_ERROR, "Add edge failed,src op:%s,dst op:%s", arg_node->GetName().c_str(),
- node->GetName().c_str());
- return FAILED;
- }
- node_exists = true;
- }
- }
- GE_IF_BOOL_EXEC(!node_exists,
- REPORT_CALL_ERROR("E19999", "Node:%s(%s) not found in graph:%s, check invalid",
- anchor->GetOwnerNode()->GetName().c_str(),
- anchor->GetOwnerNode()->GetType().c_str(),
- graph->GetName().c_str());
- GELOGE(FAILED, "node not exists!"); return FAILED);
- arg_datetypes_.emplace_back(domi::tensorflow::DataType(dtype));
- index++;
- }
- return SUCCESS;
- }
-
- // Convert Davinci's graph to tensorflow's functiondef
- domi::Status GraphToFunctionDef::DavGraphToFunctionDef(ge::ComputeGraphPtr graph, const string &name,
- FunctionDef *fdef) {
- GE_CHECK_NOTNULL(graph);
- GE_CHECK_NOTNULL(fdef);
- fdef->mutable_signature()->set_name(name);
-
- std::map<string, string> tensor_renaming;
- std::map<string, string> return_values;
- NameMapHelper node_names;
-
- for (const ge::NodePtr &node : graph->GetDirectNode()) {
- GE_CHECK_NOTNULL(node);
- if (node->GetOpDesc()->GetType() == ge::parser::DATA) {
- int64_t index = 0;
- int64_t type = 1;
- GE_CHK_BOOL_RET_STATUS(ge::AttrUtils::GetInt(node->GetOpDesc(), "T", type), PARAM_INVALID,
- "Get type attr failed");
-
- GE_CHK_BOOL_RET_STATUS(ge::AttrUtils::GetInt(node->GetOpDesc(), "arg_index", index), PARAM_INVALID,
- "Get arg_index attr failed");
-
- while (fdef->signature().input_arg_size() <= index) {
- fdef->mutable_signature()->add_input_arg();
- }
- domi::tensorflow::OpDef::ArgDef *argdef = fdef->mutable_signature()->mutable_input_arg(index);
- argdef->set_type(domi::tensorflow::DataType(type));
- const string normalized = node_names.UniqueInputOrOutputName(node->GetName());
- argdef->set_name(normalized);
- tensor_renaming[node->GetName() + ":0"] = normalized;
- continue;
- }
-
- if (node->GetOpDesc()->GetType() == ge::parser::NETOUTPUT) {
- int64_t index = 0;
- int64_t type = 1;
- GE_CHK_BOOL_RET_STATUS(ge::AttrUtils::GetInt(node->GetOpDesc(), "T", type), PARAM_INVALID,
- "Get type attr failed");
-
- GE_CHK_BOOL_RET_STATUS(ge::AttrUtils::GetInt(node->GetOpDesc(), "ret_index", index), PARAM_INVALID,
- "Get arg_index attr failed");
-
- while (fdef->signature().output_arg_size() <= index) {
- fdef->mutable_signature()->add_output_arg();
- }
-
- domi::tensorflow::OpDef::ArgDef *argdef = fdef->mutable_signature()->mutable_output_arg(index);
- argdef->set_type(domi::tensorflow::DataType(type));
- const string normalized = node_names.UniqueInputOrOutputName(node->GetName());
- argdef->set_name(normalized);
-
- ge::OutDataAnchorPtr o_anchor = node->GetAllInDataAnchors().at(0)->GetPeerOutAnchor();
- GE_CHECK_NOTNULL(o_anchor);
- string n_name = o_anchor->GetOwnerNode()->GetName() + ":" + to_string(o_anchor->GetIdx());
- return_values[normalized] = n_name;
- continue;
- }
-
- // Analysis of nodedef of original tensorflow
- ge::Buffer nodedef_bytes;
- GE_CHK_BOOL_RET_STATUS(ge::AttrUtils::GetBytes(node->GetOpDesc(), ge::ATTR_NAME_FRAMEWORK_NODE_DEF, nodedef_bytes),
- PARAM_INVALID, "Get type attr nodedef failed.");
- domi::tensorflow::NodeDef node_def_;
- GE_CHK_BOOL_RET_STATUS(node_def_.ParseFromArray(nodedef_bytes.GetData(), nodedef_bytes.GetSize()), PARAM_INVALID,
- "parse nodedef failed.");
-
- // Analysis of opdef of original tensorflow
- string opdef_string;
- GE_CHK_BOOL_RET_STATUS(ge::AttrUtils::GetStr(node->GetOpDesc(), ge::ATTR_NAME_FRAMEWORK_OP_DEF, opdef_string),
- PARAM_INVALID, "Get type attr op_def failed.");
-
- domi::tensorflow::OpDef op_def;
- GE_CHK_BOOL_RET_STATUS(op_def.ParseFromString(opdef_string), PARAM_INVALID, "parse op_def failed.");
-
- // add nodedef
- NodeDef *node_def = fdef->add_node_def();
- *node_def = node_def_;
-
- node_def->mutable_attr()->erase(ge::ATTR_NAME_FRAMEWORK_OP_DEF);
- node_def->mutable_attr()->erase(ge::ATTR_NAME_OUTPUT_TENSOR_DESC);
- node_def->mutable_attr()->erase(ge::ATTR_NAME_INPUT_TENSOR_DESC);
- // No device information required for framework
- node_def->clear_device();
-
- node_def->set_name(node_names.UniqueNodeName(node->GetName()));
-
- // Reset input names based on graph rather than the NodeDef.
- node_def->clear_input();
-
- // Edges, indexed by dst_input.
- vector<ge::InDataAnchorPtr> in_anchors;
- ge::InControlAnchorPtr in_control_anchor;
-
- for (const auto &anchor : node->GetAllInDataAnchors()) {
- if (static_cast<int>(in_anchors.size()) <= anchor->GetIdx()) {
- in_anchors.resize(anchor->GetIdx() + 1);
- }
- in_anchors[anchor->GetIdx()] = anchor;
- }
-
- // Add regular inputs
- for (auto anchor : in_anchors) {
- GE_IF_BOOL_EXEC(anchor == nullptr,
- REPORT_INNER_ERROR("E19999", "Nonconsecutive input edges; missing input edge for node %s",
- node_def_.name().c_str());
- GELOGE(domi::INTERNAL_ERROR, "Nonconsecutive input edges; missing input edge , for node %s .",
- node_def_.name().c_str());
- return domi::INTERNAL_ERROR);
-
- if (anchor->GetPeerOutAnchor() != nullptr) {
- string t_name =
- anchor->GetPeerOutAnchor()->GetOwnerNode()->GetName() + ":" + to_string(anchor->GetPeerOutAnchor()->GetIdx());
- node_def->add_input(t_name);
- }
- }
-
- // Add control inputs
- GE_CHECK_NOTNULL(node->GetInControlAnchor());
- for (const auto &anchor : node->GetInControlAnchor()->GetPeerOutControlAnchors()) {
- node_def->add_input("^" + anchor->GetOwnerNode()->GetName());
- }
-
- // Populate tensor_renaming.
- NameRangeMap output_ranges;
- GE_RETURN_IF_ERROR(NameRangesForNode(node_def_, op_def, &output_ranges));
-
- for (const auto &output : output_ranges) {
- for (int i = output.second.first; i < output.second.second; ++i) {
- const string tensor_name = node_def->name() + ":" + output.first + ":" + to_string(i - output.second.first);
- tensor_renaming[(node->GetName() + ":" + to_string(i))] = tensor_name;
- }
- }
- }
-
- // Remap FunctionDef
- GE_RETURN_IF_ERROR(RemapFunctionDef(fdef, name, node_names, tensor_renaming, return_values));
-
- return SUCCESS;
- }
-
- void SetInputOut(NodeDef *call_node_def, vector<ge::InDataAnchorPtr> &in_anchor) {
- GE_CHK_BOOL_EXEC(call_node_def != nullptr, return, "call_node_def is null.");
- for (const auto &anchor : in_anchor) {
- if ((anchor != nullptr) && (anchor->GetPeerOutAnchor() != nullptr)) {
- call_node_def->add_input(anchor->GetPeerOutAnchor()->GetOwnerNode()->GetName() + "_" +
- to_string(anchor->GetPeerOutAnchor()->GetIdx()));
- }
- }
- }
-
- domi::Status GraphToFunctionDef::BuildFunctionDef(ge::ComputeGraphPtr &graph, const string &name_in,
- FunctionDefLibrary *library, NodeDef *call_node_def,
- vector<ge::InDataAnchorPtr> &in_anchor,
- vector<ge::OutDataAnchorPtr> &out_anchor) {
- GE_CHECK_NOTNULL(graph);
- GE_CHECK_NOTNULL(library);
- GE_CHECK_NOTNULL(call_node_def);
- // Current date / time base on the current system
- string now_time = ge::parser::CurrentTimeInStr();
- static int i = 0;
- const string name = name_in + now_time + to_string(i);
- i++;
- // set node_def
- call_node_def->set_op(name);
- call_node_def->set_name(name);
-
- // Add func property
- domi::tensorflow::AttrValue value;
- domi::tensorflow::NameAttrList *function = value.mutable_func();
- function->set_name(name);
- *function->mutable_attr() = call_node_def->attr();
- GraphToFunctionDef::AddNodeAttr("function", value, call_node_def);
-
- // Add input for nodedef
- SetInputOut(call_node_def, in_anchor);
-
- // Add input and output nodes to the graph
- GE_RETURN_IF_ERROR(GraphToFunctionDef::RecordArg(graph, in_anchor));
- GE_RETURN_IF_ERROR(GraphToFunctionDef::RecordResult(graph, out_anchor));
-
- domi::tensorflow::AttrValue tin_value;
- domi::tensorflow::AttrValue tout_value;
- // Add tin tout attribute
- domi::tensorflow::AttrValue::ListValue list;
- for (auto type : arg_datetypes_) {
- tin_value.mutable_list()->clear_type();
- tin_value.mutable_list()->add_type(type);
- }
- if (!arg_datetypes_.empty()) {
- GraphToFunctionDef::AddNodeAttr("Tin", tin_value, call_node_def);
- }
- for (auto type : result_datetypes_) {
- tout_value.mutable_list()->clear_type();
- tout_value.mutable_list()->add_type(type);
- }
- if (!result_datetypes_.empty()) {
- GraphToFunctionDef::AddNodeAttr("Tout", tout_value, call_node_def);
- }
- // Convert DaVinci graph to functiondef
- FunctionDef *fdef = library->add_function();
- GE_RETURN_IF_ERROR(GraphToFunctionDef::DavGraphToFunctionDef(graph, name, fdef));
-
- return SUCCESS;
- }
-
- bool GraphToFunctionDef::FindAttrValue(const domi::tensorflow::NodeDef *node_def, const string attr_name,
- domi::tensorflow::AttrValue &attr_value) {
- if (node_def == nullptr) {
- GELOGE(PARAM_INVALID, "Input param node is nullptr.");
- return false;
- }
- const google::protobuf::Map<std::string, domi::tensorflow::AttrValue> &attr = node_def->attr();
-
- const google::protobuf::Map<std::string, domi::tensorflow::AttrValue>::const_iterator it = attr.find(attr_name);
- if (it != attr.end()) {
- attr_value = it->second;
- return true;
- }
-
- return false;
- }
-
- void GraphToFunctionDef::AddNodeAttr(const string &attr_name, const domi::tensorflow::AttrValue &value,
- domi::tensorflow::NodeDef *node_def) {
- if (node_def == nullptr) {
- GELOGI("input parameter is null.");
- return;
- }
- node_def->mutable_attr()->insert(AttrValueMap::value_type(attr_name, value));
- }
- } // namespace ge
|