|
- /**
- * 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 "parser/common/acl_graph_parser_util.h"
-
- #include <dlfcn.h>
- #include <regex.h>
-
- #include <cstdlib>
- #include <ctime>
- #include <fstream>
-
- #include "common/string_util.h"
- #include "common/util.h"
- #include "common/util/error_manager/error_manager.h"
- #include "external/ge/ge_api_types.h"
- #include "framework/common/debug/ge_log.h"
- #include "framework/omg/parser/parser_types.h"
- #include "ge/ge_api_types.h"
- #include "google/protobuf/io/coded_stream.h"
- #include "google/protobuf/io/zero_copy_stream_impl.h"
- #include "graph/debug/ge_attr_define.h"
- #include "graph/opsproto_manager.h"
- #include "graph/utils/type_utils.h"
- #include "omg/parser/parser_inner_ctx.h"
- #include "parser/common/register_tbe.h"
- #include "tbe_plugin_loader.h"
- #include "mmpa/mmpa_api.h"
-
- using google::protobuf::io::CodedInputStream;
- using google::protobuf::io::FileInputStream;
- using google::protobuf::io::ZeroCopyInputStream;
- using namespace ge::parser;
-
- namespace {
- const std::string kGraphDefaultName = "domi_default";
- /// The maximum length of the file.
- /// Based on the security coding specification and the current actual (protobuf) model size, it is determined as 2G-1
- const int kMaxFileSizeLimit = INT_MAX;
- const int kMaxBuffSize = 256;
- const int kProtoReadBytesLimit = INT_MAX; // Max size of 2 GB minus 1 byte.
- const int kWarningThreshold = 536870912 * 2; // 536870912 represent 512M
- const uint32_t kSetOutputWithNodeAndIndex = 0x1;
- const uint32_t kSetOutputWithTensorName = 0x2;
- const uint32_t kSetOutputModeMixed = 0x3;
- const std::set<domi::FrameworkType> kSupportTensorAsOutput = {
- domi::CAFFE,
- domi::ONNX
- };
-
- static string GetSoPath() {
- Dl_info dl_info;
- if (dladdr(reinterpret_cast<void *>(&GetSoPath), &dl_info) == 0) {
- GELOGW("Failed to read so_path!");
- return string();
- } else {
- std::string so_path = dl_info.dli_fname;
- char path[PATH_MAX] = {0};
- if (so_path.length() >= PATH_MAX) {
- GELOGW("File path is too long!");
- return string();
- }
- if (realpath(so_path.c_str(), path) == nullptr) {
- GELOGW("Failed to get realpath of %s", so_path.c_str());
- return string();
- }
-
- so_path = path;
- so_path = so_path.substr(0, so_path.rfind('/') + 1);
- return so_path;
- }
- }
-
- static void GetOpsProtoPath(string &opsproto_path) {
- GELOGD("Start to get ops proto path schedule.");
- const char *path_env = std::getenv("ASCEND_OPP_PATH");
- if (path_env != nullptr) {
- string path = path_env;
- string file_path = ge::parser::RealPath(path.c_str());
- if (file_path.empty()) {
- REPORT_INNER_ERROR("E19999", "File path %s is invalid.", path.c_str());
- GELOGE(ge::FAILED, "[Get][Path] File path %s is invalid.", path.c_str());
- return;
- }
- opsproto_path = (path + "/op_proto/custom/" + ":") + (path + "/op_proto/built-in/");
- GELOGI("Get opsproto so path from env : %s", path.c_str());
- return;
- }
- string path_base = GetSoPath();
- GELOGI("path_base is %s", path_base.c_str());
- path_base = path_base.substr(0, path_base.rfind('/'));
- path_base = path_base.substr(0, path_base.rfind('/') + 1);
- opsproto_path = (path_base + "ops/op_proto/custom/" + ":") + (path_base + "ops/op_proto/built-in/");
- }
-
- static void GetAclParams(const std::map<ge::AscendString, ge::AscendString> &parser_params, const string &key,
- string &value) {
- for (auto &ele : parser_params) {
- const char *key_ascend = ele.first.GetString();
- if (key_ascend == nullptr) {
- GELOGW("Input options key is null, Please check!");
- continue;
- }
-
- string key_str = key_ascend;
- if (key == key_str) {
- const char *value_ascend = ele.second.GetString();
- if (value_ascend == nullptr) {
- value = "";
- } else {
- value = value_ascend;
- }
- return;
- }
- }
- value = "";
- return;
- }
-
- static bool CheckDigitStr(std::string &str) {
- for (char c : str) {
- if (!isdigit(c)) {
- REPORT_CALL_ERROR("E19999", "param str:%s is not positive integer", str.c_str());
- GELOGE(domi::FAILED, "[Check][Param] Value[%s] is not positive integer", str.c_str());
- return false;
- }
- }
- return true;
- }
- } // namespace
-
- namespace ge {
- static bool CheckInputTrueOrFalse(const std::string &s, const std::string &atc_param) {
- if ((s == "true") || (s == "false")) {
- return true;
- } else {
- ErrorManager::GetInstance().ATCReportErrMessage("E10005", {"parameter", "value"}, {atc_param, s});
- GELOGE(PARAM_INVALID, "[Check][Param] Input parameter[%s]'s value[%s] must be true or false.",
- atc_param.c_str(), s.c_str());
- return false;
- }
- }
-
- static Status CheckOutNode(ge::OpDescPtr op_desc, int32_t index) {
- int32_t out_size = op_desc->GetOutputsSize();
- if (index < 0 || index >= out_size) {
- GELOGE(domi::FAILED, "[Check][Param]out_node [%s] output index:%d must be smaller "
- "than node output size:%d and can not be negative!", op_desc->GetName().c_str(), index, out_size);
- std::string fail_reason = "output index:" + to_string(index) +
- " must be smaller than output size:" + to_string(out_size) + " and can not be negative!";
- ErrorManager::GetInstance().ATCReportErrMessage("E10003", {"parameter", "value", "reason"},
- {"out_nodes", op_desc->GetName(), fail_reason});
- return domi::FAILED;
- }
- return domi::SUCCESS;
- }
-
- domi::Status AclGrphParseUtil::LoadOpsProtoLib() {
- string opsproto_path;
- GetOpsProtoPath(opsproto_path);
- GELOGI("Get opsproto path is %s", opsproto_path.c_str());
- OpsProtoManager *manager = OpsProtoManager::Instance();
- map<string, string> option_tmp;
- option_tmp.emplace(std::pair<string, string>(string("ge.opsProtoLibPath"), opsproto_path));
- bool is_proto_init = manager->Initialize(option_tmp);
- if (!is_proto_init) {
- REPORT_INNER_ERROR("E19999", "OpsProtoManager init failed because ops proto path:%s is invalid.",
- opsproto_path.c_str());
- GELOGE(FAILED, "[Invoke][Initialize] Load ops_proto lib failed, ops proto path:%s is invalid.",
- opsproto_path.c_str());
- return FAILED;
- }
- return SUCCESS;
- }
-
- void AclGrphParseUtil::SaveCustomCaffeProtoPath() {
- GELOGD("Enter save custom caffe proto path.");
- std::string path_base = GetSoPath();
- path_base = path_base.substr(0, path_base.rfind('/'));
- path_base = path_base.substr(0, path_base.rfind('/') + 1);
- ge::GetParserContext().caffe_proto_path = path_base + "include/proto/";
-
- string custom_op_path;
- const char *path_env = std::getenv("ASCEND_OPP_PATH");
- if (path_env != nullptr) {
- std::string path = path_env;
- custom_op_path = path + "/framework/custom/caffe/";
- GELOGI("Get custom proto path from env : %s", path_env);
- GetParserContext().custom_proto_path = custom_op_path;
- return;
- }
- custom_op_path = path_base + "ops/framework/custom/caffe/";
- ge::GetParserContext().custom_proto_path = custom_op_path;
- return;
- }
-
- // Initialize PARSER, load custom op plugin
- // options will be used later for parser decoupling
- domi::Status AclGrphParseUtil::AclParserInitialize(const std::map<std::string, std::string> &options) {
- GELOGT(TRACE_INIT, "AclParserInitialize start");
- // check init status
- if (parser_initialized) {
- GELOGW("AclParserInitialize is called more than once");
- return SUCCESS;
- }
-
- // load custom op plugin
- TBEPluginLoader::Instance().LoadPluginSo(options);
-
- // load and save custom op proto for prediction
- (void)LoadOpsProtoLib();
- SaveCustomCaffeProtoPath();
-
- auto op_registry = domi::OpRegistry::Instance();
- if (op_registry == nullptr) {
- REPORT_CALL_ERROR("E19999", "Call OpRegistry::Instance failed, ret nullptr.");
- GELOGE(FAILED, "[Get][OpRegistry] instance failed");
- return FAILED;
- }
-
- auto it = options.find(ge::FRAMEWORK_TYPE);
- if (it == options.end()) {
- REPORT_INNER_ERROR("E19999", "Can not find ge.frameworkType in param options");
- GELOGE(FAILED, "[Check][Param]Can not find ge.frameworkType in options");
- return FAILED;
- }
- std::string fmk_type = it->second;
- std::vector<OpRegistrationData> registrationDatas = op_registry->registrationDatas;
- GELOGI("The size of registrationDatas in parser is: %zu", registrationDatas.size());
- for (OpRegistrationData ®_data : registrationDatas) {
- if (std::to_string(reg_data.GetFrameworkType()) == fmk_type) {
- (void)OpRegistrationTbe::Instance()->Finalize(reg_data, false);
- (void)domi::OpRegistry::Instance()->Register(reg_data);
- }
- }
-
- // set init status
- if (!parser_initialized) {
- // Initialize success, first time calling initialize
- parser_initialized = true;
- }
-
- GELOGT(TRACE_STOP, "AclParserInitialize finished");
- return SUCCESS;
- }
-
- void AclGrphParseUtil::SetDefaultFormat() {
- if (ge::GetParserContext().type == domi::TENSORFLOW) {
- ge::GetParserContext().format = domi::DOMI_TENSOR_NHWC;
- } else {
- ge::GetParserContext().format = domi::DOMI_TENSOR_NCHW;
- }
- }
-
- domi::Status AclGrphParseUtil::ParseAclOutputNodes(const string &out_nodes) {
- try {
- ge::GetParserContext().out_nodes_map.clear();
- ge::GetParserContext().user_out_nodes.clear();
- ge::GetParserContext().user_out_tensors.clear();
- ge::GetParserContext().default_out_nodes.clear();
- // parse output node
- if (!out_nodes.empty()) {
- uint32_t set_output_mode = 0;
-
- vector<string> nodes_v = StringUtils::Split(out_nodes, ';');
- for (const string &node : nodes_v) {
- vector<string> key_value_v = StringUtils::Split(node, ':');
- if (key_value_v.size() != 2) { // The size must be 2.
- if (key_value_v.size() == 1 && kSupportTensorAsOutput.count(ge::GetParserContext().type) > 0) {
- set_output_mode |= kSetOutputWithTensorName;
- if (set_output_mode == kSetOutputModeMixed) {
- break;
- }
- ge::GetParserContext().user_out_tensors.push_back(node);
- continue;
- }
- ErrorManager::GetInstance().ATCReportErrMessage(
- "E10001", {"parameter", "value", "reason"},
- {"out_nodes", node, "the correct format is \"node_name1:0; node_name1:1; node_name2:0\""});
- GELOGE(PARAM_INVALID, "[Check][Param] The input format of out_nodes is invalid, the correct format is "
- "\"node_name1:0; node_name1:1; node_name2:0\", while the actual input is %s.",
- node.c_str());
- return PARAM_INVALID;
- }
- set_output_mode |= kSetOutputWithNodeAndIndex;
- if (set_output_mode == kSetOutputModeMixed) {
- break;
- }
- // stoi: The method may throw an exception: invalid_argument/out_of_range
- if (!CheckDigitStr(key_value_v[1])) {
- ErrorManager::GetInstance().ATCReportErrMessage("E10001", {"parameter", "value", "reason"},
- {"out_nodes", out_nodes, "is not positive integer"});
- GELOGE(PARAM_INVALID, "[Check][Param] This str:%s must be digit string, while the actual input is %s",
- key_value_v[1].c_str(), out_nodes.c_str());
- return PARAM_INVALID;
- }
-
- auto iter = ge::GetParserContext().out_nodes_map.find(key_value_v[0]);
- int32_t index = stoi(StringUtils::Trim(key_value_v[1]));
- GELOGD("Get output info: node[%s] and index[%d]", key_value_v[0].c_str(), index);
- if (iter != ge::GetParserContext().out_nodes_map.end()) {
- iter->second.emplace_back(index);
- } else {
- std::vector<int32_t> index_v;
- index_v.emplace_back(index);
- ge::GetParserContext().out_nodes_map.emplace(key_value_v[0], index_v);
- }
- ge::GetParserContext().user_out_nodes.emplace_back(key_value_v[0], index);
- }
- if (set_output_mode == kSetOutputModeMixed) {
- ErrorManager::GetInstance().ATCReportErrMessage("E10001", {"parameter", "value", "reason"},
- {"--out_nodes", out_nodes, "is not all index or top_name"});
- GELOGE(PARAM_INVALID, "[Parse][Param]This out_nodes str must be all index or tensor_name, "
- "while the actual input is %s", out_nodes.c_str());
- return PARAM_INVALID;
- }
- }
- } catch (std::invalid_argument &) {
- GELOGE(PARAM_INVALID, "[Check][Param] Invalid of out_nodes: %s ", out_nodes.c_str());
- ErrorManager::GetInstance().ATCReportErrMessage("E10014", {"parameter", "value"}, {"out_nodes", out_nodes});
- return PARAM_INVALID;
- } catch (std::out_of_range &) {
- GELOGE(PARAM_INVALID, "[Check][Param] Invalid of out_nodes: %s ", out_nodes.c_str());
- ErrorManager::GetInstance().ATCReportErrMessage("E10013", {"parameter", "value"}, {"out_nodes", out_nodes});
- return PARAM_INVALID;
- }
- return SUCCESS;
- }
-
- domi::Status AclGrphParseUtil::ParseAclOutputFp16NodesFormat(const string &is_output_fp16) {
- if (is_output_fp16.empty()) {
- return SUCCESS;
- }
-
- vector<domiTensorFormat_t> &output_formats = ge::GetParserContext().output_formats;
- output_formats.clear();
- vector<string> node_format_vec = StringUtils::Split(is_output_fp16, ',');
- for (auto &is_fp16 : node_format_vec) {
- StringUtils::Trim(is_fp16);
- if (!CheckInputTrueOrFalse(is_fp16, "is_output_adjust_hw_layout")) {
- GELOGE(PARAM_INVALID, "[Check][Param]Invalid Param, is_output_adjust_hw_layout "
- "only support true/false: but is [%s]", is_output_fp16.c_str());
- return PARAM_INVALID;
- }
- if (is_fp16 == "false") {
- output_formats.push_back(DOMI_TENSOR_ND);
- } else if (is_fp16 == "true") {
- output_formats.push_back(domi::DOMI_TENSOR_NC1HWC0);
- }
- }
- return SUCCESS;
- }
-
- domi::Status AclGrphParseUtil::ParseAclEnableScope(const string &enable_scope_fusion_passes) {
- ge::GetParserContext().enable_scope_fusion_passes.clear();
- if (enable_scope_fusion_passes.empty()) {
- return SUCCESS;
- }
- ge::GetParserContext().enable_scope_fusion_passes = enable_scope_fusion_passes;
- return SUCCESS;
- }
-
- void AclGrphParseUtil::AddAttrsForInputNodes(const vector<string> &adjust_fp16_format_vec,
- const string &fp16_nodes_name, uint32_t index, OpDescPtr &op_desc) {
- if (AttrUtils::SetStr(op_desc, ATTR_ATC_USER_DEFINE_DATATYPE, TypeUtils::DataTypeToSerialString(DT_FLOAT16))) {
- if ((index < adjust_fp16_format_vec.size()) && (adjust_fp16_format_vec[index] == "true")) {
- GELOGI("This node [%s] should be set NC1HWC0", fp16_nodes_name.c_str());
- if (!AttrUtils::SetStr(op_desc, ATTR_ATC_USER_DEFINE_FORMAT, TypeUtils::FormatToSerialString(FORMAT_NC1HWC0))) {
- GELOGW("This node [%s] set NC1HWC0 failed", fp16_nodes_name.c_str());
- }
- }
- }
- }
-
- domi::Status AclGrphParseUtil::ParseAclInputFp16Nodes(const ComputeGraphPtr &graph, const string &input_fp16_nodes,
- const string &is_input_adjust_hw_layout) {
- GE_CHECK_NOTNULL(graph);
- vector<string> adjust_fp16_format_vec;
- if (!is_input_adjust_hw_layout.empty()) {
- adjust_fp16_format_vec = StringUtils::Split(is_input_adjust_hw_layout, ',');
- for (auto &s : adjust_fp16_format_vec) {
- StringUtils::Trim(s);
- if (!CheckInputTrueOrFalse(s, "is_input_adjust_hw_layout")) {
- GELOGE(PARAM_INVALID, "[Check][Param] Invalid Param, is_input_adjust_hw_layout "
- "only support true/false: but is [%s]", is_input_adjust_hw_layout.c_str());
- return PARAM_INVALID;
- }
- }
- }
- if (input_fp16_nodes.empty()) {
- return SUCCESS;
- }
- GELOGI("The input_fp16_nodes is set %s", input_fp16_nodes.c_str());
- vector<string> input_fp16_nodes_vec = StringUtils::Split(input_fp16_nodes, ';');
- for (uint32_t i = 0; i < input_fp16_nodes_vec.size(); ++i) {
- ge::NodePtr node = graph->FindNode(input_fp16_nodes_vec[i]);
- if (node == nullptr) {
- ErrorManager::GetInstance().ATCReportErrMessage("E10016", {"parameter", "opname"},
- {"input_fp16_nodes", input_fp16_nodes_vec[i]});
- GELOGE(PARAM_INVALID, "[Check][Param] Input parameter[input_fp16_nodes]'s opname[%s] is not exist in model",
- input_fp16_nodes_vec[i].c_str());
- return PARAM_INVALID;
- }
- auto op_desc = node->GetOpDesc();
- GE_CHECK_NOTNULL(op_desc);
- if (op_desc->GetType() != ge::parser::DATA) {
- ErrorManager::GetInstance().ATCReportErrMessage("E10017", {"parameter", "opname"},
- {"input_fp16_nodes", input_fp16_nodes_vec[i]});
- GELOGE(PARAM_INVALID, "[Check][Param] Input parameter[input_fp16_nodes]'s opname[%s] is not a input opname",
- input_fp16_nodes_vec[i].c_str());
- return PARAM_INVALID;
- }
- AddAttrsForInputNodes(adjust_fp16_format_vec, input_fp16_nodes_vec[i], i, op_desc);
- }
- return SUCCESS;
- }
-
- void AclGrphParseUtil::CreateOutputNodesInfo(std::vector<std::pair<ge::NodePtr, int32_t>> &output_nodes_info,
- std::vector<std::string> &output_nodes_name) {
- output_nodes_name.clear();
- auto &out_tensor_names = ge::GetParserContext().out_tensor_names;
- if (out_tensor_names.empty()) {
- // tf process, no top name.
- for (const auto output_node_info : output_nodes_info) {
- std::string node_name = output_node_info.first->GetName();
- int32_t index = output_node_info.second;
- output_nodes_name.push_back(node_name + ":" + std::to_string(index));
- }
- return;
- }
-
- // Need add top name after node_name:index
- for (size_t i = 0; i < output_nodes_info.size(); ++i) {
- auto node = output_nodes_info[i].first;
- int32_t index = output_nodes_info[i].second;
- std::string node_name = node->GetName();
- if (i < out_tensor_names.size()) {
- auto output_desc = node->GetOpDesc()->MutableOutputDesc(static_cast<uint32_t>(index));
- (void)AttrUtils::SetStr(output_desc, ATTR_NAME_ORIGIN_OUTPUT_TENSOR_NAME, out_tensor_names[i]);
- std::string output_name = node->GetName() + ":" + std::to_string(index) + ":" + out_tensor_names[i];
- output_nodes_name.push_back(output_name);
- GELOGD("Output[%zu] name[%s]", i, output_name.c_str());
- } else {
- GELOGW("Get top name of node [%s] fail.", node_name.c_str());
- output_nodes_name.push_back(node_name + ":" + std::to_string(index));
- }
- }
- }
-
- domi::Status AclGrphParseUtil::GetOutputLeaf(NodePtr node,
- std::vector<std::pair<ge::NodePtr, int32_t>> &output_nodes_info) {
- ge::OpDescPtr tmpDescPtr = node->GetOpDesc();
- if (tmpDescPtr == nullptr) {
- REPORT_INNER_ERROR("E19999", "param node has no opdesc.");
- GELOGE(domi::FAILED, "[Get][OpDesc] param node has no opdesc.");
- return domi::FAILED;
- }
- size_t size = tmpDescPtr->GetOutputsSize();
- if (node->GetType() != ge::parser::NETOUTPUT) {
- for (size_t index = 0; index < size; ++index) {
- output_nodes_info.push_back(std::make_pair(node, index));
- GELOGD("Get output leaf node:%s.", node->GetName().c_str());
- }
- } else {
- const auto in_anchors = node->GetAllInDataAnchors();
- for (auto in_anchor : in_anchors) {
- auto out_anchor = in_anchor->GetPeerOutAnchor();
- if (out_anchor == nullptr) {
- REPORT_INNER_ERROR("E19999", "Get leaf node op desc fail.");
- GELOGE(domi::FAILED, "[Invoke][GetPeerOutAnchor] Get leaf node op desc fail.");
- return domi::FAILED;
- }
- auto out_node = out_anchor->GetOwnerNode();
- output_nodes_info.push_back(std::make_pair(out_node, out_anchor->GetIdx()));
- }
- }
- return SUCCESS;
- }
-
- domi::Status AclGrphParseUtil::GetDefaultOutInfo(ge::ComputeGraphPtr &compute_graph,
- std::vector<std::pair<ge::NodePtr, int32_t>> &output_nodes_info) {
- std::vector<std::pair<std::string, int32_t>> default_out_nodes = ge::GetParserContext().default_out_nodes;
- if (!default_out_nodes.empty()) {
- for (uint32_t i = 0; i < default_out_nodes.size(); ++i) {
- ge::NodePtr out_node = compute_graph->FindNode(default_out_nodes[i].first);
- if (out_node == nullptr) {
- ErrorManager::GetInstance().ATCReportErrMessage("E10016", {"parameter", "opname"},
- {"out_nodes", default_out_nodes[i].first});
- GELOGE(domi::FAILED, "[Check][Param] Can not find out_nodes(%d) (%s) in graph.",
- i, default_out_nodes[i].first.c_str());
- return domi::FAILED;
- }
- output_nodes_info.push_back(std::make_pair(out_node, default_out_nodes[i].second));
- GELOGD("Get default output node:%s.", out_node->GetName().c_str());
- }
- return domi::SUCCESS;
- }
-
- for (ge::NodePtr node : compute_graph->GetDirectNode()) {
- if (!node->GetInAllNodes().empty() && node->GetOutAllNodes().empty()) {
- Status ret = GetOutputLeaf(node, output_nodes_info);
- GE_CHK_BOOL_RET_STATUS(ret == SUCCESS, ret, "[Invoke][GetOutputLeaf] Find leaf fail.");
- }
- }
- return domi::SUCCESS;
- }
-
- domi::Status AclGrphParseUtil::SetOutputNodeInfo(ge::Graph &graph,
- const std::map<AscendString, AscendString> &parser_params) {
- (void)parser_params;
- ge::ComputeGraphPtr compute_graph = ge::GraphUtils::GetComputeGraph(graph);
- GE_CHECK_NOTNULL(compute_graph);
-
- std::vector<std::pair<std::string, int32_t>> user_out_nodes = ge::GetParserContext().user_out_nodes;
- std::vector<domiTensorFormat_t> output_formats = ge::GetParserContext().output_formats;
- std::vector<std::pair<ge::NodePtr, int32_t>> output_nodes_info;
- std::vector<std::string> output_nodes_name;
-
- // User declared outputs
- for (uint32_t i = 0; i < user_out_nodes.size(); ++i) {
- ge::NodePtr out_node = compute_graph->FindNode(user_out_nodes[i].first);
- if (out_node == nullptr) {
- ErrorManager::GetInstance().ATCReportErrMessage("E10016", {"parameter", "opname"},
- {"out_nodes", user_out_nodes[i].first});
- GELOGE(domi::FAILED, "[Check][Param] Can not find out_nodes(%d) (%s) in graph.",
- i, user_out_nodes[i].first.c_str());
- return domi::FAILED;
- }
- auto op_desc = out_node->GetOpDesc();
- GE_CHECK_NOTNULL(op_desc);
- if (CheckOutNode(op_desc, user_out_nodes[i].second) != SUCCESS) {
- GELOGE(domi::FAILED, "[CheckOut][Node] (%s) fail.", user_out_nodes[i].first.c_str());
- return domi::FAILED;
- }
-
- // add user_define_output_nodes attr.
- (void)ge::AttrUtils::SetStr(op_desc, ATTR_ATC_USER_DEFINE_OUTPUT_NODES, "true");
-
- if (i < output_formats.size()) {
- if (output_formats[i] == domi::DOMI_TENSOR_NC1HWC0) {
- GELOGI("The output node [%s] should be set NC1HWC0", user_out_nodes[i].first.c_str());
- vector<string> output_fp16_5hd_vec;
- (void)ge::AttrUtils::GetListStr(op_desc, "_user_defined_output_fp16_5hd", output_fp16_5hd_vec);
- output_fp16_5hd_vec.push_back(std::to_string(user_out_nodes[i].second) + ":" + "NC1HWC0");
- (void)ge::AttrUtils::SetListStr(op_desc, "_user_defined_output_fp16_5hd", output_fp16_5hd_vec);
- }
- }
- output_nodes_info.push_back(std::make_pair(out_node, user_out_nodes[i].second));
- }
- // default output node (leaf)
- if (user_out_nodes.empty()) {
- if (GetDefaultOutInfo(compute_graph, output_nodes_info) != SUCCESS) {
- REPORT_CALL_ERROR("E19999", "GetDefaultOutInfo failed for graph:%s", compute_graph->GetName().c_str());
- GELOGE(domi::FAILED, "[Invoke][GetDefaultOutInfo] failed, graph:%s.", compute_graph->GetName().c_str());
- return domi::FAILED;
- }
- }
- CreateOutputNodesInfo(output_nodes_info, output_nodes_name);
- compute_graph->SetGraphOutNodesInfo(output_nodes_info);
- ge::GetParserContext().net_out_nodes = output_nodes_name;
- GELOGI("Set graph %s output node success.", compute_graph->GetName().c_str());
- return domi::SUCCESS;
- }
-
- domi::Status AclGrphParseUtil::CheckOptions(const std::map<AscendString, AscendString> &parser_params) {
- for (auto &ele : parser_params) {
- const char *key_ascend = ele.first.GetString();
- if (key_ascend == nullptr) {
- ErrorManager::GetInstance().ATCReportErrMessage("E10016", {"parameter", "opname"},
- {"parser_params", "null AscendString"});
- GELOGE(PARAM_INVALID, "[Check][Param] Input options key is null, Please check!");
- return PARAM_INVALID;
- }
-
- string key_str = key_ascend;
- auto it = ge::ir_option::ir_parser_suppported_options.find(key_str);
- if (it == ge::ir_option::ir_parser_suppported_options.end()) {
- ErrorManager::GetInstance().ATCReportErrMessage("E10016", {"parameter", "opname"}, {"parser_params", key_str});
- GELOGE(PARAM_INVALID, "[Check][Param] Input options include unsupported option(%s).Please check!", key_ascend);
- return PARAM_INVALID;
- }
- }
- return SUCCESS;
- }
-
- domi::Status AclGrphParseUtil::ParseParamsBeforeGraph(const std::map<AscendString, AscendString> &parser_params,
- string &graph_name) {
- GELOGI("Parse graph user options start.");
- ge::GetParserContext().input_nodes_format_map.clear();
- ge::GetParserContext().output_formats.clear();
- ge::GetParserContext().user_input_dims.clear();
- ge::GetParserContext().input_dims.clear();
- ge::GetParserContext().op_conf_map.clear();
- ge::GetParserContext().user_out_nodes.clear();
- ge::GetParserContext().default_out_nodes.clear();
- ge::GetParserContext().out_nodes_map.clear();
- ge::GetParserContext().user_out_tensors.clear();
- ge::GetParserContext().net_out_nodes.clear();
- ge::GetParserContext().out_tensor_names.clear();
- ge::GetParserContext().data_tensor_names.clear();
-
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(CheckOptions(parser_params) != SUCCESS,
- return PARAM_INVALID, "[Check][Options] Parse paragrams invalid, graph:%s.",
- graph_name.c_str());
- // support paragrams: out_nodes, is_output_adjust_hw_layout, output, enable_scope_fusion_passes
- SetDefaultFormat();
-
- string out_nodes;
- GetAclParams(parser_params, ge::ir_option::OUT_NODES, out_nodes);
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(ParseAclOutputNodes(out_nodes) != SUCCESS,
- return PARAM_INVALID,
- "[Invoke][ParseAclOutputNodes] Parse out_nodes failed, graph:%s.", graph_name.c_str());
-
- string is_output_adjust_hw_layout;
- GetAclParams(parser_params, ge::ir_option::IS_OUTPUT_ADJUST_HW_LAYOUT, is_output_adjust_hw_layout);
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(ParseAclOutputFp16NodesFormat(is_output_adjust_hw_layout) != SUCCESS,
- return PARAM_INVALID,
- "[Invoke][ParseAclOutputFp16NodesFormat] Parse is_output_adjust_hw_layout failed, "
- "graph:%s.", graph_name.c_str());
-
- string tmp_name;
- GetAclParams(parser_params, ge::ir_option::OUTPUT, tmp_name);
- graph_name = tmp_name.empty() ? (kGraphDefaultName + "_" + ge::parser::CurrentTimeInStr()) : tmp_name;
-
- string enable_scope_fusion_passes;
- GetAclParams(parser_params, ge::ir_option::ENABLE_SCOPE_FUSION_PASSES, enable_scope_fusion_passes);
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(ParseAclEnableScope(enable_scope_fusion_passes) != SUCCESS,
- return PARAM_INVALID,
- "[Invoke][ParseAclEnableScope] Parse enable_scope_fusion_passes failed, graph:%s.",
- graph_name.c_str());
-
- return SUCCESS;
- }
-
- domi::Status AclGrphParseUtil::ParseParamsAfterGraph(ge::Graph &graph,
- const std::map<AscendString, AscendString> &parser_params) {
- // support paragrams: input_fp16_nodes, is_input_adjust_hw_layout,
- ComputeGraphPtr compute_graph = GraphUtils::GetComputeGraph(graph);
- GE_CHECK_NOTNULL(compute_graph);
-
- string input_fp16_nodes;
- GetAclParams(parser_params, ge::ir_option::INPUT_FP16_NODES, input_fp16_nodes);
-
- string is_input_adjust_hw_layout;
- GetAclParams(parser_params, ge::ir_option::IS_INPUT_ADJUST_HW_LAYOUT, is_input_adjust_hw_layout);
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(
- ParseAclInputFp16Nodes(compute_graph, input_fp16_nodes, is_input_adjust_hw_layout) != SUCCESS,
- return PARAM_INVALID, "[Invoke][ParseAclInputFp16Nodes] Parse input_fp16_nodes failed, graph:%s",
- compute_graph->GetName().c_str());
-
- return SUCCESS;
- }
-
- namespace parser {
- FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY std::string RealPath(const char *path) {
- if (path == nullptr) {
- GELOGE(ge::FAILED, "path pointer is NULL.");
- return "";
- }
- if (strlen(path) >= PATH_MAX) {
- ErrorManager::GetInstance().ATCReportErrMessage("E19002", {"filepath", "size"}, {path, std::to_string(PATH_MAX)});
- GELOGE(ge::FAILED, "[Check][Param] Path[%s] len is too long, it must be less than %d", path, PATH_MAX);
- return "";
- }
- // Nullptr is returned when the path does not exist or there is no permission
- // Return absolute path when path is accessible
- std::string res;
- char resolved_path[PATH_MAX] = {0};
- if (realpath(path, resolved_path) != nullptr) {
- res = resolved_path;
- }
-
- return res;
- }
-
- // Get file length
- FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY long GetFileLength(const std::string &input_file) {
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(input_file.empty(),
- REPORT_INNER_ERROR("E19999", "input_file path is null, check invalid.");
- return -1, "[Check][Param] input_file path is null.");
-
- std::string real_path = RealPath(input_file.c_str());
-
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(real_path.empty(),
- REPORT_INPUT_ERROR("E19000", std::vector<std::string>({"path", "errmsg"}),
- std::vector<std::string>({real_path, strerror(errno)}));
- return -1, "[Get][Path] input_file path '%s' not valid", input_file.c_str());
- unsigned long long file_length = 0;
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(mmGetFileSize(input_file.c_str(), &file_length) != EN_OK,
- ErrorManager::GetInstance().ATCReportErrMessage("E19001", {"file", "errmsg"},
- {input_file, strerror(errno)});
- return -1, "[Open][File] [%s] failed. %s", input_file.c_str(), strerror(errno));
-
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG((file_length == 0 || file_length > kMaxFileSizeLimit),
- REPORT_INPUT_ERROR(
- "E19015", std::vector<std::string>({"file", "size", "maxsize"}),
- std::vector<std::string>({input_file, std::to_string(file_length),
- std::to_string(kMaxFileSizeLimit)}));
- return -1, "[Check][Param] File[%s] size %lld is out of range(0,%d).",
- input_file.c_str(), file_length, kMaxFileSizeLimit);
- return static_cast<long>(file_length);
- }
-
- FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY uint64_t GetCurrentTimestamp() {
- struct timeval tv{};
- int ret = gettimeofday(&tv, nullptr);
- GE_LOGE_IF(ret != 0, "[Func][GetTimeOfDay] may failed: ret=%d", ret);
- auto total_use_time = tv.tv_usec + tv.tv_sec * 1000000; // 1000000: seconds to microseconds
- return static_cast<uint64_t>(total_use_time);
- }
-
- static bool ReadProtoFromCodedInputStream(CodedInputStream &coded_stream, Message *proto) {
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(proto == nullptr,
- REPORT_INNER_ERROR("E19999", "param proto is nullptr, check invalid");
- return false, "[Check][Param] incorrect parameter. nullptr == proto");
-
- coded_stream.SetTotalBytesLimit(kProtoReadBytesLimit);
- return proto->ParseFromCodedStream(&coded_stream);
- }
-
- /** @ingroup domi_common
- * @brief Read all data from binary file
- * @param [in] file_name File path
- * @param [out] buffer The address of the output memory, which needs to be released by the caller
- * @param [out] length Output memory size
- * @return false fail
- * @return true success
- */
- FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY bool ReadBytesFromBinaryFile(const char *file_name, char **buffer,
- int &length) {
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG((file_name == nullptr),
- REPORT_INNER_ERROR("E19999", "param file_name is nullptr, check invalid");
- return false, "[Check][Param] incorrect parameter. file is nullptr");
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG((buffer == nullptr),
- REPORT_INNER_ERROR("E19999", "param buffer is nullptr, check invalid");
- return false, "[Check][Param] incorrect parameter. buffer is nullptr");
-
- std::string real_path = RealPath(file_name);
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(real_path.empty(),
- REPORT_INNER_ERROR("E19999", "file path '%s' not valid, realpath failed", file_name);
- return false, "[Check][Param]file path '%s' not valid, realpath failed", file_name);
-
- std::ifstream file(real_path.c_str(), std::ios::binary | std::ios::ate);
- if (!file.is_open()) {
- REPORT_INNER_ERROR("E19999", "read file %s failed", file_name);
- GELOGE(ge::FAILED, "[Read][File] %s failed.", file_name);
- return false;
- }
-
- length = static_cast<int>(file.tellg());
-
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG((length <= 0), file.close(); REPORT_INNER_ERROR("E19999", "file length <= 0");
- return false, "[Check][Param] file length <= 0");
-
- file.seekg(0, std::ios::beg);
-
- *buffer = new(std::nothrow) char[length]();
- GE_CHK_BOOL_TRUE_EXEC_RET_STATUS(*buffer == nullptr, false, file.close();
- REPORT_CALL_ERROR("E19999", "new an object failed."),
- "[Create][Buffer] new an object failed.");
-
- file.read(*buffer, length);
- file.close();
- return true;
- }
-
- FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY bool ReadProtoFromBinaryFile(const char *file, Message *proto) {
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG((file == nullptr || proto == nullptr),
- REPORT_INNER_ERROR("E19999", "param file or proto is nullptr, check invalid");
- return false, "[Check][Param] Input parameter file or proto is nullptr!");
-
- std::string real_path = RealPath(file);
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(real_path.empty(),
- REPORT_INNER_ERROR("E19999", "file path '%s' not valid, realpath failed", file);
- return false, "[Check][Param]pb file path '%s' not valid, realpath failed", file);
-
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(GetFileLength(real_path) == -1, return false, "[Get][FileLength]file size not valid.");
-
- std::ifstream fs(real_path, std::ifstream::in | std::ifstream::binary);
- if (!fs.is_open()) {
- ErrorManager::GetInstance().ATCReportErrMessage("E19001", {"file", "errmsg"}, {file, "ifstream is_open failed"});
- GELOGE(ge::FAILED, "[Open][RealPath][%s] failed.", file);
- return false;
- }
-
- google::protobuf::io::IstreamInputStream istream(&fs);
- google::protobuf::io::CodedInputStream coded_stream(&istream);
-
- bool ret = ReadProtoFromCodedInputStream(coded_stream, proto);
-
- fs.close();
-
- if (!ret) {
- ErrorManager::GetInstance().ATCReportErrMessage("E19005", {"file"}, {file});
- GELOGE(ge::FAILED, "[Read][Proto] Parse file[%s] failed.", file);
- return ret;
- }
-
- return ret;
- }
-
- FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY bool ReadProtoFromArray(const void *data, int size, Message *proto) {
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG((proto == nullptr || data == nullptr || size == 0),
- REPORT_INNER_ERROR("E19999", "param proto or data is nullptr "
- "or size is 0, check invalid"); return false,
- "[Check][Param]incorrect parameter. proto is nullptr || data is nullptr || size is 0");
-
- google::protobuf::io::CodedInputStream coded_stream(reinterpret_cast<uint8_t *>(const_cast<void *>(data)), size);
- return ReadProtoFromCodedInputStream(coded_stream, proto);
- }
-
- FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY bool ReadProtoFromText(const char *file,
- google::protobuf::Message *message) {
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG((file == nullptr || message == nullptr),
- REPORT_INNER_ERROR("E19999", "param file or message is nullptr, check invalid");
- return false,
- "[Check][Param]incorrect parameter. nullptr == file || nullptr == message");
-
- std::string real_path = RealPath(file);
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(real_path.empty(),
- ErrorManager::GetInstance().ATCReportErrMessage("E19000", {"path", "errmsg"},
- {file, strerror(errno)});
- return false, "[Check][Param]Path[%s]'s realpath is empty, errmsg[%s]", file,
- strerror(errno));
-
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(GetFileLength(real_path) == -1, return false, "[Check][Param] file size not valid.");
-
- std::ifstream fs(real_path.c_str(), std::ifstream::in);
-
- if (!fs.is_open()) {
- REPORT_INNER_ERROR("E19999", "open file:%s failed", real_path.c_str());
- GELOGE(ge::FAILED, "[Open][ProtoFile] failed, real path is '%s' when orginal file path is '%s'.",
- real_path.c_str(), file);
- return false;
- }
-
- google::protobuf::io::IstreamInputStream input(&fs);
- bool ret = google::protobuf::TextFormat::Parse(&input, message);
- GE_IF_BOOL_EXEC(!ret, ErrorManager::GetInstance().ATCReportErrMessage("E19018", {"protofile"}, {file});
- GELOGE(ret, "[Parse][File] [%s] through [google::protobuf::TextFormat::Parse] failed, "
- "please check whether the file is a valid protobuf format file.", file));
- fs.close();
-
- return ret;
- }
-
- FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY bool ReadProtoFromMem(const char *data, int size,
- google::protobuf::Message *message) {
- GE_CHK_BOOL_TRUE_EXEC_WITH_LOG((data == nullptr || message == nullptr),
- REPORT_INNER_ERROR("E19999", "param data or message is nullptr,check invalid");
- return false,
- "[Check][Param] incorrect parameter. data is nullptr || message is nullptr");
- std::string str(data, static_cast<size_t>(size));
- std::istringstream fs(str);
-
- google::protobuf::io::IstreamInputStream input(&fs);
- bool ret = google::protobuf::TextFormat::Parse(&input, message);
- GE_IF_BOOL_EXEC(!ret, REPORT_CALL_ERROR("E19999", "parse failed, please check your text file.");
- GELOGE(ret, "[Call][Parse] ret fail, please check your text file."));
-
- return ret;
- }
-
- ///
- /// @brief get the Original Type of FrameworkOp
- /// @param [in] node
- /// @param [out] type
- /// @return Status
- ///
- Status GetOriginalType(const ge::NodePtr &node, string &type) {
- GE_CHECK_NOTNULL(node);
- type = node->GetType();
- GE_IF_BOOL_EXEC(type != FRAMEWORKOP, return SUCCESS);
- GE_CHECK_NOTNULL(node->GetOpDesc());
- bool ret = ge::AttrUtils::GetStr(node->GetOpDesc(), ATTR_NAME_FRAMEWORK_ORIGINAL_TYPE, type);
- if (!ret) {
- REPORT_CALL_ERROR("E19999", "Get FrameWorkOp original type [%s] from node:%s failed.",
- type.c_str(), node->GetName().c_str());
- GELOGE(INTERNAL_ERROR, "[Invoke][GetStr] Get FrameWorkOp original type [%s] from node:%s failed",
- type.c_str(), node->GetName().c_str());
- return INTERNAL_ERROR;
- }
- GELOGD("Get FrameWorkOp original type [%s]", type.c_str());
- return SUCCESS;
- }
-
- FMK_FUNC_HOST_VISIBILITY bool ValidateStr(const std::string &str, const std::string &mode) {
- char ebuff[kMaxBuffSize];
- regex_t reg;
- int cflags = REG_EXTENDED | REG_NOSUB;
- int ret = regcomp(®, mode.c_str(), cflags);
- if (ret) {
- regerror(ret, ®, ebuff, kMaxBuffSize);
- GELOGW("regcomp failed, reason: %s", ebuff);
- regfree(®);
- return true;
- }
-
- ret = regexec(®, str.c_str(), 0, nullptr, 0);
- if (ret) {
- regerror(ret, ®, ebuff, kMaxBuffSize);
- GELOGE(ge::PARAM_INVALID, "[Invoke][RegExec] failed, reason: %s", ebuff);
- regfree(®);
- return false;
- }
-
- regfree(®);
- return true;
- }
-
- FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY std::string CurrentTimeInStr() {
- std::time_t now = std::time(nullptr);
- std::tm *ptm = std::localtime(&now);
- if (ptm == nullptr) {
- GELOGE(ge::FAILED, "[Invoke][LocalTime] failed.");
- return "";
- }
-
- const int kTimeBufferLen = 32;
- char buffer[kTimeBufferLen + 1] = {0};
- // format: 20171122042550
- std::strftime(buffer, kTimeBufferLen, "%Y%m%d%H%M%S", ptm);
- return std::string(buffer);
- }
- } // namespace parser
- } // namespace ge
|