forked from huawei/mindspore2022
ascend310_infer
This commit is contained in:
parent
db606e6786
commit
f7cd15e0d9
|
|
@ -84,6 +84,9 @@ python eval.py --device_target=Ascend --data_path=[DATA_PATH] --ckpt_path=[CKPT_
|
|||
├── README.md // descriptions about all the models
|
||||
├── lenet_quant
|
||||
├── README.md // descriptions about LeNet-Quant
|
||||
├── ascend310_infer // application for 310 inference
|
||||
├── scripts
|
||||
├── run_infer_310.sh // shell script for 310 inference
|
||||
├── src
|
||||
│ ├── config.py // parameter configuration
|
||||
│ ├── dataset.py // creating dataset
|
||||
|
|
@ -93,6 +96,8 @@ python eval.py --device_target=Ascend --data_path=[DATA_PATH] --ckpt_path=[CKPT_
|
|||
├── requirements.txt // package needed
|
||||
├── train.py // training LeNet-Quant network with device Ascend
|
||||
├── eval.py // evaluating LeNet-Quant network with device Ascend
|
||||
├── export_bin_file.py // export bin file of MNIST for 310 inference
|
||||
├── postprocess.py // post process for 310 inference
|
||||
```
|
||||
|
||||
## [Script Parameters](#contents)
|
||||
|
|
@ -152,6 +157,34 @@ You can view the results through the file "log.txt". The accuracy of the test da
|
|||
'Accuracy': 0.9842
|
||||
```
|
||||
|
||||
## [Model Export](#contents)
|
||||
|
||||
```shell
|
||||
python export.py --ckpt_path [CKPT_PATH] --data_path [DATA_PATH] --device_target [PLATFORM]
|
||||
```
|
||||
|
||||
## [Ascend 310 inference](#contents)
|
||||
|
||||
You should export AIR model at Ascend 910 before running the command below.
|
||||
You can use export_bin_file.py to export MNIST bin and label for 310 inference.
|
||||
|
||||
```shell
|
||||
python export_bin_file.py --dataset_dir [DATASET_PATH] --save_dir [SAVE_PATH]
|
||||
```
|
||||
|
||||
Run run_infer_310.sh and get the accuracy:
|
||||
|
||||
```shell
|
||||
# Ascend310 inference
|
||||
bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [LABEL_PATH] [DEVICE_ID]
|
||||
```
|
||||
|
||||
You can view the results through the file "acc.log". The accuracy of the test dataset will be as follows:
|
||||
|
||||
```bash
|
||||
'Accuracy':0.9883
|
||||
```
|
||||
|
||||
## [Model Description](#contents)
|
||||
|
||||
### [Performance](#contents)
|
||||
|
|
|
|||
|
|
@ -90,6 +90,9 @@ python eval.py --device_target=Ascend --data_path=[DATA_PATH] --ckpt_path=[CKPT_
|
|||
├── README.md // 所有型号的描述
|
||||
├── lenet_quant
|
||||
├── README.md // LeNet-Quant描述
|
||||
├── ascend310_infer //实现310推理源代码
|
||||
├── scripts
|
||||
├── run_infer_310.sh // Ascend推理shell脚本
|
||||
├──src
|
||||
│ ├── config.py // 参数配置
|
||||
│ ├── dataset.py // 创建数据集
|
||||
|
|
@ -98,7 +101,9 @@ python eval.py --device_target=Ascend --data_path=[DATA_PATH] --ckpt_path=[CKPT_
|
|||
│ ├── loss_monitor.py // 监控网络损失和其他数据
|
||||
├── requirements.txt // 需要的包
|
||||
├── train.py // 使用Ascend训练LeNet-Quant网络
|
||||
├── eval.py // 使用Ascend评估LeNet-Quant网络d
|
||||
├── eval.py // 使用Ascend评估LeNet-Quant网络
|
||||
├── export_bin_file.py // 导出MNIST数据集的bin文件用于310推理
|
||||
├── postprocess.py // 310推理后处理脚本
|
||||
```
|
||||
|
||||
### 脚本参数
|
||||
|
|
@ -156,6 +161,34 @@ python eval.py --data_path Data --ckpt_path ckpt/checkpoint_lenet-1_937.ckpt > l
|
|||
'Accuracy':0.9842
|
||||
```
|
||||
|
||||
### 模型导出
|
||||
|
||||
```shell
|
||||
python export.py --ckpt_path [CKPT_PATH] --data_path [DATA_PATH] --device_target [PLATFORM]
|
||||
```
|
||||
|
||||
### Ascend 310推理
|
||||
|
||||
在推理之前需要在昇腾910环境上完成AIR模型的导出。
|
||||
并使用export_bin_file.py导出MNIST数据集的bin文件和对应的label文件:
|
||||
|
||||
```shell
|
||||
python export_bin_file.py --dataset_dir [DATASET_PATH] --save_dir [SAVE_PATH]
|
||||
```
|
||||
|
||||
执行推理并得到推理精度:
|
||||
|
||||
```shell
|
||||
# Ascend310 inference
|
||||
bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [LABEL_PATH] [DEVICE_ID]
|
||||
```
|
||||
|
||||
您可以通过acc.log文件查看结果。推理准确性如下:
|
||||
|
||||
```bash
|
||||
'Accuracy':0.9883
|
||||
```
|
||||
|
||||
## 模型描述
|
||||
|
||||
### 性能
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
/**
|
||||
* Copyright 2021 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 MODELPROCESS_H
|
||||
#define MODELPROCESS_H
|
||||
|
||||
#include "acl/acl.h"
|
||||
#include "../inc/utils.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 dump model output result to file
|
||||
*/
|
||||
void DumpModelOutputResult(char *output_name);
|
||||
|
||||
/**
|
||||
* @brief get model output result
|
||||
*/
|
||||
void OutputModelResult();
|
||||
|
||||
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_;
|
||||
};
|
||||
#endif
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* Copyright 2021 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 SAMPLEPROCESS_H
|
||||
#define SAMPLEPROCESS_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "acl/acl.h"
|
||||
#include "../inc/utils.h"
|
||||
|
||||
/**
|
||||
* SampleProcess
|
||||
*/
|
||||
class SampleProcess {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
explicit SampleProcess(int32_t deviceId);
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~SampleProcess();
|
||||
|
||||
/**
|
||||
* @brief init reousce
|
||||
* @return result
|
||||
*/
|
||||
Result InitResource(const char *acl_config_path);
|
||||
|
||||
/**
|
||||
* @brief sample process
|
||||
* @return result
|
||||
*/
|
||||
Result Process(const char *om_path, const char *input_folder);
|
||||
|
||||
void GetAllFiles(std::string path, std::vector<std::string> *files);
|
||||
|
||||
private:
|
||||
void DestroyResource();
|
||||
|
||||
int32_t deviceId_;
|
||||
aclrtContext context_;
|
||||
aclrtStream stream_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* Copyright 2021 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 MINDSPORE_INFERENCE_UTILS_H_
|
||||
#define MINDSPORE_INFERENCE_UTILS_H_
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#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 Read bin 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);
|
||||
};
|
||||
#endif
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
|
||||
|
||||
# CMake lowest version requirement
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
# project information
|
||||
project(InferClassification)
|
||||
# Check environment variable
|
||||
if(NOT DEFINED ENV{ASCEND_HOME})
|
||||
message(FATAL_ERROR "please define environment variable:ASCEND_HOME")
|
||||
endif()
|
||||
|
||||
# Compile options
|
||||
add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -std=c++17 -Werror -Wall -fPIE -Wl,--allow-shlib-undefined")
|
||||
|
||||
# Skip build rpath
|
||||
set(CMAKE_SKIP_BUILD_RPATH True)
|
||||
|
||||
# Set output directory
|
||||
set(PROJECT_SRC_ROOT ${CMAKE_CURRENT_LIST_DIR}/)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SRC_ROOT}/out)
|
||||
|
||||
# Set include directory and library directory
|
||||
set(ACL_LIB_DIR $ENV{ASCEND_HOME}/acllib)
|
||||
set(ATLAS_ACL_LIB_DIR $ENV{ASCEND_HOME}/ascend-toolkit/latest/acllib)
|
||||
|
||||
# Header path
|
||||
include_directories(${ACL_LIB_DIR}/include/)
|
||||
include_directories(${ATLAS_ACL_LIB_DIR}/include/)
|
||||
include_directories(${PROJECT_SRC_ROOT}/../inc)
|
||||
|
||||
# add host lib path
|
||||
link_directories(${ACL_LIB_DIR})
|
||||
find_library(acl libascendcl.so ${ACL_LIB_DIR}/lib64 ${ATLAS_ACL_LIB_DIR}/lib64)
|
||||
|
||||
add_executable(main utils.cpp
|
||||
SampleProcess.cpp
|
||||
ModelProcess.cpp
|
||||
main.cpp)
|
||||
|
||||
target_link_libraries(main ${acl} gflags pthread)
|
||||
|
|
@ -0,0 +1,326 @@
|
|||
/**
|
||||
* Copyright 2021 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 "../inc/ModelProcess.h"
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include "../inc/utils.h"
|
||||
|
||||
extern bool g_isDevice;
|
||||
|
||||
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_HUGE_FIRST);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("malloc buffer for mem failed, require size is %zu", modelMemSize_);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = aclrtMalloc(&modelWeightPtr_, modelWeightSize_, ACL_MEM_MALLOC_HUGE_FIRST);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("malloc buffer for weight failed, require size is %zu", modelWeightSize_);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = aclmdlLoadFromFileWithMem(modelPath, &modelId_, modelMemPtr_,
|
||||
modelMemSize_, modelWeightPtr_, modelWeightSize_);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("load model from file failed, model file is %s", modelPath);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
loadFlag_ = true;
|
||||
INFO_LOG("load model %s success", modelPath);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
Result ModelProcess::CreateDesc() {
|
||||
modelDesc_ = aclmdlCreateDesc();
|
||||
if (modelDesc_ == nullptr) {
|
||||
ERROR_LOG("create model description failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
aclError ret = aclmdlGetDesc(modelDesc_, modelId_);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("get model description failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
INFO_LOG("create model description success");
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void ModelProcess::DestroyDesc() {
|
||||
if (modelDesc_ != nullptr) {
|
||||
(void)aclmdlDestroyDesc(modelDesc_);
|
||||
modelDesc_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Result ModelProcess::CreateInput(void *inputDataBuffer, size_t bufferSize) {
|
||||
input_ = aclmdlCreateDataset();
|
||||
if (input_ == nullptr) {
|
||||
ERROR_LOG("can't create dataset, create input failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
aclDataBuffer* inputData = aclCreateDataBuffer(inputDataBuffer, bufferSize);
|
||||
if (inputData == nullptr) {
|
||||
ERROR_LOG("can't create data buffer, create input failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
aclError ret = aclmdlAddDatasetBuffer(input_, inputData);
|
||||
if (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 output 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(char *output_name) {
|
||||
size_t outputNum = aclmdlGetDatasetNumBuffers(output_);
|
||||
std::string homePath = "./result_Files";
|
||||
for (size_t i = 0; i < outputNum; ++i) {
|
||||
std::string fileName = std::string(output_name) + '_' + std::to_string(i) + ".bin";
|
||||
std::string outputFileName = homePath + "/" + fileName;
|
||||
FILE *outputFile = fopen(outputFileName.c_str(), "wb");
|
||||
if (outputFile) {
|
||||
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i);
|
||||
void* data = aclGetDataBufferAddr(dataBuffer);
|
||||
uint32_t len = aclGetDataBufferSizeV2(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() {
|
||||
for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) {
|
||||
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i);
|
||||
void* data = aclGetDataBufferAddr(dataBuffer);
|
||||
uint32_t len = aclGetDataBufferSizeV2(dataBuffer);
|
||||
void *outHostData = NULL;
|
||||
aclError ret = ACL_ERROR_NONE;
|
||||
float *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;
|
||||
}
|
||||
outData = reinterpret_cast<float*>(outHostData);
|
||||
} else {
|
||||
outData = reinterpret_cast<float*>(data);
|
||||
}
|
||||
std::map<float, unsigned int, std::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::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 success, modelId is %u", modelId_);
|
||||
}
|
||||
|
|
@ -0,0 +1,199 @@
|
|||
/**
|
||||
* Copyright 2021 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 "../inc/SampleProcess.h"
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include "../inc/utils.h"
|
||||
#include "../inc/ModelProcess.h"
|
||||
#include "acl/acl.h"
|
||||
|
||||
extern bool g_isDevice;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
SampleProcess::SampleProcess(int32_t deviceId) : context_(nullptr), stream_(nullptr) {
|
||||
deviceId_ = deviceId;
|
||||
}
|
||||
|
||||
SampleProcess::~SampleProcess() {
|
||||
DestroyResource();
|
||||
}
|
||||
|
||||
Result SampleProcess::InitResource(const char *aclConfigPath) {
|
||||
// ACL init
|
||||
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;
|
||||
}
|
||||
|
||||
void SampleProcess::GetAllFiles(std::string path, std::vector<string> *files) {
|
||||
DIR *pDir;
|
||||
struct dirent* ptr;
|
||||
if (!(pDir = opendir(path.c_str())))
|
||||
return;
|
||||
while ((ptr = readdir(pDir)) != 0) {
|
||||
if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0)
|
||||
files->push_back(path + "/" + ptr->d_name);
|
||||
}
|
||||
closedir(pDir);
|
||||
}
|
||||
|
||||
Result SampleProcess::Process(const char *om_path, const char *input_folder) {
|
||||
// model init
|
||||
ModelProcess processModel;
|
||||
|
||||
Result ret = processModel.LoadModelFromFileWithMem(om_path);
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute LoadModelFromFileWithMem failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = processModel.CreateDesc();
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute CreateDesc failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = processModel.CreateOutput();
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute CreateOutput failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
std::vector<string> testFile;
|
||||
GetAllFiles(input_folder, &testFile);
|
||||
|
||||
if (testFile.size() == 0) {
|
||||
WARN_LOG("no input data under folder");
|
||||
}
|
||||
|
||||
// loop begin
|
||||
for (size_t index = 0; index < testFile.size(); ++index) {
|
||||
INFO_LOG("start to process file:%s", testFile[index].c_str());
|
||||
// model process
|
||||
uint32_t devBufferSize;
|
||||
void *picDevBuffer = Utils::GetDeviceBufferOfFile(testFile[index], &devBufferSize);
|
||||
if (picDevBuffer == nullptr) {
|
||||
ERROR_LOG("get pic device buffer failed,index is %zu", index);
|
||||
return FAILED;
|
||||
}
|
||||
ret = processModel.CreateInput(picDevBuffer, devBufferSize);
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute CreateInput failed");
|
||||
aclrtFree(picDevBuffer);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = processModel.Execute();
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute inference failed");
|
||||
aclrtFree(picDevBuffer);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
int pos = testFile[index].find_last_of('/');
|
||||
std::string name = testFile[index].substr(pos+1);
|
||||
std::string outputname = name.substr(0, name.rfind("."));
|
||||
|
||||
// print the top 5 confidence values
|
||||
processModel.OutputModelResult();
|
||||
// dump output result to file in the current directory
|
||||
processModel.DumpModelOutputResult(const_cast<char *>(outputname.c_str()));
|
||||
|
||||
// release model input buffer
|
||||
aclrtFree(picDevBuffer);
|
||||
processModel.DestroyInput();
|
||||
}
|
||||
// loop end
|
||||
|
||||
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 @@
|
|||
{}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
#!/bin/bash
|
||||
# Copyright 2021 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.
|
||||
# ============================================================================
|
||||
path_cur=$(cd "`dirname $0`" || exit; pwd)
|
||||
|
||||
function preparePath() {
|
||||
rm -rf $1
|
||||
mkdir -p $1
|
||||
cd $1 || exit
|
||||
}
|
||||
|
||||
function buildA300() {
|
||||
if [ ! "${ARCH_PATTERN}" ]; then
|
||||
# set ARCH_PATTERN to acllib when it was not specified by user
|
||||
export ARCH_PATTERN=acllib
|
||||
echo "ARCH_PATTERN is set to the default value: ${ARCH_PATTERN}"
|
||||
else
|
||||
echo "ARCH_PATTERN is set to ${ARCH_PATTERN} by user, reset it to ${ARCH_PATTERN}/acllib"
|
||||
export ARCH_PATTERN=${ARCH_PATTERN}/acllib
|
||||
fi
|
||||
|
||||
path_build=$path_cur/build
|
||||
preparePath $path_build
|
||||
cmake ..
|
||||
make -j
|
||||
ret=$?
|
||||
cd ..
|
||||
return ${ret}
|
||||
}
|
||||
|
||||
# set ASCEND_VERSION to ascend-toolkit/latest when it was not specified by user
|
||||
if [ ! "${ASCEND_VERSION}" ]; then
|
||||
export ASCEND_VERSION=ascend-toolkit/latest
|
||||
echo "Set ASCEND_VERSION to the default value: ${ASCEND_VERSION}"
|
||||
else
|
||||
echo "ASCEND_VERSION is set to ${ASCEND_VERSION} by user"
|
||||
fi
|
||||
|
||||
buildA300
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* Copyright 2021 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 <gflags/gflags.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include "../inc/SampleProcess.h"
|
||||
#include "../inc/utils.h"
|
||||
|
||||
bool g_isDevice = false;
|
||||
|
||||
DEFINE_string(om_path, "", "om path");
|
||||
DEFINE_string(dataset_path, "", "dataset path");
|
||||
DEFINE_string(acljson_path, "", "acl json path");
|
||||
DEFINE_int32(device_id, 0, "device id");
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
std::string om_path = FLAGS_om_path;
|
||||
std::string dataset_path = FLAGS_dataset_path;
|
||||
std::string acljson_path = FLAGS_acljson_path;
|
||||
int32_t device_id = FLAGS_device_id;
|
||||
std::ifstream fin(om_path);
|
||||
if (!fin) {
|
||||
std::cout << "Invalid om path." << std::endl;
|
||||
return FAILED;
|
||||
}
|
||||
SampleProcess processSample(device_id);
|
||||
// acl.json is deployed for dump data.
|
||||
Result ret = processSample.InitResource(acljson_path.c_str());
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("sample init resource failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = processSample.Process(om_path.c_str(), dataset_path.c_str());
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("sample process failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
INFO_LOG("execute sample success");
|
||||
return SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
/**
|
||||
* Copyright 2021 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 "../inc/utils.h"
|
||||
#include <sys/stat.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
#include "acl/acl.h"
|
||||
|
||||
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 (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("malloc for binFileBufferData failed");
|
||||
binFile.close();
|
||||
return nullptr;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
# Copyright 2021 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.
|
||||
# ============================================================================
|
||||
"""
|
||||
export mnist dataset to bin.
|
||||
"""
|
||||
import os
|
||||
import argparse
|
||||
from mindspore import context
|
||||
from src.dataset import create_dataset
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description='MNIST to bin')
|
||||
parser.add_argument('--device_target', type=str, default="Ascend",
|
||||
choices=['Ascend', 'GPU'],
|
||||
help='device where the code will be implemented (default: Ascend)')
|
||||
parser.add_argument('--dataset_dir', type=str, default='', help='dataset path')
|
||||
parser.add_argument('--save_dir', type=str, default='', help='path to save bin file')
|
||||
parser.add_argument('--batch_size', type=int, default=1, help='batch size for bin')
|
||||
args_, _ = parser.parse_known_args()
|
||||
return args_
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_args()
|
||||
os.environ["RANK_SIZE"] = '1'
|
||||
os.environ["RANK_ID"] = '0'
|
||||
device_id = int(os.getenv('DEVICE_ID')) if os.getenv('DEVICE_ID') else 0
|
||||
context.set_context(mode=context.GRAPH_MODE, device_target=args.device_target, device_id=device_id)
|
||||
mnist_path = os.path.join(args.dataset_dir, 'test')
|
||||
batch_size = args.batch_size
|
||||
save_dir = os.path.join(args.save_dir, 'lenet_quant_mnist_310_infer_data')
|
||||
folder = os.path.join(save_dir, 'mnist_bs_' + str(batch_size) + '_bin')
|
||||
if not os.path.exists(folder):
|
||||
os.makedirs(folder)
|
||||
ds = create_dataset(mnist_path, batch_size)
|
||||
iter_num = 0
|
||||
label_file = os.path.join(save_dir, './mnist_bs_' + str(batch_size) + '_label.txt')
|
||||
with open(label_file, 'w') as f:
|
||||
for data in ds.create_dict_iterator():
|
||||
image = data['image']
|
||||
label = data['label']
|
||||
file_name = "mnist_" + str(iter_num) + ".bin"
|
||||
file_path = folder + "/" + file_name
|
||||
image.asnumpy().tofile(file_path)
|
||||
f.write(file_name)
|
||||
for i in label:
|
||||
f.write(',' + str(i))
|
||||
f.write('\n')
|
||||
iter_num += 1
|
||||
print("=====iter_num:{}=====".format(iter_num))
|
||||
print("=====image_data:{}=====".format(image))
|
||||
print("=====label_data:{}=====".format(label))
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
# Copyright 2021 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.
|
||||
# ============================================================================
|
||||
"""
|
||||
post process for 310 inference.
|
||||
"""
|
||||
import os
|
||||
import argparse
|
||||
import numpy as np
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description='lenet_quant inference')
|
||||
parser.add_argument('--result_path', type=str, default='', help='result files path')
|
||||
parser.add_argument('--label_path', type=str, default='', help='label file path')
|
||||
args_, _ = parser.parse_known_args()
|
||||
return args_
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_args()
|
||||
path = args.result_path
|
||||
label_path = args.label_path
|
||||
files = os.listdir(path)
|
||||
step = 0
|
||||
sum_right = 0
|
||||
label_dict = {}
|
||||
with open(label_path, 'r') as f:
|
||||
for line in f.readlines():
|
||||
batch_label = line.strip().split(',')
|
||||
label_dict[batch_label[0]] = batch_label[1:]
|
||||
for file in files:
|
||||
full_file_path = os.path.join(path, file)
|
||||
if os.path.isfile(full_file_path):
|
||||
label_file = file.split('_0.bin')[0] + '.bin'
|
||||
label_array = np.array(label_dict[label_file])
|
||||
line = np.fromfile(full_file_path, dtype=np.float32)
|
||||
batch_size = label_array.shape[0]
|
||||
line_comp = line.reshape(batch_size, int(line.shape[0] / batch_size))
|
||||
for i in range(0, batch_size):
|
||||
pred = np.argmax(line_comp[i], axis=0)
|
||||
step += 1
|
||||
if pred == label_array[i].astype(np.int64):
|
||||
sum_right += 1
|
||||
print("=====step:{}=====".format(step))
|
||||
print("=====sum_right:{}=====".format(sum_right))
|
||||
accuracy = sum_right * 100.0 / step
|
||||
print("=====accuracy:{}=====".format(accuracy))
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
#!/bin/bash
|
||||
# Copyright 2021 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.
|
||||
# ============================================================================
|
||||
|
||||
if [[ $# -lt 3 || $# -gt 4 ]]; then
|
||||
echo "Usage: bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [LABEL_PATH] [DEVICE_ID]
|
||||
DEVICE_ID is optional, it can be set by environment variable device_id, otherwise the value is zero"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
get_real_path(){
|
||||
if [ "${1:0:1}" == "/" ]; then
|
||||
echo "$1"
|
||||
else
|
||||
echo "$(realpath -m $PWD/$1)"
|
||||
fi
|
||||
}
|
||||
model=$(get_real_path $1)
|
||||
data_path=$(get_real_path $2)
|
||||
label_path=$(get_real_path $3)
|
||||
|
||||
device_id=0
|
||||
if [ $# == 4 ]; then
|
||||
device_id=$4
|
||||
fi
|
||||
|
||||
echo "mindir name: "$model
|
||||
echo "dataset path: "$data_path
|
||||
echo "label path: "$label_path
|
||||
echo "device id: "$device_id
|
||||
|
||||
export ASCEND_HOME=/usr/local/Ascend/
|
||||
if [ -d ${ASCEND_HOME}/ascend-toolkit ]; then
|
||||
export PATH=$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/ccec_compiler/bin:$ASCEND_HOME/ascend-toolkit/latest/atc/bin:$PATH
|
||||
export LD_LIBRARY_PATH=/usr/local/lib:$ASCEND_HOME/ascend-toolkit/latest/atc/lib64:$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/lib64:$ASCEND_HOME/driver/lib64:$ASCEND_HOME/add-ons:$LD_LIBRARY_PATH
|
||||
export TBE_IMPL_PATH=$ASCEND_HOME/ascend-toolkit/latest/opp/op_impl/built-in/ai_core/tbe
|
||||
export PYTHONPATH=${TBE_IMPL_PATH}:$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/python/site-packages:$PYTHONPATH
|
||||
export ASCEND_OPP_PATH=$ASCEND_HOME/ascend-toolkit/latest/opp
|
||||
else
|
||||
export PATH=$ASCEND_HOME/atc/ccec_compiler/bin:$ASCEND_HOME/atc/bin:$PATH
|
||||
export LD_LIBRARY_PATH=/usr/local/lib:$ASCEND_HOME/atc/lib64:$ASCEND_HOME/acllib/lib64:$ASCEND_HOME/driver/lib64:$ASCEND_HOME/add-ons:$LD_LIBRARY_PATH
|
||||
export PYTHONPATH=$ASCEND_HOME/atc/python/site-packages:$PYTHONPATH
|
||||
export ASCEND_OPP_PATH=$ASCEND_HOME/opp
|
||||
fi
|
||||
|
||||
function air_to_om()
|
||||
{
|
||||
atc --input_format=NCHW --framework=1 --model=$model --output=lenet_quant --soc_version=Ascend310 &> atc.log
|
||||
}
|
||||
|
||||
function compile_app()
|
||||
{
|
||||
cd ../ascend310_infer/src || exit
|
||||
bash build.sh &> build.log
|
||||
}
|
||||
|
||||
function infer()
|
||||
{
|
||||
cd - || exit
|
||||
if [ -d result_Files ]; then
|
||||
rm -rf ./result_Files
|
||||
fi
|
||||
if [ -d time_Result ]; then
|
||||
rm -rf ./time_Result
|
||||
fi
|
||||
mkdir result_Files
|
||||
mkdir time_Result
|
||||
../ascend310_infer/src/out/main --om_path=./lenet_quant.om --dataset_path=$data_path --acljson_path=../ascend310_infer/src/acl.json --device_id=$device_id &> infer.log
|
||||
}
|
||||
|
||||
function cal_acc()
|
||||
{
|
||||
python3.7 ../postprocess.py --result_path=./result_Files --label_path=$label_path &> acc.log
|
||||
}
|
||||
|
||||
air_to_om
|
||||
if [ $? -ne 0 ]; then
|
||||
echo " air to om failed"
|
||||
exit 1
|
||||
fi
|
||||
compile_app
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "compile app code failed"
|
||||
exit 1
|
||||
fi
|
||||
infer
|
||||
if [ $? -ne 0 ]; then
|
||||
echo " execute inference failed"
|
||||
exit 1
|
||||
fi
|
||||
cal_acc
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "calculate accuracy failed"
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -86,11 +86,13 @@ MobileNetV2总体网络架构如下:
|
|||
```python
|
||||
├── mobileNetv2_quant
|
||||
├── Readme.md # MobileNetV2-Quant相关描述
|
||||
├── ascend310_infer # 实现310推理源代码
|
||||
├── scripts
|
||||
│ ├──run_train.sh # 使用Ascend或GPU进行训练的shell脚本
|
||||
│ ├──run_infer.sh # 使用Ascend或GPU进行评估的shell脚本
|
||||
│ ├──run_lsq_train.sh # 使用Ascend或GPU进行LSQ训练的shell脚本
|
||||
│ ├──run_lsq_infer.sh # 使用Ascend或GPU进行LSQ评估的shell脚本
|
||||
│ ├──run_infer_310.sh # Ascend 310 推理shell脚本
|
||||
├── src
|
||||
│ ├──config.py # 参数配置
|
||||
│ ├──dataset.py # 创建数据集
|
||||
|
|
@ -101,6 +103,8 @@ MobileNetV2总体网络架构如下:
|
|||
├── train.py # 训练脚本
|
||||
├── eval.py # 评估脚本
|
||||
├── export.py # 导出检查点文件到air/mindir中
|
||||
├── export_bin_file.py # 导出ImageNet数据集的bin文件用于310推理
|
||||
├── postprocess.py # 310推理后处理脚本
|
||||
```
|
||||
|
||||
## 脚本参数
|
||||
|
|
@ -241,6 +245,28 @@ python export.py --checkpoint_path [CKPT_PATH] --file_format [EXPORT_FORMAT] --d
|
|||
|
||||
`OptimizeOption` 可选 ["QAT", "LEARNED_SCALE"].
|
||||
|
||||
## Ascend 310 推理
|
||||
|
||||
在推理之前需要在昇腾910环境上完成AIR模型的导出。
|
||||
并使用export_bin_file.py导出ImageNet数据集的bin文件和对应的label文件:
|
||||
|
||||
```shell
|
||||
python export_bin_file.py --dataset_dir [EVAL_DATASET_PATH] --save_dir [SAVE_PATH]
|
||||
```
|
||||
|
||||
执行推理并得到推理精度:
|
||||
|
||||
```shell
|
||||
# Ascend310 inference
|
||||
bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [LABEL_PATH] [DEVICE_ID]
|
||||
```
|
||||
|
||||
您可以通过acc.log文件查看结果。QAT量化推理准确性如下:
|
||||
|
||||
```bash
|
||||
'Accuracy':0.7221
|
||||
```
|
||||
|
||||
# 模型描述
|
||||
|
||||
## 性能
|
||||
|
|
|
|||
|
|
@ -73,11 +73,13 @@ Users are free to choose whether to use the LEARNED_SCALE optimize option for qu
|
|||
```python
|
||||
├── mobileNetv2_quant
|
||||
├── Readme.md # descriptions about MobileNetV2-Quant
|
||||
├── ascend310_infer # application for 310 inference
|
||||
├── scripts
|
||||
│ ├──run_train.sh # shell script for train on Ascend or GPU
|
||||
│ ├──run_infer.sh # shell script for evaluation on Ascend or GPU
|
||||
│ ├──run_lsq_train.sh # shell script for train (using the LEARNED_SCALE optimize option) on Ascend or GPU
|
||||
│ ├──run_lsq_infer.sh # shell script for evaluation (using the LEARNED_SCALE optimize option) on Ascend or GPU
|
||||
│ ├──run_infer_310.sh # shell script for 310 inference
|
||||
├── src
|
||||
│ ├──config.py # parameter configuration
|
||||
│ ├──dataset.py # creating dataset
|
||||
|
|
@ -87,7 +89,9 @@ Users are free to choose whether to use the LEARNED_SCALE optimize option for qu
|
|||
│ ├──utils.py # supply the monitor module
|
||||
├── train.py # training script
|
||||
├── eval.py # evaluation script
|
||||
├── export.py # export checkpoint files into air/onnx
|
||||
├── export.py # export checkpoint files into air/mindir
|
||||
├── export_bin_file.py # export bin file of ImageNet for 310 inference
|
||||
├── postprocess.py # post process for 310 inference
|
||||
```
|
||||
|
||||
## [Script Parameters](#contents)
|
||||
|
|
@ -231,6 +235,28 @@ python export.py --checkpoint_path [CKPT_PATH] --file_format [EXPORT_FORMAT] --d
|
|||
`EXPORT_FORMAT` should be in ["AIR", "MINDIR"].
|
||||
`OptimizeOption` should be in ["QAT", "LEARNED_SCALE"].
|
||||
|
||||
## [Ascend 310 inference](#contents)
|
||||
|
||||
You should export AIR model at Ascend 910 before running the command below.
|
||||
You can use export_bin_file.py to export ImageNet bin and label for 310 inference.
|
||||
|
||||
```shell
|
||||
python export_bin_file.py --dataset_dir [EVAL_DATASET_PATH] --save_dir [SAVE_PATH]
|
||||
```
|
||||
|
||||
Run run_infer_310.sh and get the accuracy:
|
||||
|
||||
```shell
|
||||
# Ascend310 inference
|
||||
bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [LABEL_PATH] [DEVICE_ID]
|
||||
```
|
||||
|
||||
You can view the results through the file "acc.log". The accuracy of the test dataset will be as follows:
|
||||
|
||||
```bash
|
||||
'Accuracy':0.7221
|
||||
```
|
||||
|
||||
# [Model description](#contents)
|
||||
|
||||
## [Performance](#contents)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
/**
|
||||
* Copyright 2021 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 MODELPROCESS_H
|
||||
#define MODELPROCESS_H
|
||||
|
||||
#include "acl/acl.h"
|
||||
#include "../inc/utils.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 dump model output result to file
|
||||
*/
|
||||
void DumpModelOutputResult(char *output_name);
|
||||
|
||||
/**
|
||||
* @brief get model output result
|
||||
*/
|
||||
void OutputModelResult();
|
||||
|
||||
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_;
|
||||
};
|
||||
#endif
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* Copyright 2021 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 SAMPLEPROCESS_H
|
||||
#define SAMPLEPROCESS_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "acl/acl.h"
|
||||
#include "../inc/utils.h"
|
||||
|
||||
/**
|
||||
* SampleProcess
|
||||
*/
|
||||
class SampleProcess {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
explicit SampleProcess(int32_t deviceId);
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~SampleProcess();
|
||||
|
||||
/**
|
||||
* @brief init reousce
|
||||
* @return result
|
||||
*/
|
||||
Result InitResource(const char *acl_config_path);
|
||||
|
||||
/**
|
||||
* @brief sample process
|
||||
* @return result
|
||||
*/
|
||||
Result Process(const char *om_path, const char *input_folder);
|
||||
|
||||
void GetAllFiles(std::string path, std::vector<std::string> *files);
|
||||
|
||||
private:
|
||||
void DestroyResource();
|
||||
|
||||
int32_t deviceId_;
|
||||
aclrtContext context_;
|
||||
aclrtStream stream_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* Copyright 2021 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 MINDSPORE_INFERENCE_UTILS_H_
|
||||
#define MINDSPORE_INFERENCE_UTILS_H_
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#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 Read bin 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);
|
||||
};
|
||||
#endif
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
|
||||
|
||||
# CMake lowest version requirement
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
# project information
|
||||
project(InferClassification)
|
||||
# Check environment variable
|
||||
if(NOT DEFINED ENV{ASCEND_HOME})
|
||||
message(FATAL_ERROR "please define environment variable:ASCEND_HOME")
|
||||
endif()
|
||||
|
||||
# Compile options
|
||||
add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -std=c++17 -Werror -Wall -fPIE -Wl,--allow-shlib-undefined")
|
||||
|
||||
# Skip build rpath
|
||||
set(CMAKE_SKIP_BUILD_RPATH True)
|
||||
|
||||
# Set output directory
|
||||
set(PROJECT_SRC_ROOT ${CMAKE_CURRENT_LIST_DIR}/)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SRC_ROOT}/out)
|
||||
|
||||
# Set include directory and library directory
|
||||
set(ACL_LIB_DIR $ENV{ASCEND_HOME}/acllib)
|
||||
set(ATLAS_ACL_LIB_DIR $ENV{ASCEND_HOME}/ascend-toolkit/latest/acllib)
|
||||
|
||||
# Header path
|
||||
include_directories(${ACL_LIB_DIR}/include/)
|
||||
include_directories(${ATLAS_ACL_LIB_DIR}/include/)
|
||||
include_directories(${PROJECT_SRC_ROOT}/../inc)
|
||||
|
||||
# add host lib path
|
||||
link_directories(${ACL_LIB_DIR})
|
||||
find_library(acl libascendcl.so ${ACL_LIB_DIR}/lib64 ${ATLAS_ACL_LIB_DIR}/lib64)
|
||||
|
||||
add_executable(main utils.cpp
|
||||
SampleProcess.cpp
|
||||
ModelProcess.cpp
|
||||
main.cpp)
|
||||
|
||||
target_link_libraries(main ${acl} gflags pthread)
|
||||
|
|
@ -0,0 +1,326 @@
|
|||
/**
|
||||
* Copyright 2021 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 "../inc/ModelProcess.h"
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include "../inc/utils.h"
|
||||
|
||||
extern bool g_isDevice;
|
||||
|
||||
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_HUGE_FIRST);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("malloc buffer for mem failed, require size is %zu", modelMemSize_);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = aclrtMalloc(&modelWeightPtr_, modelWeightSize_, ACL_MEM_MALLOC_HUGE_FIRST);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("malloc buffer for weight failed, require size is %zu", modelWeightSize_);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = aclmdlLoadFromFileWithMem(modelPath, &modelId_, modelMemPtr_,
|
||||
modelMemSize_, modelWeightPtr_, modelWeightSize_);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("load model from file failed, model file is %s", modelPath);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
loadFlag_ = true;
|
||||
INFO_LOG("load model %s success", modelPath);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
Result ModelProcess::CreateDesc() {
|
||||
modelDesc_ = aclmdlCreateDesc();
|
||||
if (modelDesc_ == nullptr) {
|
||||
ERROR_LOG("create model description failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
aclError ret = aclmdlGetDesc(modelDesc_, modelId_);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("get model description failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
INFO_LOG("create model description success");
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void ModelProcess::DestroyDesc() {
|
||||
if (modelDesc_ != nullptr) {
|
||||
(void)aclmdlDestroyDesc(modelDesc_);
|
||||
modelDesc_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Result ModelProcess::CreateInput(void *inputDataBuffer, size_t bufferSize) {
|
||||
input_ = aclmdlCreateDataset();
|
||||
if (input_ == nullptr) {
|
||||
ERROR_LOG("can't create dataset, create input failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
aclDataBuffer* inputData = aclCreateDataBuffer(inputDataBuffer, bufferSize);
|
||||
if (inputData == nullptr) {
|
||||
ERROR_LOG("can't create data buffer, create input failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
aclError ret = aclmdlAddDatasetBuffer(input_, inputData);
|
||||
if (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 output 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(char *output_name) {
|
||||
size_t outputNum = aclmdlGetDatasetNumBuffers(output_);
|
||||
std::string homePath = "./result_Files";
|
||||
for (size_t i = 0; i < outputNum; ++i) {
|
||||
std::string fileName = std::string(output_name) + '_' + std::to_string(i) + ".bin";
|
||||
std::string outputFileName = homePath + "/" + fileName;
|
||||
FILE *outputFile = fopen(outputFileName.c_str(), "wb");
|
||||
if (outputFile) {
|
||||
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i);
|
||||
void* data = aclGetDataBufferAddr(dataBuffer);
|
||||
uint32_t len = aclGetDataBufferSizeV2(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() {
|
||||
for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) {
|
||||
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i);
|
||||
void* data = aclGetDataBufferAddr(dataBuffer);
|
||||
uint32_t len = aclGetDataBufferSizeV2(dataBuffer);
|
||||
void *outHostData = NULL;
|
||||
aclError ret = ACL_ERROR_NONE;
|
||||
float *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;
|
||||
}
|
||||
outData = reinterpret_cast<float*>(outHostData);
|
||||
} else {
|
||||
outData = reinterpret_cast<float*>(data);
|
||||
}
|
||||
std::map<float, unsigned int, std::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::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 success, modelId is %u", modelId_);
|
||||
}
|
||||
|
|
@ -0,0 +1,199 @@
|
|||
/**
|
||||
* Copyright 2021 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 "../inc/SampleProcess.h"
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include "../inc/utils.h"
|
||||
#include "../inc/ModelProcess.h"
|
||||
#include "acl/acl.h"
|
||||
|
||||
extern bool g_isDevice;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
SampleProcess::SampleProcess(int32_t deviceId) : context_(nullptr), stream_(nullptr) {
|
||||
deviceId_ = deviceId;
|
||||
}
|
||||
|
||||
SampleProcess::~SampleProcess() {
|
||||
DestroyResource();
|
||||
}
|
||||
|
||||
Result SampleProcess::InitResource(const char *aclConfigPath) {
|
||||
// ACL init
|
||||
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;
|
||||
}
|
||||
|
||||
void SampleProcess::GetAllFiles(std::string path, std::vector<string> *files) {
|
||||
DIR *pDir;
|
||||
struct dirent* ptr;
|
||||
if (!(pDir = opendir(path.c_str())))
|
||||
return;
|
||||
while ((ptr = readdir(pDir)) != 0) {
|
||||
if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0)
|
||||
files->push_back(path + "/" + ptr->d_name);
|
||||
}
|
||||
closedir(pDir);
|
||||
}
|
||||
|
||||
Result SampleProcess::Process(const char *om_path, const char *input_folder) {
|
||||
// model init
|
||||
ModelProcess processModel;
|
||||
|
||||
Result ret = processModel.LoadModelFromFileWithMem(om_path);
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute LoadModelFromFileWithMem failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = processModel.CreateDesc();
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute CreateDesc failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = processModel.CreateOutput();
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute CreateOutput failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
std::vector<string> testFile;
|
||||
GetAllFiles(input_folder, &testFile);
|
||||
|
||||
if (testFile.size() == 0) {
|
||||
WARN_LOG("no input data under folder");
|
||||
}
|
||||
|
||||
// loop begin
|
||||
for (size_t index = 0; index < testFile.size(); ++index) {
|
||||
INFO_LOG("start to process file:%s", testFile[index].c_str());
|
||||
// model process
|
||||
uint32_t devBufferSize;
|
||||
void *picDevBuffer = Utils::GetDeviceBufferOfFile(testFile[index], &devBufferSize);
|
||||
if (picDevBuffer == nullptr) {
|
||||
ERROR_LOG("get pic device buffer failed,index is %zu", index);
|
||||
return FAILED;
|
||||
}
|
||||
ret = processModel.CreateInput(picDevBuffer, devBufferSize);
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute CreateInput failed");
|
||||
aclrtFree(picDevBuffer);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = processModel.Execute();
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute inference failed");
|
||||
aclrtFree(picDevBuffer);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
int pos = testFile[index].find_last_of('/');
|
||||
std::string name = testFile[index].substr(pos+1);
|
||||
std::string outputname = name.substr(0, name.rfind("."));
|
||||
|
||||
// print the top 5 confidence values
|
||||
processModel.OutputModelResult();
|
||||
// dump output result to file in the current directory
|
||||
processModel.DumpModelOutputResult(const_cast<char *>(outputname.c_str()));
|
||||
|
||||
// release model input buffer
|
||||
aclrtFree(picDevBuffer);
|
||||
processModel.DestroyInput();
|
||||
}
|
||||
// loop end
|
||||
|
||||
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 @@
|
|||
{}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
#!/bin/bash
|
||||
# Copyright 2021 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.
|
||||
# ============================================================================
|
||||
path_cur=$(cd "`dirname $0`" || exit; pwd)
|
||||
|
||||
function preparePath() {
|
||||
rm -rf $1
|
||||
mkdir -p $1
|
||||
cd $1 || exit
|
||||
}
|
||||
|
||||
function buildA300() {
|
||||
if [ ! "${ARCH_PATTERN}" ]; then
|
||||
# set ARCH_PATTERN to acllib when it was not specified by user
|
||||
export ARCH_PATTERN=acllib
|
||||
echo "ARCH_PATTERN is set to the default value: ${ARCH_PATTERN}"
|
||||
else
|
||||
echo "ARCH_PATTERN is set to ${ARCH_PATTERN} by user, reset it to ${ARCH_PATTERN}/acllib"
|
||||
export ARCH_PATTERN=${ARCH_PATTERN}/acllib
|
||||
fi
|
||||
|
||||
path_build=$path_cur/build
|
||||
preparePath $path_build
|
||||
cmake ..
|
||||
make -j
|
||||
ret=$?
|
||||
cd ..
|
||||
return ${ret}
|
||||
}
|
||||
|
||||
# set ASCEND_VERSION to ascend-toolkit/latest when it was not specified by user
|
||||
if [ ! "${ASCEND_VERSION}" ]; then
|
||||
export ASCEND_VERSION=ascend-toolkit/latest
|
||||
echo "Set ASCEND_VERSION to the default value: ${ASCEND_VERSION}"
|
||||
else
|
||||
echo "ASCEND_VERSION is set to ${ASCEND_VERSION} by user"
|
||||
fi
|
||||
|
||||
buildA300
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* Copyright 2021 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 <gflags/gflags.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include "../inc/SampleProcess.h"
|
||||
#include "../inc/utils.h"
|
||||
|
||||
bool g_isDevice = false;
|
||||
|
||||
DEFINE_string(om_path, "", "om path");
|
||||
DEFINE_string(dataset_path, "", "dataset path");
|
||||
DEFINE_string(acljson_path, "", "acl json path");
|
||||
DEFINE_int32(device_id, 0, "device id");
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
std::string om_path = FLAGS_om_path;
|
||||
std::string dataset_path = FLAGS_dataset_path;
|
||||
std::string acljson_path = FLAGS_acljson_path;
|
||||
int32_t device_id = FLAGS_device_id;
|
||||
std::ifstream fin(om_path);
|
||||
if (!fin) {
|
||||
std::cout << "Invalid om path." << std::endl;
|
||||
return FAILED;
|
||||
}
|
||||
SampleProcess processSample(device_id);
|
||||
// acl.json is deployed for dump data.
|
||||
Result ret = processSample.InitResource(acljson_path.c_str());
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("sample init resource failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = processSample.Process(om_path.c_str(), dataset_path.c_str());
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("sample process failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
INFO_LOG("execute sample success");
|
||||
return SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
/**
|
||||
* Copyright 2021 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 "../inc/utils.h"
|
||||
#include <sys/stat.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
#include "acl/acl.h"
|
||||
|
||||
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 (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("malloc for binFileBufferData failed");
|
||||
binFile.close();
|
||||
return nullptr;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
# Copyright 2021 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.
|
||||
# ============================================================================
|
||||
"""
|
||||
export imagenet2012 dataset to bin.
|
||||
"""
|
||||
import os
|
||||
import argparse
|
||||
from mindspore import context
|
||||
from src.dataset import create_dataset
|
||||
from src.config import config_ascend_quant
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description='ImageNet2012 to bin')
|
||||
parser.add_argument('--device_target', type=str, default="Ascend",
|
||||
choices=['Ascend', 'GPU'],
|
||||
help='device where the code will be implemented (default: Ascend)')
|
||||
parser.add_argument('--dataset_dir', type=str, default='', help='dataset path')
|
||||
parser.add_argument('--save_dir', type=str, default='', help='path to save bin file')
|
||||
parser.add_argument('--batch_size', type=int, default=1, help='batch size for bin')
|
||||
args_, _ = parser.parse_known_args()
|
||||
return args_
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_args()
|
||||
os.environ["RANK_SIZE"] = '1'
|
||||
os.environ["RANK_ID"] = '0'
|
||||
device_id = int(os.getenv('DEVICE_ID')) if os.getenv('DEVICE_ID') else 0
|
||||
context.set_context(mode=context.GRAPH_MODE, device_target=args.device_target, device_id=device_id)
|
||||
imagenet2012_path = args.dataset_dir
|
||||
batch_size = args.batch_size
|
||||
save_dir = os.path.join(args.save_dir, 'imagenet2012_310_infer_data')
|
||||
folder = os.path.join(save_dir, 'imagenet2012_bs_' + str(batch_size) + '_bin')
|
||||
if not os.path.exists(folder):
|
||||
os.makedirs(folder)
|
||||
ds = create_dataset(imagenet2012_path, do_train=False, config=config_ascend_quant,
|
||||
device_target=args.device_target, repeat_num=1, batch_size=batch_size)
|
||||
iter_num = 0
|
||||
label_file = os.path.join(save_dir, './imagenet2012_bs_' + str(batch_size) + '_label.txt')
|
||||
with open(label_file, 'w') as f:
|
||||
for data in ds.create_dict_iterator():
|
||||
image = data['image']
|
||||
label = data['label']
|
||||
file_name = "imagenet2012_" + str(iter_num) + ".bin"
|
||||
file_path = folder + "/" + file_name
|
||||
image.asnumpy().tofile(file_path)
|
||||
f.write(file_name)
|
||||
for i in label:
|
||||
f.write(',' + str(i))
|
||||
f.write('\n')
|
||||
iter_num += 1
|
||||
print("=====iter_num:{}=====".format(iter_num))
|
||||
print("=====image_data:{}=====".format(image))
|
||||
print("=====label_data:{}=====".format(label))
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
# Copyright 2021 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.
|
||||
# ============================================================================
|
||||
"""
|
||||
post process for 310 inference.
|
||||
"""
|
||||
import os
|
||||
import argparse
|
||||
import numpy as np
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description='mobilenetv2_quant inference')
|
||||
parser.add_argument('--result_path', type=str, default='', help='result files path')
|
||||
parser.add_argument('--label_path', type=str, default='', help='label file path')
|
||||
args_, _ = parser.parse_known_args()
|
||||
return args_
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_args()
|
||||
path = args.result_path
|
||||
label_path = args.label_path
|
||||
files = os.listdir(path)
|
||||
step = 0
|
||||
sum_right = 0
|
||||
label_dict = {}
|
||||
with open(label_path, 'r') as f:
|
||||
for line in f.readlines():
|
||||
batch_label = line.strip().split(',')
|
||||
label_dict[batch_label[0]] = batch_label[1:]
|
||||
for file in files:
|
||||
full_file_path = os.path.join(path, file)
|
||||
if os.path.isfile(full_file_path):
|
||||
label_file = file.split('_0.bin')[0] + '.bin'
|
||||
label_array = np.array(label_dict[label_file])
|
||||
line = np.fromfile(full_file_path, dtype=np.float32)
|
||||
batch_size = label_array.shape[0]
|
||||
line_comp = line.reshape(batch_size, int(line.shape[0] / batch_size))
|
||||
for i in range(0, batch_size):
|
||||
pred = np.argmax(line_comp[i], axis=0)
|
||||
step += 1
|
||||
if pred == label_array[i].astype(np.int64):
|
||||
sum_right += 1
|
||||
print("=====step:{}=====".format(step))
|
||||
print("=====sum_right:{}=====".format(sum_right))
|
||||
accuracy = sum_right * 100.0 / step
|
||||
print("=====accuracy:{}=====".format(accuracy))
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
#!/bin/bash
|
||||
# Copyright 2021 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.
|
||||
# ============================================================================
|
||||
|
||||
if [[ $# -lt 3 || $# -gt 4 ]]; then
|
||||
echo "Usage: bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [LABEL_PATH] [DEVICE_ID]
|
||||
DEVICE_ID is optional, it can be set by environment variable device_id, otherwise the value is zero"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
get_real_path(){
|
||||
if [ "${1:0:1}" == "/" ]; then
|
||||
echo "$1"
|
||||
else
|
||||
echo "$(realpath -m $PWD/$1)"
|
||||
fi
|
||||
}
|
||||
model=$(get_real_path $1)
|
||||
data_path=$(get_real_path $2)
|
||||
label_path=$(get_real_path $3)
|
||||
|
||||
device_id=0
|
||||
if [ $# == 4 ]; then
|
||||
device_id=$4
|
||||
fi
|
||||
|
||||
echo "mindir name: "$model
|
||||
echo "dataset path: "$data_path
|
||||
echo "label path: "$label_path
|
||||
echo "device id: "$device_id
|
||||
|
||||
export ASCEND_HOME=/usr/local/Ascend/
|
||||
if [ -d ${ASCEND_HOME}/ascend-toolkit ]; then
|
||||
export PATH=$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/ccec_compiler/bin:$ASCEND_HOME/ascend-toolkit/latest/atc/bin:$PATH
|
||||
export LD_LIBRARY_PATH=/usr/local/lib:$ASCEND_HOME/ascend-toolkit/latest/atc/lib64:$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/lib64:$ASCEND_HOME/driver/lib64:$ASCEND_HOME/add-ons:$LD_LIBRARY_PATH
|
||||
export TBE_IMPL_PATH=$ASCEND_HOME/ascend-toolkit/latest/opp/op_impl/built-in/ai_core/tbe
|
||||
export PYTHONPATH=${TBE_IMPL_PATH}:$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/python/site-packages:$PYTHONPATH
|
||||
export ASCEND_OPP_PATH=$ASCEND_HOME/ascend-toolkit/latest/opp
|
||||
else
|
||||
export PATH=$ASCEND_HOME/atc/ccec_compiler/bin:$ASCEND_HOME/atc/bin:$PATH
|
||||
export LD_LIBRARY_PATH=/usr/local/lib:$ASCEND_HOME/atc/lib64:$ASCEND_HOME/acllib/lib64:$ASCEND_HOME/driver/lib64:$ASCEND_HOME/add-ons:$LD_LIBRARY_PATH
|
||||
export PYTHONPATH=$ASCEND_HOME/atc/python/site-packages:$PYTHONPATH
|
||||
export ASCEND_OPP_PATH=$ASCEND_HOME/opp
|
||||
fi
|
||||
|
||||
function air_to_om()
|
||||
{
|
||||
atc --input_format=NCHW --framework=1 --model=$model --output=mobilenetv2_quant --soc_version=Ascend310 &> atc.log
|
||||
}
|
||||
|
||||
function compile_app()
|
||||
{
|
||||
cd ../ascend310_infer/src || exit
|
||||
bash build.sh &> build.log
|
||||
}
|
||||
|
||||
function infer()
|
||||
{
|
||||
cd - || exit
|
||||
if [ -d result_Files ]; then
|
||||
rm -rf ./result_Files
|
||||
fi
|
||||
if [ -d time_Result ]; then
|
||||
rm -rf ./time_Result
|
||||
fi
|
||||
mkdir result_Files
|
||||
mkdir time_Result
|
||||
../ascend310_infer/src/out/main --om_path=./mobilenetv2_quant.om --dataset_path=$data_path --acljson_path=../ascend310_infer/src/acl.json --device_id=$device_id &> infer.log
|
||||
}
|
||||
|
||||
function cal_acc()
|
||||
{
|
||||
python3.7 ../postprocess.py --result_path=./result_Files --label_path=$label_path &> acc.log
|
||||
}
|
||||
|
||||
air_to_om
|
||||
if [ $? -ne 0 ]; then
|
||||
echo " air to om failed"
|
||||
exit 1
|
||||
fi
|
||||
compile_app
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "compile app code failed"
|
||||
exit 1
|
||||
fi
|
||||
infer
|
||||
if [ $? -ne 0 ]; then
|
||||
echo " execute inference failed"
|
||||
exit 1
|
||||
fi
|
||||
cal_acc
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "calculate accuracy failed"
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -73,9 +73,11 @@ For FP16 operators, if the input data type is FP32, the backend of MindSpore wil
|
|||
```python
|
||||
├── resnet50_quant
|
||||
├── README.md # descriptions about Resnet50-Quant
|
||||
├── ascend310_infer # application for 310 inference
|
||||
├── scripts
|
||||
│ ├──run_train.sh # shell script for train on Ascend
|
||||
│ ├──run_infer.sh # shell script for evaluation on Ascend
|
||||
│ ├──run_infer_310.sh # shell script for 310 inference
|
||||
├── models
|
||||
│ ├──resnet_quant.py # define the network model of resnet50-quant
|
||||
│ ├──resnet_quant_manual.py # define the manually quantized network model of resnet50-quant
|
||||
|
|
@ -88,6 +90,8 @@ For FP16 operators, if the input data type is FP32, the backend of MindSpore wil
|
|||
├── train.py # training script
|
||||
├── eval.py # evaluation script
|
||||
├── export.py # export script
|
||||
├── export_bin_file.py # export bin file of ImageNet for 310 inference
|
||||
├── postprocess.py # post process for 310 inference
|
||||
|
||||
```
|
||||
|
||||
|
|
@ -169,6 +173,36 @@ Inference result will be stored in the example path, you can find result like th
|
|||
result: {'acc': 0.76576314102564111}
|
||||
```
|
||||
|
||||
## [Model Export](#contents)
|
||||
|
||||
```shell
|
||||
python export.py --checkpoint_path [CKPT_PATH] --file_format [EXPORT_FORMAT] --device_target [PLATFORM]
|
||||
```
|
||||
|
||||
`EXPORT_FORMAT` should be in ["AIR", "MINDIR"].
|
||||
|
||||
## [Ascend 310 inference](#contents)
|
||||
|
||||
You should export AIR model at Ascend 910 before running the command below.
|
||||
You can use export_bin_file.py to export ImageNet bin and label for 310 inference.
|
||||
|
||||
```shell
|
||||
python export_bin_file.py --dataset_dir [EVAL_DATASET_PATH] --save_dir [SAVE_PATH]
|
||||
```
|
||||
|
||||
Run run_infer_310.sh and get the accuracy:
|
||||
|
||||
```shell
|
||||
# Ascend310 inference
|
||||
bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [LABEL_PATH] [DEVICE_ID]
|
||||
```
|
||||
|
||||
You can view the results through the file "acc.log". The accuracy of the test dataset will be as follows:
|
||||
|
||||
```bash
|
||||
'Accuracy':0.77052
|
||||
```
|
||||
|
||||
# [Model description](#contents)
|
||||
|
||||
## [Performance](#contents)
|
||||
|
|
|
|||
|
|
@ -82,9 +82,11 @@ ResNet-50总体网络架构如下:
|
|||
```python
|
||||
├── resnet50_quant
|
||||
├── Readme.md # ResNet-50-Quant相关描述
|
||||
├── ascend310_infer # 实现310推理源代码
|
||||
├── scripts
|
||||
│ ├──run_train.sh # 使用昇腾处理器进行训练的shell脚本
|
||||
│ ├──run_infer.sh # 使用昇腾处理器进行评估的shell脚本
|
||||
│ ├──run_infer_310.sh # Ascend 310 推理shell脚本
|
||||
├── model
|
||||
│ ├──resnet_quant.py # 定义ResNet50-Quant的网络模型
|
||||
├──src
|
||||
|
|
@ -96,6 +98,8 @@ ResNet-50总体网络架构如下:
|
|||
├── train.py # 训练脚本
|
||||
├── eval.py # 评估脚本
|
||||
├── export.py # 导出脚本
|
||||
├── export_bin_file.py # 导出ImageNet数据集的bin文件用于310推理
|
||||
├── postprocess.py # 310推理后处理脚本
|
||||
|
||||
```
|
||||
|
||||
|
|
@ -177,6 +181,36 @@ epoch: 5 step: 5004, loss is 3.1978393
|
|||
result:{'acc':0.76576314102564111}
|
||||
```
|
||||
|
||||
## 模型导出
|
||||
|
||||
```shell
|
||||
python export.py --checkpoint_path [CKPT_PATH] --file_format [EXPORT_FORMAT] --device_target [PLATFORM]
|
||||
```
|
||||
|
||||
`EXPORT_FORMAT` 可选 ["AIR", "MINDIR"].
|
||||
|
||||
## Ascend 310 推理
|
||||
|
||||
在推理之前需要在昇腾910环境上完成AIR模型的导出。
|
||||
并使用export_bin_file.py导出ImageNet数据集的bin文件和对应的label文件:
|
||||
|
||||
```shell
|
||||
python export_bin_file.py --dataset_dir [EVAL_DATASET_PATH] --save_dir [SAVE_PATH]
|
||||
```
|
||||
|
||||
执行推理并得到推理精度:
|
||||
|
||||
```shell
|
||||
# Ascend310 inference
|
||||
bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [LABEL_PATH] [DEVICE_ID]
|
||||
```
|
||||
|
||||
您可以通过acc.log文件查看结果。推理准确性如下:
|
||||
|
||||
```bash
|
||||
'Accuracy':0.77052
|
||||
```
|
||||
|
||||
# 模型描述
|
||||
|
||||
## 性能
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
/**
|
||||
* Copyright 2021 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 MODELPROCESS_H
|
||||
#define MODELPROCESS_H
|
||||
|
||||
#include "acl/acl.h"
|
||||
#include "../inc/utils.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 dump model output result to file
|
||||
*/
|
||||
void DumpModelOutputResult(char *output_name);
|
||||
|
||||
/**
|
||||
* @brief get model output result
|
||||
*/
|
||||
void OutputModelResult();
|
||||
|
||||
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_;
|
||||
};
|
||||
#endif
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* Copyright 2021 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 SAMPLEPROCESS_H
|
||||
#define SAMPLEPROCESS_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "acl/acl.h"
|
||||
#include "../inc/utils.h"
|
||||
|
||||
/**
|
||||
* SampleProcess
|
||||
*/
|
||||
class SampleProcess {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
explicit SampleProcess(int32_t deviceId);
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~SampleProcess();
|
||||
|
||||
/**
|
||||
* @brief init reousce
|
||||
* @return result
|
||||
*/
|
||||
Result InitResource(const char *acl_config_path);
|
||||
|
||||
/**
|
||||
* @brief sample process
|
||||
* @return result
|
||||
*/
|
||||
Result Process(const char *om_path, const char *input_folder);
|
||||
|
||||
void GetAllFiles(std::string path, std::vector<std::string> *files);
|
||||
|
||||
private:
|
||||
void DestroyResource();
|
||||
|
||||
int32_t deviceId_;
|
||||
aclrtContext context_;
|
||||
aclrtStream stream_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* Copyright 2021 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 MINDSPORE_INFERENCE_UTILS_H_
|
||||
#define MINDSPORE_INFERENCE_UTILS_H_
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#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 Read bin 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);
|
||||
};
|
||||
#endif
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
|
||||
|
||||
# CMake lowest version requirement
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
# project information
|
||||
project(InferClassification)
|
||||
# Check environment variable
|
||||
if(NOT DEFINED ENV{ASCEND_HOME})
|
||||
message(FATAL_ERROR "please define environment variable:ASCEND_HOME")
|
||||
endif()
|
||||
|
||||
# Compile options
|
||||
add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -std=c++17 -Werror -Wall -fPIE -Wl,--allow-shlib-undefined")
|
||||
|
||||
# Skip build rpath
|
||||
set(CMAKE_SKIP_BUILD_RPATH True)
|
||||
|
||||
# Set output directory
|
||||
set(PROJECT_SRC_ROOT ${CMAKE_CURRENT_LIST_DIR}/)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SRC_ROOT}/out)
|
||||
|
||||
# Set include directory and library directory
|
||||
set(ACL_LIB_DIR $ENV{ASCEND_HOME}/acllib)
|
||||
set(ATLAS_ACL_LIB_DIR $ENV{ASCEND_HOME}/ascend-toolkit/latest/acllib)
|
||||
|
||||
# Header path
|
||||
include_directories(${ACL_LIB_DIR}/include/)
|
||||
include_directories(${ATLAS_ACL_LIB_DIR}/include/)
|
||||
include_directories(${PROJECT_SRC_ROOT}/../inc)
|
||||
|
||||
# add host lib path
|
||||
link_directories(${ACL_LIB_DIR})
|
||||
find_library(acl libascendcl.so ${ACL_LIB_DIR}/lib64 ${ATLAS_ACL_LIB_DIR}/lib64)
|
||||
|
||||
add_executable(main utils.cpp
|
||||
SampleProcess.cpp
|
||||
ModelProcess.cpp
|
||||
main.cpp)
|
||||
|
||||
target_link_libraries(main ${acl} gflags pthread)
|
||||
|
|
@ -0,0 +1,326 @@
|
|||
/**
|
||||
* Copyright 2021 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 "../inc/ModelProcess.h"
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include "../inc/utils.h"
|
||||
|
||||
extern bool g_isDevice;
|
||||
|
||||
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_HUGE_FIRST);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("malloc buffer for mem failed, require size is %zu", modelMemSize_);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = aclrtMalloc(&modelWeightPtr_, modelWeightSize_, ACL_MEM_MALLOC_HUGE_FIRST);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("malloc buffer for weight failed, require size is %zu", modelWeightSize_);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = aclmdlLoadFromFileWithMem(modelPath, &modelId_, modelMemPtr_,
|
||||
modelMemSize_, modelWeightPtr_, modelWeightSize_);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("load model from file failed, model file is %s", modelPath);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
loadFlag_ = true;
|
||||
INFO_LOG("load model %s success", modelPath);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
Result ModelProcess::CreateDesc() {
|
||||
modelDesc_ = aclmdlCreateDesc();
|
||||
if (modelDesc_ == nullptr) {
|
||||
ERROR_LOG("create model description failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
aclError ret = aclmdlGetDesc(modelDesc_, modelId_);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("get model description failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
INFO_LOG("create model description success");
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void ModelProcess::DestroyDesc() {
|
||||
if (modelDesc_ != nullptr) {
|
||||
(void)aclmdlDestroyDesc(modelDesc_);
|
||||
modelDesc_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Result ModelProcess::CreateInput(void *inputDataBuffer, size_t bufferSize) {
|
||||
input_ = aclmdlCreateDataset();
|
||||
if (input_ == nullptr) {
|
||||
ERROR_LOG("can't create dataset, create input failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
aclDataBuffer* inputData = aclCreateDataBuffer(inputDataBuffer, bufferSize);
|
||||
if (inputData == nullptr) {
|
||||
ERROR_LOG("can't create data buffer, create input failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
aclError ret = aclmdlAddDatasetBuffer(input_, inputData);
|
||||
if (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 output 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(char *output_name) {
|
||||
size_t outputNum = aclmdlGetDatasetNumBuffers(output_);
|
||||
std::string homePath = "./result_Files";
|
||||
for (size_t i = 0; i < outputNum; ++i) {
|
||||
std::string fileName = std::string(output_name) + '_' + std::to_string(i) + ".bin";
|
||||
std::string outputFileName = homePath + "/" + fileName;
|
||||
FILE *outputFile = fopen(outputFileName.c_str(), "wb");
|
||||
if (outputFile) {
|
||||
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i);
|
||||
void* data = aclGetDataBufferAddr(dataBuffer);
|
||||
uint32_t len = aclGetDataBufferSizeV2(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() {
|
||||
for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) {
|
||||
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i);
|
||||
void* data = aclGetDataBufferAddr(dataBuffer);
|
||||
uint32_t len = aclGetDataBufferSizeV2(dataBuffer);
|
||||
void *outHostData = NULL;
|
||||
aclError ret = ACL_ERROR_NONE;
|
||||
float *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;
|
||||
}
|
||||
outData = reinterpret_cast<float*>(outHostData);
|
||||
} else {
|
||||
outData = reinterpret_cast<float*>(data);
|
||||
}
|
||||
std::map<float, unsigned int, std::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::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 success, modelId is %u", modelId_);
|
||||
}
|
||||
|
|
@ -0,0 +1,199 @@
|
|||
/**
|
||||
* Copyright 2021 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 "../inc/SampleProcess.h"
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include "../inc/utils.h"
|
||||
#include "../inc/ModelProcess.h"
|
||||
#include "acl/acl.h"
|
||||
|
||||
extern bool g_isDevice;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
SampleProcess::SampleProcess(int32_t deviceId) : context_(nullptr), stream_(nullptr) {
|
||||
deviceId_ = deviceId;
|
||||
}
|
||||
|
||||
SampleProcess::~SampleProcess() {
|
||||
DestroyResource();
|
||||
}
|
||||
|
||||
Result SampleProcess::InitResource(const char *aclConfigPath) {
|
||||
// ACL init
|
||||
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;
|
||||
}
|
||||
|
||||
void SampleProcess::GetAllFiles(std::string path, std::vector<string> *files) {
|
||||
DIR *pDir;
|
||||
struct dirent* ptr;
|
||||
if (!(pDir = opendir(path.c_str())))
|
||||
return;
|
||||
while ((ptr = readdir(pDir)) != 0) {
|
||||
if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0)
|
||||
files->push_back(path + "/" + ptr->d_name);
|
||||
}
|
||||
closedir(pDir);
|
||||
}
|
||||
|
||||
Result SampleProcess::Process(const char *om_path, const char *input_folder) {
|
||||
// model init
|
||||
ModelProcess processModel;
|
||||
|
||||
Result ret = processModel.LoadModelFromFileWithMem(om_path);
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute LoadModelFromFileWithMem failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = processModel.CreateDesc();
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute CreateDesc failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = processModel.CreateOutput();
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute CreateOutput failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
std::vector<string> testFile;
|
||||
GetAllFiles(input_folder, &testFile);
|
||||
|
||||
if (testFile.size() == 0) {
|
||||
WARN_LOG("no input data under folder");
|
||||
}
|
||||
|
||||
// loop begin
|
||||
for (size_t index = 0; index < testFile.size(); ++index) {
|
||||
INFO_LOG("start to process file:%s", testFile[index].c_str());
|
||||
// model process
|
||||
uint32_t devBufferSize;
|
||||
void *picDevBuffer = Utils::GetDeviceBufferOfFile(testFile[index], &devBufferSize);
|
||||
if (picDevBuffer == nullptr) {
|
||||
ERROR_LOG("get pic device buffer failed,index is %zu", index);
|
||||
return FAILED;
|
||||
}
|
||||
ret = processModel.CreateInput(picDevBuffer, devBufferSize);
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute CreateInput failed");
|
||||
aclrtFree(picDevBuffer);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = processModel.Execute();
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute inference failed");
|
||||
aclrtFree(picDevBuffer);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
int pos = testFile[index].find_last_of('/');
|
||||
std::string name = testFile[index].substr(pos+1);
|
||||
std::string outputname = name.substr(0, name.rfind("."));
|
||||
|
||||
// print the top 5 confidence values
|
||||
processModel.OutputModelResult();
|
||||
// dump output result to file in the current directory
|
||||
processModel.DumpModelOutputResult(const_cast<char *>(outputname.c_str()));
|
||||
|
||||
// release model input buffer
|
||||
aclrtFree(picDevBuffer);
|
||||
processModel.DestroyInput();
|
||||
}
|
||||
// loop end
|
||||
|
||||
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 @@
|
|||
{}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
#!/bin/bash
|
||||
# Copyright 2021 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.
|
||||
# ============================================================================
|
||||
path_cur=$(cd "`dirname $0`" || exit; pwd)
|
||||
|
||||
function preparePath() {
|
||||
rm -rf $1
|
||||
mkdir -p $1
|
||||
cd $1 || exit
|
||||
}
|
||||
|
||||
function buildA300() {
|
||||
if [ ! "${ARCH_PATTERN}" ]; then
|
||||
# set ARCH_PATTERN to acllib when it was not specified by user
|
||||
export ARCH_PATTERN=acllib
|
||||
echo "ARCH_PATTERN is set to the default value: ${ARCH_PATTERN}"
|
||||
else
|
||||
echo "ARCH_PATTERN is set to ${ARCH_PATTERN} by user, reset it to ${ARCH_PATTERN}/acllib"
|
||||
export ARCH_PATTERN=${ARCH_PATTERN}/acllib
|
||||
fi
|
||||
|
||||
path_build=$path_cur/build
|
||||
preparePath $path_build
|
||||
cmake ..
|
||||
make -j
|
||||
ret=$?
|
||||
cd ..
|
||||
return ${ret}
|
||||
}
|
||||
|
||||
# set ASCEND_VERSION to ascend-toolkit/latest when it was not specified by user
|
||||
if [ ! "${ASCEND_VERSION}" ]; then
|
||||
export ASCEND_VERSION=ascend-toolkit/latest
|
||||
echo "Set ASCEND_VERSION to the default value: ${ASCEND_VERSION}"
|
||||
else
|
||||
echo "ASCEND_VERSION is set to ${ASCEND_VERSION} by user"
|
||||
fi
|
||||
|
||||
buildA300
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* Copyright 2021 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 <gflags/gflags.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include "../inc/SampleProcess.h"
|
||||
#include "../inc/utils.h"
|
||||
|
||||
bool g_isDevice = false;
|
||||
|
||||
DEFINE_string(om_path, "", "om path");
|
||||
DEFINE_string(dataset_path, "", "dataset path");
|
||||
DEFINE_string(acljson_path, "", "acl json path");
|
||||
DEFINE_int32(device_id, 0, "device id");
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
std::string om_path = FLAGS_om_path;
|
||||
std::string dataset_path = FLAGS_dataset_path;
|
||||
std::string acljson_path = FLAGS_acljson_path;
|
||||
int32_t device_id = FLAGS_device_id;
|
||||
std::ifstream fin(om_path);
|
||||
if (!fin) {
|
||||
std::cout << "Invalid om path." << std::endl;
|
||||
return FAILED;
|
||||
}
|
||||
SampleProcess processSample(device_id);
|
||||
// acl.json is deployed for dump data.
|
||||
Result ret = processSample.InitResource(acljson_path.c_str());
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("sample init resource failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = processSample.Process(om_path.c_str(), dataset_path.c_str());
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("sample process failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
INFO_LOG("execute sample success");
|
||||
return SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
/**
|
||||
* Copyright 2021 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 "../inc/utils.h"
|
||||
#include <sys/stat.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
#include "acl/acl.h"
|
||||
|
||||
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 (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("malloc for binFileBufferData failed");
|
||||
binFile.close();
|
||||
return nullptr;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
# Copyright 2021 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.
|
||||
# ============================================================================
|
||||
"""
|
||||
export imagenet2012 dataset to bin.
|
||||
"""
|
||||
import os
|
||||
import argparse
|
||||
from mindspore import context
|
||||
from src.dataset import create_dataset
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description='ImageNet2012 to bin')
|
||||
parser.add_argument('--device_target', type=str, default="Ascend",
|
||||
choices=['Ascend', 'GPU'],
|
||||
help='device where the code will be implemented (default: Ascend)')
|
||||
parser.add_argument('--dataset_dir', type=str, default='', help='dataset path')
|
||||
parser.add_argument('--save_dir', type=str, default='', help='path to save bin file')
|
||||
parser.add_argument('--batch_size', type=int, default=1, help='batch size for bin')
|
||||
args_, _ = parser.parse_known_args()
|
||||
return args_
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_args()
|
||||
os.environ["RANK_SIZE"] = '1'
|
||||
os.environ["RANK_ID"] = '0'
|
||||
device_id = int(os.getenv('DEVICE_ID')) if os.getenv('DEVICE_ID') else 0
|
||||
context.set_context(mode=context.GRAPH_MODE, device_target=args.device_target, device_id=device_id)
|
||||
imagenet2012_path = args.dataset_dir
|
||||
batch_size = args.batch_size
|
||||
save_dir = os.path.join(args.save_dir, 'imagenet2012_310_infer_data')
|
||||
folder = os.path.join(save_dir, 'imagenet2012_bs_' + str(batch_size) + '_bin')
|
||||
if not os.path.exists(folder):
|
||||
os.makedirs(folder)
|
||||
ds = create_dataset(imagenet2012_path, do_train=False, repeat_num=1, batch_size=batch_size,
|
||||
target=args.device_target)
|
||||
iter_num = 0
|
||||
label_file = os.path.join(save_dir, './imagenet2012_bs_' + str(batch_size) + '_label.txt')
|
||||
with open(label_file, 'w') as f:
|
||||
for data in ds.create_dict_iterator():
|
||||
image = data['image']
|
||||
label = data['label']
|
||||
file_name = "imagenet2012_" + str(iter_num) + ".bin"
|
||||
file_path = folder + "/" + file_name
|
||||
image.asnumpy().tofile(file_path)
|
||||
f.write(file_name)
|
||||
for i in label:
|
||||
f.write(',' + str(i))
|
||||
f.write('\n')
|
||||
iter_num += 1
|
||||
print("=====iter_num:{}=====".format(iter_num))
|
||||
print("=====image_data:{}=====".format(image))
|
||||
print("=====label_data:{}=====".format(label))
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
# Copyright 2021 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.
|
||||
# ============================================================================
|
||||
"""
|
||||
post process for 310 inference.
|
||||
"""
|
||||
import os
|
||||
import argparse
|
||||
import numpy as np
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description='resnet50_quant inference')
|
||||
parser.add_argument('--result_path', type=str, default='', help='result files path')
|
||||
parser.add_argument('--label_path', type=str, default='', help='label file path')
|
||||
args_, _ = parser.parse_known_args()
|
||||
return args_
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_args()
|
||||
path = args.result_path
|
||||
label_path = args.label_path
|
||||
files = os.listdir(path)
|
||||
step = 0
|
||||
sum_right = 0
|
||||
label_dict = {}
|
||||
with open(label_path, 'r') as f:
|
||||
for line in f.readlines():
|
||||
batch_label = line.strip().split(',')
|
||||
label_dict[batch_label[0]] = batch_label[1:]
|
||||
for file in files:
|
||||
full_file_path = os.path.join(path, file)
|
||||
if os.path.isfile(full_file_path):
|
||||
label_file = file.split('_0.bin')[0] + '.bin'
|
||||
label_array = np.array(label_dict[label_file])
|
||||
line = np.fromfile(full_file_path, dtype=np.float32)
|
||||
batch_size = label_array.shape[0]
|
||||
line_comp = line.reshape(batch_size, int(line.shape[0] / batch_size))
|
||||
for i in range(0, batch_size):
|
||||
pred = np.argmax(line_comp[i], axis=0)
|
||||
step += 1
|
||||
if pred == label_array[i].astype(np.int64):
|
||||
sum_right += 1
|
||||
print("=====step:{}=====".format(step))
|
||||
print("=====sum_right:{}=====".format(sum_right))
|
||||
accuracy = sum_right * 100.0 / step
|
||||
print("=====accuracy:{}=====".format(accuracy))
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
#!/bin/bash
|
||||
# Copyright 2021 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.
|
||||
# ============================================================================
|
||||
|
||||
if [[ $# -lt 3 || $# -gt 4 ]]; then
|
||||
echo "Usage: bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [LABEL_PATH] [DEVICE_ID]
|
||||
DEVICE_ID is optional, it can be set by environment variable device_id, otherwise the value is zero"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
get_real_path(){
|
||||
if [ "${1:0:1}" == "/" ]; then
|
||||
echo "$1"
|
||||
else
|
||||
echo "$(realpath -m $PWD/$1)"
|
||||
fi
|
||||
}
|
||||
model=$(get_real_path $1)
|
||||
data_path=$(get_real_path $2)
|
||||
label_path=$(get_real_path $3)
|
||||
|
||||
device_id=0
|
||||
if [ $# == 4 ]; then
|
||||
device_id=$4
|
||||
fi
|
||||
|
||||
echo "mindir name: "$model
|
||||
echo "dataset path: "$data_path
|
||||
echo "label path: "$label_path
|
||||
echo "device id: "$device_id
|
||||
|
||||
export ASCEND_HOME=/usr/local/Ascend/
|
||||
if [ -d ${ASCEND_HOME}/ascend-toolkit ]; then
|
||||
export PATH=$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/ccec_compiler/bin:$ASCEND_HOME/ascend-toolkit/latest/atc/bin:$PATH
|
||||
export LD_LIBRARY_PATH=/usr/local/lib:$ASCEND_HOME/ascend-toolkit/latest/atc/lib64:$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/lib64:$ASCEND_HOME/driver/lib64:$ASCEND_HOME/add-ons:$LD_LIBRARY_PATH
|
||||
export TBE_IMPL_PATH=$ASCEND_HOME/ascend-toolkit/latest/opp/op_impl/built-in/ai_core/tbe
|
||||
export PYTHONPATH=${TBE_IMPL_PATH}:$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/python/site-packages:$PYTHONPATH
|
||||
export ASCEND_OPP_PATH=$ASCEND_HOME/ascend-toolkit/latest/opp
|
||||
else
|
||||
export PATH=$ASCEND_HOME/atc/ccec_compiler/bin:$ASCEND_HOME/atc/bin:$PATH
|
||||
export LD_LIBRARY_PATH=/usr/local/lib:$ASCEND_HOME/atc/lib64:$ASCEND_HOME/acllib/lib64:$ASCEND_HOME/driver/lib64:$ASCEND_HOME/add-ons:$LD_LIBRARY_PATH
|
||||
export PYTHONPATH=$ASCEND_HOME/atc/python/site-packages:$PYTHONPATH
|
||||
export ASCEND_OPP_PATH=$ASCEND_HOME/opp
|
||||
fi
|
||||
|
||||
function air_to_om()
|
||||
{
|
||||
atc --input_format=NCHW --framework=1 --model=$model --output=resnet50_quant --soc_version=Ascend310 &> atc.log
|
||||
}
|
||||
|
||||
function compile_app()
|
||||
{
|
||||
cd ../ascend310_infer/src || exit
|
||||
bash build.sh &> build.log
|
||||
}
|
||||
|
||||
function infer()
|
||||
{
|
||||
cd - || exit
|
||||
if [ -d result_Files ]; then
|
||||
rm -rf ./result_Files
|
||||
fi
|
||||
if [ -d time_Result ]; then
|
||||
rm -rf ./time_Result
|
||||
fi
|
||||
mkdir result_Files
|
||||
mkdir time_Result
|
||||
../ascend310_infer/src/out/main --om_path=./resnet50_quant.om --dataset_path=$data_path --acljson_path=../ascend310_infer/src/acl.json --device_id=$device_id &> infer.log
|
||||
}
|
||||
|
||||
function cal_acc()
|
||||
{
|
||||
python3.7 ../postprocess.py --result_path=./result_Files --label_path=$label_path &> acc.log
|
||||
}
|
||||
|
||||
air_to_om
|
||||
if [ $? -ne 0 ]; then
|
||||
echo " air to om failed"
|
||||
exit 1
|
||||
fi
|
||||
compile_app
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "compile app code failed"
|
||||
exit 1
|
||||
fi
|
||||
infer
|
||||
if [ $? -ne 0 ]; then
|
||||
echo " execute inference failed"
|
||||
exit 1
|
||||
fi
|
||||
cal_acc
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "calculate accuracy failed"
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -106,11 +106,13 @@ sh run_eval.sh dataset/coco2014/ checkpoint/yolov3_quant.ckpt 0
|
|||
.
|
||||
└─yolov3_darknet53_quant
|
||||
├─README.md
|
||||
├─ascend310_infer # application for 310 inference
|
||||
├─mindspore_hub_conf.md # config for mindspore hub
|
||||
├─scripts
|
||||
├─run_standalone_train.sh # launch standalone training(1p) in ascend
|
||||
├─run_distribute_train.sh # launch distributed training(8p) in ascend
|
||||
└─run_eval.sh # launch evaluating in ascend
|
||||
└─run_infer_310.sh # shell script for 310 inference
|
||||
├─src
|
||||
├─__init__.py # python init file
|
||||
├─config.py # parameter configuration
|
||||
|
|
@ -126,6 +128,8 @@ sh run_eval.sh dataset/coco2014/ checkpoint/yolov3_quant.ckpt 0
|
|||
├─yolo_dataset.py # create dataset for YOLOV3
|
||||
├─eval.py # eval net
|
||||
└─train.py # train net
|
||||
└─export_bin_file.py # export bin file of coco2014 for 310 inference
|
||||
└─postprocess.py # post process for 310 inference
|
||||
```
|
||||
|
||||
### [Script Parameters](#contents)
|
||||
|
|
@ -257,6 +261,48 @@ Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.450
|
|||
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.558
|
||||
```
|
||||
|
||||
## [Model Export](#contents)
|
||||
|
||||
```shell
|
||||
python export.py --ckpt_file [CKPT_PATH] --file_format [EXPORT_FORMAT]
|
||||
```
|
||||
|
||||
`EXPORT_FORMAT` should be in ["AIR", "MINDIR"].
|
||||
|
||||
## [Ascend 310 inference](#contents)
|
||||
|
||||
You should export AIR model at Ascend 910 before running the command below.
|
||||
You can use export_bin_file.py to export coco2014 bin, image_shape.npy and image_id.npy for 310 inference.
|
||||
|
||||
```shell
|
||||
python export_bin_file.py --data_dir [DATASET_PATH] --save_path [SAVE_PATH]
|
||||
```
|
||||
|
||||
Run run_infer_310.sh and get the accuracy:
|
||||
|
||||
```shell
|
||||
# Ascend310 inference
|
||||
bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [ANNO_PATH] [IMAGESHAPE_PATH] [IMAGEID_PATH] [DEVICE_ID]
|
||||
```
|
||||
|
||||
You can view the results through the file "acc.log". The accuracy of the test dataset will be as follows:
|
||||
|
||||
```bash
|
||||
=============coco eval reulst=========
|
||||
Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.306
|
||||
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.528
|
||||
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.315
|
||||
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.122
|
||||
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.322
|
||||
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.426
|
||||
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.259
|
||||
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.398
|
||||
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.423
|
||||
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.226
|
||||
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.442
|
||||
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.555
|
||||
```
|
||||
|
||||
## [Model Description](#contents)
|
||||
|
||||
### [Performance](#contents)
|
||||
|
|
|
|||
|
|
@ -116,11 +116,13 @@ sh run_eval.sh dataset/coco2014/ checkpoint/yolov3_quant.ckpt 0
|
|||
.
|
||||
└─yolov3_darknet53_quant
|
||||
├─README.md
|
||||
├─ascend310_infer # 实现310推理源代码
|
||||
├─mindspore_hub_conf.md # Mindspore Hub配置
|
||||
├─scripts
|
||||
├─run_standalone_train.sh # 在Ascend中启动单机训练(1卡)
|
||||
├─run_distribute_train.sh # 在Ascend中启动分布式训练(8卡)
|
||||
└─run_eval.sh # 在Ascend中启动评估
|
||||
├─run_eval.sh # 在Ascend中启动评估
|
||||
├─run_infer_310.sh # Ascend 310 推理shell脚本
|
||||
├─src
|
||||
├─__init__.py # python初始化文件
|
||||
├─config.py # 参数配置
|
||||
|
|
@ -136,6 +138,8 @@ sh run_eval.sh dataset/coco2014/ checkpoint/yolov3_quant.ckpt 0
|
|||
├─yolo_dataset.py # 为YOLOV3创建数据集
|
||||
├─eval.py # 评估网络
|
||||
└─train.py # 训练网络
|
||||
├─export_bin_file.py # 导出coco2014数据集的bin文件用于310推理
|
||||
├─postprocess.py # 310推理后处理脚本
|
||||
```
|
||||
|
||||
### 脚本参数
|
||||
|
|
@ -266,6 +270,48 @@ Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.450
|
|||
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.558
|
||||
```
|
||||
|
||||
## 模型导出
|
||||
|
||||
```shell
|
||||
python export.py --ckpt_file [CKPT_PATH] --file_format [EXPORT_FORMAT]
|
||||
```
|
||||
|
||||
`EXPORT_FORMAT` 可选 ["AIR", "MINDIR"].
|
||||
|
||||
## Ascend 310 推理
|
||||
|
||||
在推理之前需要在昇腾910环境上完成AIR模型的导出。
|
||||
并使用export_bin_file.py导出coco2014数据集的bin文件和对应的image_shape, image_id文件:
|
||||
|
||||
```shell
|
||||
python export_bin_file.py --data_dir [DATASET_PATH] --save_path [SAVE_PATH]
|
||||
```
|
||||
|
||||
执行推理并得到推理精度:
|
||||
|
||||
```shell
|
||||
# Ascend310 inference
|
||||
bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [ANNO_PATH] [IMAGESHAPE_PATH] [IMAGEID_PATH] [DEVICE_ID]
|
||||
```
|
||||
|
||||
您可以通过acc.log文件查看结果。推理准确性如下:
|
||||
|
||||
```bash
|
||||
=============coco eval reulst=========
|
||||
Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.306
|
||||
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.528
|
||||
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.315
|
||||
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.122
|
||||
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.322
|
||||
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.426
|
||||
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.259
|
||||
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.398
|
||||
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.423
|
||||
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.226
|
||||
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.442
|
||||
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.555
|
||||
```
|
||||
|
||||
## 模型描述
|
||||
|
||||
### 性能
|
||||
|
|
|
|||
|
|
@ -0,0 +1,114 @@
|
|||
/**
|
||||
* Copyright 2021 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 MODELPROCESS_H
|
||||
#define MODELPROCESS_H
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "acl/acl.h"
|
||||
#include "../inc/utils.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(const std::vector<void *> &inputDataBuffer, const std::vector<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(char *output_name);
|
||||
|
||||
/**
|
||||
* @brief get model output result
|
||||
*/
|
||||
void OutputModelResult();
|
||||
|
||||
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_;
|
||||
};
|
||||
#endif
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* Copyright 2021 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 SAMPLEPROCESS_H
|
||||
#define SAMPLEPROCESS_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "acl/acl.h"
|
||||
#include "../inc/utils.h"
|
||||
|
||||
/**
|
||||
* SampleProcess
|
||||
*/
|
||||
class SampleProcess {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
explicit SampleProcess(int32_t deviceId);
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~SampleProcess();
|
||||
|
||||
/**
|
||||
* @brief init reousce
|
||||
* @return result
|
||||
*/
|
||||
Result InitResource(const char *acl_config_path);
|
||||
|
||||
/**
|
||||
* @brief sample process
|
||||
* @return result
|
||||
*/
|
||||
Result Process(const char *om_path, const char *input_folder);
|
||||
|
||||
void GetAllFiles(std::string path, std::vector<std::string> *files);
|
||||
|
||||
private:
|
||||
void DestroyResource();
|
||||
|
||||
int32_t deviceId_;
|
||||
aclrtContext context_;
|
||||
aclrtStream stream_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* Copyright 2021 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 MINDSPORE_INFERENCE_UTILS_H_
|
||||
#define MINDSPORE_INFERENCE_UTILS_H_
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#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 Read bin 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);
|
||||
};
|
||||
#endif
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
# Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
|
||||
|
||||
# CMake lowest version requirement
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
# project information
|
||||
project(InferClassification)
|
||||
# Check environment variable
|
||||
if(NOT DEFINED ENV{ASCEND_HOME})
|
||||
message(FATAL_ERROR "please define environment variable:ASCEND_HOME")
|
||||
endif()
|
||||
|
||||
# Compile options
|
||||
add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -std=c++17 -Werror -Wall -fPIE -Wl,--allow-shlib-undefined")
|
||||
|
||||
# Skip build rpath
|
||||
set(CMAKE_SKIP_BUILD_RPATH True)
|
||||
|
||||
# Set output directory
|
||||
set(PROJECT_SRC_ROOT ${CMAKE_CURRENT_LIST_DIR}/)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SRC_ROOT}/out)
|
||||
|
||||
# Set include directory and library directory
|
||||
set(ACL_LIB_DIR $ENV{ASCEND_HOME}/acllib)
|
||||
set(ATLAS_ACL_LIB_DIR $ENV{ASCEND_HOME}/ascend-toolkit/latest/acllib)
|
||||
|
||||
# Header path
|
||||
include_directories(${ACL_LIB_DIR}/include/)
|
||||
include_directories(${ATLAS_ACL_LIB_DIR}/include/)
|
||||
include_directories(${PROJECT_SRC_ROOT}/../inc)
|
||||
|
||||
# add host lib path
|
||||
link_directories(${ACL_LIB_DIR})
|
||||
find_library(acl libascendcl.so ${ACL_LIB_DIR}/lib64 ${ATLAS_ACL_LIB_DIR}/lib64)
|
||||
|
||||
add_executable(main utils.cpp
|
||||
SampleProcess.cpp
|
||||
ModelProcess.cpp
|
||||
main.cpp)
|
||||
|
||||
target_link_libraries(main ${acl} gflags pthread)
|
||||
|
||||
|
|
@ -0,0 +1,337 @@
|
|||
/**
|
||||
* Copyright 2021 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 "../inc/ModelProcess.h"
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include "../inc/utils.h"
|
||||
|
||||
extern bool g_isDevice;
|
||||
|
||||
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_HUGE_FIRST);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("malloc buffer for mem failed, require size is %zu", modelMemSize_);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = aclrtMalloc(&modelWeightPtr_, modelWeightSize_, ACL_MEM_MALLOC_HUGE_FIRST);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("malloc buffer for weight failed, require size is %zu", modelWeightSize_);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = aclmdlLoadFromFileWithMem(modelPath, &modelId_, modelMemPtr_,
|
||||
modelMemSize_, modelWeightPtr_, modelWeightSize_);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("load model from file failed, model file is %s", modelPath);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
loadFlag_ = true;
|
||||
INFO_LOG("load model %s success", modelPath);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
Result ModelProcess::CreateDesc() {
|
||||
modelDesc_ = aclmdlCreateDesc();
|
||||
if (modelDesc_ == nullptr) {
|
||||
ERROR_LOG("create model description failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
aclError ret = aclmdlGetDesc(modelDesc_, modelId_);
|
||||
if (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("get model description failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
INFO_LOG("create model description success");
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void ModelProcess::DestroyDesc() {
|
||||
if (modelDesc_ != nullptr) {
|
||||
(void)aclmdlDestroyDesc(modelDesc_);
|
||||
modelDesc_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Result ModelProcess::CreateInput(const std::vector<void *> &inputDataBuffer, const std::vector<size_t> &bufferSize) {
|
||||
input_ = aclmdlCreateDataset();
|
||||
if (input_ == nullptr) {
|
||||
ERROR_LOG("can't create dataset, create input failed");
|
||||
return FAILED;
|
||||
}
|
||||
for (size_t i = 0; i < inputDataBuffer.size(); ++i) {
|
||||
aclDataBuffer* inputData = aclCreateDataBuffer(inputDataBuffer[i], bufferSize[i]);
|
||||
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 output 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(char *output_name) {
|
||||
size_t outputNum = aclmdlGetDatasetNumBuffers(output_);
|
||||
std::string homePath = "./result_Files";
|
||||
for (size_t i = 0; i < outputNum; ++i) {
|
||||
std::string fileName = std::string(output_name) + '_' + std::to_string(i) + ".bin";
|
||||
std::string outputFileName = homePath + "/" + fileName;
|
||||
FILE *outputFile = fopen(outputFileName.c_str(), "wb");
|
||||
if (outputFile) {
|
||||
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i);
|
||||
void* data = aclGetDataBufferAddr(dataBuffer);
|
||||
uint32_t len = aclGetDataBufferSizeV2(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() {
|
||||
for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) {
|
||||
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i);
|
||||
void* data = aclGetDataBufferAddr(dataBuffer);
|
||||
uint32_t len = aclGetDataBufferSizeV2(dataBuffer);
|
||||
|
||||
void *outHostData = NULL;
|
||||
aclError ret = ACL_ERROR_NONE;
|
||||
float *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;
|
||||
}
|
||||
|
||||
outData = reinterpret_cast<float*>(outHostData);
|
||||
} else {
|
||||
outData = reinterpret_cast<float*>(data);
|
||||
}
|
||||
std::map<float, unsigned int, std::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::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 success, modelId is %u", modelId_);
|
||||
}
|
||||
|
|
@ -0,0 +1,214 @@
|
|||
/**
|
||||
* Copyright 2021 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 "../inc/SampleProcess.h"
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include "../inc/utils.h"
|
||||
#include "../inc/ModelProcess.h"
|
||||
#include "acl/acl.h"
|
||||
|
||||
extern bool g_isDevice;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
SampleProcess::SampleProcess(int32_t deviceId) : context_(nullptr), stream_(nullptr) {
|
||||
deviceId_ = deviceId;
|
||||
}
|
||||
|
||||
SampleProcess::~SampleProcess() {
|
||||
DestroyResource();
|
||||
}
|
||||
|
||||
Result SampleProcess::InitResource(const char *aclConfigPath) {
|
||||
// ACL init
|
||||
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;
|
||||
}
|
||||
|
||||
void SampleProcess::GetAllFiles(std::string path, std::vector<string> *files) {
|
||||
DIR *pDir;
|
||||
struct dirent* ptr;
|
||||
if (!(pDir = opendir(path.c_str())))
|
||||
return;
|
||||
while ((ptr = readdir(pDir)) != 0) {
|
||||
if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0)
|
||||
files->push_back(path + "/" + ptr->d_name);
|
||||
}
|
||||
closedir(pDir);
|
||||
}
|
||||
|
||||
Result SampleProcess::Process(const char *om_path, const char *input_folder) {
|
||||
// model init
|
||||
ModelProcess processModel;
|
||||
|
||||
Result ret = processModel.LoadModelFromFileWithMem(om_path);
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute LoadModelFromFileWithMem failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = processModel.CreateDesc();
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute CreateDesc failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = processModel.CreateOutput();
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute CreateOutput failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
std::vector<string> testFile;
|
||||
GetAllFiles(input_folder, &testFile);
|
||||
|
||||
if (testFile.size() == 0) {
|
||||
WARN_LOG("no input data under folder");
|
||||
}
|
||||
float *inputShape = reinterpret_cast<float *>(malloc(sizeof(float) * 2));
|
||||
inputShape[0] = 416;
|
||||
inputShape[1] = 416;
|
||||
void *inputShapeBuffer = nullptr;
|
||||
int mret = aclrtMalloc(&inputShapeBuffer, 8, ACL_MEM_MALLOC_NORMAL_ONLY);
|
||||
if (mret != ACL_ERROR_NONE) {
|
||||
aclrtFree(inputShapeBuffer);
|
||||
return FAILED;
|
||||
}
|
||||
mret = aclrtMemcpy(reinterpret_cast<uint8_t *>(inputShapeBuffer), 8, inputShape, 8, ACL_MEMCPY_HOST_TO_DEVICE);
|
||||
if (mret != ACL_ERROR_NONE) {
|
||||
aclrtFree(inputShapeBuffer);
|
||||
return FAILED;
|
||||
}
|
||||
// loop begin
|
||||
for (size_t index = 0; index < testFile.size(); ++index) {
|
||||
INFO_LOG("start to process file:%s", testFile[index].c_str());
|
||||
// model process
|
||||
uint32_t devBufferSize;
|
||||
void *picDevBuffer = Utils::GetDeviceBufferOfFile(testFile[index], &devBufferSize);
|
||||
if (picDevBuffer == nullptr) {
|
||||
ERROR_LOG("get pic device buffer failed,index is %zu", index);
|
||||
return FAILED;
|
||||
}
|
||||
std::vector<void *> inputBuffers({picDevBuffer, inputShapeBuffer});
|
||||
std::vector<size_t> inputSizes({devBufferSize, 8});
|
||||
ret = processModel.CreateInput(inputBuffers, inputSizes);
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute CreateInput failed");
|
||||
aclrtFree(picDevBuffer);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = processModel.Execute();
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("execute inference failed");
|
||||
aclrtFree(picDevBuffer);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
int pos = testFile[index].find_last_of('/');
|
||||
std::string name = testFile[index].substr(pos+1);
|
||||
std::string outputname = name.substr(0, name.rfind("."));
|
||||
|
||||
// print the top 5 confidence values
|
||||
processModel.OutputModelResult();
|
||||
// dump output result to file in the current directory
|
||||
processModel.DumpModelOutputResult(const_cast<char *>(outputname.c_str()));
|
||||
|
||||
// release model input buffer
|
||||
aclrtFree(picDevBuffer);
|
||||
processModel.DestroyInput();
|
||||
}
|
||||
// loop end
|
||||
|
||||
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 @@
|
|||
{}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
#!/bin/bash
|
||||
# Copyright 2021 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.
|
||||
# ============================================================================
|
||||
path_cur=$(cd "`dirname $0`" || exit; pwd)
|
||||
|
||||
function preparePath() {
|
||||
rm -rf $1
|
||||
mkdir -p $1
|
||||
cd $1 || exit
|
||||
}
|
||||
|
||||
function buildA300() {
|
||||
if [ ! "${ARCH_PATTERN}" ]; then
|
||||
# set ARCH_PATTERN to acllib when it was not specified by user
|
||||
export ARCH_PATTERN=acllib
|
||||
echo "ARCH_PATTERN is set to the default value: ${ARCH_PATTERN}"
|
||||
else
|
||||
echo "ARCH_PATTERN is set to ${ARCH_PATTERN} by user, reset it to ${ARCH_PATTERN}/acllib"
|
||||
export ARCH_PATTERN=${ARCH_PATTERN}/acllib
|
||||
fi
|
||||
|
||||
path_build=$path_cur/build
|
||||
preparePath $path_build
|
||||
cmake ..
|
||||
make -j
|
||||
ret=$?
|
||||
cd ..
|
||||
return ${ret}
|
||||
}
|
||||
|
||||
# set ASCEND_VERSION to ascend-toolkit/latest when it was not specified by user
|
||||
if [ ! "${ASCEND_VERSION}" ]; then
|
||||
export ASCEND_VERSION=ascend-toolkit/latest
|
||||
echo "Set ASCEND_VERSION to the default value: ${ASCEND_VERSION}"
|
||||
else
|
||||
echo "ASCEND_VERSION is set to ${ASCEND_VERSION} by user"
|
||||
fi
|
||||
|
||||
buildA300
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* Copyright 2021 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 <gflags/gflags.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include "../inc/SampleProcess.h"
|
||||
#include "../inc/utils.h"
|
||||
|
||||
bool g_isDevice = false;
|
||||
|
||||
DEFINE_string(om_path, "", "om path");
|
||||
DEFINE_string(dataset_path, "", "dataset path");
|
||||
DEFINE_string(acljson_path, "", "acl json path");
|
||||
DEFINE_int32(device_id, 0, "device id");
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
std::string om_path = FLAGS_om_path;
|
||||
std::string dataset_path = FLAGS_dataset_path;
|
||||
std::string acljson_path = FLAGS_acljson_path;
|
||||
int32_t device_id = FLAGS_device_id;
|
||||
std::ifstream fin(om_path);
|
||||
if (!fin) {
|
||||
std::cout << "Invalid om path." << std::endl;
|
||||
return FAILED;
|
||||
}
|
||||
SampleProcess processSample(device_id);
|
||||
// acl.json is deployed for dump data.
|
||||
Result ret = processSample.InitResource(acljson_path.c_str());
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("sample init resource failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
ret = processSample.Process(om_path.c_str(), dataset_path.c_str());
|
||||
if (ret != SUCCESS) {
|
||||
ERROR_LOG("sample process failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
INFO_LOG("execute sample success");
|
||||
return SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
/**
|
||||
* Copyright 2021 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 "../inc/utils.h"
|
||||
#include <sys/stat.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
#include "acl/acl.h"
|
||||
|
||||
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 (ret != ACL_ERROR_NONE) {
|
||||
ERROR_LOG("malloc for binFileBufferData failed");
|
||||
binFile.close();
|
||||
return nullptr;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
# Copyright 2021 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.
|
||||
# ============================================================================
|
||||
"""YoloV3_quant export coco bin."""
|
||||
import os
|
||||
import argparse
|
||||
import datetime
|
||||
import numpy as np
|
||||
import mindspore as ms
|
||||
from mindspore import Tensor
|
||||
from mindspore.context import ParallelMode
|
||||
from mindspore import context
|
||||
|
||||
from src.logger import get_logger
|
||||
from src.yolo_dataset import create_yolo_dataset
|
||||
from src.config import ConfigYOLOV3DarkNet53
|
||||
|
||||
def parse_args():
|
||||
"""Parse arguments."""
|
||||
parser = argparse.ArgumentParser('mindspore coco export bin')
|
||||
parser.add_argument('--device_target', type=str, default="Ascend",
|
||||
choices=['Ascend', 'GPU'],
|
||||
help='device where the code will be implemented (default: Ascend)')
|
||||
# dataset related
|
||||
parser.add_argument('--data_dir', type=str, default="", help='Eval data dir. Default: ""')
|
||||
parser.add_argument('--per_batch_size', default=1, type=int, help='Batch size for per device, Default: 1')
|
||||
|
||||
# logging related
|
||||
parser.add_argument('--log_path', type=str, default="outputs/", help='Log save location, Default: "outputs/"')
|
||||
parser.add_argument('--save_path', type=str, default="", help='Bin file save location')
|
||||
|
||||
# detect_related
|
||||
parser.add_argument('--nms_thresh', type=float, default=0.5, help='Threshold for NMS. Default: 0.5')
|
||||
parser.add_argument('--annFile', type=str, default="", help='The path to annotation. Default: ""')
|
||||
parser.add_argument('--testing_shape', type=str, default="", help='Shape for test. Default: ""')
|
||||
|
||||
args_, _ = parser.parse_known_args()
|
||||
|
||||
args_.data_root = os.path.join(args_.data_dir, 'val2014')
|
||||
args_.annFile = os.path.join(args_.data_dir, 'annotations/instances_val2014.json')
|
||||
|
||||
return args_
|
||||
|
||||
def conver_testing_shape(args_org):
|
||||
"""Convert testing shape to list."""
|
||||
testing_shape = [int(args_org.testing_shape), int(args_org.testing_shape)]
|
||||
return testing_shape
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_args()
|
||||
devid = int(os.getenv('DEVICE_ID')) if os.getenv('DEVICE_ID') else 0
|
||||
context.set_context(mode=context.GRAPH_MODE, device_target=args.device_target, device_id=devid)
|
||||
|
||||
# logger
|
||||
args.outputs_dir = os.path.join(args.log_path,
|
||||
datetime.datetime.now().strftime('%Y-%m-%d_time_%H_%M_%S'))
|
||||
rank_id = int(os.environ.get('RANK_ID')) if os.environ.get('RANK_ID') else 0
|
||||
args.logger = get_logger(args.outputs_dir, rank_id)
|
||||
|
||||
context.reset_auto_parallel_context()
|
||||
parallel_mode = ParallelMode.STAND_ALONE
|
||||
context.set_auto_parallel_context(parallel_mode=parallel_mode, gradients_mean=True, device_num=1)
|
||||
|
||||
config = ConfigYOLOV3DarkNet53()
|
||||
if args.testing_shape:
|
||||
config.test_img_shape = conver_testing_shape(args)
|
||||
data_root = args.data_root
|
||||
ann_file = args.annFile
|
||||
|
||||
ds, data_size = create_yolo_dataset(data_root, ann_file, is_training=False, batch_size=args.per_batch_size,
|
||||
max_epoch=1, device_num=1, rank=rank_id, shuffle=False,
|
||||
config=config)
|
||||
|
||||
args.logger.info('testing shape : {}'.format(config.test_img_shape))
|
||||
args.logger.info('totol {} images to eval'.format(data_size))
|
||||
|
||||
cur_dir = args.save_path
|
||||
save_folder = os.path.join(cur_dir, "yolov3_quant_coco_310_infer_data")
|
||||
image_folder = os.path.join(save_folder, "image_bin")
|
||||
if not os.path.exists(image_folder):
|
||||
os.makedirs(image_folder)
|
||||
|
||||
list_image_shape = []
|
||||
list_image_id = []
|
||||
|
||||
input_shape = Tensor(tuple(config.test_img_shape), ms.float32)
|
||||
args.logger.info('Start inference....')
|
||||
for i, data in enumerate(ds.create_dict_iterator()):
|
||||
image = data["image"].asnumpy()
|
||||
image_shape = data["image_shape"]
|
||||
image_id = data["img_id"]
|
||||
file_name = "YoloV3-DarkNet_coco_bs_" + str(args.per_batch_size) + "_" + str(i) + ".bin"
|
||||
file_path = image_folder + "/" + file_name
|
||||
image.tofile(file_path)
|
||||
list_image_shape.append(image_shape.asnumpy())
|
||||
list_image_id.append(image_id.asnumpy())
|
||||
shapes = np.array(list_image_shape)
|
||||
ids = np.array(list_image_id)
|
||||
np.save(save_folder + "/image_shape.npy", shapes)
|
||||
np.save(save_folder + "/image_id.npy", ids)
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
# Copyright 2021 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.
|
||||
# ============================================================================
|
||||
"""YoloV3 postprocess."""
|
||||
import os
|
||||
import argparse
|
||||
import datetime
|
||||
import numpy as np
|
||||
from eval import DetectionEngine
|
||||
|
||||
parser = argparse.ArgumentParser('YoloV3_quant postprocess')
|
||||
parser.add_argument('--result_path', type=str, required=True, help='result files path.')
|
||||
parser.add_argument('--per_batch_size', default=1, type=int, help='batch size for per gpu')
|
||||
parser.add_argument('--nms_thresh', type=float, default=0.5, help='threshold for NMS')
|
||||
parser.add_argument('--annFile', type=str, default='', help='path to annotation')
|
||||
parser.add_argument('--image_shape', type=str, default='./image_shape.npy', help='path to image_shape.npy')
|
||||
parser.add_argument('--image_id', type=str, default='./image_id.npy', help='path to image_id.npy')
|
||||
parser.add_argument('--ignore_threshold', type=float, default=0.001, help='threshold to throw low quality boxes')
|
||||
parser.add_argument('--log_path', type=str, default='outputs/', help='inference result save location')
|
||||
|
||||
args, _ = parser.parse_known_args()
|
||||
|
||||
if __name__ == "__main__":
|
||||
args.outputs_dir = os.path.join(args.log_path,
|
||||
datetime.datetime.now().strftime('%Y-%m-%d_time_%H_%M_%S'))
|
||||
if not os.path.exists(args.outputs_dir):
|
||||
os.makedirs(args.outputs_dir)
|
||||
|
||||
detection = DetectionEngine(args)
|
||||
bs = args.per_batch_size
|
||||
|
||||
f_list = os.listdir(args.result_path)
|
||||
shape_list = np.load(args.image_shape)
|
||||
id_list = np.load(args.image_id)
|
||||
prefix = "YoloV3-DarkNet_coco_bs_" + str(bs) + "_"
|
||||
iter_num = 0
|
||||
for image_id in id_list:
|
||||
image_shape = shape_list[iter_num]
|
||||
path_small = os.path.join(args.result_path, prefix + str(iter_num) + '_0.bin')
|
||||
path_medium = os.path.join(args.result_path, prefix + str(iter_num) + '_1.bin')
|
||||
path_big = os.path.join(args.result_path, prefix + str(iter_num) + '_2.bin')
|
||||
if os.path.exists(path_small) and os.path.exists(path_medium) and os.path.exists(path_big):
|
||||
output_small = np.fromfile(path_small, np.float32).reshape(bs, 13, 13, 3, 85)
|
||||
output_medium = np.fromfile(path_medium, np.float32).reshape(bs, 26, 26, 3, 85)
|
||||
output_big = np.fromfile(path_big, np.float32).reshape(bs, 52, 52, 3, 85)
|
||||
detection.detect([output_small, output_medium, output_big], bs, image_shape, image_id)
|
||||
else:
|
||||
print("Error: Image ", iter_num, " is not exist.")
|
||||
iter_num += 1
|
||||
|
||||
detection.do_nms_for_results()
|
||||
result_file_path = detection.write_result()
|
||||
eval_result = detection.get_eval_result()
|
||||
|
||||
print('\n=============coco eval result=========\n' + eval_result)
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
#!/bin/bash
|
||||
# Copyright 2021 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.
|
||||
# ============================================================================
|
||||
|
||||
if [[ $# -lt 5 || $# -gt 6 ]]; then
|
||||
echo "Usage: bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [ANNO_PATH] [IMAGESHAPE_PATH] [IMAGEID_PATH] [DEVICE_ID]
|
||||
DEVICE_ID is optional, it can be set by environment variable device_id, otherwise the value is zero"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
get_real_path(){
|
||||
if [ "${1:0:1}" == "/" ]; then
|
||||
echo "$1"
|
||||
else
|
||||
echo "$(realpath -m $PWD/$1)"
|
||||
fi
|
||||
}
|
||||
model=$(get_real_path $1)
|
||||
data_path=$(get_real_path $2)
|
||||
anno_path=$(get_real_path $3)
|
||||
image_shape_path=$(get_real_path $4)
|
||||
image_id_path=$(get_real_path $5)
|
||||
|
||||
device_id=0
|
||||
if [ $# == 6 ]; then
|
||||
device_id=$6
|
||||
fi
|
||||
|
||||
echo "mindir name: "$model
|
||||
echo "dataset path: "$data_path
|
||||
echo "annotation path: "$anno_path
|
||||
echo "image shape path: "$image_shape_path
|
||||
echo "image id path: "$image_id_path
|
||||
echo "device id: "$device_id
|
||||
|
||||
export ASCEND_HOME=/usr/local/Ascend/
|
||||
if [ -d ${ASCEND_HOME}/ascend-toolkit ]; then
|
||||
export PATH=$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/ccec_compiler/bin:$ASCEND_HOME/ascend-toolkit/latest/atc/bin:$PATH
|
||||
export LD_LIBRARY_PATH=/usr/local/lib:$ASCEND_HOME/ascend-toolkit/latest/atc/lib64:$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/lib64:$ASCEND_HOME/driver/lib64:$ASCEND_HOME/add-ons:$LD_LIBRARY_PATH
|
||||
export TBE_IMPL_PATH=$ASCEND_HOME/ascend-toolkit/latest/opp/op_impl/built-in/ai_core/tbe
|
||||
export PYTHONPATH=${TBE_IMPL_PATH}:$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/python/site-packages:$PYTHONPATH
|
||||
export ASCEND_OPP_PATH=$ASCEND_HOME/ascend-toolkit/latest/opp
|
||||
else
|
||||
export PATH=$ASCEND_HOME/atc/ccec_compiler/bin:$ASCEND_HOME/atc/bin:$PATH
|
||||
export LD_LIBRARY_PATH=/usr/local/lib:$ASCEND_HOME/atc/lib64:$ASCEND_HOME/acllib/lib64:$ASCEND_HOME/driver/lib64:$ASCEND_HOME/add-ons:$LD_LIBRARY_PATH
|
||||
export PYTHONPATH=$ASCEND_HOME/atc/python/site-packages:$PYTHONPATH
|
||||
export ASCEND_OPP_PATH=$ASCEND_HOME/opp
|
||||
fi
|
||||
|
||||
function air_to_om()
|
||||
{
|
||||
atc --input_format=NCHW --framework=1 --model=$model --output=yolov3_darknet53_quant --soc_version=Ascend310 &> atc.log
|
||||
}
|
||||
|
||||
function compile_app()
|
||||
{
|
||||
cd ../ascend310_infer/src || exit
|
||||
bash build.sh &> build.log
|
||||
}
|
||||
|
||||
function infer()
|
||||
{
|
||||
cd - || exit
|
||||
if [ -d result_Files ]; then
|
||||
rm -rf ./result_Files
|
||||
fi
|
||||
if [ -d time_Result ]; then
|
||||
rm -rf ./time_Result
|
||||
fi
|
||||
mkdir result_Files
|
||||
mkdir time_Result
|
||||
|
||||
../ascend310_infer/src/out/main --om_path=./yolov3_darknet53_quant.om --dataset_path=$data_path --acljson_path=../ascend310_infer/src/acl.json --device_id=$device_id &> infer.log
|
||||
|
||||
}
|
||||
|
||||
function cal_acc()
|
||||
{
|
||||
python3.7 ../postprocess.py --result_path=./result_Files --img_path=$data_path --annFile=$anno_path --image_shape=$image_shape_path --image_id=$image_id_path &> acc.log
|
||||
}
|
||||
|
||||
air_to_om
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "air to om code failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
compile_app
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "compile app code failed"
|
||||
exit 1
|
||||
fi
|
||||
infer
|
||||
if [ $? -ne 0 ]; then
|
||||
echo " execute inference failed"
|
||||
exit 1
|
||||
fi
|
||||
cal_acc
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "calculate accuracy failed"
|
||||
exit 1
|
||||
fi
|
||||
Loading…
Reference in New Issue