/** * Copyright 2020 Huawei Technologies Co., Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * File model_process.cpp * Description: handle model process */ #include "model_process.h" #include #include "utils.h" using namespace std; ModelProcess::ModelProcess():loadFlag_(false), modelId_(0), modelMemPtr_(nullptr), modelMemSize_(0), modelWeightPtr_(nullptr),modelWeightSize_(0), modelDesc_(nullptr), input_(nullptr), output_(nullptr) { } ModelProcess::~ModelProcess() { Unload(); DestroyDesc(); DestroyInput(); DestroyOutput(); } Result ModelProcess::LoadModelFromFileWithMem(const char *modelPath) { if (loadFlag_) { ERROR_LOG("has already loaded a model"); return FAILED; } aclError ret = aclmdlQuerySize(modelPath, &modelMemSize_, &modelWeightSize_); if (ret != ACL_ERROR_NONE) { ERROR_LOG("query model failed, model file is %s", modelPath); return FAILED; } ret = aclrtMalloc(&modelMemPtr_, modelMemSize_, ACL_MEM_MALLOC_HUGE_FIRST); if (ret != ACL_ERROR_NONE) { ERROR_LOG("malloc buffer for mem failed, require size is %zu", modelMemSize_); return FAILED; } ret = aclrtMalloc(&modelWeightPtr_, modelWeightSize_, ACL_MEM_MALLOC_HUGE_FIRST); if (ret != ACL_ERROR_NONE) { ERROR_LOG("malloc buffer for weight failed, require size is %zu", modelWeightSize_); return FAILED; } ret = aclmdlLoadFromFileWithMem(modelPath, &modelId_, modelMemPtr_, modelMemSize_, modelWeightPtr_, modelWeightSize_); if (ret != ACL_ERROR_NONE) { ERROR_LOG("load model from file failed, model file is %s", modelPath); return FAILED; } loadFlag_ = true; INFO_LOG("load model %s success", modelPath); return SUCCESS; } Result ModelProcess::CreateDesc() { modelDesc_ = aclmdlCreateDesc(); if (modelDesc_ == nullptr) { ERROR_LOG("create model description failed"); return FAILED; } aclError ret = aclmdlGetDesc(modelDesc_, modelId_); if (ret != ACL_ERROR_NONE) { ERROR_LOG("get model description failed"); return FAILED; } INFO_LOG("create model description success"); return SUCCESS; } void ModelProcess::DestroyDesc() { if (modelDesc_ != nullptr) { (void)aclmdlDestroyDesc(modelDesc_); modelDesc_ = nullptr; } } Result ModelProcess::CreateInput(void *inputDataBuffer, size_t bufferSize) { input_ = aclmdlCreateDataset(); if (input_ == nullptr) { ERROR_LOG("can't create dataset, create input failed"); return FAILED; } aclDataBuffer* inputData = aclCreateDataBuffer(inputDataBuffer, bufferSize); if (inputData == nullptr) { ERROR_LOG("can't create data buffer, create input failed"); return FAILED; } aclError ret = aclmdlAddDatasetBuffer(input_, inputData); if (inputData == nullptr) { ERROR_LOG("can't add data buffer, create input failed"); aclDestroyDataBuffer(inputData); inputData = nullptr; return FAILED; } return SUCCESS; } void ModelProcess::DestroyInput() { if (input_ == nullptr) { return; } for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(input_); ++i) { aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(input_, i); aclDestroyDataBuffer(dataBuffer); } aclmdlDestroyDataset(input_); input_ = nullptr; } Result ModelProcess::CreateOutput() { if (modelDesc_ == nullptr) { ERROR_LOG("no model description, create ouput failed"); return FAILED; } output_ = aclmdlCreateDataset(); if (output_ == nullptr) { ERROR_LOG("can't create dataset, create output failed"); return FAILED; } size_t outputSize = aclmdlGetNumOutputs(modelDesc_); for (size_t i = 0; i < outputSize; ++i) { size_t buffer_size = aclmdlGetOutputSizeByIndex(modelDesc_, i); void *outputBuffer = nullptr; aclError ret = aclrtMalloc(&outputBuffer, buffer_size, ACL_MEM_MALLOC_NORMAL_ONLY); if (ret != ACL_ERROR_NONE) { ERROR_LOG("can't malloc buffer, size is %zu, create output failed", buffer_size); return FAILED; } aclDataBuffer* outputData = aclCreateDataBuffer(outputBuffer, buffer_size); if (ret != ACL_ERROR_NONE) { ERROR_LOG("can't create data buffer, create output failed"); aclrtFree(outputBuffer); return FAILED; } ret = aclmdlAddDatasetBuffer(output_, outputData); if (ret != ACL_ERROR_NONE) { ERROR_LOG("can't add data buffer, create output failed"); aclrtFree(outputBuffer); aclDestroyDataBuffer(outputData); return FAILED; } } INFO_LOG("create model output success"); return SUCCESS; } void ModelProcess::DestroyOutput() { if (output_ == nullptr) { return; } for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) { aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i); void* data = aclGetDataBufferAddr(dataBuffer); (void)aclrtFree(data); (void)aclDestroyDataBuffer(dataBuffer); } (void)aclmdlDestroyDataset(output_); output_ = nullptr; } Result ModelProcess::Execute() { aclError ret = aclmdlExecute(modelId_, input_, output_); if (ret != ACL_ERROR_NONE) { ERROR_LOG("execute model failed, modelId is %u", modelId_); return FAILED; } INFO_LOG("model execute success"); return SUCCESS; } void ModelProcess::Unload() { if (!loadFlag_) { return; } aclError ret = aclmdlUnload(modelId_); if (ret != ACL_ERROR_NONE) { ERROR_LOG("unload model failed, modelId is %u", modelId_); } if (modelDesc_ != nullptr) { (void)aclmdlDestroyDesc(modelDesc_); modelDesc_ = nullptr; } if (modelMemPtr_ != nullptr) { aclrtFree(modelMemPtr_); modelMemPtr_ = nullptr; modelMemSize_ = 0; } if (modelWeightPtr_ != nullptr) { aclrtFree(modelWeightPtr_); modelWeightPtr_ = nullptr; modelWeightSize_ = 0; } loadFlag_ = false; INFO_LOG("unload model success, modelId is %u", modelId_); } aclmdlDataset *ModelProcess::GetModelOutputData() { return output_; }