* 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/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/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 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);
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);
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);
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); });
modelData.priority = priority;
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);
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_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;
}
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) {
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;
}
}
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();
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);
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));
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 ¤tModelId,
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,
¤tModelId, loadArgs.weight_ptr, loadArgs.weight_size,
weightPath, priority, loadArgs.file_constant_mems, rtSession);
} else {
ret = acl::ModelLoadFromMemWithMem(currentModePtr, modelSize, modelPath, ¤tModelId, 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)
{
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)
{
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);
info.loadedSubModelIdSet.insert(currentModelId);
}
if (!info.fromFilePath.empty()) {
info.bundleModelData = nullptr;
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);
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;
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;
}
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);
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;
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;
}
}
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) {
const auto ret = UnloadModelInner(modelId);
if (ret != ACL_SUCCESS) {
finalRet = ret;
}
}
ACL_REQUIRES_OK(finalRet);
acl::AclResourceManager::GetInstance().DeleteBundleInfo(bundleId);
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));
}
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);
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;
}