From d5278b4c1ea6a05977adda124c52abba6d420115 Mon Sep 17 00:00:00 2001 From: xuanyue Date: Thu, 13 Nov 2025 17:05:34 +0800 Subject: [PATCH] [Refactor]adjust and optimize GE scheduler --- mindspore-lite/src/common/CMakeLists.txt | 1 + mindspore-lite/src/common/common.cc | 23 ++ mindspore-lite/src/common/common.h | 3 +- .../src/extendrt/convert/runtime_convert.cc | 2 +- .../cxx_api/model/model_group_impl.cc | 2 +- .../delegate/ascend_ge/ge_device_context.cc | 2 +- .../delegate/ascend_ge/ge_graph_compiler.cc | 151 ++++++++++ .../delegate/ascend_ge/ge_graph_compiler.h | 50 ++++ .../ascend_ge/ge_graph_executor_v1.cc | 282 ++++++++++++++++++ .../delegate/ascend_ge/ge_graph_executor_v1.h | 79 +++++ .../ascend_ge/ge_options_container.cc | 179 +++++++++++ .../delegate/ascend_ge/ge_options_container.h | 45 +++ mindspore-lite/src/extendrt/infer_session.cc | 10 +- .../src/extendrt/session/delegate_session.cc | 2 +- 14 files changed, 818 insertions(+), 13 deletions(-) create mode 100644 mindspore-lite/src/common/common.cc create mode 100644 mindspore-lite/src/extendrt/delegate/ascend_ge/ge_graph_compiler.cc create mode 100644 mindspore-lite/src/extendrt/delegate/ascend_ge/ge_graph_compiler.h create mode 100644 mindspore-lite/src/extendrt/delegate/ascend_ge/ge_graph_executor_v1.cc create mode 100644 mindspore-lite/src/extendrt/delegate/ascend_ge/ge_graph_executor_v1.h create mode 100644 mindspore-lite/src/extendrt/delegate/ascend_ge/ge_options_container.cc create mode 100644 mindspore-lite/src/extendrt/delegate/ascend_ge/ge_options_container.h diff --git a/mindspore-lite/src/common/CMakeLists.txt b/mindspore-lite/src/common/CMakeLists.txt index 41bbc654..8cc25f9a 100644 --- a/mindspore-lite/src/common/CMakeLists.txt +++ b/mindspore-lite/src/common/CMakeLists.txt @@ -3,6 +3,7 @@ set(LITE_SRC_TRAIN_COMMON_MID_SRC "") set(LITE_SRC_COMMON_MID_SRC ${LITE_SRC_COMMON_MID_SRC} + ${CMAKE_CURRENT_SOURCE_DIR}/common.cc ${CMAKE_CURRENT_SOURCE_DIR}/context_util.cc ${CMAKE_CURRENT_SOURCE_DIR}/file_utils.cc ${CMAKE_CURRENT_SOURCE_DIR}/mmap_utils.cc diff --git a/mindspore-lite/src/common/common.cc b/mindspore-lite/src/common/common.cc new file mode 100644 index 00000000..ea4ffb20 --- /dev/null +++ b/mindspore-lite/src/common/common.cc @@ -0,0 +1,23 @@ +/** + * Copyright 2025 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 "src/common/common.h" + +namespace mindspore { +namespace lite { +bool IsGe(const std::string &provider) { return provider == "ge" || provider == "ge-v1"; } +} // namespace lite +} // namespace mindspore diff --git a/mindspore-lite/src/common/common.h b/mindspore-lite/src/common/common.h index 9c42cd7c..674fe441 100644 --- a/mindspore-lite/src/common/common.h +++ b/mindspore-lite/src/common/common.h @@ -1,5 +1,5 @@ /** - * Copyright 2020-2023 Huawei Technologies Co., Ltd + * Copyright 2020-2025 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. @@ -196,6 +196,7 @@ static const char *const kInnerGraphSplit = "inner_graph_split"; static const char *const kInnerInputNames = "inner_input_names"; static const char *const kInnerOutputNames = "inner_output_names"; +bool IsGe(const std::string &provider); } // namespace lite } // namespace mindspore #endif // MINDSPORE_LITE_SRC_COMMON_COMMON_H_ diff --git a/mindspore-lite/src/extendrt/convert/runtime_convert.cc b/mindspore-lite/src/extendrt/convert/runtime_convert.cc index f0ff1f55..54afa189 100644 --- a/mindspore-lite/src/extendrt/convert/runtime_convert.cc +++ b/mindspore-lite/src/extendrt/convert/runtime_convert.cc @@ -183,7 +183,7 @@ int RuntimeConvert(const mindspore::api::FuncGraphPtr &graph, const std::shared_ return RET_ERROR; } } - if (device->GetProvider() == mindspore::lite::kAscendProviderGe) { + if (mindspore::lite::IsGe(device->GetProvider())) { param->provider = mindspore::lite::kAscendProviderGe; continue; } diff --git a/mindspore-lite/src/extendrt/cxx_api/model/model_group_impl.cc b/mindspore-lite/src/extendrt/cxx_api/model/model_group_impl.cc index e6082156..807a6fce 100644 --- a/mindspore-lite/src/extendrt/cxx_api/model/model_group_impl.cc +++ b/mindspore-lite/src/extendrt/cxx_api/model/model_group_impl.cc @@ -89,7 +89,7 @@ Status ModelGroupImpl::AddModel(const std::vector> &m } Status ModelGroupImpl::CalMaxSizeOfWorkspace(ModelType model_type, const std::shared_ptr &ms_context) { - if (ms_context->MutableDeviceInfo().size() > 0 && ms_context->MutableDeviceInfo()[0]->GetProvider() == "ge") { + if (ms_context->MutableDeviceInfo().size() > 0 && lite::IsGe(ms_context->MutableDeviceInfo()[0]->GetProvider())) { MS_LOG(ERROR) << "Not Support GE model to ModelGroup::CalMaxSizeOfWorkspace!"; return kLiteError; } diff --git a/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_device_context.cc b/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_device_context.cc index d2929768..3c5d6a21 100644 --- a/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_device_context.cc +++ b/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_device_context.cc @@ -177,7 +177,7 @@ std::shared_ptr GeDeviceContext::GetGeAscendDeviceInfo(const s auto device_list = context->MutableDeviceInfo(); auto ascend_info_iter = std::find_if( device_list.begin(), device_list.end(), [&](std::shared_ptr &device_info) { - return (device_info && device_info->GetDeviceType() == kAscend && device_info->GetProvider() == "ge"); + return (device_info && device_info->GetDeviceType() == kAscend && lite::IsGe(device_info->GetProvider())); }); if (ascend_info_iter == device_list.end()) { MS_LOG(ERROR) << "AscendDeviceInfo is not set. If using distributed inference, make sure device_id " diff --git a/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_graph_compiler.cc b/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_graph_compiler.cc new file mode 100644 index 00000000..0ae7b2eb --- /dev/null +++ b/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_graph_compiler.cc @@ -0,0 +1,151 @@ +/** + * Copyright 2025 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 "extendrt/delegate/ascend_ge/ge_graph_compiler.h" +#include +#include "src/common/log_util.h" +#include "tools/common/graph_util.h" +#include "tools/optimizer/graph/remove_load_pass.h" +#include "tools/optimizer/graph/attr_to_args_pass.h" + +namespace mindspore { +namespace { +constexpr auto kDump = "dump"; +constexpr auto kDumpMode = "dump_mode"; +constexpr auto kProfiling = "profiler"; +backend::ge_backend::TensorOrderMap GetParams(const FuncGraphPtr &anf_graph) { + backend::ge_backend::TensorOrderMap res; + for (auto &anf_node : anf_graph->parameters()) { + MS_EXCEPTION_IF_NULL(anf_node); + auto para = anf_node->cast(); + MS_EXCEPTION_IF_NULL(para); + if (para->has_default()) { + auto value = para->default_param(); + MS_EXCEPTION_IF_NULL(value); + auto tensor = value->cast>(); + res.emplace(para->name(), tensor); + MS_LOG(INFO) << "Parameter " << para->name() << " has default value."; + } + } + return res; +} +} // namespace + +bool GeGraphCompiler::CompileGraph(const FuncGraphPtr &graph, GeSessionInfo *ge_session_info, + const GeOptionsContainer &ge_options_container) { + MS_CHECK_TRUE_MSG(graph != nullptr, false, "graph is NULL."); + MS_CHECK_TRUE_MSG(ge_session_info != nullptr, false, "ge_session_info is NULL."); + (void)setenv("GE_TRAIN", "0", 1); + if (ge_session_info->session_ == nullptr) { + MS_LOG(ERROR) << "ge_session hasn't been created."; + return false; + } + auto df_graph = ToGeGraph(graph, ge_session_info, ge_options_container.GeGraphOptions().at(kGeGraphKey)); + if (df_graph == nullptr) { + MS_LOG(ERROR) << "Convert FuncGraph to ge::graph failed."; + return false; + } + uint32_t graph_id = ge_session_info->graph_ids_.size(); + auto ge_status = ge_session_info->session_->AddGraph(graph_id, *(df_graph), ge_options_container.GeGraphOptions()); + if (ge_status != ge::GRAPH_SUCCESS) { + MS_LOG(ERROR) << "Call GE AddGraph Failed: " << ge::GEGetErrorMsg(); + return false; + } + ge_status = ge_session_info->session_->CompileGraph(graph_id); + if (ge_status != ge::GRAPH_SUCCESS) { + MS_LOG(ERROR) << "Call GE CompileGraph Failed: " << ge::GEGetErrorMsg(); + return false; + } + ge_session_info->graph_ids_.push_back(graph_id); + return true; +} + +backend::ge_backend::DfGraphPtr GeGraphCompiler::ToGeGraph(const FuncGraphPtr &graph, GeSessionInfo *ge_session_info, + const std::string &graph_key) { + MS_EXCEPTION_IF_NULL(graph); + lite::AdjustDuplicateNodeName(graph); + auto remove_load_pass = std::make_shared(); + remove_load_pass->Run(graph); + opt::UpdateManager(graph); + + // Convert mindir attributes to inputs because of dynamic_shape operator. + // For the transformed operators, the GE adapter only supports inputs but not attributes. + auto args_to_attr_pass = std::make_shared(); + if (args_to_attr_pass == nullptr) { + MS_LOG(ERROR) << "create AttrToArgsPass failed"; + return nullptr; + } + if (!args_to_attr_pass->Run(graph)) { + MS_LOG(ERROR) << "convert args to attr pass failed"; + return nullptr; + } + + // Convert to ge::graph + backend::ge_backend::TensorOrderMap params_vals = GetParams(graph); + auto converter = + std::make_shared(graph, "", backend::ge_backend::RefModeFlag::kRefModeNone); + backend::ge_backend::BuildGraph(graph_key, converter, params_vals); + if (backend::ge_backend::ErrCode(converter) != 0) { + backend::ge_backend::ClearGraph(); + MS_LOG(ERROR) << "Convert df graph failed"; + return nullptr; + } + if (!ProcessGeInitGraph(ge_session_info, backend::ge_backend::GetInitGraph(converter), params_vals, + converter->GetInitDataNames())) { + MS_LOG(ERROR) << "Process GE's Init-Graph failed."; + return nullptr; + } + auto df_graph = backend::ge_backend::GetComputeGraph(converter); + return df_graph; +} + +bool GeGraphCompiler::ProcessGeInitGraph(GeSessionInfo *ge_session_info, backend::ge_backend::DfGraphPtr init_graph, + const backend::ge_backend::TensorOrderMap ¶ms, + const std::vector &init_data_names) { + if (init_graph == nullptr) { + return true; + } + MS_LOG(DEBUG) << "ExecInitGraph start."; + std::vector<::ge::Tensor> ge_inputs; + for (auto &item : init_data_names) { + auto it = params.find(item); + if (it == params.end()) { + MS_LOG(ERROR) << "Cannot find parameter " << item << " in parameter map"; + return false; + } + auto ge_tensor = device::ascend::TransformUtil::ConvertTensor(it->second, kOpFormat_NCHW, false); + if (ge_tensor == nullptr) { + MS_LOG(ERROR) << "Failed to converter MS Tensor to GE Tensor"; + return false; + } + ge_inputs.emplace_back(*ge_tensor); + } + std::vector<::ge::Tensor> ge_outputs; + uint32_t graph_id = ge_session_info->graph_ids_.size(); + auto ge_status = ge_session_info->session_->AddGraph(graph_id, *(init_graph), std::map{}); + if (ge_status != ge::GRAPH_SUCCESS) { + MS_LOG(ERROR) << "Call GE AddGraph Failed: " << ge::GEGetErrorMsg(); + return false; + } + ge_status = ge_session_info->session_->RunGraph(graph_id, ge_inputs, ge_outputs); + if (ge_status != ge::GRAPH_SUCCESS) { + MS_LOG(ERROR) << "Exec init graph failed, graph id " << graph_id; + return false; + } + MS_LOG(INFO) << "Exec init graph success, graph id " << graph_id; + ge_session_info->session_->RemoveGraph(graph_id); + return true; +} +} // namespace mindspore diff --git a/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_graph_compiler.h b/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_graph_compiler.h new file mode 100644 index 00000000..7720996e --- /dev/null +++ b/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_graph_compiler.h @@ -0,0 +1,50 @@ +/** + * Copyright 2025 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. + */ +#ifndef MINDSPORE_LITE_SRC_EXTENDRT_DELEGATE_ASCEND_GE_GE_GRAPH_COMPILER_H_ +#define MINDSPORE_LITE_SRC_EXTENDRT_DELEGATE_ASCEND_GE_GE_GRAPH_COMPILER_H_ + +#include +#include +#include "backend/ge_backend/graph_ir/types.h" +#include "backend/ge_backend/graph_ir/utils.h" +#include "extendrt/delegate/ascend_ge/ge_options_container.h" + +namespace mindspore { +using GeSessionPtr = std::shared_ptr; + +struct GeSessionInfo { + GeSessionPtr session_{nullptr}; + int64_t session_id_{-1}; + std::vector graph_ids_; +}; + +class GeGraphCompiler { + public: + GeGraphCompiler() = default; + ~GeGraphCompiler() = default; + + bool CompileGraph(const FuncGraphPtr &graph, GeSessionInfo *ge_session_info, + const GeOptionsContainer &ge_options_container); + + private: + backend::ge_backend::DfGraphPtr ToGeGraph(const FuncGraphPtr &graph, GeSessionInfo *ge_session_info, + const std::string &graph_key); + bool ProcessGeInitGraph(GeSessionInfo *ge_session_info, backend::ge_backend::DfGraphPtr init_graph, + const backend::ge_backend::TensorOrderMap ¶ms, + const std::vector &init_data_names); +}; +} // namespace mindspore +#endif // MINDSPORE_LITE_SRC_EXTENDRT_DELEGATE_ASCEND_GE_GE_GRAPH_COMPILER_H_ diff --git a/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_graph_executor_v1.cc b/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_graph_executor_v1.cc new file mode 100644 index 00000000..a6f88022 --- /dev/null +++ b/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_graph_executor_v1.cc @@ -0,0 +1,282 @@ +/** + * Copyright 2025 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 "extendrt/delegate/ascend_ge/ge_graph_executor_v1.h" +#include +#include +#include +#include "extendrt/delegate/ascend_ge/ge_utils.h" +#include "extendrt/utils/func_graph_utils.h" +#include "extendrt/delegate/factory.h" +#include "src/common/common.h" +#include "src/common/log_util.h" + +namespace mindspore { +namespace { +constexpr auto kProviderGeV1 = "ge-v1"; +constexpr auto kIsAdapted = "is_adapted"; +std::mutex g_compile_graph_mutex; +constexpr size_t kAlignRefData = 32; +std::atomic_int64_t global_session_idx = 0; +} // namespace + +bool GeGraphExecutorV1::Init() { + ge_global_context_ = GeDeviceContext::InitGlobalContext(context_, config_infos_); + if (ge_global_context_ == nullptr) { + MS_LOG(ERROR) << "Failed to Init global context"; + return false; + } + return true; +} +GeGraphExecutorV1::~GeGraphExecutorV1() { + if (ge_session_info_.session_) { + for (auto graph_id : ge_session_info_.graph_ids_) { + ge_session_info_.session_->RemoveGraph(graph_id); + } + } + ge_session_info_.session_ = nullptr; +} + +bool GeGraphExecutorV1::CompileGraph(const FuncGraphPtr &graph, const std::map &, uint32_t *graph_id) { + MS_CHECK_TRUE_MSG(graph != nullptr, false, "graph is NULL."); + MS_CHECK_TRUE_MSG(graph_id != nullptr, false, "graph_id is NULL."); + if (!ge_options_container_.InitGeOptions(graph, config_infos_, context_)) { + MS_LOG(ERROR) << "Init Ge options failed."; + return false; + } + if (ge_session_info_.session_ == nullptr) { + ge_session_info_.session_ = std::make_shared(ge_options_container_.GeSessionOptions()); + if (ge_session_info_.session_ == nullptr) { + MS_LOG(ERROR) << "Failed to create ge session"; + return false; + } + ge_session_info_.session_id_ = global_session_idx++; + } + if (CheckParallelCompile()) { + MS_LOG(WARNING) << lite::kCompileGraphParallel << " does not support ge provider"; + } + + std::lock_guard lock(g_compile_graph_mutex); + bool is_adapted = graph->has_attr(kIsAdapted); + if (!is_adapted) { + auto ret = GeUtils::AdaptGraph(graph); + MS_CHECK_TRUE_MSG(ret == kSuccess, false, "Adapt graph failed"); + graph->set_attr(kIsAdapted, MakeValue(true)); + } + if (!ge_graph_compiler_.CompileGraph(graph, &ge_session_info_, ge_options_container_)) { + MS_LOG(ERROR) << "GE compile graph failed."; + return false; + } + *graph_id = ge_session_info_.graph_ids_.back(); + if (!InitGEResource()) { + MS_LOG(ERROR) << "Init resource for GE failed."; + return false; + } + if (!InitMsTensor(graph, *graph_id)) { + MS_LOG(ERROR) << "Init MSTensor for inputs/outputs failed."; + return false; + } + if (!InitGeTensor(*graph_id)) { + MS_LOG(ERROR) << "Init ge::Tensor for inputs/outputs failed."; + return false; + } + return true; +} + +bool GeGraphExecutorV1::CheckParallelCompile() { + auto config_it = config_infos_.find(lite::kCommonContextSection); + if (config_it == config_infos_.end()) { + return false; + } + auto &options = config_it->second; + auto option_it = options.find(lite::kCompileGraphParallel); + if (option_it == options.end()) { + return false; + } + return option_it->second == lite::kEnableValue; +} + +bool GeGraphExecutorV1::InitGEResource() { + if (memory_manager_ == nullptr) { + memory_manager_ = std::make_shared(); + if (memory_manager_ == nullptr) { + MS_LOG(ERROR) << "Failed to create memory manager"; + return false; + } + } + if (context_manager_ == nullptr) { + context_manager_ = std::make_shared(); + if (context_manager_ == nullptr) { + MS_LOG(ERROR) << "Failed to create context manager"; + return false; + } + auto ascend_info = GeUtils::GetAscendDeviceInfo(context_); + if (ascend_info == nullptr) { + MS_LOG(ERROR) << "Can not find ascend device context."; + return false; + } + if (!context_manager_->InitContext(ascend_info->GetDeviceID())) { + MS_LOG(ERROR) << "Failed to init device"; + return false; + } + } + if (!context_manager_->SetContext()) { + MS_LOG(ERROR) << "Failed to set ge context"; + return false; + } + return true; +} + +bool GeGraphExecutorV1::InitMsTensor(const FuncGraphPtr &graph, uint32_t graph_id) { + auto create_func = [](const std::vector &nodes, std::vector *ms_tensors, + bool is_input) { + std::string prefix = is_input ? "Input_" : "Output_"; + for (size_t i = 0; i < nodes.size(); ++i) { + auto shape = FuncGraphUtils::GetTensorShape(nodes[i]); + auto dtype = static_cast(FuncGraphUtils::GetTensorDataType(nodes[i])); + auto ms_tensor_ptr = mindspore::MSTensor::CreateTensor(prefix + std::to_string(i), dtype, {}, nullptr, 0); + if (ms_tensor_ptr == nullptr) { + MS_LOG(ERROR) << "Create " << prefix + std::to_string(i) << " MSTensor failed."; + return false; + } + ms_tensor_ptr->SetShape(shape); + ms_tensors->push_back(*ms_tensor_ptr); + delete ms_tensor_ptr; + } + return true; + }; + auto inputs = graph->get_inputs(); + std::vector in_nodes; + (void)std::transform(inputs.begin(), inputs.end(), std::back_inserter(in_nodes), + [](const AnfNodePtr &input) { return std::make_pair(input, 0); }); + ms_inputs_[graph_id] = {}; + if (!create_func(in_nodes, &ms_inputs_[graph_id], true)) { + MS_LOG(ERROR) << "Create MSTensor for inputs failed."; + return false; + } + std::vector out_nodes; + if (!FuncGraphUtils::GetFuncGraphOutputs(graph, &out_nodes)) { + MS_LOG(ERROR) << "Failed to get func graph outputs"; + return false; + } + ms_outputs_[graph_id] = {}; + if (!create_func(out_nodes, &ms_outputs_[graph_id], false)) { + MS_LOG(ERROR) << "Create MSTensor for outputs failed."; + return false; + } + return true; +} + +bool GeGraphExecutorV1::InitGeTensor(uint32_t graph_id) { + // Delayed HBM memory allocation. + auto create_func = [](const std::vector &ms_tensors, std::vector *ge_tensors) { + ge_tensors->resize(ms_tensors.size()); + for (size_t i = 0; i < ms_tensors.size(); ++i) { + auto dtype = static_cast(ms_tensors[i].DataType()); + auto desc = device::ascend::TransformUtil::GetGeTensorDesc({}, dtype, kOpFormat_NCHW); + if (desc == nullptr) { + MS_LOG(ERROR) << "Failed to create Tensor Desc"; + return false; + } + desc->SetPlacement(::ge::kPlacementDevice); + auto ret = ge_tensors->at(i).SetTensorDesc(*desc); + if (ret != ACL_SUCCESS) { + MS_LOG(ERROR) << "Failed to call ge::Tensor::SetTensorDesc, ret " << ret; + return false; + } + } + return true; + }; + ge_inputs_[graph_id] = {}; + if (!create_func(ms_inputs_[graph_id], &ge_inputs_[graph_id])) { + MS_LOG(ERROR) << "Create ge::Tensor for inputs failed."; + return false; + } + ge_outputs_[graph_id] = {}; + if (!create_func(ms_outputs_[graph_id], &ge_outputs_[graph_id])) { + MS_LOG(ERROR) << "Create ge::Tensor for outputs failed."; + return false; + } + return true; +} + +std::vector GeGraphExecutorV1::GetInputInfos(uint32_t graph_id) { + return ms_inputs_.find(graph_id) != ms_inputs_.end() ? ms_inputs_.at(graph_id) : std::vector(); +} +std::vector GeGraphExecutorV1::GetOutputInfos(uint32_t graph_id) { + return ms_outputs_.find(graph_id) != ms_outputs_.end() ? ms_outputs_.at(graph_id) + : std::vector(); +} + +bool GeGraphExecutorV1::RunGraph(uint32_t graph_id, const std::vector &inputs, std::vector *outputs, + const std::map & /* compile_options */) { + if (outputs == nullptr) { + MS_LOG(ERROR) << " outputs param is nullptr."; + return false; + } + + MS_LOG(INFO) << "Run ge graph [" << graph_id << "] with " << inputs.size() << " ms_tensor_inputs"; + if (!PrepareGeInputs(inputs, graph_id)) { + MS_LOG(ERROR) << "Prepare ge inputs failed."; + return false; + } + if (!PrepareGeOutputs(outputs, graph_id)) { + MS_LOG(ERROR) << "Prepare ge outputs failed."; + return false; + } + auto stream = context_manager_->GetDefaultStream(); + auto time_start = std::chrono::system_clock::now(); + auto ret = + ge_session_info_.session_->RunGraphWithStreamAsync(graph_id, stream, ge_inputs_[graph_id], ge_outputs_[graph_id]); + if (ret != ge::GRAPH_SUCCESS) { + MS_LOG(ERROR) << "Call GE RunGraphWithStreamAsync Failed, ret is: " << ret; + return false; + } + if (!context_manager_->SyncStream(stream)) { + MS_LOG(ERROR) << "Sync stream for RunGraphWithStreamAsync failed"; + return false; + } + auto time_cost = + std::chrono::duration_cast(std::chrono::system_clock::now() - time_start).count(); + MS_LOG(INFO) << "Call GE RunGraph Success in " << time_cost << " us, graph id " << graph_id; + if (!PostProcessGeOutputs(outputs, graph_id)) { + MS_LOG(ERROR) << "PostPrecess ge outputs failed."; + return false; + } + return true; +} + +// Todo +bool GeGraphExecutorV1::PrepareGeInputs(const std::vector &inputs, uint32_t graph_id) { return true; } + +// Todo +bool GeGraphExecutorV1::PrepareGeOutputs(std::vector *outputs, uint32_t graph_id) { return true; } + +// Todo +bool GeGraphExecutorV1::PostProcessGeOutputs(std::vector *outputs, uint32_t graph_id) { return true; } + +static std::shared_ptr GeGraphExecutorCreatorV1(const std::shared_ptr &ctx, + const ConfigInfos &config_infos) { + auto ge_executor = std::make_shared(ctx, config_infos); + if (ge_executor == nullptr || !ge_executor->Init()) { + MS_LOG(ERROR) << "Failed to init GeGraphExecutor"; + return nullptr; + } + return ge_executor; +} + +REG_DELEGATE(kAscend, kProviderGeV1, GeGraphExecutorCreatorV1) +} // namespace mindspore diff --git a/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_graph_executor_v1.h b/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_graph_executor_v1.h new file mode 100644 index 00000000..4e3ab608 --- /dev/null +++ b/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_graph_executor_v1.h @@ -0,0 +1,79 @@ +/** + * Copyright 2025 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. + */ +#ifndef MINDSPORE_LITE_SRC_EXTENDRT_DELEGATE_ASCEND_GE_GE_GRAPH_EXECUTOR_V1_H_ +#define MINDSPORE_LITE_SRC_EXTENDRT_DELEGATE_ASCEND_GE_GE_GRAPH_EXECUTOR_V1_H_ + +#include +#include +#include +#include +#include "include/api/context.h" +#include "backend/ge_backend/graph_ir/types.h" +#include "common/config_infos.h" +#include "extendrt/session/lite_graph_executor.h" +#include "extendrt/delegate/ascend_ge/ge_device_context.h" +#include "extendrt/delegate/ascend_ge/ge_memory_manager.h" +#include "extendrt/delegate/ascend_ge/ge_context_manager.h" +#include "extendrt/delegate/ascend_ge/ge_options_container.h" +#include "extendrt/delegate/ascend_ge/ge_graph_compiler.h" + +namespace mindspore { +using MSTensorPtr = std::shared_ptr; + +class GeGraphExecutorV1 : public LiteGraphExecutor { + public: + GeGraphExecutorV1(const std::shared_ptr &context, const ConfigInfos &config_infos) + : context_(context), config_infos_(config_infos) {} + ~GeGraphExecutorV1(); + + bool Init(); + bool CompileGraph(const FuncGraphPtr &graph, const std::map &compile_options, + uint32_t *graph_id) override; + + bool RunGraph(uint32_t graph_id, const std::vector &inputs, std::vector *outputs, + const std::map &compile_options) override; + + bool Resize(uint32_t graph_id, const std::vector &inputs, + const std::vector &dims) override { + return true; + } + + std::vector GetInputInfos(uint32_t graph_id) override; + std::vector GetOutputInfos(uint32_t graph_id) override; + + private: + bool CheckParallelCompile(); + bool InitGEResource(); + bool InitMsTensor(const FuncGraphPtr &graph, uint32_t graph_id); + bool InitGeTensor(uint32_t graph_id); + bool PrepareGeInputs(const std::vector &inputs, uint32_t graph_id); + bool PrepareGeOutputs(std::vector *outputs, uint32_t graph_id); + bool PostProcessGeOutputs(std::vector *outputs, uint32_t graph_id); + GeOptionsContainer ge_options_container_; + GeGraphCompiler ge_graph_compiler_; + const std::shared_ptr context_; + ConfigInfos config_infos_; + GeSessionInfo ge_session_info_; + std::shared_ptr ge_global_context_{nullptr}; + std::shared_ptr memory_manager_{nullptr}; + std::shared_ptr context_manager_{nullptr}; + std::map> ge_inputs_; + std::map> ge_outputs_; + std::map> ms_inputs_; + std::map> ms_outputs_; +}; +} // namespace mindspore +#endif // MINDSPORE_LITE_SRC_EXTENDRT_DELEGATE_ASCEND_GE_GE_GRAPH_EXECUTOR_V1_H_ diff --git a/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_options_container.cc b/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_options_container.cc new file mode 100644 index 00000000..a5512d28 --- /dev/null +++ b/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_options_container.cc @@ -0,0 +1,179 @@ +/** + * Copyright 2025 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 "extendrt/delegate/ascend_ge/ge_options_container.h" +#include +#include +#include +#include +#include "extendrt/delegate/ascend_ge/ge_utils.h" +#include "src/common/common.h" +#include "src/common/file_utils.h" +#include "tools/converter/adapter/acl/cxx_api_lite/cxx_api/acl_utils.h" + +namespace mindspore { +namespace { +constexpr auto kDump = "dump"; +constexpr auto kDumpMode = "dump_mode"; +constexpr auto kProfiling = "profiler"; +} // namespace +std::atomic_int64_t GeOptionsContainer::unique_identification_ = 0; +bool GeOptionsContainer::InitGeOptions(const FuncGraphPtr &graph, const ConfigInfos &config_info, + const std::shared_ptr &context) { + MS_CHECK_TRUE_MSG(graph != nullptr, false, "graph is NULL."); + MS_CHECK_TRUE_MSG(context != nullptr, false, "context is NULL."); + ge_session_options_.clear(); + ge_graph_options_.clear(); + if (!InitGeSessionOptions(config_info, context)) { + MS_LOG(ERROR) << "Init ge_session_options failed."; + return false; + } + if (!InitGeGraphOptions(config_info, context, graph->ToString())) { + MS_LOG(ERROR) << "Init ge_graph_options failed."; + return false; + } + return true; +} + +bool GeOptionsContainer::InitGeSessionOptions(const ConfigInfos &config_info, + const std::shared_ptr &context) { + auto ascend_device_info = GeUtils::GetAscendDeviceInfo(context); + if (ascend_device_info == nullptr) { + MS_LOG(ERROR) << "Failed to get graph session options, can not find ascend device context."; + return false; + } + + ge_session_options_["ge.trainFlag"] = "0"; + ge_session_options_["ge.enablePrintOpPass"] = "0"; + ge_session_options_["ge.exec.device_id"] = std::to_string(ascend_device_info->GetDeviceID()); + ge_session_options_["ge.exec.staticMemoryPolicy"] = "2"; + auto config_it = config_info.find(lite::kGeSessionOptionsSection); + if (config_it != config_info.end()) { + for (auto &item : config_it->second) { + ge_session_options_[item.first] = item.second; + } + } + return GetGeSessionOptionsFromAscendSection(config_info, ascend_device_info); +} + +bool GeOptionsContainer::GetGeSessionOptionsFromAscendSection( + const ConfigInfos &config_info, const std::shared_ptr &ascend_device_info) { + auto config_it = config_info.find(lite::kAscendContextSection); + if (config_it == config_info.end()) { + return true; + } + + auto config = config_it->second; + auto option_it = config.find(lite::kModelCacheMode); + if (option_it != config.end()) { + if (!option_it->second.empty()) { + auto build_cache_dir = "model_build_cache_" + std::to_string(ascend_device_info->GetRankID()); + if (lite::CreateDir(build_cache_dir) != lite::RET_OK) { + MS_LOG(ERROR) << "Failed to create build cache dir " << build_cache_dir; + return false; + } + ge_session_options_[kGeGraphCompilerCacheDir] = build_cache_dir; + MS_LOG(INFO) << "Update session attr " << kGeGraphCompilerCacheDir << " to " << build_cache_dir; + } + } + option_it = config.find(lite::kDumpPathKey); + if (option_it != config.end()) { + auto dump_path = option_it->second; + auto real_path = lite::RealPath(dump_path.c_str()); + std::ifstream ifs(real_path); + if (!ifs.good() || !ifs.is_open()) { + MS_LOG(ERROR) << "The dump config file is not exit or open failed."; + return false; + } + nlohmann::json dump_cfg_json; + try { + dump_cfg_json = nlohmann::json::parse(ifs); + } catch (const nlohmann::json::parse_error &error) { + MS_LOG(EXCEPTION) << "parse json failed, please check the file."; + } + if (dump_cfg_json[kDump] != nullptr && dump_cfg_json[kDump][kDumpMode] != nullptr) { + ge_session_options_["ge.exec.enableDump"] = "1"; + ge_session_options_["ge.exec.dumpMode"] = dump_cfg_json[kDump][kDumpMode].get(); + } + } + option_it = config.find(lite::kProfilingPathKey); + if (option_it != config.end()) { + auto profiling_path = option_it->second; + auto real_path = lite::RealPath(profiling_path.c_str()); + std::ifstream ifs(real_path); + if (!ifs.good() || !ifs.is_open()) { + MS_LOG(EXCEPTION) << "The profiling_path config file is not exit or open failed."; + } + nlohmann::json profiling_cfg_json; + try { + profiling_cfg_json = nlohmann::json::parse(ifs); + } catch (const nlohmann::json::parse_error &error) { + MS_LOG(EXCEPTION) << "parse json failed, please check the file."; + } + if (profiling_cfg_json[kProfiling] != nullptr) { + ge_session_options_["ge.exec.profilingMode"] = "1"; + ge_session_options_["ge.exec.profilingOptions"] = profiling_cfg_json[kProfiling].dump(); + } + } + option_it = config.find(lite::kGeVariableMemoryMaxSize); + if (option_it != config.end()) { + ge_session_options_["ge.variableMemoryMaxSize"] = option_it->second; + } + option_it = config.find(lite::kGeGraphMemoryMaxSize); + if (option_it != config.end()) { + ge_session_options_["ge.graphMemoryMaxSize"] = option_it->second; + } + option_it = config.find(lite::kGraphCompilerCacheDirKey); + if (option_it != config.end()) { + ge_session_options_[kGeGraphCompilerCacheDir] = option_it->second; + } + return true; +} + +bool GeOptionsContainer::InitGeGraphOptions(const ConfigInfos &config_info, + const std::shared_ptr &context, + const std::string &graph_key_suffix) { + auto ascend_device_info = GeUtils::GetAscendDeviceInfo(context); + if (ascend_device_info == nullptr) { + MS_LOG(ERROR) << "Failed to get graph session options, can not find ascend device context."; + return false; + } + auto graph_key = std::to_string(ascend_device_info->GetRankID()) + "_" + std::to_string(unique_identification_++) + + "_" + graph_key_suffix; + std::replace_if(graph_key.begin(), graph_key.end(), [](char c) { return c == '.'; }, '_'); + ge_graph_options_[kGeGraphKey] = graph_key; + auto config_it = config_info.find(lite::kGeGraphOptionsSection); + if (config_it != config_info.end()) { + for (auto &item : config_it->second) { + ge_graph_options_[item.first] = item.second; + } + } + auto precision_mode = ascend_device_info->GetPrecisionMode(); + if (!precision_mode.empty()) { + ge_graph_options_["ge.exec.precision_mode"] = TransforPrecisionToAcl(precision_mode); + } + config_it = config_info.find(lite::kAscendContextSection); + if (config_it == config_info.end()) { + return true; + } + auto config = config_it->second; + auto option_it = config.find(lite::kModifyMixList); + if (option_it != config.end()) { + ge_graph_options_["ge.exec.modify_mixlist"] = option_it->second; + } + return true; +} +} // namespace mindspore diff --git a/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_options_container.h b/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_options_container.h new file mode 100644 index 00000000..fceababe --- /dev/null +++ b/mindspore-lite/src/extendrt/delegate/ascend_ge/ge_options_container.h @@ -0,0 +1,45 @@ +/** + * Copyright 2025 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. + */ +#ifndef MINDSPORE_LITE_SRC_EXTENDRT_DELEGATE_ASCEND_GE_GE_OPTIONS_CONTAINER_H_ +#define MINDSPORE_LITE_SRC_EXTENDRT_DELEGATE_ASCEND_GE_GE_OPTIONS_CONTAINER_H_ + +#include +#include "common/config_infos.h" +#include "include/api/context.h" +#include "ir/func_graph.h" + +namespace mindspore { +class GeOptionsContainer { + public: + GeOptionsContainer() = default; + ~GeOptionsContainer() = default; + bool InitGeOptions(const FuncGraphPtr &graph, const ConfigInfos &config_info, + const std::shared_ptr &context); + const std::map &GeSessionOptions() const { return ge_session_options_; } + const std::map &GeGraphOptions() const { return ge_graph_options_; } + + private: + bool InitGeSessionOptions(const ConfigInfos &config_info, const std::shared_ptr &context); + bool GetGeSessionOptionsFromAscendSection(const ConfigInfos &config_info, + const std::shared_ptr &ascend_device_info); + bool InitGeGraphOptions(const ConfigInfos &config_info, const std::shared_ptr &context, + const std::string &graph_key_suffix); + std::map ge_session_options_; + std::map ge_graph_options_; + static std::atomic_int64_t unique_identification_; +}; +} // namespace mindspore +#endif // MINDSPORE_LITE_SRC_EXTENDRT_DELEGATE_ASCEND_GE_GE_OPTIONS_CONTAINER_H_ diff --git a/mindspore-lite/src/extendrt/infer_session.cc b/mindspore-lite/src/extendrt/infer_session.cc index d174f8ee..d188d6f2 100644 --- a/mindspore-lite/src/extendrt/infer_session.cc +++ b/mindspore-lite/src/extendrt/infer_session.cc @@ -20,14 +20,14 @@ #include "extendrt/delegate/plugin/litert_executor_plugin.h" #include "extendrt/delegate/plugin/ascend_ge_executor_plugin.h" #include "extendrt/delegate/plugin/ascend_acl_executor_plugin.h" +#include "src/common/common.h" #include "nnacl_c/op_base.h" namespace mindspore { namespace { void AscendPluginRegistration(const std::shared_ptr &ascend_device, bool use_experimental_rts) { - constexpr auto default_npu_provider = "ge"; auto provider = ascend_device->GetProvider(); - if (provider == default_npu_provider) { + if (lite::IsGe(provider)) { if (!lite::AscendGeExecutorPlugin::GetInstance().Register()) { MS_LOG(WARNING) << "Failed to register AscendGe plugin"; return; @@ -102,12 +102,6 @@ SessionType InferSession::SelectSession(const std::shared_ptr &context, auto &device_contexts = context->MutableDeviceInfo(); for (const auto &device_context : device_contexts) { MS_EXCEPTION_IF_NULL(device_context); - if (device_context->GetDeviceType() == kAscend) { - if (device_context->GetProvider() == "ge") { - return kDelegateSession; - } - return kDelegateSession; - } return kDelegateSession; } } else { diff --git a/mindspore-lite/src/extendrt/session/delegate_session.cc b/mindspore-lite/src/extendrt/session/delegate_session.cc index 9208b5fe..bdba53ef 100644 --- a/mindspore-lite/src/extendrt/session/delegate_session.cc +++ b/mindspore-lite/src/extendrt/session/delegate_session.cc @@ -428,7 +428,7 @@ static std::shared_ptr DelegateSessionCreator(const std::shared_pt auto device_type = device_contexts.at(0)->GetDeviceType(); auto provider = device_contexts.at(0)->GetProvider(); if (device_type == DeviceType::kAscend) { - if (provider == "ge") { + if (lite::IsGe(provider)) { if (!lite::AscendGeExecutorPlugin::GetInstance().Register()) { MS_LOG(WARNING) << "Failed to register AscendGe plugin"; return nullptr; -- Gitee