aclmdlLoadFromMemWithMem:从HOST侧内存加载权重到aclrtMalloc申请的Device内存上
主要讲解同步推理
转换成om模型时,batch_size已固定。
aclError aclmdlLoadFromFile(const char *modelPath, uint32_t *modelId)
:从文件加载om模型,返回模型ID(确保om有权限访问)
aclError aclmdlLoadFromMem(const void *model, size_t modelSize, uint32 _t *modelId)
:从内存加载om模型。此处输入参数model是模型的内存地址,需要申请运行模式的内存(HOST / Device)
aclError aclmdlQuerySize(const char *fileName, size_t *workSize, size_t *weightSize)
:返回权值内存大小和工作内存大小aclError aclmdlLoadFromFileWithMem(const char *modelPath, uint32_t *modelId, void *workPtr, size_t workSize, void *weightPtr, size_t weightSize)
aclrtMalloc
由用户自行申请,管理。aclError aclmdlQuerySizeFromMem(const void *model, size_t modelSize, size_t *workSize, size_t *weightSize)
aclError aclmdlLoadFromMemWithMem(const void *model, size_t modelSize, uint32_t *modelId, void *workPtr, size_t workSize, void *weightPtr, size_t weightSize)
:同样两个Ptr需要申请
aclError aclmdlUnload(uint32_t modelId)
aclmdlDesc* aclmdlCreateDesc()
:创建描述信息对象;用aclError aclmdlDestroyDesc(aclmdlDesc *modelDesc)
销毁aclError aclmdlGetDesc(aclmdlDesc* modelDesc, uint32_t modelId)
:根据模型ID获取模型描述信息
创建数据结构
aclmdlDataset* aclmdlCreateDataset()
;用aclError aclmdlDestroyDataset(const aclmdlDataset *dataset)
销毁
向Dataset添加DataBuffer
aclError aclmdlAddDatasetBuffer(aclmdlDataset* dataset, aclDataBuffer * dataBuffer)
:向aclmdlDataset中增加DataBuffer
获取dataset中buffer数
size_t aclmdlGetDatasetNumBuffer(const aclmdlDataset* dataset)
:常用于输出数据的获取阶段
获取aclmdlDataset中第index个DataBuffer
aclDataBuffer* aclmdlGetDatasetBuffer(const aclmdlDataset *dataset, size_t index)
:常用于输出数据的获取阶段
创建DataBuffer
aclDataBuffer *aclCreateDataBuffer(void *data, size_t size)
:data是由aclrtMalloc申请的device上内存。aclError aclDestroyDataBuffer(const alcDataBuffer *dataBuffer)
仅销毁DataBuffer,data内存没有被释放
获取DataBuffer内容
void *aclGetDataBufferAddr(const acIDataBuffer *dataBuffer)
:返回数据的内存地址
size_t aclGetDataBufferSize(const acIDataBuffer *dataBuffer)
:返回数据的内存大小
同步
aclError aclmdlExecute(uint32_t modelId, const aclmdlDataset *input, aclmdlDataset *output)
异步
aclError aclmdlExecuteAsync(uint32_t modelId, const aclmdlDataset *input, aclmdlDataset *output, aclrtStream stream)
- caffe_model
- .prototxt 模型结构文件
- data
- 1.jpg
- 2.jpg
- inc
- model_process.h
- sample_process.h
- utils.h
- src
- acl.json
- CMakeLists.txt
- main.cpp 主函数
- model_process.cpp
- sample_process.cpp
- utils.cpp
- script
- transferPic.py
- .project
- CMakeLists.txt
#pragma once
#include
#define INFO_LOG(fmt, args...) fprintf(stdout, "[INFO] " fmt "\n", ##args)
#define WARN_LOG(fmt, args...) fprintf(stdout, "[WARN] " fmt "\n", ##args)
#define ERROR_LOG(fmt, args...) fprintf(stdout, "[ERROR] " fmt "\n", ##args)
typedef enum Result {
SUCCESS = 0,
FAILED = 1
} Result;
/**
* Utils
*/
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);
};
#pragma once
#pragma once
#include "utils.h"
#include "acl/acl.h"
/**
* SampleProcess
*/
class SampleProcess {
public:
/**
* @brief Constructor
*/
SampleProcess();
/**
* @brief Destructor
*/
~SampleProcess();
/**
* @brief init reousce
* @return result
*/
Result InitResource();
/**
* @brief sample process
* @return result
*/
Result Process();
private:
void DestroyResource();
int32_t deviceId_;
aclrtContext context_;
aclrtStream stream_;
};
#pragma once
#include
#include "utils.h"
#include "acl/acl.h"
/**
* 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();
/**
* @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();
/**
* @brief model execute
* @return result
*/
Result Execute();
/**
* @brief get model output result
*/
void OutputModelResult();
// void DumpModelOutputResult();
private:
uint32_t modelId_;
size_t modelMemSize_;
size_t modelWeightSize_;
void *modelMemPtr_;
void *modelWeightPtr_;
bool loadFlag_; // model load flag
aclmdlDesc *modelDesc_;
aclmdlDataset *input_;
aclmdlDataset *output_;
};
import numpy as np
import os
from PIL import Image
def process(input_path):
try:
input_image = Image.open(input_path)
input_image = input_image.resize((256, 256))
# hwc
img = np.array(input_image)
height = img.shape[0]
width = img.shape[1]
h_off = int((height-224)/2)
w_off = int((width-224)/2)
crop_img = img[h_off:height-h_off, w_off:width-w_off, :]
# rgb to bgr
img = crop_img[:, :, ::-1]
shape = img.shape
img = img.astype("float16")
img[:, :, 0] -= 104
img[:, :, 1] -= 117
img[:, :, 2] -= 123
img = img.reshape([1] + list(shape))
result = img.transpose([0, 3, 1, 2])
output_name = input_path.split('.')[0] + ".bin"
result.tofile(output_name)
except Exception as except_err:
print(except_err)
return 1
else:
return 0
if __name__ == "__main__":
count_ok = 0
count_ng = 0
images = os.listdir(r'./')
for image_name in images:
if not image_name.endswith("jpg"):
continue
print("start to process image {}....".format(image_name))
ret = process(image_name)
if ret == 0:
print("process image {} successfully".format(image_name))
count_ok = count_ok + 1
elif ret == 1:
print("failed to process image {}".format(image_name))
count_ng = count_ng + 1
print("{} images in total, {} images process successfully, {} images process failed"
.format(count_ok + count_ng, count_ok, count_ng))
# include
# include "sample_process.h"
# include "utils.h"
using namespace std;
bool g_isDevice = false; // 全局变量赋初值
int main(){
SampleProcess processSample;
Result ret = processSample.InitResource(); // 运行资源初始化
if (ret != SUCCESS){
ERROR_LOG("sample init resource failed");
return FAILED;
}
ret = processSample.Process();
if (ret != SUCCESS){
ERROR_LOG("sample process failed");
return FAILED;
}
INFO_LOG("execute sample success");
return SUCCESS;
}
# include
# include "sample_process.h"
# include "utils.h"
# include "model_process.h"
# include "acl/acl.h"
using namespace std;
extern bool g_isDevice;
// 构造方法,为三个成员变量赋初值
SampleProcess::SampleProcess() :deviceId_(0), context_(nullptr), stream_(nullptr)
{
}
// 析构
SampleProcess::~SampleProcess(){
DestroyResource();
}
// 初始化函数
Result SampleProcess::InitResource(){
// ACL初始化
const char *aclConfigPath = "../src/acl.json";
aclError ret = aclInit(aclConfigPath);
if (ret != ACL_ERROR_NONE){ // 判断初始化成功
ERROR_LOG("acl init 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("acl open device %d success", deviceId_);
// create context
ret = aclrtCreateContext(&context_, deviceId_);
if (ret != ACL_ERROR_NONE){
ERROR_LOG("acl create context failed");
return FAILED;
}
INFO_LOG("acl create contxt success");
// create stream
ret = aclrtCreateStream(&stream_);
if (ret != ACL_ERROR_NONE){
ERROR_LOG("acl create stream failed");
return FAILED;
}
INFO_LOG("acl 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");
return SUCCESS;
}
Result SampleProcess::Process(){
// 创建一个modelProcess对象, 这个类构造于model_process.cpp
ModelProcess processModel;
const char* omModelPath = "../model/resnet50.om"; // 模型文件路径
// 手动管理内存, 从文件加载模型
Result ret = processModel.LoadModelFromFileWithMem(omModelPath);
if (ret != SUCCESS){
ERROR_LOG("excute LoadModelFromFileWithMem failed");
return FAILED;
}
// 创建模型描述信息
ret = processModel.CreateDesc();
if (ret != SUCCESS) {
ERROR_LOG("execute CreateModelDesc failed");
return FAILED;
}
// 对于一个模型, 他的输出应该是固定的
ret = processModel.CreateOutput();
if (ret != SUCCESS) {
ERROR_LOG("execute CreateOutput failed");
return FAILED;
}
// =================
// 图片数据
// =================
string testFile[] = {
"../data/dog1_1024_683.bin",
"../data/dog2_1024_683.bin"
};
for (size_t index = 0; index < sizeof(testFile) / sizeof(testFile[0]); ++index) {
INFO_LOG("start to process file:%s", testFile[index].c_str());
// 处理模型
// 不同于resnet50_imageclassification工程; 这里将获取输入放在了循环里
uint32_t devBufferSize;
// 申请这个文件在device上的内存 并返回内存地址
void *picDevBuffer = Utils::GetDeviceBufferOfFile(testFile[index], devBufferSize);
if (picDevBuffer == nullptr){
ERROR_LOG("get pic device buffer failed, index is %zu", index);
return FAILED;
}
// 图片数据内存地址放入input
ret = processModel.CreateInput(picDevBuffer, devBufferSize);
if (ret != SUCCESS){
ERROR_LOG("get pic device buffer failed, index is %zu", index);
aclrtFree(picDevBuffer); // 失败及时销毁
return FAILED;
}
// 推理;结果保存在processModel的成员变量中
ret = processModel.Execute();
if (ret != SUCCESS){
ERROR_LOG("execute inference failed");
aclrtFree(picDevBuffer);
return FAILED;
}
processModel.OutputModelResult();
aclrtFree(picDevBuffer);
processModel.DestroyInput();
}
return SUCCESS;
}
void SampleProcess::DestroyResource()
{
// 销毁顺序:stream -> context -> device -> finalize
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 %d", deviceId_);
ret = aclFinalize();
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("finalize acl failed");
}
INFO_LOG("end to finalize acl");
}
手动管理内存
# include
# include "model_process.h"
# include
# include
# include
# include "utils.h"
using namespace std;
extern bool g_isDevice;
// 构造函数 loadFlag_ 1表示模型已加载
ModelProcess::ModelProcess() :modelId_(0), modelMemSize_(0), modelWeightSize_(0), modelMemPtr_(nullptr), modelWeightPtr_(nullptr), loadFlag_(false), 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 mem of model file %s failed", modelPath);
return FAILED;
}
// 根据查询的模型内存大小分配空间
ret = aclrtMalloc(&modelMemPtr_, modelMemSize_, ACL_MEM_MALLOC_HUGE_FIRST);
if (ret != ACL_ERROR_NONE){
ERROR_LOG("malloc buffer for mem failed, required 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, required size is %zu", modelMemSize_);
return FAILED;
}
// 调用acl接口,从文件加载模型
ret = aclmdlLoadFromFileWithMem(modelPath, &modelId_, modelMemPtr_, modelMemSize_, modelWeightPtr_, modelWeightSize_);
if (ret != ACL_ERROR_NONE){
ERROR_LOG("load model from file %s failed", 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_SUCCESS) {
ERROR_LOG("get model description failed, modelId is %u", modelId_);
return FAILED;
}
INFO_LOG("create model description success");
return SUCCESS;
}
// 有了模型描述, 然后才可以创建输出
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) {
// 获取第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;
}
// 创建databuffer
aclDataBuffer *outputData = aclCreateDataBuffer(outputBuffer, buffer_size);
if (outputData == nullptr) {
ERROR_LOG("can't create data buffer, create output failed");
(void)aclrtFree(outputBuffer);
return FAILED;
}
// 将databuffer放入output dataset
ret = aclmdlAddDatasetBuffer(output_, outputData);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("can't add data buffer, create output failed");
// 如果失败,释放内存
(void)aclrtFree(outputBuffer);
(void)aclDestroyDataBuffer(outputData);
return FAILED;
}
}
INFO_LOG("create model output success");
return SUCCESS;
}
Result ModelProcess::CreateInput(void *inputDataBuffer, size_t bufferSize)
{
input_ = aclmdlCreateDataset();
if (input_ == nullptr) {
ERROR_LOG("can't create dataset, create input failed");
return FAILED;
}
// 创建databuffer
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 (ret != ACL_SUCCESS) {
ERROR_LOG("add input dataset buffer failed");
(void)aclDestroyDataBuffer(inputData);
inputData = nullptr;
return FAILED;
}
INFO_LOG("create model input success");
return SUCCESS;
}
Result ModelProcess::Execute()
{
// 推理,结果放入output中
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::OutputModelResult()
{
for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) {
// 遍历output dataset里的data buffer
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i);
void* data = aclGetDataBufferAddr(dataBuffer);
// uint32_t len = aclGetDataBufferSizeV2(dataBuffer);
uint32_t len = aclGetDataBufferSizeV2(dataBuffer);
void *outHostData = nullptr;
aclError ret = ACL_ERROR_NONE;
float *outData = nullptr;
if (!g_isDevice) { // 如果正在运行在HOST上,就需要把数据从Device上取回到HOST
aclError ret = aclrtMallocHost(&outHostData, len);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("aclrtMallocHost failed, ret[%d]", ret);
return;
}
// Device -> HOST
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;
}
outData = reinterpret_cast<float*>(outHostData);
} else {
outData = reinterpret_cast<float*>(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);
}
if (!g_isDevice) {
ret = aclrtFreeHost(outHostData);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("aclrtFreeHost failed, ret[%d]", ret);
return;
}
}
}
INFO_LOG("output data success");
return;
}
void ModelProcess::DestroyInput()
{
if (input_ == nullptr) {
return;
}
for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(input_); ++i) {
// 销毁所有的buffer
aclDataBuffer *dataBuffer = aclmdlGetDatasetBuffer(input_, i);
(void)aclDestroyDataBuffer(dataBuffer);
}
(void)aclmdlDestroyDataset(input_);
input_ = nullptr;
INFO_LOG("destroy model input success");
}
void ModelProcess::Unload()
{
if (!loadFlag_) {
WARN_LOG("no model had been loaded, unload failed");
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) {
(void)aclrtFree(modelMemPtr_);
modelMemPtr_ = nullptr;
modelMemSize_ = 0;
}
if (modelWeightPtr_ != nullptr) {
(void)aclrtFree(modelWeightPtr_);
modelWeightPtr_ = nullptr;
modelWeightSize_ = 0;
}
loadFlag_ = false;
INFO_LOG("unload model success, modelId is %u", modelId_);
}
void ModelProcess::DestroyDesc()
{
if (modelDesc_ != nullptr) {
(void)aclmdlDestroyDesc(modelDesc_);
modelDesc_ = nullptr;
}
INFO_LOG("destroy model description 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;
INFO_LOG("destroy model output success");
}
#include "utils.h"
#include
#include
#include
#include "acl/acl.h"
#include
extern bool g_isDevice;
void* Utils::ReadBinFile(std::string fileName, uint32_t &fileSize)
{
struct stat sBuf;
int fileStatus = stat(fileName.data(), &sBuf);
if (fileStatus == -1) {
ERROR_LOG("failed to get file");
return nullptr;
}
if (S_ISREG(sBuf.st_mode) == 0) {
ERROR_LOG("%s is not a file, please enter a file", fileName.c_str());
return nullptr;
}
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;
}
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, ACL_MEM_MALLOC_NORMAL_ONLY);
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, ACL_MEM_MALLOC_NORMAL_ONLY);
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;
}
}
下载模型文件.prototxt
和.caffemodel
设置环境. /usr/local/Ascend/ascend-toolkit/set_env.sh
转换模型atc --model caffe_model/resnet50.prototxt --weight caffe_model/resnet50.caffemodel --framework 0 --output model/resnet50 --soc_version Ascend310 --input_format NCHW --input_fp16_nodes data --output_type FP32 --out_nodes prob:0
转换图片格式python3 ../scripts/transferPic.py
转到根目录下mkdir -p build/intermediates/host
编译cmake ../../../src/ -DCMAKE_CXX_COMPILER=g++ -DCMAKE_SKIP_RPATH=TRUE
make
转到生成的out目录下 ./main