diff --git a/inc/external/acl/acl_mdl.h b/inc/external/acl/acl_mdl.h index 17940c175cb71547fb3be79a29b4c230b669b672..6420cf7eb08daf86caed3bd5385fac377235017f 100755 --- a/inc/external/acl/acl_mdl.h +++ b/inc/external/acl/acl_mdl.h @@ -54,6 +54,7 @@ typedef struct aclmdlAIPP aclmdlAIPP; typedef struct aclAippExtendInfo aclAippExtendInfo; typedef struct aclmdlConfigHandle aclmdlConfigHandle; typedef struct aclmdlExecConfigHandle aclmdlExecConfigHandle; +typedef struct aclmdlBundleQueryInfo aclmdlBundleQueryInfo; typedef enum { ACL_YUV420SP_U8 = 1, @@ -517,6 +518,193 @@ ACL_FUNC_VISIBILITY aclError aclmdlBundleGetModelNum(uint32_t bundleId, size_t * */ ACL_FUNC_VISIBILITY aclError aclmdlBundleGetModelId(uint32_t bundleId, size_t index, uint32_t *modelId); +/** + * @ingroup AscendCL + * @brief Create data of type aclmdlBundleQueryInfo + * + * @retval the aclmdlBundleQueryInfo pointer + */ +ACL_FUNC_VISIBILITY aclmdlBundleQueryInfo* aclmdlBundleCreateQueryInfo(); + +/** + * @ingroup AscendCL + * @brief destroy data of type aclmdlBundleQueryInfo + * + * @param modelDesc [IN] Pointer to aclmdlBundleQueryInfo to be destroyed + * + * @retval ACL_SUCCESS The function is successfully executed. + * @retval OtherValues Failure + */ +ACL_FUNC_VISIBILITY aclError aclmdlBundleDestroyQueryInfo(aclmdlBundleQueryInfo *queryInfo); + +/** + * @ingroup AscendCL + * @brief Get the bundle om query info + * + * @param fileName [IN] Model path to get memory information + * @param queryInfo [OUT] The aclmdlBundleQueryInfo struct which is acquired by aclmdlBundleCreateQueryInfo + * + * @retval ACL_SUCCESS The function is successfully executed. + * @retval OtherValues Failure + */ +ACL_FUNC_VISIBILITY aclError aclmdlBundleQueryInfoFromFile(const char* fileName, aclmdlBundleQueryInfo *queryInfo); + +/** + * @ingroup AscendCL + * @brief Get the bundle om query info + * + * @param model [IN] model memory which user manages + * @param modelSize [IN] model data size + * @param queryInfo [OUT] The aclmdlBundleQueryInfo struct which is acquired by aclmdlBundleCreateQueryInfo + * + * @retval ACL_SUCCESS The function is successfully executed. + * @retval OtherValues Failure + */ +ACL_FUNC_VISIBILITY aclError aclmdlBundleQueryInfoFromMem(const void *model, size_t modelSize, + aclmdlBundleQueryInfo *queryInfo); + +/** + * @ingroup AscendCL + * @brief Get the bundle om inner model num + * + * @param queryInfo [IN] The aclmdlBundleQueryInfo struct which is acquired by aclmdlBundleQuerySizexx + * @param modelNum [OUT] the pointer to model num + * + * @retval ACL_SUCCESS The function is successfully executed. + * @retval OtherValues Failure + */ +ACL_FUNC_VISIBILITY aclError aclmdlBundleGetQueryModelNum(const aclmdlBundleQueryInfo *queryInfo, size_t *modelNum); + +/** + * @ingroup AscendCL + * @brief Get the bundle om variable weight size + * + * @param queryInfo [IN] The aclmdlBundleQueryInfo struct which is acquired by aclmdlBundleQuerySizexx + * @param variableWeightSize [OUT] the pointer to variable weight size + * + * @retval ACL_SUCCESS The function is successfully executed. + * @retval OtherValues Failure + */ +ACL_FUNC_VISIBILITY aclError aclmdlBundleGetVarWeightSize(const aclmdlBundleQueryInfo *queryInfo, + size_t *variableWeightSize); + +/** + * @ingroup AscendCL + * @brief Get the bundle om variable weight size + * + * @param queryInfo [IN] The aclmdlBundleQueryInfo struct which is acquired by aclmdlBundleQuerySizexx + * @param index [IN] The inner model index + * @param workSize [OUT] The amount of working memory for model executed + * @param constWeightSize [OUT] The amount of weight memory for model executed + * + * @retval ACL_SUCCESS The function is successfully executed. + * @retval OtherValues Failure + */ +ACL_FUNC_VISIBILITY aclError aclmdlBundleGetSize(const aclmdlBundleQueryInfo *queryInfo, size_t index, + size_t *workSize, size_t *constWeightSize); + +/** + * @ingroup AscendCL + * @brief init bundle model data from file + * + * @par Function + * After the system finishes loading the bundle model, + * the bundle model ID returned is used as a mark to identify the bundle model + * during subsequent operations + * + * @param modelPath [IN] Storage path for offline bundle model file + * @param varWeightPtr [IN] the pointer to varWeight, can be null + * @param varWeightSize [IN] varWeightSize + * @param bundleId [OUT] Bundle model id generated + * + * @retval ACL_SUCCESS The function is successfully executed. + * @retval OtherValues Failure + */ +ACL_FUNC_VISIBILITY aclError aclmdlBundleInitFromFile(const char* modelPath, void *varWeightPtr, + size_t varWeightSize, uint32_t *bundleId); + +/** + * @ingroup AscendCL + * @brief init bundle model data from mem + * + * @par Function + * After the system finishes loading the bundle model, + * the bundle model ID returned is used as a mark to identify the bundle model + * during subsequent operations + * + * @param model [IN] model memory which user manages + * @param modelSize [IN] model data size + * @param varWeightPtr [IN] the pointer to varWeight, can be null + * @param varWeightSize [IN] varWeightSize + * @param bundleId [OUT] Bundle model id generated + * + * @retval ACL_SUCCESS The function is successfully executed. + * @retval OtherValues Failure + */ +ACL_FUNC_VISIBILITY aclError aclmdlBundleInitFromMem(const void* model, size_t modelSize, void *varWeightPtr, + size_t varWeightSize, uint32_t *bundleId); + +/** + * @ingroup AscendCL + * @brief Load bundle model inner model + * + * @param bundleId [IN] Bundle model id generated after + * @param index [IN] Bundle om inner model index + * @param modelId [IN] inner model id loaded which can be executed + * + * @retval ACL_SUCCESS The function is successfully executed. + * @retval OtherValues Failure + */ +ACL_FUNC_VISIBILITY aclError aclmdlBundleLoadModel(uint32_t bundleId, size_t index, uint32_t *modelId); + +/** + * @ingroup AscendCL + * @brief Load bundle model inner model with mem + * + * @param bundleId [IN] Bundle model id generated after + * @param index [IN] Bundle om inner model index + * @param workPtr [IN] A pointer to the working memory + * required by the model on the Device,can be null + * @param workSize [IN] work memory size + * @param weightPtr [IN] Pointer to model weight memory on Device,can be null + * @param weightSize [IN] The amount of weight memory required by the model + + * @param modelId [IN] inner model id loaded which can be executed + * + * @retval ACL_SUCCESS The function is successfully executed. + * @retval OtherValues Failure + */ +ACL_FUNC_VISIBILITY aclError aclmdlBundleLoadModelWithMem(uint32_t bundleId, size_t index, void *workPtr, + size_t workSize, void *weightPtr, + size_t weightSize, uint32_t *modelId); + +/** + * @ingroup AscendCL + * @brief Load bundle model inner model + * + * @param bundleId [IN] Bundle model id generated after + * @param index [IN] Bundle om inner model index + * @param handle [IN] pointer to model config handle + * @param modelId [IN] inner model id loaded which can be executed + * + * @retval ACL_SUCCESS The function is successfully executed. + * @retval OtherValues Failure + */ +ACL_FUNC_VISIBILITY aclError aclmdlBundleLoadModelWithConfig(uint32_t bundleId, size_t index, + aclmdlConfigHandle *handle, uint32_t *modelId); + +/** + * @ingroup AscendCL + * @brief unload bundle inner model with model id + * + * @param bundleId [IN] Bundle model id generated after + * @param modelId [IN] inner model id to be unloaded + * + * @retval ACL_SUCCESS The function is successfully executed. + * @retval OtherValues Failure + */ +ACL_FUNC_VISIBILITY aclError aclmdlBundleUnloadModel(uint32_t bundleId, uint32_t modelId); + /** * @ingroup AscendCL * @brief Load offline model data from memory and manage the memory of diff --git a/model/acl_resource_manager.cpp b/model/acl_resource_manager.cpp index cbfdcef926904f0e4f8774f197a1d2d9bd720213..4438248bfd6f7685f81bcc958f209134e43b50f4 100644 --- a/model/acl_resource_manager.cpp +++ b/model/acl_resource_manager.cpp @@ -43,16 +43,31 @@ AclResourceManager::AclResourceManager() GetRuntimeV2Env(); } -void AclResourceManager::AddBundleInfo(const uint32_t bundleId, const std::vector &bundleInfos) +void AclResourceManager::AddBundleSubmodelId(const uint32_t bundleId, uint32_t modelId) +{ + const std::lock_guard locker(mutex_); + bundleInfos_[bundleId].loadedSubModelIdSet.insert(modelId); + (void)bundleInnerIds_.insert(modelId); +} + +void AclResourceManager::DeleteBundleSubmodelId(const uint32_t bundleId, uint32_t modelId) +{ + const std::lock_guard locker(mutex_); + bundleInfos_[bundleId].loadedSubModelIdSet.erase(modelId); + (void)bundleInnerIds_.erase(modelId); +} + +aclError AclResourceManager::SetBundleInfo(const uint32_t bundleId, const BundleModelInfo &bundleInfos) { const std::lock_guard locker(mutex_); bundleInfos_[bundleId] = bundleInfos; - for (const auto &info : bundleInfos) { - (void)bundleInnerIds_.insert(info.modelId); + for (const auto &modelId : bundleInfos.loadedSubModelIdSet) { + (void)bundleInnerIds_.insert(modelId); } + return ACL_SUCCESS; } -aclError AclResourceManager::GetBundleInfo(const uint32_t bundleId, std::vector &bundleInfos) +aclError AclResourceManager::GetBundleInfo(const uint32_t bundleId, BundleModelInfo &bundleInfos) { const std::lock_guard locker(mutex_); const auto it = bundleInfos_.find(bundleId); @@ -75,8 +90,8 @@ void AclResourceManager::DeleteBundleInfo(const uint32_t bundleId) const std::lock_guard locker(mutex_); const auto it = bundleInfos_.find(bundleId); if (it != bundleInfos_.end()) { - for (const auto &info : it->second) { - (void)bundleInnerIds_.erase(info.modelId); + for (const auto &id : it->second.loadedSubModelIdSet) { + (void)bundleInnerIds_.erase(id); } (void)bundleInfos_.erase(it); } diff --git a/model/acl_resource_manager.h b/model/acl_resource_manager.h index 28a4a0c8cef4c4c43438f5f22be868130334eaff..f60f130620f887b829641d3820075cc8aa57c655 100644 --- a/model/acl_resource_manager.h +++ b/model/acl_resource_manager.h @@ -27,6 +27,7 @@ #include "single_op/compile/op_compiler.h" #include "utils/acl_op_map.h" #include "utils/string_utils.h" +#include "model_desc_internal.h" #include "framework/runtime/mem_allocator.h" #include "framework/runtime/model_v2_executor.h" #include "framework/runtime/stream_executor.h" @@ -61,8 +62,16 @@ public: aclrtAllocatorGetAddrFromBlockFunc getAddrFromBlockFunc_{ nullptr }; }; -struct BundleInfo { - uint32_t modelId = 0; +struct BundleModelInfo { + bool is_init = false; // aclmdlBundleInit scene means true + std::shared_ptr rtSession; + size_t varSize = 0U; + std::string fromFilePath; + std::shared_ptr bundleModelData; + size_t bundleModelSize = 0U; + std::vector subModelInfos; + std::vector loadedSubModelId; // aclmdlBundleGetModelId use this when aclmdlBundleLoadFromxx is called + std::set loadedSubModelIdSet; }; class ACL_FUNC_VISIBILITY AclResourceManager { @@ -136,9 +145,13 @@ public: gert::Allocators *CreateDefaultAllocators(const void * const cacheKey); - void AddBundleInfo(const uint32_t bundleId, const std::vector &bundleInfos); + void AddBundleSubmodelId(const uint32_t bundleId, uint32_t modelId); - aclError GetBundleInfo(const uint32_t bundleId, std::vector &bundleInfos); + void DeleteBundleSubmodelId(const uint32_t bundleId, uint32_t modelId); + + aclError SetBundleInfo(const uint32_t bundleId, const BundleModelInfo &bundleInfos); + + aclError GetBundleInfo(const uint32_t bundleId, BundleModelInfo &bundleInfos); void DeleteBundleInfo(const uint32_t bundleId); @@ -201,7 +214,7 @@ private: ModelMap opModels_; OpModelCache modelCache_; - std::unordered_map> bundleInfos_; + std::unordered_map bundleInfos_; std::unordered_set bundleInnerIds_; }; } diff --git a/model/model.cpp b/model/model.cpp index 2f0671b1d3a8db9504ce84aeefeaac2ef23ecd39..7332eb9c68ef57d68873d7302d66436ff4fd8fa8 100755 --- a/model/model.cpp +++ b/model/model.cpp @@ -58,6 +58,7 @@ constexpr const char_t *MODEL_ID_STR = "modelId"; constexpr const char_t *OPTION_EXEC_REUSE_ZERO_COPY_MEMORY = "ge.exec.reuseZeroCopyMemory"; std::mutex aclmdlGetOpAttrMutex; +std::mutex aclmdlBundleMutex; enum class DimsType : std::uint8_t { DIMS_TYPE_V1 = 0, @@ -448,9 +449,9 @@ static aclError IsSupportRuntimeV2WithModelPath(const char *filePath, bool &isSu } static aclError GetBundleNumAndOffset(const void *const model, const size_t modelSize, - bool &isBundleOm, std::vector> &offsetAndSize) + size_t &varSize, std::vector> &subModelOffsetAndSize) { - isBundleOm = false; + varSize = 0; 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.", @@ -459,11 +460,10 @@ static aclError IsSupportRuntimeV2WithModelPath(const char *filePath, bool &isSu } const auto *fileHeader = ge::PtrToPtr(model); if (fileHeader->modeltype != ge::MODEL_TYPE_BUNDLE_MODEL) { - ACL_LOG_INFO("this is not bundle om"); - return ACL_SUCCESS; + ACL_LOG_ERROR("this is not bundle om, please check"); + return ACL_ERROR_INVALID_PARAM; } currentOffset += sizeof(ge::ModelFileHeader); - isBundleOm = true; const auto *partitionTable = ge::PtrToPtr(ge::ValueToPtr(ge::PtrToValue(model) + currentOffset)); const size_t partitionTableSize = ge::SizeOfModelPartitionTable(*partitionTable); @@ -472,13 +472,17 @@ static aclError IsSupportRuntimeV2WithModelPath(const char *filePath, bool &isSu 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); + 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(ge::ValueToPtr(ge::PtrToValue(model) + currentOffset)); + ACL_LOG_INFO("get var size %zu", varSize); + } if (partitionTable->partition[i].type == ge::BUNDLE_MODEL_INFO) { - offsetAndSize.emplace_back(currentOffset, partitionTable->partition[i].mem_size); + 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); + ACL_REQUIRES_OK(acl::CheckSizeTAddOverflow(currentOffset, + partitionTable->partition[i].mem_size, currentOffset)); + ACL_REQUIRES_LE(currentOffset, modelSize); } return ACL_SUCCESS; } @@ -1844,47 +1848,106 @@ static aclError UnloadModelInner(const uint32_t modelId) return ACL_SUCCESS; } -static aclError BundleLoadFromMem(const void *model, size_t modelSize, - const std::string &modelPath, uint32_t *bundleId) +static aclError QueryBundleSubModelInfo(const void *data, size_t modelSize, aclmdlBundleQueryInfo *queryInfo) { + std::vector> subModelOffsetAndSize; + size_t varSize = 0; + ACL_REQUIRES_OK(acl::GetBundleNumAndOffset(data, modelSize, varSize, subModelOffsetAndSize)); + queryInfo->varSize = static_cast(varSize); + for (const auto &ele : subModelOffsetAndSize) { + acl::BundleSubModelInfo tmpInfo; + tmpInfo.offset = ele.first; + tmpInfo.modelSize = ele.second; + bool isSupportRT2 = false; + void *currentModePtr = ge::ValueToPtr(ge::PtrToValue(data) + ele.first); + ACL_REQUIRES_OK(acl::IsSupportRuntimeV2WithModelData(currentModePtr, ele.second, isSupportRT2)); + // only static shape model can query size + if (!isSupportRT2) { + ge::GeExecutor executor; + ACL_REQUIRES_CALL_GE_OK(executor.GetMemAndWeightSize(currentModePtr, ele.second, + tmpInfo.workSize, tmpInfo.weightSize), "Query size failed"); + } + ACL_LOG_INFO("get work size %zu, weight size %zu", tmpInfo.workSize, tmpInfo.weightSize); + queryInfo->subModelInfos.emplace_back(tmpInfo); + } + return ACL_SUCCESS; +} + +static aclError LoadBundleSubModelFromMem(const void *const currentModePtr, const size_t modelSize, + const std::string &modelPath, std::shared_ptr &rtSession, + const ge::ModelLoadArg &loadArgs, uint32_t ¤tModelId, + const char_t *const weightPath = nullptr, const int32_t priority = 0) { - // get bundle num from file header - bool isBundleOm = false; - std::vector> offsetAndSize; - ACL_REQUIRES_OK(acl::GetBundleNumAndOffset(model, modelSize, isBundleOm, offsetAndSize)); - if (!isBundleOm) { - ACL_LOG_ERROR("this is not bundle om, please check"); - return ACL_ERROR_INVALID_PARAM; + 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); } - std::vector bundleInfos; + return ret; +} + +static aclError BundleInitFromMem(std::shared_ptr model, size_t modelSize, const std::string &modelPath, + void *varWeightPtr, size_t varWeightSize, uint32_t *bundleId) +{ + (void)varWeightPtr; + (void)varWeightSize; + // get bundle num from file header + std::vector> subModelOffsetAndSize; + size_t varSize = 0; + ACL_REQUIRES_OK(acl::GetBundleNumAndOffset(model.get(), modelSize, varSize, subModelOffsetAndSize)); auto rtSession = acl::AclResourceManager::GetInstance().CreateRtSession(); ACL_REQUIRES_NOT_NULL(rtSession); - for (const auto &offsetSize : offsetAndSize) { - acl::BundleInfo bundleInfo{}; + rtSession->SetExternalVar(varWeightPtr, varWeightSize); + acl::AclResourceManager::GetInstance().AddExecutor(*bundleId, nullptr, rtSession); + acl::BundleModelInfo info; + info.is_init = 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 model, size_t modelSize, const std::string &modelPath, + uint32_t *bundleId) +{ + // BundleLoadFromMem = BundleInitFromMem + load sub model + ACL_REQUIRES_OK(BundleInitFromMem(model, modelSize, modelPath, nullptr, 0, bundleId)); + acl::BundleModelInfo info; + ACL_REQUIRES_OK(acl::AclResourceManager::GetInstance().GetBundleInfo(*bundleId, info)); + info.is_init = false; + const auto loadArgs = ConstructGeModelLoadArg(nullptr, 0, nullptr, 0, info.rtSession.get(), {}); + for (const auto &subInfo : info.subModelInfos) { uint32_t currentModelId = 0U; - bool isSupportRT2 = false; - void *currentModePtr = ge::ValueToPtr(ge::PtrToValue(model) + offsetSize.first); - ACL_REQUIRES_OK(acl::IsSupportRuntimeV2WithModelData(currentModePtr, offsetSize.second, isSupportRT2)); - aclError ret = ACL_SUCCESS; - if (isSupportRT2) { - ret = acl::RuntimeV2ModelLoadFromMemWithMem(currentModePtr, offsetSize.second, modelPath, - ¤tModelId, nullptr, 0U, nullptr, 0, {}, rtSession); - } else { - const auto loadArgs = ConstructGeModelLoadArg(nullptr, 0U, nullptr, - 0U, rtSession.get(), {}); - ret = acl::ModelLoadFromMemWithMem(currentModePtr, offsetSize.second, modelPath, - ¤tModelId, loadArgs, nullptr, 0); - } + 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 : bundleInfos) { - (void)UnloadModelInner(ele.modelId); + for (const auto &ele : info.loadedSubModelIdSet) { + (void)UnloadModelInner(ele); } return ret; } - bundleInfo.modelId = currentModelId; - bundleInfos.emplace_back(bundleInfo); + info.loadedSubModelId.emplace_back(currentModelId); // only BundleLoadFromMem need set + info.loadedSubModelIdSet.insert(currentModelId); } - acl::AclResourceManager::GetInstance().AddExecutor(*bundleId, nullptr, rtSession); - acl::AclResourceManager::GetInstance().AddBundleInfo(*bundleId, bundleInfos); + if (!info.fromFilePath.empty()) { + info.bundleModelData = nullptr; // need reset nullptr when aclmdlBundleLoadFromFile to ensure compatibility + info.bundleModelSize = 0; + } + acl::AclResourceManager::GetInstance().SetBundleInfo(*bundleId, info); return ACL_SUCCESS; } @@ -1902,20 +1965,20 @@ aclError aclmdlBundleLoadFromFile(const char *modelPath, uint32_t *bundleId) ge::graphStatus ret = ge::GRAPH_SUCCESS; ACL_LOG_INFO("call ge interface gert::LoadDataFromFile"); ret = gert::LoadDataFromFile(modelPath, modelData); - std::shared_ptr data; - data.reset(modelData.model_data, [](const void * const p) { delete[] static_cast(p); }); + std::shared_ptr data; + data.reset(ge::PtrToPtr(modelData.model_data), std::default_delete()); 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(ret)); } - ACL_REQUIRES_OK(BundleLoadFromMem(modelData.model_data, modelData.model_len, modelPath, bundleId)); + ACL_REQUIRES_OK(BundleLoadFromMem(data, modelData.model_len, modelPath, bundleId)); ACL_ADD_APPLY_SUCCESS_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL); ACL_LOG_INFO("successfully execute aclmdlBundleLoadFromFile, bundle id is %u", *bundleId); return ACL_SUCCESS; } -aclError aclmdlBundleLoadFromMem(const void *model, size_t modelSize, uint32_t *bundleId) +aclError aclmdlBundleLoadFromMem(const void *model, size_t modelSize, uint32_t *bundleId) { ACL_PROFILING_REG(acl::AclProfType::AclmdlBundleLoadFromMem); ACL_ADD_APPLY_TOTAL_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL); @@ -1923,8 +1986,10 @@ aclError aclmdlBundleLoadFromMem(const void *model, size_t modelSize, uint32_t ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(model); ACL_REQUIRES_POSITIVE_WITH_INPUT_REPORT(modelSize); ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(bundleId); - - ACL_REQUIRES_OK(BundleLoadFromMem(model, modelSize, "", bundleId)); + std::shared_ptr data; + // no delete func + data.reset(ge::PtrToPtr(const_cast(model)), [](const uint8_t* const p) { (void) p; }); + ACL_REQUIRES_OK(BundleLoadFromMem(data, modelSize, "", bundleId)); ACL_LOG_INFO("execute aclmdlBundleLoadFromMem success, bundleId[%u]", *bundleId); ACL_ADD_APPLY_SUCCESS_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL); @@ -2012,9 +2077,9 @@ aclError aclmdlLoadFromMem(const void *model, size_t modelSize, uint32_t *modelI aclError aclmdlBundleGetModelNum(uint32_t bundleId, size_t *modelNum) { ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelNum); - std::vector bundleInfos; + acl::BundleModelInfo bundleInfos; ACL_REQUIRES_OK(acl::AclResourceManager::GetInstance().GetBundleInfo(bundleId, bundleInfos)); - *modelNum = bundleInfos.size(); + *modelNum = bundleInfos.subModelInfos.size(); ACL_LOG_INFO("get bundleId %u model num %zu", bundleId, *modelNum); return ACL_SUCCESS; } @@ -2022,18 +2087,233 @@ aclError aclmdlBundleGetModelNum(uint32_t bundleId, size_t *modelNum) aclError aclmdlBundleGetModelId(uint32_t bundleId, size_t index, uint32_t *modelId) { ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelId); - std::vector bundleInfos; + acl::BundleModelInfo bundleInfos; ACL_REQUIRES_OK(acl::AclResourceManager::GetInstance().GetBundleInfo(bundleId, bundleInfos)); - if (index >= bundleInfos.size()) { + if (bundleInfos.is_init) { + 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.size()); + bundleId, index, bundleInfos.loadedSubModelId.size()); return ACL_ERROR_INVALID_PARAM; } - *modelId = bundleInfos[index].modelId; + *modelId = bundleInfos.loadedSubModelId[index]; ACL_LOG_INFO("get bundleId %u index %zu model id %u", bundleId, index, *modelId); return ACL_SUCCESS; } +aclmdlBundleQueryInfo* aclmdlBundleCreateQueryInfo() { + ACL_ADD_APPLY_TOTAL_COUNT(acl::ACL_STATISTICS_CREATE_DESTROY_BUNDLE_QUERY_INFO); + ACL_ADD_APPLY_SUCCESS_COUNT(acl::ACL_STATISTICS_CREATE_DESTROY_BUNDLE_QUERY_INFO); + return new(std::nothrow) aclmdlBundleQueryInfo(); +} + +aclError aclmdlBundleDestroyQueryInfo(aclmdlBundleQueryInfo *queryInfo) +{ + ACL_ADD_RELEASE_TOTAL_COUNT(acl::ACL_STATISTICS_CREATE_DESTROY_BUNDLE_QUERY_INFO); + ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(queryInfo); + ACL_DELETE_AND_SET_NULL(queryInfo); + ACL_ADD_RELEASE_SUCCESS_COUNT(acl::ACL_STATISTICS_CREATE_DESTROY_BUNDLE_QUERY_INFO); + return ACL_SUCCESS; +} + +aclError aclmdlBundleQueryInfoFromFile(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 aclmdlBundleQuerySize %s", fileName); + // 1. load model data from file + ge::ModelData modelData; + modelData.om_path = fileName; + ge::graphStatus ret = ge::GRAPH_SUCCESS; + ACL_LOG_INFO("call ge interface gert::LoadDataFromFile"); + ret = gert::LoadDataFromFile(fileName, modelData); + std::shared_ptr data; + data.reset(ge::PtrToPtr(modelData.model_data), std::default_delete()); + 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(ret)); + } + ACL_REQUIRES_OK(QueryBundleSubModelInfo(modelData.model_data, modelData.model_len, queryInfo)); + ACL_LOG_INFO("end to execute aclmdlBundleQuerySize %s", fileName); + return ACL_SUCCESS; +} + +aclError aclmdlBundleQueryInfoFromMem(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 aclmdlBundleQuerySizeFromMem"); + ACL_REQUIRES_OK(QueryBundleSubModelInfo(model, modelSize, queryInfo)); + ACL_LOG_INFO("end to execute aclmdlBundleQuerySizeFromMem"); + return ACL_SUCCESS; +} + +aclError aclmdlBundleGetQueryModelNum(const aclmdlBundleQueryInfo *queryInfo, size_t *modelNum) +{ + ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(queryInfo); + ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelNum); + *modelNum = queryInfo->subModelInfos.size(); + return ACL_SUCCESS; +} + +aclError aclmdlBundleGetVarWeightSize(const aclmdlBundleQueryInfo *queryInfo, size_t *variableWeightSize) +{ + ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(queryInfo); + ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(variableWeightSize); + *variableWeightSize = queryInfo->varSize; + return ACL_SUCCESS; +} + +aclError aclmdlBundleGetSize(const aclmdlBundleQueryInfo *queryInfo, size_t index, size_t *workSize, + size_t *constWeightSize) +{ + ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(queryInfo); + ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(workSize); + ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(constWeightSize); + if (index >= queryInfo->subModelInfos.size()) { + ACL_LOG_ERROR("index %zu should be less than %zu", index, queryInfo->subModelInfos.size()); + return ACL_ERROR_INVALID_PARAM; + } + *workSize = queryInfo->subModelInfos[index].workSize; + *constWeightSize = queryInfo->subModelInfos[index].weightSize; + return ACL_SUCCESS; +} + +aclError aclmdlBundleInitFromFile(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 tmpData; + tmpData.reset(ge::PtrToPtr(modelData.model_data), std::default_delete()); + 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 aclmdlBundleInitFromMem(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 tmpData; + // no delete func + tmpData.reset(ge::PtrToPtr(const_cast(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 aclmdlBundleLoadModel(uint32_t bundleId, size_t index, uint32_t *modelId) +{ + return aclmdlBundleLoadModelWithMem(bundleId, index, nullptr, 0U, nullptr, 0U, modelId); +} + +static aclError GetTargetBundleInfo(uint32_t bundleId, acl::BundleModelInfo &bundleInfos) { + const std::unique_lock lock(aclmdlBundleMutex); + ACL_REQUIRES_OK(acl::AclResourceManager::GetInstance().GetBundleInfo(bundleId, bundleInfos)); + bool need_load_mem_from_file = !bundleInfos.is_init && !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 data; + data.reset(ge::PtrToPtr(modelData.model_data), std::default_delete()); + bundleInfos.bundleModelData = data; + bundleInfos.bundleModelSize = modelData.model_len; + acl::AclResourceManager::GetInstance().SetBundleInfo(bundleId, bundleInfos); + } + return ACL_SUCCESS; +} + +aclError aclmdlBundleLoadModelWithMem(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 aclmdlBundleLoadModelWithConfig(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); + + 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 aclmdlBundleUnloadModel(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)); + acl::AclResourceManager::GetInstance().DeleteBundleSubmodelId(bundleId, modelId); + ACL_LOG_INFO("end to execute aclmdlBundleUnloadModel bundleId %u, modelId %u", bundleId, modelId); + return ACL_SUCCESS; +} + aclError aclmdlLoadFromMemWithMem(const void *model, size_t modelSize, uint32_t *modelId, void *workPtr, size_t workSize, void *weightPtr, size_t weightSize) @@ -2207,12 +2487,12 @@ aclError aclmdlBundleUnload(uint32_t bundleId) ACL_PROFILING_REG(acl::AclProfType::AclmdlBundleUnload); ACL_ADD_RELEASE_TOTAL_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL); ACL_LOG_INFO("start to execute aclmdlBundleUnload %u", bundleId); - std::vector bundleInfos; + acl::BundleModelInfo bundleInfos; ACL_REQUIRES_OK(acl::AclResourceManager::GetInstance().GetBundleInfo(bundleId, bundleInfos)); aclError finalRet = ACL_SUCCESS; - for (auto &bundleInfo: bundleInfos) { + for (auto &modelId: bundleInfos.loadedSubModelIdSet) { // unload all and check result - const auto ret = UnloadModelInner(bundleInfo.modelId); + const auto ret = UnloadModelInner(modelId); if (ret != ACL_SUCCESS) { finalRet = ret; } @@ -2945,7 +3225,7 @@ aclError aclmdlLoadWithConfig(const aclmdlConfigHandle *handle, uint32_t *modelI ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle->mdlAddr); ACL_REQUIRES_OK(acl::IsSupportRuntimeV2WithModelData(handle->mdlAddr, handle->mdlSize, isSupportRT2)); if (isSupportRT2) { - return acl::RuntimeV2ModelLoadFromMemWithMem(handle->mdlAddr, handle->mdlSize, "", modelId, nullptr, 0U, + return acl::RuntimeV2ModelLoadFromMemWithMem(handle->mdlAddr, handle->mdlSize, handle->loadPath, modelId, nullptr, 0U, handle->weightPath.c_str(), handle->priority, file_constant_mems); } @@ -2959,15 +3239,16 @@ aclError aclmdlLoadWithConfig(const aclmdlConfigHandle *handle, uint32_t *modelI ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle->mdlAddr); ACL_REQUIRES_OK(acl::IsSupportRuntimeV2WithModelData(handle->mdlAddr, handle->mdlSize, isSupportRT2)); if (isSupportRT2) { - return acl::RuntimeV2ModelLoadFromMemWithMem(handle->mdlAddr, handle->mdlSize, "", modelId, + return acl::RuntimeV2ModelLoadFromMemWithMem(handle->mdlAddr, handle->mdlSize, handle->loadPath, modelId, handle->weightPtr, handle->weightSize, - nullptr, handle->priority, file_constant_mems); + handle->weightPath.c_str(), handle->priority, file_constant_mems); } const auto loadArgs = ConstructGeModelLoadArg(handle->workPtr, handle->workSize, handle->weightPtr, handle->weightSize, nullptr, file_constant_mems); - return acl::ModelLoadFromMemWithMem(handle->mdlAddr, handle->mdlSize, "", modelId, loadArgs, - nullptr, handle->priority); + return acl::ModelLoadFromMemWithMem(handle->mdlAddr, handle->mdlSize, handle->loadPath, modelId, loadArgs, + handle->weightPath.c_str(), handle->priority); } + case ACL_MDL_LOAD_FROM_FILE_WITH_Q: { if (aclmdlCheckQueueParam(handle->inputQ, handle->inputQNum, handle->outputQ, handle->outputQNum) != diff --git a/model/model_desc_internal.h b/model/model_desc_internal.h index 996bc01a588b13e40b2180d856641578a809072d..02dea17933f5148777bc92e9cdbe420411443b4a 100755 --- a/model/model_desc_internal.h +++ b/model/model_desc_internal.h @@ -16,6 +16,7 @@ #include #include #include "acl/acl_base.h" +#include "acl/acl_mdl.h" #include "common/dynamic_aipp.h" #include "mmpa/mmpa_api.h" #include "common/ge_common/ge_types.h" @@ -91,6 +92,13 @@ enum AippMode : int32_t { STATIC_AIPP = 1, DYNAMIC_AIPP = 2 }; + +struct BundleSubModelInfo { + size_t workSize = 0U; + size_t weightSize = 0U; + size_t offset = 0U; + size_t modelSize = 0U; +}; } struct aclmdlDataset { @@ -172,4 +180,9 @@ struct aclrtUtilizationExtendInfo { bool isUtilizationExtend = false; }; +struct aclmdlBundleQueryInfo { + size_t varSize = 0U; + std::vector subModelInfos; +}; + #endif // ACL_MODEL_DESC_INTERNAL_H diff --git a/tests/ut/acl/testcase/acl_model_unittest.cpp b/tests/ut/acl/testcase/acl_model_unittest.cpp index 6f978355cf36792e2da726c0007f3c20eff88823..1fa3bcb81979c4b5f0fa8a6f45c9e0424e64e993 100755 --- a/tests/ut/acl/testcase/acl_model_unittest.cpp +++ b/tests/ut/acl/testcase/acl_model_unittest.cpp @@ -3931,13 +3931,13 @@ std::shared_ptr ConstructBundleOm(size_t model_num, size_t &size) header->modeltype = ge::MODEL_TYPE_BUNDLE_MODEL; header->model_num = model_num; header->length = size; - offset += sizeof(ModelFileHeader); ModelPartitionTable *p = (ModelPartitionTable *)(model_data + offset); p->num = 3; offset += sizeof(ModelPartitionTable); for (size_t i = 0; i < model_num; ++i) { ModelPartitionMemInfo *part = (ModelPartitionMemInfo *)(model_data + offset); + part->type = ge::BUNDLE_MODEL_INFO; part->mem_size = sizeof(ModelFileHeader) + 10; part->type = ge::BUNDLE_MODEL_INFO; offset += sizeof(ModelPartitionMemInfo); @@ -3945,7 +3945,7 @@ std::shared_ptr ConstructBundleOm(size_t model_num, size_t &size) for (size_t i = 0; i < model_num; ++i) { ModelFileHeader *inner_header = (ModelFileHeader *)(model_data + offset); inner_header->version = ge::MODEL_VERSION + 1U; - if ( i == 0) { + if ( i == 2) { inner_header->model_num = 2U; inner_header->is_unknow_model = 1; } else { @@ -3958,6 +3958,54 @@ std::shared_ptr ConstructBundleOm(size_t model_num, size_t &size) return model_p; } +std::shared_ptr ConstructBundleOmWithVarWeight(size_t model_num, size_t &size) +{ + // need add var + const size_t other_partition_num = 1U; + const size_t partition_num = model_num + other_partition_num; // add var partition + size = sizeof(ge::ModelFileHeader) + sizeof(ModelPartitionTable) + + (sizeof(ModelPartitionMemInfo) * partition_num) + sizeof(int64_t) +((sizeof(ModelFileHeader) + 10) * model_num); + std::shared_ptr model_p(new (std::nothrow) uint8_t[size], std::default_delete()); + uint8_t *model_data = model_p.get(); + size_t offset = 0; + ModelFileHeader *header = (ModelFileHeader *)model_data; + header->modeltype = ge::MODEL_TYPE_BUNDLE_MODEL; + header->model_num = model_num; + header->length = size; + offset += sizeof(ModelFileHeader); + ModelPartitionTable *p = (ModelPartitionTable *)(model_data + offset); + p->num = partition_num; + offset += sizeof(ModelPartitionTable); + int var_type = 25; + for (size_t i = 0; i < partition_num; ++i) { + ModelPartitionMemInfo *part = (ModelPartitionMemInfo *)(model_data + offset); + if (i == 0) { + part->type = *(ModelPartitionType*)(&var_type); + part->mem_size = sizeof(int64_t); + } else { + part->type = ge::BUNDLE_MODEL_INFO; + part->mem_size = sizeof(ModelFileHeader) + 10; + } + offset += sizeof(ModelPartitionMemInfo); + } + *(int64_t *)(model_data + offset) = 1024; // varWeight + offset += sizeof(int64_t); + for (size_t i = 0; i < model_num; ++i) { + ModelFileHeader *inner_header = (ModelFileHeader *)(model_data + offset); + inner_header->version = ge::MODEL_VERSION + 1U; + if ( i == 2) { + inner_header->model_num = 2U; + inner_header->is_unknow_model = 1; + } else { + inner_header->model_num = 1U; + inner_header->is_unknow_model = 0; + } + offset += sizeof(ModelFileHeader); + offset += 10; + } + return model_p; +} + TEST_F(UTEST_ACL_Model, TestaclmdlBundleLoadFromMem_verify_input_param) { uint32_t bundle_id = 0; @@ -4010,6 +4058,19 @@ ge::graphStatus LoadDataFromFileV2Stub(const char *path, ge::ModelData &model_da return GRAPH_SUCCESS; } +ge::graphStatus LoadDataFromFileV3Stub(const char *path, ge::ModelData &model_data) +{ + (void) path; + size_t size = 0; + auto model_p = ConstructBundleOmWithVarWeight(3, size); + // delete is outside + auto p_new = new uint8_t[size]; + memcpy_s(p_new, size, model_p.get(), size); + model_data.model_len = size; + model_data.model_data = p_new; + return GRAPH_SUCCESS; +} + TEST_F(UTEST_ACL_Model, TestaclmdlBundleLoadFromFile) { const char *path = "/"; @@ -4107,7 +4168,211 @@ TEST_F(UTEST_ACL_Model, TestBundleInfo) EXPECT_EQ(AclResourceManager::GetInstance().executorMap_.size(), 2); EXPECT_EQ(AclResourceManager::GetInstance().rtSessionMap_.size(), 2); EXPECT_EQ(AclResourceManager::GetInstance().rtSessionMap_[bundle_id].get(), - AclResourceManager::GetInstance().rtSessionMap_[model_ids[0]].get()); + AclResourceManager::GetInstance().rtSessionMap_[model_ids[2]].get()); + + ret = aclmdlBundleUnload(bundle_id); + EXPECT_EQ(ret , ACL_SUCCESS); + EXPECT_EQ(AclResourceManager::GetInstance().bundleInfos_.size(), 0); + EXPECT_EQ(AclResourceManager::GetInstance().bundleInnerIds_.size(), 0); + EXPECT_EQ(AclResourceManager::GetInstance().executorMap_.size(), 0); + EXPECT_EQ(AclResourceManager::GetInstance().rtSessionMap_.size(), 0); +} + +TEST_F(UTEST_ACL_Model, TestBundleInfoFromVarSizeOm) +{ + AclResourceManager::GetInstance().bundleInfos_.clear(); + AclResourceManager::GetInstance().bundleInnerIds_.clear(); + AclResourceManager::GetInstance().executorMap_.clear(); + AclResourceManager::GetInstance().rtSessionMap_.clear(); + // load + uint32_t bundle_id = 0; + size_t size = 0; + auto model_p = ConstructBundleOmWithVarWeight(3, size); + uint8_t * model_data = model_p.get(); + acl::AclResourceManager::GetInstance().enableRuntimeV2ForModel_ = true; + EXPECT_CALL(MockFunctionTest::aclStubInstance(), LoadExecutorFromModelData(_,_,_)) + .WillRepeatedly(Invoke(LoadExecutorFromModelDataSuccess)); + EXPECT_CALL(MockFunctionTest::aclStubInstance(), LoadModelFromDataWithArgs(_,_,_)) + .WillRepeatedly(Invoke(LoadModelFromDataWithArgsStub)); + auto ret = aclmdlBundleLoadFromMem(model_data, size, &bundle_id); + EXPECT_EQ(ret , ACL_SUCCESS); + + // check bundle info + size_t modelNum = 0; + ret = aclmdlBundleGetModelNum(bundle_id, nullptr); + EXPECT_EQ(ret , ACL_ERROR_INVALID_PARAM); + ret = aclmdlBundleGetModelNum((bundle_id + 1), &modelNum); + EXPECT_EQ(ret , ACL_ERROR_INVALID_BUNDLE_MODEL_ID); + ret = aclmdlBundleGetModelNum(bundle_id, &modelNum); + EXPECT_EQ(ret , ACL_SUCCESS); + EXPECT_EQ(modelNum , 3); + + size_t index = 0; + uint32_t model_id = 0; + std::vector model_ids; + ret = aclmdlBundleGetModelId(bundle_id, 999, nullptr); + EXPECT_EQ(ret , ACL_ERROR_INVALID_PARAM); + ret = aclmdlBundleGetModelId(bundle_id, 999, &model_id); + EXPECT_EQ(ret , ACL_ERROR_INVALID_PARAM); + ret = aclmdlBundleGetModelId(bundle_id + 1, index, &model_id); + EXPECT_EQ(ret , ACL_ERROR_INVALID_BUNDLE_MODEL_ID); + for (size_t i = 0; i < modelNum; ++i) { + ret = aclmdlBundleGetModelId(bundle_id, i, &model_id); + EXPECT_EQ(ret , ACL_SUCCESS); + model_ids.emplace_back(model_id); + } + for (auto id : model_ids) { + ret = aclmdlUnload(id); + EXPECT_EQ(ret , ACL_ERROR_INVALID_PARAM); + } + + EXPECT_EQ(AclResourceManager::GetInstance().bundleInfos_.size(), 1); + EXPECT_EQ(AclResourceManager::GetInstance().bundleInnerIds_.size(), 3); + EXPECT_EQ(AclResourceManager::GetInstance().bundleInfos_[bundle_id].loadedSubModelId.size(), 3); + EXPECT_EQ(AclResourceManager::GetInstance().bundleInfos_[bundle_id].loadedSubModelIdSet.size(), 3); + EXPECT_EQ(AclResourceManager::GetInstance().bundleInfos_[bundle_id].is_init, false); + EXPECT_EQ(AclResourceManager::GetInstance().bundleInfos_[bundle_id].subModelInfos.size(), 3); + EXPECT_EQ(AclResourceManager::GetInstance().executorMap_.size(), 2); + EXPECT_EQ(AclResourceManager::GetInstance().rtSessionMap_.size(), 2); + EXPECT_EQ(AclResourceManager::GetInstance().rtSessionMap_[bundle_id].get(), + AclResourceManager::GetInstance().rtSessionMap_[model_ids[2]].get()); + + ret = aclmdlBundleUnload(bundle_id); + EXPECT_EQ(ret , ACL_SUCCESS); + EXPECT_EQ(AclResourceManager::GetInstance().bundleInfos_.size(), 0); + EXPECT_EQ(AclResourceManager::GetInstance().bundleInnerIds_.size(), 0); + EXPECT_EQ(AclResourceManager::GetInstance().executorMap_.size(), 0); + EXPECT_EQ(AclResourceManager::GetInstance().rtSessionMap_.size(), 0); +} + +Status GetMemAndWeightSizeStub(const void *model_data, size_t model_size, size_t &mem_size, size_t &weight_size) +{ + (void)model_data; + (void)model_size; + mem_size = 2048; + weight_size = 1024; + return SUCCESS; +} + +TEST_F(UTEST_ACL_Model, TestaclmdlBundleQueryInfoFromFile) +{ + auto query_info = aclmdlBundleCreateQueryInfo(); + EXPECT_NE(query_info, nullptr); + size_t model_size = 0; + auto model_data = ConstructBundleOmWithVarWeight(3, model_size); + EXPECT_NE(model_data, nullptr); + EXPECT_CALL(MockFunctionTest::aclStubInstance(), LoadDataFromFileV2(_,_)) + .WillOnce(Return(ge::GRAPH_FAILED)) + .WillRepeatedly(Invoke(LoadDataFromFileV3Stub)); + EXPECT_NE(aclmdlBundleQuerySize("./test.om", query_info), ACL_SUCCESS); + EXPECT_CALL(MockFunctionTest::aclStubInstance(), GetMemAndWeightSize(_,_,_,_)) + .WillRepeatedly(Invoke(GetMemAndWeightSizeStub)); + EXPECT_EQ(aclmdlBundleQuerySize("./test.om", query_info), ACL_SUCCESS); + size_t model_num = 0; + EXPECT_EQ(aclmdlBundleGetQueryModelNum(query_info, &model_num), ACL_SUCCESS); + EXPECT_EQ(model_num, 3); + size_t var_size = 0; + EXPECT_EQ(aclmdlBundleGetVarWeightSize(query_info, &var_size), ACL_SUCCESS); + EXPECT_EQ(var_size, 1024); + size_t work_size = 99; + size_t weight_size = 999; + EXPECT_EQ(aclmdlBundleGetSize(query_info, 0, &work_size, &weight_size), ACL_SUCCESS); + EXPECT_EQ(work_size, 2048); + EXPECT_EQ(weight_size, 1024); + EXPECT_EQ(aclmdlBundleGetSize(query_info, 2, &work_size, &weight_size), ACL_SUCCESS); + EXPECT_EQ(work_size, 0); + EXPECT_EQ(weight_size, 0); + EXPECT_EQ(aclmdlBundleGetSize(query_info, 1, &work_size, &weight_size), ACL_SUCCESS); + EXPECT_EQ(work_size, 2048); + EXPECT_EQ(weight_size, 1024); + EXPECT_EQ(aclmdlBundleGetSize(query_info, 10, &work_size, &weight_size), ACL_ERROR_INVALID_PARAM); + EXPECT_EQ(aclmdlBundleDestroyQueryInfo(query_info), ACL_SUCCESS); +} + +TEST_F(UTEST_ACL_Model, TestaclmdlBundleQueryInfoFromMem) +{ + auto query_info = aclmdlBundleCreateQueryInfo(); + EXPECT_NE(query_info, nullptr); + size_t model_size = 0; + auto model_data = ConstructBundleOmWithVarWeight(3, model_size); + EXPECT_NE(model_data, nullptr); + + EXPECT_CALL(MockFunctionTest::aclStubInstance(), GetMemAndWeightSize(_,_,_,_)) + .WillRepeatedly(Invoke(GetMemAndWeightSizeStub)); + EXPECT_EQ(aclmdlBundleQuerySizeFromMem(model_data.get(), model_size, query_info), ACL_SUCCESS); + size_t model_num = 0; + EXPECT_EQ(aclmdlBundleGetQueryModelNum(query_info, &model_num), ACL_SUCCESS); + EXPECT_EQ(model_num, 3); + size_t var_size = 0; + EXPECT_EQ(aclmdlBundleGetVarWeightSize(query_info, &var_size), ACL_SUCCESS); + EXPECT_EQ(var_size, 1024); + size_t work_size = 99; + size_t weight_size = 999; + EXPECT_EQ(aclmdlBundleGetSize(query_info, 0, &work_size, &weight_size), ACL_SUCCESS); + EXPECT_EQ(work_size, 2048); + EXPECT_EQ(weight_size, 1024); + EXPECT_EQ(aclmdlBundleGetSize(query_info, 2, &work_size, &weight_size), ACL_SUCCESS); + EXPECT_EQ(work_size, 0); + EXPECT_EQ(weight_size, 0); + EXPECT_EQ(aclmdlBundleGetSize(query_info, 1, &work_size, &weight_size), ACL_SUCCESS); + EXPECT_EQ(work_size, 2048); + EXPECT_EQ(weight_size, 1024); + EXPECT_EQ(aclmdlBundleDestroyQueryInfo(query_info), ACL_SUCCESS); +} + +void Verify(uint32_t bundle_id, bool is_init = true) { + // check bundle info + size_t modelNum = 0; + size_t load_cnt = is_init ? 0 : 3; + + auto ret = aclmdlBundleGetModelNum(bundle_id, nullptr); + EXPECT_EQ(ret , ACL_ERROR_INVALID_PARAM); + ret = aclmdlBundleGetModelNum((bundle_id + 1), &modelNum); + EXPECT_EQ(ret , ACL_ERROR_INVALID_BUNDLE_MODEL_ID); + ret = aclmdlBundleGetModelNum(bundle_id, &modelNum); + EXPECT_EQ(ret , ACL_SUCCESS); + EXPECT_EQ(modelNum , 3); + + uint32_t model_id = 0; + ret = aclmdlBundleGetModelId(bundle_id, 999, nullptr); + EXPECT_EQ(ret , ACL_ERROR_INVALID_PARAM); + if (is_init) { + ret = aclmdlBundleGetModelId(bundle_id, 0, &model_id); + EXPECT_EQ(ret , ACL_ERROR_API_NOT_SUPPORT); + } + + EXPECT_EQ(aclmdlBundleLoadModel(bundle_id, 3, &model_id), ACL_ERROR_INVALID_PARAM); + uint32_t infer_id_1, infer_id_2, init_id, update_id; + EXPECT_EQ(aclmdlBundleLoadModel(bundle_id, 0, &infer_id_1), ACL_SUCCESS); + EXPECT_EQ(aclmdlBundleLoadModelWithMem(bundle_id, 0, nullptr, 0, nullptr, 0, &infer_id_2), ACL_SUCCESS); + EXPECT_EQ(aclmdlBundleLoadModelWithMem(bundle_id, 1, nullptr, 0, nullptr, 0, &init_id), ACL_SUCCESS); + aclmdlConfigHandle handle; + EXPECT_EQ(aclmdlBundleLoadModelWithConfig(bundle_id, 2, &handle, &update_id), ACL_SUCCESS); + EXPECT_EQ(aclmdlBundleLoadModelWithMem(bundle_id, 3, nullptr, 0, nullptr, 0, &model_id), ACL_ERROR_INVALID_PARAM); + load_cnt += 4; + ret = aclmdlUnload(infer_id_1); + EXPECT_EQ(ret , ACL_ERROR_INVALID_PARAM); + + EXPECT_EQ(AclResourceManager::GetInstance().bundleInfos_.size(), 1); + if (is_init) { + EXPECT_EQ(AclResourceManager::GetInstance().bundleInfos_[bundle_id].loadedSubModelId.size(), 0); + } else { + EXPECT_EQ(AclResourceManager::GetInstance().bundleInfos_[bundle_id].loadedSubModelId.size(), 3); + } + EXPECT_EQ(AclResourceManager::GetInstance().bundleInfos_[bundle_id].loadedSubModelIdSet.size(), load_cnt); + EXPECT_EQ(AclResourceManager::GetInstance().bundleInfos_[bundle_id].is_init, is_init); + EXPECT_EQ(AclResourceManager::GetInstance().bundleInfos_[bundle_id].subModelInfos.size(), 3); + EXPECT_EQ(AclResourceManager::GetInstance().bundleInnerIds_.size(), load_cnt); + size_t session_map_size = is_init ? 2 : 3; + EXPECT_EQ(AclResourceManager::GetInstance().executorMap_.size(), session_map_size); + EXPECT_EQ(AclResourceManager::GetInstance().rtSessionMap_.size(), session_map_size); + EXPECT_EQ(AclResourceManager::GetInstance().rtSessionMap_[bundle_id].get(), + AclResourceManager::GetInstance().rtSessionMap_[update_id].get()); + + EXPECT_EQ(aclmdlBundleUnloadModel(bundle_id, infer_id_1), ACL_SUCCESS); + load_cnt--; + EXPECT_EQ(AclResourceManager::GetInstance().bundleInfos_[bundle_id].loadedSubModelIdSet.size(), load_cnt); + EXPECT_EQ(AclResourceManager::GetInstance().bundleInnerIds_.size(), load_cnt); ret = aclmdlBundleUnload(bundle_id); EXPECT_EQ(ret , ACL_SUCCESS); @@ -4117,6 +4382,84 @@ TEST_F(UTEST_ACL_Model, TestBundleInfo) EXPECT_EQ(AclResourceManager::GetInstance().rtSessionMap_.size(), 0); } +TEST_F(UTEST_ACL_Model, TestaclmdlBundleLoadSubModelFromFile) { + AclResourceManager::GetInstance().bundleInfos_.clear(); + AclResourceManager::GetInstance().bundleInnerIds_.clear(); + AclResourceManager::GetInstance().executorMap_.clear(); + AclResourceManager::GetInstance().rtSessionMap_.clear(); + // load + uint32_t bundle_id = 0; + acl::AclResourceManager::GetInstance().enableRuntimeV2ForModel_ = true; + EXPECT_CALL(MockFunctionTest::aclStubInstance(), LoadExecutorFromModelData(_,_,_)) + .WillRepeatedly(Invoke(LoadExecutorFromModelDataSuccess)); + EXPECT_CALL(MockFunctionTest::aclStubInstance(), LoadModelFromDataWithArgs(_,_,_)) + .WillRepeatedly(Invoke(LoadModelFromDataWithArgsStub)); + EXPECT_CALL(MockFunctionTest::aclStubInstance(), LoadDataFromFileV2(_,_)) + .WillRepeatedly(Invoke(LoadDataFromFileV3Stub)); + auto ret = aclmdlBundleInitFromFile("./fake.om", nullptr, 0, &bundle_id); + EXPECT_EQ(ret , ACL_SUCCESS); + Verify(bundle_id); +} + +TEST_F(UTEST_ACL_Model, TestaclmdlBundleLoadSubModelFromMem) { + AclResourceManager::GetInstance().bundleInfos_.clear(); + AclResourceManager::GetInstance().bundleInnerIds_.clear(); + AclResourceManager::GetInstance().executorMap_.clear(); + AclResourceManager::GetInstance().rtSessionMap_.clear(); + // load + uint32_t bundle_id = 0; + size_t size = 0; + auto model_p = ConstructBundleOmWithVarWeight(3, size); + uint8_t * model_data = model_p.get(); + acl::AclResourceManager::GetInstance().enableRuntimeV2ForModel_ = true; + EXPECT_CALL(MockFunctionTest::aclStubInstance(), LoadExecutorFromModelData(_,_,_)) + .WillRepeatedly(Invoke(LoadExecutorFromModelDataSuccess)); + EXPECT_CALL(MockFunctionTest::aclStubInstance(), LoadModelFromDataWithArgs(_,_,_)) + .WillRepeatedly(Invoke(LoadModelFromDataWithArgsStub)); + auto ret = aclmdlBundleInitFromMem(model_data, size, nullptr, 0, &bundle_id); + EXPECT_EQ(ret , ACL_SUCCESS); + Verify(bundle_id); +} + +TEST_F(UTEST_ACL_Model, TestaclmdlaclmdlBundleLoadFromFileAndBundleLoadSubModel) { + AclResourceManager::GetInstance().bundleInfos_.clear(); + AclResourceManager::GetInstance().bundleInnerIds_.clear(); + AclResourceManager::GetInstance().executorMap_.clear(); + AclResourceManager::GetInstance().rtSessionMap_.clear(); + // load + uint32_t bundle_id = 0; + acl::AclResourceManager::GetInstance().enableRuntimeV2ForModel_ = true; + EXPECT_CALL(MockFunctionTest::aclStubInstance(), LoadExecutorFromModelData(_,_,_)) + .WillRepeatedly(Invoke(LoadExecutorFromModelDataSuccess)); + EXPECT_CALL(MockFunctionTest::aclStubInstance(), LoadModelFromDataWithArgs(_,_,_)) + .WillRepeatedly(Invoke(LoadModelFromDataWithArgsStub)); + EXPECT_CALL(MockFunctionTest::aclStubInstance(), LoadDataFromFileV2(_,_)) + .WillRepeatedly(Invoke(LoadDataFromFileV3Stub)); + auto ret = aclmdlBundleLoadFromFile("./fake.om", &bundle_id); + EXPECT_EQ(ret , ACL_SUCCESS); + Verify(bundle_id, false); +} + +TEST_F(UTEST_ACL_Model, TestaclmdlaclmdlBundleLoadFromMemAndBundleLoadSubModel) { + AclResourceManager::GetInstance().bundleInfos_.clear(); + AclResourceManager::GetInstance().bundleInnerIds_.clear(); + AclResourceManager::GetInstance().executorMap_.clear(); + AclResourceManager::GetInstance().rtSessionMap_.clear(); + // load + uint32_t bundle_id = 0; + size_t size = 0; + auto model_p = ConstructBundleOmWithVarWeight(3, size); + uint8_t * model_data = model_p.get(); + acl::AclResourceManager::GetInstance().enableRuntimeV2ForModel_ = true; + EXPECT_CALL(MockFunctionTest::aclStubInstance(), LoadExecutorFromModelData(_,_,_)) + .WillRepeatedly(Invoke(LoadExecutorFromModelDataSuccess)); + EXPECT_CALL(MockFunctionTest::aclStubInstance(), LoadModelFromDataWithArgs(_,_,_)) + .WillRepeatedly(Invoke(LoadModelFromDataWithArgsStub)); + auto ret = aclmdlBundleLoadFromMem(model_data, size, &bundle_id); + EXPECT_EQ(ret , ACL_SUCCESS); + Verify(bundle_id, false); +} + TEST_F(UTEST_ACL_Model, TestaclmdlRICaptureBegin) { aclrtStream stream = (aclrtStream)0x01; diff --git a/toolchain/profiling_manager.cpp b/toolchain/profiling_manager.cpp index 80f749cb58f1d61e02156b0e5c56744e1c89c0d8..7f8af0e15012158ef2b8940be469c1c25c1a72d0 100755 --- a/toolchain/profiling_manager.cpp +++ b/toolchain/profiling_manager.cpp @@ -32,7 +32,10 @@ namespace acl { {AclProfType::AclmdlLoadFromMem, "aclmdlLoadFromMem"}, {AclProfType::AclmdlBundleLoadFromFile, "aclmdlBundleLoadFromFile"}, {AclProfType::AclmdlBundleLoadFromMem, "aclmdlBundleLoadFromMem"}, + {AclProfType::aclmdlBundleLoadModelWithMem, "aclmdlBundleLoadModelWithMem"}, + {AclProfType::aclmdlBundleLoadModelWithConfig, "aclmdlBundleLoadModelWithConfig"}, {AclProfType::AclmdlBundleUnload, "aclmdlBundleUnload"}, + {AclProfType::aclmdlBundleUnloadModel, "aclmdlBundleUnloadModel"}, {AclProfType::AclmdlSetInputAIPP, "aclmdlSetInputAIPP"}, {AclProfType::AclmdlSetAIPPByInputIndex, "aclmdlSetAIPPByInputIndex"}, {AclProfType::AclmdlExecuteAsync, "aclmdlExecuteAsync"}, diff --git a/toolchain/profiling_manager.h b/toolchain/profiling_manager.h index a5ddf29dd5799958df08daf5b795df4b032ff2dd..35ccb2e7563247b666791ea7998e250657e79385 100755 --- a/toolchain/profiling_manager.h +++ b/toolchain/profiling_manager.h @@ -28,7 +28,10 @@ enum AclProfType { AclmdlLoadFromMem, AclmdlBundleLoadFromFile, AclmdlBundleLoadFromMem, + aclmdlBundleLoadModelWithMem, + aclmdlBundleLoadModelWithConfig, AclmdlBundleUnload, + aclmdlBundleUnloadModel, AclmdlSetInputAIPP, AclmdlSetAIPPByInputIndex, AclmdlExecuteAsync, diff --git a/toolchain/resource_statistics.h b/toolchain/resource_statistics.h index 9b107babff1b1c5872c4c4a7c2f34166816d119f..a133228a1b0e8e81c93e05e53c34b3c78a80f11f 100755 --- a/toolchain/resource_statistics.h +++ b/toolchain/resource_statistics.h @@ -74,6 +74,7 @@ namespace acl { ACL_STATISTICS_MALLOC_FREE_PHYSICAL_MEMORY, ACL_STATISTICS_MAP_UNMAP_MEMORY, ACL_STATISTICS_LOAD_UNLOAD_BINARY, + ACL_STATISTICS_CREATE_DESTROY_BUNDLE_QUERY_INFO, // add enum before this comment, ACL_STATISTICS_RESOURCE_TYPE_SIZE is length of enum ACL_STATISTICS_RESOURCE_TYPE_SIZE, };