From ee6dfdb21dddca9bdab09e2c66c8f35f2e55405a Mon Sep 17 00:00:00 2001 From: zhaoyingzhuo Date: Tue, 27 Sep 2022 17:16:00 +0800 Subject: [PATCH] support config file in ascend --- .jenkins/check/config/filter_cpplint.txt | 1 + .../cxx_api/model/acl/acl_model_options.cc | 3 + .../src/extendrt/convert/runtime_convert.cc | 208 ++++++++++++++++-- .../src/extendrt/convert/runtime_convert.h | 5 +- .../src/extendrt/cxx_api/model/model_impl.cc | 7 +- .../adapter/acl/src/acl_pass_impl.cc | 26 ++- mindspore/lite/tools/converter/converter.cc | 11 + 7 files changed, 220 insertions(+), 41 deletions(-) diff --git a/.jenkins/check/config/filter_cpplint.txt b/.jenkins/check/config/filter_cpplint.txt index 476ef5fc95a..92e834b5899 100644 --- a/.jenkins/check/config/filter_cpplint.txt +++ b/.jenkins/check/config/filter_cpplint.txt @@ -80,3 +80,4 @@ "mindspore/mindspore/core/mindrt/include/async/defer.h" "runtime/explicit" "mindspore/mindspore/lite/src/litert/delegate/nnapi/nnapi_implementation.h" "build/include_order" "mindspore/mindspore/lite/src/litert/delegate/nnapi/nnapi_implementation.cc" "build/include_order" +"mindspore/mindspore/lite/src/extendrt/cxx_api/model/model_impl.cc" "whitespace/parens" diff --git a/mindspore/ccsrc/cxx_api/model/acl/acl_model_options.cc b/mindspore/ccsrc/cxx_api/model/acl/acl_model_options.cc index 0de0280817e..407ae418576 100644 --- a/mindspore/ccsrc/cxx_api/model/acl/acl_model_options.cc +++ b/mindspore/ccsrc/cxx_api/model/acl/acl_model_options.cc @@ -57,6 +57,9 @@ AclModelOptions::AclModelOptions(const std::shared_ptr &context) { fusion_switch_cfg_path_ = ascend_info->GetFusionSwitchConfigPath(); device_id_ = ascend_info->GetDeviceID(); buffer_optimize_mode_ = ascend_info->GetBufferOptimizeMode(); + if (!ascend_info->GetInputShape().empty()) { + input_shape_ = ascend_info->GetInputShape(); + } const char *soc_name = aclrtGetSocName(); if (soc_name == nullptr) { MS_LOG(WARNING) << "Get soc version failed."; diff --git a/mindspore/lite/src/extendrt/convert/runtime_convert.cc b/mindspore/lite/src/extendrt/convert/runtime_convert.cc index a8c508a0394..b4693d98918 100644 --- a/mindspore/lite/src/extendrt/convert/runtime_convert.cc +++ b/mindspore/lite/src/extendrt/convert/runtime_convert.cc @@ -14,13 +14,168 @@ * limitations under the License. */ #include +#include +#include #include "src/extendrt/convert/runtime_convert.h" +#include "src/common/config_infos.h" #include "tools/common/string_util.h" #include "tools/converter/converter.h" #include "tools/converter/cxx_api/converter_para.h" +const int kBatchDim = 0; +const int kDynImgSize = 0; +const int kDynBatchSize = 1; +int CheckBatchStringSupport(const std::vector &batch_str_vec) { + if (batch_str_vec.empty()) { + return -1; + } + std::string only_batch = batch_str_vec[0]; + for (size_t i = 1; i < batch_str_vec.size(); ++i) { + if (batch_str_vec[i] != only_batch) { + return -1; + } + } + return 0; +} + +const size_t kIndex0 = 0; +const size_t kIndex1 = 1; +const size_t kIndex2 = 2; +const size_t kIndex3 = 3; +const int64_t kdynDim = -1; +int DynBatchOrDynImage(const ShapeVector &shape) { + if (shape.size() != 4) { + MS_LOG(ERROR) << "Do not support input shape which is not equal to 4 (N C H W)"; + return -1; + } + if (shape[kIndex0] != -1 && ((shape[kIndex1] == kdynDim && shape[kIndex2] == kdynDim && shape[kIndex3] != kdynDim) || + (shape[kIndex1] == kdynDim && shape[kIndex2] != kdynDim && shape[kIndex3] == kdynDim) || + (shape[kIndex1] != kdynDim && shape[kIndex2] == kdynDim && shape[kIndex3] == kdynDim))) { + return kDynImgSize; + } + if (shape[kIndex0] == kdynDim && shape[kIndex1] != kdynDim && shape[kIndex2] != kdynDim && + shape[kIndex3] != kdynDim) { + return kDynBatchSize; + } + return -1; +} + +std::string CombineDynImgString(const struct mindspore::ProfileConfigs &profile) { + ShapeVector shape = profile.input_infos[kIndex0].input_shape; + std::string ret = ""; + size_t first_dim = kIndex0, second_dim = kIndex0; + if (shape[kIndex1] == kdynDim && shape[kIndex2] == kdynDim) { + first_dim = kIndex1; + second_dim = kIndex2; + } else if (shape[kIndex1] == kdynDim && shape[kIndex3] == kdynDim) { + first_dim = kIndex1; + second_dim = kIndex3; + } else if (shape[kIndex2] == kdynDim && shape[kIndex3] == kdynDim) { + first_dim = kIndex2; + second_dim = kIndex3; + } + int64_t min_first = profile.profiles[kIndex0].inputs[kIndex0].min_dims[first_dim]; + int64_t max_first = profile.profiles[kIndex0].inputs[kIndex0].max_dims[first_dim]; + int64_t min_second = profile.profiles[kIndex0].inputs[kIndex0].min_dims[second_dim]; + int64_t max_second = profile.profiles[kIndex0].inputs[kIndex0].max_dims[second_dim]; + for (int64_t i = min_first; i <= max_first; ++i) { + for (int64_t j = min_second; j <= max_second; ++j) { + ret += std::to_string(i) + "," + std::to_string(j) + ";"; + } + } + ret = ret.substr(0, ret.size() - 1); // discard the final ";" + return ret; +} + +std::string RemoveInputShapeBrackets(const std::string &input_shape_str) { + std::string ret = ""; + for (size_t i = 0; i < input_shape_str.size(); ++i) { + if (input_shape_str[i] == '[' || input_shape_str[i] == ']') { + continue; + } + ret += input_shape_str[i]; + } + return ret; +} + +std::string FindInAscendMap(const std::string &key, const std::map &ascend_map) { + auto it = ascend_map.find(key); + if (it != ascend_map.end()) { + return it->second; + } + return ""; +} + +void SetParamByConfigfile(const std::shared_ptr ¶m, + const std::map &ascend_map) { + param->aclModelOptionCfgParam.input_format = FindInAscendMap("input_format", ascend_map); + param->aclModelOptionCfgParam.precision_mode = FindInAscendMap("precision_mode", ascend_map); + param->aclModelOptionCfgParam.op_select_impl_mode = FindInAscendMap("op_select_impl_mode", ascend_map); + param->aclModelOptionCfgParam.fusion_switch_config_file_path = + FindInAscendMap("fusion_switch_config_file_path", ascend_map); + param->aclModelOptionCfgParam.buffer_optimize = FindInAscendMap("buffer_optimize", ascend_map); + param->aclModelOptionCfgParam.insert_op_config_file_path = FindInAscendMap("insert_op_config_file_path", ascend_map); + param->aclModelOptionCfgParam.om_file_path = FindInAscendMap("om_file_path", ascend_map); + + auto it = ascend_map.find("input_shape"); + if (it != ascend_map.end()) { + param->aclModelOptionCfgParam.input_shape = RemoveInputShapeBrackets(it->second); + } + + it = ascend_map.find("device_id"); + if (it != ascend_map.end()) { + int32_t val; + if (mindspore::lite::ConvertIntNum(it->second, &val)) { + param->aclModelOptionCfgParam.device_id = val; + } else { + MS_LOG(ERROR) << "Convert device id failed"; + } + } + + it = ascend_map.find("output_type"); + if (it != ascend_map.end()) { + int32_t val; + if (mindspore::lite::ConvertIntNum(it->second, &val)) { + param->aclModelOptionCfgParam.output_type = static_cast(val); + } else { + MS_LOG(ERROR) << "Convert output_type failed"; + } + } + + it = ascend_map.find("dynamic_dims"); + if (it != ascend_map.end()) { + std::vector batch_size_string = mindspore::lite::SplitStringToVector(it->second, ';'); + if (CheckBatchStringSupport(batch_size_string) != 0) { + MS_LOG(ERROR) << "Do not support different dynamic_dims!"; + return; + } + struct mindspore::ProfileConfigs tmp_profile; + if (!mindspore::ProfileParser::Parse(ascend_map, false, &tmp_profile)) { + MS_LOG(ERROR) << "Parse dynamic_dims failed"; + } + ShapeVector input_shape_vec = tmp_profile.input_infos[0].input_shape; + switch (DynBatchOrDynImage(input_shape_vec)) { + case kDynImgSize: + param->aclModelOptionCfgParam.dynamic_image_size = CombineDynImgString(tmp_profile); + break; + case kDynBatchSize: + for (size_t i = 0; i < tmp_profile.profiles.size(); ++i) { // dynamic batch size + int64_t min_batch = tmp_profile.profiles[i].inputs[0].min_dims[kBatchDim]; + int64_t max_batch = tmp_profile.profiles[i].inputs[0].max_dims[kBatchDim]; + for (int64_t batch = min_batch; batch <= max_batch; ++batch) { + param->aclModelOptionCfgParam.dynamic_batch_size.push_back(batch); + } + } + break; + default: + MS_LOG(ERROR) << "Do not support input shape which is not equal to 4 (N C H W)"; + } + } +} + mindspore::api::FuncGraphPtr RuntimeConvert(const char *model_buf, const size_t &buf_size, - const std::shared_ptr &context) { + const std::shared_ptr &context, + const ConfigInfos &config_info) { auto param = std::make_shared(); if (param == nullptr) { MS_LOG(ERROR) << "New ConverterPara failed"; @@ -38,32 +193,37 @@ mindspore::api::FuncGraphPtr RuntimeConvert(const char *model_buf, const size_t auto device_list = context->MutableDeviceInfo(); for (auto &device : device_list) { if (device->GetDeviceType() == mindspore::kAscend) { - auto ascend_info = device->Cast(); - std::string dynamic_batch_size = ascend_info->GetDynamicBatchSize(); - if (!dynamic_batch_size.empty()) { - std::vector batch_size_string = mindspore::lite::SplitStringToVector(dynamic_batch_size, ','); - for (const auto &item : batch_size_string) { - int32_t val; - if (mindspore::lite::ConvertIntNum(item, &val)) { - size_t tmp_val = static_cast(val); - param->aclModelOptionCfgParam.dynamic_batch_size.push_back(tmp_val); - } - } - } param->aclModelOptionCfgParam.offline = false; - param->aclModelOptionCfgParam.device_id = ascend_info->GetDeviceID(); - param->aclModelOptionCfgParam.output_type = ascend_info->GetOutputType(); - param->aclModelOptionCfgParam.input_shape_map = ascend_info->GetInputShapeMap(); - param->aclModelOptionCfgParam.input_format = ascend_info->GetInputFormat(); - param->aclModelOptionCfgParam.input_shape = ascend_info->GetInputShape(); - param->aclModelOptionCfgParam.precision_mode = ascend_info->GetPrecisionMode(); - param->aclModelOptionCfgParam.op_select_impl_mode = ascend_info->GetOpSelectImplMode(); - param->aclModelOptionCfgParam.fusion_switch_config_file_path = ascend_info->GetFusionSwitchConfigPath(); - param->aclModelOptionCfgParam.buffer_optimize = ascend_info->GetBufferOptimizeMode(); - param->aclModelOptionCfgParam.insert_op_config_file_path = ascend_info->GetInsertOpConfigPath(); - param->aclModelOptionCfgParam.dynamic_image_size = ascend_info->GetDynamicImageSize(); param->device = "Ascend"; param->no_fusion = false; + if (config_info.find("ascend_context") != config_info.end()) { + std::map ascend_map = config_info.at("ascend_context"); + SetParamByConfigfile(param, ascend_map); + } else { + auto ascend_info = device->Cast(); + std::string dynamic_batch_size = ascend_info->GetDynamicBatchSize(); + if (!dynamic_batch_size.empty()) { + std::vector batch_size_string = mindspore::lite::SplitStringToVector(dynamic_batch_size, ','); + for (const auto &item : batch_size_string) { + int32_t val; + if (mindspore::lite::ConvertIntNum(item, &val)) { + size_t tmp_val = static_cast(val); + param->aclModelOptionCfgParam.dynamic_batch_size.push_back(tmp_val); + } + } + } + param->aclModelOptionCfgParam.device_id = ascend_info->GetDeviceID(); + param->aclModelOptionCfgParam.output_type = ascend_info->GetOutputType(); + param->aclModelOptionCfgParam.input_shape_map = ascend_info->GetInputShapeMap(); + param->aclModelOptionCfgParam.input_format = ascend_info->GetInputFormat(); + param->aclModelOptionCfgParam.input_shape = ascend_info->GetInputShape(); + param->aclModelOptionCfgParam.precision_mode = ascend_info->GetPrecisionMode(); + param->aclModelOptionCfgParam.op_select_impl_mode = ascend_info->GetOpSelectImplMode(); + param->aclModelOptionCfgParam.fusion_switch_config_file_path = ascend_info->GetFusionSwitchConfigPath(); + param->aclModelOptionCfgParam.buffer_optimize = ascend_info->GetBufferOptimizeMode(); + param->aclModelOptionCfgParam.insert_op_config_file_path = ascend_info->GetInsertOpConfigPath(); + param->aclModelOptionCfgParam.dynamic_image_size = ascend_info->GetDynamicImageSize(); + } } else { continue; } diff --git a/mindspore/lite/src/extendrt/convert/runtime_convert.h b/mindspore/lite/src/extendrt/convert/runtime_convert.h index be5ec4d806b..de6db45bd03 100644 --- a/mindspore/lite/src/extendrt/convert/runtime_convert.h +++ b/mindspore/lite/src/extendrt/convert/runtime_convert.h @@ -19,14 +19,17 @@ #include #include #include +#include #include "include/api/context.h" #include "mindapi/ir/func_graph.h" #ifdef __cplusplus extern "C" { #endif +using ConfigInfos = std::map>; mindspore::api::FuncGraphPtr RuntimeConvert(const char *model_buf, const size_t &buf_size, - const std::shared_ptr &context); + const std::shared_ptr &context, + const ConfigInfos &config_info); #ifdef __cplusplus } #endif diff --git a/mindspore/lite/src/extendrt/cxx_api/model/model_impl.cc b/mindspore/lite/src/extendrt/cxx_api/model/model_impl.cc index c747b926578..f3f26356ca4 100644 --- a/mindspore/lite/src/extendrt/cxx_api/model/model_impl.cc +++ b/mindspore/lite/src/extendrt/cxx_api/model/model_impl.cc @@ -99,11 +99,10 @@ Status ModelImpl::CompileGraphOnline(const void *model_data, size_t data_size, MS_LOG(WARNING) << "DLSoOpen RuntimeConvert failed, so path: " << plugin_path; return kLiteError; } - auto convert = - reinterpret_cast &)>( - function); + auto convert = reinterpret_cast &, const ConfigInfos &)>(function); if (convert != nullptr) { - auto api_graph = convert(static_cast(model_data), data_size, model_context); + auto api_graph = convert(static_cast(model_data), data_size, model_context, config_info_); auto impl = api_graph->impl(); auto inner_graph = std::dynamic_pointer_cast(impl); return session_->CompileGraph(inner_graph); diff --git a/mindspore/lite/tools/converter/adapter/acl/src/acl_pass_impl.cc b/mindspore/lite/tools/converter/adapter/acl/src/acl_pass_impl.cc index e94855a574e..b5c06438ecb 100644 --- a/mindspore/lite/tools/converter/adapter/acl/src/acl_pass_impl.cc +++ b/mindspore/lite/tools/converter/adapter/acl/src/acl_pass_impl.cc @@ -335,20 +335,22 @@ STATUS AclPassImpl::SetAclModelOptions(const FuncGraphPtr &func_graph) { options_ = std::make_shared(model_context); CHECK_NULL_RETURN(options_); auto inputs = func_graph->get_inputs(); - std::vector input_names; - for (auto node : inputs) { - CHECK_NULL_RETURN(node); - auto para = node->cast(); - CHECK_NULL_RETURN(para); - std::string name = para->name(); - for (auto pos = name.find(':'); pos != std::string::npos; pos = name.find(':')) { - name = name.substr(0, pos) + "_" + name.substr(pos + 1); - MS_LOG(INFO) << "Input name: " << name; + if (user_options_cfg_.input_shape.empty()) { + std::vector input_names; + for (auto node : inputs) { + CHECK_NULL_RETURN(node); + auto para = node->cast(); + CHECK_NULL_RETURN(para); + std::string name = para->name(); + for (auto pos = name.find(':'); pos != std::string::npos; pos = name.find(':')) { + name = name.substr(0, pos) + "_" + name.substr(pos + 1); + MS_LOG(INFO) << "Input name: " << name; + } + para->set_name(name); + input_names.push_back(name); } - para->set_name(name); - input_names.push_back(name); + options_->RenameInput(input_names); } - options_->RenameInput(input_names); options_->SetOmFilePath(user_options_cfg_.om_file_path); MS_LOG(INFO) << "Set acl model options success."; return lite::RET_OK; diff --git a/mindspore/lite/tools/converter/converter.cc b/mindspore/lite/tools/converter/converter.cc index 9608f25011d..5e76d8e13f0 100644 --- a/mindspore/lite/tools/converter/converter.cc +++ b/mindspore/lite/tools/converter/converter.cc @@ -636,6 +636,17 @@ int ConverterImpl::SaveOutputNames(const FuncGraphPtr &graph) { update_output_names.emplace_back(name); } } + + for (auto &input : graph->get_inputs()) { + auto parameter = input->cast(); + if (!parameter->has_default()) { + auto abstract = parameter->abstract(); + MS_CHECK_TRUE_MSG(abstract != nullptr, RET_ERROR, "Abstract is nullptr."); + if (!abstract->name().empty()) { + parameter->set_name(abstract->name()); + } + } + } ConverterInnerContext::GetInstance()->SetGraphOutputTensorNames(update_output_names); return RET_OK; }