commit tools
This commit is contained in:
Executable
BIN
Binary file not shown.
Executable
+8
@@ -0,0 +1,8 @@
|
||||
rm -rf build
|
||||
mkdir -p build/intermediates/host
|
||||
cd build/intermediates/host
|
||||
cmake ../../../src -DCMAKE_CXX_COMPILER=g++ -DCMAKE_SKIP_RPATH=TRUE
|
||||
make
|
||||
cd ../../../out
|
||||
mv main amexec
|
||||
|
||||
Executable
+106
@@ -0,0 +1,106 @@
|
||||
//Model_process.h
|
||||
|
||||
/**
|
||||
* @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 "utils.h"
|
||||
#include "acl/acl.h"
|
||||
|
||||
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();
|
||||
|
||||
/**
|
||||
* @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 dump model output result to file
|
||||
*/
|
||||
void DumpModelOutputResult();
|
||||
|
||||
/**
|
||||
* @brief get model output result
|
||||
*/
|
||||
void OutputModelResult(std::string& s,std::string& modelName,size_t index);
|
||||
|
||||
|
||||
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_;
|
||||
};
|
||||
Executable
+50
@@ -0,0 +1,50 @@
|
||||
//Sample_process.h
|
||||
|
||||
/**
|
||||
* @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"
|
||||
|
||||
using namespace std;
|
||||
/**
|
||||
* SampleProcess
|
||||
*/
|
||||
class SampleProcess {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
SampleProcess();
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~SampleProcess();
|
||||
|
||||
/**
|
||||
* @brief init reousce
|
||||
* @return result
|
||||
*/
|
||||
Result InitResource();
|
||||
|
||||
/**
|
||||
* @brief sample process
|
||||
* @return result
|
||||
*/
|
||||
Result Process(vector<string>& params, vector<string>& inputs, size_t idx);
|
||||
|
||||
private:
|
||||
void DestroyResource();
|
||||
|
||||
int32_t deviceId_;
|
||||
aclrtContext context_;
|
||||
aclrtStream stream_;
|
||||
};
|
||||
Executable
+71
@@ -0,0 +1,71 @@
|
||||
//Util.h
|
||||
|
||||
/**
|
||||
* @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 <sstream>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#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)
|
||||
|
||||
using namespace std;
|
||||
static size_t loop = 1;
|
||||
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);
|
||||
|
||||
static void SplitString(std::string& s, std::vector<std::string>& v, char c);
|
||||
|
||||
static int str2num(char *str);
|
||||
|
||||
static std::string modelName(string& s);
|
||||
|
||||
static std::string TimeLine();
|
||||
|
||||
static void printCurrentTime();
|
||||
|
||||
static void printHelpLetter();
|
||||
|
||||
};
|
||||
|
||||
#pragma once
|
||||
Executable
BIN
Binary file not shown.
Executable
+25
@@ -0,0 +1,25 @@
|
||||
**此工具为模型推理工具**
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
功能:输入.om模型和模型所需要的输入bin文件,输出模型的输出数据文件
|
||||
|
||||
|
||||
|
||||
模型必须是通过c7x版本的atc工具转换的om模型,输入bin文件需要符合模型的输入要求
|
||||
|
||||
|
||||
|
||||
工具为命令行的运行方式,例如
|
||||
|
||||
*./amexec --model /home/HwHiAiUser/ljj/colorization.om --input /home/HwHiAiUser/ljj/colorization_input.bin --output /home/HwHiAiUser/ljj/AMEXEC/out/output1 --outfmt TXT --loop 2*
|
||||
|
||||
需要注意的是这几个参数的顺序不能颠倒,outfmt与loop为可选参数,默认值分别有BIN、1。其他参数详情可使用--help查询。
|
||||
|
||||
|
||||
|
||||
运行工具的用户在当前目录需要有创建目录以及执行工具的权限,使用前请自行检查。
|
||||
|
||||
dump、profiling以及动态多batch功能暂不支持。
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
# Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved.
|
||||
|
||||
# CMake lowest version requirement
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
|
||||
# project information
|
||||
project(AME)
|
||||
|
||||
# Compile options
|
||||
add_compile_options(-std=c++11)
|
||||
|
||||
add_definitions(-DENABLE_DVPP_INTERFACE)
|
||||
|
||||
# Specify target generation path
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "../../../out")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-fPIC -O0 -g -Wall")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-fPIC -O2 -Wall")
|
||||
|
||||
set(INC_PATH $ENV{DDK_PATH})
|
||||
|
||||
if (NOT DEFINED ENV{DDK_PATH})
|
||||
set(INC_PATH "/usr/local/Ascend")
|
||||
message(STATUS "set default INC_PATH: ${INC_PATH}")
|
||||
else ()
|
||||
message(STATUS "env INC_PATH: ${INC_PATH}")
|
||||
endif()
|
||||
|
||||
set(LIB_PATH $ENV{NPU_HOST_LIB})
|
||||
|
||||
if (NOT DEFINED ENV{NPU_HOST_LIB})
|
||||
set(LIB_PATH "/usr/local/Ascend/acllib/lib64/stub/")
|
||||
message(STATUS "set default LIB_PATH: ${LIB_PATH}")
|
||||
else ()
|
||||
message(STATUS "env LIB_PATH: ${LIB_PATH}")
|
||||
endif()
|
||||
|
||||
# Header path
|
||||
include_directories(
|
||||
${INC_PATH}/acllib/include/
|
||||
../inc/
|
||||
)
|
||||
|
||||
# add host lib path
|
||||
link_directories(
|
||||
${LIB_PATH}
|
||||
)
|
||||
|
||||
add_executable(main
|
||||
utils.cpp
|
||||
# dvpp_process.cpp
|
||||
model_process.cpp
|
||||
# singleOp_process.cpp
|
||||
sample_process.cpp
|
||||
main.cpp)
|
||||
|
||||
target_link_libraries(main
|
||||
ascendcl acl_cblas acl_dvpp stdc++)
|
||||
|
||||
install(TARGETS main DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
|
||||
Executable
+136
@@ -0,0 +1,136 @@
|
||||
//main.cpp
|
||||
/**
|
||||
* @file main.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 "utils.h"
|
||||
#include<getopt.h>
|
||||
using namespace std;
|
||||
|
||||
|
||||
bool f_isTXT = false;
|
||||
bool g_isDevice = false;
|
||||
string input_Ftype = ".bin";
|
||||
string model_Ftype = ".om";
|
||||
string check = "";
|
||||
|
||||
|
||||
void InitAndCheckParams(int argc, char* argv[], vector<string>& params, vector<string>& inputs)
|
||||
{
|
||||
|
||||
const char *optstring="m::i::o::f::hd::p::l::y::";
|
||||
int c,deb,index;
|
||||
struct option opts[]={{"model",required_argument,NULL,'m'},
|
||||
{"input",required_argument,NULL,'i'},
|
||||
{"output",required_argument,NULL,'o'},
|
||||
{"outfmt",required_argument,NULL,'f'},
|
||||
{"help",no_argument,NULL,1},
|
||||
{"dumpConf",required_argument,NULL,'d'},
|
||||
{"profConf",required_argument,NULL,'p'},
|
||||
{"loop",required_argument,NULL,'l'},
|
||||
{"dymBatch",required_argument,NULL,'y'},
|
||||
{0,0,0,0}};
|
||||
while((c=getopt_long(argc,argv,optstring,opts,&index))!=-1)
|
||||
{
|
||||
|
||||
switch(c)
|
||||
{
|
||||
case 'm':
|
||||
check = optarg;
|
||||
if (check.find(model_Ftype) != string::npos){
|
||||
params.push_back(optarg);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
printf("input model file type is not .om , please check your model type!\n");
|
||||
exit(0);
|
||||
}
|
||||
case 'i':
|
||||
check = optarg;
|
||||
if (check.find(input_Ftype) == string::npos){
|
||||
printf("input data file type is not .bin , please check your input file type!\n");
|
||||
exit(0);
|
||||
}
|
||||
params.push_back(optarg);
|
||||
Utils::SplitString(params[1], inputs, ',');
|
||||
break;
|
||||
case 'o':
|
||||
params.push_back(optarg);
|
||||
break;
|
||||
case 'f':
|
||||
params.push_back(optarg);
|
||||
break;
|
||||
case '?':
|
||||
printf("unknown paramenter\n");
|
||||
printf("Execute sample failed.\n");
|
||||
exit(0);
|
||||
case 'd':
|
||||
params.push_back(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
params.push_back(optarg);
|
||||
break;
|
||||
case 'l':
|
||||
loop = Utils::str2num(optarg);
|
||||
if (loop > 100 || loop < 1)
|
||||
{
|
||||
printf("loop must in 1 to 100\n");
|
||||
exit(0);
|
||||
}
|
||||
break;
|
||||
case 'y':
|
||||
params.push_back(optarg);
|
||||
break;
|
||||
case 1:
|
||||
Utils::printHelpLetter();
|
||||
exit(0);
|
||||
default:
|
||||
printf("unknown paramenter\n");
|
||||
printf("Execute sample failed.\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
vector<string> params;
|
||||
vector<string> inputs;
|
||||
InitAndCheckParams(argc, argv, params, inputs);
|
||||
printf("******************************\n");
|
||||
printf("Test Start!\n");
|
||||
|
||||
|
||||
if (params.empty() || inputs.empty()) {
|
||||
printf("Invalid params.\n");
|
||||
printf("Execute sample failed.\n");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
SampleProcess processSample;
|
||||
|
||||
Result ret = processSample.InitResource();
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("Sample init resource failed.");
|
||||
return FAILED;
|
||||
}
|
||||
for (size_t i = 0;i < loop;i++){
|
||||
std::cout << i << endl;
|
||||
ret = processSample.Process(params, inputs, i);
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("Sample process failed.");
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
INFO_LOG("Execute sample success.");
|
||||
printf("Test Finish!\n");
|
||||
printf("******************************\n");
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
Executable
+571
@@ -0,0 +1,571 @@
|
||||
//Model_procccess.cpp
|
||||
|
||||
/**
|
||||
* @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 "utils.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <cstddef>
|
||||
|
||||
using namespace std;
|
||||
extern bool g_isDevice;
|
||||
extern bool f_isTXT;
|
||||
|
||||
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 model failed, model file is %s", modelPath);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = aclrtMalloc(&modelMemPtr_, modelMemSize_, ACL_MEM_MALLOC_NORMAL_ONLY);
|
||||
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_NORMAL_ONLY);
|
||||
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)
|
||||
{
|
||||
if (input_ == nullptr) {
|
||||
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 (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, 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::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(std::string& s,std::string& modelName,size_t index)
|
||||
{
|
||||
const char* temp_s = s.c_str();
|
||||
if (NULL == opendir(temp_s)){
|
||||
mkdir(temp_s,0775);
|
||||
}
|
||||
std::string T = Utils::TimeLine();
|
||||
//std::string t = s.c_str()+"/"+T.c_str();
|
||||
//const char* time = t.c_str();
|
||||
string times = s+"/"+T+"_"+to_string(index);
|
||||
const char* time = times.c_str();
|
||||
cout << time <<endl;
|
||||
mkdir(time,0775);
|
||||
if (NULL == opendir(time))
|
||||
{
|
||||
ERROR_LOG("current user does not have permission");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) {
|
||||
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i);
|
||||
void* data = aclGetDataBufferAddr(dataBuffer);
|
||||
uint32_t len = aclGetDataBufferSize(dataBuffer);
|
||||
aclDataType datatype = aclmdlGetOutputDataType(modelDesc_, i);
|
||||
void *dims = nullptr;
|
||||
aclmdlIODims *dim = nullptr;
|
||||
aclError ret = aclrtMallocHost(&dims, sizeof(aclmdlIODims));
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("aclrtMallocHost failed, ret[%d]", ret);
|
||||
return;
|
||||
}
|
||||
dim = reinterpret_cast<aclmdlIODims*>(dims);
|
||||
ret = aclmdlGetOutputDims(modelDesc_, i, dim);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("aclmdlGetOutputDims failed, ret[%d]", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
void *outHostData = NULL;
|
||||
ret = ACL_ERROR_NONE;
|
||||
void *outData = NULL;
|
||||
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);
|
||||
return;
|
||||
}
|
||||
switch (datatype)
|
||||
{
|
||||
case 0:
|
||||
outData = reinterpret_cast<float*>(outHostData);
|
||||
break;
|
||||
case 1:
|
||||
outData = reinterpret_cast<aclFloat16*>(outHostData);
|
||||
break;
|
||||
case 2:
|
||||
outData = reinterpret_cast<int8_t*>(outHostData);
|
||||
break;
|
||||
case 3:
|
||||
outData = reinterpret_cast<int*>(outHostData);
|
||||
break;
|
||||
case 4:
|
||||
outData = reinterpret_cast<uint8_t*>(outHostData);
|
||||
break;
|
||||
case 6:
|
||||
outData = reinterpret_cast<int16_t*>(outHostData);
|
||||
break;
|
||||
case 7:
|
||||
outData = reinterpret_cast<uint16_t*>(outHostData);
|
||||
break;
|
||||
case 8:
|
||||
outData = reinterpret_cast<uint32_t*>(outHostData);
|
||||
break;
|
||||
case 9:
|
||||
outData = reinterpret_cast<int64_t*>(outHostData);
|
||||
break;
|
||||
case 10:
|
||||
outData = reinterpret_cast<uint64_t*>(outHostData);
|
||||
break;
|
||||
case 11:
|
||||
outData = reinterpret_cast<double*>(outHostData);
|
||||
break;
|
||||
case 12:
|
||||
outData = reinterpret_cast<bool*>(outHostData);
|
||||
break;
|
||||
default :
|
||||
printf("undefined data type!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
outData = reinterpret_cast<float*>(data);
|
||||
}
|
||||
if (f_isTXT)
|
||||
{
|
||||
ofstream outstr(times+"/"+modelName+"_output_"+to_string(i)+".txt", ios::out);
|
||||
switch (datatype)
|
||||
{
|
||||
case 0:
|
||||
for (int i = 0; i < len/sizeof(float); i++)
|
||||
{
|
||||
float out = *((float*)outData+i);
|
||||
outstr << out << " ";
|
||||
for (int j = 0; j < dim->dimCount; j++)
|
||||
{
|
||||
if (i !=0 && i%dim->dims[j] == 0 && dim->dims[j] > 10)
|
||||
{outstr << "\n" ;}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
for (int i = 0; i < len/sizeof(aclFloat16); i++)
|
||||
{
|
||||
aclFloat16 out = *((aclFloat16*)outData+i);
|
||||
outstr << out << " ";
|
||||
for (int j = 0; j < dim->dimCount; j++)
|
||||
{
|
||||
if (i !=0 && i%dim->dims[j] == 0 && dim->dims[j] > 10)
|
||||
{outstr << "\n" ;}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for (int i = 0; i < len/sizeof(int8_t); i++)
|
||||
{
|
||||
int8_t out = *((int8_t*)outData+i);
|
||||
outstr << out << " ";
|
||||
for (int j = 0; j < dim->dimCount; j++)
|
||||
{
|
||||
if (i !=0 && i%dim->dims[j] == 0 && dim->dims[j] > 10)
|
||||
{outstr << "\n" ;}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for (int i = 0; i < len/sizeof(int); i++)
|
||||
{
|
||||
int out = *((int*)outData+i);
|
||||
outstr << out << " ";
|
||||
for (int j = 0; j < dim->dimCount; j++)
|
||||
{
|
||||
if (i !=0 && i%dim->dims[j] == 0 && dim->dims[j] > 10)
|
||||
{outstr << "\n" ;}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for (int i = 0; i < len/sizeof(uint8_t); i++)
|
||||
{
|
||||
uint8_t out = *((uint8_t*)outData+i);
|
||||
outstr << out << " ";
|
||||
for (int j = 0; j < dim->dimCount; j++)
|
||||
{
|
||||
if (i !=0 && i%dim->dims[j] == 0 && dim->dims[j] > 10)
|
||||
{outstr << "\n" ;}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
for (int i = 0; i < len/sizeof(int16_t); i++)
|
||||
{
|
||||
int16_t out = *((int16_t*)outData+i);
|
||||
outstr << out << " ";
|
||||
for (int j = 0; j < dim->dimCount; j++)
|
||||
{
|
||||
if (i !=0 && i%dim->dims[j] == 0 && dim->dims[j] > 10)
|
||||
{outstr << "\n" ;}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
for (int i = 0; i < len/sizeof(uint16_t); i++)
|
||||
{
|
||||
uint16_t out = *((uint16_t*)outData+i);
|
||||
outstr << out << " ";
|
||||
for (int j = 0; j < dim->dimCount; j++)
|
||||
{
|
||||
if (i !=0 && i%dim->dims[j] == 0 && dim->dims[j] > 10)
|
||||
{outstr << "\n" ;}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
for (int i = 0; i < len/sizeof(uint32_t); i++)
|
||||
{
|
||||
uint32_t out = *((uint32_t*)outData+i);
|
||||
outstr << out << " ";
|
||||
for (int j = 0; j < dim->dimCount; j++)
|
||||
{
|
||||
if (i !=0 && i%dim->dims[j] == 0 && dim->dims[j] > 10)
|
||||
{outstr << "\n" ;}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
for (int i = 0; i < len/sizeof(int64_t); i++)
|
||||
{
|
||||
int64_t out = *((int64_t*)outData+i);
|
||||
outstr << out << " ";
|
||||
for (int j = 0; j < dim->dimCount; j++)
|
||||
{
|
||||
if (i !=0 && i%dim->dims[j] == 0 && dim->dims[j] > 10)
|
||||
{outstr << "\n" ;}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
for (int i = 0; i < len/sizeof(uint64_t); i++)
|
||||
{
|
||||
uint64_t out = *((uint64_t*)outData+i);
|
||||
outstr << out << " ";
|
||||
for (int j = 0; j < dim->dimCount; j++)
|
||||
{
|
||||
if (i !=0 && i%dim->dims[j] == 0 && dim->dims[j] > 10)
|
||||
{outstr << "\n" ;}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
for (int i = 0; i < len/sizeof(double); i++)
|
||||
{
|
||||
double out = *((double*)outData+i);
|
||||
outstr << out << " ";
|
||||
for (int j = 0; j < dim->dimCount; j++)
|
||||
{
|
||||
if (i !=0 && i%dim->dims[j] == 0 && dim->dims[j] > 10)
|
||||
{outstr << "\n" ;}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
for (int i = 0; i < len/sizeof(bool); i++)
|
||||
{
|
||||
int out = *((bool*)outData+i);
|
||||
outstr << out << " ";
|
||||
for (int j = 0; j < dim->dimCount; j++)
|
||||
{
|
||||
if (i !=0 && i%dim->dims[j] == 0 && dim->dims[j] > 10)
|
||||
{outstr << "\n" ;}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default :
|
||||
printf("undefined data type!\n");
|
||||
break;
|
||||
}
|
||||
outstr.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
ofstream outstr(times+"/"+modelName+"_output_"+to_string(i)+".bin", ios::out|ios::binary);
|
||||
|
||||
outstr.write((char*)outData, len);
|
||||
outstr.close();
|
||||
}
|
||||
|
||||
|
||||
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::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_) {
|
||||
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) {
|
||||
aclrtFree(modelMemPtr_);
|
||||
modelMemPtr_ = nullptr;
|
||||
modelMemSize_ = 0;
|
||||
}
|
||||
if (modelWeightPtr_ != nullptr) {
|
||||
aclrtFree(modelWeightPtr_);
|
||||
modelWeightPtr_ = nullptr;
|
||||
modelWeightSize_ = 0;
|
||||
}
|
||||
|
||||
loadFlag_ = false;
|
||||
INFO_LOG("unload model syccess, model Id is %u", modelId_);
|
||||
}
|
||||
Executable
+193
@@ -0,0 +1,193 @@
|
||||
//Sample_process.cpp
|
||||
|
||||
/**
|
||||
* @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 "model_process.h"
|
||||
#include "acl/acl.h"
|
||||
#include "utils.h"
|
||||
using namespace std;
|
||||
extern bool g_isDevice;
|
||||
extern bool f_isTXT;
|
||||
|
||||
SampleProcess::SampleProcess() :deviceId_(0), context_(nullptr), stream_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
SampleProcess::~SampleProcess()
|
||||
{
|
||||
DestroyResource();
|
||||
}
|
||||
|
||||
Result SampleProcess::InitResource()
|
||||
{
|
||||
// ACL init
|
||||
const char *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");
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
Result SampleProcess::Process(vector<string>& params, vector<string>& input_files, size_t idx)
|
||||
{
|
||||
// model init
|
||||
ModelProcess processModel;
|
||||
const char* omModelPath = params[0].c_str();
|
||||
std::string output_path = params[2].c_str();
|
||||
const char* outfmt = params[3].c_str();
|
||||
const char* fmt_TXT = "TXT";
|
||||
f_isTXT = (strcmp(outfmt,fmt_TXT)==0);
|
||||
const char* dumpConf = params[4].c_str();
|
||||
const char* profConf = params[5].c_str();
|
||||
const char* dymBatch = params[6].c_str();
|
||||
|
||||
std::string modelPath = params[0].c_str();
|
||||
std::string modelName = Utils::modelName(modelPath);
|
||||
|
||||
Result ret = processModel.LoadModelFromFileWithMem(omModelPath);
|
||||
if (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;
|
||||
}
|
||||
|
||||
vector<void*> picDevBuffer(input_files.size(),nullptr);
|
||||
|
||||
for (size_t index = 0; index < input_files.size(); ++index) {
|
||||
INFO_LOG("start to process file:%s", input_files[index].c_str());
|
||||
// model process
|
||||
uint32_t devBufferSize;
|
||||
picDevBuffer[index] = Utils::GetDeviceBufferOfFile(input_files[index], devBufferSize);
|
||||
if (picDevBuffer[index] == nullptr) {
|
||||
ERROR_LOG("get pic device buffer failed,index is %zu", index);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = processModel.CreateInput(picDevBuffer[index], devBufferSize);
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("model create input failed");
|
||||
for (size_t i = 0; i <= index; i++) {
|
||||
aclrtFree(picDevBuffer[i]);
|
||||
}
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
// loop end
|
||||
|
||||
printf("Inference begin time: ");
|
||||
Utils::printCurrentTime();
|
||||
ret = processModel.Execute();
|
||||
printf("Inference end time: ");
|
||||
Utils::printCurrentTime();
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("model execute failed");
|
||||
for (size_t i = 0; i < index; i++) {
|
||||
aclrtFree(picDevBuffer[i]);
|
||||
}
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
// print the top 5 confidence values with indexes.use function DumpModelOutputResult
|
||||
// if want to dump output result to file in the current directory
|
||||
//processModel.DumpModelOutputResult();
|
||||
processModel.OutputModelResult(output_path,modelName,idx);
|
||||
processModel.DestroyInput();
|
||||
}
|
||||
// release model input buffer
|
||||
for (size_t i = 0; i < input_files.size(); i++) {
|
||||
aclrtFree(picDevBuffer[i]);
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
}
|
||||
Executable
+177
@@ -0,0 +1,177 @@
|
||||
//Util.cpp
|
||||
|
||||
/**
|
||||
* @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 <sys/time.h>
|
||||
#include "acl/acl.h"
|
||||
using namespace std;
|
||||
extern bool g_isDevice;
|
||||
extern bool f_isTXT;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void Utils::SplitString(std::string& s, std::vector<std::string>& v, char c)
|
||||
{
|
||||
std::string::size_type pos1, pos2;
|
||||
pos2 = s.find(c);
|
||||
pos1 = 0;
|
||||
while(std::string::npos != pos2)
|
||||
{
|
||||
v.push_back(s.substr(pos1, pos2-pos1));
|
||||
pos1 = pos2 + 1;
|
||||
pos2 = s.find(c, pos1);
|
||||
}
|
||||
if(pos1 != s.length())
|
||||
v.push_back(s.substr(pos1));
|
||||
}
|
||||
|
||||
int Utils::str2num(char *str)
|
||||
{
|
||||
int n = 0;
|
||||
int flag = 0;
|
||||
while(*str >= '0' && *str <= '9')
|
||||
{
|
||||
n = n*10 + (*str - '0');
|
||||
str++;
|
||||
}
|
||||
if(flag == 1)
|
||||
{
|
||||
n = -n;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
std::string Utils::modelName(string& s)
|
||||
{
|
||||
string::size_type position1,position2;
|
||||
position1 = s.find_last_of("/");
|
||||
if (position1 == s.npos)
|
||||
{
|
||||
position1 = 0;
|
||||
}
|
||||
position2 = s.find_last_of(".");
|
||||
std::string modelName = s.substr(position1,position2-position1);
|
||||
return modelName;
|
||||
}
|
||||
|
||||
std::string Utils::TimeLine()
|
||||
{
|
||||
time_t currentTime = time(NULL);
|
||||
char chCurrentTime[64];
|
||||
strftime(chCurrentTime, sizeof(chCurrentTime), "%Y%m%d_%H%M%S", localtime(¤tTime));
|
||||
std::string stCurrentTime = chCurrentTime;
|
||||
return stCurrentTime;
|
||||
}
|
||||
|
||||
void Utils::printCurrentTime()
|
||||
{
|
||||
char szBuf[256] = {0};
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
struct tm *p;
|
||||
|
||||
gettimeofday(&tv, &tz);
|
||||
p = localtime(&tv.tv_sec);
|
||||
printf("%02d-%02d-%02d %02d:%02d:%02d.%06ld\n", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, tv.tv_usec);
|
||||
|
||||
}
|
||||
void Utils::printHelpLetter()
|
||||
{
|
||||
cout<< "generate offline model inference output file example:" << endl;
|
||||
cout<< "./amexec --model /home/HwHiAiUser/ljj/colorization.om --input /home/HwHiAiUser/ljj/colorization_input.bin --output /home/HwHiAiUser/ljj/AMEXEC/out/output1 --outfmt TXT --loop 2" << endl << endl;
|
||||
|
||||
cout<< "arguments explain:" << endl;
|
||||
cout<< " --model Model file path" << endl;
|
||||
cout<< " --input Input data path(only accept binary data file) If there are several file, please seprate by ','" << endl;
|
||||
cout<< " --output Output path(User needs to have permission to create directories)" << endl;
|
||||
cout<< " --outfmt Output file format (TXT or BIN, default BIN)" << endl;
|
||||
cout<< " --loop loop time(must in 1 to 100)" << endl;
|
||||
cout<< " --dumpConf dump configure file path (Do not support now)" << endl;
|
||||
cout<< " --profConf profiling configure file path (Do not support now)" << endl;
|
||||
cout<< " --dymBatch dynamic batch (Do not support now)" << endl << endl << endl;
|
||||
|
||||
|
||||
cout<< "NOTECE: " << endl;
|
||||
cout<< " The order of parameter must follow in --model --input --output --outfmt --loop " << endl;
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,40 @@
|
||||
# imgtobin
|
||||
|
||||
imgtobin能够生成模型推理所需的输入数据,以.bin格式保存。
|
||||
有两类数据,一类是图片数据,另一类是模型需要的第二个输入数据,如fasterrcnn的第二个输入是图片的shape信息。
|
||||
|
||||
## 使用方法
|
||||
|
||||
-i后跟**目录**表示转换图片,-i后跟**文件路径**表示转换第二类数据。
|
||||
|
||||
### 第一类图片:
|
||||
|
||||
- 脚本会将 -i 后指定的图片目录下的所有图片按参数设置做相应的预处理,并以"文件名.bin"命名保存在-o指定的输出目录下。
|
||||
|
||||
```
|
||||
python3 imgtobin.py -i ./images -w 416 -h 416 -f BGR -a NCHW -m [104,117,123] -c [1,1,1] -o ./out
|
||||
```
|
||||
|
||||
### 第二类:
|
||||
|
||||
- 第二类数据,需要新建一个文件,文件模板为test.txt,input_node为数据,shape为数据的shape信息。
|
||||
- 第二类数据只需 -i、-t、-o三个参数。
|
||||
- 参数 -i 需要指定文件的路径,-t 需要指定数据类型,-o指定输出目录。
|
||||
|
||||
```
|
||||
python3 imgtobin.py -i ./test.txt -t uint8 -o ./out
|
||||
```
|
||||
|
||||
## 参数说明
|
||||
|
||||
| 参数名 | 说明 |
|
||||
| - | - |
|
||||
| -i | 图片的输入目录或第二个输入的文件路径 |
|
||||
| -w | 输出图片宽 |
|
||||
| -h | 输出图片高 |
|
||||
| -f | 输出图片色彩格式,支持(BGR/RGB/YUV/GRAY) |
|
||||
| -a | 输出图片格式,支持(NCHW/NHWC) |
|
||||
| -t | 图片或第二个数据的输出数据类型,支持(float32/uint8/int32/uint32) |
|
||||
| -m | 减均值,默认为[0,0,0],顺序与图片色彩格式保持一致 <br>当色彩格式为yuv时,设置[0,0] <br>当色彩格式为gray时,设置[0] |
|
||||
| -c | 归一化,默认为 [1,1,1],顺序与图片色彩格式保持一致 <br>当色彩格式为yuv时,设置[1,1] <br>当色彩格式为gray时,设置[1] |
|
||||
| -o | 输出目录 |
|
||||
Binary file not shown.
@@ -0,0 +1,234 @@
|
||||
# !/usr/bin/env python3
|
||||
# -*- coding: UTF-8 -*-
|
||||
#
|
||||
# =======================================================================
|
||||
#
|
||||
# Copyright (C) 2018, Hisilicon Technologies Co., Ltd. All Rights Reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1 Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2 Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 3 Neither the names of the copyright holders nor the names of the
|
||||
# contributors may be used to endorse or promote products derived from this
|
||||
# software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
# =======================================================================
|
||||
#
|
||||
import argparse
|
||||
import configparser
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
def get_args():
|
||||
parser = argparse.ArgumentParser(
|
||||
conflict_handler='resolve',
|
||||
description='''eg1: python3 imgtobin.py
|
||||
-i ./images -w 416 -h 416 -f BGR -a NCHW -m [104,117,123] -o ./out
|
||||
eg2: python3 imgtobin.py -i ./test.txt -t uint8''')
|
||||
parser.add_argument('-i', '--input', required=True, type=str, \
|
||||
help='folder of input image or file of other input.')
|
||||
parser.add_argument('-w', '--width', type=int, \
|
||||
help='resized image width before inference.')
|
||||
parser.add_argument('-h', '--height', type=int, \
|
||||
help='resized image height before inference.')
|
||||
parser.add_argument('-f', '--output_image_format', default='BGR', type=str, \
|
||||
help='output image format in (BGR/RGB/YUV/GRAY).')
|
||||
parser.add_argument('-a', '--output_format', default='NCHW', type=str, \
|
||||
help='output format in (NCHW/NHWC).')
|
||||
parser.add_argument('-t', '--output_type', required=True, type=str, \
|
||||
help='output type in (float32/uint8/int32/uint32).')
|
||||
parser.add_argument('-m', '--mean', default='[0, 0, 0]', \
|
||||
help='reduce mean for each channel.')
|
||||
parser.add_argument('-c', '--coefficient', default='[1, 1, 1]', \
|
||||
help='multiplying coefficients for each channel.')
|
||||
parser.add_argument('-o', '--output', default='./', \
|
||||
help='output path.')
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def eprint(*args, **kwargs):
|
||||
"""print error message to stderr
|
||||
"""
|
||||
print(*args, file=sys.stderr, **kwargs)
|
||||
|
||||
|
||||
def check_args(args):
|
||||
"""check console parameters according to restrictions.
|
||||
:return: True or False
|
||||
"""
|
||||
check_flag = True
|
||||
is_dir = True
|
||||
if os.path.isdir(args.input):
|
||||
#print(args)
|
||||
if not os.listdir(args.input):
|
||||
eprint('[ERROR] input image path=%r is empty.' % path)
|
||||
check_flag = False
|
||||
elif os.path.isfile(args.input):
|
||||
is_dir = False
|
||||
else:
|
||||
eprint('[ERROR] input path=%r does not exist.' % path)
|
||||
check_flag = False
|
||||
|
||||
if args.output_image_format not in ('BGR','RGB', 'YUV', 'GRAY'):
|
||||
eprint("ERROR:Convert to %d is not support"%(args.output_image_format))
|
||||
check_flag = False
|
||||
# if os.path.isfile(args.output_path):
|
||||
# eprint('[ERROR] argument output_path should be a folder.')
|
||||
# elif not os.path.exists(args.output_path):
|
||||
# os.makedirs(args.output_path)
|
||||
# if not 16 <= args.model_width <= 4096:
|
||||
# eprint('[ERROR] resized image width should between 16 and 4096.')
|
||||
# check_flag = False
|
||||
# if not 16 <= args.model_height <= 4096:
|
||||
# eprint('[ERROR] resized image height should between 16 andd 4096.')
|
||||
# check_flag = False
|
||||
return check_flag, is_dir
|
||||
|
||||
|
||||
def convert_img(args, input_img):
|
||||
if args.output_image_format == 'BGR':
|
||||
converted_input_img = input_img
|
||||
elif args.output_image_format == 'RGB':
|
||||
converted_input_img = cv.cvtColor(input_img, cv.COLOR_BGR2RGB)
|
||||
elif args.output_image_format == 'YUV':
|
||||
if input_img.shape[0] % 2 == 1:
|
||||
if input_img.shape[1] % 2 == 1:
|
||||
input_img = cv.resize(input_img, ((input_img.shape[0] + 1), (input_img.shape[1] + 1)))
|
||||
else:
|
||||
input_img = cv.resize(input_img, ((input_img.shape[0] + 1), input_img.shape[1]))
|
||||
elif input_img.shape[1] % 2 == 1:
|
||||
input_img = cv.resize(input_img, (input_img.shape[0], input_img.shape[1] + 1))
|
||||
converted_input_img = cv.cvtColor(input_img, cv.COLOR_BGR2YUV_I420)
|
||||
elif args.output_image_format == 'GRAY':
|
||||
converted_input_img = cv.cvtColor(input_img, cv.COLOR_BGR2GRAY)
|
||||
return converted_input_img
|
||||
|
||||
|
||||
def resize_img(args, input_img):
|
||||
resized_img = cv.resize(input_img, (args.width, args.height))
|
||||
return resized_img
|
||||
|
||||
|
||||
def change_type(args, input_img):
|
||||
if args.output_type == 'float32':
|
||||
change_type_img = input_img.astype(np.float32)
|
||||
elif args.output_type == 'int32':
|
||||
change_type_img = input_img.astype(np.int32)
|
||||
elif args.output_type == 'uint32':
|
||||
change_type_img = input_img.astype(np.uint32)
|
||||
else:
|
||||
change_type_img = input_img.astype(np.uint8)
|
||||
return change_type_img
|
||||
|
||||
|
||||
def mean(args, input_img):
|
||||
if isinstance (args.mean, str):
|
||||
args.mean = json.loads(args.mean)
|
||||
input_img = input_img.astype(np.float32)
|
||||
if args.output_image_format == 'GRAY':
|
||||
input_img[:, :] -= args.mean[0]
|
||||
elif args.output_image_format in ('BGR', 'RGB'):
|
||||
input_img[:, :, 0] -= args.mean[0]
|
||||
input_img[:, :, 1] -= args.mean[1]
|
||||
input_img[:, :, 2] -= args.mean[2]
|
||||
else:
|
||||
input_img[: int(args.width / 1.5), :] -= args.mean[0]
|
||||
input_img[int(args.width / 1.5) :, :: 2] -= args.mean[1]
|
||||
input_img[int(args.width / 1.5) :, 1: 2] -= args.mean[2]
|
||||
return input_img
|
||||
|
||||
|
||||
def coefficient(args, input_img):
|
||||
if isinstance (args.coefficient, str):
|
||||
args.coefficient = json.loads(args.coefficient)
|
||||
input_img = input_img.astype(np.float32)
|
||||
if args.output_image_format == 'GRAY':
|
||||
input_img[:, :] *= args.coefficient[0]
|
||||
elif args.output_image_format in ('BGR', 'RGB'):
|
||||
input_img[:, :, 0] *= args.coefficient[0]
|
||||
input_img[:, :, 1] *= args.coefficient[1]
|
||||
input_img[:, :, 2] *= args.coefficient[2]
|
||||
else:
|
||||
input_img[: int(args.width / 1.5), :] *= args.coefficient[0]
|
||||
input_img[int(args.width / 1.5) :, :: 2] *= args.coefficient[1]
|
||||
input_img[int(args.width / 1.5) :, 1: 2] *= args.coefficient[2]
|
||||
return input_img
|
||||
|
||||
|
||||
def change_format(args, input_img):
|
||||
if args.output_format == 'NCHW':
|
||||
if args.output_image_format in ('RGB', 'BGR'):
|
||||
change_format_img = input_img.transpose(2,0,1).copy()
|
||||
return change_format_img
|
||||
return input_img
|
||||
|
||||
|
||||
def mkdir_output(args):
|
||||
if not os.path.exists(args.output):
|
||||
os.makedirs(args.output)
|
||||
return
|
||||
|
||||
|
||||
def main():
|
||||
"""main function to receive params them change data to bin.
|
||||
"""
|
||||
args = get_args()
|
||||
ret,is_dir = check_args(args)
|
||||
if ret:
|
||||
if is_dir:
|
||||
img_names = os.listdir(args.input)
|
||||
for img_name in img_names:
|
||||
img_path = os.path.join(args.input, img_name)
|
||||
input_img = cv.imread(img_path)
|
||||
if args.output_image_format == 'YUV':
|
||||
resized_img1 = resize_img(args, input_img)
|
||||
converted_img = convert_img(args, resized_img1)
|
||||
mean_img = mean(args, converted_img)
|
||||
else:
|
||||
converted_img = convert_img(args, input_img)
|
||||
resized_img = resize_img(args, converted_img)
|
||||
mean_img = mean(args, resized_img)
|
||||
coefficient_img = coefficient(args, mean_img)
|
||||
change_type_img = change_type(args, coefficient_img)
|
||||
change_format_img = change_format(args, change_type_img)
|
||||
out_path = os.path.join(args.output, os.path.splitext(img_name)[0] + ".bin")
|
||||
mkdir_output(args)
|
||||
change_format_img.tofile(out_path)
|
||||
else:
|
||||
config = configparser.ConfigParser()
|
||||
config.read(args.input)
|
||||
input_node = json.loads(config['baseconf']['input_node'])
|
||||
shape = json.loads(config['baseconf']['shape'])
|
||||
input_node_np = np.array(input_node)
|
||||
change_type_img_info = change_type(args, input_node_np)
|
||||
img_info = np.reshape(change_type_img_info, shape)
|
||||
out_path = os.path.join(args.output, os.path.splitext(args.input)[0] + ".bin")
|
||||
mkdir_output(args)
|
||||
img_info.tofile(out_path)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 136 KiB |
@@ -0,0 +1,3 @@
|
||||
[baseconf]
|
||||
input_node=[1200,1150,416,416]
|
||||
shape=[1,4]
|
||||
Reference in New Issue
Block a user