Upload dnmetis test tool for NPU inference

This commit is contained in:
chengchunlei
2020-10-24 10:25:36 +08:00
committed by Gitee
parent caac104a32
commit 15981373b9
14 changed files with 1477 additions and 0 deletions
@@ -0,0 +1,61 @@
/**
* 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.
*/
#include "BackendFactory.h"
BackendFactory *BackendFactory::Instance() {
static BackendFactory instance;
return &instance;
}
int BackendFactory::Init() {
if (!is_init_) {
std::string skt_bin = "libaclbackend.so";
//handle_ = dlopen(skt_bin.c_str(), RTLD_NOW | RTLD_GLOBAL);
//if (handle_ == nullptr) {
// GELOGE(FAILED, "SKT: open skt lib failed, please check LD_LIBRARY_PATH.");
//}
}
is_init_ = true;
return 0;
}
std::shared_ptr<BaseBackend> BackendFactory::CreateBaseBackend(const FrameworkType type) {
std::map<FrameworkType, BASE_BACKEND_CREATOR_FUN>::iterator iter = creator_map_.find(type);
if (iter != creator_map_.end()) {
return iter->second();
}
return nullptr;
}
void BackendFactory::RegisterCreator(const FrameworkType type, BASE_BACKEND_CREATOR_FUN fun) {
std::map<FrameworkType, BASE_BACKEND_CREATOR_FUN>::iterator iter = creator_map_.find(type);
if (iter != creator_map_.end()) {
return;
}
creator_map_[type] = fun;
}
BackendFactory::~BackendFactory() {
creator_map_.clear();
}
@@ -0,0 +1,49 @@
/**
* 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.
*/
#include "BaseBackend.h"
int BaseBackend::param()
{
return 0;
}
int BaseBackend::runner()
{
return 0;
}
int BaseBackend::runnerthread()
{
return 0;
}
int BaseBackend::statistic()
{
return 0;
}
@@ -0,0 +1,46 @@
#include "aclbackend.h"
CREATE_BACKEND_INIT(AclBackend,model,data)
{
Result ret = processSample.InitResource(model);
if (ret != SUCCESS) {
ERROR_LOG("sample init resource failed");
return FAILED;
}
return SUCCESS;
}
CREATE_BACKEND_LOAD(AclBackend,model,data)
{
INFO_LOG("AclBackend LOAD model success");
return SUCCESS;
}
CREATE_BACKEND_PREDICT(AclBackend,model,data,len,output,npuTime)
{
Result ret = processSample.Process(data,len,output,npuTime);
if (ret != SUCCESS) {
ERROR_LOG("sample process failed");
return FAILED;
}
INFO_LOG("execute sample success");
return SUCCESS;
}
CREATE_BACKEND_UNLOAD(AclBackend,model,data)
{
Result ret = processSample.Unload();
if (ret != SUCCESS) {
ERROR_LOG("sample unload failed");
return FAILED;
}
INFO_LOG("AclBackend UNLOAD model success");
return SUCCESS;
}
REGISTER_BASE_BACKEND_CREATOR(ACL, AclBackend)
@@ -0,0 +1,8 @@
#include "BackendFactory.h"
#include "sample_process.h"
#include <vector>
using namespace std;
CREATE_BACKEND(AclBackend)
SampleProcess processSample;
@@ -0,0 +1,113 @@
/**
* @file model_process.h
*
* Copyright (C) 2020. Huawei Technologies Co., Ltd. All rights reserved.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#pragma once
#include <iostream>
#include "utils.h"
#include "acl/acl.h"
#include<vector>
using namespace std;
/**
* ModelProcess
*/
class ModelProcess {
public:
/**
* @brief Constructor
*/
ModelProcess();
/**
* @brief Destructor
*/
~ModelProcess();
/**
* @brief load model from file with mem
* @param [in] modelPath: model path
* @return result
*/
Result LoadModelFromFileWithMem(const char *modelPath);
/**
* @brief unload model
*/
void Unload();
/**
* @brief create model desc
* @return result
*/
Result CreateDesc();
/**
* @brief destroy desc
*/
void DestroyDesc();
aclmdlDesc *GetDesc(){return modelDesc_;};
/**
* @brief create model input
* @param [in] inputDataBuffer: input buffer
* @param [in] bufferSize: input buffer size
* @return result
*/
Result CreateInput(void *inputDataBuffer, size_t bufferSize);
/**
* @brief destroy input resource
*/
void DestroyInput();
/**
* @brief create output buffer
* @return result
*/
Result CreateOutput();
/**
* @brief destroy output resource
*/
void DestroyOutput();
//void * GetOutput(){return outputdata;};
/**
* @brief model execute
* @return result
*/
Result Execute();
/**
* @brief dump model output result to file
*/
void DumpModelOutputResult();
/**
* @brief get model output result
*/
void OutputModelResult();
void OutputModelResult(vector<Output_buf> &output);
public:
uint32_t modelId_;
size_t modelMemSize_;
size_t modelWeightSize_;
void *modelMemPtr_;
void *modelWeightPtr_;
bool loadFlag_; // model load flag
aclmdlDesc *modelDesc_;
aclmdlDataset *input_;
aclmdlDataset *output_;
vector<void *> outputdata;
};
@@ -0,0 +1,62 @@
/**
* @file sample_process.h
*
* Copyright (C) 2020. Huawei Technologies Co., Ltd. All rights reserved.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#pragma once
#include "utils.h"
#include "acl/acl.h"
#include "model_process.h"
#include<vector>
using namespace std;
/**
* SampleProcess
*/
class SampleProcess {
public:
/**
* @brief Constructor
*/
SampleProcess();
/**
* @brief Destructor
*/
~SampleProcess();
/**
* @brief init reousce
* @return result
*/
Result InitResource(char* omModelPath);
/**
* @brief sample process
* @return result
*/
//Result Process(char* binfile);
Result Process(void* binfile,int len);
Result Process(void* binfile,int len, vector<Output_buf> &output, long &npuTime);
Result Unload();
//ModelProcess GetModelProcess();
ModelProcess GetModelProcess(){return processModel;};
public:
void DestroyResource();
int32_t deviceId_;
aclrtContext context_;
aclrtStream stream_;
ModelProcess processModel;
};
@@ -0,0 +1,69 @@
/**
* @file utils.h
*
* Copyright (C) 2020. Huawei Technologies Co., Ltd. All rights reserved.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#pragma once
#include <iostream>
#include "common.h"
#include <map>
#include "acl/acl_base.h"
//#include "Config.h"
/**
* Utils
*/
struct aclmdlTensorDesc {
aclmdlTensorDesc() : name(""), size(0), format(ACL_FORMAT_UNDEFINED), dataType(ACL_DT_UNDEFINED) {}
std::string name;
size_t size;
aclFormat format;
aclDataType dataType;
std::vector<int64_t> dims;
};
struct aclmdlDesc {
void Clear()
{
inputDesc.clear();
outputDesc.clear();
dynamicBatch.clear();
dynamicHW.clear();
}
std::vector<aclmdlTensorDesc> inputDesc;
std::vector<aclmdlTensorDesc> outputDesc;
std::vector<uint64_t> dynamicBatch;
std::vector<std::vector<uint64_t>> dynamicHW;
};
class Utils {
public:
/**
* @brief create device buffer of file
* @param [in] fileName: file name
* @param [out] fileSize: size of file
* @return device buffer of file
*/
static void *GetDeviceBufferOfFile(std::string fileName, uint32_t &fileSize);
/**
* @brief create buffer of file
* @param [in] fileName: file name
* @param [out] fileSize: size of file
* @return buffer of pic
*/
static void* ReadBinFile(std::string fileName, uint32_t& fileSize);
static void* GetDeviceBufferOfptr(void* fileName, uint32_t fileSize);
static long getCurrentTime();
};
#pragma once
@@ -0,0 +1,444 @@
/**
* @file model_process.cpp
*
* Copyright (C) 2020. Huawei Technologies Co., Ltd. All rights reserved.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#include "model_process.h"
#include <iostream>
#include <map>
#include <sstream>
#include <algorithm>
#include "utils.h"
using namespace std;
extern bool g_isDevice;
//extern Config configSettings;
extern std::map<aclDataType, std::string> ACLdt;
extern std::map<aclDataType, int> ACLdt_size;
ModelProcess::ModelProcess() :modelId_(0), modelMemSize_(0), modelWeightSize_(0), modelMemPtr_(nullptr),
modelWeightPtr_(nullptr), loadFlag_(false), modelDesc_(nullptr), input_(nullptr), output_(nullptr)
{
}
ModelProcess::~ModelProcess()
{
}
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;
}
//int mem_malloc_type=configSettings.Read("aclrtMemMallocPolicy", 0);
ret = aclrtMalloc(&modelMemPtr_, modelMemSize_, (aclrtMemMallocPolicy)(Config::getInstance()->Read("aclrtMemMallocPolicy", 0)));
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("malloc buffer for mem failed, require size is %zu", modelMemSize_);
return FAILED;
}
ret = aclrtMalloc(&modelWeightPtr_, modelWeightSize_, (aclrtMemMallocPolicy)(Config::getInstance()->Read("aclrtMemMallocPolicy", 0)));
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;
}
//INFO_LOG("start CreateInput::aclCreateDataBuffer is %d", Utils::getCurrentTime());
aclDataBuffer* inputData = aclCreateDataBuffer(inputDataBuffer, bufferSize);
//INFO_LOG("end CreateInput::aclCreateDataBuffer is %d", Utils::getCurrentTime());
if (inputData == nullptr) {
ERROR_LOG("can't create data buffer, create input failed");
return FAILED;
}
//INFO_LOG("start CreateInput::aclmdlAddDatasetBuffer is %d", Utils::getCurrentTime());
aclError ret = aclmdlAddDatasetBuffer(input_, inputData);
//INFO_LOG("end CreateInput::aclmdlAddDatasetBuffer is %d", Utils::getCurrentTime());
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("add input dataset buffer 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, (aclrtMemMallocPolicy)(Config::getInstance()->Read("aclrtMemMallocPolicy", 0)));
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::DumpModelOutputResult()
{
stringstream ss;
size_t outputNum = aclmdlGetDatasetNumBuffers(output_);
static int executeNum = 0;
for (size_t i = 0; i < outputNum; ++i) {
ss << "output" << ++executeNum << "_" << i << ".bin";
string outputFileName = ss.str();
FILE *outputFile = fopen(outputFileName.c_str(), "wb");
if (outputFile) {
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i);
void* data = aclGetDataBufferAddr(dataBuffer);
uint32_t len = aclGetDataBufferSize(dataBuffer);
void* outHostData = NULL;
aclError ret = ACL_ERROR_NONE;
if (!g_isDevice) {
ret = aclrtMallocHost(&outHostData, len);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("aclrtMallocHost failed, ret[%d]", ret);
return;
}
ret = aclrtMemcpy(outHostData, len, data, len, ACL_MEMCPY_DEVICE_TO_HOST);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("aclrtMemcpy failed, ret[%d]", ret);
(void)aclrtFreeHost(outHostData);
return;
}
fwrite(outHostData, len, sizeof(char), outputFile);
ret = aclrtFreeHost(outHostData);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("aclrtFreeHost failed, ret[%d]", ret);
return;
}
} else {
fwrite(data, len, sizeof(char), outputFile);
}
fclose(outputFile);
outputFile = nullptr;
} else {
ERROR_LOG("create output file [%s] failed", outputFileName.c_str());
return;
}
}
INFO_LOG("dump data success");
return;
}
void ModelProcess::OutputModelResult()
{
aclError ret = ACL_ERROR_NONE;
if(outputdata.size()!=0)
{
for(auto it=outputdata.begin();it!=outputdata.end();++it){
ret = aclrtFreeHost(*it);
}
outputdata.clear();
}
for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) {
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i);
void* data = aclGetDataBufferAddr(dataBuffer);
uint32_t len = aclGetDataBufferSize(dataBuffer);
//INFO_LOG("OutputModelResult::len %d", len);
//void *outHostData = NULL;
outputdata.push_back(NULL);
ret = ACL_ERROR_NONE;
float *outData = NULL;
if (!g_isDevice) {
//INFO_LOG("start OutputModelResult::aclrtMallocHost is %d", Utils::getCurrentTime());
aclError ret = aclrtMallocHost(&outputdata[i], len);
//INFO_LOG("end OutputModelResult::aclrtMallocHost is %d", Utils::getCurrentTime());
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("aclrtMallocHost failed, ret[%d]", ret);
return;
}
//INFO_LOG("start OutputModelResult::aclrtMemcpy is %d", Utils::getCurrentTime());
ret = aclrtMemcpy(outputdata[i], len, data, len, ACL_MEMCPY_DEVICE_TO_HOST);
//INFO_LOG("end OutputModelResult::aclrtMemcpy is %d", Utils::getCurrentTime());
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("aclrtMemcpy failed, ret[%d]", ret);
return;
}
outData = reinterpret_cast<float*>(outputdata[i]);
//outputdata.push_back(outHostData);
} else {
outData = reinterpret_cast<float*>(data);
outputdata.push_back(data);
}
map<float, unsigned int, greater<float> > resultMap;
for (unsigned int j = 0; j < len / sizeof(float); ++j) {
resultMap[*outData] = j;
outData++;
}
int cnt = 0;
for (auto it = resultMap.begin(); it != resultMap.end(); ++it) {
// print top 5
if (++cnt > 5) {
break;
}
//INFO_LOG("top %d: index[%d] value[%lf]", cnt, it->second, it->first);
}
}
INFO_LOG("1.output data success");
return;
}
void ModelProcess::OutputModelResult(vector<Output_buf> &output)
{
OutputModelResult();
size_t outputSize = aclmdlGetNumOutputs(modelDesc_);
for (size_t i = 0; i < outputSize; ++i) {
Output_buf tmp_output;
//ptr
tmp_output.ptr = outputdata[i];
//size
tmp_output.size = aclmdlGetOutputSizeByIndex(modelDesc_, i);
//ndim & shape
aclmdlIODims d={{'a'},0,{1,2,3}};
aclmdlIODims *dims=&d;
aclError ret = aclmdlGetOutputDims((const aclmdlDesc *)modelDesc_, i, dims);
tmp_output.ndim = (*dims).dimCount;
for(int j=0;j<(*dims).dimCount;j++)
tmp_output.shape.push_back((*dims).dims[j]);
//itemsize & format
aclDataType dt = aclmdlGetOutputDataType(modelDesc_, i);
tmp_output.itemsize=ACLdt_size[dt];
tmp_output.format=ACLdt[dt];
// if(dt==ACL_FLOAT)
// {
// tmp_output.itemsize=4;
// tmp_output.format="float";
// }
// if(dt==ACL_FLOAT16)
// {
// tmp_output.itemsize=2;
// tmp_output.format="float16";
// }
// if(dt==ACL_UINT8)
// {
// tmp_output.itemsize=1;
// tmp_output.format="uint8";
// }
// if(dt==ACL_INT8)
// {
// tmp_output.itemsize=1;
// tmp_output.format="int8";
// }
//strides
int strides=tmp_output.itemsize;
std::vector<int64_t> tmp_strides;
std::vector<int64_t> tmp1_strides;
//vector<int64_t>::reverse_iterator it;//声明一个迭代器,来访问vector容器,作用:遍历或者指向vector容器的元素
for(auto it=tmp_output.shape.rbegin();it!=tmp_output.shape.rend();++it)
{
tmp_strides.push_back(strides);
strides = strides * (*it);
}
//for (int index = 0 ; index < tmp_output.ndim; index++) {
// tmp_strides.push_back(strides);
// strides = strides * tmp_output.shape[index];
//}
for(auto it=tmp_strides.rbegin();it!=tmp_strides.rend();++it){
//for (int index=0;index < tmp_strides.size(); index++) {
tmp1_strides.push_back(*it);
}
tmp_output.strides = tmp1_strides;
output.push_back(tmp_output);
}
INFO_LOG("2.output data 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()
{
aclError ret;
if (!g_isDevice) {
//INFO_LOG("start Unload::aclrtFreeHost is %d", Utils::getCurrentTime());
//for (int index = 0 ; index < outputdata.size(); index++) {
// ret = aclrtFreeHost(outputdata[index]);
//}
for(auto it=outputdata.begin();it!=outputdata.end();++it){
ret = aclrtFreeHost(*it);
}
//INFO_LOG("end Unload::aclrtFreeHost is %d", Utils::getCurrentTime());
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("aclrtFreeHost failed, ret[%d]", ret);
return;
}
}
if (!loadFlag_) {
WARN_LOG("no model had been loaded, unload failed");
return;
}
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_);
}
@@ -0,0 +1,249 @@
/**
* @file sample_process.cpp
*
* Copyright (C) 2020. Huawei Technologies Co., Ltd. All rights reserved.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#include "sample_process.h"
#include <iostream>
#include "acl/acl.h"
#include "utils.h"
using namespace std;
extern bool g_isDevice;
SampleProcess::SampleProcess() :deviceId_(0), context_(nullptr), stream_(nullptr)
{
}
SampleProcess::~SampleProcess()
{
}
Result SampleProcess::InitResource(char* omModelPath)
{
// ACL init
const char *aclConfigPath;
if((aclConfigPath = getenv("ACL_CONFIG_PATH"))) {
INFO_LOG("acl init with config file:%s", aclConfigPath);
} else {
aclConfigPath = "";
}
aclError ret = aclInit(aclConfigPath);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("acl init failed");
return FAILED;
}
INFO_LOG("acl init success");
// open device
ret = aclrtSetDevice(deviceId_);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("acl open device %d failed", deviceId_);
return FAILED;
}
INFO_LOG("open device %d success", deviceId_);
// create context (set current)
ret = aclrtCreateContext(&context_, deviceId_);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("acl create context failed");
return FAILED;
}
INFO_LOG("create context success");
// create stream
ret = aclrtCreateStream(&stream_);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("acl create stream failed");
return FAILED;
}
INFO_LOG("create stream success");
// get run mode
aclrtRunMode runMode;
ret = aclrtGetRunMode(&runMode);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("acl get run mode failed");
return FAILED;
}
g_isDevice = (runMode == ACL_DEVICE);
INFO_LOG("get run mode success");
Result r_ret = processModel.LoadModelFromFileWithMem(omModelPath);
if (r_ret != SUCCESS) {
ERROR_LOG("load model from file failed");
return FAILED;
}
ret = processModel.CreateDesc();
if (ret != SUCCESS) {
ERROR_LOG("create model description failed");
return FAILED;
}
ret = processModel.CreateOutput();
if (ret != SUCCESS) {
ERROR_LOG("create model output failed");
return FAILED;
}
return SUCCESS;
}
Result SampleProcess::Process(void* binfile,int len)
{
//for (size_t index = 0; index < sizeof(testFile) / sizeof(testFile[0]); ++index) {
//INFO_LOG("start to process file:%s", binfile.c_str());
// model process
//INFO_LOG("start memcpy is %d", Utils::getCurrentTime());
uint32_t devBufferSize = len;
void *picDevBuffer = Utils::GetDeviceBufferOfptr(binfile,len);
//ERROR_LOG("devBufferSize is %d", len);
//ERROR_LOG("picDevBuffer:%f.", *((float*)picDevBuffer));
if (picDevBuffer == nullptr) {
ERROR_LOG("get pic device buffer failed,index is %zu", 0);
return FAILED;
}
//INFO_LOG("end memcpy is %d", Utils::getCurrentTime());
//INFO_LOG("start CreateInput is %d", Utils::getCurrentTime());
Result ret = processModel.CreateInput(picDevBuffer, devBufferSize);
if (ret != SUCCESS) {
ERROR_LOG("model create input failed");
aclrtFree(picDevBuffer);
return FAILED;
}
//INFO_LOG("end CreateInput is %d", Utils::getCurrentTime());
INFO_LOG("start Execute is %d", Utils::getCurrentTime());
ret = processModel.Execute();
if (ret != SUCCESS) {
ERROR_LOG("model execute failed");
aclrtFree(picDevBuffer);
return FAILED;
}
INFO_LOG("end Execute is %d", Utils::getCurrentTime());
//INFO_LOG("start aclrtFree is %d", Utils::getCurrentTime());
// release model input buffer
aclrtFree(picDevBuffer);
//INFO_LOG("end aclrtFree is %d", Utils::getCurrentTime());
// print the top 5 confidence values with indexes.use function DumpModelOutputResult
// if want to dump output result to file in the current directory
processModel.OutputModelResult();
//}
// loop end
return SUCCESS;
}
Result SampleProcess::Process(void* binfile,int len, vector<Output_buf> &output, long &npuTime)
{
//for (size_t index = 0; index < sizeof(testFile) / sizeof(testFile[0]); ++index) {
//INFO_LOG("start to process file:%s", binfile.c_str());
// model process
//INFO_LOG("start memcpy is %d", Utils::getCurrentTime());
uint32_t devBufferSize = len;
void *picDevBuffer = Utils::GetDeviceBufferOfptr(binfile,len);
//ERROR_LOG("devBufferSize is %d", len);
//ERROR_LOG("picDevBuffer:%f.", *((float*)picDevBuffer));
if (picDevBuffer == nullptr) {
ERROR_LOG("get pic device buffer failed,index is %zu", 0);
return FAILED;
}
//INFO_LOG("end memcpy is %d", Utils::getCurrentTime());
//INFO_LOG("start CreateInput is %d", Utils::getCurrentTime());
Result ret = processModel.CreateInput(picDevBuffer, devBufferSize);
if (ret != SUCCESS) {
ERROR_LOG("model create input failed");
aclrtFree(picDevBuffer);
return FAILED;
}
//INFO_LOG("end CreateInput is %d", Utils::getCurrentTime());
INFO_LOG("start Execute is %d", Utils::getCurrentTime());
long start = Utils::getCurrentTime();
ret = processModel.Execute();
if (ret != SUCCESS) {
ERROR_LOG("model execute failed");
aclrtFree(picDevBuffer);
return FAILED;
}
long end = Utils::getCurrentTime();
INFO_LOG("end Execute is %d", end);
npuTime = end - start;
if (npuTime < 0) {
ERROR_LOG("NPU time not correct: %d start: %d end: %d", npuTime, start, end);
aclrtFree(picDevBuffer);
return FAILED;
}
INFO_LOG("npu compute cost %f ms", 1.0*(npuTime)/1000.0);
//INFO_LOG("start aclrtFree is %d", Utils::getCurrentTime());
// release model input buffer
aclrtFree(picDevBuffer);
//INFO_LOG("end aclrtFree is %d", Utils::getCurrentTime());
// print the top 5 confidence values with indexes.use function DumpModelOutputResult
// if want to dump output result to file in the current directory
processModel.OutputModelResult(output);
//}
// loop end
return SUCCESS;
}
Result SampleProcess::Unload()
{
processModel.Unload();
processModel.DestroyDesc();
processModel.DestroyInput();
processModel.DestroyOutput();
DestroyResource();
return SUCCESS;
}
void SampleProcess::DestroyResource()
{
aclError ret;
if (stream_ != nullptr) {
ret = aclrtDestroyStream(stream_);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("destroy stream failed");
}
stream_ = nullptr;
INFO_LOG("end to destroy stream");
}
if (context_ != nullptr) {
ret = aclrtDestroyContext(context_);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("destroy context failed");
}
context_ = nullptr;
INFO_LOG("end to destroy context");
}
ret = aclrtResetDevice(deviceId_);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("reset device failed");
}
INFO_LOG("end to reset device is %d", deviceId_);
ret = aclFinalize();
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("finalize acl failed");
}
INFO_LOG("end to finalize acl");
}
@@ -0,0 +1,171 @@
/**
* @file utils.cpp
*
* Copyright (C) 2020. Huawei Technologies Co., Ltd. All rights reserved.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#include "utils.h"
#include <iostream>
#include <fstream>
#include <cstring>
#include "acl/acl.h"
#include <stdio.h>
#include <sys/time.h>
bool g_isDevice = false;
std::map<aclDataType, std::string> ACLdt{{ ACL_DT_UNDEFINED , "undefined"},
{ ACL_FLOAT , "float"},
{ ACL_FLOAT16 , "float16"},
{ ACL_INT8 , "int8"},
{ ACL_INT32 , "int32"},
{ ACL_UINT8 , "uint8"},
{ ACL_INT16 , "int16"},
{ ACL_UINT16 , "uint16"},
{ ACL_UINT32 , "uint32"},
{ ACL_INT64 , "int64"},
{ ACL_UINT64 , "uint64"},
{ ACL_DOUBLE , "double"},
{ ACL_BOOL , "bool"}};
std::map<aclDataType, int> ACLdt_size{{ ACL_DT_UNDEFINED , -1},
{ ACL_FLOAT , 4},
{ ACL_FLOAT16 , 2},
{ ACL_INT8 , 1},
{ ACL_INT32 , 4},
{ ACL_UINT8 , 1},
{ ACL_INT16 , 2},
{ ACL_UINT16 , 2},
{ ACL_UINT32 , 4},
{ ACL_INT64 , 8},
{ ACL_UINT64 , 8},
{ ACL_DOUBLE , 8},
{ ACL_BOOL , 1}};
//Config configSettings("cfg/built-in_config.txt");
void* Utils::ReadBinFile(std::string fileName, uint32_t &fileSize)
{
std::ifstream binFile(fileName, std::ifstream::binary);
if (binFile.is_open() == false) {
ERROR_LOG("open file %s failed", fileName.c_str());
return nullptr;
}
binFile.seekg(0, binFile.end);
uint32_t binFileBufferLen = binFile.tellg();
if (binFileBufferLen == 0) {
ERROR_LOG("binfile is empty, filename is %s", fileName.c_str());
binFile.close();
return nullptr;
}
//ERROR_LOG("binFileBufferLen is %d", binFileBufferLen);
binFile.seekg(0, binFile.beg);
void* binFileBufferData = nullptr;
aclError ret = ACL_ERROR_NONE;
if (!g_isDevice) {
ret = aclrtMallocHost(&binFileBufferData, binFileBufferLen);
if (binFileBufferData == nullptr) {
ERROR_LOG("malloc binFileBufferData failed");
binFile.close();
return nullptr;
}
} else {
ret = aclrtMalloc(&binFileBufferData, binFileBufferLen, (aclrtMemMallocPolicy)(Config::getInstance()->Read("aclrtMemMallocPolicy", 0)));
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("malloc device buffer failed. size is %u", binFileBufferLen);
binFile.close();
return nullptr;
}
}
binFile.read(static_cast<char *>(binFileBufferData), binFileBufferLen);
binFile.close();
fileSize = binFileBufferLen;
return binFileBufferData;
}
void* Utils::GetDeviceBufferOfFile(std::string fileName, uint32_t &fileSize)
{
uint32_t inputHostBuffSize = 0;
void* inputHostBuff = Utils::ReadBinFile(fileName, inputHostBuffSize);
if (inputHostBuff == nullptr) {
return nullptr;
}
if (!g_isDevice) {
void *inBufferDev = nullptr;
uint32_t inBufferSize = inputHostBuffSize;
aclError ret = aclrtMalloc(&inBufferDev, inBufferSize, (aclrtMemMallocPolicy)(Config::getInstance()->Read("aclrtMemMallocPolicy", 0)));
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("malloc device buffer failed. size is %u", inBufferSize);
aclrtFreeHost(inputHostBuff);
return nullptr;
}
ret = aclrtMemcpy(inBufferDev, inBufferSize, inputHostBuff, inputHostBuffSize, ACL_MEMCPY_HOST_TO_DEVICE);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("memcpy failed. device buffer size is %u, input host buffer size is %u",
inBufferSize, inputHostBuffSize);
aclrtFree(inBufferDev);
aclrtFreeHost(inputHostBuff);
return nullptr;
}
aclrtFreeHost(inputHostBuff);
fileSize = inBufferSize;
return inBufferDev;
} else {
fileSize = inputHostBuffSize;
return inputHostBuff;
}
}
void* Utils::GetDeviceBufferOfptr(void* fileName, uint32_t len)
{
uint32_t inputHostBuffSize = len;
void* inputHostBuff = fileName;
if (inputHostBuff == nullptr) {
return nullptr;
}
if (!g_isDevice) {
void *inBufferDev = nullptr;
uint32_t inBufferSize = inputHostBuffSize;
//INFO_LOG("start memcpy::aclrtMalloc is %d", Utils::getCurrentTime());
aclError ret = aclrtMalloc(&inBufferDev, inBufferSize, (aclrtMemMallocPolicy)(Config::getInstance()->Read("aclrtMemMallocPolicy", 0)));
//INFO_LOG("end memcpy::aclrtMalloc is %d", Utils::getCurrentTime());
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("malloc device buffer failed. size is %u", inBufferSize);
aclrtFreeHost(inputHostBuff);
return nullptr;
}
//INFO_LOG("start memcpy::aclrtMemcpy is %d", Utils::getCurrentTime());
ret = aclrtMemcpy(inBufferDev, inBufferSize, inputHostBuff, inputHostBuffSize, ACL_MEMCPY_HOST_TO_DEVICE);
//INFO_LOG("end memcpy::aclrtMemcpy is %d", Utils::getCurrentTime());
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("memcpy failed. device buffer size is %u, input host buffer size is %u",
inBufferSize, inputHostBuffSize);
aclrtFree(inBufferDev);
aclrtFreeHost(inputHostBuff);
return nullptr;
}
//INFO_LOG("start memcpy::aclrtFreeHost is %d", Utils::getCurrentTime());
aclrtFreeHost(inputHostBuff);
//INFO_LOG("end memcpy::aclrtFreeHost is %d", Utils::getCurrentTime());
//fileSize = inBufferSize;
return inBufferDev;
} else {
//fileSize = inputHostBuffSize;
return inputHostBuff;
}
}
long Utils::getCurrentTime()
{
struct timeval tv;
gettimeofday(&tv,NULL);
return tv.tv_sec * 1000000 + tv.tv_usec;
// return tv.tv_usec;
}
@@ -0,0 +1,29 @@
#include "trtbackend.h"
CREATE_BACKEND_INIT(TrtBackend,model,data)
{
INFO_LOG("TrtBackend INIT model success");
return 0;
}
CREATE_BACKEND_LOAD(TrtBackend,model,data)
{
INFO_LOG("TrtBackend LOAD model success");
return 0;
}
CREATE_BACKEND_PREDICT(TrtBackend,model,data,len,output,gpuTime)
{
INFO_LOG("TrtBackend PREDICT model success");
return 0;
}
CREATE_BACKEND_UNLOAD(TrtBackend,model,data)
{
INFO_LOG("TrtBackend UNLOAD model success");
return 0;
}
REGISTER_BASE_BACKEND_CREATOR(TRT, TrtBackend)
@@ -0,0 +1,7 @@
#include "BackendFactory.h"
#include <vector>
CREATE_BACKEND(TrtBackend)
@@ -0,0 +1,91 @@
/**
* 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.
*/
#ifndef BASE_BACKEND_FACTORY_H_
#define BASE_BACKEND_FACTORY_H_
#include <map>
#include <memory>
#include <mutex>
#include <string>
#include "BaseBackend.h"
typedef std::shared_ptr<BaseBackend> (*BASE_BACKEND_CREATOR_FUN)(void);
class BackendFactory {
public:
static BackendFactory *Instance();
int Init();
/**
* @ingroup domi_omg
* @brief Create a backend based on the type entered
* @param [in] type Framework type
* @return Created backend
*/
std::shared_ptr<BaseBackend> CreateBaseBackend(const FrameworkType type);
/**
* @ingroup domi_omg
* @brief Register create function
* @param [in] type Framework type
* @param [in] fun ModelParser's create function
*/
void RegisterCreator(const FrameworkType type, BASE_BACKEND_CREATOR_FUN fun);
protected:
BackendFactory() {}
~BackendFactory();
private:
std::map<FrameworkType, BASE_BACKEND_CREATOR_FUN> creator_map_;
bool is_init_ = false;
}; // end class BackendFactory
class BaseBackendRegisterar {
public:
BaseBackendRegisterar(const FrameworkType type, BASE_BACKEND_CREATOR_FUN fun) {
BackendFactory::Instance()->RegisterCreator(type, fun);
}
~BaseBackendRegisterar() {}
};
// Registration macros for backend
typedef std::shared_ptr<BaseBackend> (*BASE_BACKEND_CREATOR_FUN)(void);
// Registration macros for BaseBackend
#define REGISTER_BASE_BACKEND_CREATOR(type, clazz) \
std::shared_ptr<BaseBackend> Creator_##type##_Base_Backend() { \
std::shared_ptr<clazz> ptr = nullptr; \
try { \
ptr = std::make_shared<clazz>(); \
} catch (...) { \
ptr = nullptr; \
} \
return std::shared_ptr<BaseBackend>(ptr); \
} \
BaseBackendRegisterar g_##type##_Base_Backend_Creator(type, Creator_##type##_Base_Backend);
#endif
@@ -0,0 +1,78 @@
/**
* 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.
*/
#ifndef BASE_BACKEND_H_
#define BASE_BACKEND_H_
//#include "utils.h"
#include "common.h"
#include <vector>
using namespace std;
class BaseBackend {
public:
BaseBackend() {};
/**
* @ingroup domi_omg
* @brief Deconstructor
*/
~BaseBackend() {};
virtual int init(char* model,char* data){};
virtual int load(char* model,char* data){};
virtual int predict(char* model,void* data,int len, std::vector<Output_buf> &output, long &deviceTime){};
virtual int unload(char* model,char* data){};
int param();
int runner();
int runnerthread();
int statistic();
};
#define CREATE_BACKEND(x) \
class x : public BaseBackend{ \
public: \
x(){}; \
~x(){}; \
int init(char* model,char* data); \
int load(char* model,char* data); \
int predict(char* model,void* data,int len, vector<Output_buf> &output, long &deviceTime); \
int unload(char* model,char* data); \
char* model; \
char* data; \
}; \
#define CREATE_BACKEND_INIT(x,model,data) \
int x::init(char* model,char* data)
#define CREATE_BACKEND_LOAD(x,model,data) \
int x::load(char* model,char* data)
#define CREATE_BACKEND_PREDICT(x,model,data,len,output,deviceTime) \
int x::predict(char* model,void* data,int len,vector<Output_buf> &output, long &deviceTime)
#define CREATE_BACKEND_UNLOAD(x,model,data) \
int x::unload(char* model,char* data)
#endif