239 lines
6.7 KiB
C++
239 lines
6.7 KiB
C++
/**
|
|
* 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 <iostream>
|
|
#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_;
|
|
}
|
|
|
|
|