/**
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
 * CANN Open Software License Agreement Version 2.0 (the "License").
 * Please refer to the License for details. You may not use this file except in compliance with the License.
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
 * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
 * See LICENSE in the root of the software repository for the full text of the License.
 */
#include <vector>
#include <mutex>
#include <string>
#include <queue>
#include "securec.h"
#include "acl/acl_base.h"
#include "executor/ge_executor.h"
#include "common/log_inner.h"
#include "graph/tensor.h"
#include "graph/types.h"
#include "exe_graph/runtime/runtime_tensor.h"
#include "exe_graph/runtime/shape.h"
#include "model_desc_internal.h"
#include "error_codes_inner.h"
#include "common/prof_api_reg.h"
#include "framework/runtime/model_v2_executor.h"
#include "framework/runtime/gert_api.h"
#include "framework/runtime/subscriber/global_profiler.h"
#include "utils/math_utils.h"
#include "utils/acl_string_utils.h"
#include "model_config.h"
#include "acl_resource_manager.h"
#include "graph/ge_local_context.h"
#include "graph/ge_context.h"
#include "graph/def_types.h"
#include "types/tensor_desc_internal.h"
#include "types/data_buffer_internal.h"
#include "acl_model_impl.h"
#include "acl_model_impl_om2.h"
#include "acl/acl_rt.h"
#include "model_common.h"

namespace ge {
class JsonFile;
}

namespace {
constexpr size_t MIN_OUTPUT_SHAPE_INFO_SIZE = 2U;
constexpr size_t MAX_OUTPUT_SHAPE_INFO_SIZE = MIN_OUTPUT_SHAPE_INFO_SIZE + static_cast<size_t>(ACL_MAX_DIM_CNT);
constexpr size_t DYNAMIC_BATCH_SIZE = 1U;
constexpr size_t DYNAMIC_HW_SIZE = 2U;
constexpr int32_t DEFAULT_SYNC_TIMEOUT = -1;
constexpr uint16_t kStartTag = 0U;
constexpr uint16_t kEndTag = 1U;
constexpr const char_t *OPTION_EXEC_REUSE_ZERO_COPY_MEMORY = "ge.exec.reuseZeroCopyMemory";

std::mutex aclmdlGetOpAttrMutex;
std::mutex aclmdlBundleMutex;

aclError aclmdlCheckQueueParam(const uint32_t *const inputQ, const size_t inputQNum, const uint32_t *const outputQ,
                               const size_t outputQNum) {
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(inputQ);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(outputQ);
  if ((inputQNum == 0U) || (outputQNum == 0U)) {
    ACL_LOG_INNER_ERROR("[Check][QNum]inputQNum[%zu] or outputQNum[%zu] is invalid, can't be zero", inputQNum,
                        outputQNum);
    return ACL_ERROR_INVALID_PARAM;
  }
  return ACL_SUCCESS;
}

ge::ModelLoadArg ConstructGeModelLoadArg(void *devPtr, size_t memSize, void *weightPtr, size_t weightSize,
                                         gert::RtSession *rtSession = nullptr,
                                         const std::vector<ge::FileConstantMem> &fileConstantMems = {},
                                         const bool need_clear_dfx_cache = false) {
  ge::ModelLoadArg loadArgs;
  loadArgs.dev_ptr = devPtr;
  loadArgs.mem_size = memSize;
  loadArgs.weight_ptr = weightPtr;
  loadArgs.weight_size = weightSize;
  loadArgs.rt_session = rtSession;
  loadArgs.file_constant_mems = fileConstantMems;
  loadArgs.need_clear_dfx_cache = need_clear_dfx_cache;
  return loadArgs;
}
}  // namespace

namespace acl {

static aclError GetDynamicTensorInfo(aclmdlDesc *const modelDesc) {
  ACL_LOG_DEBUG("call ge interface executor.GetDynamicBatchInfo");
  const uint32_t modelId = modelDesc->modelId;
  std::vector<std::vector<int64_t>> batchInfo;
  int32_t dynamicType = static_cast<int32_t>(ge::FIXED);
  std::vector<std::string> userDesignateShapeOrder;
  {
    ge::GeExecutor executor;
    ge::Status ret = executor.GetDynamicBatchInfo(modelId, batchInfo, dynamicType);
    if (ret != ge::SUCCESS) {
      ACL_LOG_WARN("cannot get dynamic model info, ge result[%u], model id[%u]", ret, modelId);
    }
    ret = executor.GetUserDesignateShapeOrder(modelId, userDesignateShapeOrder);
    if (ret != ge::SUCCESS) {
      ACL_LOG_WARN("cannot get user designate shape order, ge result[%u], model id[%u]", ret, modelId);
    }
  }
  modelDesc->dataNameOrder = userDesignateShapeOrder;
  return GetDynamicTensorInfoHelp(modelDesc, dynamicType, batchInfo);
}

static aclError RuntimeV2GetDynamicTensorInfo(aclmdlDesc *const modelDesc, const gert::ModelDesc &geModelDesc) {
  ACL_LOG_DEBUG("call ge interface executor.GetDynamicBatchInfo");
  std::vector<std::vector<int64_t>> batchInfo;
  const uint32_t modelId = modelDesc->modelId;
  int32_t dynamicType = static_cast<int32_t>(ge::FIXED);
  ge::Status ret = geModelDesc.GetDynamicBatchInfo(batchInfo, dynamicType);
  if (ret != ge::SUCCESS) {
    ACL_LOG_WARN("get dynamic model info failed, ge result[%u], model id[%u]", ret, modelId);
  }
  std::vector<std::string> userDesignateShapeOrder;
  ret = geModelDesc.GetUserDesignateShapeOrder(userDesignateShapeOrder);
  if (ret != ge::SUCCESS) {
    ACL_LOG_WARN("get user designate shape order failed, ge result[%u], model id[%u]", ret, modelId);
  }
  modelDesc->dataNameOrder = userDesignateShapeOrder;

  return GetDynamicTensorInfoHelp(modelDesc, dynamicType, batchInfo);
}

static aclError GetModelOutputShapeInfo(aclmdlDesc *const modelDesc) {
  ACL_LOG_DEBUG("call ge interface executor.GetModelAttr");
  const uint32_t modelId = modelDesc->modelId;
  std::vector<std::string> geDynamicOutputShape;
  ge::Status ret = ge::SUCCESS;
  {
    ge::GeExecutor executor;
    ret = executor.GetModelAttr(modelId, geDynamicOutputShape);
  }
  if (ret != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("[Get][ModelAttr]get model attribute failed, ge result[%u], model id[%u]", ret, modelId);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }
  return GetModelOutputShapeInfoHelp(modelDesc, geDynamicOutputShape);
}

static aclError RuntimeV2GetModelOutputShapeInfo(aclmdlDesc *const modelDesc, const gert::ModelDesc &geModeDesc) {
  ACL_LOG_DEBUG("call ge interface executor.GetModelAttr");
  std::vector<std::string> geDynamicOutputShape;
  const uint32_t modelId = modelDesc->modelId;
  const ge::Status ret = geModeDesc.GetModelAttrs(geDynamicOutputShape);
  if (ret != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("[Get][ModelAttr]get model attribute failed, ge result[%u], model id[%u]", ret, modelId);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }

  return GetModelOutputShapeInfoHelp(modelDesc, geDynamicOutputShape);
}

static aclError ModelLoadFromFileWithMem(const char_t *const modelPath, uint32_t *const modelId,
                                         const ge::ModelLoadArg &loadArgs, const int32_t priority) {
  ACL_LOG_INFO(
      "start to execute ModelLoadFromFileWithMem, modelPath[%s], "
      "workSize[%zu], weightSize[%zu], priority[%d]",
      modelPath, loadArgs.mem_size, loadArgs.weight_size, priority);

  ge::GeExecutor executor;
  uint32_t id = 0U;
  ge::ModelData data;
  const std::string path(modelPath);
  data.om_path = path;
  ACL_LOG_INFO("call ge interface executor.LoadDataFromFile, workSize[%zu], weightSize[%zu]", loadArgs.mem_size,
               loadArgs.weight_size);
  ge::Status ret = executor.LoadDataFromFile(path, data);
  if (ret != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("[Model][FromFile]load model from file[%s] failed, ge result[%u]", modelPath, ret);
    ACL_DELETE_ARRAY(data.model_data);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }
  data.priority = priority;
  ACL_LOG_INFO("call ge interface executor.LoadModelFromDataWithArgs, workSize[%zu], weightSize[%zu]",
               loadArgs.mem_size, loadArgs.weight_size);
  ret = executor.LoadModelFromDataWithArgs(id, data, loadArgs);
  if (ret != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("[Model][FromData]load model from data failed, ge result[%u]", ret);
    ACL_DELETE_ARRAY(data.model_data);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }

  *modelId = id;
  ACL_DELETE_ARRAY(data.model_data);
  ACL_LOG_INFO("successfully execute ModelLoadFromFileWithMem, workSize[%zu], weightSize[%zu], modelId[%u]",
               loadArgs.mem_size, loadArgs.weight_size, *modelId);
  return ACL_SUCCESS;
}

static aclError RuntimeV2ModelLoadCommon(ge::ModelData &modelData, uint32_t *const modelId, const void *const weightPtr,
                                         const size_t weightSize, std::vector<ge::FileConstantMem> file_constant_mems,
                                         const std::shared_ptr<gert::RtSession> &rtSessionExternal) {
  ACL_LOG_INFO("call ge interface gert::LoadExecutorFromModelData, weightSize[%zu]", weightSize);
  ge::graphStatus ret = ge::GRAPH_SUCCESS;
  std::unique_ptr<gert::ModelV2Executor> executor;
  auto rtSession =
      (rtSessionExternal != nullptr) ? rtSessionExternal : acl::AclResourceManager::GetInstance().CreateRtSession();
  ACL_REQUIRES_NOT_NULL(rtSession);
  gert::LoadExecutorArgs args = {.rt_session = rtSession.get(), .file_constant_mems = std::move(file_constant_mems)};
  executor = gert::LoadExecutorFromModelData(modelData, args, ret);
  if (ret != ge::GRAPH_SUCCESS) {
    ACL_LOG_CALL_ERROR(
        "[Model][FromData]call gert::LoadExecutorFromModelDataWithMem load model from data failed, "
        "ge result[%u]",
        ret);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }
  ACL_REQUIRES_NOT_NULL(executor);
  // 4. load rt2.0 executor
  ACL_LOG_DEBUG("call ge interface executorV2.Load");
  aclrtStream rtStream = nullptr;
  ACL_REQUIRES_CALL_RTS_OK(aclrtCreateStream(&rtStream), aclrtCreateStream);

  gert::ModelExecuteArg exeArg;
  exeArg.stream = rtStream;
  ret = executor->Load(exeArg, gert::ModelLoadArg(rtSession.get(), {weightPtr, weightSize}));
  if (ret != ge::GRAPH_SUCCESS) {
    ACL_LOG_CALL_ERROR("[Model][FromData]call load executorV2 failed, ge result[%u]", ret);
    (void)aclrtDestroyStream(rtStream);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }
  ret = aclrtSynchronizeStream(rtStream);
  if (ret != ACL_ERROR_NONE) {
    ACL_LOG_CALL_ERROR("synchronize stream failed, runtime result = %d", static_cast<int32_t>(ret));
    (void)aclrtDestroyStream(rtStream);
    return ACL_GET_ERRCODE_RTS(ret);
  }
  (void)aclrtDestroyStream(rtStream);

  // 5. get model-id
  acl::AclResourceManager::GetInstance().AddExecutor(*modelId, std::move(executor), rtSession);
  return ACL_SUCCESS;
}

static aclError RuntimeV2ModelLoadFromFileWithMem(const char_t *const modelPath, uint32_t *const modelId,
                                                  void *const weightPtr, const size_t weightSize,
                                                  const int32_t priority,
                                                  std::vector<ge::FileConstantMem> file_constant_mems = {},
                                                  const std::shared_ptr<gert::RtSession> &rtSessionExternal = nullptr) {
  ACL_LOG_INFO("start to execute RuntimeV2ModelLoadFromFileWithMem, priority[%d], weightSize[%zu]", priority,
               weightSize);

  // 1. load model data from file
  ge::ModelData modelData;
  modelData.om_path = modelPath;
  ge::graphStatus ret = ge::GRAPH_SUCCESS;
  ACL_LOG_INFO("call ge interface gert::LoadDataFromFile");
  ret = gert::LoadDataFromFile(modelPath, modelData);
  if (ret != ge::GRAPH_SUCCESS) {
    ACL_LOG_CALL_ERROR("[Load][Model]failed to load model from file by runtime2.0, ge errorCode is %u", ret);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }
  std::shared_ptr<void> dataAuto;
  dataAuto.reset(modelData.model_data, [](const void *const p) { delete[] static_cast<const uint8_t *>(p); });
  // 2. config model data
  modelData.priority = priority;
  // 3. get rt2.0 executor
  ACL_REQUIRES_OK(RuntimeV2ModelLoadCommon(modelData, modelId, weightPtr, weightSize, std::move(file_constant_mems),
                                           rtSessionExternal));
  ACL_LOG_INFO("successfully execute RuntimeV2ModelLoadFromFileWithMem, modelSize[%lu], modelId[%u], weightSize[%zu]",
               modelData.model_len, *modelId, weightSize);
  return ACL_SUCCESS;
}

static aclError ModelLoadFromMemWithMem(const void *const model, const size_t modelSize, const std::string &modelPath,
                                        uint32_t *const modelId, const ge::ModelLoadArg &loadArgs,
                                        const char_t *const weightPath, const int32_t priority) {
  ACL_LOG_INFO("start to execute ModelLoadFromMemWithMem, workSize[%zu], weightSize[%zu], priority[%d]",
               loadArgs.mem_size, loadArgs.weight_size, priority);
  if (modelSize == 0U) {
    ACL_LOG_INNER_ERROR("[Check][ModelSize]modelSize[%zu] is invalid, should not be zero", modelSize);
    return ACL_ERROR_INVALID_PARAM;
  }

  ge::GeExecutor geExecutor;
  uint32_t id = 0U;
  ge::ModelData modelData;
  modelData.model_data = const_cast<void *>(model);
  modelData.model_len = static_cast<uint64_t>(modelSize);
  modelData.priority = priority;
  modelData.om_path = modelPath;
  if (weightPath != nullptr) {
    modelData.weight_path = std::string(weightPath);
    ACL_LOG_INFO("Load weight path is [%s]", modelData.weight_path.c_str());
  }
  ACL_LOG_INFO("call ge interface executor.LoadModelFromDataWithArgs, modelSize[%zu], workSize[%zu], weightSize[%zu]",
               modelSize, loadArgs.mem_size, loadArgs.weight_size);
  const auto ret = geExecutor.LoadModelFromDataWithArgs(id, modelData, loadArgs);
  if (ret != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("[Model][FromData]load model from data failed, ge result[%u]", ret);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }

  *modelId = id;
  ACL_LOG_INFO(
      "successfully execute ModelLoadFromMemWithMem, modelSize[%zu], workSize[%zu], "
      "weightSize[%zu], modelId[%u]",
      modelSize, loadArgs.mem_size, loadArgs.weight_size, *modelId);
  return ACL_SUCCESS;
}

static aclError IsSupportRuntimeV2WithModelPath(const char *filePath, bool &isSupportRuntimeV2) {
  if (!acl::AclResourceManager::GetInstance().IsRuntimeV2Enable(true)) {
    isSupportRuntimeV2 = false;
    return ACL_SUCCESS;
  }
  const auto ret = gert::IsDynamicModel(filePath, isSupportRuntimeV2);
  if (ret != ge::GRAPH_SUCCESS) {
    ACL_LOG_ERROR("[Check][Model] failed, modelPath is null, or file is invalid, ret[%u].", ret);
    return static_cast<aclError>(ret);
  }
  return ACL_SUCCESS;
}

static aclError GetBundleNumAndOffset(const void *const model, const size_t modelSize, size_t &varSize,
                                      std::vector<std::pair<size_t, size_t>> &subModelOffsetAndSize) {
  varSize = 0U;
  size_t currentOffset = 0U;
  if (modelSize < (sizeof(ge::ModelFileHeader) + sizeof(ge::ModelPartitionTable))) {
    ACL_LOG_ERROR("[Check][Param] Invalid model size, Model data size %zu must be greater than or equal to %zu.",
                  modelSize, sizeof(ge::ModelFileHeader));
    return ACL_ERROR_INVALID_PARAM;
  }
  const auto *fileHeader = ge::PtrToPtr<void, ge::ModelFileHeader>(model);
  if (fileHeader->modeltype != ge::MODEL_TYPE_BUNDLE_MODEL) {
    ACL_LOG_ERROR("this is not bundle om, please check");
    return ACL_ERROR_INVALID_PARAM;
  }
  currentOffset += sizeof(ge::ModelFileHeader);
  const auto *partitionTable =
      ge::PtrToPtr<void, ge::ModelPartitionTable>(ge::ValueToPtr(ge::PtrToValue(model) + currentOffset));
  const size_t partitionTableSize = ge::SizeOfModelPartitionTable(*partitionTable);
  ACL_LOG_INFO("get offset %zu, partitionTableSize %zu", currentOffset, partitionTableSize);
  ACL_REQUIRES_OK(acl::CheckSizeTAddOverflow(currentOffset, partitionTableSize, currentOffset));
  ACL_REQUIRES_LE(currentOffset, modelSize);
  for (size_t i = 0; i < partitionTable->num; ++i) {
    ACL_LOG_INFO("get %zu om offset %zu, size %zu", i, currentOffset, partitionTable->partition[i].mem_size);
    if (partitionTable->partition[i].type == ge::BUNDLE_MODEL_VAR_INFO) {
      varSize = *ge::PtrToPtr<void, int64_t>(ge::ValueToPtr(ge::PtrToValue(model) + currentOffset));
      ACL_LOG_INFO("get var size %zu", varSize);
    }
    if (partitionTable->partition[i].type == ge::BUNDLE_MODEL_INFO) {
      subModelOffsetAndSize.emplace_back(currentOffset, partitionTable->partition[i].mem_size);
    }
    ACL_REQUIRES_OK(acl::CheckSizeTAddOverflow(currentOffset, partitionTable->partition[i].mem_size, currentOffset));
    ACL_REQUIRES_LE(currentOffset, modelSize);
  }
  return ACL_SUCCESS;
}

static aclError IsSupportRuntimeV2WithModelData(const void *const model, const size_t modelSize,
                                                bool &isSupportRuntimeV2) {
  if (!acl::AclResourceManager::GetInstance().IsRuntimeV2Enable(true)) {
    isSupportRuntimeV2 = false;
    return ACL_SUCCESS;
  }
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(model);
  if (modelSize < sizeof(ge::ModelFileHeader)) {
    ACL_LOG_ERROR("[Check][Param] Invalid model size, Model data size %zu must be greater than or equal to %zu.",
                  modelSize, sizeof(ge::ModelFileHeader));
    return ACL_ERROR_INVALID_PARAM;
  }
  const auto *fileHeader = reinterpret_cast<const ge::ModelFileHeader *>(model);
  constexpr uint32_t kStaticOmFileModelNum = 1U;
  constexpr uint8_t kDynamicOmFlag = 1U;
  isSupportRuntimeV2 =
      ((fileHeader->version >= ge::MODEL_VERSION) &&
       ((fileHeader->model_num > kStaticOmFileModelNum) || (fileHeader->is_unknow_model == kDynamicOmFlag)));
  return ACL_SUCCESS;
}

static aclError CheckIsRuntimeV2WithConfig(const aclmdlConfigHandle *handle, const char *filePath,
                                           const void *const model, const size_t modelSize, bool &isSupportRuntimeV2) {
  if (filePath != nullptr) {
    ACL_REQUIRES_OK(IsSupportRuntimeV2WithModelPath(filePath, isSupportRuntimeV2));
  } else {
    ACL_REQUIRES_OK(IsSupportRuntimeV2WithModelData(model, modelSize, isSupportRuntimeV2));
  }
  if (isSupportRuntimeV2) {
    ACL_REQUIRES_NOT_NULL(handle);
    if (handle->attrState.find(ACL_MDL_WITHOUT_GRAPH_INT32) != handle->attrState.end()) {
      ACL_LOG_ERROR("ACL_MDL_WITHOUT_GRAPH_INT32 cannot be configured when model is dynamic");
      const std::string errMsg = "ACL_MDL_WITHOUT_GRAPH_INT32 cannot be configured when model is dynamic";
      acl::AclErrorLogManager::ReportInputError(
          acl::INVALID_PARAM_MSG, std::vector<const char *>({"param", "value", "reason"}),
          std::vector<const char *>({"aclmdlConfigHandle", "ACL_MDL_WITHOUT_GRAPH_INT32", errMsg.c_str()}));
      return ACL_ERROR_INVALID_PARAM;
    }
  }
  return ACL_SUCCESS;
}

aclError DetectModelTypeInLoadWithConfig(const aclmdlConfigHandle *handle, const char *filePath, const void *model,
                                         const size_t modelSize, bool &isSupportRT2) {
  if (filePath != nullptr) {
    ACL_REQUIRES_OK(CheckIsRuntimeV2WithConfig(handle, filePath, nullptr, 0, isSupportRT2));
  } else {
    ACL_REQUIRES_OK(CheckIsRuntimeV2WithConfig(handle, nullptr, model, modelSize, isSupportRT2));
  }
  return ACL_SUCCESS;
}

static aclError RuntimeV2ModelLoadFromMemWithMem(const void *const model, const size_t modelSize,
                                                 const std::string &modelPath, uint32_t *const modelId,
                                                 void *const weightPtr, const size_t weightSize,
                                                 const char_t *const weightPath, const int32_t priority,
                                                 std::vector<ge::FileConstantMem> file_constant_mems = {},
                                                 const std::shared_ptr<gert::RtSession> &rtSessionExternal = nullptr) {
  ACL_LOG_INFO("start to execute RuntimeV2ModelLoadFromMemWithMem, modelSize[%zu], priority[%d], weightSize[%zu]",
               modelSize, priority, weightSize);
  ACL_CHECK_WITH_INNER_MESSAGE_AND_RETURN(modelSize != 0U, ACL_ERROR_INVALID_PARAM,
                                          "[Check][ModelSize]modelSize[%zu] is invalid, should not be zero", modelSize);
  // 1. config model data
  ge::ModelData modelData;
  modelData.model_data = const_cast<void *>(model);
  modelData.model_len = static_cast<uint64_t>(modelSize);
  modelData.priority = priority;
  modelData.om_path = modelPath;
  if (weightPath != nullptr) {
    modelData.weight_path = std::string(weightPath);
    ACL_LOG_INFO("Load weight path is [%s]", modelData.weight_path.c_str());
  }

  // 2. get executorV2
  ACL_REQUIRES_OK(RuntimeV2ModelLoadCommon(modelData, modelId, weightPtr, weightSize, std::move(file_constant_mems),
                                           rtSessionExternal));
  ACL_LOG_INFO("successfully execute RuntimeV2ModelLoadFromMemWithMem, modelSize[%zu], modelId[%u], weightSize[%zu]",
               modelSize, *modelId, weightSize);
  return ACL_SUCCESS;
}

static aclError ModelLoadFromFileWithQ(const char_t *const modelPath, uint32_t *const modelId,
                                       const ge::ModelQueueArg &args, const int32_t priority) {
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelPath);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelId);
  ACL_LOG_INFO(
      "start to execute ModelLoadFromFileWithQ, modelPath[%s], inputQNum[%zu], "
      "outputQNum[%zu], priority[%d]",
      modelPath, args.input_queue_ids.size(), args.output_queue_ids.size(), priority);

  ge::GeExecutor geExecutor;
  uint32_t id = 0U;
  ge::ModelData modelData;
  const std::string path(modelPath);
  ACL_LOG_INFO("call ge interface executor.LoadDataFromFile");
  ge::Status ret = geExecutor.LoadDataFromFile(path, modelData);
  if (ret != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("[Load][FromFile]load model from file[%s], ge result[%u], failed", modelPath, ret);
    ACL_DELETE_ARRAY(modelData.model_data);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }
  modelData.priority = priority;

  ACL_LOG_INFO("call ge interface executor.LoadModelWithQ");
  ret = geExecutor.LoadModelWithQ(id, modelData, args);
  if (ret != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("[Load][WithQ]execute LoadModelWithQ failed, ge result[%u]", ret);
    ACL_DELETE_ARRAY(modelData.model_data);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }

  *modelId = id;
  ACL_DELETE_ARRAY(modelData.model_data);
  ACL_LOG_INFO(
      "successfully execute ModelLoadFromFileWithQ, modelPath[%s], inputQNum[%zu], outputQNum[%zu], "
      "modelId[%u]",
      modelPath, args.input_queue_ids.size(), args.output_queue_ids.size(), *modelId);
  return ACL_SUCCESS;
}

static aclError ModelLoadFromMemWithQ(const void *const model, const size_t modelSize, uint32_t *const modelId,
                                      const ge::ModelQueueArg &args, const int32_t priority) {
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(model);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelId);
  ACL_LOG_INFO(
      "start to execute ModelLoadFromMemWithQ, modelSize[%zu], inputQNum[%zu], outputQNum[%zu], "
      "priority[%d]",
      modelSize, args.input_queue_ids.size(), args.output_queue_ids.size(), priority);

  if (modelSize == 0U) {
    ACL_LOG_INNER_ERROR(
        "[Check][Params]modelSize[%zu] is invalid, "
        "can't be zero",
        modelSize);
    return ACL_ERROR_INVALID_PARAM;
  }

  ge::GeExecutor executor;
  uint32_t id = 0U;
  ge::ModelData data;

  data.model_data = const_cast<void *>(model);
  data.model_len = static_cast<uint64_t>(modelSize);
  data.priority = priority;

  ACL_LOG_INFO("call ge interface executor.LoadModelWithQ, modelSize[%zu]", modelSize);
  const ge::Status ret = executor.LoadModelWithQ(id, data, args);
  if (ret != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("[Load][WithQ]load model with Q, ge result[%u], failed", ret);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }

  *modelId = id;
  ACL_LOG_INFO(
      "successfully execute ModelLoadFromMemWithQ, modelSize[%zu], inputQNum[%zu], outputQNum[%zu], "
      "modelId[%u]",
      modelSize, args.input_queue_ids.size(), args.output_queue_ids.size(), *modelId);

  return ACL_SUCCESS;
}

static void SetInputData(const std::vector<AclModelTensor> &blobs, std::vector<ge::GeTensorDesc> &inputGeDesc,
                         bool &isDynamic) {
  for (size_t i = 0U; i < blobs.size(); ++i) {
    if (blobs[i].tensorDesc != nullptr) {
      isDynamic = true;
      break;
    }
  }
  if (isDynamic) {
    for (size_t i = 0U; i < blobs.size(); ++i) {
      if (blobs[i].tensorDesc != nullptr) {
        std::vector<int64_t> dims;
        ConvertSvecToVec(blobs[i].tensorDesc->dims, dims);
        const ge::GeShape shape(dims);
        ge::GeTensorDesc geTensorDescTmp(shape);
        geTensorDescTmp.SetOriginShape(shape);
        inputGeDesc.push_back(geTensorDescTmp);
      } else {
        const ge::GeTensorDesc geTensorDescTmp;
        inputGeDesc.push_back(geTensorDescTmp);
      }
    }
  }
  return;
}

static void WrapGeShape(gert::Shape &geShape,
                        const ge::SmallVector<int64_t, static_cast<size_t>(ge::kDefaultMaxInputNum)> &dims) {
  geShape.SetDimNum(dims.size());
  for (size_t i = 0U; i < dims.size(); ++i) {
    (void)geShape.SetDim(i, dims[i]);
  }
}

static void SetInputData(const std::vector<AclModelTensor> &blobs, std::vector<gert::Tensor> &inputTensor) {
  for (size_t i = 0U; i < inputTensor.size(); ++i) {
    if (blobs[i].tensorDesc != nullptr) {
      WrapGeShape(inputTensor[i].MutableOriginShape(), blobs[i].tensorDesc->dims);
      WrapGeShape(inputTensor[i].MutableStorageShape(), blobs[i].tensorDesc->dims);
    }
  }
  return;
}

// runtime2.0 execute
static aclError RuntimeV2ModelExecute(const uint32_t modelId, const aclmdlDataset *const input,
                                      aclmdlDataset *const output, const bool isAsync, const aclrtStream stream) {
  ACL_LOG_INFO("start to execute ModelExecute, modelId[%u]", modelId);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(input);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(output);

  auto const executor = acl::AclResourceManager::GetInstance().GetExecutor(modelId);
  if (executor == nullptr) {
    ACL_LOG_ERROR("input modelId[%u] is invalid, please make sure model has been loaed", modelId);
    return static_cast<aclError>(ACL_ERROR_GE_EXEC_MODEL_ID_INVALID);
  }

  const gert::ModelDesc &desc = executor->GetModelDesc();
  const size_t inputNum = desc.GetInputNum();
  ACL_LOG_INFO("get model input num %zu, input num %zu", inputNum, input->blobs.size());
  if (input->blobs.size() < inputNum) {
    ACL_LOG_ERROR("input blobs %zu cannot be smaller than input desc size %zu", input->blobs.size(), inputNum);
    return static_cast<aclError>(ACL_ERROR_INVALID_PARAM);
  }

  std::vector<gert::Tensor> inputTensor(inputNum);
  std::vector<gert::Tensor> outputTensor(output->blobs.size());
  std::vector<gert::Tensor *> inputVec(inputNum);
  std::vector<gert::Tensor *> outputVec(output->blobs.size());
  for (size_t i = 0UL; i < inputNum; ++i) {
    const auto dataBuffer = input->blobs[i].dataBuf;
    if (dataBuffer == nullptr) {
      ACL_LOG_ERROR(
          "[Check][dataBuffer]input dataset blobs is null, "
          "modelId[%d], index[%zu]",
          modelId, i);
      acl::AclErrorLogManager::ReportInputError(acl::INVALID_NULL_POINTER_MSG, std::vector<const char *>({"param"}),
                                                std::vector<const char *>({"dataBuffer"}));
      return ACL_ERROR_INVALID_PARAM;
    }
    inputTensor[i].MutableTensorData().SetPlacement(gert::kOnDeviceHbm);
    (void)inputTensor[i].MutableTensorData().SetAddr(dataBuffer->data, nullptr);
    inputTensor[i].MutableTensorData().SetSize(dataBuffer->length);
    inputTensor[i].MutableOriginShape() = desc.GetInputDesc(i)->GetOriginShape();
    inputTensor[i].MutableStorageShape() = desc.GetInputDesc(i)->GetStorageShape();
    inputVec[i] = &(inputTensor[i]);
  }

  SetInputData(input->blobs, inputTensor);
  ge::InputAippType type = ge::DATA_WITHOUT_AIPP;
  size_t aippIndex = 0U;
  for (size_t i = 0UL; i < inputNum; ++i) {
    (void)executor->GetAippType(static_cast<uint32_t>(i), type, aippIndex);
    if (type == ge::DATA_WITH_DYNAMIC_AIPP) {
      // dynamic aipp input no need to check range for compatibility
      continue;
    }
    if (!desc.GetInputDesc(i)->IsOriginShapeInRange(inputTensor[i].GetOriginShape())) {
      ACL_LOG_ERROR("[Check][InputShape] Input [%zu] shape out of shape range.", i);
      return ACL_ERROR_INVALID_PARAM;
    }
  }

  for (size_t i = 0UL; i < output->blobs.size(); ++i) {
    const auto dataBuffer = output->blobs[i].dataBuf;
    if (dataBuffer == nullptr) {
      ACL_LOG_ERROR("[Check][Databuffer]output dataset blobs is null, modelId[%d], index[%zu]", modelId, i);
      acl::AclErrorLogManager::ReportInputError(acl::INVALID_NULL_POINTER_MSG, std::vector<const char *>({"param"}),
                                                std::vector<const char *>({"dataBuffer"}));
      return ACL_ERROR_INVALID_PARAM;
    }
    if ((dataBuffer->data == nullptr) && (!isAsync)) {
      const size_t memSize = static_cast<size_t>(desc.GetOutputDesc(i)->GetSize());
      if (memSize > 0UL) {
        ACL_REQUIRES_CALL_RTS_OK(
            aclrtMalloc(reinterpret_cast<void **>(&dataBuffer->data), memSize, ACL_MEM_TYPE_HIGH_BAND_WIDTH),
            aclrtMalloc);
        dataBuffer->length = memSize;
        ACL_LOG_DEBUG(
            "ModelExecute, assign acl-malloced output addr to user-defined buffer, addr:[%p], "
            "len:[%lu]",
            dataBuffer->data, dataBuffer->length);
      }
    }

    outputTensor[i].MutableTensorData().SetPlacement(gert::kOnDeviceHbm);
    (void)outputTensor[i].MutableTensorData().SetAddr(dataBuffer->data, nullptr);
    outputTensor[i].MutableTensorData().SetSize(dataBuffer->length);
    outputVec[i] = &(outputTensor[i]);
  }

  ge::Status ret = ge::GRAPH_SUCCESS;
  const auto index_id = executor->GetIterationNum();
  MsprofEvent event{};
  CANN_PROFILING_EVENT_START(modelId, index_id, gert::GeProfInfoType::kModelExecute, event);
  CANN_PROFILING_STEP_TRACE(modelId, index_id, kStartTag, stream);
  if (isAsync) {
    gert::ModelExecuteArg arg;
    arg.stream = stream;
    arg.external_allocator = acl::AclResourceManager::GetInstance().GetAllocators(arg.stream, false).get();
    ret = executor->Execute(arg, inputVec.data(), inputTensor.size(), outputVec.data(), outputTensor.size());
  } else {
    ret = executor->ExecuteSync(inputVec.data(), inputTensor.size(), outputVec.data(), outputTensor.size());
  }
  CANN_PROFILING_STEP_TRACE(modelId, index_id, kEndTag, stream);
  CANN_PROFILING_EVENT_END(modelId, index_id, gert::GeProfInfoType::kModelExecute, event);
  if (ret != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("[Exec][Model]Execute model failed, ge result[%u], modelId[%u]", ret, modelId);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }
  for (size_t i = 0UL; i < output->blobs.size(); ++i) {
    if (output->blobs[i].tensorDesc != nullptr) {
      aclDestroyTensorDescImplOm2(output->blobs[i].tensorDesc);
    }
    output->blobs[i].tensorDesc = aclCreateTensorDescImplOm2(ACL_DT_UNDEFINED, 0, nullptr, ACL_FORMAT_UNDEFINED);
  }

  for (size_t i = 0UL; i < outputTensor.size(); ++i) {
    if (output->blobs[i].tensorDesc != nullptr) {
      output->blobs[i].tensorDesc->dims.clear();
      const ge::Format format = outputTensor[i].GetFormat().GetStorageFormat();
      const ge::DataType dataType = outputTensor[i].GetDataType();
      for (size_t idx = 0U; idx < outputTensor[i].MutableStorageShape().GetDimNum(); ++idx) {
        output->blobs[i].tensorDesc->dims.push_back(outputTensor[i].MutableStorageShape().GetDim(idx));
      }
      if (format != ge::FORMAT_RESERVED) {
        output->blobs[i].tensorDesc->format = static_cast<aclFormat>(format);
      }
      if (dataType != ge::DT_UNDEFINED) {
        output->blobs[i].tensorDesc->dataType = static_cast<aclDataType>(dataType);
      }
    }

    auto &dataBuffer = output->blobs[i].dataBuf;
    if ((dataBuffer->data == nullptr) && (!isAsync)) {
      ACL_REQUIRES_NOT_NULL(outputTensor[i].MutableTensorData().GetAddr());
      const auto outputSize = outputTensor[i].MutableTensorData().GetSize();
      ACL_REQUIRES_CALL_RTS_OK(
          aclrtMalloc(reinterpret_cast<void **>(&dataBuffer->data), outputSize, ACL_MEM_TYPE_HIGH_BAND_WIDTH),
          aclrtMalloc);
      ACL_REQUIRES_CALL_RTS_OK(aclrtMemcpy(dataBuffer->data, outputSize, outputTensor[i].MutableTensorData().GetAddr(),
                                           outputSize, ACL_MEMCPY_DEVICE_TO_DEVICE),
                               aclrtMemcpy);
      dataBuffer->length = outputSize;
      ACL_LOG_DEBUG("ModelExecute, assign acl-malloced output addr to user-defined buffer, addr:[%p], len:[%lu]",
                    dataBuffer->data, dataBuffer->length);
    }
  }

  ACL_LOG_INFO("successfully execute ModelExecute, modelId[%u]", modelId);
  return ACL_SUCCESS;
}

static aclError ModelExecute(const uint32_t modelId, const aclmdlDataset *const input, aclmdlDataset *const output,
                             const bool basync, const aclrtStream stream) {
  ACL_LOG_INFO("start to execute ModelExecute, modelId[%u]", modelId);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(input);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(output);

  ge::RunModelData inputData;
  inputData.timeout = 0U;
  inputData.timestamp = 0U;
  inputData.index = 0U;
  inputData.modelId = modelId;

  inputData.dynamic_batch_size = input->dynamicBatchSize;
  inputData.dynamic_image_height = input->dynamicResolutionHeight;
  inputData.dynamic_image_width = input->dynamicResolutionWidth;
  inputData.dynamic_dims = input->dynamicDims;
  ACL_LOG_DEBUG("ModelExecute dynamic param: batch_size[%lu], height[%lu], width[%lu], dim_num[%zu]",
                input->dynamicBatchSize, input->dynamicResolutionHeight, input->dynamicResolutionWidth,
                input->dynamicDims.size());
  inputData.blobs.resize(input->blobs.size());
  for (size_t i = 0UL; i < input->blobs.size(); ++i) {
    ge::DataBuffer &inputBuffer = inputData.blobs[i];
    const auto dataBuffer = input->blobs[i].dataBuf;
    if (dataBuffer == nullptr) {
      ACL_LOG_ERROR(
          "[Check][dataBuffer]input dataset blobs is null, "
          "modelId[%d], index[%zu]",
          modelId, i);
      acl::AclErrorLogManager::ReportInputError(acl::INVALID_NULL_POINTER_MSG, std::vector<const char *>({"param"}),
                                                std::vector<const char *>({"dataBuffer"}));
      return ACL_ERROR_INVALID_PARAM;
    }
    inputBuffer.data = dataBuffer->data;
    inputBuffer.length = dataBuffer->length;
    inputBuffer.isDataSupportMemShare = false;
    inputBuffer.placement = ge::Placement::kPlacementDevice;
  }

  std::vector<ge::GeTensorDesc> inputGeDesc;
  bool dynamicFlag = false;
  SetInputData(input->blobs, inputGeDesc, dynamicFlag);

  ge::RunModelData outputData;
  outputData.modelId = modelId;

  std::vector<size_t> needMallocIndexes;
  outputData.blobs.resize(output->blobs.size());
  for (size_t i = 0UL; i < output->blobs.size(); ++i) {
    ge::DataBuffer &outputBuffer = outputData.blobs[i];
    const auto dataBuffer = output->blobs[i].dataBuf;
    if (dataBuffer == nullptr) {
      ACL_LOG_ERROR("[Check][Databuffer]output dataset blobs is null, modelId[%d], index[%zu]", modelId, i);
      acl::AclErrorLogManager::ReportInputError(acl::INVALID_NULL_POINTER_MSG, std::vector<const char *>({"param"}),
                                                std::vector<const char *>({"dataBuffer"}));
      return ACL_ERROR_INVALID_PARAM;
    }
    if (dataBuffer->data == nullptr) {
      needMallocIndexes.push_back(i);
    }
    outputBuffer.data = dataBuffer->data;
    outputBuffer.length = dataBuffer->length;
    outputBuffer.isDataSupportMemShare = false;
    outputBuffer.placement = ge::Placement::kPlacementDevice;
  }

  ge::GeExecutor executor;
  if ((!needMallocIndexes.empty()) && (!basync)) {
    std::vector<ge::TensorDesc> inputDesc;
    std::vector<ge::TensorDesc> outputDesc;
    (void)executor.GetModelDescInfo(modelId, inputDesc, outputDesc);
    if (outputDesc.size() < output->blobs.size()) {
      ACL_LOG_ERROR("[Check][OutputDesc] outputDesc size [%zu] mismatch with blobs size[%zu].", outputDesc.size(),
                    output->blobs.size());
      return ACL_ERROR_INVALID_PARAM;
    }

    for (auto &idx : needMallocIndexes) {
      auto &dataBuffer = output->blobs[idx].dataBuf;
      const size_t outputSize = static_cast<size_t>(outputDesc[idx].GetSize());
      if (outputSize > 0UL) {
        ACL_REQUIRES_CALL_RTS_OK(
            aclrtMalloc(reinterpret_cast<void **>(&dataBuffer->data), outputSize, ACL_MEM_TYPE_HIGH_BAND_WIDTH),
            aclrtMalloc);
        dataBuffer->length = outputSize;
        outputData.blobs[idx].data = dataBuffer->data;
        outputData.blobs[idx].length = outputSize;
        ACL_LOG_DEBUG(
            "ModelExecute, assign acl-malloced output addr to user-defined buffer, addr:[%p], "
            "len:[%lu]",
            dataBuffer->data, dataBuffer->length);
      }
    }
  }

  ACL_LOG_INFO("call ge interface executor.ExecModel, modelId[%u], asyncMode[%d]", modelId,
               static_cast<int32_t>(basync));
  std::vector<ge::GeTensorDesc> outputGeDesc;
  const ge::Status ret = executor.ExecModel(modelId, stream, inputData, inputGeDesc, outputData, outputGeDesc, basync);
  if (ret != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("[Exec][Model]Execute model failed, ge result[%u], modelId[%u]", ret, modelId);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }

  if (dynamicFlag) {
    for (size_t i = 0U; i < output->blobs.size(); ++i) {
      if (output->blobs[i].tensorDesc != nullptr) {
        aclDestroyTensorDescImplOm2(output->blobs[i].tensorDesc);
      }
      output->blobs[i].tensorDesc = aclCreateTensorDescImplOm2(ACL_DT_UNDEFINED, 0, nullptr, ACL_FORMAT_UNDEFINED);
    }
  }
  ACL_REQUIRES_LE(outputGeDesc.size(), output->blobs.size());
  for (size_t i = 0UL; i < outputGeDesc.size(); ++i) {
    if (output->blobs[i].tensorDesc != nullptr) {
      output->blobs[i].tensorDesc->dims.clear();
      const std::vector<int64_t> dims = outputGeDesc[i].GetShape().GetDims();
      const ge::Format format = outputGeDesc[i].GetFormat();
      const ge::DataType dataType = outputGeDesc[i].GetDataType();
      for (const auto &dim : dims) {
        output->blobs[i].tensorDesc->dims.push_back(dim);
      }
      if (format != ge::FORMAT_RESERVED) {
        output->blobs[i].tensorDesc->format = static_cast<aclFormat>(format);
      }
      if (dataType != ge::DT_UNDEFINED) {
        output->blobs[i].tensorDesc->dataType = static_cast<aclDataType>(dataType);
      }
    }

    auto &dataBuffer = output->blobs[i].dataBuf;
    if ((dataBuffer->data == nullptr) && (!basync)) {
      const auto outputSize = outputData.blobs[i].length;
      ACL_REQUIRES_CALL_RTS_OK(
          aclrtMalloc(reinterpret_cast<void **>(&dataBuffer->data), outputSize, ACL_MEM_TYPE_HIGH_BAND_WIDTH),
          aclrtMalloc);
      ACL_REQUIRES_CALL_RTS_OK(
          aclrtMemcpy(dataBuffer->data, outputSize, outputData.blobs[i].data, outputSize, ACL_MEMCPY_DEVICE_TO_DEVICE),
          aclrtMemcpy);
      dataBuffer->length = outputSize;
      ACL_LOG_DEBUG(
          "ModelExecute, assign acl-malloced output addr to user-defined buffer, addr:[%p], "
          "len:[%lu]",
          dataBuffer->data, dataBuffer->length);
    }
  }

  ACL_LOG_INFO("successfully execute ModelExecute, modelId[%u]", modelId);
  return ACL_SUCCESS;
}

static void UpdateGraphOptions(const std::string &key, const std::string &value) {
  auto options = ge::GetThreadLocalContext().GetAllGraphOptions();
  options[key] = value;
  ge::GetThreadLocalContext().SetGraphOption(options);
}

static void GetTensorInfo(std::vector<aclmdlTensorDesc> &inputDesc, const gert::ModelIoDesc *const inputs,
                          size_t &inputNum) {
  for (size_t i = 0U; i < inputNum; ++i) {
    aclmdlTensorDesc tensorDesc;
    const auto tempPtr = inputs + i;
    tensorDesc.size = static_cast<size_t>(tempPtr->GetSize());
    std::string inputStr;
    const char_t *const inputName = tempPtr->GetName();
    if (inputName != nullptr) {
      inputStr = std::string(inputName);
    }
    tensorDesc.name = inputStr;
    tensorDesc.format = static_cast<aclFormat>(tempPtr->GetOriginFormat());
    tensorDesc.dataType = static_cast<aclDataType>(tempPtr->GetDataType());
    const gert::Shape &shape = tempPtr->GetOriginShape();
    for (size_t j = 0U; j < shape.GetDimNum(); ++j) {
      tensorDesc.dims.emplace_back(shape.GetDim(j));
    }
    const auto &shapeRangeVector = tempPtr->GetOriginShapeRangeVector();
    (void)tensorDesc.shapeRanges.insert(tensorDesc.shapeRanges.cend(), shapeRangeVector.cbegin(),
                                        shapeRangeVector.cend());
    const gert::Shape &aippShapeV2 = tempPtr->GetAippShape();
    for (size_t j = 0U; j < aippShapeV2.GetDimNum(); ++j) {
      tensorDesc.dimsV2.emplace_back(aippShapeV2.GetDim(j));
    }
    inputDesc.push_back(tensorDesc);
  }
}

static aclError RuntimeV2GetDesc(aclmdlDesc *const modelDesc, const uint32_t modelId) {
  const auto executor = acl::AclResourceManager::GetInstance().GetExecutor(modelId);
  if (executor == nullptr) {
    ACL_LOG_ERROR("input modelId[%u] is invalid while get executor", modelId);
    return static_cast<aclError>(ACL_ERROR_GE_EXEC_MODEL_ID_INVALID);
  }
  const auto &geModelDesc = executor->GetModelDesc();
  size_t inputNum = 0U;
  size_t outputNum = 0U;
  const gert::ModelIoDesc *const inputs = geModelDesc.GetAllInputsDesc(inputNum);
  GetTensorInfo(modelDesc->inputDesc, inputs, inputNum);
  const gert::ModelIoDesc *const outputs = geModelDesc.GetAllOutputsDesc(outputNum);
  GetTensorInfo(modelDesc->outputDesc, outputs, outputNum);

  modelDesc->modelId = modelId;
  aclError retVal = acl::RuntimeV2GetDynamicTensorInfo(modelDesc, geModelDesc);
  if (retVal != ACL_SUCCESS) {
    ACL_LOG_INNER_ERROR("[Get][DynamicTensorInfo]get model dynamic info failed, result[%d], model id[%u]", retVal,
                        modelId);
    return retVal;
  }

  retVal = acl::RuntimeV2GetModelOutputShapeInfo(modelDesc, geModelDesc);
  if (retVal != ACL_SUCCESS) {
    ACL_LOG_INNER_ERROR("[Get][ModelOutputShapeInfo]get model output shape info failed, result[%d], model id[%u]",
                        retVal, modelId);
    return retVal;
  }

  ACL_LOG_INFO("successfully execute aclmdlGetDesc, model id[%u]", modelId);
  return ACL_SUCCESS;
}
}  // namespace acl

aclError aclmdlGetDescImpl(aclmdlDesc *modelDesc, uint32_t modelId) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlGetDesc);
  ACL_LOG_INFO("start to execute aclmdlGetDesc, model id[%u]", modelId);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelDesc);
  modelDesc->Clear();
  if ((acl::AclResourceManager::GetInstance().IsRuntimeV2Enable(true)) &&
      (acl::AclResourceManager::GetInstance().GetExecutor(modelId) != nullptr)) {
    return acl::RuntimeV2GetDesc(modelDesc, modelId);
  }

  std::vector<ge::TensorDesc> inputDesc;
  std::vector<ge::TensorDesc> outputDesc;
  std::vector<ge::TensorDesc> inputDescV2;
  std::vector<ge::TensorDesc> outputDescV2;
  {
    ge::GeExecutor executor;
    ge::Status ret = executor.GetModelDescInfo(modelId, inputDesc, outputDesc);
    if (ret != ge::SUCCESS) {
      ACL_LOG_CALL_ERROR("[Get][ModelDescInfo]get model description failed, ge result[%u], model id[%u]", ret, modelId);
      return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }

    ret = executor.GetModelDescInfo(modelId, inputDescV2, outputDescV2, true);
    if (ret != ge::SUCCESS) {
      ACL_LOG_CALL_ERROR("[Get][ModelDescInfo]get model description v2 failed, ge result[%u], model id[%u]", ret,
                         modelId);
      return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }
  }

  if ((inputDescV2.size() < inputDesc.size()) || (outputDescV2.size() < outputDesc.size())) {
    ACL_LOG_CALL_ERROR("[Get][ModelDescInfo]description v2 size less than description v1 size, model id[%u]", modelId);
    return ACL_ERROR_FAILURE;
  }

  for (size_t i = 0U; i < inputDesc.size(); ++i) {
    ge::AscendString inputName;
    aclmdlTensorDesc tensorDesc;
    tensorDesc.size = static_cast<size_t>(inputDesc[i].GetSize());
    const ge::graphStatus retStatus = inputDesc[i].GetName(inputName);
    if (retStatus != ge::GRAPH_SUCCESS) {
      ACL_LOG_CALL_ERROR("[Get][TensorName]the %zu input tensor GetName failed.", i);
      return ACL_GET_ERRCODE_GE(static_cast<int32_t>(retStatus));
    }
    std::string inputStr;
    if (inputName.GetString() != nullptr) {
      inputStr = std::string(inputName.GetString());
    }
    tensorDesc.name = inputStr;
    tensorDesc.format = static_cast<aclFormat>(inputDesc[i].GetFormat());
    tensorDesc.dataType = static_cast<aclDataType>(inputDesc[i].GetDataType());
    const ge::Shape shape = inputDesc[i].GetShape();
    tensorDesc.dims = shape.GetDims();
    const ge::Shape shapeV2 = inputDescV2[i].GetShape();
    tensorDesc.dimsV2 = shapeV2.GetDims();
    (void)inputDesc[i].GetShapeRange(tensorDesc.shapeRanges);
    modelDesc->inputDesc.push_back(tensorDesc);
  }

  for (size_t i = 0U; i < outputDesc.size(); ++i) {
    ge::AscendString outputName;
    aclmdlTensorDesc tensorDesc;
    tensorDesc.size = static_cast<size_t>(outputDesc[i].GetSize());
    const ge::graphStatus retStatus = outputDesc[i].GetName(outputName);
    if (retStatus != ge::GRAPH_SUCCESS) {
      ACL_LOG_CALL_ERROR("[Get][TensorName]the %zu output tensor GetName failed.", i);
      return ACL_GET_ERRCODE_GE(static_cast<int32_t>(retStatus));
    }
    std::string outputStr;
    if (outputName.GetString() != nullptr) {
      outputStr = std::string(outputName.GetString());
    }
    tensorDesc.name = outputStr;
    tensorDesc.format = static_cast<aclFormat>(outputDesc[i].GetFormat());
    tensorDesc.dataType = static_cast<aclDataType>(outputDesc[i].GetDataType());
    const ge::Shape shape = outputDesc[i].GetShape();
    tensorDesc.dims = shape.GetDims();
    const ge::Shape shapeV2 = outputDescV2[i].GetShape();
    tensorDesc.dimsV2 = shapeV2.GetDims();
    (void)outputDesc[i].GetShapeRange(tensorDesc.shapeRanges);
    modelDesc->outputDesc.push_back(tensorDesc);
  }

  modelDesc->modelId = modelId;
  aclError retVal = acl::GetDynamicTensorInfo(modelDesc);
  if (retVal != ACL_SUCCESS) {
    ACL_LOG_INNER_ERROR("[Get][DynamicTensorInfo]get model dynamic info failed, result[%d], model id[%u]", retVal,
                        modelId);
    return retVal;
  }

  retVal = acl::GetModelOutputShapeInfo(modelDesc);
  if (retVal != ACL_SUCCESS) {
    ACL_LOG_INNER_ERROR("[Get][ModelOutputShapeInfo]get model output shape info failed, result[%d], model id[%u]",
                        retVal, modelId);
    return retVal;
  }

  ACL_LOG_INFO("successfully execute aclmdlGetDesc, model id[%u]", modelId);
  return ACL_SUCCESS;
}

static void GetModelTensorDesc(const ge::ModelInOutInfo &info, aclmdlDesc *modelDesc, bool isInput) {
  const auto &descs = isInput ? info.input_desc : info.output_desc;
  for (const auto &desc : descs) {
    aclmdlTensorDesc tmpDesc;
    tmpDesc.name = desc.name;
    tmpDesc.size = desc.size;
    tmpDesc.format = (desc.format != ge::FORMAT_RESERVED) ? static_cast<aclFormat>(desc.format) : ACL_FORMAT_UNDEFINED;
    tmpDesc.dataType = (desc.dataType != ge::DT_UNDEFINED) ? static_cast<aclDataType>(desc.dataType) : ACL_DT_UNDEFINED;
    tmpDesc.dims = desc.dims;
    tmpDesc.dimsV2 = desc.dimsV2;
    tmpDesc.shapeRanges = desc.shape_ranges;
    if (isInput) {
      modelDesc->inputDesc.emplace_back(tmpDesc);
    } else {
      modelDesc->outputDesc.emplace_back(tmpDesc);
    }
  }
}

static aclError GetDescFromMem(const ge::ModelData &modelData, const ge::GeExecutor &executor, aclmdlDesc *modelDesc) {
  ACL_LOG_INFO("call ge interface GetModelDescInfoFromMem");
  ge::ModelInOutInfo info;
  const auto ret = executor.GetModelDescInfoFromMem(modelData, info);
  if (ret != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("GetModelDescInfoFromMem failed");
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }
  GetModelTensorDesc(info, modelDesc, true);
  GetModelTensorDesc(info, modelDesc, false);
  modelDesc->dynamicBatch = info.dynamic_batch;
  modelDesc->dynamicHW = info.dynamic_hw;
  modelDesc->dynamicDims = info.dynamic_dims;
  ACL_REQUIRES_OK(acl::GetModelOutputShapeInfoHelp(modelDesc, info.dynamic_output_shape));
  modelDesc->dataNameOrder = info.data_name_order;
  return ACL_SUCCESS;
}

aclError aclmdlGetDescFromFileImpl(aclmdlDesc *modelDesc, const char *modelPath) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlGetDesc);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelDesc);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelPath);
  ACL_LOG_INFO("start to execute aclmdlGetDescFromFile, path is %s", modelPath);
  modelDesc->Clear();

  ge::GeExecutor executor;
  ge::ModelData data;
  ACL_LOG_INFO("call ge interface executor.LoadDataFromFile, path is %s", modelPath);
  const ge::Status ret = executor.LoadDataFromFile(modelPath, data);
  std::shared_ptr<void> dataAuto;
  dataAuto.reset(data.model_data, [](const void *const p) { delete[] static_cast<const uint8_t *>(p); });
  if (ret != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("[Model][FromFile]load model from file[%s] failed, ge result[%u]", modelPath, ret);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }
  ACL_REQUIRES_OK(GetDescFromMem(data, executor, modelDesc));
  ACL_LOG_INFO("end to execute aclmdlGetDescFromFile, path is %s", modelPath);
  return ACL_SUCCESS;
}

aclError aclmdlGetDescFromMemImpl(aclmdlDesc *modelDesc, const void *model, size_t modelSize) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlGetDesc);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelDesc);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(model);
  ACL_REQUIRES_POSITIVE_WITH_INPUT_REPORT(modelSize);
  ACL_LOG_INFO("start to execute aclmdlGetDescFromMem, modelSize is %zu", modelSize);
  modelDesc->Clear();

  // Existing non-OM2 logic
  ge::GeExecutor executor;
  ge::ModelData modelData;
  modelData.model_data = const_cast<void *>(model);
  modelData.model_len = static_cast<uint64_t>(modelSize);
  ACL_REQUIRES_OK(GetDescFromMem(modelData, executor, modelDesc));
  ACL_LOG_INFO("end to execute aclmdlGetDescFromMem, modelSize is %zu", modelSize);
  return ACL_SUCCESS;
}

static aclError UnloadRt2Model(const uint32_t modelId, const bool isSessionShared) {
  const auto executor = acl::AclResourceManager::GetInstance().GetExecutor(modelId);
  ge::graphStatus ret = ge::GRAPH_SUCCESS;
  if (executor != nullptr) {
    ret = executor->UnLoad();
  } else {
    ACL_LOG_ERROR("modelId[%u] is invalid", modelId);
    return static_cast<aclError>(ACL_ERROR_GE_EXEC_MODEL_ID_INVALID);
  }
  if (ret != ge::GRAPH_SUCCESS) {
    ACL_LOG_CALL_ERROR("[Unload][Model]failed to unload model, modelId is %u, errorCode is %u", modelId, ret);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }
  auto session = acl::AclResourceManager::GetInstance().GetRtSession(modelId);
  // cannot destroy shared session
  if ((session != nullptr) && !isSessionShared) {
    session->DestroyResources();
  }
  return acl::AclResourceManager::GetInstance().DeleteExecutor(modelId);
}

static aclError UnloadModelInner(const uint32_t modelId, const bool isSessionShared = false) {
  if ((acl::AclResourceManager::GetInstance().IsRuntimeV2Enable(true)) &&
      (acl::AclResourceManager::GetInstance().GetExecutor(modelId) != nullptr)) {
    const auto ret = UnloadRt2Model(modelId, isSessionShared);
    if (ret != ACL_SUCCESS) {
      ACL_LOG_ERROR("failed to unload model, modelId is %u, errorCode is %u", modelId, ret);
      return ret;
    }
  } else {
    ge::GeExecutor executor;
    ACL_LOG_INFO("call ge interface executor.UnloadModel, modelId[%u]", modelId);
    const ge::Status ret = executor.UnloadModel(modelId);
    if (ret != ge::SUCCESS) {
      ACL_LOG_CALL_ERROR("[Unload][Model]model unload failed, ge result[%u], modelId[%u]", ret, modelId);
      return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }
  }
  return ACL_SUCCESS;
}

static aclError QueryBundleSubModelInfo(const void *data, size_t modelSize, aclmdlBundleQueryInfo *queryInfo) {
  std::vector<std::pair<size_t, size_t>> subModelOffsetAndSize;
  size_t varSize = 0U;
  ACL_REQUIRES_OK(acl::GetBundleNumAndOffset(data, modelSize, varSize, subModelOffsetAndSize));
  queryInfo->varSize = static_cast<size_t>(varSize);
  for (const auto &ele : subModelOffsetAndSize) {
    acl::BundleSubModelInfo tmpInfo;
    tmpInfo.offset = ele.first;
    tmpInfo.modelSize = ele.second;
    bool isSupportRT2 = false;
    void *currentModePtr = ge::ValueToPtr(ge::PtrToValue(data) + ele.first);
    ACL_REQUIRES_OK(acl::IsSupportRuntimeV2WithModelData(currentModePtr, ele.second, isSupportRT2));
    // only static shape model can query size
    if (!isSupportRT2) {
      ge::GeExecutor executor;
      ACL_REQUIRES_CALL_GE_OK(
          executor.GetMemAndWeightSize(currentModePtr, ele.second, tmpInfo.workSize, tmpInfo.weightSize),
          "Query size failed");
    }
    ACL_LOG_INFO("get work size %zu, weight size %zu", tmpInfo.workSize, tmpInfo.weightSize);
    queryInfo->subModelInfos.emplace_back(tmpInfo);
  }
  return ACL_SUCCESS;
}

static aclError LoadBundleSubModelFromMem(const void *const currentModePtr, const size_t modelSize,
                                          const std::string &modelPath, std::shared_ptr<gert::RtSession> &rtSession,
                                          const ge::ModelLoadArg &loadArgs, uint32_t &currentModelId,
                                          const char_t *const weightPath = nullptr, const int32_t priority = 0) {
  bool isSupportRT2 = false;
  ACL_REQUIRES_OK(acl::IsSupportRuntimeV2WithModelData(currentModePtr, modelSize, isSupportRT2));
  aclError ret = ACL_SUCCESS;
  if (isSupportRT2) {
    ret = acl::RuntimeV2ModelLoadFromMemWithMem(currentModePtr, modelSize, modelPath, &currentModelId,
                                                loadArgs.weight_ptr, loadArgs.weight_size, weightPath, priority,
                                                loadArgs.file_constant_mems, rtSession);
  } else {
    ret = acl::ModelLoadFromMemWithMem(currentModePtr, modelSize, modelPath, &currentModelId, loadArgs, weightPath,
                                       priority);
  }
  return ret;
}

static aclError BundleInitFromMem(std::shared_ptr<const uint8_t> model, size_t modelSize, const std::string &modelPath,
                                  void *varWeightPtr, size_t varWeightSize, uint32_t *bundleId) {
  // get bundle num from file header
  std::vector<std::pair<size_t, size_t>> subModelOffsetAndSize;
  size_t varSize = 0U;
  ACL_REQUIRES_OK(acl::GetBundleNumAndOffset(model.get(), modelSize, varSize, subModelOffsetAndSize));
  if ((varWeightPtr != nullptr) && (varWeightSize < varSize)) {
    ACL_LOG_ERROR("varWeightSize %zu is invalid, it cannot be smaller than model required size %zu", varWeightSize,
                  varSize);
    const std::string errMsg = "it cannot be smaller than model required size " + std::to_string(varSize);
    acl::AclErrorLogManager::ReportInputError(
        acl::INVALID_PARAM_MSG, std::vector<const char *>({"param", "value", "reason"}),
        std::vector<const char *>({"varWeightSize", std::to_string(varWeightSize).c_str(), errMsg.c_str()}));
    return ACL_ERROR_INVALID_PARAM;
  }
  auto rtSession = acl::AclResourceManager::GetInstance().CreateRtSession();
  ACL_REQUIRES_NOT_NULL(rtSession);
  rtSession->SetExternalVar(varWeightPtr, varWeightSize);
  acl::AclResourceManager::GetInstance().AddExecutor(*bundleId, nullptr, rtSession);
  acl::BundleModelInfo info;
  info.isInit = true;
  info.varSize = varSize;
  info.fromFilePath = modelPath;
  info.bundleModelSize = modelSize;
  info.bundleModelData = model;
  info.rtSession = rtSession;
  for (const auto &offsetSize : subModelOffsetAndSize) {
    acl::BundleSubModelInfo subInfo;
    subInfo.offset = offsetSize.first;
    subInfo.modelSize = offsetSize.second;
    info.subModelInfos.emplace_back(subInfo);
  }
  acl::AclResourceManager::GetInstance().SetBundleInfo(*bundleId, info);
  return ACL_SUCCESS;
}

static aclError BundleLoadFromMem(std::shared_ptr<const uint8_t> model, size_t modelSize, const std::string &modelPath,
                                  uint32_t *bundleId) {
  // BundleLoadFromMem = BundleInitFromMem + load sub model
  ACL_REQUIRES_OK(BundleInitFromMem(model, modelSize, modelPath, nullptr, 0, bundleId));
  acl::BundleModelInfo info;
  ACL_REQUIRES_OK(acl::AclResourceManager::GetInstance().GetBundleInfo(*bundleId, info));
  info.isInit = false;
  const auto loadArgs = ConstructGeModelLoadArg(nullptr, 0, nullptr, 0, info.rtSession.get(), {});
  for (const auto &subInfo : info.subModelInfos) {
    uint32_t currentModelId = 0U;
    void *currentModePtr = ge::ValueToPtr(ge::PtrToValue(model.get()) + subInfo.offset);
    aclError ret = LoadBundleSubModelFromMem(currentModePtr, subInfo.modelSize, modelPath, info.rtSession, loadArgs,
                                             currentModelId);
    if (ret != ACL_SUCCESS) {
      for (const auto &ele : info.loadedSubModelIdSet) {
        (void)UnloadModelInner(ele);
      }
      return ret;
    }
    info.loadedSubModelId.emplace_back(currentModelId);  // only BundleLoadFromMem need set
    info.loadedSubModelIdSet.insert(currentModelId);
  }
  if (!info.fromFilePath.empty()) {
    info.bundleModelData = nullptr;  // need reset nullptr when aclmdlBundleLoadFromFile to ensure compatibility
    info.bundleModelSize = 0U;
  }
  acl::AclResourceManager::GetInstance().SetBundleInfo(*bundleId, info);
  return ACL_SUCCESS;
}

aclError aclmdlBundleLoadFromFileImpl(const char *modelPath, uint32_t *bundleId) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlBundleLoadFromFile);
  ACL_LOG_INFO("start to execute aclmdlBundleLoadFromFile");
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelPath);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(bundleId);

  // 1. load model data from file
  ge::ModelData modelData;
  modelData.om_path = modelPath;
  ge::graphStatus ret = ge::GRAPH_SUCCESS;
  ACL_LOG_INFO("call ge interface gert::LoadDataFromFile");
  ret = gert::LoadDataFromFile(modelPath, modelData);
  std::shared_ptr<uint8_t> data;
  data.reset(ge::PtrToPtr<void, uint8_t>(modelData.model_data), std::default_delete<uint8_t[]>());
  if (ret != ge::GRAPH_SUCCESS) {
    ACL_LOG_CALL_ERROR("[Load][Model]failed to load model from file by runtime2.0, ge errorCode is %u", ret);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }

  ACL_REQUIRES_OK(BundleLoadFromMem(data, modelData.model_len, modelPath, bundleId));
  ACL_LOG_INFO("successfully execute aclmdlBundleLoadFromFile, bundle id is %u", *bundleId);
  return ACL_SUCCESS;
}

aclError aclmdlBundleLoadFromMemImpl(const void *model, size_t modelSize, uint32_t *bundleId) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlBundleLoadFromMem);
  ACL_LOG_INFO("start to execute aclmdlBundleLoadFromMem, modelSize[%zu]", modelSize);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(model);
  ACL_REQUIRES_POSITIVE_WITH_INPUT_REPORT(modelSize);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(bundleId);

  std::shared_ptr<const uint8_t> data;
  // no delete func
  data.reset(ge::PtrToPtr<void, uint8_t>(model), [](const uint8_t *const p) { (void)p; });
  ACL_REQUIRES_OK(BundleLoadFromMem(data, modelSize, "", bundleId));

  ACL_LOG_INFO("execute aclmdlBundleLoadFromMem success, bundleId[%u]", *bundleId);
  return ACL_SUCCESS;
}

aclError aclmdlLoadFromFileImpl(const char *modelPath, uint32_t *modelId) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlLoadFromFile);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelPath);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelId);
  aclError ret = ACL_SUCCESS;
  bool isSupportRT2 = false;
  ACL_REQUIRES_OK(acl::IsSupportRuntimeV2WithModelPath(modelPath, isSupportRT2));
  if (isSupportRT2) {
    ret = acl::RuntimeV2ModelLoadFromFileWithMem(modelPath, modelId, nullptr, 0U, 0);
  } else {
    ge::ModelLoadArg loadArgs{};
    ret = acl::ModelLoadFromFileWithMem(modelPath, modelId, loadArgs, 0);
  }
  if (ret != ACL_SUCCESS) {
    ACL_LOG_ERROR("Load model from file failed!");
    return ret;
  }
  ACL_LOG_INFO("successfully execute aclmdlLoadFromFile");
  return ACL_SUCCESS;
}

aclError aclmdlLoadFromFileWithMemImpl(const char *modelPath, uint32_t *modelId, void *workPtr, size_t workSize,
                                       void *weightPtr, size_t weightSize) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlLoadFromFileWithMem);
  ACL_LOG_INFO("start to execute aclmdlLoadFromFileWithMem, workSize[%zu], weightSize[%zu]", workSize, weightSize);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelPath);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelId);

  aclError ret = ACL_SUCCESS;
  bool isSupportRT2 = false;
  ACL_REQUIRES_OK(acl::IsSupportRuntimeV2WithModelPath(modelPath, isSupportRT2));
  if (isSupportRT2) {
    ret = acl::RuntimeV2ModelLoadFromFileWithMem(modelPath, modelId, weightPtr, weightSize, 0);
  } else {
    const auto loadArgs = ConstructGeModelLoadArg(workPtr, workSize, weightPtr, weightSize);
    ret = acl::ModelLoadFromFileWithMem(modelPath, modelId, loadArgs, 0);
  }
  if (ret != ACL_SUCCESS) {
    return ret;
  }
  ACL_LOG_INFO("Load model from file[%s] with memory success, modelId[%u]", modelPath, *modelId);
  return ACL_SUCCESS;
}

aclError aclmdlLoadFromMemImpl(const void *model, size_t modelSize, uint32_t *modelId) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlLoadFromMem);
  ACL_LOG_INFO("start to execute aclmdlLoadFromMem, modelSize[%zu]", modelSize);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(model);
  ACL_REQUIRES_POSITIVE_WITH_INPUT_REPORT(modelSize);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelId);
  bool isSupportRT2 = false;
  ACL_REQUIRES_OK(acl::IsSupportRuntimeV2WithModelData(model, modelSize, isSupportRT2));
  aclError ret = ACL_SUCCESS;
  if (isSupportRT2) {
    ret = acl::RuntimeV2ModelLoadFromMemWithMem(model, modelSize, "", modelId, nullptr, 0U, nullptr, 0);
  } else {
    ge::ModelLoadArg loadArgs{};
    ret = acl::ModelLoadFromMemWithMem(model, modelSize, "", modelId, loadArgs, nullptr, 0);
  }
  if (ret != ACL_SUCCESS) {
    return ret;
  }

  ACL_LOG_INFO("Load model from data success, modelId[%u]", *modelId);
  return ACL_SUCCESS;
}

// get some info from bundleId
aclError aclmdlBundleGetModelNumImpl(uint32_t bundleId, size_t *modelNum) {
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelNum);
  acl::BundleModelInfo bundleInfos;
  ACL_REQUIRES_OK(acl::AclResourceManager::GetInstance().GetBundleInfo(bundleId, bundleInfos));
  *modelNum = bundleInfos.subModelInfos.size();
  ACL_LOG_INFO("get bundleId %u model num %zu", bundleId, *modelNum);
  return ACL_SUCCESS;
}

aclError aclmdlBundleGetModelIdImpl(uint32_t bundleId, size_t index, uint32_t *modelId) {
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelId);
  acl::BundleModelInfo bundleInfos;
  ACL_REQUIRES_OK(acl::AclResourceManager::GetInstance().GetBundleInfo(bundleId, bundleInfos));
  if (bundleInfos.isInit) {
    ACL_LOG_ERROR(
        "aclmdlBundleGetModelId is supported only aclmdlBundleLoadFromFile or aclmdlBundleLoadFromMem is executed");
    return ACL_ERROR_API_NOT_SUPPORT;
  }
  if (index >= bundleInfos.loadedSubModelId.size()) {
    ACL_LOG_ERROR("bundleId %u input index %zu should be smaller than bundle size %zu", bundleId, index,
                  bundleInfos.loadedSubModelId.size());
    return ACL_ERROR_INVALID_PARAM;
  }
  *modelId = bundleInfos.loadedSubModelId[index];
  ACL_LOG_INFO("get bundleId %u index %zu model id %u", bundleId, index, *modelId);
  return ACL_SUCCESS;
}

aclError aclmdlBundleQueryInfoFromFileImpl(const char *fileName, aclmdlBundleQueryInfo *queryInfo) {
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(fileName);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(queryInfo);
  ACL_LOG_INFO("start to execute aclmdlBundleQueryInfoFromFile %s", fileName);
  // 1. load model data from file
  ge::ModelData modelData;
  modelData.om_path = fileName;
  ge::graphStatus ret = ge::GRAPH_SUCCESS;
  ACL_LOG_INFO("call ge interface gert::LoadDataFromFile");
  ret = gert::LoadDataFromFile(fileName, modelData);
  std::shared_ptr<uint8_t> data;
  data.reset(ge::PtrToPtr<void, uint8_t>(modelData.model_data), std::default_delete<uint8_t[]>());
  if (ret != ge::GRAPH_SUCCESS) {
    ACL_LOG_CALL_ERROR("[Load][Model]failed to load model from file by runtime2.0, ge errorCode is %u", ret);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }
  ACL_REQUIRES_OK(QueryBundleSubModelInfo(modelData.model_data, modelData.model_len, queryInfo));
  ACL_LOG_INFO("end to execute aclmdlBundleQueryInfoFromFile %s", fileName);
  return ACL_SUCCESS;
}

aclError aclmdlBundleQueryInfoFromMemImpl(const void *model, size_t modelSize, aclmdlBundleQueryInfo *queryInfo) {
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(model);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(queryInfo);
  ACL_LOG_INFO("start to execute aclmdlBundleQueryInfoFromMem");
  ACL_REQUIRES_OK(QueryBundleSubModelInfo(model, modelSize, queryInfo));
  ACL_LOG_INFO("end to execute aclmdlBundleQueryInfoFromMem");
  return ACL_SUCCESS;
}

aclError aclmdlBundleInitFromFileImpl(const char *modelPath, void *varWeightPtr, size_t varWeightSize,
                                      uint32_t *bundleId) {
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelPath);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(bundleId);
  ACL_LOG_INFO("start to execute aclmdlBundleInitFromFile, model path %s, varWeightSize %zu", modelPath, varWeightSize);
  ge::ModelData modelData;
  modelData.om_path = modelPath;
  ACL_LOG_INFO("call ge interface gert::LoadDataFromFile");
  ACL_REQUIRES_CALL_GE_OK(gert::LoadDataFromFile(modelPath, modelData), "load data form file %s failed", modelPath);
  std::shared_ptr<uint8_t> tmpData;
  tmpData.reset(ge::PtrToPtr<void, uint8_t>(modelData.model_data), std::default_delete<uint8_t[]>());
  ACL_REQUIRES_NOT_NULL(tmpData);
  ACL_REQUIRES_OK(BundleInitFromMem(tmpData, modelData.model_len, modelPath, varWeightPtr, varWeightSize, bundleId));
  ACL_LOG_INFO("end to execute aclmdlBundleInitFromFile, model path %s, varWeightSize %zu, bundleId %u", modelPath,
               varWeightSize, *bundleId);
  return ACL_SUCCESS;
}

aclError aclmdlBundleInitFromMemImpl(const void *model, size_t modelSize, void *varWeightPtr, size_t varWeightSize,
                                     uint32_t *bundleId) {
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(model);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(bundleId);
  ACL_LOG_INFO("start to execute aclmdlBundleInitFromMem, model size %zu, varWeightSize %zu", modelSize, varWeightSize);
  std::shared_ptr<const uint8_t> tmpData;
  // no delete func
  tmpData.reset(ge::PtrToPtr<void, uint8_t>(model), [](const uint8_t *const p) { (void)p; });
  ACL_REQUIRES_OK(BundleInitFromMem(tmpData, modelSize, "", varWeightPtr, varWeightSize, bundleId));
  ACL_LOG_INFO("end to execute aclmdlBundleInitFromMem, model size %zu, varWeightSize %zu, bundleId %u", modelSize,
               varWeightSize, *bundleId);
  return ACL_SUCCESS;
}

aclError aclmdlBundleLoadModelImpl(uint32_t bundleId, size_t index, uint32_t *modelId) {
  return aclmdlBundleLoadModelWithMemImpl(bundleId, index, nullptr, 0U, nullptr, 0U, modelId);
}

static aclError GetTargetBundleInfo(uint32_t bundleId, acl::BundleModelInfo &bundleInfos) {
  const std::unique_lock<std::mutex> lock(aclmdlBundleMutex);
  ACL_REQUIRES_OK(acl::AclResourceManager::GetInstance().GetBundleInfo(bundleId, bundleInfos));
  bool need_load_mem_from_file =
      !bundleInfos.isInit && !bundleInfos.fromFilePath.empty() && (bundleInfos.bundleModelData == nullptr);
  if (need_load_mem_from_file) {
    ACL_LOG_INFO("bundle mem should allocated again when aclmdlBundleLoadFromFile called");
    ge::ModelData modelData;
    modelData.om_path = bundleInfos.fromFilePath;
    ACL_LOG_INFO("call ge interface gert::LoadDataFromFile");
    ACL_REQUIRES_CALL_GE_OK(gert::LoadDataFromFile(bundleInfos.fromFilePath.c_str(), modelData),
                            "load bundle om %s failed", bundleInfos.fromFilePath.c_str());
    std::shared_ptr<uint8_t> data;
    data.reset(ge::PtrToPtr<void, uint8_t>(modelData.model_data), std::default_delete<uint8_t[]>());
    bundleInfos.bundleModelData = data;
    bundleInfos.bundleModelSize = modelData.model_len;
    acl::AclResourceManager::GetInstance().SetBundleInfo(bundleId, bundleInfos);
  }
  return ACL_SUCCESS;
}

aclError aclmdlBundleLoadModelWithMemImpl(uint32_t bundleId, size_t index, void *workPtr, size_t workSize,
                                          void *weightPtr, size_t weightSize, uint32_t *modelId) {
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelId);
  ACL_PROFILING_REG(acl::AclProfType::AclmdlBundleLoadModelWithMem);
  ACL_LOG_INFO("strat to execute aclmdlBundleLoadModelWithMem, bundleId %u, index %zu", bundleId, index);
  acl::BundleModelInfo bundleInfos;
  ACL_REQUIRES_OK(GetTargetBundleInfo(bundleId, bundleInfos));
  if (index >= bundleInfos.subModelInfos.size()) {
    ACL_LOG_ERROR("index %zu should be smaller than %zu", index, bundleInfos.subModelInfos.size());
    return ACL_ERROR_INVALID_PARAM;
  }
  ACL_REQUIRES_NOT_NULL(bundleInfos.bundleModelData);
  const size_t offset = bundleInfos.subModelInfos[index].offset;
  const size_t modelSize = bundleInfos.subModelInfos[index].modelSize;
  void *currentModePtr = ge::ValueToPtr(ge::PtrToValue(bundleInfos.bundleModelData.get()) + offset);
  const auto loadArgs =
      ConstructGeModelLoadArg(workPtr, workSize, weightPtr, weightSize, bundleInfos.rtSession.get(), {});
  ACL_REQUIRES_OK(LoadBundleSubModelFromMem(currentModePtr, modelSize, bundleInfos.fromFilePath, bundleInfos.rtSession,
                                            loadArgs, *modelId));
  acl::AclResourceManager::GetInstance().AddBundleSubmodelId(bundleId, *modelId);
  ACL_LOG_INFO("end to execute aclmdlBundleLoadModelWithMem, bundleId %u, index %zu", bundleId, index);
  return ACL_SUCCESS;
}

aclError aclmdlBundleLoadModelWithConfigImpl(uint32_t bundleId, size_t index, aclmdlConfigHandle *handle,
                                             uint32_t *modelId) {
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelId);
  ACL_PROFILING_REG(acl::AclProfType::AclmdlBundleLoadModelWithConfig);
  ACL_LOG_INFO("start to execute aclmdlBundleLoadModelWithConfig, bundleId %u, index %zu", bundleId, index);
  acl::BundleModelInfo bundleInfos;
  ACL_REQUIRES_OK(GetTargetBundleInfo(bundleId, bundleInfos));
  if (index >= bundleInfos.subModelInfos.size()) {
    ACL_LOG_ERROR("index %zu should be smaller than %zu", index, bundleInfos.subModelInfos.size());
    return ACL_ERROR_INVALID_PARAM;
  }
  acl::UpdateGraphOptions(OPTION_EXEC_REUSE_ZERO_COPY_MEMORY, std::to_string(handle->reuseZeroCopy));
  ACL_REQUIRES_NOT_NULL(bundleInfos.bundleModelData);
  const size_t offset = bundleInfos.subModelInfos[index].offset;
  const size_t modelSize = bundleInfos.subModelInfos[index].modelSize;
  void *currentModePtr = ge::ValueToPtr(ge::PtrToValue(bundleInfos.bundleModelData.get()) + offset);
  const auto loadArgs =
      ConstructGeModelLoadArg(handle->workPtr, handle->workSize, handle->weightPtr, handle->weightSize,
                              bundleInfos.rtSession.get(), handle->fileConstantMem, handle->withoutGraph);

  ACL_REQUIRES_OK(LoadBundleSubModelFromMem(currentModePtr, modelSize, bundleInfos.fromFilePath, bundleInfos.rtSession,
                                            loadArgs, *modelId, handle->weightPath.c_str(), handle->priority));
  acl::AclResourceManager::GetInstance().AddBundleSubmodelId(bundleId, *modelId);
  ACL_LOG_INFO("end to execute aclmdlBundleLoadModelWithConfig, bundleId %u, index %zu, model id is %u", bundleId,
               index, *modelId);
  return ACL_SUCCESS;
}

aclError aclmdlBundleUnloadModelImpl(uint32_t bundleId, uint32_t modelId) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlBundleUnloadModel);
  ACL_LOG_INFO("start to execute aclmdlBundleUnloadModel bundleId %u, modelId %u", bundleId, modelId);
  acl::BundleModelInfo bundleInfos;
  ACL_REQUIRES_OK(acl::AclResourceManager::GetInstance().GetBundleInfo(bundleId, bundleInfos));
  if (bundleInfos.loadedSubModelIdSet.find(modelId) == bundleInfos.loadedSubModelIdSet.end()) {
    ACL_LOG_ERROR("current modelId %u is not bundleId %u sub model", modelId, bundleId);
    return ACL_ERROR_INVALID_PARAM;
  }
  ACL_REQUIRES_OK(UnloadModelInner(modelId, true));
  acl::AclResourceManager::GetInstance().DeleteBundleSubmodelId(bundleId, modelId);
  ACL_LOG_INFO("end to execute aclmdlBundleUnloadModel bundleId %u, modelId %u", bundleId, modelId);
  return ACL_SUCCESS;
}

aclError aclmdlLoadFromMemWithMemImpl(const void *model, size_t modelSize, uint32_t *modelId, void *workPtr,
                                      size_t workSize, void *weightPtr, size_t weightSize) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlLoadFromMemWithMem);
  ACL_LOG_INFO("start to execute aclmdlLoadFromMemWithMem, modelSize[%zu], workSize[%zu], weightSize[%zu]", modelSize,
               workSize, weightSize);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(model);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelId);

  bool isSupportRT2 = false;
  ACL_REQUIRES_OK(acl::IsSupportRuntimeV2WithModelData(model, modelSize, isSupportRT2));
  aclError ret = ACL_SUCCESS;
  if (isSupportRT2) {
    ret = acl::RuntimeV2ModelLoadFromMemWithMem(model, modelSize, "", modelId, weightPtr, weightSize, nullptr, 0);
  } else {
    const auto loadArgs = ConstructGeModelLoadArg(workPtr, workSize, weightPtr, weightSize);
    ret = acl::ModelLoadFromMemWithMem(model, modelSize, "", modelId, loadArgs, nullptr, 0);
  }
  if (ret != ACL_SUCCESS) {
    return ret;
  }
  ACL_LOG_INFO("successfully execute aclmdlLoadFromMemWithMem, modelSize[%zu], workSize[%zu], weightSize[%zu]",
               modelSize, workSize, weightSize);
  return ACL_SUCCESS;
}

aclError aclmdlLoadFromFileWithQImpl(const char *modelPath, uint32_t *modelId, const uint32_t *inputQ, size_t inputQNum,
                                     const uint32_t *outputQ, size_t outputQNum) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlLoadFromFileWithQ);
  if (aclmdlCheckQueueParam(inputQ, inputQNum, outputQ, outputQNum) != ACL_SUCCESS) {
    return ACL_ERROR_INVALID_PARAM;
  }
  ACL_LOG_INFO("start to execute aclmdlLoadFromFileWithQ, inputQNum[%zu], outputQNum[%zu]", inputQNum, outputQNum);
  std::vector<uint32_t> inputQVec(inputQ, inputQ + inputQNum);
  std::vector<uint32_t> outputQVec(outputQ, outputQ + outputQNum);
  ge::ModelQueueArg args{std::move(inputQVec), std::move(outputQVec), {}, false};
  const aclError ret = acl::ModelLoadFromFileWithQ(modelPath, modelId, args, 0);
  if (ret != ACL_SUCCESS) {
    return ret;
  }
  ACL_LOG_INFO("successfully execute aclmdlLoadFromFileWithQ, inputQNum[%zu], outputQNum[%zu]", inputQNum, outputQNum);
  return ACL_SUCCESS;
}

aclError aclmdlLoadFromMemWithQImpl(const void *model, size_t modelSize, uint32_t *modelId, const uint32_t *inputQ,
                                    size_t inputQNum, const uint32_t *outputQ, size_t outputQNum) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlLoadFromMemWithQ);
  if (aclmdlCheckQueueParam(inputQ, inputQNum, outputQ, outputQNum) != ACL_SUCCESS) {
    return ACL_ERROR_INVALID_PARAM;
  }
  ACL_LOG_INFO("start to execute aclmdlLoadFromMemWithQ, modelSize[%zu], inputQNum[%zu], outputQNum[%zu]", modelSize,
               inputQNum, outputQNum);
  std::vector<uint32_t> inputQVec(inputQ, inputQ + inputQNum);
  std::vector<uint32_t> outputQVec(outputQ, outputQ + outputQNum);
  ge::ModelQueueArg args{std::move(inputQVec), std::move(outputQVec), {}, false};
  const aclError ret = acl::ModelLoadFromMemWithQ(model, modelSize, modelId, args, 0);
  if (ret != ACL_SUCCESS) {
    return ret;
  }
  ACL_LOG_INFO("successfully execute aclmdlLoadFromMemWithQ, modelSize[%zu], inputQNum[%zu], outputQNum[%zu]",
               modelSize, inputQNum, outputQNum);
  return ACL_SUCCESS;
}

aclError aclmdlExecuteImpl(uint32_t modelId, const aclmdlDataset *input, aclmdlDataset *output) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlExecute);
  ACL_LOG_INFO("start to execute aclmdlExecute, modelId[%u]", modelId);
  aclError ret = ACL_SUCCESS;
  if ((acl::AclResourceManager::GetInstance().IsRuntimeV2Enable(true)) &&
      (acl::AclResourceManager::GetInstance().GetExecutor(modelId) != nullptr)) {
    ret = acl::RuntimeV2ModelExecute(modelId, input, output, false, nullptr);
  } else {
    ret = acl::ModelExecute(modelId, input, output, false, nullptr);
  }
  if (ret == ACL_SUCCESS) {
    ACL_LOG_INFO("aclmdlExecute success, modelId[%u]", modelId);
  } else {
    ACL_LOG_INNER_ERROR("[Exec][Model]modelId[%u] execute failed, result[%d]", modelId, ret);
  }
  return ret;
}

namespace {
static aclError AclMdlSetPriority(uint32_t model_id, const aclmdlAttrValue_t *value) {
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(value);
  const uint32_t priority = value->mdlPriority;
  int32_t least_priority = 0;
  int32_t greatest_priority = 0;
  aclError ret = aclrtDeviceGetStreamPriorityRange(&least_priority, &greatest_priority);
  if (ret != ACL_SUCCESS) {
    ACL_LOG_ERROR("[SetAttr][Priority] Failed to get priority range, ret=%d", ret);
    return ret;
  }
  if ((priority < static_cast<uint32_t>(greatest_priority)) || (priority > static_cast<uint32_t>(least_priority))) {
    ACL_LOG_ERROR("[SetAttr][Priority] Priority %u out of range [%d, %d]", priority, greatest_priority, least_priority);
    return ACL_ERROR_INVALID_PARAM;
  }
  ge::Status status = ge::GeExecutor().SetModelStreamPriority(model_id, priority);
  if (status != ge::SUCCESS) {
    ACL_LOG_ERROR("[SetAttr][Priority] SetModelStreamPriority failed, model_id=%u, ret=%u", model_id, status);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(status));
  }
  return ACL_SUCCESS;
}

static aclError AclMdlGetPriority(uint32_t model_id, aclmdlAttrValue_t *value) {
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(value);
  uint32_t priority = 0;
  ge::Status status = ge::GeExecutor().GetModelStreamPriority(model_id, priority);
  if (status != ge::SUCCESS) {
    ACL_LOG_ERROR("[GetAttr][Priority] GetModelStreamPriority failed, model_id=%u, ret=%u", model_id, status);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(status));
  }
  value->mdlPriority = priority;
  return ACL_SUCCESS;
}
}  // namespace

aclError aclmdlSetAttributeImpl(uint32_t modelId, aclmdlAttr attr, aclmdlAttrValue_t *attrValue) {
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(attrValue);
  switch (attr) {
    case ACL_MDL_ATTR_PRIORITY_INT32: {
      ACL_LOG_INFO("start to execute aclmdlSetAttribute for ACL_MDL_ATTR_PRIORITY_INT32, modelId[%u]", modelId);
      return AclMdlSetPriority(modelId, attrValue);
    }
    default: {
      ACL_LOG_ERROR("[SetAttr] Unsupported attr=%d", attr);
      return ACL_ERROR_INVALID_PARAM;
    }
  }
}

aclError aclmdlGetAttributeImpl(uint32_t modelId, aclmdlAttr attr, aclmdlAttrValue_t *attrValue) {
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(attrValue);
  switch (attr) {
    case ACL_MDL_ATTR_PRIORITY_INT32: {
      ACL_LOG_INFO("start to execute aclmdlGetAttribute for ACL_MDL_ATTR_PRIORITY_INT32, modelId[%u]", modelId);
      return AclMdlGetPriority(modelId, attrValue);
    }
    default: {
      ACL_LOG_ERROR("[GetAttr] Unsupported attr=%d", attr);
      return ACL_ERROR_INVALID_PARAM;
    }
  }
}

aclError aclmdlExecuteV2Impl(uint32_t modelId, const aclmdlDataset *input, aclmdlDataset *output, aclrtStream stream,
                             const aclmdlExecConfigHandle *handle) {
  ACL_LOG_INFO("start to execute aclmdlExecuteV2, modelId[%u]", modelId);

  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle);
  if (handle->streamSyncTimeout >= DEFAULT_SYNC_TIMEOUT) {
    ACL_LOG_INFO("stream synchronize timeout = %dms", handle->streamSyncTimeout);
    ge::GetContext().SetStreamSyncTimeout(handle->streamSyncTimeout);
  }
  if (handle->eventSyncTimeout >= DEFAULT_SYNC_TIMEOUT) {
    ACL_LOG_INFO("event synchronize timeout = %dms", handle->eventSyncTimeout);
    ge::GetContext().SetEventSyncTimeout(handle->eventSyncTimeout);
  }

  aclError ret = ACL_SUCCESS;
  if ((acl::AclResourceManager::GetInstance().IsRuntimeV2Enable(true)) &&
      (acl::AclResourceManager::GetInstance().GetExecutor(modelId) != nullptr)) {
    ret = acl::RuntimeV2ModelExecute(modelId, input, output, false, stream);
  } else {
    ret = acl::ModelExecute(modelId, input, output, false, stream);
    if (stream != nullptr) {
      const aclError rtErr = aclrtSynchronizeStreamWithTimeout(stream, handle->streamSyncTimeout);
      if (rtErr != ACL_ERROR_NONE) {
        ACL_LOG_CALL_ERROR("synchronize stream failed, runtime result = %d", static_cast<int32_t>(rtErr));
        return ACL_GET_ERRCODE_RTS(rtErr);
      }
    }
  }
  if (ret == ACL_SUCCESS) {
    ACL_LOG_INFO("aclmdlExecuteV2 success, modelId[%u]", modelId);
  } else {
    ACL_LOG_INNER_ERROR("[Exec][Model]modelId[%u] execute failed, result[%d]", modelId, ret);
  }
  return ret;
}

aclError aclmdlExecuteAsyncImpl(uint32_t modelId, const aclmdlDataset *input, aclmdlDataset *output,
                                aclrtStream stream) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlExecuteAsync);
  ACL_LOG_INFO("start to execute aclmdlExecuteAsync, modelId[%u]", modelId);

  aclError ret = ACL_SUCCESS;
  if ((acl::AclResourceManager::GetInstance().IsRuntimeV2Enable(true)) &&
      (acl::AclResourceManager::GetInstance().GetExecutor(modelId) != nullptr)) {
    ret = acl::RuntimeV2ModelExecute(modelId, input, output, true, stream);
  } else {
    ret = acl::ModelExecute(modelId, input, output, true, stream);
  }
  if (ret == ACL_SUCCESS) {
    ACL_LOG_INFO("aclmdlExecuteAsync success, modelId[%u]", modelId);
  } else {
    ACL_LOG_INNER_ERROR("[Exec][Model]aclmdlExecuteAsync failed, result[%d], modelId[%u]", ret, modelId);
  }
  return ret;
}

aclError aclmdlUnloadImpl(uint32_t modelId) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlUnload);
  ACL_LOG_INFO("start to execute aclmdlUnload, modelId[%u]", modelId);
  if (acl::AclResourceManager::GetInstance().IsBundleInnerId(modelId)) {
    ACL_LOG_ERROR("this modeId %u is bundle inner modelId, please ues aclmdlBundleUnload api instead", modelId);
    return ACL_ERROR_INVALID_PARAM;
  }
  ACL_REQUIRES_OK(UnloadModelInner(modelId));
  ACL_LOG_INFO("aclmdlUnload success, modelId[%u]", modelId);
  return ACL_SUCCESS;
}

aclError aclmdlBundleUnloadImpl(uint32_t bundleId) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlBundleUnload);
  ACL_LOG_INFO("start to execute aclmdlBundleUnload %u", bundleId);
  acl::BundleModelInfo bundleInfos;
  ACL_REQUIRES_OK(acl::AclResourceManager::GetInstance().GetBundleInfo(bundleId, bundleInfos));
  aclError finalRet = ACL_SUCCESS;
  for (auto &modelId : bundleInfos.loadedSubModelIdSet) {
    // unload all and check result
    const auto ret = UnloadModelInner(modelId);
    if (ret != ACL_SUCCESS) {
      finalRet = ret;
    }
  }
  ACL_REQUIRES_OK(finalRet);
  acl::AclResourceManager::GetInstance().DeleteBundleInfo(bundleId);
  // release session var manager
  auto bundleSession = acl::AclResourceManager::GetInstance().GetRtSession(bundleId);
  ACL_REQUIRES_NOT_NULL(bundleSession);
  bundleSession->DestroyResources();
  ACL_REQUIRES_OK(acl::AclResourceManager::GetInstance().DeleteExecutor(bundleId));
  ACL_LOG_INFO("end to execute aclmdlBundleUnload %u", bundleId);
  return ACL_SUCCESS;
}

aclError aclmdlQuerySizeImpl(const char *fileName, size_t *workSize, size_t *weightSize) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlQuerySize);
  ACL_LOG_INFO("start to execute aclmdlQuerySize");
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(fileName);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(workSize);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(weightSize);

  const std::string path(fileName);
  size_t work;
  size_t weight;
  ACL_LOG_DEBUG("call ge interface executor.GetMemAndWeightSize");
  const ge::Status ret = ge::GeExecutor().GetMemAndWeightSize(path, work, weight);
  if (ret != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("[Get][MemAndWeightSize]query size failed, ge result[%u]", ret);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }

  *workSize = work;
  *weightSize = weight;
  ACL_LOG_INFO("success to get size from file[%s], work size[%zu] bytes, weight size[%zu] bytes", fileName, *workSize,
               *weightSize);

  return ACL_SUCCESS;
}

aclError aclmdlQuerySizeFromMemImpl(const void *model, size_t modelSize, size_t *workSize, size_t *weightSize) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlQuerySizeFromMem);
  ACL_LOG_INFO("start to execute ACL_QueryModelSizeFromMem, modelSize[%zu]", modelSize);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(model);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(workSize);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(weightSize);

  size_t work;
  size_t weight;
  ACL_LOG_DEBUG("call ge interface executor.GetMemAndWeightSize, modelSize[%zu]", modelSize);
  const ge::Status ret = ge::GeExecutor().GetMemAndWeightSize(model, modelSize, work, weight);
  if (ret != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("[Get][MemAndWeightSize]query size from mem failed, ge result[%u]", ret);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }

  *workSize = work;
  *weightSize = weight;
  ACL_LOG_INFO("success to get size from mem, work size[%zu] bytes, weight size[%zu] bytes", *workSize, *weightSize);

  return ACL_SUCCESS;
}

aclError aclmdlSetDynamicBatchSizeImpl(uint32_t modelId, aclmdlDataset *dataset, size_t index, uint64_t batchSize) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlSetDynamicBatchSize);
  ACL_LOG_INFO("start to execute aclmdlSetDynamicBatchSize, modelId[%u], index[%zu], batchSize[%lu]", modelId, index,
               batchSize);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dataset);

  if (batchSize == 0U) {
    ACL_LOG_INNER_ERROR("[Check][Batchsize]input param[batchSize] invalid, batchSize can't be zero");
    return ACL_ERROR_INVALID_PARAM;
  }

  const aclDataBuffer *const buf = aclmdlGetDatasetBufferImplOm2(dataset, index);
  if (buf == nullptr) {
    ACL_LOG_INNER_ERROR("[Check][buf]failed to get data buffer by index[%zu], dataset buffer is null", index);
    return ACL_ERROR_INVALID_PARAM;
  }

  void *const devPtr = aclGetDataBufferAddr(buf);
  if (devPtr == nullptr) {
    ACL_LOG_INNER_ERROR("[Check][devPtr]get addr by index[%zu] failed, data buffer addr cannot be null", index);
    return ACL_ERROR_INVALID_PARAM;
  }
  const uint64_t memSize = aclGetDataBufferSizeV2(buf);

  dataset->dynamicBatchSize = batchSize;
  dataset->dynamicResolutionHeight = 0U;
  dataset->dynamicResolutionWidth = 0U;
  ACL_LOG_DEBUG("call ge interface executor.SetDynamicBatchSize, batchSize[%lu]", batchSize);
  ge::GeExecutor executor;
  const ge::Status ret = executor.SetDynamicBatchSize(modelId, devPtr, memSize, batchSize);
  if (ret != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("[Set][DynamicBatchSize]set DynamicBatchSize failed, ge result[%u]", ret);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }

  ACL_LOG_INFO("successfully execute aclmdlSetDynamicBatchSize, modelId[%u], index[%zu], batchSize[%lu]", modelId,
               index, batchSize);
  return ACL_SUCCESS;
}

aclError aclmdlSetDynamicHWSizeImpl(uint32_t modelId, aclmdlDataset *dataset, size_t index, uint64_t height,
                                    uint64_t width) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlSetDynamicHWSize);
  ACL_LOG_INFO("start to execute aclmdlSetDynamicHWSize, modelId[%u], index[%zu], height[%lu], width[%lu]", modelId,
               index, height, width);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dataset);

  if ((height == 0U) || (width == 0U)) {
    ACL_LOG_INNER_ERROR("[Check][Params]height[%lu] or width[%lu] is invalid, can't be zero.", height, width);
    return ACL_ERROR_INVALID_PARAM;
  }

  aclDataBuffer *const buffer = aclmdlGetDatasetBufferImplOm2(dataset, index);
  if (buffer == nullptr) {
    ACL_LOG_INNER_ERROR("[Check][buffer]get data buffer by index[%zu] failed, dataset buffer cannot be null", index);
    return ACL_ERROR_INVALID_PARAM;
  }

  void *const devPtr = aclGetDataBufferAddr(buffer);
  if (devPtr == nullptr) {
    ACL_LOG_INNER_ERROR("[Check][devPtr]get addr by index[%zu] failed, data buffer addr cannot be nullptr", index);
    return ACL_ERROR_INVALID_PARAM;
  }
  const uint64_t memSize = aclGetDataBufferSizeV2(buffer);

  dataset->dynamicBatchSize = 0U;
  dataset->dynamicResolutionHeight = height;
  dataset->dynamicResolutionWidth = width;
  ACL_LOG_DEBUG("call ge interface executor.SetDynamicImageSize, height[%lu],width[%lu]", height, width);
  ge::GeExecutor executor;
  const ge::Status ret = executor.SetDynamicImageSize(modelId, devPtr, memSize, height, width);
  if (ret != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("[Set][DynamicImageSize]Set dynamic image size, ge result[%u]", ret);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }

  ACL_LOG_INFO("successfully execute aclmdlSetDynamicHWSize, modelId[%u], index[%zu], height[%lu], width[%lu]", modelId,
               index, height, width);
  return ACL_SUCCESS;
}

aclError aclmdlSetInputDynamicDimsImpl(uint32_t modelId, aclmdlDataset *dataset, size_t index,
                                       const aclmdlIODims *dims) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlSetInputDynamicDims);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dataset);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dims);
  if (dims->dimCount == 0U) {
    ACL_LOG_ERROR("[Check][dimCount]dimCount[%zu] is invalid, can't be zero.", dims->dimCount);
    const std::string errMsg = acl::AclErrorLogManager::FormatStr("dimCount[%u] can't be zero", dims->dimCount);
    acl::AclErrorLogManager::ReportInputError(acl::INVALID_PARAM_MSG,
                                              std::vector<const char *>({"param", "value", "reason"}),
                                              std::vector<const char *>({"dimCount", "0", errMsg.c_str()}));
    return ACL_ERROR_INVALID_PARAM;
  }

  ACL_LOG_INFO("start to execute aclmdlSetInputDynamicDims, modelId[%u], index[%zu], dimCount[%zu]", modelId, index,
               dims->dimCount);
  aclDataBuffer *const buffer = aclmdlGetDatasetBufferImplOm2(dataset, index);
  ACL_CHECK_WITH_INNER_MESSAGE_AND_RETURN(
      buffer != nullptr, ACL_ERROR_INVALID_PARAM,
      "[Check][buffer]get data buffer by index[%zu] failed, dataset buffer cannot be null", index);

  void *const devPtr = aclGetDataBufferAddr(buffer);
  ACL_CHECK_WITH_INNER_MESSAGE_AND_RETURN(devPtr != nullptr, ACL_ERROR_INVALID_PARAM,
                                          "[Get][devPtr]get addr by index[%zu] failed, data buffer addr cannot be null",
                                          index);
  const uint64_t memSize = aclGetDataBufferSizeV2(buffer);

  dataset->dynamicBatchSize = 0U;
  dataset->dynamicResolutionHeight = 0U;
  dataset->dynamicResolutionWidth = 0U;
  dataset->dynamicDims.clear();
  std::vector<uint64_t> curAllDims;
  for (size_t i = 0U; i < static_cast<std::size_t>(dims->dimCount); ++i) {
    curAllDims.push_back(static_cast<size_t>(dims->dims[i]));
  }
  ACL_LOG_DEBUG("Call ge interface executor.SetDynamicDims, dimCount[%zu]", dims->dimCount);
  ACL_LOG_DEBUG("Cur all dims size %zu", curAllDims.size());
  ge::GeExecutor executor;
  ge::Status ret = executor.SetDynamicDims(modelId, devPtr, memSize, curAllDims);
  if (ret != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("[Set][DynamicDims]set dynamic dims failed, ge result[%u]", ret);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }

  std::vector<uint64_t> curDynmaicDims;
  ret = executor.GetCurDynamicDims(modelId, curAllDims, curDynmaicDims);
  if (ret != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("[Get][CurDynamicDims]get current dynamic dims failed, ge result[%u]", ret);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
  }
  ACL_LOG_DEBUG("current dynamic dims size %zu", curDynmaicDims.size());
  dataset->dynamicDims = curDynmaicDims;

  ACL_LOG_INFO("successfully execute aclmdlSetInputDynamicDims, modelId[%u], index[%zu], dimCount[%zu]", modelId, index,
               dims->dimCount);
  return ACL_SUCCESS;
}

aclError aclmdlGetCurOutputDimsImpl(const aclmdlDesc *modelDesc, size_t index, aclmdlIODims *dims) {
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelDesc);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dims);
  if (acl::AclResourceManager::GetInstance().IsRuntimeV2Enable(true) &&
      (acl::AclResourceManager::GetInstance().GetExecutor(modelDesc->modelId) != nullptr)) {
    ACL_LOG_WARN("This api does not support dynamic model, please check.");
    return ACL_ERROR_API_NOT_SUPPORT;
  }
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dims);
  const uint32_t modelId = modelDesc->modelId;
  const size_t descSize = modelDesc->outputDesc.size();
  ACL_CHECK_WITH_INNER_MESSAGE_AND_RETURN(
      index < descSize, ACL_ERROR_INVALID_PARAM,
      "[Check][descSize]aclmdlGetCurOutputDims failed, index[%zu] should be smaller "
      "than tensor size[%zu], modelId[%u]",
      index, descSize, modelId);

  std::vector<int64_t> geShapeInfo;
  ge::GeExecutor executor;
  int32_t dynamicType = static_cast<int32_t>(ge::FIXED);
  const ge::Status geRet = executor.GetCurShape(modelId, geShapeInfo, dynamicType);
  if (geRet != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("[Get][CurShape]cannot get current shape, ge result[%d], modelId[%u]", geRet, modelId);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(geRet));
  }
  // dynamic batch type is 1, dynamic hw type is 2, dynamic dims type is 3;
  // static model or not set dynamic shape info, dynamic type is 0, other value is invalid
  aclError aclRet;
  const size_t shapeSize = geShapeInfo.size();
  if ((dynamicType != static_cast<int32_t>(ge::DYNAMIC_DIMS)) && (shapeSize > 2U)) {
    ACL_LOG_INNER_ERROR("[Check][dynamicType]shapeSize[%zu] is invalid, modelId[%u]", shapeSize, modelId);
    return ACL_ERROR_GE_FAILURE;
  }
  if (shapeSize == 0U) {
    ACL_LOG_DEBUG("Dynamic type is 0, model[%u] is static or not set dynamic shape info", modelId);
    aclRet = acl::GetDims(modelDesc, TensorType::OUTPUT_TENSOR_TYPE, DimsType::DIMS_TYPE_V1, index, dims);
    ACL_REQUIRES_OK_WITH_INNER_MESSAGE(aclRet,
                                       "[Get][Dims]get current output dims failed, result[%d], index[%zu], modelId[%u]",
                                       aclRet, index, modelId);
    return ACL_SUCCESS;
  }

  size_t curGearIndex = 0U;
  std::vector<uint64_t> shapeInfo;
  for (auto &it : geShapeInfo) {
    shapeInfo.emplace_back(static_cast<uint64_t>(it));
  }
  aclRet = acl::GetCurGearIndex(modelDesc, shapeInfo, dynamicType, curGearIndex);
  ACL_REQUIRES_OK_WITH_INNER_MESSAGE(aclRet,
                                     "[Get][CurGearIndex]get current gear index failed, result[%d], index[%zu], "
                                     "modelId[%u], dynamicBatchSize[%zu], dynamicHWSize[%zu]",
                                     aclRet, index, modelId, modelDesc->dynamicBatch.size(),
                                     modelDesc->dynamicHW.size());

  aclRet = acl::GetCurOuputShapeInfo(modelDesc, index, curGearIndex, dims);
  ACL_REQUIRES_OK_WITH_INNER_MESSAGE(aclRet,
                                     "[Get][CurOuputShapeInfo]get current output shape info failed, result[%d], "
                                     "index[%zu], modelId[%u], the size of dynamicOutputShape[%zu]",
                                     aclRet, index, modelId, modelDesc->dynamicOutputShape.size());

  return ACL_SUCCESS;
}

const char *aclmdlGetOpAttrImpl(aclmdlDesc *modelDesc, const char *opName, const char *attr) {
  ACL_LOG_INFO("start to execute aclmdlGetOpAttr");
  ACL_REQUIRES_NOT_NULL_RET_NULL(modelDesc);
  ACL_REQUIRES_NOT_NULL_RET_NULL(opName);
  ACL_REQUIRES_NOT_NULL_RET_NULL(attr);

  const std::string opNameStr(opName);
  const std::string attrStr(attr);
  if (attrStr != ACL_ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES) {
    ACL_LOG_INNER_ERROR(
        "failed to execute aclmdlGetOpAttr, attr[%s] is invalid, only support "
        "ACL_ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES",
        attrStr.c_str());
    return nullptr;
  }

  const std::unique_lock<std::mutex> lock(aclmdlGetOpAttrMutex);

  // Lookup in opAttrValueMap only
  std::map<std::string, std::map<std::string, std::string>>::const_iterator itOpName =
      modelDesc->opAttrValueMap.find(opName);
  if (itOpName != modelDesc->opAttrValueMap.cend()) {
    std::map<std::string, std::string>::const_iterator itAttr = itOpName->second.find(attr);
    if (itAttr != itOpName->second.cend()) {
      ACL_LOG_INFO("opName is [%s], the value of attr [%s] is %s", opName, attr, itAttr->second.c_str());
      return itAttr->second.c_str();
    }
  }

  ge::GeExecutor executor;
  const uint32_t modelId = modelDesc->modelId;
  ACL_LOG_INFO("Call ge interface executor.GetOpAttr, modelId is [%u], opName is [%s], attr is [%s]", modelId, opName,
               attr);
  std::string attrValue;
  const ge::Status ret = executor.GetOpAttr(modelId, opNameStr, attrStr, attrValue);
  if (ret != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("[Get][Opattr]Execute GetOpAttr failed, ge result[%u], modelId[%u]", ret, modelId);
    return nullptr;
  }
  ACL_LOG_INFO("Execute aclmdlGetOpAttr successfully, opName is [%s], the value of attr[%s] is %s", opName, attr,
               attrValue.c_str());
  modelDesc->opAttrValueMap[opNameStr][attrStr] = attrValue;
  return modelDesc->opAttrValueMap[opNameStr][attrStr].c_str();
}

aclError aclmdlCreateAndGetOpDescImpl(uint32_t deviceId, uint32_t streamId, uint32_t taskId, char *opName,
                                      size_t opNameLen, aclTensorDesc **inputDesc, size_t *numInputs,
                                      aclTensorDesc **outputDesc, size_t *numOutputs) {
  ACL_LOG_INFO("start to execute aclmdlCreateAndGetOpDesc, deviceId[%u], streamId[%u], taskId[%u]", deviceId, streamId,
               taskId);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(opName);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(inputDesc);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(outputDesc);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(numInputs);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(numOutputs);

  ge::GeExecutor executor;
  ge::OpDescInfo opDescInfo;
  ACL_LOG_DEBUG("call ge interface executor.GetOpDescInfo");
  const ge::Status geRet = executor.GetOpDescInfo(deviceId, streamId, taskId, opDescInfo);
  if (geRet != ge::SUCCESS) {
    ACL_LOG_CALL_ERROR("[Get][OpDescInfo]get op desc failed, ge result[%d], deviceId[%u], streamId[%u], taskId[%u]",
                       geRet, deviceId, streamId, taskId);
    return ACL_GET_ERRCODE_GE(static_cast<int32_t>(geRet));
  }

  if (opNameLen <= opDescInfo.op_name.length()) {
    ACL_LOG_INNER_ERROR("[Check][opNameLen]input length = %zu must be larger than op name real length = %zu", opNameLen,
                        opDescInfo.op_name.length());
    return ACL_ERROR_INVALID_PARAM;
  }
  const auto ret = strncpy_s(opName, opNameLen, opDescInfo.op_name.c_str(), opDescInfo.op_name.length());
  if (ret != EOK) {
    ACL_LOG_INNER_ERROR(
        "[Copy][OpName]copy op name failed, copy errorCode = %d, input opNameLen = %zu, "
        "real opNameLen = %zu",
        ret, opNameLen, opDescInfo.op_name.length());
    return ACL_ERROR_FAILURE;
  }

  const size_t inputNum = opDescInfo.input_format.size();
  const size_t outputNum = opDescInfo.output_format.size();

  ACL_REQUIRES_POSITIVE(inputNum);
  ACL_REQUIRES_POSITIVE(outputNum);
  *inputDesc = new (std::nothrow) aclTensorDesc[inputNum];
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(*inputDesc);
  *outputDesc = new (std::nothrow) aclTensorDesc[outputNum];
  if (*outputDesc == nullptr) {
    ACL_LOG_INNER_ERROR("[Check][outputDesc]alloc outputDesc memory failed");
    ACL_DELETE_ARRAY_AND_SET_NULL(*inputDesc);
    return ACL_ERROR_FAILURE;
  }
  ACL_REQUIRES_EQ(opDescInfo.input_data_type.size(), inputNum);
  ACL_REQUIRES_EQ(opDescInfo.input_shape.size(), inputNum);
  ACL_REQUIRES_EQ(opDescInfo.input_addrs.size(), inputNum);
  for (size_t idx = 0U; idx < inputNum; ++idx) {
    (*inputDesc)[idx].format = static_cast<aclFormat>(opDescInfo.input_format[idx]);
    (*inputDesc)[idx].dataType = static_cast<aclDataType>(opDescInfo.input_data_type[idx]);
    (*inputDesc)[idx].dims.assign(opDescInfo.input_shape[idx].begin(), opDescInfo.input_shape[idx].end());
    (*inputDesc)[idx].address = opDescInfo.input_addrs[idx];
  }
  ACL_REQUIRES_EQ(opDescInfo.output_data_type.size(), outputNum);
  ACL_REQUIRES_EQ(opDescInfo.output_shape.size(), outputNum);
  ACL_REQUIRES_EQ(opDescInfo.output_addrs.size(), outputNum);
  for (size_t idx = 0U; idx < outputNum; ++idx) {
    (*outputDesc)[idx].format = static_cast<aclFormat>(opDescInfo.output_format[idx]);
    (*outputDesc)[idx].dataType = static_cast<aclDataType>(opDescInfo.output_data_type[idx]);
    (*outputDesc)[idx].dims.assign(opDescInfo.output_shape[idx].begin(), opDescInfo.output_shape[idx].end());
    (*outputDesc)[idx].address = opDescInfo.output_addrs[idx];
  }
  *numInputs = inputNum;
  *numOutputs = outputNum;
  ACL_LOG_INFO(
      "successfully execute aclmdlCreateAndGetOpDesc, deviceId[%u], streamId[%u], "
      "taskId[%u], numInputs[%zu], numOutputs[%zu]",
      deviceId, streamId, taskId, *numInputs, *numOutputs);
  return ACL_SUCCESS;
}

static aclError LoadFromFile(const aclmdlConfigHandle *handle, const std::vector<ge::FileConstantMem> &fileConstantMems,
                             uint32_t *const modelId) {
  bool isSupportRT2 = false;
  ACL_REQUIRES_OK(acl::DetectModelTypeInLoadWithConfig(handle, handle->loadPath.c_str(), nullptr, 0, isSupportRT2));
  if (isSupportRT2) {
    return acl::RuntimeV2ModelLoadFromFileWithMem(handle->loadPath.c_str(), modelId, nullptr, 0U, handle->priority,
                                                  fileConstantMems);
  }
  ge::ModelLoadArg loadArgs{};
  loadArgs.file_constant_mems = fileConstantMems;
  loadArgs.need_clear_dfx_cache = handle->withoutGraph;
  return acl::ModelLoadFromFileWithMem(handle->loadPath.c_str(), modelId, loadArgs, handle->priority);
}

static aclError LoadFromFileWithMem(const aclmdlConfigHandle *handle,
                                    const std::vector<ge::FileConstantMem> &fileConstantMems, uint32_t *const modelId) {
  bool isSupportRT2 = false;
  ACL_REQUIRES_OK(acl::DetectModelTypeInLoadWithConfig(handle, handle->loadPath.c_str(), nullptr, 0, isSupportRT2));
  if (isSupportRT2) {
    return acl::RuntimeV2ModelLoadFromFileWithMem(handle->loadPath.c_str(), modelId, handle->weightPtr,
                                                  handle->weightSize, handle->priority, fileConstantMems);
  }
  const auto loadArgs = ConstructGeModelLoadArg(handle->workPtr, handle->workSize, handle->weightPtr,
                                                handle->weightSize, nullptr, fileConstantMems, handle->withoutGraph);
  return acl::ModelLoadFromFileWithMem(handle->loadPath.c_str(), modelId, loadArgs, handle->priority);
}

static aclError LoadFromMem(const aclmdlConfigHandle *handle, const std::vector<ge::FileConstantMem> &fileConstantMems,
                            uint32_t *const modelId) {
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle->mdlAddr);
  bool isSupportRT2 = false;
  ACL_REQUIRES_OK(
      acl::DetectModelTypeInLoadWithConfig(handle, nullptr, handle->mdlAddr, handle->mdlSize, isSupportRT2));
  if (isSupportRT2) {
    return acl::RuntimeV2ModelLoadFromMemWithMem(handle->mdlAddr, handle->mdlSize, handle->loadPath, modelId, nullptr,
                                                 0U, handle->weightPath.c_str(), handle->priority, fileConstantMems);
  }
  ge::ModelLoadArg loadArgs{};
  loadArgs.file_constant_mems = fileConstantMems;
  loadArgs.need_clear_dfx_cache = handle->withoutGraph;
  return acl::ModelLoadFromMemWithMem(handle->mdlAddr, handle->mdlSize, "", modelId, loadArgs,
                                      handle->weightPath.c_str(), handle->priority);
}

static aclError LoadFromMemWithMem(const aclmdlConfigHandle *handle,
                                   const std::vector<ge::FileConstantMem> &fileConstantMems, uint32_t *const modelId) {
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle->mdlAddr);
  bool isSupportRT2 = false;
  ACL_REQUIRES_OK(
      acl::DetectModelTypeInLoadWithConfig(handle, nullptr, handle->mdlAddr, handle->mdlSize, isSupportRT2));
  if (isSupportRT2) {
    return acl::RuntimeV2ModelLoadFromMemWithMem(handle->mdlAddr, handle->mdlSize, handle->loadPath, modelId,
                                                 handle->weightPtr, handle->weightSize, handle->weightPath.c_str(),
                                                 handle->priority, fileConstantMems);
  }
  const auto loadArgs = ConstructGeModelLoadArg(handle->workPtr, handle->workSize, handle->weightPtr,
                                                handle->weightSize, nullptr, fileConstantMems, handle->withoutGraph);
  return acl::ModelLoadFromMemWithMem(handle->mdlAddr, handle->mdlSize, handle->loadPath, modelId, loadArgs,
                                      handle->weightPath.c_str(), handle->priority);
}

static aclError LoadFromFileWithQ(const aclmdlConfigHandle *handle,
                                  const std::vector<ge::FileConstantMem> &fileConstantMems, uint32_t *const modelId) {
  if (aclmdlCheckQueueParam(handle->inputQ, handle->inputQNum, handle->outputQ, handle->outputQNum) != ACL_SUCCESS) {
    return ACL_ERROR_INVALID_PARAM;
  }
  std::vector<uint32_t> inputQVec(handle->inputQ, handle->inputQ + handle->inputQNum);
  std::vector<uint32_t> outputQVec(handle->outputQ, handle->outputQ + handle->outputQNum);
  ge::ModelQueueArg args{std::move(inputQVec), std::move(outputQVec), fileConstantMems, handle->withoutGraph};
  return acl::ModelLoadFromFileWithQ(handle->loadPath.c_str(), modelId, args, handle->priority);
}

static aclError LoadFromMemWithQ(const aclmdlConfigHandle *handle,
                                 const std::vector<ge::FileConstantMem> &fileConstantMems, uint32_t *const modelId) {
  if (aclmdlCheckQueueParam(handle->inputQ, handle->inputQNum, handle->outputQ, handle->outputQNum) != ACL_SUCCESS) {
    return ACL_ERROR_INVALID_PARAM;
  }
  std::vector<uint32_t> inputQVec(handle->inputQ, handle->inputQ + handle->inputQNum);
  std::vector<uint32_t> outputQVec(handle->outputQ, handle->outputQ + handle->outputQNum);
  ge::ModelQueueArg que_args{std::move(inputQVec), std::move(outputQVec), fileConstantMems, handle->withoutGraph};
  return acl::ModelLoadFromMemWithQ(handle->mdlAddr, handle->mdlSize, modelId, que_args, handle->priority);
}

aclError aclmdlLoadWithConfigImpl(const aclmdlConfigHandle *handle, uint32_t *modelId) {
  ACL_PROFILING_REG(acl::AclProfType::AclmdlLoadWithConfig);
  ACL_LOG_INFO("start to execute aclmdlLoadWithConfig");
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle);
  ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelId);
  if (!acl::CheckMdlConfigHandle(handle)) {
    ACL_LOG_ERROR("[Check][ConfigHandle]model config is invalid because some params may not be set or invalid");
    return ACL_ERROR_INVALID_PARAM;
  }
  acl::UpdateGraphOptions(OPTION_EXEC_REUSE_ZERO_COPY_MEMORY, std::to_string(handle->reuseZeroCopy));
  auto &file_constant_mems = handle->fileConstantMem;
  for (const auto &file_constant_mem : file_constant_mems) {
    ACL_LOG_INFO("file constant name[%s], device memory address[%p], device memory size[%zu]",
                 file_constant_mem.file_name.c_str(), file_constant_mem.device_mem, file_constant_mem.mem_size);
  }
  switch (static_cast<int32_t>(handle->mdlLoadType)) {
    case ACL_MDL_LOAD_FROM_FILE:
      return LoadFromFile(handle, file_constant_mems, modelId);
    case ACL_MDL_LOAD_FROM_FILE_WITH_MEM:
      return LoadFromFileWithMem(handle, file_constant_mems, modelId);
    case ACL_MDL_LOAD_FROM_MEM:
      return LoadFromMem(handle, file_constant_mems, modelId);
    case ACL_MDL_LOAD_FROM_MEM_WITH_MEM:
      return LoadFromMemWithMem(handle, file_constant_mems, modelId);
    case ACL_MDL_LOAD_FROM_FILE_WITH_Q:
      return LoadFromFileWithQ(handle, file_constant_mems, modelId);
    case ACL_MDL_LOAD_FROM_MEM_WITH_Q:
      return LoadFromMemWithQ(handle, file_constant_mems, modelId);
    default:
      ACL_LOG_INNER_ERROR("[Load][Model]model load type[%zu] is invalid, it should be in [%d, %d]", handle->mdlLoadType,
                          ACL_MDL_LOAD_FROM_FILE, ACL_MDL_LOAD_FROM_MEM_WITH_Q);
      return ACL_ERROR_INVALID_PARAM;
  }
}

aclError aclRecoverAllHcclTasksImpl(int32_t deviceId) {
  ACL_LOG_INFO("start to execute aclRecoverAllHcclTasks in device %d", deviceId);
  ge::GeExecutor executor;
  const ge::Status ret = executor.RecoverAllModel(deviceId);
  ACL_CHECK_WITH_MESSAGE_AND_RETURN(ret == ge::SUCCESS, ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret)),
                                    "call RecoverAllModel fail in deviceid %d", deviceId);
  ACL_LOG_INFO("end to execute aclRecoverAllHcclTasks in device %d", deviceId);
  return ACL_SUCCESS;
}