Browse Source

mindir inferenct for fasterrcnn and maskrcnn

pull/15584/head
yuzhenhua 4 years ago
parent
commit
1b2e2d005a
41 changed files with 951 additions and 3995 deletions
  1. +3
    -4
      model_zoo/official/cv/faster_rcnn/README.md
  2. +3
    -4
      model_zoo/official/cv/faster_rcnn/README_CN.md
  3. +14
    -0
      model_zoo/official/cv/faster_rcnn/ascend310_infer/CMakeLists.txt
  4. +29
    -0
      model_zoo/official/cv/faster_rcnn/ascend310_infer/build.sh
  5. +0
    -62
      model_zoo/official/cv/faster_rcnn/ascend310_infer/inc/AclProcess.h
  6. +0
    -95
      model_zoo/official/cv/faster_rcnn/ascend310_infer/inc/CommonDataType.h
  7. +0
    -139
      model_zoo/official/cv/faster_rcnn/ascend310_infer/inc/DvppCommon.h
  8. +0
    -63
      model_zoo/official/cv/faster_rcnn/ascend310_infer/inc/ModelProcess.h
  9. +32
    -0
      model_zoo/official/cv/faster_rcnn/ascend310_infer/inc/utils.h
  10. +0
    -367
      model_zoo/official/cv/faster_rcnn/ascend310_infer/src/AclProcess.cpp
  11. +0
    -42
      model_zoo/official/cv/faster_rcnn/ascend310_infer/src/CMakeLists.txt
  12. +0
    -735
      model_zoo/official/cv/faster_rcnn/ascend310_infer/src/DvppCommon.cpp
  13. +0
    -226
      model_zoo/official/cv/faster_rcnn/ascend310_infer/src/ModelProcess.cpp
  14. +0
    -56
      model_zoo/official/cv/faster_rcnn/ascend310_infer/src/build.sh
  15. +236
    -0
      model_zoo/official/cv/faster_rcnn/ascend310_infer/src/main.cc
  16. +0
    -136
      model_zoo/official/cv/faster_rcnn/ascend310_infer/src/main.cpp
  17. +129
    -0
      model_zoo/official/cv/faster_rcnn/ascend310_infer/src/utils.cc
  18. +8
    -7
      model_zoo/official/cv/faster_rcnn/postprocess.py
  19. +20
    -35
      model_zoo/official/cv/faster_rcnn/scripts/run_infer_310.sh
  20. +0
    -26
      model_zoo/official/cv/faster_rcnn/src/aipp.cfg
  21. +3
    -4
      model_zoo/official/cv/maskrcnn/README.md
  22. +3
    -4
      model_zoo/official/cv/maskrcnn/README_CN.md
  23. +14
    -0
      model_zoo/official/cv/maskrcnn/ascend310_infer/CMakeLists.txt
  24. +29
    -0
      model_zoo/official/cv/maskrcnn/ascend310_infer/build.sh
  25. +1
    -0
      model_zoo/official/cv/maskrcnn/ascend310_infer/fusion_switch.cfg
  26. +0
    -62
      model_zoo/official/cv/maskrcnn/ascend310_infer/inc/AclProcess.h
  27. +0
    -95
      model_zoo/official/cv/maskrcnn/ascend310_infer/inc/CommonDataType.h
  28. +0
    -139
      model_zoo/official/cv/maskrcnn/ascend310_infer/inc/DvppCommon.h
  29. +0
    -63
      model_zoo/official/cv/maskrcnn/ascend310_infer/inc/ModelProcess.h
  30. +32
    -0
      model_zoo/official/cv/maskrcnn/ascend310_infer/inc/utils.h
  31. +0
    -371
      model_zoo/official/cv/maskrcnn/ascend310_infer/src/AclProcess.cpp
  32. +0
    -42
      model_zoo/official/cv/maskrcnn/ascend310_infer/src/CMakeLists.txt
  33. +0
    -735
      model_zoo/official/cv/maskrcnn/ascend310_infer/src/DvppCommon.cpp
  34. +0
    -226
      model_zoo/official/cv/maskrcnn/ascend310_infer/src/ModelProcess.cpp
  35. +0
    -56
      model_zoo/official/cv/maskrcnn/ascend310_infer/src/build.sh
  36. +235
    -0
      model_zoo/official/cv/maskrcnn/ascend310_infer/src/main.cc
  37. +0
    -132
      model_zoo/official/cv/maskrcnn/ascend310_infer/src/main.cpp
  38. +129
    -0
      model_zoo/official/cv/maskrcnn/ascend310_infer/src/utils.cc
  39. +10
    -8
      model_zoo/official/cv/maskrcnn/postprocess.py
  40. +21
    -35
      model_zoo/official/cv/maskrcnn/scripts/run_infer_310.sh
  41. +0
    -26
      model_zoo/official/cv/maskrcnn/src/aipp.cfg

+ 3
- 4
model_zoo/official/cv/faster_rcnn/README.md View File

@@ -177,7 +177,7 @@ sh run_eval_ascend.sh [VALIDATION_JSON_FILE] [CHECKPOINT_PATH]


```shell ```shell
# inference # inference
sh run_infer_310.sh [AIR_PATH] [DATA_PATH] [ANN_FILE_PATH]
sh run_infer_310.sh [MINDIR_PATH] [DATA_PATH] [ANN_FILE] [DEVICE_ID]
``` ```


# Script Description # Script Description
@@ -210,7 +210,6 @@ sh run_infer_310.sh [AIR_PATH] [DATA_PATH] [ANN_FILE_PATH]
├─resnet50.py // backbone network ├─resnet50.py // backbone network
├─roi_align.py // roi align network ├─roi_align.py // roi align network
└─rpn.py // region proposal network └─rpn.py // region proposal network
├─aipp.cfg // aipp config file
├─config.py // total config ├─config.py // total config
├─dataset.py // create dataset and process dataset ├─dataset.py // create dataset and process dataset
├─lr_schedule.py // learning ratio generator ├─lr_schedule.py // learning ratio generator
@@ -339,7 +338,7 @@ Eval result will be stored in the example path, whose folder name is "eval". Und
python export.py --ckpt_file [CKPT_PATH] --device_target [DEVICE_TARGET] --file_format[EXPORT_FORMAT] python export.py --ckpt_file [CKPT_PATH] --device_target [DEVICE_TARGET] --file_format[EXPORT_FORMAT]
``` ```


`EXPORT_FORMAT` should be in ["AIR", "ONNX", "MINDIR"]
`EXPORT_FORMAT` should be in ["AIR", "MINDIR"]


## Inference Process ## Inference Process


@@ -349,7 +348,7 @@ Before performing inference, the air file must bu exported by export script on t


```shell ```shell
# Ascend310 inference # Ascend310 inference
sh run_infer_310.sh [AIR_PATH] [DATA_PATH] [ANN_FILE_PATH]
sh run_infer_310.sh [MINDIR_PATH] [DATA_PATH] [ANN_FILE] [DEVICE_ID]
``` ```


### result ### result


+ 3
- 4
model_zoo/official/cv/faster_rcnn/README_CN.md View File

@@ -120,7 +120,7 @@ sh run_distribute_train_ascend.sh [RANK_TABLE_FILE] [PRETRAINED_MODEL]
sh run_eval_ascend.sh [VALIDATION_JSON_FILE] [CHECKPOINT_PATH] sh run_eval_ascend.sh [VALIDATION_JSON_FILE] [CHECKPOINT_PATH]


#推理 #推理
sh run_infer_310.sh [AIR_PATH] [DATA_PATH] [ANN_FILE_PATH] [DEVICE_ID]
sh run_infer_310.sh [MINDIR_PATH] [DATA_PATH] [ANN_FILE] [DEVICE_ID]
``` ```


## 在GPU上运行 ## 在GPU上运行
@@ -211,7 +211,6 @@ sh run_infer_310.sh [AIR_PATH] [DATA_PATH] [ANN_FILE_PATH] [DEVICE_ID]
├─resnet50.py // 骨干网络 ├─resnet50.py // 骨干网络
├─roi_align.py // ROI对齐网络 ├─roi_align.py // ROI对齐网络
└─rpn.py // 区域候选网络 └─rpn.py // 区域候选网络
├─aipp.cfg // aipp 配置文件
├─config.py // 总配置 ├─config.py // 总配置
├─dataset.py // 创建并处理数据集 ├─dataset.py // 创建并处理数据集
├─lr_schedule.py // 学习率生成器 ├─lr_schedule.py // 学习率生成器
@@ -340,7 +339,7 @@ sh run_eval_gpu.sh [VALIDATION_JSON_FILE] [CHECKPOINT_PATH]
python export.py --ckpt_file [CKPT_PATH] --device_target [DEVICE_TARGET] --file_format[EXPORT_FORMAT] python export.py --ckpt_file [CKPT_PATH] --device_target [DEVICE_TARGET] --file_format[EXPORT_FORMAT]
``` ```


`EXPORT_FORMAT` 可选 ["AIR", "ONNX", "MINDIR"]
`EXPORT_FORMAT` 可选 ["AIR", "MINDIR"]


## 推理过程 ## 推理过程


@@ -350,7 +349,7 @@ python export.py --ckpt_file [CKPT_PATH] --device_target [DEVICE_TARGET] --file_


```shell ```shell
# Ascend310 inference # Ascend310 inference
sh run_infer_310.sh [AIR_PATH] [DATA_PATH] [ANN_FILE_PATH] [DEVICE_ID]
sh run_infer_310.sh [MINDIR_PATH] [DATA_PATH] [ANN_FILE] [DEVICE_ID]
``` ```


### 结果 ### 结果


+ 14
- 0
model_zoo/official/cv/faster_rcnn/ascend310_infer/CMakeLists.txt View File

@@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.14.1)
project(Ascend310Infer)
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")
set(PROJECT_SRC_ROOT ${CMAKE_CURRENT_LIST_DIR}/)
option(MINDSPORE_PATH "mindspore install path" "")
include_directories(${MINDSPORE_PATH})
include_directories(${MINDSPORE_PATH}/include)
include_directories(${PROJECT_SRC_ROOT})
find_library(MS_LIB libmindspore.so ${MINDSPORE_PATH}/lib)
file(GLOB_RECURSE MD_LIB ${MINDSPORE_PATH}/_c_dataengine*)

add_executable(main src/main.cc src/utils.cc)
target_link_libraries(main ${MS_LIB} ${MD_LIB} gflags)

+ 29
- 0
model_zoo/official/cv/faster_rcnn/ascend310_infer/build.sh View File

@@ -0,0 +1,29 @@
#!/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 [ -d out ]; then
rm -rf out
fi

mkdir out
cd out || exit

if [ -f "Makefile" ]; then
make clean
fi

cmake .. \
-DMINDSPORE_PATH="`pip3.7 show mindspore-ascend | grep Location | awk '{print $2"/mindspore"}' | xargs realpath`"
make

+ 0
- 62
model_zoo/official/cv/faster_rcnn/ascend310_infer/inc/AclProcess.h View File

@@ -1,62 +0,0 @@
/*
* Copyright (c) 2020.Huawei Technologies Co., Ltd. All rights reserved.
* 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 ACLMANAGER_H
#define ACLMANAGER_H

#include <map>
#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include "acl/acl.h"
#include "CommonDataType.h"
#include "ModelProcess.h"
#include "DvppCommon.h"

struct ModelInfo {
std::string modelPath;
uint32_t modelWidth;
uint32_t modelHeight;
uint32_t outputNum;
};

class AclProcess {
public:
AclProcess(int deviceId, const std::string &om_path, uint32_t width, uint32_t height);
~AclProcess() {}
void Release();
int InitResource();
int Process(const std::string& imageFile, std::map<double, double> *costTime_map);

private:
int InitModule();
int Preprocess(const std::string& imageFile);
int ModelInfer(std::map<double, double> *costTime_map);
int WriteResult(const std::string& imageFile);
int ReadFile(const std::string &filePath, RawData *fileData);

int32_t deviceId_;
ModelInfo modelInfo_;
aclrtContext context_;
aclrtStream stream_;
std::shared_ptr<ModelProcess> modelProcess_;
std::shared_ptr<DvppCommon> dvppCommon_;
bool keepRatio_;
std::vector<void *> outputBuffers_;
std::vector<size_t> outputSizes_;
};

#endif

+ 0
- 95
model_zoo/official/cv/faster_rcnn/ascend310_infer/inc/CommonDataType.h View File

@@ -1,95 +0,0 @@
/*
* Copyright (c) 2020.Huawei Technologies Co., Ltd. All rights reserved.
* 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 COMMONDATATYPE_H
#define COMMONDATATYPE_H

#include <stdio.h>
#include <iostream>
#include <memory>
#include <vector>
#include "acl/acl.h"
#include "acl/ops/acl_dvpp.h"

#define DVPP_ALIGN_UP(x, align) ((((x) + ((align)-1)) / (align)) * (align))

#define OK 0
#define ERROR -1
#define INVALID_POINTER -2
#define READ_FILE_FAIL -3
#define OPEN_FILE_FAIL -4
#define INIT_FAIL -5
#define INVALID_PARAM -6
#define DECODE_FAIL -7

const float SEC2MS = 1000.0;
const int YUV_BGR_SIZE_CONVERT_3 = 3;
const int YUV_BGR_SIZE_CONVERT_2 = 2;
const int VPC_WIDTH_ALIGN = 16;
const int VPC_HEIGHT_ALIGN = 2;

// Description of image data
struct ImageInfo {
uint32_t width; // Image width
uint32_t height; // Image height
uint32_t lenOfByte; // Size of image data, bytes
std::shared_ptr<uint8_t> data; // Smart pointer of image data
};

// Description of data in device
struct RawData {
size_t lenOfByte; // Size of memory, bytes
std::shared_ptr<void> data; // Smart pointer of data
};

// define the structure of an rectangle
struct Rectangle {
uint32_t leftTopX;
uint32_t leftTopY;
uint32_t rightBottomX;
uint32_t rightBottomY;
};

enum VpcProcessType {
VPC_PT_DEFAULT = 0,
VPC_PT_PADDING, // Resize with locked ratio and paste on upper left corner
VPC_PT_FIT, // Resize with locked ratio and paste on middle location
VPC_PT_FILL, // Resize with locked ratio and paste on whole locatin, the input image may be cropped
};

struct DvppDataInfo {
uint32_t width = 0; // Width of image
uint32_t height = 0; // Height of image
uint32_t widthStride = 0; // Width after align up
uint32_t heightStride = 0; // Height after align up
acldvppPixelFormat format = PIXEL_FORMAT_YUV_SEMIPLANAR_420; // Format of image
uint32_t frameId = 0; // Needed by video
uint32_t dataSize = 0; // Size of data in byte
uint8_t *data = nullptr; // Image data
};

struct CropRoiConfig {
uint32_t left;
uint32_t right;
uint32_t down;
uint32_t up;
};

struct DvppCropInputInfo {
DvppDataInfo dataInfo;
CropRoiConfig roi;
};

#endif

+ 0
- 139
model_zoo/official/cv/faster_rcnn/ascend310_infer/inc/DvppCommon.h View File

@@ -1,139 +0,0 @@
/*
* Copyright (c) 2020.Huawei Technologies Co., Ltd. All rights reserved.
* 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 DVPP_COMMON_H
#define DVPP_COMMON_H
#include <memory>

#include "CommonDataType.h"
#include "acl/ops/acl_dvpp.h"

const int MODULUS_NUM_2 = 2;
const uint32_t ODD_NUM_1 = 1;

const uint32_t JPEGD_STRIDE_WIDTH = 128; // Jpegd module output width need to align up to 128
const uint32_t JPEGD_STRIDE_HEIGHT = 16; // Jpegd module output height need to align up to 16
const uint32_t VPC_STRIDE_WIDTH = 16; // Vpc module output width need to align up to 16
const uint32_t VPC_STRIDE_HEIGHT = 2; // Vpc module output height need to align up to 2
const uint32_t YUV422_WIDTH_NU = 2; // Width of YUV422, WidthStride = Width * 2
const uint32_t YUV444_RGB_WIDTH_NU = 3; // Width of YUV444 and RGB888, WidthStride = Width * 3
const uint32_t XRGB_WIDTH_NU = 4; // Width of XRGB8888, WidthStride = Width * 4
const uint32_t JPEG_OFFSET = 8; // Offset of input file for jpegd module
const uint32_t MAX_JPEGD_WIDTH = 8192; // Max width of jpegd module
const uint32_t MAX_JPEGD_HEIGHT = 8192; // Max height of jpegd module
const uint32_t MIN_JPEGD_WIDTH = 32; // Min width of jpegd module
const uint32_t MIN_JPEGD_HEIGHT = 32; // Min height of jpegd module
const uint32_t MAX_RESIZE_WIDTH = 4096; // Max width stride of resize module
const uint32_t MAX_RESIZE_HEIGHT = 4096; // Max height stride of resize module
const uint32_t MIN_RESIZE_WIDTH = 32; // Min width stride of resize module
const uint32_t MIN_RESIZE_HEIGHT = 6; // Min height stride of resize module
const float MIN_RESIZE_SCALE = 0.03125; // Min resize scale of resize module
const float MAX_RESIZE_SCALE = 16.0; // Min resize scale of resize module
const uint32_t MAX_VPC_WIDTH = 4096; // Max width of picture to VPC(resize/crop)
const uint32_t MAX_VPC_HEIGHT = 4096; // Max height of picture to VPC(resize/crop)
const uint32_t MIN_VPC_WIDTH = 32; // Min width of picture to VPC(resize/crop)
const uint32_t MIN_VPC_HEIGHT = 6; // Min height of picture to VPC(resize/crop)
const uint32_t MIN_CROP_WIDTH = 10; // Min width of crop area
const uint32_t MIN_CROP_HEIGHT = 6; // Min height of crop area
const uint8_t YUV_GREYER_VALUE = 128; // Filling value of the resized YUV image

#define CONVERT_TO_ODD(NUM) (((NUM) % MODULUS_NUM_2 != 0) ? (NUM) : ((NUM) - 1))
#define CONVERT_TO_EVEN(NUM) (((NUM) % MODULUS_NUM_2 == 0) ? (NUM) : ((NUM) - 1))
#define CHECK_ODD(num) ((num) % MODULUS_NUM_2 != 0)
#define CHECK_EVEN(num) ((num) % MODULUS_NUM_2 == 0)
#define RELEASE_DVPP_DATA(dvppDataPtr) do { \
int retMacro; \
if (dvppDataPtr != nullptr) { \
retMacro = acldvppFree(dvppDataPtr); \
if (retMacro != OK) { \
std::cout << "Failed to free memory on dvpp, ret = " << retMacro << "." << std::endl; \
} \
dvppDataPtr = nullptr; \
} \
} while (0);

class DvppCommon {
public:
explicit DvppCommon(aclrtStream dvppStream);
~DvppCommon();
int Init(void);
int DeInit(void);

static int GetVpcDataSize(uint32_t widthVpc, uint32_t heightVpc, acldvppPixelFormat format,
uint32_t *vpcSize);

static int GetVpcInputStrideSize(uint32_t width, uint32_t height, acldvppPixelFormat format,
uint32_t *widthStride, uint32_t *heightStride);

static int GetVpcOutputStrideSize(uint32_t width, uint32_t height, acldvppPixelFormat format,
uint32_t *widthStride, uint32_t *heightStride);

static void GetJpegDecodeStrideSize(uint32_t width, uint32_t height, uint32_t *widthStride, uint32_t *heightStride);
static int GetJpegImageInfo(const void *data, uint32_t dataSize, uint32_t *width, uint32_t *height,
int32_t *components);

static int GetJpegDecodeDataSize(const void *data, uint32_t dataSize, acldvppPixelFormat format,
uint32_t *decSize);

int VpcResize(std::shared_ptr<DvppDataInfo> input, std::shared_ptr<DvppDataInfo> output, bool withSynchronize,
VpcProcessType processType = VPC_PT_DEFAULT);

int JpegDecode(std::shared_ptr<DvppDataInfo> input, std::shared_ptr<DvppDataInfo> output, bool withSynchronize);

int CombineResizeProcess(std::shared_ptr<DvppDataInfo> input, const DvppDataInfo &output, bool withSynchronize,
VpcProcessType processType = VPC_PT_DEFAULT);

int CombineJpegdProcess(const RawData& imageInfo, acldvppPixelFormat format, bool withSynchronize);

std::shared_ptr<DvppDataInfo> GetInputImage();
std::shared_ptr<DvppDataInfo> GetDecodedImage();
std::shared_ptr<DvppDataInfo> GetResizedImage();

void ReleaseDvppBuffer();

private:
int SetDvppPicDescData(std::shared_ptr<DvppDataInfo> dataInfo, std::shared_ptr<acldvppPicDesc>picDesc);
int ResizeProcess(std::shared_ptr<acldvppPicDesc> inputDesc,
std::shared_ptr<acldvppPicDesc> outputDesc, bool withSynchronize);

int ResizeWithPadding(std::shared_ptr<acldvppPicDesc> inputDesc, std::shared_ptr<acldvppPicDesc> outputDesc,
const CropRoiConfig &cropRoi, const CropRoiConfig &pasteRoi, bool withSynchronize);

void GetCropRoi(std::shared_ptr<DvppDataInfo> input, std::shared_ptr<DvppDataInfo> output,
VpcProcessType processType, CropRoiConfig *cropRoi);

void GetPasteRoi(std::shared_ptr<DvppDataInfo> input, std::shared_ptr<DvppDataInfo> output,
VpcProcessType processType, CropRoiConfig *pasteRoi);

int CheckResizeParams(const DvppDataInfo &input, const DvppDataInfo &output);
int TransferImageH2D(const RawData& imageInfo, const std::shared_ptr<DvppDataInfo>& jpegInput);
int CreateStreamDesc(std::shared_ptr<DvppDataInfo> data);
int DestroyResource();

std::shared_ptr<acldvppRoiConfig> cropAreaConfig_ = nullptr;
std::shared_ptr<acldvppRoiConfig> pasteAreaConfig_ = nullptr;

std::shared_ptr<acldvppPicDesc> resizeInputDesc_ = nullptr;
std::shared_ptr<acldvppPicDesc> resizeOutputDesc_ = nullptr;
std::shared_ptr<acldvppPicDesc> decodeOutputDesc_ = nullptr;
std::shared_ptr<acldvppResizeConfig> resizeConfig_ = nullptr;

acldvppChannelDesc *dvppChannelDesc_ = nullptr;
aclrtStream dvppStream_ = nullptr;
std::shared_ptr<DvppDataInfo> inputImage_ = nullptr;
std::shared_ptr<DvppDataInfo> decodedImage_ = nullptr;
std::shared_ptr<DvppDataInfo> resizedImage_ = nullptr;
};
#endif

+ 0
- 63
model_zoo/official/cv/faster_rcnn/ascend310_infer/inc/ModelProcess.h View File

@@ -1,63 +0,0 @@
/*
* Copyright(C) 2020. Huawei Technologies Co.,Ltd. All rights reserved.
*
* 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 MODELPROCSS_H
#define MODELPROCSS_H

#include <cstdio>
#include <vector>
#include <unordered_map>
#include <mutex>
#include <map>
#include <memory>
#include <string>
#include "acl/acl.h"
#include "CommonDataType.h"

class ModelProcess {
public:
explicit ModelProcess(const int deviceId);
ModelProcess();
~ModelProcess();

int Init(const std::string &modelPath);
int DeInit();

int ModelInference(const std::vector<void *> &inputBufs,
const std::vector<size_t> &inputSizes,
const std::vector<void *> &ouputBufs,
const std::vector<size_t> &outputSizes,
std::map<double, double> *costTime_map);
aclmdlDesc *GetModelDesc();
int ReadBinaryFile(const std::string &fileName, uint8_t **buffShared, int *buffLength);

private:
aclmdlDataset *CreateAndFillDataset(const std::vector<void *> &bufs, const std::vector<size_t> &sizes);
void DestroyDataset(aclmdlDataset *dataset);

std::mutex mtx_ = {};
int deviceId_ = 0;
uint32_t modelId_ = 0;
void *modelDevPtr_ = nullptr;
size_t modelDevPtrSize_ = 0;
void *weightDevPtr_ = nullptr;
size_t weightDevPtrSize_ = 0;
aclrtContext contextModel_ = nullptr;
std::shared_ptr<aclmdlDesc> modelDesc_ = nullptr;
bool isDeInit_ = false;
};

#endif

+ 32
- 0
model_zoo/official/cv/faster_rcnn/ascend310_infer/inc/utils.h View File

@@ -0,0 +1,32 @@
/**
* 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 <sys/stat.h>
#include <dirent.h>
#include <vector>
#include <string>
#include <memory>
#include "include/api/types.h"

std::vector<std::string> GetAllFiles(std::string_view dirName);
DIR *OpenDir(std::string_view dirName);
std::string RealPath(std::string_view path);
mindspore::MSTensor ReadFileToTensor(const std::string &file);
int WriteResult(const std::string& imageFile, const std::vector<mindspore::MSTensor> &outputs);
#endif

+ 0
- 367
model_zoo/official/cv/faster_rcnn/ascend310_infer/src/AclProcess.cpp View File

@@ -1,367 +0,0 @@
/*
* Copyright (c) 2020.Huawei Technologies Co., Ltd. All rights reserved.
* 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 "AclProcess.h"
#include <sys/time.h>
#include <thread>
#include <string>

/*
* @description Implementation of constructor for class AclProcess with parameter list
* @attention context is passed in as a parameter after being created in ResourceManager::InitResource
*/
AclProcess::AclProcess(int deviceId, const std::string &om_path, uint32_t width, uint32_t height)
: deviceId_(deviceId), stream_(nullptr), modelProcess_(nullptr), dvppCommon_(nullptr), keepRatio_(true) {
modelInfo_.modelPath = om_path;
modelInfo_.modelWidth = width;
modelInfo_.modelHeight = height;
}

/*
* @description Release all the resource
* @attention context will be released in ResourceManager::Release
*/
void AclProcess::Release() {
// Synchronize stream and release Dvpp channel
dvppCommon_->DeInit();
// Release stream
if (stream_ != nullptr) {
int ret = aclrtDestroyStream(stream_);
if (ret != OK) {
std::cout << "Failed to destroy the stream, ret = " << ret << ".";
}
stream_ = nullptr;
}
// Destroy resources of modelProcess_
modelProcess_->DeInit();

// Release Dvpp buffer
dvppCommon_->ReleaseDvppBuffer();

return;
}

/*
* @description Initialize the modules used by this sample
* @return int int code
*/
int AclProcess::InitModule() {
// Create Dvpp common object
if (dvppCommon_ == nullptr) {
dvppCommon_ = std::make_shared<DvppCommon>(stream_);
int retDvppCommon = dvppCommon_->Init();
if (retDvppCommon != OK) {
std::cout << "Failed to initialize dvppCommon, ret = " << retDvppCommon << std::endl;
return retDvppCommon;
}
}
// Create model inference object
if (modelProcess_ == nullptr) {
modelProcess_ = std::make_shared<ModelProcess>(deviceId_);
}
// Initialize ModelProcess module
int ret = modelProcess_->Init(modelInfo_.modelPath);
if (ret != OK) {
std::cout << "Failed to initialize the model process module, ret = " << ret << "." << std::endl;
return ret;
}
std::cout << "Initialized the model process module successfully." << std::endl;
return OK;
}

/*
* @description Create resource for this sample
* @return int int code
*/
int AclProcess::InitResource() {
int ret = aclInit(nullptr); // Initialize ACL
if (ret != OK) {
std::cout << "Failed to init acl, ret = " << ret << std::endl;
return ret;
}

ret = aclrtSetDevice(deviceId_);
if (ret != ACL_SUCCESS) {
std::cout << "acl set device " << deviceId_ << "intCode = "<< static_cast<int32_t>(ret) << std::endl;
return ret;
}
std::cout << "set device "<< deviceId_ << " success" << std::endl;

// create context (set current)
ret = aclrtCreateContext(&context_, deviceId_);
if (ret != ACL_SUCCESS) {
std::cout << "acl create context failed, deviceId = " << deviceId_ <<
"intCode = "<< static_cast<int32_t>(ret) << std::endl;
return ret;
}
std::cout << "create context success" << std::endl;

ret = aclrtCreateStream(&stream_); // Create stream for application
if (ret != OK) {
std::cout << "Failed to create the acl stream, ret = " << ret << "." << std::endl;
return ret;
}
std::cout << "Created the acl stream successfully." << std::endl;
// Initialize dvpp module
if (InitModule() != OK) {
return INIT_FAIL;
}

aclmdlDesc *modelDesc = modelProcess_->GetModelDesc();
size_t outputSize = aclmdlGetNumOutputs(modelDesc);
modelInfo_.outputNum = outputSize;
for (size_t i = 0; i < outputSize; i++) {
size_t bufferSize = aclmdlGetOutputSizeByIndex(modelDesc, i);
void *outputBuffer = nullptr;
ret = aclrtMalloc(&outputBuffer, bufferSize, ACL_MEM_MALLOC_NORMAL_ONLY);
if (ret != OK) {
std::cout << "Failed to malloc buffer, ret = " << ret << "." << std::endl;
return ret;
}
outputBuffers_.push_back(outputBuffer);
outputSizes_.push_back(bufferSize);
}

return OK;
}

int AclProcess::WriteResult(const std::string& imageFile) {
std::string homePath = "./result_Files";
void *resHostBuf = nullptr;
for (size_t i = 0; i < outputBuffers_.size(); ++i) {
size_t output_size;
void *netOutput;
netOutput = outputBuffers_[i];
output_size = outputSizes_[i];
int ret = aclrtMallocHost(&resHostBuf, output_size);
if (ret != OK) {
std::cout << "Failed to print the result, malloc host failed, ret = " << ret << "." << std::endl;
return ret;
}

ret = aclrtMemcpy(resHostBuf, output_size, netOutput,
output_size, ACL_MEMCPY_DEVICE_TO_HOST);
if (ret != OK) {
std::cout << "Failed to print result, memcpy device to host failed, ret = " << ret << "." << std::endl;
return ret;
}

int pos = imageFile.rfind('/');
std::string fileName(imageFile, pos + 1);
fileName.replace(fileName.find('.'), fileName.size() - fileName.find('.'), "_" + std::to_string(i) + ".bin");

std::string outFileName = homePath + "/" + fileName;
try {
FILE *outputFile = fopen(outFileName.c_str(), "wb");
if (outputFile == nullptr) {
std::cout << "open result file " << outFileName << " failed" << std::endl;
return INVALID_POINTER;
}
size_t size = fwrite(resHostBuf, sizeof(char), output_size, outputFile);
if (size != output_size) {
fclose(outputFile);
outputFile = nullptr;
std::cout << "write result file " << outFileName << " failed, write size[" << size <<
"] is smaller than output size[" << output_size << "], maybe the disk is full." << std::endl;
return ERROR;
}

fclose(outputFile);
outputFile = nullptr;
} catch (std::exception &e) {
std::cout << "write result file " << outFileName << " failed, error info: " << e.what() << std::endl;
std::exit(1);
}

ret = aclrtFreeHost(resHostBuf);
if (ret != OK) {
std::cout << "aclrtFree host output memory failed" << std::endl;
return ret;
}
}
return OK;
}

/**
* Read a file, store it into the RawData structure
*
* @param filePath file to read to
* @param fileData RawData structure to store in
* @return OK if create success, int code otherwise
*/
int AclProcess::ReadFile(const std::string &filePath, RawData *fileData) {
// Open file with reading mode
FILE *fp = fopen(filePath.c_str(), "rb");
if (fp == nullptr) {
std::cout << "Failed to open file, filePath = " << filePath << std::endl;
return OPEN_FILE_FAIL;
}
// Get the length of input file
fseek(fp, 0, SEEK_END);
size_t fileSize = ftell(fp);
fseek(fp, 0, SEEK_SET);
// If file not empty, read it into FileInfo and return it
if (fileSize > 0) {
fileData->lenOfByte = fileSize;
fileData->data = std::make_shared<uint8_t>();
fileData->data.reset(new uint8_t[fileSize], std::default_delete<uint8_t[]>());
uint32_t readRet = fread(fileData->data.get(), 1, fileSize, fp);
if (readRet == 0) {
fclose(fp);
return READ_FILE_FAIL;
}
fclose(fp);
return OK;
}
fclose(fp);
return INVALID_PARAM;
}
/*
* @description Preprocess the input image
* @param imageFile input image path
* @return int int code
*/
int AclProcess::Preprocess(const std::string& imageFile) {
RawData imageInfo;
int ret = ReadFile(imageFile, &imageInfo); // Read image data from input image file
if (ret != OK) {
std::cout << "Failed to read file, ret = " << ret << "." << std::endl;
return ret;
}
// Run process of jpegD
ret = dvppCommon_->CombineJpegdProcess(imageInfo, PIXEL_FORMAT_YUV_SEMIPLANAR_420, true);
if (ret != OK) {
std::cout << "Failed to execute image decoded of preprocess module, ret = " << ret << "." << std::endl;
return ret;
}
// Get output of decode jpeg image
std::shared_ptr<DvppDataInfo> decodeOutData = dvppCommon_->GetDecodedImage();
// Run resize application function
DvppDataInfo resizeOutData;
resizeOutData.height = modelInfo_.modelHeight;
resizeOutData.width = modelInfo_.modelWidth;
resizeOutData.format = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
ret = dvppCommon_->CombineResizeProcess(decodeOutData, resizeOutData, true, VPC_PT_PADDING);
if (ret != OK) {
std::cout << "Failed to execute image resized of preprocess module, ret = " << ret << "." << std::endl;
return ret;
}

RELEASE_DVPP_DATA(decodeOutData->data);
return OK;
}

/*
* @description Inference of model
* @return int int code
*/
int AclProcess::ModelInfer(std::map<double, double> *costTime_map) {
// Get output of resize module
std::shared_ptr<DvppDataInfo> resizeOutData = dvppCommon_->GetResizedImage();
std::shared_ptr<DvppDataInfo> inputImg = dvppCommon_->GetInputImage();

float widthScale, heightScale;
if (keepRatio_) {
widthScale = static_cast<float>(resizeOutData->width) / inputImg->width;
if (widthScale > static_cast<float>(resizeOutData->height) / inputImg->height) {
widthScale = static_cast<float>(resizeOutData->height) / inputImg->height;
}
heightScale = widthScale;
} else {
widthScale = static_cast<float>(resizeOutData->width) / inputImg->width;
heightScale = static_cast<float>(resizeOutData->height) / inputImg->height;
}

float im_info[4];
im_info[0] = static_cast<float>(inputImg->height);
im_info[1] = static_cast<float>(inputImg->width);
im_info[2] = heightScale;
im_info[3] = widthScale;
void *imInfo_dst = nullptr;
int ret = aclrtMalloc(&imInfo_dst, 16, ACL_MEM_MALLOC_NORMAL_ONLY);
if (ret != ACL_ERROR_NONE) {
std::cout << "aclrtMalloc failed, ret = " << ret << std::endl;
aclrtFree(imInfo_dst);
return ret;
}
ret = aclrtMemcpy(reinterpret_cast<uint8_t *>(imInfo_dst), 16, im_info, 16, ACL_MEMCPY_HOST_TO_DEVICE);
if (ret != ACL_ERROR_NONE) {
std::cout << "aclrtMemcpy failed, ret = " << ret << std::endl;
aclrtFree(imInfo_dst);
return ret;
}

std::vector<void *> inputBuffers({resizeOutData->data, imInfo_dst});
std::vector<size_t> inputSizes({resizeOutData->dataSize, 4 * 4});

for (size_t i = 0; i < modelInfo_.outputNum; i++) {
aclrtMemset(outputBuffers_[i], outputSizes_[i], 0, outputSizes_[i]);
}
// Execute classification model
ret = modelProcess_->ModelInference(inputBuffers, inputSizes, outputBuffers_, outputSizes_, costTime_map);
if (ret != OK) {
aclrtFree(imInfo_dst);
std::cout << "Failed to execute the classification model, ret = " << ret << "." << std::endl;
return ret;
}

ret = aclrtFree(imInfo_dst);
if (ret != OK) {
std::cout << "aclrtFree image info failed" << std::endl;
return ret;
}
RELEASE_DVPP_DATA(resizeOutData->data);
return OK;
}

/*
* @description Process classification
*
* @par Function
* 1.Dvpp module preprocess
* 2.Execute classification model
* 3.Execute single operator
* 4.Write result
*
* @param imageFile input file path
* @return int int code
*/

int AclProcess::Process(const std::string& imageFile, std::map<double, double> *costTime_map) {
struct timeval begin = {0};
struct timeval end = {0};
gettimeofday(&begin, nullptr);

int ret = Preprocess(imageFile);
if (ret != OK) {
return ret;
}

ret = ModelInfer(costTime_map);
if (ret != OK) {
return ret;
}

ret = WriteResult(imageFile);
if (ret != OK) {
std::cout << "write result failed." << std::endl;
return ret;
}
gettimeofday(&end, nullptr);

const double costMs = SEC2MS * (end.tv_sec - begin.tv_sec) + (end.tv_usec - begin.tv_usec) / SEC2MS;
std::cout << "[Process Delay] cost: " << costMs << "ms." << std::endl;
return OK;
}

+ 0
- 42
model_zoo/official/cv/faster_rcnn/ascend310_infer/src/CMakeLists.txt View File

@@ -1,42 +0,0 @@
# Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved.

# CMake lowest version requirement
cmake_minimum_required(VERSION 3.5.1)
# Add definitions ENABLE_DVPP_INTERFACE to use dvpp api
add_definitions(-DENABLE_DVPP_INTERFACE)
# 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_options(-std=c++11 -fPIE -g -fstack-protector-all -Werror -Wreturn-type)

# 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)
find_library(acl_dvpp libacl_dvpp.so ${ACL_LIB_DIR}/lib64 ${ATLAS_ACL_LIB_DIR}/lib64)

add_executable(main AclProcess.cpp
DvppCommon.cpp
ModelProcess.cpp
main.cpp)

target_link_libraries(main ${acl} gflags ${acl_dvpp} pthread)

+ 0
- 735
model_zoo/official/cv/faster_rcnn/ascend310_infer/src/DvppCommon.cpp View File

@@ -1,735 +0,0 @@
/*
* Copyright (c) 2020.Huawei Technologies Co., Ltd. All rights reserved.
* 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 <iostream>
#include <memory>

#include "../inc/DvppCommon.h"
#include "../inc/CommonDataType.h"

static auto g_resizeConfigDeleter = [](acldvppResizeConfig *p) { acldvppDestroyResizeConfig(p); };
static auto g_picDescDeleter = [](acldvppPicDesc *picDesc) { acldvppDestroyPicDesc(picDesc); };
static auto g_roiConfigDeleter = [](acldvppRoiConfig *p) { acldvppDestroyRoiConfig(p); };

DvppCommon::DvppCommon(aclrtStream dvppStream):dvppStream_(dvppStream) {}

/*
* @description: Create a channel for processing image data,
* the channel description is created by acldvppCreateChannelDesc
* @return: OK if success, other values if failure
*/
int DvppCommon::Init(void) {
dvppChannelDesc_ = acldvppCreateChannelDesc();
if (dvppChannelDesc_ == nullptr) {
return -1;
}
int ret = acldvppCreateChannel(dvppChannelDesc_);
if (ret != 0) {
std::cout << "Failed to create dvpp channel, ret = " << ret << "." << std::endl;
acldvppDestroyChannelDesc(dvppChannelDesc_);
dvppChannelDesc_ = nullptr;
return ret;
}

return OK;
}

/*
* @description: destroy the channel and the channel description used by image.
* @return: OK if success, other values if failure
*/
int DvppCommon::DeInit(void) {
int ret = aclrtSynchronizeStream(dvppStream_); // int ret
if (ret != OK) {
std::cout << "Failed to synchronize stream, ret = " << ret << "." << std::endl;
return ret;
}

ret = acldvppDestroyChannel(dvppChannelDesc_);
if (ret != OK) {
std::cout << "Failed to destroy dvpp channel, ret = " << ret << "." << std::endl;
return ret;
}

ret = acldvppDestroyChannelDesc(dvppChannelDesc_);
if (ret != OK) {
std::cout << "Failed to destroy dvpp channel description, ret = " << ret << "." << std::endl;
return ret;
}
return OK;
}

/*
* @description: Release the memory that is allocated in the interfaces which are started with "Combine"
*/
void DvppCommon::ReleaseDvppBuffer() {
if (resizedImage_ != nullptr) {
RELEASE_DVPP_DATA(resizedImage_->data);
}
if (decodedImage_ != nullptr) {
RELEASE_DVPP_DATA(decodedImage_->data);
}
if (inputImage_ != nullptr) {
RELEASE_DVPP_DATA(inputImage_->data);
}
}

/*
* @description: Get the size of buffer used to save image for VPC according to width, height and format
* @param width specifies the width of the output image
* @param height specifies the height of the output image
* @param format specifies the format of the output image
* @param: vpcSize is used to save the result size
* @return: OK if success, other values if failure
*/
int DvppCommon::GetVpcDataSize(uint32_t width, uint32_t height, acldvppPixelFormat format, uint32_t *vpcSize) {
if (format != PIXEL_FORMAT_YUV_SEMIPLANAR_420 && format != PIXEL_FORMAT_YVU_SEMIPLANAR_420) {
std::cout << "Format[" << format << "] for VPC is not supported, just support NV12 or NV21." << std::endl;
return INVALID_PARAM;
}
uint32_t widthStride = DVPP_ALIGN_UP(width, VPC_WIDTH_ALIGN);
uint32_t heightStride = DVPP_ALIGN_UP(height, VPC_HEIGHT_ALIGN);
*vpcSize = widthStride * heightStride * YUV_BGR_SIZE_CONVERT_3 / YUV_BGR_SIZE_CONVERT_2;
return OK;
}

/*
* @description: Get the aligned width and height of the input image according to the image format
* @param: width specifies the width before alignment
* @param: height specifies the height before alignment
* @param: format specifies the image format
* @param: widthStride is used to save the width after alignment
* @param: heightStride is used to save the height after alignment
* @return: OK if success, other values if failure
*/
int DvppCommon::GetVpcInputStrideSize(uint32_t width, uint32_t height, acldvppPixelFormat format,
uint32_t *widthStride, uint32_t *heightStride) {
uint32_t inputWidthStride;
if (format >= PIXEL_FORMAT_YUV_400 && format <= PIXEL_FORMAT_YVU_SEMIPLANAR_444) {
inputWidthStride = DVPP_ALIGN_UP(width, VPC_STRIDE_WIDTH);
} else if (format >= PIXEL_FORMAT_YUYV_PACKED_422 && format <= PIXEL_FORMAT_VYUY_PACKED_422) {
inputWidthStride = DVPP_ALIGN_UP(width, VPC_STRIDE_WIDTH) * YUV422_WIDTH_NU;
} else if (format >= PIXEL_FORMAT_YUV_PACKED_444 && format <= PIXEL_FORMAT_BGR_888) {
inputWidthStride = DVPP_ALIGN_UP(width, VPC_STRIDE_WIDTH) * YUV444_RGB_WIDTH_NU;
} else if (format >= PIXEL_FORMAT_ARGB_8888 && format <= PIXEL_FORMAT_BGRA_8888) {
inputWidthStride = DVPP_ALIGN_UP(width, VPC_STRIDE_WIDTH) * XRGB_WIDTH_NU;
} else {
std::cout << "Input format[" << format << "] for VPC is invalid, please check it." << std::endl;
return INVALID_PARAM;
}
uint32_t inputHeightStride = DVPP_ALIGN_UP(height, VPC_STRIDE_HEIGHT);
if (inputWidthStride > MAX_RESIZE_WIDTH || inputWidthStride < MIN_RESIZE_WIDTH) {
std::cout << "Input width stride " << inputWidthStride << " is invalid, not in [" << MIN_RESIZE_WIDTH \
<< ", " << MAX_RESIZE_WIDTH << "]." << std::endl;
return INVALID_PARAM;
}

if (inputHeightStride > MAX_RESIZE_HEIGHT || inputHeightStride < MIN_RESIZE_HEIGHT) {
std::cout << "Input height stride " << inputHeightStride << " is invalid, not in [" << MIN_RESIZE_HEIGHT \
<< ", " << MAX_RESIZE_HEIGHT << "]." << std::endl;
return INVALID_PARAM;
}
*widthStride = inputWidthStride;
*heightStride = inputHeightStride;
return OK;
}

/*
* @description: Get the aligned width and height of the output image according to the image format
* @param: width specifies the width before alignment
* @param: height specifies the height before alignment
* @param: format specifies the image format
* @param: widthStride is used to save the width after alignment
* @param: heightStride is used to save the height after alignment
* @return: OK if success, other values if failure
*/
int DvppCommon::GetVpcOutputStrideSize(uint32_t width, uint32_t height, acldvppPixelFormat format,
uint32_t *widthStride, uint32_t *heightStride) {
if (format != PIXEL_FORMAT_YUV_SEMIPLANAR_420 && format != PIXEL_FORMAT_YVU_SEMIPLANAR_420) {
std::cout << "Output format[" << format << "] is not supported, just support NV12 or NV21." << std::endl;
return INVALID_PARAM;
}

*widthStride = DVPP_ALIGN_UP(width, VPC_STRIDE_WIDTH);
*heightStride = DVPP_ALIGN_UP(height, VPC_STRIDE_HEIGHT);
return OK;
}

/*
* @description: Set picture description information and execute resize function
* @param: input specifies the input image information
* @param: output specifies the output image information
* @param: withSynchronize specifies whether to execute synchronously
* @param: processType specifies whether to perform proportional scaling, default is non-proportional resize
* @return: OK if success, other values if failure
* @attention: This function can be called only when the DvppCommon object is initialized with Init
*/
int DvppCommon::VpcResize(std::shared_ptr<DvppDataInfo> input, std::shared_ptr<DvppDataInfo> output,
bool withSynchronize, VpcProcessType processType) {
acldvppPicDesc *inputDesc = acldvppCreatePicDesc();
acldvppPicDesc *outputDesc = acldvppCreatePicDesc();
resizeInputDesc_.reset(inputDesc, g_picDescDeleter);
resizeOutputDesc_.reset(outputDesc, g_picDescDeleter);

// Set dvpp picture descriptin info of input image
int ret = SetDvppPicDescData(input, resizeInputDesc_);
if (ret != OK) {
std::cout << "Failed to set dvpp input picture description, ret = " << ret << "." << std::endl;
return ret;
}

// Set dvpp picture descriptin info of output image
ret = SetDvppPicDescData(output, resizeOutputDesc_);
if (ret != OK) {
std::cout << "Failed to set dvpp output picture description, ret = " << ret << "." << std::endl;
return ret;
}
if (processType == VPC_PT_DEFAULT) {
return ResizeProcess(resizeInputDesc_, resizeOutputDesc_, withSynchronize);
}

// Get crop area according to the processType
CropRoiConfig cropRoi = {0};
GetCropRoi(input, output, processType, &cropRoi);

// The width and height of the original image will be resized by the same ratio
CropRoiConfig pasteRoi = {0};
GetPasteRoi(input, output, processType, &pasteRoi);

return ResizeWithPadding(resizeInputDesc_, resizeOutputDesc_, cropRoi, pasteRoi, withSynchronize);
}

/*
* @description: Set image description information
* @param: dataInfo specifies the image information
* @param: picsDesc specifies the picture description information to be set
* @return: OK if success, other values if failure
*/
int DvppCommon::SetDvppPicDescData(std::shared_ptr<DvppDataInfo> dataInfo, std::shared_ptr<acldvppPicDesc>picDesc) {
int ret = acldvppSetPicDescData(picDesc.get(), dataInfo->data);
if (ret != OK) {
std::cout << "Failed to set data for dvpp picture description, ret = " << ret << "." << std::endl;
return ret;
}
ret = acldvppSetPicDescSize(picDesc.get(), dataInfo->dataSize);
if (ret != OK) {
std::cout << "Failed to set size for dvpp picture description, ret = " << ret << "." << std::endl;
return ret;
}
ret = acldvppSetPicDescFormat(picDesc.get(), dataInfo->format);
if (ret != OK) {
std::cout << "Failed to set format for dvpp picture description, ret = " << ret << "." << std::endl;
return ret;
}
ret = acldvppSetPicDescWidth(picDesc.get(), dataInfo->width);
if (ret != OK) {
std::cout << "Failed to set width for dvpp picture description, ret = " << ret << "." << std::endl;
return ret;
}
ret = acldvppSetPicDescHeight(picDesc.get(), dataInfo->height);
if (ret != OK) {
std::cout << "Failed to set height for dvpp picture description, ret = " << ret << "." << std::endl;
return ret;
}

ret = acldvppSetPicDescWidthStride(picDesc.get(), dataInfo->widthStride);
if (ret != OK) {
std::cout << "Failed to set aligned width for dvpp picture description, ret = " << ret << "." << std::endl;
return ret;
}
ret = acldvppSetPicDescHeightStride(picDesc.get(), dataInfo->heightStride);
if (ret != OK) {
std::cout << "Failed to set aligned height for dvpp picture description, ret = " << ret << "." << std::endl;
return ret;
}

return OK;
}

/*
* @description: Check whether the image format and zoom ratio meet the requirements
* @param: input specifies the input image information
* @param: output specifies the output image information
* @return: OK if success, other values if failure
*/
int DvppCommon::CheckResizeParams(const DvppDataInfo &input, const DvppDataInfo &output) {
if (output.format != PIXEL_FORMAT_YUV_SEMIPLANAR_420 && output.format != PIXEL_FORMAT_YVU_SEMIPLANAR_420) {
std::cout << "Output format[" << output.format << "]is not supported, just support NV12 or NV21." << std::endl;
return INVALID_PARAM;
}
float heightScale = static_cast<float>(output.height) / input.height;
if (heightScale < MIN_RESIZE_SCALE || heightScale > MAX_RESIZE_SCALE) {
std::cout << "Resize scale should be in range [1/16, 32], which is " << heightScale << "." << std::endl;
return INVALID_PARAM;
}
float widthScale = static_cast<float>(output.width) / input.width;
if (widthScale < MIN_RESIZE_SCALE || widthScale > MAX_RESIZE_SCALE) {
std::cout << "Resize scale should be in range [1/16, 32], which is " << widthScale << "." << std::endl;
return INVALID_PARAM;
}
return OK;
}

/*
* @description: Scale the input image to the size specified by the output image and
* saves the result to the output image (non-proportionate scaling)
* @param: inputDesc specifies the description information of the input image
* @param: outputDesc specifies the description information of the output image
* @param: withSynchronize specifies whether to execute synchronously
* @return: OK if success, other values if failure
*/
int DvppCommon::ResizeProcess(std::shared_ptr<acldvppPicDesc>inputDesc,
std::shared_ptr<acldvppPicDesc>outputDesc,
bool withSynchronize) {
acldvppResizeConfig *resizeConfig = acldvppCreateResizeConfig();
if (resizeConfig == nullptr) {
std::cout << "Failed to create dvpp resize config." << std::endl;
return INVALID_POINTER;
}

resizeConfig_.reset(resizeConfig, g_resizeConfigDeleter);
int ret = acldvppVpcResizeAsync(dvppChannelDesc_, inputDesc.get(), outputDesc.get(),
resizeConfig_.get(), dvppStream_);
if (ret != OK) {
std::cout << "Failed to resize asynchronously, ret = " << ret << "." << std::endl;
return ret;
}

if (withSynchronize) {
ret = aclrtSynchronizeStream(dvppStream_);
if (ret != OK) {
std::cout << "Failed to synchronize stream, ret = " << ret << "." << std::endl;
return ret;
}
}
return OK;
}

/*
* @description: Crop the image from the input image based on the specified area and
* paste the cropped image to the specified position of the target image
* as the output image
* @param: inputDesc specifies the description information of the input image
* @param: outputDesc specifies the description information of the output image
* @param: cropRoi specifies the cropped area
* @param: pasteRoi specifies the pasting area
* @param: withSynchronize specifies whether to execute synchronously
* @return: OK if success, other values if failure
* @attention: If the width and height of the crop area are different from those of the
* paste area, the image is scaled again
*/
int DvppCommon::ResizeWithPadding(std::shared_ptr<acldvppPicDesc> inputDesc,
std::shared_ptr<acldvppPicDesc> outputDesc,
const CropRoiConfig &cropRoi, const CropRoiConfig &pasteRoi, bool withSynchronize) {
acldvppRoiConfig *cropRoiCfg = acldvppCreateRoiConfig(cropRoi.left, cropRoi.right, cropRoi.up, cropRoi.down);
if (cropRoiCfg == nullptr) {
std::cout << "Failed to create dvpp roi config for corp area." << std::endl;
return INVALID_POINTER;
}
cropAreaConfig_.reset(cropRoiCfg, g_roiConfigDeleter);

acldvppRoiConfig *pastRoiCfg = acldvppCreateRoiConfig(pasteRoi.left, pasteRoi.right, pasteRoi.up, pasteRoi.down);
if (pastRoiCfg == nullptr) {
std::cout << "Failed to create dvpp roi config for paster area." << std::endl;
return INVALID_POINTER;
}
pasteAreaConfig_.reset(pastRoiCfg, g_roiConfigDeleter);

int ret = acldvppVpcCropAndPasteAsync(dvppChannelDesc_, inputDesc.get(), outputDesc.get(), cropAreaConfig_.get(),
pasteAreaConfig_.get(), dvppStream_);
if (ret != OK) {
// release resource.
std::cout << "Failed to crop and paste asynchronously, ret = " << ret << "." << std::endl;
return ret;
}
if (withSynchronize) {
ret = aclrtSynchronizeStream(dvppStream_);
if (ret != OK) {
std::cout << "Failed tp synchronize stream, ret = " << ret << "." << std::endl;
return ret;
}
}
return OK;
}

/*
* @description: Get crop area
* @param: input specifies the input image information
* @param: output specifies the output image information
* @param: processType specifies whether to perform proportional scaling
* @param: cropRoi is used to save the info of the crop roi area
* @return: OK if success, other values if failure
*/
void DvppCommon::GetCropRoi(std::shared_ptr<DvppDataInfo> input, std::shared_ptr<DvppDataInfo> output,
VpcProcessType processType, CropRoiConfig *cropRoi) {
// When processType is not VPC_PT_FILL, crop area is the whole input image
if (processType != VPC_PT_FILL) {
cropRoi->right = CONVERT_TO_ODD(input->width - ODD_NUM_1);
cropRoi->down = CONVERT_TO_ODD(input->height - ODD_NUM_1);
return;
}

bool widthRatioSmaller = true;
// The scaling ratio is based on the smaller ratio to ensure the smallest edge to fill the targe edge
float resizeRatio = static_cast<float>(input->width) / output->width;
if (resizeRatio > (static_cast<float>(input->height) / output->height)) {
resizeRatio = static_cast<float>(input->height) / output->height;
widthRatioSmaller = false;
}

const int halfValue = 2;
// The left and up must be even, right and down must be odd which is required by acl
if (widthRatioSmaller) {
cropRoi->left = 0;
cropRoi->right = CONVERT_TO_ODD(input->width - ODD_NUM_1);
cropRoi->up = CONVERT_TO_EVEN(static_cast<uint32_t>((input->height - output->height * resizeRatio) /
halfValue));
cropRoi->down = CONVERT_TO_ODD(input->height - cropRoi->up - ODD_NUM_1);
return;
}

cropRoi->up = 0;
cropRoi->down = CONVERT_TO_ODD(input->height - ODD_NUM_1);
cropRoi->left = CONVERT_TO_EVEN(static_cast<uint32_t>((input->width - output->width * resizeRatio) / halfValue));
cropRoi->right = CONVERT_TO_ODD(input->width - cropRoi->left - ODD_NUM_1);
return;
}

/*
* @description: Get paste area
* @param: input specifies the input image information
* @param: output specifies the output image information
* @param: processType specifies whether to perform proportional scaling
* @param: pasteRio is used to save the info of the paste area
* @return: OK if success, other values if failure
*/
void DvppCommon::GetPasteRoi(std::shared_ptr<DvppDataInfo> input, std::shared_ptr<DvppDataInfo> output,
VpcProcessType processType, CropRoiConfig *pasteRoi) {
if (processType == VPC_PT_FILL) {
pasteRoi->right = CONVERT_TO_ODD(output->width - ODD_NUM_1);
pasteRoi->down = CONVERT_TO_ODD(output->height - ODD_NUM_1);
return;
}

bool widthRatioLarger = true;
// The scaling ratio is based on the larger ratio to ensure the largest edge to fill the targe edge
float resizeRatio = static_cast<float>(input->width) / output->width;
if (resizeRatio < (static_cast<float>(input->height) / output->height)) {
resizeRatio = static_cast<float>(input->height) / output->height;
widthRatioLarger = false;
}

// Left and up is 0 when the roi paste on the upper left corner
if (processType == VPC_PT_PADDING) {
pasteRoi->right = (input->width / resizeRatio) - ODD_NUM_1;
pasteRoi->down = (input->height / resizeRatio) - ODD_NUM_1;
pasteRoi->right = CONVERT_TO_ODD(pasteRoi->right);
pasteRoi->down = CONVERT_TO_ODD(pasteRoi->down);
return;
}

const int halfValue = 2;
// Left and up is 0 when the roi paste on the middler location
if (widthRatioLarger) {
pasteRoi->left = 0;
pasteRoi->right = output->width - ODD_NUM_1;
pasteRoi->up = (output->height - (input->height / resizeRatio)) / halfValue;
pasteRoi->down = output->height - pasteRoi->up - ODD_NUM_1;
} else {
pasteRoi->up = 0;
pasteRoi->down = output->height - ODD_NUM_1;
pasteRoi->left = (output->width - (input->width / resizeRatio)) / halfValue;
pasteRoi->right = output->width - pasteRoi->left - ODD_NUM_1;
}

// The left must be even and align to 16, up must be even, right and down must be odd which is required by acl
pasteRoi->left = DVPP_ALIGN_UP(CONVERT_TO_EVEN(pasteRoi->left), VPC_WIDTH_ALIGN);
pasteRoi->right = CONVERT_TO_ODD(pasteRoi->right);
pasteRoi->up = CONVERT_TO_EVEN(pasteRoi->up);
pasteRoi->down = CONVERT_TO_ODD(pasteRoi->down);
return;
}

/*
* @description: Resize the image specified by input and save the result to member variable resizedImage_
* @param: input specifies the input image information
* @param: output specifies the output image information
* @param: withSynchronize specifies whether to execute synchronously
* @param: processType specifies whether to perform proportional scaling, default is non-proportional resize
* @return: OK if success, other values if failure
* @attention: This function can be called only when the DvppCommon object is initialized with Init
*/
int DvppCommon::CombineResizeProcess(std::shared_ptr<DvppDataInfo> input, const DvppDataInfo &output,
bool withSynchronize, VpcProcessType processType) {
int ret = CheckResizeParams(*input, output);
if (ret != OK) {
return ret;
}
// Get widthStride and heightStride for input and output image according to the format
ret = GetVpcInputStrideSize(input->widthStride, input->heightStride, input->format,
&(input->widthStride), &(input->heightStride));
if (ret != OK) {
return ret;
}

resizedImage_ = std::make_shared<DvppDataInfo>();
resizedImage_->width = output.width;
resizedImage_->height = output.height;
resizedImage_->format = output.format;
ret = GetVpcOutputStrideSize(output.width, output.height, output.format, &(resizedImage_->widthStride),
&(resizedImage_->heightStride));
if (ret != OK) {
return ret;
}
// Get output buffer size for resize output
ret = GetVpcDataSize(output.width, output.height, output.format, &(resizedImage_->dataSize));
if (ret != OK) {
return ret;
}
// Malloc buffer for output of resize module
// Need to pay attention to release of the buffer
ret = acldvppMalloc(reinterpret_cast<void **>(&(resizedImage_->data)), resizedImage_->dataSize);
if (ret != OK) {
std::cout << "Failed to malloc " << resizedImage_->dataSize << " bytes on dvpp for resize" << std::endl;
return ret;
}

aclrtMemset(resizedImage_->data, resizedImage_->dataSize, YUV_GREYER_VALUE, resizedImage_->dataSize);
resizedImage_->frameId = input->frameId;
ret = VpcResize(input, resizedImage_, withSynchronize, processType);
if (ret != OK) {
// Release the output buffer when resize failed, otherwise release it after use
RELEASE_DVPP_DATA(resizedImage_->data);
}
return ret;
}

/*
* @description: Set the description of the output image and decode
* @param: input specifies the input image information
* @param: output specifies the output image information
* @param: withSynchronize specifies whether to execute synchronously
* @return: OK if success, other values if failure
* @attention: This function can be called only when the DvppCommon object is initialized with Init
*/
int DvppCommon::JpegDecode(std::shared_ptr<DvppDataInfo> input,
std::shared_ptr<DvppDataInfo> output,
bool withSynchronize) {
acldvppPicDesc *outputDesc = acldvppCreatePicDesc();
decodeOutputDesc_.reset(outputDesc, g_picDescDeleter);

int ret = SetDvppPicDescData(output, decodeOutputDesc_);
if (ret != OK) {
return ret;
}

ret = acldvppJpegDecodeAsync(dvppChannelDesc_, input->data, input->dataSize, decodeOutputDesc_.get(), dvppStream_);
if (ret != OK) {
std::cout << "Failed to decode jpeg, ret = " << ret << "." << std::endl;
return ret;
}
if (withSynchronize) {
ret = aclrtSynchronizeStream(dvppStream_);
if (ret != OK) {
std::cout << "Failed to synchronize stream, ret = " << ret << "." << std::endl;
return DECODE_FAIL;
}
}
return OK;
}

/*
* @description: Get the aligned width and height of the image after decoding
* @param: width specifies the width before alignment
* @param: height specifies the height before alignment
* @param: widthStride is used to save the width after alignment
* @param: heightStride is used to save the height after alignment
* @return: OK if success, other values if failure
*/
void DvppCommon::GetJpegDecodeStrideSize(uint32_t width, uint32_t height,
uint32_t *widthStride, uint32_t *heightStride) {
*widthStride = DVPP_ALIGN_UP(width, JPEGD_STRIDE_WIDTH);
*heightStride = DVPP_ALIGN_UP(height, JPEGD_STRIDE_HEIGHT);
}

/*
* @description: Get picture width and height and number of channels from image data
* @param: data specifies the memory to store the image data
* @param: dataSize specifies the size of the image data
* @param: width is used to save the image width
* @param: height is used to save the image height
* @param: components is used to save the number of channels
* @return: OK if success, other values if failure
*/
int DvppCommon::GetJpegImageInfo(const void *data, uint32_t dataSize, uint32_t *width, uint32_t *height,
int32_t *components) {
uint32_t widthTmp;
uint32_t heightTmp;
int32_t componentsTmp;
int ret = acldvppJpegGetImageInfo(data, dataSize, &widthTmp, &heightTmp, &componentsTmp);
if (ret != OK) {
std::cout << "Failed to get image info of jpeg, ret = " << ret << "." << std::endl;
return ret;
}
if (widthTmp > MAX_JPEGD_WIDTH || widthTmp < MIN_JPEGD_WIDTH) {
std::cout << "Input width is invalid, not in [" << MIN_JPEGD_WIDTH << ", "
<< MAX_JPEGD_WIDTH << "]." << std::endl;
return INVALID_PARAM;
}
if (heightTmp > MAX_JPEGD_HEIGHT || heightTmp < MIN_JPEGD_HEIGHT) {
std::cout << "Input height is invalid, not in [" << MIN_JPEGD_HEIGHT << ", "
<< MAX_JPEGD_HEIGHT << "]." << std::endl;
return INVALID_PARAM;
}
*width = widthTmp;
*height = heightTmp;
*components = componentsTmp;
return OK;
}

/*
* @description: Get the size of the buffer for storing decoded images based on the image data, size, and format
* @param: data specifies the memory to store the image data
* @param: dataSize specifies the size of the image data
* @param: format specifies the image format
* @param: decSize is used to store the result size
* @return: OK if success, other values if failure
*/
int DvppCommon::GetJpegDecodeDataSize(const void *data, uint32_t dataSize, acldvppPixelFormat format,
uint32_t *decSize) {
uint32_t outputSize;
int ret = acldvppJpegPredictDecSize(data, dataSize, format, &outputSize);
if (ret != OK) {
std::cout << "Failed to predict decode size of jpeg image, ret = " << ret << "." << std::endl;
return ret;
}
*decSize = outputSize;
return OK;
}

/*
* @description: Decode the image specified by imageInfo and save the result to member variable decodedImage_
* @param: imageInfo specifies image information
* @param: format specifies the image format
* @param: withSynchronize specifies whether to execute synchronously
* @return: OK if success, other values if failure
* @attention: This function can be called only when the DvppCommon object is initialized with Init
*/
int DvppCommon::CombineJpegdProcess(const RawData& imageInfo, acldvppPixelFormat format, bool withSynchronize) {
int32_t components;
inputImage_ = std::make_shared<DvppDataInfo>();
inputImage_->format = format;
int ret = GetJpegImageInfo(imageInfo.data.get(), imageInfo.lenOfByte, &(inputImage_->width), &(inputImage_->height),
&components);
if (ret != OK) {
std::cout << "Failed to get input image info, ret = " << ret << "." << std::endl;
return ret;
}

// Get the buffer size of decode output according to the input data and output format
uint32_t outBuffSize;
ret = GetJpegDecodeDataSize(imageInfo.data.get(), imageInfo.lenOfByte, format, &outBuffSize);
if (ret != OK) {
std::cout << "Failed to get size of decode output buffer, ret = " << ret << "." << std::endl;
return ret;
}

// In TransferImageH2D function, device buffer will be allocated to store the input image
// Need to pay attention to release of the buffer
ret = TransferImageH2D(imageInfo, inputImage_);
if (ret != OK) {
return ret;
}

decodedImage_ = std::make_shared<DvppDataInfo>();
decodedImage_->format = format;
decodedImage_->width = inputImage_->width;
decodedImage_->height = inputImage_->height;
GetJpegDecodeStrideSize(inputImage_->width, inputImage_->height, &(decodedImage_->widthStride),
&(decodedImage_->heightStride));
decodedImage_->dataSize = outBuffSize;
// Need to pay attention to release of the buffer
ret = acldvppMalloc(reinterpret_cast<void **>(&decodedImage_->data), decodedImage_->dataSize);
if (ret != OK) {
std::cout << "Failed to malloc memory on dvpp, ret = " << ret << "." << std::endl;
RELEASE_DVPP_DATA(inputImage_->data);
return ret;
}

ret = JpegDecode(inputImage_, decodedImage_, withSynchronize);
if (ret != OK) {
RELEASE_DVPP_DATA(inputImage_->data);
inputImage_->data = nullptr;
RELEASE_DVPP_DATA(decodedImage_->data);
decodedImage_->data = nullptr;
return ret;
}

return OK;
}

/*
* @description: Transfer data from host to device
* @param: imageInfo specifies the image data on the host
* @param: jpegInput is used to save the buffer and its size which is allocate on the device
* @return: OK if success, other values if failure
*/
int DvppCommon::TransferImageH2D(const RawData& imageInfo, const std::shared_ptr<DvppDataInfo>& jpegInput) {
if (imageInfo.lenOfByte == 0) {
std::cout << "The input buffer size on host should not be empty." << std::endl;
return INVALID_PARAM;
}

uint8_t* inDevBuff = nullptr;
int ret = acldvppMalloc(reinterpret_cast<void **>(&inDevBuff), imageInfo.lenOfByte);
if (ret != OK) {
std::cout << "Failed to malloc " << imageInfo.lenOfByte << " bytes on dvpp, ret = " << ret << "." << std::endl;
return ret;
}

// Copy the image data from host to device
ret = aclrtMemcpyAsync(inDevBuff, imageInfo.lenOfByte, imageInfo.data.get(), imageInfo.lenOfByte,
ACL_MEMCPY_HOST_TO_DEVICE, dvppStream_);
if (ret != OK) {
std::cout << "Failed to copy " << imageInfo.lenOfByte << " bytes from host to device" << std::endl;
RELEASE_DVPP_DATA(inDevBuff);
return ret;
}
// Attention: We must call the aclrtSynchronizeStream to ensure the task of memory replication has been completed
// after calling aclrtMemcpyAsync
ret = aclrtSynchronizeStream(dvppStream_);
if (ret != OK) {
std::cout << "Failed to synchronize stream, ret = " << ret << "." << std::endl;
RELEASE_DVPP_DATA(inDevBuff);
return ret;
}
jpegInput->data = inDevBuff;
jpegInput->dataSize = imageInfo.lenOfByte;
return OK;
}

std::shared_ptr<DvppDataInfo> DvppCommon::GetInputImage() {
return inputImage_;
}

std::shared_ptr<DvppDataInfo> DvppCommon::GetDecodedImage() {
return decodedImage_;
}

std::shared_ptr<DvppDataInfo> DvppCommon::GetResizedImage() {
return resizedImage_;
}

DvppCommon::~DvppCommon() {}

+ 0
- 226
model_zoo/official/cv/faster_rcnn/ascend310_infer/src/ModelProcess.cpp View File

@@ -1,226 +0,0 @@
/*
* Copyright(C) 2020. Huawei Technologies Co.,Ltd. All rights reserved.
*
* 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 <sys/time.h>
#include <fstream>
#include "../inc/ModelProcess.h"

ModelProcess::ModelProcess(const int deviceId) {
deviceId_ = deviceId;
}

ModelProcess::ModelProcess() {}

ModelProcess::~ModelProcess() {
if (!isDeInit_) {
DeInit();
}
}

void ModelProcess::DestroyDataset(aclmdlDataset *dataset) {
// Just release the DataBuffer object and DataSet object, remain the buffer, because it is managerd by user
if (dataset != nullptr) {
for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(dataset); i++) {
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(dataset, i);
if (dataBuffer != nullptr) {
aclDestroyDataBuffer(dataBuffer);
dataBuffer = nullptr;
}
}
aclmdlDestroyDataset(dataset);
}
}

aclmdlDesc *ModelProcess::GetModelDesc() {
return modelDesc_.get();
}

int ModelProcess::ModelInference(const std::vector<void *> &inputBufs,
const std::vector<size_t> &inputSizes,
const std::vector<void *> &ouputBufs,
const std::vector<size_t> &outputSizes,
std::map<double, double> *costTime_map) {
std::cout << "ModelProcess:Begin to inference." << std::endl;
aclmdlDataset *input = nullptr;
input = CreateAndFillDataset(inputBufs, inputSizes);
if (input == nullptr) {
return INVALID_POINTER;
}
int ret;

aclmdlDataset *output = nullptr;
output = CreateAndFillDataset(ouputBufs, outputSizes);
if (output == nullptr) {
DestroyDataset(input);
input = nullptr;
return INVALID_POINTER;
}
struct timeval start;
struct timeval end;
double startTime_ms;
double endTime_ms;
mtx_.lock();
gettimeofday(&start, NULL);
ret = aclmdlExecute(modelId_, input, output);
gettimeofday(&end, NULL);
startTime_ms = (1.0 * start.tv_sec * 1000000 + start.tv_usec) / 1000;
endTime_ms = (1.0 * end.tv_sec * 1000000 + end.tv_usec) / 1000;
costTime_map->insert(std::pair<double, double>(startTime_ms, endTime_ms));
mtx_.unlock();
if (ret != OK) {
std::cout << "aclmdlExecute failed, ret[" << ret << "]." << std::endl;
return ret;
}

DestroyDataset(input);
DestroyDataset(output);
return OK;
}

int ModelProcess::DeInit() {
isDeInit_ = true;
int ret = aclmdlUnload(modelId_);
if (ret != OK) {
std::cout << "aclmdlUnload failed, ret["<< ret << "]." << std::endl;
return ret;
}

if (modelDevPtr_ != nullptr) {
ret = aclrtFree(modelDevPtr_);
if (ret != OK) {
std::cout << "aclrtFree failed, ret[" << ret << "]." << std::endl;
return ret;
}
modelDevPtr_ = nullptr;
}
if (weightDevPtr_ != nullptr) {
ret = aclrtFree(weightDevPtr_);
if (ret != OK) {
std::cout << "aclrtFree failed, ret[" << ret << "]." << std::endl;
return ret;
}
weightDevPtr_ = nullptr;
}

return OK;
}
/**
* Read a binary file, store the data into a uint8_t array
*
* @param fileName the file for reading
* @param buffShared a shared pointer to a uint8_t array for storing file
* @param buffLength the length of the array
* @return OK if create success, error code otherwise
*/
int ModelProcess::ReadBinaryFile(const std::string &fileName, uint8_t **buffShared, int *buffLength) {
std::ifstream inFile(fileName, std::ios::in | std::ios::binary);
if (!inFile) {
std::cout << "FaceFeatureLib: read file " << fileName << " fail." <<std::endl;
return READ_FILE_FAIL;
}

inFile.seekg(0, inFile.end);
*buffLength = inFile.tellg();
inFile.seekg(0, inFile.beg);

uint8_t *tempShared = reinterpret_cast<uint8_t *>(malloc(*buffLength));
inFile.read(reinterpret_cast<char *>(tempShared), *buffLength);
inFile.close();
*buffShared = tempShared;

std::cout << "read file: fileName=" << fileName << ", size=" << *buffLength << "." << std::endl;

return OK;
}

int ModelProcess::Init(const std::string &modelPath) {
std::cout << "ModelProcess:Begin to init instance." << std::endl;
int modelSize = 0;
uint8_t *modelData = nullptr;
int ret = ReadBinaryFile(modelPath, &modelData, &modelSize);
if (ret != OK) {
std::cout << "read model file failed, ret[" << ret << "]." << std::endl;
return ret;
}
ret = aclmdlQuerySizeFromMem(modelData, modelSize, &modelDevPtrSize_, &weightDevPtrSize_);
if (ret != OK) {
std::cout << "aclmdlQuerySizeFromMem failed, ret[" << ret << "]." << std::endl;
return ret;
}
std::cout << "modelDevPtrSize_[" << modelDevPtrSize_ << "]" << std::endl;
std::cout << " weightDevPtrSize_[" << weightDevPtrSize_ << "]." << std::endl;

ret = aclrtMalloc(&modelDevPtr_, modelDevPtrSize_, ACL_MEM_MALLOC_HUGE_FIRST);
if (ret != OK) {
std::cout << "aclrtMalloc dev_ptr failed, ret[" << ret << "]." << std::endl;
return ret;
}
ret = aclrtMalloc(&weightDevPtr_, weightDevPtrSize_, ACL_MEM_MALLOC_HUGE_FIRST);
if (ret != OK) {
std::cout << "aclrtMalloc weight_ptr failed, ret[" << ret << "] " << std::endl;
return ret;
}
ret = aclmdlLoadFromMemWithMem(modelData, modelSize, &modelId_, modelDevPtr_, modelDevPtrSize_,
weightDevPtr_, weightDevPtrSize_);
if (ret != OK) {
std::cout << "aclmdlLoadFromMemWithMem failed, ret[" << ret << "]." << std::endl;
return ret;
}
ret = aclrtGetCurrentContext(&contextModel_);
if (ret != OK) {
std::cout << "aclrtMalloc weight_ptr failed, ret[" << ret << "]." << std::endl;
return ret;
}

aclmdlDesc *modelDesc = aclmdlCreateDesc();
if (modelDesc == nullptr) {
std::cout << "aclmdlCreateDesc failed." << std::endl;
return ret;
}
ret = aclmdlGetDesc(modelDesc, modelId_);
if (ret != OK) {
std::cout << "aclmdlGetDesc ret fail, ret:" << ret << "." << std::endl;
return ret;
}
modelDesc_.reset(modelDesc, aclmdlDestroyDesc);
free(modelData);
return OK;
}

aclmdlDataset *ModelProcess::CreateAndFillDataset(const std::vector<void *> &bufs, const std::vector<size_t> &sizes) {
aclmdlDataset *dataset = aclmdlCreateDataset();
if (dataset == nullptr) {
std::cout << "ACL_ModelInputCreate failed." << std::endl;
return nullptr;
}

for (size_t i = 0; i < bufs.size(); ++i) {
aclDataBuffer *data = aclCreateDataBuffer(bufs[i], sizes[i]);
if (data == nullptr) {
DestroyDataset(dataset);
std::cout << "aclCreateDataBuffer failed." << std::endl;
return nullptr;
}

int ret = aclmdlAddDatasetBuffer(dataset, data);
if (ret != OK) {
DestroyDataset(dataset);
std::cout << "ACL_ModelInputDataAdd failed, ret[" << ret << "]." << std::endl;
return nullptr;
}
}
return dataset;
}

+ 0
- 56
model_zoo/official/cv/faster_rcnn/ascend310_infer/src/build.sh View File

@@ -1,56 +0,0 @@
#!/bin/bash
# Copyright 2020 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
path_cur=$(cd "`dirname $0`" || exit; pwd)
build_type="Release"

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 -DCMAKE_BUILD_TYPE=$build_type ..
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

+ 236
- 0
model_zoo/official/cv/faster_rcnn/ascend310_infer/src/main.cc View File

@@ -0,0 +1,236 @@
/**
* 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 <sys/time.h>
#include <gflags/gflags.h>
#include <dirent.h>
#include <iostream>
#include <string>
#include <algorithm>
#include <iosfwd>
#include <vector>
#include <fstream>
#include <sstream>

#include "include/api/context.h"
#include "include/api/model.h"
#include "include/api/types.h"
#include "include/api/serialization.h"
#include "include/minddata/dataset/include/vision.h"
#include "include/minddata/dataset/include/execute.h"
#include "../inc/utils.h"

using mindspore::Context;
using mindspore::Serialization;
using mindspore::Model;
using mindspore::Status;
using mindspore::ModelType;
using mindspore::GraphCell;
using mindspore::kSuccess;
using mindspore::MSTensor;
using mindspore::DataType;
using mindspore::dataset::Execute;
using mindspore::dataset::TensorTransform;
using mindspore::dataset::vision::Resize;
using mindspore::dataset::vision::Pad;
using mindspore::dataset::vision::HWC2CHW;
using mindspore::dataset::vision::Normalize;
using mindspore::dataset::vision::SwapRedBlue;
using mindspore::dataset::vision::Decode;


DEFINE_string(mindir_path, "", "mindir path");
DEFINE_string(dataset_path, ".", "dataset path");
DEFINE_int32(device_id, 0, "device id");

const int IMAGEWIDTH = 1280;
const int IMAGEHEIGHT = 768;

int PadImage(const MSTensor &input, MSTensor *output) {
std::shared_ptr<TensorTransform> normalize(new Normalize({103.53, 116.28, 123.675},
{57.375, 57.120, 58.395}));
Execute composeNormalize({normalize});
std::vector<int64_t> shape = input.Shape();
auto imgResize = MSTensor();
auto imgPad = MSTensor();

float widthScale, heightScale;
widthScale = static_cast<float>(IMAGEWIDTH) / shape[1];
heightScale = static_cast<float>(IMAGEHEIGHT) / shape[0];
Status ret;
if (widthScale < heightScale) {
int heightSize = shape[0]*widthScale;
std::shared_ptr<TensorTransform> resize(new Resize({heightSize, IMAGEWIDTH}));
Execute composeResizeWidth({resize});
ret = composeResizeWidth(input, &imgResize);
if (ret != kSuccess) {
std::cout << "ERROR: Resize Width failed." << std::endl;
return 1;
}

int paddingSize = IMAGEHEIGHT - heightSize;
std::shared_ptr<TensorTransform> pad(new Pad({0, 0, 0, paddingSize}));
Execute composePad({pad});
ret = composePad(imgResize, &imgPad);
if (ret != kSuccess) {
std::cout << "ERROR: Height Pad failed." << std::endl;
return 1;
}

ret = composeNormalize(imgPad, output);
if (ret != kSuccess) {
std::cout << "ERROR: Normalize failed." << std::endl;
return 1;
}
} else {
int widthSize = shape[1]*heightScale;
std::shared_ptr<TensorTransform> resize(new Resize({IMAGEHEIGHT, widthSize}));
Execute composeResizeHeight({resize});
ret = composeResizeHeight(input, &imgResize);
if (ret != kSuccess) {
std::cout << "ERROR: Resize Height failed." << std::endl;
return 1;
}

int paddingSize = IMAGEWIDTH - widthSize;
std::shared_ptr<TensorTransform> pad(new Pad({0, 0, paddingSize, 0}));
Execute composePad({pad});
ret = composePad(imgResize, &imgPad);
if (ret != kSuccess) {
std::cout << "ERROR: Width Pad failed." << std::endl;
return 1;
}

ret = composeNormalize(imgPad, output);
if (ret != kSuccess) {
std::cout << "ERROR: Normalize failed." << std::endl;
return 1;
}
}
return 0;
}

int main(int argc, char **argv) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
if (RealPath(FLAGS_mindir_path).empty()) {
std::cout << "Invalid mindir" << std::endl;
return 1;
}

auto context = std::make_shared<Context>();
auto ascend310 = std::make_shared<mindspore::Ascend310DeviceInfo>();
ascend310->SetDeviceID(FLAGS_device_id);
ascend310->SetPrecisionMode("allow_fp32_to_fp16");
context->MutableDeviceInfo().push_back(ascend310);
mindspore::Graph graph;
Serialization::Load(FLAGS_mindir_path, ModelType::kMindIR, &graph);

Model model;
Status ret = model.Build(GraphCell(graph), context);
if (ret != kSuccess) {
std::cout << "ERROR: Build failed." << std::endl;
return 1;
}
std::vector<MSTensor> model_inputs = model.GetInputs();
if (model_inputs.empty()) {
std::cout << "Invalid model, inputs is empty." << std::endl;
return 1;
}

auto all_files = GetAllFiles(FLAGS_dataset_path);
if (all_files.empty()) {
std::cout << "ERROR: no input data." << std::endl;
return 1;
}

std::map<double, double> costTime_map;
size_t size = all_files.size();
std::shared_ptr<TensorTransform> decode(new Decode());
Execute composeDecode({decode});
std::shared_ptr<TensorTransform> hwc2chw(new HWC2CHW());
Execute composeTranspose({hwc2chw});

for (size_t i = 0; i < size; ++i) {
struct timeval start = {0};
struct timeval end = {0};
double startTimeMs;
double endTimeMs;
std::vector<MSTensor> inputs;
std::vector<MSTensor> outputs;
std::cout << "Start predict input files:" << all_files[i] << std::endl;
auto imgDecode = MSTensor();
auto image = ReadFileToTensor(all_files[i]);
ret = composeDecode(image, &imgDecode);
if (ret != kSuccess) {
std::cout << "ERROR: Decode failed." << std::endl;
return 1;
}
auto imgPad = MSTensor();
PadImage(imgDecode, &imgPad);
auto img = MSTensor();
composeTranspose(imgPad, &img);

std::vector<int64_t> shape = imgDecode.Shape();

float widthScale = static_cast<float>(IMAGEWIDTH) / shape[1];
float heightScale = static_cast<float>(IMAGEHEIGHT) / shape[0];
float resizeScale = widthScale < heightScale ? widthScale : heightScale;

float imgInfo[4];
imgInfo[0] = shape[0];
imgInfo[1] = shape[1];
imgInfo[2] = resizeScale;
imgInfo[3] = resizeScale;

MSTensor imgMeta("imgMeta", DataType::kNumberTypeFloat32, {static_cast<int64_t>(4)}, imgInfo, 16);

inputs.emplace_back(model_inputs[0].Name(), model_inputs[0].DataType(), model_inputs[0].Shape(),
img.Data().get(), img.DataSize());
inputs.emplace_back(model_inputs[1].Name(), model_inputs[1].DataType(), model_inputs[1].Shape(),
imgMeta.Data().get(), imgMeta.DataSize());

gettimeofday(&start, nullptr);
ret = model.Predict(inputs, &outputs);
gettimeofday(&end, nullptr);
if (ret != kSuccess) {
std::cout << "Predict " << all_files[i] << " failed." << std::endl;
return 1;
}
startTimeMs = (1.0 * start.tv_sec * 1000000 + start.tv_usec) / 1000;
endTimeMs = (1.0 * end.tv_sec * 1000000 + end.tv_usec) / 1000;
costTime_map.insert(std::pair<double, double>(startTimeMs, endTimeMs));
WriteResult(all_files[i], outputs);
}
double average = 0.0;
int inferCount = 0;

for (auto iter = costTime_map.begin(); iter != costTime_map.end(); iter++) {
double diff = 0.0;
diff = iter->second - iter->first;
average += diff;
inferCount++;
}
average = average / inferCount;
std::stringstream timeCost;
timeCost << "NN inference cost average time: "<< average << " ms of infer_count " << inferCount << std::endl;
std::cout << "NN inference cost average time: "<< average << "ms of infer_count " << inferCount << std::endl;

std::string fileName = "./time_Result" + std::string("/test_perform_static.txt");
std::ofstream fileStream(fileName.c_str(), std::ios::trunc);
fileStream << timeCost.str();
fileStream.close();
costTime_map.clear();
return 0;
}

+ 0
- 136
model_zoo/official/cv/faster_rcnn/ascend310_infer/src/main.cpp View File

@@ -1,136 +0,0 @@
/*
* Copyright (c) 2020.Huawei Technologies Co., Ltd. All rights reserved.
* 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 <dirent.h>
#include <sys/stat.h>
#include <gflags/gflags.h>
#include <unistd.h>
#include <cstring>
#include <fstream>
#include <sstream>
#include "../inc/AclProcess.h"
#include "../inc/CommonDataType.h"

DEFINE_string(om_path, "./fasterrcnn.om", "om model path.");
DEFINE_string(data_path, "./test.jpg", "om model path.");
DEFINE_int32(width, 1280, "width");
DEFINE_int32(height, 768, "height");
DEFINE_int32(device_id, 0, "height");

static bool is_file(const std::string &filename) {
struct stat buffer;
return (stat(filename.c_str(), &buffer) == 0 && S_ISREG(buffer.st_mode));
}

static bool is_dir(const std::string &filefodler) {
struct stat buffer;
return (stat(filefodler.c_str(), &buffer) == 0 && S_ISDIR(buffer.st_mode));
}
/*
* @description Initialize and run AclProcess module
* @param resourceInfo resource info of deviceIds, model info, single Operator Path, etc
* @param file the absolute path of input file
* @return int int code
*/
int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
std::cout << "OM File Path :" << FLAGS_om_path << std::endl;
std::cout << "data Path :" << FLAGS_data_path << std::endl;
std::cout << "width :" << FLAGS_width << std::endl;
std::cout << "height :" << FLAGS_height << std::endl;
std::cout << "deviceId :" << FLAGS_device_id << std::endl;

char omAbsPath[PATH_MAX];
if (realpath(FLAGS_om_path.c_str(), omAbsPath) == nullptr) {
std::cout << "Failed to get the om real path." << std::endl;
return INVALID_PARAM;
}

if (access(omAbsPath, R_OK) == -1) {
std::cout << "ModelPath " << omAbsPath << " doesn't exist or read failed." << std::endl;
return INVALID_PARAM;
}

char dataAbsPath[PATH_MAX];
if (realpath(FLAGS_data_path.c_str(), dataAbsPath) == nullptr) {
std::cout << "Failed to get the data real path." << std::endl;
return INVALID_PARAM;
}
if (access(dataAbsPath, R_OK) == -1) {
std::cout << "data paeh " << dataAbsPath << " doesn't exist or read failed." << std::endl;
return INVALID_PARAM;
}

std::map<double, double> costTime_map;
AclProcess aclProcess(FLAGS_device_id, FLAGS_om_path, FLAGS_width, FLAGS_height);
int ret = aclProcess.InitResource();
if (ret != OK) {
aclProcess.Release();
return ret;
}
if (is_file(FLAGS_data_path)) {
ret = aclProcess.Process(FLAGS_data_path, &costTime_map);
if (ret != OK) {
std::cout << "model process failed, errno = " << ret << std::endl;
aclProcess.Release();
return ret;
}
} else if (is_dir(FLAGS_data_path)) {
struct dirent *filename;
DIR *dir;
dir = opendir(FLAGS_data_path.c_str());
if (dir == nullptr) {
aclProcess.Release();
return ERROR;
}

while ((filename = readdir(dir)) != nullptr) {
if (strcmp(filename->d_name, ".") == 0 || strcmp(filename->d_name, "..") == 0) {
continue;
}
std::string wholePath = FLAGS_data_path + "/" + filename->d_name;
ret = aclProcess.Process(wholePath, &costTime_map);
if (ret != OK) {
std::cout << "model process failed, errno = " << ret << std::endl;
aclProcess.Release();
return ret;
}
}
} else {
std::cout << " input image path error" << std::endl;
}

double average = 0.0;
int infer_cnt = 0;
for (auto iter = costTime_map.begin(); iter != costTime_map.end(); iter++) {
double diff = 0.0;
diff = iter->second - iter->first;
average += diff;
infer_cnt++;
}
average = average / infer_cnt;

std::stringstream timeCost;
timeCost << "NN inference cost average time: "<< average << " ms of infer_count " << infer_cnt << std::endl;
std::cout << "NN inference cost average time: "<< average << "ms of infer_count " << infer_cnt << std::endl;

std::string file_name = "./time_Result" + std::string("/test_perform_static.txt");
std::ofstream file_stream(file_name.c_str(), std::ios::trunc);
file_stream << timeCost.str();
file_stream.close();
costTime_map.clear();

aclProcess.Release();
return OK;
}

+ 129
- 0
model_zoo/official/cv/faster_rcnn/ascend310_infer/src/utils.cc View File

@@ -0,0 +1,129 @@
/**
* 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 <fstream>
#include <algorithm>
#include <iostream>
#include "../inc/utils.h"

using mindspore::MSTensor;
using mindspore::DataType;

std::vector<std::string> GetAllFiles(std::string_view dirName) {
struct dirent *filename;
DIR *dir = OpenDir(dirName);
if (dir == nullptr) {
return {};
}
std::vector<std::string> res;
while ((filename = readdir(dir)) != nullptr) {
std::string dName = std::string(filename->d_name);
if (dName == "." || dName == ".." || filename->d_type != DT_REG) {
continue;
}
res.emplace_back(std::string(dirName) + "/" + filename->d_name);
}
std::sort(res.begin(), res.end());
for (auto &f : res) {
std::cout << "image file: " << f << std::endl;
}
return res;
}

int WriteResult(const std::string& imageFile, const std::vector<MSTensor> &outputs) {
std::string homePath = "./result_Files";
for (size_t i = 0; i < outputs.size(); ++i) {
size_t outputSize;
std::shared_ptr<const void> netOutput;
netOutput = outputs[i].Data();
outputSize = outputs[i].DataSize();
int pos = imageFile.rfind('/');
std::string fileName(imageFile, pos + 1);
fileName.replace(fileName.find('.'), fileName.size() - fileName.find('.'), '_' + std::to_string(i) + ".bin");
std::string outFileName = homePath + "/" + fileName;
FILE * outputFile = fopen(outFileName.c_str(), "wb");
fwrite(netOutput.get(), outputSize, sizeof(char), outputFile);
fclose(outputFile);
outputFile = nullptr;
}
return 0;
}

MSTensor ReadFileToTensor(const std::string &file) {
if (file.empty()) {
std::cout << "Pointer file is nullptr" << std::endl;
return MSTensor();
}

std::ifstream ifs(file);
if (!ifs.good()) {
std::cout << "File: " << file << " is not exist" << std::endl;
return MSTensor();
}

if (!ifs.is_open()) {
std::cout << "File: " << file << "open failed" << std::endl;
return MSTensor();
}

ifs.seekg(0, std::ios::end);
size_t size = ifs.tellg();
MSTensor buffer(file, mindspore::DataType::kNumberTypeUInt8, {static_cast<int64_t>(size)}, nullptr, size);

ifs.seekg(0, std::ios::beg);
ifs.read(reinterpret_cast<char *>(buffer.MutableData()), size);
ifs.close();

return buffer;
}


DIR *OpenDir(std::string_view dirName) {
if (dirName.empty()) {
std::cout << " dirName is null ! " << std::endl;
return nullptr;
}
std::string realPath = RealPath(dirName);
struct stat s;
lstat(realPath.c_str(), &s);
if (!S_ISDIR(s.st_mode)) {
std::cout << "dirName is not a valid directory !" << std::endl;
return nullptr;
}
DIR *dir;
dir = opendir(realPath.c_str());
if (dir == nullptr) {
std::cout << "Can not open dir " << dirName << std::endl;
return nullptr;
}
std::cout << "Successfully opened the dir " << dirName << std::endl;
return dir;
}

std::string RealPath(std::string_view path) {
char realPathMem[PATH_MAX] = {0};
char *realPathRet = nullptr;
realPathRet = realpath(path.data(), realPathMem);

if (realPathRet == nullptr) {
std::cout << "File: " << path << " is not exist.";
return "";
}

std::string realPath(realPathMem);
std::cout << path << " realpath is: " << realPath << std::endl;
return realPath;
}

+ 8
- 7
model_zoo/official/cv/faster_rcnn/postprocess.py View File

@@ -13,6 +13,7 @@
# limitations under the License. # limitations under the License.
# ============================================================================ # ============================================================================
"""post process for 310 inference""" """post process for 310 inference"""
import os
import argparse import argparse
import numpy as np import numpy as np
from pycocotools.coco import COCO from pycocotools.coco import COCO
@@ -25,13 +26,13 @@ dst_height = 768


parser = argparse.ArgumentParser(description="FasterRcnn inference") parser = argparse.ArgumentParser(description="FasterRcnn inference")
parser.add_argument("--ann_file", type=str, required=True, help="ann file.") parser.add_argument("--ann_file", type=str, required=True, help="ann file.")
parser.add_argument("--img_path", type=str, required=True, help="image file path.")
parser.add_argument("--result_path", type=str, required=True, help="result file path.")
args = parser.parse_args() args = parser.parse_args()


def get_eval_result(ann_file):
def get_eval_result(ann_file, result_path):
""" get evaluation result of faster rcnn""" """ get evaluation result of faster rcnn"""
max_num = 128 max_num = 128
result_path = "./result_Files/"
result_path = result_path


outputs = [] outputs = []


@@ -41,9 +42,9 @@ def get_eval_result(ann_file):
for img_id in img_ids: for img_id in img_ids:
file_id = str(img_id).zfill(12) file_id = str(img_id).zfill(12)


bbox_result_file = result_path + file_id + "_0.bin"
label_result_file = result_path + file_id + "_1.bin"
mask_result_file = result_path + file_id + "_2.bin"
bbox_result_file = os.path.join(result_path, file_id + "_0.bin")
label_result_file = os.path.join(result_path, file_id + "_1.bin")
mask_result_file = os.path.join(result_path, file_id + "_2.bin")


all_bbox = np.fromfile(bbox_result_file, dtype=np.float16).reshape(80000, 5) all_bbox = np.fromfile(bbox_result_file, dtype=np.float16).reshape(80000, 5)
all_label = np.fromfile(label_result_file, dtype=np.int32).reshape(80000, 1) all_label = np.fromfile(label_result_file, dtype=np.int32).reshape(80000, 1)
@@ -70,4 +71,4 @@ def get_eval_result(ann_file):
coco_eval(result_files, eval_types, dataset_coco, single_result=False) coco_eval(result_files, eval_types, dataset_coco, single_result=False)


if __name__ == '__main__': if __name__ == '__main__':
get_eval_result(args.ann_file)
get_eval_result(args.ann_file, args.result_path)

+ 20
- 35
model_zoo/official/cv/faster_rcnn/scripts/run_infer_310.sh View File

@@ -14,61 +14,51 @@
# limitations under the License. # limitations under the License.
# ============================================================================ # ============================================================================


if [[ $# -lt 3 || $# -gt 4 ]]; then
echo "Usage: sh run_infer_310.sh [AIR_PATH] [DATA_PATH] [ANN_FILE_PATH] [DEVICE_ID]
if [[ $# -lt 3 || $# -gt 4 ]]; then
echo "Usage: bash run_infer_310.sh [MINDIR_PATH] [DATA_PATH] [ANN_FILE] [DEVICE_ID]
DEVICE_ID is optional, it can be set by environment variable device_id, otherwise the value is zero" DEVICE_ID is optional, it can be set by environment variable device_id, otherwise the value is zero"
exit 1 exit 1
fi fi


get_real_path(){ get_real_path(){
if [ "${1:0:1}" == "/" ]; then
echo "$1"
else
echo "$(realpath -m $PWD/$1)"
fi
if [ "${1:0:1}" == "/" ]; then
echo "$1"
else
echo "$(realpath -m $PWD/$1)"
fi
} }
model=$(get_real_path $1) model=$(get_real_path $1)
data_path=$(get_real_path $2) data_path=$(get_real_path $2)
ann_file=$(get_real_path $3) ann_file=$(get_real_path $3)

device_id=0
if [ $# == 4 ]; then if [ $# == 4 ]; then
device_id=$4 device_id=$4
elif [ $# == 3 ]; then
# shellcheck disable=SC2153 #DEVICE_ID is en
if [ -z $device_id ]; then
device_id=0
else
device_id=$device_id
fi
fi fi


echo $model
echo $data_path
echo $ann_file
echo $device_id
echo "mindir name: "$model
echo "dataset path: "$data_path
echo "ann_file: " $ann_file
echo "device id: "$device_id


export ASCEND_HOME=/usr/local/Ascend/ export ASCEND_HOME=/usr/local/Ascend/
if [ -d ${ASCEND_HOME}/ascend-toolkit ]; then 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 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/acllib/lib64:$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/lib64:$ASCEND_HOME/driver/lib64:$ASCEND_HOME/add-ones:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/usr/local/lib:$ASCEND_HOME/ascend-toolkit/latest/atc/lib64:$ASCEND_HOME/ascend-toolkit/latest/acllib/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 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 PYTHONPATH=${TBE_IMPL_PATH}:$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/python/site-packages:$PYTHONPATH
export ASCEND_OPP_PATH=$ASCEND_HOME/ascend-toolkit/latest/opp export ASCEND_OPP_PATH=$ASCEND_HOME/ascend-toolkit/latest/opp
else else
export PATH=$ASCEND_HOME/atc/ccec_compiler/bin:$ASCEND_HOME/atc/bin:$PATH 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-ones:$LD_LIBRARY_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 PYTHONPATH=$ASCEND_HOME/atc/python/site-packages:$PYTHONPATH
export ASCEND_OPP_PATH=$ASCEND_HOME/opp export ASCEND_OPP_PATH=$ASCEND_HOME/opp
fi fi


function air_to_om()
{
atc --input_format=NCHW --framework=1 --model=$model --input_shape="x:1, 3, 768, 1280; im_info: 1, 4" --output=fasterrcnn --insert_op_conf=../src/aipp.cfg --precision_mode=allow_fp32_to_fp16 --soc_version=Ascend310 &> atc.log
}

function compile_app() function compile_app()
{ {
cd ../ascend310_infer/src || exit
sh build.sh &> build.log
cd ../ascend310_infer || exit
bash build.sh &> build.log
cd - || exit cd - || exit
} }


@@ -77,24 +67,19 @@ function infer()
if [ -d result_Files ]; then if [ -d result_Files ]; then
rm -rf ./result_Files rm -rf ./result_Files
fi fi
if [ -d time_Result ]; then
if [ -d time_Result ]; then
rm -rf ./time_Result rm -rf ./time_Result
fi fi
mkdir result_Files mkdir result_Files
mkdir time_Result mkdir time_Result
../ascend310_infer/src/out/main --om_path=./fasterrcnn.om --data_path=$data_path --device_id=$device_id &> infer.log
../ascend310_infer/out/main --mindir_path=$model --dataset_path=$data_path --device_id=$device_id &> infer.log
} }


function cal_acc() function cal_acc()
{ {
python ../postprocess.py --ann_file=$ann_file --img_path=$data_path &> acc.log &
python3.7 ../postprocess.py --ann_file=$ann_file --result_path=./result_Files &> acc.log &
} }


air_to_om
if [ $? -ne 0 ]; then
echo "air to om failed"
exit 1
fi
compile_app compile_app
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "compile app code failed" echo "compile app code failed"


+ 0
- 26
model_zoo/official/cv/faster_rcnn/src/aipp.cfg View File

@@ -1,26 +0,0 @@
aipp_op {
aipp_mode : static
input_format : YUV420SP_U8
related_input_rank : 0
csc_switch : true
rbuv_swap_switch : false
matrix_r0c0 : 256
matrix_r0c1 : 0
matrix_r0c2 : 359
matrix_r1c0 : 256
matrix_r1c1 : -88
matrix_r1c2 : -183
matrix_r2c0 : 256
matrix_r2c1 : 454
matrix_r2c2 : 0
input_bias_0 : 0
input_bias_1 : 128
input_bias_2 : 128
mean_chn_0 : 124
mean_chn_1 : 117
mean_chn_2 : 104
var_reci_chn_0 : 0.0171247538316637
var_reci_chn_1 : 0.0175070028011204
var_reci_chn_2 : 0.0174291938997821
}

+ 3
- 4
model_zoo/official/cv/maskrcnn/README.md View File

@@ -172,7 +172,7 @@ bash run_eval.sh [VALIDATION_JSON_FILE] [CHECKPOINT_PATH]


```shell ```shell
# inference # inference
bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [ANN_FILE_PATH]
bash run_infer_310.sh [MINDIR_PATH] [DATA_PATH] [ANN_FILE] [DEVICE_ID]
``` ```


# [Script Description](#contents) # [Script Description](#contents)
@@ -203,7 +203,6 @@ bash run_eval.sh [VALIDATION_JSON_FILE] [CHECKPOINT_PATH]
├─resnet50.py # backbone network ├─resnet50.py # backbone network
├─roi_align.py # roi align network ├─roi_align.py # roi align network
└─rpn.py # reagion proposal network └─rpn.py # reagion proposal network
├─aipp.cfg #aipp config file
├─config.py # network configuration ├─config.py # network configuration
├─convert_checkpoint.py # convert resnet50 backbone checkpoint ├─convert_checkpoint.py # convert resnet50 backbone checkpoint
├─dataset.py # dataset utils ├─dataset.py # dataset utils
@@ -502,7 +501,7 @@ Accumulating evaluation results...
python export.py --ckpt_file [CKPT_PATH] --device_target [DEVICE_TARGET] --file_format[EXPORT_FORMAT] python export.py --ckpt_file [CKPT_PATH] --device_target [DEVICE_TARGET] --file_format[EXPORT_FORMAT]
``` ```


`EXPORT_FORMAT` should be in ["AIR", "ONNX", "MINDIR"]
`EXPORT_FORMAT` should be in ["AIR", "MINDIR"]


## Inference Process ## Inference Process


@@ -513,7 +512,7 @@ Current batch_ Size can only be set to 1. The inference process needs about 600G


```shell ```shell
# Ascend310 inference # Ascend310 inference
sh run_infer_310.sh [AIR_PATH] [DATA_PATH] [ANN_FILE_PATH]
sh run_infer_310.sh [MINDIR_PATH] [DATA_PATH] [ANN_FILE] [DEVICE_ID]
``` ```


### result ### result


+ 3
- 4
model_zoo/official/cv/maskrcnn/README_CN.md View File

@@ -129,7 +129,7 @@ pip install mmcv=0.2.14


```bash ```bash
# 评估 # 评估
sh run_infer_310.sh [AIR_PATH] [DATA_PATH] [ANN_FILE_PATH]
sh run_infer_310.sh [MINDIR_PATH] [DATA_PATH] [ANN_FILE] [DEVICE_ID]
``` ```


注: 注:
@@ -197,7 +197,6 @@ bash run_eval.sh [VALIDATION_JSON_FILE] [CHECKPOINT_PATH]
├─resnet50.py # 骨干网 ├─resnet50.py # 骨干网
├─roi_align.py # 兴趣点对齐网络 ├─roi_align.py # 兴趣点对齐网络
└─rpn.py # 区域候选网络 └─rpn.py # 区域候选网络
├─aipp.cfg #aipp 配置文件
├─config.py # 网络配置 ├─config.py # 网络配置
├─convert_checkpoint.py # 转换预训练checkpoint文件 ├─convert_checkpoint.py # 转换预训练checkpoint文件
├─dataset.py # 数据集工具 ├─dataset.py # 数据集工具
@@ -500,7 +499,7 @@ sh run_eval.sh [VALIDATION_ANN_FILE_JSON] [CHECKPOINT_PATH]
python export.py --ckpt_file [CKPT_PATH] --device_target [DEVICE_TARGET] --file_format[EXPORT_FORMAT] python export.py --ckpt_file [CKPT_PATH] --device_target [DEVICE_TARGET] --file_format[EXPORT_FORMAT]
``` ```


`EXPORT_FORMAT` 选项 ["AIR", "ONNX", "MINDIR"]
`EXPORT_FORMAT` 选项 ["AIR", "MINDIR"]


## 推理过程 ## 推理过程


@@ -510,7 +509,7 @@ python export.py --ckpt_file [CKPT_PATH] --device_target [DEVICE_TARGET] --file_


```shell ```shell
# Ascend310 推理 # Ascend310 推理
sh run_infer_310.sh [AIR_PATH] [DATA_PATH] [ANN_FILE_PATH]
sh run_infer_310.sh [MINDIR_PATH] [DATA_PATH] [ANN_FILE] [DEVICE_ID]
``` ```


### 结果 ### 结果


+ 14
- 0
model_zoo/official/cv/maskrcnn/ascend310_infer/CMakeLists.txt View File

@@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.14.1)
project(Ascend310Infer)
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")
set(PROJECT_SRC_ROOT ${CMAKE_CURRENT_LIST_DIR}/)
option(MINDSPORE_PATH "mindspore install path" "")
include_directories(${MINDSPORE_PATH})
include_directories(${MINDSPORE_PATH}/include)
include_directories(${PROJECT_SRC_ROOT})
find_library(MS_LIB libmindspore.so ${MINDSPORE_PATH}/lib)
file(GLOB_RECURSE MD_LIB ${MINDSPORE_PATH}/_c_dataengine*)

add_executable(main src/main.cc src/utils.cc)
target_link_libraries(main ${MS_LIB} ${MD_LIB} gflags)

+ 29
- 0
model_zoo/official/cv/maskrcnn/ascend310_infer/build.sh View File

@@ -0,0 +1,29 @@
#!/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 [ -d out ]; then
rm -rf out
fi

mkdir out
cd out || exit

if [ -f "Makefile" ]; then
make clean
fi

cmake .. \
-DMINDSPORE_PATH="`pip3.7 show mindspore-ascend | grep Location | awk '{print $2"/mindspore"}' | xargs realpath`"
make

+ 1
- 0
model_zoo/official/cv/maskrcnn/ascend310_infer/fusion_switch.cfg View File

@@ -0,0 +1 @@
ConvBatchnormFusionPass:off

+ 0
- 62
model_zoo/official/cv/maskrcnn/ascend310_infer/inc/AclProcess.h View File

@@ -1,62 +0,0 @@
/*
* Copyright (c) 2020.Huawei Technologies Co., Ltd. All rights reserved.
* 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 ACLMANAGER_H
#define ACLMANAGER_H

#include <map>
#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include "acl/acl.h"
#include "CommonDataType.h"
#include "ModelProcess.h"
#include "DvppCommon.h"

struct ModelInfo {
std::string modelPath;
uint32_t modelWidth;
uint32_t modelHeight;
uint32_t outputNum;
};

class AclProcess {
public:
AclProcess(int deviceId, const std::string &om_path, uint32_t width, uint32_t height);
~AclProcess() {}
void Release();
int InitResource();
int Process(const std::string& imageFile, std::map<double, double> *costTime_map);

private:
int InitModule();
int Preprocess(const std::string& imageFile);
int ModelInfer(std::map<double, double> *costTime_map);
int WriteResult(const std::string& imageFile);
int ReadFile(const std::string &filePath, RawData *fileData);

int32_t deviceId_;
ModelInfo modelInfo_;
aclrtContext context_;
aclrtStream stream_;
std::shared_ptr<ModelProcess> modelProcess_;
std::shared_ptr<DvppCommon> dvppCommon_;
bool keepRatio_;
std::vector<void *> outputBuffers_;
std::vector<size_t> outputSizes_;
};

#endif

+ 0
- 95
model_zoo/official/cv/maskrcnn/ascend310_infer/inc/CommonDataType.h View File

@@ -1,95 +0,0 @@
/*
* Copyright (c) 2020.Huawei Technologies Co., Ltd. All rights reserved.
* 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 COMMONDATATYPE_H
#define COMMONDATATYPE_H

#include <stdio.h>
#include <iostream>
#include <memory>
#include <vector>
#include "acl/acl.h"
#include "acl/ops/acl_dvpp.h"

#define DVPP_ALIGN_UP(x, align) ((((x) + ((align)-1)) / (align)) * (align))

#define OK 0
#define ERROR -1
#define INVALID_POINTER -2
#define READ_FILE_FAIL -3
#define OPEN_FILE_FAIL -4
#define INIT_FAIL -5
#define INVALID_PARAM -6
#define DECODE_FAIL -7

const float SEC2MS = 1000.0;
const int YUV_BGR_SIZE_CONVERT_3 = 3;
const int YUV_BGR_SIZE_CONVERT_2 = 2;
const int VPC_WIDTH_ALIGN = 16;
const int VPC_HEIGHT_ALIGN = 2;

// Description of image data
struct ImageInfo {
uint32_t width; // Image width
uint32_t height; // Image height
uint32_t lenOfByte; // Size of image data, bytes
std::shared_ptr<uint8_t> data; // Smart pointer of image data
};

// Description of data in device
struct RawData {
size_t lenOfByte; // Size of memory, bytes
std::shared_ptr<void> data; // Smart pointer of data
};

// define the structure of an rectangle
struct Rectangle {
uint32_t leftTopX;
uint32_t leftTopY;
uint32_t rightBottomX;
uint32_t rightBottomY;
};

enum VpcProcessType {
VPC_PT_DEFAULT = 0,
VPC_PT_PADDING, // Resize with locked ratio and paste on upper left corner
VPC_PT_FIT, // Resize with locked ratio and paste on middle location
VPC_PT_FILL, // Resize with locked ratio and paste on whole locatin, the input image may be cropped
};

struct DvppDataInfo {
uint32_t width = 0; // Width of image
uint32_t height = 0; // Height of image
uint32_t widthStride = 0; // Width after align up
uint32_t heightStride = 0; // Height after align up
acldvppPixelFormat format = PIXEL_FORMAT_YUV_SEMIPLANAR_420; // Format of image
uint32_t frameId = 0; // Needed by video
uint32_t dataSize = 0; // Size of data in byte
uint8_t *data = nullptr; // Image data
};

struct CropRoiConfig {
uint32_t left;
uint32_t right;
uint32_t down;
uint32_t up;
};

struct DvppCropInputInfo {
DvppDataInfo dataInfo;
CropRoiConfig roi;
};

#endif

+ 0
- 139
model_zoo/official/cv/maskrcnn/ascend310_infer/inc/DvppCommon.h View File

@@ -1,139 +0,0 @@
/*
* Copyright (c) 2020.Huawei Technologies Co., Ltd. All rights reserved.
* 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 DVPP_COMMON_H
#define DVPP_COMMON_H
#include <memory>

#include "CommonDataType.h"
#include "acl/ops/acl_dvpp.h"

const int MODULUS_NUM_2 = 2;
const uint32_t ODD_NUM_1 = 1;

const uint32_t JPEGD_STRIDE_WIDTH = 128; // Jpegd module output width need to align up to 128
const uint32_t JPEGD_STRIDE_HEIGHT = 16; // Jpegd module output height need to align up to 16
const uint32_t VPC_STRIDE_WIDTH = 16; // Vpc module output width need to align up to 16
const uint32_t VPC_STRIDE_HEIGHT = 2; // Vpc module output height need to align up to 2
const uint32_t YUV422_WIDTH_NU = 2; // Width of YUV422, WidthStride = Width * 2
const uint32_t YUV444_RGB_WIDTH_NU = 3; // Width of YUV444 and RGB888, WidthStride = Width * 3
const uint32_t XRGB_WIDTH_NU = 4; // Width of XRGB8888, WidthStride = Width * 4
const uint32_t JPEG_OFFSET = 8; // Offset of input file for jpegd module
const uint32_t MAX_JPEGD_WIDTH = 8192; // Max width of jpegd module
const uint32_t MAX_JPEGD_HEIGHT = 8192; // Max height of jpegd module
const uint32_t MIN_JPEGD_WIDTH = 32; // Min width of jpegd module
const uint32_t MIN_JPEGD_HEIGHT = 32; // Min height of jpegd module
const uint32_t MAX_RESIZE_WIDTH = 4096; // Max width stride of resize module
const uint32_t MAX_RESIZE_HEIGHT = 4096; // Max height stride of resize module
const uint32_t MIN_RESIZE_WIDTH = 32; // Min width stride of resize module
const uint32_t MIN_RESIZE_HEIGHT = 6; // Min height stride of resize module
const float MIN_RESIZE_SCALE = 0.03125; // Min resize scale of resize module
const float MAX_RESIZE_SCALE = 16.0; // Min resize scale of resize module
const uint32_t MAX_VPC_WIDTH = 4096; // Max width of picture to VPC(resize/crop)
const uint32_t MAX_VPC_HEIGHT = 4096; // Max height of picture to VPC(resize/crop)
const uint32_t MIN_VPC_WIDTH = 32; // Min width of picture to VPC(resize/crop)
const uint32_t MIN_VPC_HEIGHT = 6; // Min height of picture to VPC(resize/crop)
const uint32_t MIN_CROP_WIDTH = 10; // Min width of crop area
const uint32_t MIN_CROP_HEIGHT = 6; // Min height of crop area
const uint8_t YUV_GREYER_VALUE = 128; // Filling value of the resized YUV image

#define CONVERT_TO_ODD(NUM) (((NUM) % MODULUS_NUM_2 != 0) ? (NUM) : ((NUM) - 1))
#define CONVERT_TO_EVEN(NUM) (((NUM) % MODULUS_NUM_2 == 0) ? (NUM) : ((NUM) - 1))
#define CHECK_ODD(num) ((num) % MODULUS_NUM_2 != 0)
#define CHECK_EVEN(num) ((num) % MODULUS_NUM_2 == 0)
#define RELEASE_DVPP_DATA(dvppDataPtr) do { \
int retMacro; \
if (dvppDataPtr != nullptr) { \
retMacro = acldvppFree(dvppDataPtr); \
if (retMacro != OK) { \
std::cout << "Failed to free memory on dvpp, ret = " << retMacro << "." << std::endl; \
} \
dvppDataPtr = nullptr; \
} \
} while (0);

class DvppCommon {
public:
explicit DvppCommon(aclrtStream dvppStream);
~DvppCommon();
int Init(void);
int DeInit(void);

static int GetVpcDataSize(uint32_t widthVpc, uint32_t heightVpc, acldvppPixelFormat format,
uint32_t *vpcSize);

static int GetVpcInputStrideSize(uint32_t width, uint32_t height, acldvppPixelFormat format,
uint32_t *widthStride, uint32_t *heightStride);

static int GetVpcOutputStrideSize(uint32_t width, uint32_t height, acldvppPixelFormat format,
uint32_t *widthStride, uint32_t *heightStride);

static void GetJpegDecodeStrideSize(uint32_t width, uint32_t height, uint32_t *widthStride, uint32_t *heightStride);
static int GetJpegImageInfo(const void *data, uint32_t dataSize, uint32_t *width, uint32_t *height,
int32_t *components);

static int GetJpegDecodeDataSize(const void *data, uint32_t dataSize, acldvppPixelFormat format,
uint32_t *decSize);

int VpcResize(std::shared_ptr<DvppDataInfo> input, std::shared_ptr<DvppDataInfo> output, bool withSynchronize,
VpcProcessType processType = VPC_PT_DEFAULT);

int JpegDecode(std::shared_ptr<DvppDataInfo> input, std::shared_ptr<DvppDataInfo> output, bool withSynchronize);

int CombineResizeProcess(std::shared_ptr<DvppDataInfo> input, const DvppDataInfo &output, bool withSynchronize,
VpcProcessType processType = VPC_PT_DEFAULT);

int CombineJpegdProcess(const RawData& imageInfo, acldvppPixelFormat format, bool withSynchronize);

std::shared_ptr<DvppDataInfo> GetInputImage();
std::shared_ptr<DvppDataInfo> GetDecodedImage();
std::shared_ptr<DvppDataInfo> GetResizedImage();

void ReleaseDvppBuffer();

private:
int SetDvppPicDescData(std::shared_ptr<DvppDataInfo> dataInfo, std::shared_ptr<acldvppPicDesc>picDesc);
int ResizeProcess(std::shared_ptr<acldvppPicDesc> inputDesc,
std::shared_ptr<acldvppPicDesc> outputDesc, bool withSynchronize);

int ResizeWithPadding(std::shared_ptr<acldvppPicDesc> inputDesc, std::shared_ptr<acldvppPicDesc> outputDesc,
const CropRoiConfig &cropRoi, const CropRoiConfig &pasteRoi, bool withSynchronize);

void GetCropRoi(std::shared_ptr<DvppDataInfo> input, std::shared_ptr<DvppDataInfo> output,
VpcProcessType processType, CropRoiConfig *cropRoi);

void GetPasteRoi(std::shared_ptr<DvppDataInfo> input, std::shared_ptr<DvppDataInfo> output,
VpcProcessType processType, CropRoiConfig *pasteRoi);

int CheckResizeParams(const DvppDataInfo &input, const DvppDataInfo &output);
int TransferImageH2D(const RawData& imageInfo, const std::shared_ptr<DvppDataInfo>& jpegInput);
int CreateStreamDesc(std::shared_ptr<DvppDataInfo> data);
int DestroyResource();

std::shared_ptr<acldvppRoiConfig> cropAreaConfig_ = nullptr;
std::shared_ptr<acldvppRoiConfig> pasteAreaConfig_ = nullptr;

std::shared_ptr<acldvppPicDesc> resizeInputDesc_ = nullptr;
std::shared_ptr<acldvppPicDesc> resizeOutputDesc_ = nullptr;
std::shared_ptr<acldvppPicDesc> decodeOutputDesc_ = nullptr;
std::shared_ptr<acldvppResizeConfig> resizeConfig_ = nullptr;

acldvppChannelDesc *dvppChannelDesc_ = nullptr;
aclrtStream dvppStream_ = nullptr;
std::shared_ptr<DvppDataInfo> inputImage_ = nullptr;
std::shared_ptr<DvppDataInfo> decodedImage_ = nullptr;
std::shared_ptr<DvppDataInfo> resizedImage_ = nullptr;
};
#endif

+ 0
- 63
model_zoo/official/cv/maskrcnn/ascend310_infer/inc/ModelProcess.h View File

@@ -1,63 +0,0 @@
/*
* Copyright(C) 2020. Huawei Technologies Co.,Ltd. All rights reserved.
*
* 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 MODELPROCSS_H
#define MODELPROCSS_H

#include <cstdio>
#include <vector>
#include <unordered_map>
#include <mutex>
#include <map>
#include <memory>
#include <string>
#include "acl/acl.h"
#include "CommonDataType.h"

class ModelProcess {
public:
explicit ModelProcess(const int deviceId);
ModelProcess();
~ModelProcess();

int Init(const std::string &modelPath);
int DeInit();

int ModelInference(const std::vector<void *> &inputBufs,
const std::vector<size_t> &inputSizes,
const std::vector<void *> &ouputBufs,
const std::vector<size_t> &outputSizes,
std::map<double, double> *costTime_map);
aclmdlDesc *GetModelDesc();
int ReadBinaryFile(const std::string &fileName, uint8_t **buffShared, int *buffLength);

private:
aclmdlDataset *CreateAndFillDataset(const std::vector<void *> &bufs, const std::vector<size_t> &sizes);
void DestroyDataset(aclmdlDataset *dataset);

std::mutex mtx_ = {};
int deviceId_ = 0;
uint32_t modelId_ = 0;
void *modelDevPtr_ = nullptr;
size_t modelDevPtrSize_ = 0;
void *weightDevPtr_ = nullptr;
size_t weightDevPtrSize_ = 0;
aclrtContext contextModel_ = nullptr;
std::shared_ptr<aclmdlDesc> modelDesc_ = nullptr;
bool isDeInit_ = false;
};

#endif

+ 32
- 0
model_zoo/official/cv/maskrcnn/ascend310_infer/inc/utils.h View File

@@ -0,0 +1,32 @@
/**
* 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 <sys/stat.h>
#include <dirent.h>
#include <vector>
#include <string>
#include <memory>
#include "include/api/types.h"

std::vector<std::string> GetAllFiles(std::string_view dirName);
DIR *OpenDir(std::string_view dirName);
std::string RealPath(std::string_view path);
mindspore::MSTensor ReadFileToTensor(const std::string &file);
int WriteResult(const std::string& imageFile, const std::vector<mindspore::MSTensor> &outputs);
#endif

+ 0
- 371
model_zoo/official/cv/maskrcnn/ascend310_infer/src/AclProcess.cpp View File

@@ -1,371 +0,0 @@
/*
* Copyright (c) 2020.Huawei Technologies Co., Ltd. All rights reserved.
* 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 "AclProcess.h"
#include <sys/time.h>
#include <thread>
#include <string>

/*
* @description Implementation of constructor for class AclProcess with parameter list
* @attention context is passed in as a parameter after being created in ResourceManager::InitResource
*/
AclProcess::AclProcess(int deviceId, const std::string &om_path, uint32_t width, uint32_t height)
: deviceId_(deviceId), stream_(nullptr), modelProcess_(nullptr), dvppCommon_(nullptr), keepRatio_(true) {
modelInfo_.modelPath = om_path;
modelInfo_.modelWidth = width;
modelInfo_.modelHeight = height;
}

/*
* @description Release all the resource
* @attention context will be released in ResourceManager::Release
*/
void AclProcess::Release() {
// Synchronize stream and release Dvpp channel
dvppCommon_->DeInit();
// Release stream
if (stream_ != nullptr) {
int ret = aclrtDestroyStream(stream_);
if (ret != OK) {
std::cout << "Failed to destroy the stream, ret = " << ret << ".";
}
stream_ = nullptr;
}
// Destroy resources of modelProcess_
modelProcess_->DeInit();

// Release Dvpp buffer
dvppCommon_->ReleaseDvppBuffer();

return;
}

/*
* @description Initialize the modules used by this sample
* @return int int code
*/
int AclProcess::InitModule() {
// Create Dvpp common object
if (dvppCommon_ == nullptr) {
dvppCommon_ = std::make_shared<DvppCommon>(stream_);
int retDvppCommon = dvppCommon_->Init();
if (retDvppCommon != OK) {
std::cout << "Failed to initialize dvppCommon, ret = " << retDvppCommon << std::endl;
return retDvppCommon;
}
}
// Create model inference object
if (modelProcess_ == nullptr) {
modelProcess_ = std::make_shared<ModelProcess>(deviceId_);
}
// Initialize ModelProcess module
int ret = modelProcess_->Init(modelInfo_.modelPath);
if (ret != OK) {
std::cout << "Failed to initialize the model process module, ret = " << ret << "." << std::endl;
return ret;
}
std::cout << "Initialized the model process module successfully." << std::endl;
return OK;
}

/*
* @description Create resource for this sample
* @return int int code
*/
int AclProcess::InitResource() {
int ret = aclInit(nullptr); // Initialize ACL
if (ret != OK) {
std::cout << "Failed to init acl, ret = " << ret << std::endl;
return ret;
}

ret = aclrtSetDevice(deviceId_);
if (ret != ACL_SUCCESS) {
std::cout << "acl set device " << deviceId_ << "intCode = "<< static_cast<int32_t>(ret) << std::endl;
return ret;
}
std::cout << "set device "<< deviceId_ << " success" << std::endl;

// create context (set current)
ret = aclrtCreateContext(&context_, deviceId_);
if (ret != ACL_SUCCESS) {
std::cout << "acl create context failed, deviceId = " << deviceId_ <<
"intCode = "<< static_cast<int32_t>(ret) << std::endl;
return ret;
}
std::cout << "create context success" << std::endl;

ret = aclrtCreateStream(&stream_); // Create stream for application
if (ret != OK) {
std::cout << "Failed to create the acl stream, ret = " << ret << "." << std::endl;
return ret;
}
std::cout << "Created the acl stream successfully." << std::endl;
// Initialize dvpp module
if (InitModule() != OK) {
return INIT_FAIL;
}

aclmdlDesc *modelDesc = modelProcess_->GetModelDesc();
size_t outputSize = aclmdlGetNumOutputs(modelDesc);
modelInfo_.outputNum = outputSize;
for (size_t i = 0; i < outputSize; i++) {
size_t bufferSize = aclmdlGetOutputSizeByIndex(modelDesc, i);
void *outputBuffer = nullptr;
ret = aclrtMalloc(&outputBuffer, bufferSize, ACL_MEM_MALLOC_NORMAL_ONLY);
if (ret != OK) {
std::cout << "Failed to malloc buffer, ret = " << ret << "." << std::endl;
return ret;
}
outputBuffers_.push_back(outputBuffer);
outputSizes_.push_back(bufferSize);
}

return OK;
}

int AclProcess::WriteResult(const std::string& imageFile) {
std::string homePath = "./result_Files";
void *resHostBuf = nullptr;
for (size_t i = 0; i < outputBuffers_.size(); ++i) {
size_t output_size;
void *netOutput;
netOutput = outputBuffers_[i];
output_size = outputSizes_[i];
int ret = aclrtMallocHost(&resHostBuf, output_size);
if (ret != OK) {
std::cout << "Failed to print the result, malloc host failed, ret = " << ret << "." << std::endl;
return ret;
}

ret = aclrtMemcpy(resHostBuf, output_size, netOutput,
output_size, ACL_MEMCPY_DEVICE_TO_HOST);
if (ret != OK) {
std::cout << "Failed to print result, memcpy device to host failed, ret = " << ret << "." << std::endl;
return ret;
}

int pos = imageFile.rfind('/');
std::string fileName(imageFile, pos + 1);
fileName.replace(fileName.find('.'), fileName.size() - fileName.find('.'), "_" + std::to_string(i) + ".bin");

std::string outFileName = homePath + "/" + fileName;
try {
FILE *outputFile = fopen(outFileName.c_str(), "wb");
if (outputFile == nullptr) {
std::cout << "open result file " << outFileName << " failed" << std::endl;
return INVALID_POINTER;
}
size_t size = fwrite(resHostBuf, sizeof(char), output_size, outputFile);
if (size != output_size) {
fclose(outputFile);
outputFile = nullptr;
std::cout << "write result file " << outFileName << " failed, write size[" << size <<
"] is smaller than output size[" << output_size << "], maybe the disk is full." << std::endl;
return ERROR;
}
fclose(outputFile);
outputFile = nullptr;
} catch (std::exception &e) {
std::cout << "write result file " << outFileName << " failed, error info: " << e.what() << std::endl;
std::exit(1);
}

ret = aclrtFreeHost(resHostBuf);
if (ret != OK) {
std::cout << "aclrtFree host output memory failed" << std::endl;
return ret;
}
}
return OK;
}

/**
* Read a file, store it into the RawData structure
*
* @param filePath file to read to
* @param fileData RawData structure to store in
* @return OK if create success, int code otherwise
*/
int AclProcess::ReadFile(const std::string &filePath, RawData *fileData) {
// Open file with reading mode
FILE *fp = fopen(filePath.c_str(), "rb");
if (fp == nullptr) {
std::cout << "Failed to open file, filePath = " << filePath << std::endl;
return OPEN_FILE_FAIL;
}
// Get the length of input file
fseek(fp, 0, SEEK_END);
size_t fileSize = ftell(fp);
fseek(fp, 0, SEEK_SET);
// If file not empty, read it into FileInfo and return it
if (fileSize > 0) {
fileData->lenOfByte = fileSize;
fileData->data = std::make_shared<uint8_t>();
fileData->data.reset(new uint8_t[fileSize], std::default_delete<uint8_t[]>());
uint32_t readRet = fread(fileData->data.get(), 1, fileSize, fp);
if (readRet == 0) {
fclose(fp);
return READ_FILE_FAIL;
}
fclose(fp);
return OK;
}
fclose(fp);
return INVALID_PARAM;
}
/*
* @description Preprocess the input image
* @param imageFile input image path
* @return int int code
*/
int AclProcess::Preprocess(const std::string& imageFile) {
RawData imageInfo;
int ret = ReadFile(imageFile, &imageInfo); // Read image data from input image file
if (ret != OK) {
std::cout << "Failed to read file, ret = " << ret << "." << std::endl;
return ret;
}
// Run process of jpegD
ret = dvppCommon_->CombineJpegdProcess(imageInfo, PIXEL_FORMAT_YUV_SEMIPLANAR_420, true);
if (ret != OK) {
std::cout << "Failed to execute image decoded of preprocess module, ret = " << ret << "." << std::endl;
return ret;
}
// Get output of decode jpeg image
std::shared_ptr<DvppDataInfo> decodeOutData = dvppCommon_->GetDecodedImage();
// Run resize application function
DvppDataInfo resizeOutData;
resizeOutData.height = modelInfo_.modelHeight;
resizeOutData.width = modelInfo_.modelWidth;
resizeOutData.format = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
ret = dvppCommon_->CombineResizeProcess(decodeOutData, resizeOutData, true, VPC_PT_PADDING);
if (ret != OK) {
std::cout << "Failed to execute image resized of preprocess module, ret = " << ret << "." << std::endl;
return ret;
}

RELEASE_DVPP_DATA(decodeOutData->data);
return OK;
}

/*
* @description Inference of model
* @return int int code
*/
int AclProcess::ModelInfer(std::map<double, double> *costTime_map) {
// Get output of resize module
std::shared_ptr<DvppDataInfo> resizeOutData = dvppCommon_->GetResizedImage();
std::shared_ptr<DvppDataInfo> inputImg = dvppCommon_->GetInputImage();

float widthScale, heightScale;
if (keepRatio_) {
widthScale = static_cast<float>(resizeOutData->width) / inputImg->width;
if (widthScale > static_cast<float>(resizeOutData->height) / inputImg->height) {
widthScale = static_cast<float>(resizeOutData->height) / inputImg->height;
}
heightScale = widthScale;
} else {
widthScale = static_cast<float>(resizeOutData->width) / inputImg->width;
heightScale = static_cast<float>(resizeOutData->height) / inputImg->height;
}

aclFloat16 inputWidth = aclFloatToFloat16(static_cast<float>(inputImg->width));
aclFloat16 inputHeight = aclFloatToFloat16(static_cast<float>(inputImg->height));
aclFloat16 resizeWidthRatioFp16 = aclFloatToFloat16(widthScale);
aclFloat16 resizeHeightRatioFp16 = aclFloatToFloat16(heightScale);

aclFloat16 *im_info = reinterpret_cast<aclFloat16 *>(malloc(sizeof(aclFloat16) * 4));
im_info[0] = inputHeight;
im_info[1] = inputWidth;
im_info[2] = resizeHeightRatioFp16;
im_info[3] = resizeWidthRatioFp16;
void *imInfo_dst = nullptr;
int ret = aclrtMalloc(&imInfo_dst, 8, ACL_MEM_MALLOC_NORMAL_ONLY);
if (ret != ACL_ERROR_NONE) {
std::cout << "aclrtMalloc failed, ret = " << ret << std::endl;
aclrtFree(imInfo_dst);
return ret;
}
ret = aclrtMemcpy(reinterpret_cast<uint8_t *>(imInfo_dst), 8, im_info, 8, ACL_MEMCPY_HOST_TO_DEVICE);
if (ret != ACL_ERROR_NONE) {
std::cout << "aclrtMemcpy failed, ret = " << ret << std::endl;
aclrtFree(imInfo_dst);
return ret;
}

std::vector<void *> inputBuffers({resizeOutData->data, imInfo_dst});
std::vector<size_t> inputSizes({resizeOutData->dataSize, 4 * 2});

for (size_t i = 0; i < modelInfo_.outputNum; i++) {
aclrtMemset(outputBuffers_[i], outputSizes_[i], 0, outputSizes_[i]);
}
// Execute classification model
ret = modelProcess_->ModelInference(inputBuffers, inputSizes, outputBuffers_, outputSizes_, costTime_map);
if (ret != OK) {
aclrtFree(imInfo_dst);
std::cout << "Failed to execute the classification model, ret = " << ret << "." << std::endl;
return ret;
}

ret = aclrtFree(imInfo_dst);
if (ret != OK) {
std::cout << "aclrtFree image info failed" << std::endl;
return ret;
}
RELEASE_DVPP_DATA(resizeOutData->data);
return OK;
}

/*
* @description Process classification
*
* @par Function
* 1.Dvpp module preprocess
* 2.Execute classification model
* 3.Execute single operator
* 4.Write result
*
* @param imageFile input file path
* @return int int code
*/

int AclProcess::Process(const std::string& imageFile, std::map<double, double> *costTime_map) {
struct timeval begin = {0};
struct timeval end = {0};
gettimeofday(&begin, nullptr);

int ret = Preprocess(imageFile);
if (ret != OK) {
return ret;
}

ret = ModelInfer(costTime_map);
if (ret != OK) {
return ret;
}

ret = WriteResult(imageFile);
if (ret != OK) {
std::cout << "write result failed." << std::endl;
return ret;
}
gettimeofday(&end, nullptr);

const double costMs = SEC2MS * (end.tv_sec - begin.tv_sec) + (end.tv_usec - begin.tv_usec) / SEC2MS;
std::cout << "[Process Delay] cost: " << costMs << "ms." << std::endl;
return OK;
}

+ 0
- 42
model_zoo/official/cv/maskrcnn/ascend310_infer/src/CMakeLists.txt View File

@@ -1,42 +0,0 @@
# Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved.

# CMake lowest version requirement
cmake_minimum_required(VERSION 3.5.1)
# Add definitions ENABLE_DVPP_INTERFACE to use dvpp api
add_definitions(-DENABLE_DVPP_INTERFACE)
# 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_options(-std=c++11 -fPIE -g -fstack-protector-all -Werror -Wreturn-type)

# 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)
find_library(acl_dvpp libacl_dvpp.so ${ACL_LIB_DIR}/lib64 ${ATLAS_ACL_LIB_DIR}/lib64)

add_executable(main AclProcess.cpp
DvppCommon.cpp
ModelProcess.cpp
main.cpp)

target_link_libraries(main ${acl} gflags ${acl_dvpp} pthread)

+ 0
- 735
model_zoo/official/cv/maskrcnn/ascend310_infer/src/DvppCommon.cpp View File

@@ -1,735 +0,0 @@
/*
* Copyright (c) 2020.Huawei Technologies Co., Ltd. All rights reserved.
* 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 <iostream>
#include <memory>

#include "../inc/DvppCommon.h"
#include "../inc/CommonDataType.h"

static auto g_resizeConfigDeleter = [](acldvppResizeConfig *p) { acldvppDestroyResizeConfig(p); };
static auto g_picDescDeleter = [](acldvppPicDesc *picDesc) { acldvppDestroyPicDesc(picDesc); };
static auto g_roiConfigDeleter = [](acldvppRoiConfig *p) { acldvppDestroyRoiConfig(p); };

DvppCommon::DvppCommon(aclrtStream dvppStream):dvppStream_(dvppStream) {}

/*
* @description: Create a channel for processing image data,
* the channel description is created by acldvppCreateChannelDesc
* @return: OK if success, other values if failure
*/
int DvppCommon::Init(void) {
dvppChannelDesc_ = acldvppCreateChannelDesc();
if (dvppChannelDesc_ == nullptr) {
return -1;
}
int ret = acldvppCreateChannel(dvppChannelDesc_);
if (ret != 0) {
std::cout << "Failed to create dvpp channel, ret = " << ret << "." << std::endl;
acldvppDestroyChannelDesc(dvppChannelDesc_);
dvppChannelDesc_ = nullptr;
return ret;
}

return OK;
}

/*
* @description: destroy the channel and the channel description used by image.
* @return: OK if success, other values if failure
*/
int DvppCommon::DeInit(void) {
int ret = aclrtSynchronizeStream(dvppStream_); // int ret
if (ret != OK) {
std::cout << "Failed to synchronize stream, ret = " << ret << "." << std::endl;
return ret;
}

ret = acldvppDestroyChannel(dvppChannelDesc_);
if (ret != OK) {
std::cout << "Failed to destroy dvpp channel, ret = " << ret << "." << std::endl;
return ret;
}

ret = acldvppDestroyChannelDesc(dvppChannelDesc_);
if (ret != OK) {
std::cout << "Failed to destroy dvpp channel description, ret = " << ret << "." << std::endl;
return ret;
}
return OK;
}

/*
* @description: Release the memory that is allocated in the interfaces which are started with "Combine"
*/
void DvppCommon::ReleaseDvppBuffer() {
if (resizedImage_ != nullptr) {
RELEASE_DVPP_DATA(resizedImage_->data);
}
if (decodedImage_ != nullptr) {
RELEASE_DVPP_DATA(decodedImage_->data);
}
if (inputImage_ != nullptr) {
RELEASE_DVPP_DATA(inputImage_->data);
}
}

/*
* @description: Get the size of buffer used to save image for VPC according to width, height and format
* @param width specifies the width of the output image
* @param height specifies the height of the output image
* @param format specifies the format of the output image
* @param: vpcSize is used to save the result size
* @return: OK if success, other values if failure
*/
int DvppCommon::GetVpcDataSize(uint32_t width, uint32_t height, acldvppPixelFormat format, uint32_t *vpcSize) {
if (format != PIXEL_FORMAT_YUV_SEMIPLANAR_420 && format != PIXEL_FORMAT_YVU_SEMIPLANAR_420) {
std::cout << "Format[" << format << "] for VPC is not supported, just support NV12 or NV21." << std::endl;
return INVALID_PARAM;
}
uint32_t widthStride = DVPP_ALIGN_UP(width, VPC_WIDTH_ALIGN);
uint32_t heightStride = DVPP_ALIGN_UP(height, VPC_HEIGHT_ALIGN);
*vpcSize = widthStride * heightStride * YUV_BGR_SIZE_CONVERT_3 / YUV_BGR_SIZE_CONVERT_2;
return OK;
}

/*
* @description: Get the aligned width and height of the input image according to the image format
* @param: width specifies the width before alignment
* @param: height specifies the height before alignment
* @param: format specifies the image format
* @param: widthStride is used to save the width after alignment
* @param: heightStride is used to save the height after alignment
* @return: OK if success, other values if failure
*/
int DvppCommon::GetVpcInputStrideSize(uint32_t width, uint32_t height, acldvppPixelFormat format,
uint32_t *widthStride, uint32_t *heightStride) {
uint32_t inputWidthStride;
if (format >= PIXEL_FORMAT_YUV_400 && format <= PIXEL_FORMAT_YVU_SEMIPLANAR_444) {
inputWidthStride = DVPP_ALIGN_UP(width, VPC_STRIDE_WIDTH);
} else if (format >= PIXEL_FORMAT_YUYV_PACKED_422 && format <= PIXEL_FORMAT_VYUY_PACKED_422) {
inputWidthStride = DVPP_ALIGN_UP(width, VPC_STRIDE_WIDTH) * YUV422_WIDTH_NU;
} else if (format >= PIXEL_FORMAT_YUV_PACKED_444 && format <= PIXEL_FORMAT_BGR_888) {
inputWidthStride = DVPP_ALIGN_UP(width, VPC_STRIDE_WIDTH) * YUV444_RGB_WIDTH_NU;
} else if (format >= PIXEL_FORMAT_ARGB_8888 && format <= PIXEL_FORMAT_BGRA_8888) {
inputWidthStride = DVPP_ALIGN_UP(width, VPC_STRIDE_WIDTH) * XRGB_WIDTH_NU;
} else {
std::cout << "Input format[" << format << "] for VPC is invalid, please check it." << std::endl;
return INVALID_PARAM;
}
uint32_t inputHeightStride = DVPP_ALIGN_UP(height, VPC_STRIDE_HEIGHT);
if (inputWidthStride > MAX_RESIZE_WIDTH || inputWidthStride < MIN_RESIZE_WIDTH) {
std::cout << "Input width stride " << inputWidthStride << " is invalid, not in [" << MIN_RESIZE_WIDTH \
<< ", " << MAX_RESIZE_WIDTH << "]." << std::endl;
return INVALID_PARAM;
}

if (inputHeightStride > MAX_RESIZE_HEIGHT || inputHeightStride < MIN_RESIZE_HEIGHT) {
std::cout << "Input height stride " << inputHeightStride << " is invalid, not in [" << MIN_RESIZE_HEIGHT \
<< ", " << MAX_RESIZE_HEIGHT << "]." << std::endl;
return INVALID_PARAM;
}
*widthStride = inputWidthStride;
*heightStride = inputHeightStride;
return OK;
}

/*
* @description: Get the aligned width and height of the output image according to the image format
* @param: width specifies the width before alignment
* @param: height specifies the height before alignment
* @param: format specifies the image format
* @param: widthStride is used to save the width after alignment
* @param: heightStride is used to save the height after alignment
* @return: OK if success, other values if failure
*/
int DvppCommon::GetVpcOutputStrideSize(uint32_t width, uint32_t height, acldvppPixelFormat format,
uint32_t *widthStride, uint32_t *heightStride) {
if (format != PIXEL_FORMAT_YUV_SEMIPLANAR_420 && format != PIXEL_FORMAT_YVU_SEMIPLANAR_420) {
std::cout << "Output format[" << format << "] is not supported, just support NV12 or NV21." << std::endl;
return INVALID_PARAM;
}

*widthStride = DVPP_ALIGN_UP(width, VPC_STRIDE_WIDTH);
*heightStride = DVPP_ALIGN_UP(height, VPC_STRIDE_HEIGHT);
return OK;
}

/*
* @description: Set picture description information and execute resize function
* @param: input specifies the input image information
* @param: output specifies the output image information
* @param: withSynchronize specifies whether to execute synchronously
* @param: processType specifies whether to perform proportional scaling, default is non-proportional resize
* @return: OK if success, other values if failure
* @attention: This function can be called only when the DvppCommon object is initialized with Init
*/
int DvppCommon::VpcResize(std::shared_ptr<DvppDataInfo> input, std::shared_ptr<DvppDataInfo> output,
bool withSynchronize, VpcProcessType processType) {
acldvppPicDesc *inputDesc = acldvppCreatePicDesc();
acldvppPicDesc *outputDesc = acldvppCreatePicDesc();
resizeInputDesc_.reset(inputDesc, g_picDescDeleter);
resizeOutputDesc_.reset(outputDesc, g_picDescDeleter);

// Set dvpp picture descriptin info of input image
int ret = SetDvppPicDescData(input, resizeInputDesc_);
if (ret != OK) {
std::cout << "Failed to set dvpp input picture description, ret = " << ret << "." << std::endl;
return ret;
}

// Set dvpp picture descriptin info of output image
ret = SetDvppPicDescData(output, resizeOutputDesc_);
if (ret != OK) {
std::cout << "Failed to set dvpp output picture description, ret = " << ret << "." << std::endl;
return ret;
}
if (processType == VPC_PT_DEFAULT) {
return ResizeProcess(resizeInputDesc_, resizeOutputDesc_, withSynchronize);
}

// Get crop area according to the processType
CropRoiConfig cropRoi = {0};
GetCropRoi(input, output, processType, &cropRoi);

// The width and height of the original image will be resized by the same ratio
CropRoiConfig pasteRoi = {0};
GetPasteRoi(input, output, processType, &pasteRoi);

return ResizeWithPadding(resizeInputDesc_, resizeOutputDesc_, cropRoi, pasteRoi, withSynchronize);
}

/*
* @description: Set image description information
* @param: dataInfo specifies the image information
* @param: picsDesc specifies the picture description information to be set
* @return: OK if success, other values if failure
*/
int DvppCommon::SetDvppPicDescData(std::shared_ptr<DvppDataInfo> dataInfo, std::shared_ptr<acldvppPicDesc>picDesc) {
int ret = acldvppSetPicDescData(picDesc.get(), dataInfo->data);
if (ret != OK) {
std::cout << "Failed to set data for dvpp picture description, ret = " << ret << "." << std::endl;
return ret;
}
ret = acldvppSetPicDescSize(picDesc.get(), dataInfo->dataSize);
if (ret != OK) {
std::cout << "Failed to set size for dvpp picture description, ret = " << ret << "." << std::endl;
return ret;
}
ret = acldvppSetPicDescFormat(picDesc.get(), dataInfo->format);
if (ret != OK) {
std::cout << "Failed to set format for dvpp picture description, ret = " << ret << "." << std::endl;
return ret;
}
ret = acldvppSetPicDescWidth(picDesc.get(), dataInfo->width);
if (ret != OK) {
std::cout << "Failed to set width for dvpp picture description, ret = " << ret << "." << std::endl;
return ret;
}
ret = acldvppSetPicDescHeight(picDesc.get(), dataInfo->height);
if (ret != OK) {
std::cout << "Failed to set height for dvpp picture description, ret = " << ret << "." << std::endl;
return ret;
}

ret = acldvppSetPicDescWidthStride(picDesc.get(), dataInfo->widthStride);
if (ret != OK) {
std::cout << "Failed to set aligned width for dvpp picture description, ret = " << ret << "." << std::endl;
return ret;
}
ret = acldvppSetPicDescHeightStride(picDesc.get(), dataInfo->heightStride);
if (ret != OK) {
std::cout << "Failed to set aligned height for dvpp picture description, ret = " << ret << "." << std::endl;
return ret;
}

return OK;
}

/*
* @description: Check whether the image format and zoom ratio meet the requirements
* @param: input specifies the input image information
* @param: output specifies the output image information
* @return: OK if success, other values if failure
*/
int DvppCommon::CheckResizeParams(const DvppDataInfo &input, const DvppDataInfo &output) {
if (output.format != PIXEL_FORMAT_YUV_SEMIPLANAR_420 && output.format != PIXEL_FORMAT_YVU_SEMIPLANAR_420) {
std::cout << "Output format[" << output.format << "]is not supported, just support NV12 or NV21." << std::endl;
return INVALID_PARAM;
}
float heightScale = static_cast<float>(output.height) / input.height;
if (heightScale < MIN_RESIZE_SCALE || heightScale > MAX_RESIZE_SCALE) {
std::cout << "Resize scale should be in range [1/16, 32], which is " << heightScale << "." << std::endl;
return INVALID_PARAM;
}
float widthScale = static_cast<float>(output.width) / input.width;
if (widthScale < MIN_RESIZE_SCALE || widthScale > MAX_RESIZE_SCALE) {
std::cout << "Resize scale should be in range [1/16, 32], which is " << widthScale << "." << std::endl;
return INVALID_PARAM;
}
return OK;
}

/*
* @description: Scale the input image to the size specified by the output image and
* saves the result to the output image (non-proportionate scaling)
* @param: inputDesc specifies the description information of the input image
* @param: outputDesc specifies the description information of the output image
* @param: withSynchronize specifies whether to execute synchronously
* @return: OK if success, other values if failure
*/
int DvppCommon::ResizeProcess(std::shared_ptr<acldvppPicDesc>inputDesc,
std::shared_ptr<acldvppPicDesc>outputDesc,
bool withSynchronize) {
acldvppResizeConfig *resizeConfig = acldvppCreateResizeConfig();
if (resizeConfig == nullptr) {
std::cout << "Failed to create dvpp resize config." << std::endl;
return INVALID_POINTER;
}

resizeConfig_.reset(resizeConfig, g_resizeConfigDeleter);
int ret = acldvppVpcResizeAsync(dvppChannelDesc_, inputDesc.get(), outputDesc.get(),
resizeConfig_.get(), dvppStream_);
if (ret != OK) {
std::cout << "Failed to resize asynchronously, ret = " << ret << "." << std::endl;
return ret;
}

if (withSynchronize) {
ret = aclrtSynchronizeStream(dvppStream_);
if (ret != OK) {
std::cout << "Failed to synchronize stream, ret = " << ret << "." << std::endl;
return ret;
}
}
return OK;
}

/*
* @description: Crop the image from the input image based on the specified area and
* paste the cropped image to the specified position of the target image
* as the output image
* @param: inputDesc specifies the description information of the input image
* @param: outputDesc specifies the description information of the output image
* @param: cropRoi specifies the cropped area
* @param: pasteRoi specifies the pasting area
* @param: withSynchronize specifies whether to execute synchronously
* @return: OK if success, other values if failure
* @attention: If the width and height of the crop area are different from those of the
* paste area, the image is scaled again
*/
int DvppCommon::ResizeWithPadding(std::shared_ptr<acldvppPicDesc> inputDesc,
std::shared_ptr<acldvppPicDesc> outputDesc,
const CropRoiConfig &cropRoi, const CropRoiConfig &pasteRoi, bool withSynchronize) {
acldvppRoiConfig *cropRoiCfg = acldvppCreateRoiConfig(cropRoi.left, cropRoi.right, cropRoi.up, cropRoi.down);
if (cropRoiCfg == nullptr) {
std::cout << "Failed to create dvpp roi config for corp area." << std::endl;
return INVALID_POINTER;
}
cropAreaConfig_.reset(cropRoiCfg, g_roiConfigDeleter);

acldvppRoiConfig *pastRoiCfg = acldvppCreateRoiConfig(pasteRoi.left, pasteRoi.right, pasteRoi.up, pasteRoi.down);
if (pastRoiCfg == nullptr) {
std::cout << "Failed to create dvpp roi config for paster area." << std::endl;
return INVALID_POINTER;
}
pasteAreaConfig_.reset(pastRoiCfg, g_roiConfigDeleter);

int ret = acldvppVpcCropAndPasteAsync(dvppChannelDesc_, inputDesc.get(), outputDesc.get(), cropAreaConfig_.get(),
pasteAreaConfig_.get(), dvppStream_);
if (ret != OK) {
// release resource.
std::cout << "Failed to crop and paste asynchronously, ret = " << ret << "." << std::endl;
return ret;
}
if (withSynchronize) {
ret = aclrtSynchronizeStream(dvppStream_);
if (ret != OK) {
std::cout << "Failed tp synchronize stream, ret = " << ret << "." << std::endl;
return ret;
}
}
return OK;
}

/*
* @description: Get crop area
* @param: input specifies the input image information
* @param: output specifies the output image information
* @param: processType specifies whether to perform proportional scaling
* @param: cropRoi is used to save the info of the crop roi area
* @return: OK if success, other values if failure
*/
void DvppCommon::GetCropRoi(std::shared_ptr<DvppDataInfo> input, std::shared_ptr<DvppDataInfo> output,
VpcProcessType processType, CropRoiConfig *cropRoi) {
// When processType is not VPC_PT_FILL, crop area is the whole input image
if (processType != VPC_PT_FILL) {
cropRoi->right = CONVERT_TO_ODD(input->width - ODD_NUM_1);
cropRoi->down = CONVERT_TO_ODD(input->height - ODD_NUM_1);
return;
}

bool widthRatioSmaller = true;
// The scaling ratio is based on the smaller ratio to ensure the smallest edge to fill the targe edge
float resizeRatio = static_cast<float>(input->width) / output->width;
if (resizeRatio > (static_cast<float>(input->height) / output->height)) {
resizeRatio = static_cast<float>(input->height) / output->height;
widthRatioSmaller = false;
}

const int halfValue = 2;
// The left and up must be even, right and down must be odd which is required by acl
if (widthRatioSmaller) {
cropRoi->left = 0;
cropRoi->right = CONVERT_TO_ODD(input->width - ODD_NUM_1);
cropRoi->up = CONVERT_TO_EVEN(static_cast<uint32_t>((input->height - output->height * resizeRatio) /
halfValue));
cropRoi->down = CONVERT_TO_ODD(input->height - cropRoi->up - ODD_NUM_1);
return;
}

cropRoi->up = 0;
cropRoi->down = CONVERT_TO_ODD(input->height - ODD_NUM_1);
cropRoi->left = CONVERT_TO_EVEN(static_cast<uint32_t>((input->width - output->width * resizeRatio) / halfValue));
cropRoi->right = CONVERT_TO_ODD(input->width - cropRoi->left - ODD_NUM_1);
return;
}

/*
* @description: Get paste area
* @param: input specifies the input image information
* @param: output specifies the output image information
* @param: processType specifies whether to perform proportional scaling
* @param: pasteRio is used to save the info of the paste area
* @return: OK if success, other values if failure
*/
void DvppCommon::GetPasteRoi(std::shared_ptr<DvppDataInfo> input, std::shared_ptr<DvppDataInfo> output,
VpcProcessType processType, CropRoiConfig *pasteRoi) {
if (processType == VPC_PT_FILL) {
pasteRoi->right = CONVERT_TO_ODD(output->width - ODD_NUM_1);
pasteRoi->down = CONVERT_TO_ODD(output->height - ODD_NUM_1);
return;
}

bool widthRatioLarger = true;
// The scaling ratio is based on the larger ratio to ensure the largest edge to fill the targe edge
float resizeRatio = static_cast<float>(input->width) / output->width;
if (resizeRatio < (static_cast<float>(input->height) / output->height)) {
resizeRatio = static_cast<float>(input->height) / output->height;
widthRatioLarger = false;
}

// Left and up is 0 when the roi paste on the upper left corner
if (processType == VPC_PT_PADDING) {
pasteRoi->right = (input->width / resizeRatio) - ODD_NUM_1;
pasteRoi->down = (input->height / resizeRatio) - ODD_NUM_1;
pasteRoi->right = CONVERT_TO_ODD(pasteRoi->right);
pasteRoi->down = CONVERT_TO_ODD(pasteRoi->down);
return;
}

const int halfValue = 2;
// Left and up is 0 when the roi paste on the middler location
if (widthRatioLarger) {
pasteRoi->left = 0;
pasteRoi->right = output->width - ODD_NUM_1;
pasteRoi->up = (output->height - (input->height / resizeRatio)) / halfValue;
pasteRoi->down = output->height - pasteRoi->up - ODD_NUM_1;
} else {
pasteRoi->up = 0;
pasteRoi->down = output->height - ODD_NUM_1;
pasteRoi->left = (output->width - (input->width / resizeRatio)) / halfValue;
pasteRoi->right = output->width - pasteRoi->left - ODD_NUM_1;
}

// The left must be even and align to 16, up must be even, right and down must be odd which is required by acl
pasteRoi->left = DVPP_ALIGN_UP(CONVERT_TO_EVEN(pasteRoi->left), VPC_WIDTH_ALIGN);
pasteRoi->right = CONVERT_TO_ODD(pasteRoi->right);
pasteRoi->up = CONVERT_TO_EVEN(pasteRoi->up);
pasteRoi->down = CONVERT_TO_ODD(pasteRoi->down);
return;
}

/*
* @description: Resize the image specified by input and save the result to member variable resizedImage_
* @param: input specifies the input image information
* @param: output specifies the output image information
* @param: withSynchronize specifies whether to execute synchronously
* @param: processType specifies whether to perform proportional scaling, default is non-proportional resize
* @return: OK if success, other values if failure
* @attention: This function can be called only when the DvppCommon object is initialized with Init
*/
int DvppCommon::CombineResizeProcess(std::shared_ptr<DvppDataInfo> input, const DvppDataInfo &output,
bool withSynchronize, VpcProcessType processType) {
int ret = CheckResizeParams(*input, output);
if (ret != OK) {
return ret;
}
// Get widthStride and heightStride for input and output image according to the format
ret = GetVpcInputStrideSize(input->widthStride, input->heightStride, input->format,
&(input->widthStride), &(input->heightStride));
if (ret != OK) {
return ret;
}

resizedImage_ = std::make_shared<DvppDataInfo>();
resizedImage_->width = output.width;
resizedImage_->height = output.height;
resizedImage_->format = output.format;
ret = GetVpcOutputStrideSize(output.width, output.height, output.format, &(resizedImage_->widthStride),
&(resizedImage_->heightStride));
if (ret != OK) {
return ret;
}
// Get output buffer size for resize output
ret = GetVpcDataSize(output.width, output.height, output.format, &(resizedImage_->dataSize));
if (ret != OK) {
return ret;
}
// Malloc buffer for output of resize module
// Need to pay attention to release of the buffer
ret = acldvppMalloc(reinterpret_cast<void **>(&(resizedImage_->data)), resizedImage_->dataSize);
if (ret != OK) {
std::cout << "Failed to malloc " << resizedImage_->dataSize << " bytes on dvpp for resize" << std::endl;
return ret;
}

aclrtMemset(resizedImage_->data, resizedImage_->dataSize, YUV_GREYER_VALUE, resizedImage_->dataSize);
resizedImage_->frameId = input->frameId;
ret = VpcResize(input, resizedImage_, withSynchronize, processType);
if (ret != OK) {
// Release the output buffer when resize failed, otherwise release it after use
RELEASE_DVPP_DATA(resizedImage_->data);
}
return ret;
}

/*
* @description: Set the description of the output image and decode
* @param: input specifies the input image information
* @param: output specifies the output image information
* @param: withSynchronize specifies whether to execute synchronously
* @return: OK if success, other values if failure
* @attention: This function can be called only when the DvppCommon object is initialized with Init
*/
int DvppCommon::JpegDecode(std::shared_ptr<DvppDataInfo> input,
std::shared_ptr<DvppDataInfo> output,
bool withSynchronize) {
acldvppPicDesc *outputDesc = acldvppCreatePicDesc();
decodeOutputDesc_.reset(outputDesc, g_picDescDeleter);

int ret = SetDvppPicDescData(output, decodeOutputDesc_);
if (ret != OK) {
return ret;
}

ret = acldvppJpegDecodeAsync(dvppChannelDesc_, input->data, input->dataSize, decodeOutputDesc_.get(), dvppStream_);
if (ret != OK) {
std::cout << "Failed to decode jpeg, ret = " << ret << "." << std::endl;
return ret;
}
if (withSynchronize) {
ret = aclrtSynchronizeStream(dvppStream_);
if (ret != OK) {
std::cout << "Failed to synchronize stream, ret = " << ret << "." << std::endl;
return DECODE_FAIL;
}
}
return OK;
}

/*
* @description: Get the aligned width and height of the image after decoding
* @param: width specifies the width before alignment
* @param: height specifies the height before alignment
* @param: widthStride is used to save the width after alignment
* @param: heightStride is used to save the height after alignment
* @return: OK if success, other values if failure
*/
void DvppCommon::GetJpegDecodeStrideSize(uint32_t width, uint32_t height,
uint32_t *widthStride, uint32_t *heightStride) {
*widthStride = DVPP_ALIGN_UP(width, JPEGD_STRIDE_WIDTH);
*heightStride = DVPP_ALIGN_UP(height, JPEGD_STRIDE_HEIGHT);
}

/*
* @description: Get picture width and height and number of channels from image data
* @param: data specifies the memory to store the image data
* @param: dataSize specifies the size of the image data
* @param: width is used to save the image width
* @param: height is used to save the image height
* @param: components is used to save the number of channels
* @return: OK if success, other values if failure
*/
int DvppCommon::GetJpegImageInfo(const void *data, uint32_t dataSize, uint32_t *width, uint32_t *height,
int32_t *components) {
uint32_t widthTmp;
uint32_t heightTmp;
int32_t componentsTmp;
int ret = acldvppJpegGetImageInfo(data, dataSize, &widthTmp, &heightTmp, &componentsTmp);
if (ret != OK) {
std::cout << "Failed to get image info of jpeg, ret = " << ret << "." << std::endl;
return ret;
}
if (widthTmp > MAX_JPEGD_WIDTH || widthTmp < MIN_JPEGD_WIDTH) {
std::cout << "Input width is invalid, not in [" << MIN_JPEGD_WIDTH << ", "
<< MAX_JPEGD_WIDTH << "]." << std::endl;
return INVALID_PARAM;
}
if (heightTmp > MAX_JPEGD_HEIGHT || heightTmp < MIN_JPEGD_HEIGHT) {
std::cout << "Input height is invalid, not in [" << MIN_JPEGD_HEIGHT << ", "
<< MAX_JPEGD_HEIGHT << "]." << std::endl;
return INVALID_PARAM;
}
*width = widthTmp;
*height = heightTmp;
*components = componentsTmp;
return OK;
}

/*
* @description: Get the size of the buffer for storing decoded images based on the image data, size, and format
* @param: data specifies the memory to store the image data
* @param: dataSize specifies the size of the image data
* @param: format specifies the image format
* @param: decSize is used to store the result size
* @return: OK if success, other values if failure
*/
int DvppCommon::GetJpegDecodeDataSize(const void *data, uint32_t dataSize, acldvppPixelFormat format,
uint32_t *decSize) {
uint32_t outputSize;
int ret = acldvppJpegPredictDecSize(data, dataSize, format, &outputSize);
if (ret != OK) {
std::cout << "Failed to predict decode size of jpeg image, ret = " << ret << "." << std::endl;
return ret;
}
*decSize = outputSize;
return OK;
}

/*
* @description: Decode the image specified by imageInfo and save the result to member variable decodedImage_
* @param: imageInfo specifies image information
* @param: format specifies the image format
* @param: withSynchronize specifies whether to execute synchronously
* @return: OK if success, other values if failure
* @attention: This function can be called only when the DvppCommon object is initialized with Init
*/
int DvppCommon::CombineJpegdProcess(const RawData& imageInfo, acldvppPixelFormat format, bool withSynchronize) {
int32_t components;
inputImage_ = std::make_shared<DvppDataInfo>();
inputImage_->format = format;
int ret = GetJpegImageInfo(imageInfo.data.get(), imageInfo.lenOfByte, &(inputImage_->width), &(inputImage_->height),
&components);
if (ret != OK) {
std::cout << "Failed to get input image info, ret = " << ret << "." << std::endl;
return ret;
}

// Get the buffer size of decode output according to the input data and output format
uint32_t outBuffSize;
ret = GetJpegDecodeDataSize(imageInfo.data.get(), imageInfo.lenOfByte, format, &outBuffSize);
if (ret != OK) {
std::cout << "Failed to get size of decode output buffer, ret = " << ret << "." << std::endl;
return ret;
}

// In TransferImageH2D function, device buffer will be allocated to store the input image
// Need to pay attention to release of the buffer
ret = TransferImageH2D(imageInfo, inputImage_);
if (ret != OK) {
return ret;
}

decodedImage_ = std::make_shared<DvppDataInfo>();
decodedImage_->format = format;
decodedImage_->width = inputImage_->width;
decodedImage_->height = inputImage_->height;
GetJpegDecodeStrideSize(inputImage_->width, inputImage_->height, &(decodedImage_->widthStride),
&(decodedImage_->heightStride));
decodedImage_->dataSize = outBuffSize;
// Need to pay attention to release of the buffer
ret = acldvppMalloc(reinterpret_cast<void **>(&decodedImage_->data), decodedImage_->dataSize);
if (ret != OK) {
std::cout << "Failed to malloc memory on dvpp, ret = " << ret << "." << std::endl;
RELEASE_DVPP_DATA(inputImage_->data);
return ret;
}

ret = JpegDecode(inputImage_, decodedImage_, withSynchronize);
if (ret != OK) {
RELEASE_DVPP_DATA(inputImage_->data);
inputImage_->data = nullptr;
RELEASE_DVPP_DATA(decodedImage_->data);
decodedImage_->data = nullptr;
return ret;
}

return OK;
}

/*
* @description: Transfer data from host to device
* @param: imageInfo specifies the image data on the host
* @param: jpegInput is used to save the buffer and its size which is allocate on the device
* @return: OK if success, other values if failure
*/
int DvppCommon::TransferImageH2D(const RawData& imageInfo, const std::shared_ptr<DvppDataInfo>& jpegInput) {
if (imageInfo.lenOfByte == 0) {
std::cout << "The input buffer size on host should not be empty." << std::endl;
return INVALID_PARAM;
}

uint8_t* inDevBuff = nullptr;
int ret = acldvppMalloc(reinterpret_cast<void **>(&inDevBuff), imageInfo.lenOfByte);
if (ret != OK) {
std::cout << "Failed to malloc " << imageInfo.lenOfByte << " bytes on dvpp, ret = " << ret << "." << std::endl;
return ret;
}

// Copy the image data from host to device
ret = aclrtMemcpyAsync(inDevBuff, imageInfo.lenOfByte, imageInfo.data.get(), imageInfo.lenOfByte,
ACL_MEMCPY_HOST_TO_DEVICE, dvppStream_);
if (ret != OK) {
std::cout << "Failed to copy " << imageInfo.lenOfByte << " bytes from host to device" << std::endl;
RELEASE_DVPP_DATA(inDevBuff);
return ret;
}
// Attention: We must call the aclrtSynchronizeStream to ensure the task of memory replication has been completed
// after calling aclrtMemcpyAsync
ret = aclrtSynchronizeStream(dvppStream_);
if (ret != OK) {
std::cout << "Failed to synchronize stream, ret = " << ret << "." << std::endl;
RELEASE_DVPP_DATA(inDevBuff);
return ret;
}
jpegInput->data = inDevBuff;
jpegInput->dataSize = imageInfo.lenOfByte;
return OK;
}

std::shared_ptr<DvppDataInfo> DvppCommon::GetInputImage() {
return inputImage_;
}

std::shared_ptr<DvppDataInfo> DvppCommon::GetDecodedImage() {
return decodedImage_;
}

std::shared_ptr<DvppDataInfo> DvppCommon::GetResizedImage() {
return resizedImage_;
}

DvppCommon::~DvppCommon() {}

+ 0
- 226
model_zoo/official/cv/maskrcnn/ascend310_infer/src/ModelProcess.cpp View File

@@ -1,226 +0,0 @@
/*
* Copyright(C) 2020. Huawei Technologies Co.,Ltd. All rights reserved.
*
* 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 <sys/time.h>
#include <fstream>
#include "../inc/ModelProcess.h"

ModelProcess::ModelProcess(const int deviceId) {
deviceId_ = deviceId;
}

ModelProcess::ModelProcess() {}

ModelProcess::~ModelProcess() {
if (!isDeInit_) {
DeInit();
}
}

void ModelProcess::DestroyDataset(aclmdlDataset *dataset) {
// Just release the DataBuffer object and DataSet object, remain the buffer, because it is managerd by user
if (dataset != nullptr) {
for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(dataset); i++) {
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(dataset, i);
if (dataBuffer != nullptr) {
aclDestroyDataBuffer(dataBuffer);
dataBuffer = nullptr;
}
}
aclmdlDestroyDataset(dataset);
}
}

aclmdlDesc *ModelProcess::GetModelDesc() {
return modelDesc_.get();
}

int ModelProcess::ModelInference(const std::vector<void *> &inputBufs,
const std::vector<size_t> &inputSizes,
const std::vector<void *> &ouputBufs,
const std::vector<size_t> &outputSizes,
std::map<double, double> *costTime_map) {
std::cout << "ModelProcess:Begin to inference." << std::endl;
aclmdlDataset *input = nullptr;
input = CreateAndFillDataset(inputBufs, inputSizes);
if (input == nullptr) {
return INVALID_POINTER;
}
int ret;

aclmdlDataset *output = nullptr;
output = CreateAndFillDataset(ouputBufs, outputSizes);
if (output == nullptr) {
DestroyDataset(input);
input = nullptr;
return INVALID_POINTER;
}
struct timeval start;
struct timeval end;
double startTime_ms;
double endTime_ms;
mtx_.lock();
gettimeofday(&start, NULL);
ret = aclmdlExecute(modelId_, input, output);
gettimeofday(&end, NULL);
startTime_ms = (1.0 * start.tv_sec * 1000000 + start.tv_usec) / 1000;
endTime_ms = (1.0 * end.tv_sec * 1000000 + end.tv_usec) / 1000;
costTime_map->insert(std::pair<double, double>(startTime_ms, endTime_ms));
mtx_.unlock();
if (ret != OK) {
std::cout << "aclmdlExecute failed, ret[" << ret << "]." << std::endl;
return ret;
}

DestroyDataset(input);
DestroyDataset(output);
return OK;
}

int ModelProcess::DeInit() {
isDeInit_ = true;
int ret = aclmdlUnload(modelId_);
if (ret != OK) {
std::cout << "aclmdlUnload failed, ret["<< ret << "]." << std::endl;
return ret;
}

if (modelDevPtr_ != nullptr) {
ret = aclrtFree(modelDevPtr_);
if (ret != OK) {
std::cout << "aclrtFree failed, ret[" << ret << "]." << std::endl;
return ret;
}
modelDevPtr_ = nullptr;
}
if (weightDevPtr_ != nullptr) {
ret = aclrtFree(weightDevPtr_);
if (ret != OK) {
std::cout << "aclrtFree failed, ret[" << ret << "]." << std::endl;
return ret;
}
weightDevPtr_ = nullptr;
}

return OK;
}
/**
* Read a binary file, store the data into a uint8_t array
*
* @param fileName the file for reading
* @param buffShared a shared pointer to a uint8_t array for storing file
* @param buffLength the length of the array
* @return OK if create success, error code otherwise
*/
int ModelProcess::ReadBinaryFile(const std::string &fileName, uint8_t **buffShared, int *buffLength) {
std::ifstream inFile(fileName, std::ios::in | std::ios::binary);
if (!inFile) {
std::cout << "FaceFeatureLib: read file " << fileName << " fail." <<std::endl;
return READ_FILE_FAIL;
}

inFile.seekg(0, inFile.end);
*buffLength = inFile.tellg();
inFile.seekg(0, inFile.beg);

uint8_t *tempShared = reinterpret_cast<uint8_t *>(malloc(*buffLength));
inFile.read(reinterpret_cast<char *>(tempShared), *buffLength);
inFile.close();
*buffShared = tempShared;

std::cout << "read file: fileName=" << fileName << ", size=" << *buffLength << "." << std::endl;

return OK;
}

int ModelProcess::Init(const std::string &modelPath) {
std::cout << "ModelProcess:Begin to init instance." << std::endl;
int modelSize = 0;
uint8_t *modelData = nullptr;
int ret = ReadBinaryFile(modelPath, &modelData, &modelSize);
if (ret != OK) {
std::cout << "read model file failed, ret[" << ret << "]." << std::endl;
return ret;
}
ret = aclmdlQuerySizeFromMem(modelData, modelSize, &modelDevPtrSize_, &weightDevPtrSize_);
if (ret != OK) {
std::cout << "aclmdlQuerySizeFromMem failed, ret[" << ret << "]." << std::endl;
return ret;
}
std::cout << "modelDevPtrSize_[" << modelDevPtrSize_ << "]" << std::endl;
std::cout << " weightDevPtrSize_[" << weightDevPtrSize_ << "]." << std::endl;

ret = aclrtMalloc(&modelDevPtr_, modelDevPtrSize_, ACL_MEM_MALLOC_HUGE_FIRST);
if (ret != OK) {
std::cout << "aclrtMalloc dev_ptr failed, ret[" << ret << "]." << std::endl;
return ret;
}
ret = aclrtMalloc(&weightDevPtr_, weightDevPtrSize_, ACL_MEM_MALLOC_HUGE_FIRST);
if (ret != OK) {
std::cout << "aclrtMalloc weight_ptr failed, ret[" << ret << "] " << std::endl;
return ret;
}
ret = aclmdlLoadFromMemWithMem(modelData, modelSize, &modelId_, modelDevPtr_, modelDevPtrSize_,
weightDevPtr_, weightDevPtrSize_);
if (ret != OK) {
std::cout << "aclmdlLoadFromMemWithMem failed, ret[" << ret << "]." << std::endl;
return ret;
}
ret = aclrtGetCurrentContext(&contextModel_);
if (ret != OK) {
std::cout << "aclrtMalloc weight_ptr failed, ret[" << ret << "]." << std::endl;
return ret;
}

aclmdlDesc *modelDesc = aclmdlCreateDesc();
if (modelDesc == nullptr) {
std::cout << "aclmdlCreateDesc failed." << std::endl;
return ret;
}
ret = aclmdlGetDesc(modelDesc, modelId_);
if (ret != OK) {
std::cout << "aclmdlGetDesc ret fail, ret:" << ret << "." << std::endl;
return ret;
}
modelDesc_.reset(modelDesc, aclmdlDestroyDesc);
free(modelData);
return OK;
}

aclmdlDataset *ModelProcess::CreateAndFillDataset(const std::vector<void *> &bufs, const std::vector<size_t> &sizes) {
aclmdlDataset *dataset = aclmdlCreateDataset();
if (dataset == nullptr) {
std::cout << "ACL_ModelInputCreate failed." << std::endl;
return nullptr;
}

for (size_t i = 0; i < bufs.size(); ++i) {
aclDataBuffer *data = aclCreateDataBuffer(bufs[i], sizes[i]);
if (data == nullptr) {
DestroyDataset(dataset);
std::cout << "aclCreateDataBuffer failed." << std::endl;
return nullptr;
}

int ret = aclmdlAddDatasetBuffer(dataset, data);
if (ret != OK) {
DestroyDataset(dataset);
std::cout << "ACL_ModelInputDataAdd failed, ret[" << ret << "]." << std::endl;
return nullptr;
}
}
return dataset;
}

+ 0
- 56
model_zoo/official/cv/maskrcnn/ascend310_infer/src/build.sh View File

@@ -1,56 +0,0 @@
#!/bin/bash
# Copyright 2020 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
path_cur=$(cd "`dirname $0`" || exit; pwd)
build_type="Release"

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 -DCMAKE_BUILD_TYPE=$build_type ..
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

+ 235
- 0
model_zoo/official/cv/maskrcnn/ascend310_infer/src/main.cc View File

@@ -0,0 +1,235 @@
/**
* 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 <sys/time.h>
#include <gflags/gflags.h>
#include <dirent.h>
#include <iostream>
#include <string>
#include <algorithm>
#include <iosfwd>
#include <vector>
#include <fstream>
#include <sstream>

#include "include/api/context.h"
#include "include/api/model.h"
#include "include/api/types.h"
#include "include/api/serialization.h"
#include "include/minddata/dataset/include/vision.h"
#include "include/minddata/dataset/include/transforms.h"
#include "include/minddata/dataset/include/execute.h"
#include "../inc/utils.h"

using mindspore::Context;
using mindspore::Serialization;
using mindspore::Model;
using mindspore::Status;
using mindspore::ModelType;
using mindspore::GraphCell;
using mindspore::kSuccess;
using mindspore::MSTensor;
using mindspore::DataType;
using mindspore::dataset::Execute;
using mindspore::dataset::TensorTransform;
using mindspore::dataset::vision::Resize;
using mindspore::dataset::vision::Pad;
using mindspore::dataset::vision::HWC2CHW;
using mindspore::dataset::vision::Normalize;
using mindspore::dataset::vision::SwapRedBlue;
using mindspore::dataset::vision::Decode;
using mindspore::dataset::transforms::TypeCast;


DEFINE_string(mindir_path, "", "mindir path");
DEFINE_string(dataset_path, ".", "dataset path");
DEFINE_int32(device_id, 0, "device id");

const int IMAGEWIDTH = 1280;
const int IMAGEHEIGHT = 768;

int PadImage(const MSTensor &input, MSTensor *output) {
std::shared_ptr<TensorTransform> normalize(new Normalize({103.53, 116.28, 123.675},
{57.375, 57.120, 58.395}));
Execute composeNormalize({normalize});
std::vector<int64_t> shape = input.Shape();
auto imgResize = MSTensor();
auto imgPad = MSTensor();

float widthScale, heightScale;
widthScale = static_cast<float>(IMAGEWIDTH) / shape[1];
heightScale = static_cast<float>(IMAGEHEIGHT) / shape[0];
Status ret;
if (widthScale < heightScale) {
int heightSize = shape[0]*widthScale;
std::shared_ptr<TensorTransform> resize(new Resize({heightSize, IMAGEWIDTH}));
Execute composeResizeWidth({resize});
ret = composeResizeWidth(input, &imgResize);
if (ret != kSuccess) {
std::cout << "ERROR: Resize Width failed." << std::endl;
return 1;
}

int paddingSize = IMAGEHEIGHT - heightSize;
std::shared_ptr<TensorTransform> pad(new Pad({0, 0, 0, paddingSize}));
Execute composePad({pad});
ret = composePad(imgResize, &imgPad);
if (ret != kSuccess) {
std::cout << "ERROR: Height Pad failed." << std::endl;
return 1;
}

ret = composeNormalize(imgPad, output);
if (ret != kSuccess) {
std::cout << "ERROR: Normalize failed." << std::endl;
return 1;
}
} else {
int widthSize = shape[1]*heightScale;
std::shared_ptr<TensorTransform> resize(new Resize({IMAGEHEIGHT, widthSize}));
Execute composeResizeHeight({resize});
ret = composeResizeHeight(input, &imgResize);
if (ret != kSuccess) {
std::cout << "ERROR: Resize Height failed." << std::endl;
return 1;
}

int paddingSize = IMAGEWIDTH - widthSize;
std::shared_ptr<TensorTransform> pad(new Pad({0, 0, paddingSize, 0}));
Execute composePad({pad});
ret = composePad(imgResize, &imgPad);
if (ret != kSuccess) {
std::cout << "ERROR: Width Pad failed." << std::endl;
return 1;
}

ret = composeNormalize(imgPad, output);
if (ret != kSuccess) {
std::cout << "ERROR: Normalize failed." << std::endl;
return 1;
}
}
return 0;
}

int main(int argc, char **argv) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
if (RealPath(FLAGS_mindir_path).empty()) {
std::cout << "Invalid mindir" << std::endl;
return 1;
}

auto context = std::make_shared<Context>();
auto ascend310 = std::make_shared<mindspore::Ascend310DeviceInfo>();
ascend310->SetDeviceID(FLAGS_device_id);
ascend310->SetPrecisionMode("allow_fp32_to_fp16");
context->MutableDeviceInfo().push_back(ascend310);
mindspore::Graph graph;
Serialization::Load(FLAGS_mindir_path, ModelType::kMindIR, &graph);

Model model;
Status ret = model.Build(GraphCell(graph), context);
if (ret != kSuccess) {
std::cout << "ERROR: Build failed." << std::endl;
return 1;
}
std::vector<MSTensor> model_inputs = model.GetInputs();

auto all_files = GetAllFiles(FLAGS_dataset_path);
if (all_files.empty()) {
std::cout << "ERROR: no input data." << std::endl;
return 1;
}

std::map<double, double> costTime_map;
size_t size = all_files.size();
std::shared_ptr<TensorTransform> decode(new Decode());
Execute composeDecode({decode});
std::shared_ptr<TensorTransform> hwc2chw(new HWC2CHW());
Execute composeTranspose({hwc2chw});
std::shared_ptr<TensorTransform> typeCast(new TypeCast(DataType::kNumberTypeFloat16));
Execute transformCast(typeCast);

for (size_t i = 0; i < size; ++i) {
struct timeval start = {0};
struct timeval end = {0};
double startTimeMs;
double endTimeMs;
std::vector<MSTensor> inputs;
std::vector<MSTensor> outputs;
std::cout << "Start predict input files:" << all_files[i] << std::endl;
auto imgDecode = MSTensor();
auto image = ReadFileToTensor(all_files[i]);
composeDecode(image, &imgDecode);

auto imgPad = MSTensor();
PadImage(imgDecode, &imgPad);
auto img = MSTensor();
composeTranspose(imgPad, &img);
transformCast(img, &img);

std::vector<int64_t> shape = imgDecode.Shape();

float widthScale = static_cast<float>(IMAGEWIDTH) / shape[1];
float heightScale = static_cast<float>(IMAGEHEIGHT) / shape[0];
float resizeScale = widthScale < heightScale ? widthScale : heightScale;

float imgInfo[4];
imgInfo[0] = shape[0];
imgInfo[1] = shape[1];
imgInfo[2] = resizeScale;
imgInfo[3] = resizeScale;

MSTensor imgMeta("imgMeta", DataType::kNumberTypeFloat32, {static_cast<int64_t>(4)}, imgInfo, 16);
transformCast(imgMeta, &imgMeta);

inputs.emplace_back(model_inputs[0].Name(), model_inputs[0].DataType(), model_inputs[0].Shape(),
img.Data().get(), img.DataSize());
inputs.emplace_back(model_inputs[1].Name(), model_inputs[1].DataType(), model_inputs[1].Shape(),
imgMeta.Data().get(), imgMeta.DataSize());

gettimeofday(&start, nullptr);
ret = model.Predict(inputs, &outputs);
gettimeofday(&end, nullptr);
if (ret != kSuccess) {
std::cout << "Predict " << all_files[i] << " failed." << std::endl;
return 1;
}
startTimeMs = (1.0 * start.tv_sec * 1000000 + start.tv_usec) / 1000;
endTimeMs = (1.0 * end.tv_sec * 1000000 + end.tv_usec) / 1000;
costTime_map.insert(std::pair<double, double>(startTimeMs, endTimeMs));
WriteResult(all_files[i], outputs);
}
double average = 0.0;
int inferCount = 0;

for (auto iter = costTime_map.begin(); iter != costTime_map.end(); iter++) {
double diff = 0.0;
diff = iter->second - iter->first;
average += diff;
inferCount++;
}
average = average / inferCount;
std::stringstream timeCost;
timeCost << "NN inference cost average time: "<< average << " ms of infer_count " << inferCount << std::endl;
std::cout << "NN inference cost average time: "<< average << "ms of infer_count " << inferCount << std::endl;

std::string fileName = "./time_Result" + std::string("/test_perform_static.txt");
std::ofstream fileStream(fileName.c_str(), std::ios::trunc);
fileStream << timeCost.str();
fileStream.close();
costTime_map.clear();
return 0;
}

+ 0
- 132
model_zoo/official/cv/maskrcnn/ascend310_infer/src/main.cpp View File

@@ -1,132 +0,0 @@
/*
* Copyright (c) 2020.Huawei Technologies Co., Ltd. All rights reserved.
* 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 <dirent.h>
#include <sys/stat.h>
#include <gflags/gflags.h>
#include <unistd.h>
#include <cstring>
#include <fstream>
#include <sstream>
#include "../inc/AclProcess.h"
#include "../inc/CommonDataType.h"

DEFINE_string(om_path, "./maskrcnn.om", "om model path.");
DEFINE_string(data_path, "./test.jpg", "om model path.");
DEFINE_int32(width, 1280, "width");
DEFINE_int32(height, 768, "height");
DEFINE_int32(device_id, 0, "height");

static bool is_file(const std::string &filename) {
struct stat buffer;
return (stat(filename.c_str(), &buffer) == 0 && S_ISREG(buffer.st_mode));
}

static bool is_dir(const std::string &filefodler) {
struct stat buffer;
return (stat(filefodler.c_str(), &buffer) == 0 && S_ISDIR(buffer.st_mode));
}
/*
* @description Initialize and run AclProcess module
* @param resourceInfo resource info of deviceIds, model info, single Operator Path, etc
* @param file the absolute path of input file
* @return int int code
*/
int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
std::cout << "OM File Path :" << FLAGS_om_path << std::endl;
std::cout << "data Path :" << FLAGS_data_path << std::endl;
std::cout << "width :" << FLAGS_width << std::endl;
std::cout << "height :" << FLAGS_height << std::endl;
std::cout << "deviceId :" << FLAGS_device_id << std::endl;

char omAbsPath[PATH_MAX];
if (realpath(FLAGS_om_path.c_str(), omAbsPath) == nullptr) {
std::cout << "Failed to get the om real path." << std::endl;
return INVALID_PARAM;
}

if (access(omAbsPath, R_OK) == -1) {
std::cout << "ModelPath " << omAbsPath << " doesn't exist or read failed." << std::endl;
return INVALID_PARAM;
}

char dataAbsPath[PATH_MAX];
if (realpath(FLAGS_data_path.c_str(), dataAbsPath) == nullptr) {
std::cout << "Failed to get the data real path." << std::endl;
return INVALID_PARAM;
}
if (access(dataAbsPath, R_OK) == -1) {
std::cout << "data paeh " << dataAbsPath << " doesn't exist or read failed." << std::endl;
return INVALID_PARAM;
}

std::map<double, double> costTime_map;
AclProcess aclProcess(FLAGS_device_id, FLAGS_om_path, FLAGS_width, FLAGS_height);
int ret = aclProcess.InitResource();
if (ret != OK) {
aclProcess.Release();
return ret;
}
if (is_file(FLAGS_data_path)) {
ret = aclProcess.Process(FLAGS_data_path, &costTime_map);
if (ret != OK) {
std::cout << "model process failed, errno = " << ret << std::endl;
return ret;
}
} else if (is_dir(FLAGS_data_path)) {
struct dirent *filename;
DIR *dir;
dir = opendir(FLAGS_data_path.c_str());
if (dir == nullptr) {
return ERROR;
}

while ((filename = readdir(dir)) != nullptr) {
if (strcmp(filename->d_name, ".") == 0 || strcmp(filename->d_name, "..") == 0) {
continue;
}
std::string wholePath = FLAGS_data_path + "/" + filename->d_name;
ret = aclProcess.Process(wholePath, &costTime_map);
if (ret != OK) {
std::cout << "model process failed, errno = " << ret << std::endl;
return ret;
}
}
} else {
std::cout << " input image path error" << std::endl;
}

double average = 0.0;
int infer_cnt = 0;

for (auto iter = costTime_map.begin(); iter != costTime_map.end(); iter++) {
double diff = 0.0;
diff = iter->second - iter->first;
average += diff;
infer_cnt++;
}
average = average / infer_cnt;
std::stringstream timeCost;
timeCost << "NN inference cost average time: "<< average << " ms of infer_count " << infer_cnt << std::endl;
std::cout << "NN inference cost average time: "<< average << "ms of infer_count " << infer_cnt << std::endl;
std::string file_name = "./time_Result" + std::string("/test_perform_static.txt");
std::ofstream file_stream(file_name.c_str(), std::ios::trunc);
file_stream << timeCost.str();
file_stream.close();
costTime_map.clear();

aclProcess.Release();
return OK;
}

+ 129
- 0
model_zoo/official/cv/maskrcnn/ascend310_infer/src/utils.cc View File

@@ -0,0 +1,129 @@
/**
* 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 <fstream>
#include <algorithm>
#include <iostream>
#include "../inc/utils.h"

using mindspore::MSTensor;
using mindspore::DataType;

std::vector<std::string> GetAllFiles(std::string_view dirName) {
struct dirent *filename;
DIR *dir = OpenDir(dirName);
if (dir == nullptr) {
return {};
}
std::vector<std::string> res;
while ((filename = readdir(dir)) != nullptr) {
std::string dName = std::string(filename->d_name);
if (dName == "." || dName == ".." || filename->d_type != DT_REG) {
continue;
}
res.emplace_back(std::string(dirName) + "/" + filename->d_name);
}
std::sort(res.begin(), res.end());
for (auto &f : res) {
std::cout << "image file: " << f << std::endl;
}
return res;
}

int WriteResult(const std::string& imageFile, const std::vector<MSTensor> &outputs) {
std::string homePath = "./result_Files";
for (size_t i = 0; i < outputs.size(); ++i) {
size_t outputSize;
std::shared_ptr<const void> netOutput;
netOutput = outputs[i].Data();
outputSize = outputs[i].DataSize();
int pos = imageFile.rfind('/');
std::string fileName(imageFile, pos + 1);
fileName.replace(fileName.find('.'), fileName.size() - fileName.find('.'), '_' + std::to_string(i) + ".bin");
std::string outFileName = homePath + "/" + fileName;
FILE * outputFile = fopen(outFileName.c_str(), "wb");
fwrite(netOutput.get(), outputSize, sizeof(char), outputFile);
fclose(outputFile);
outputFile = nullptr;
}
return 0;
}

MSTensor ReadFileToTensor(const std::string &file) {
if (file.empty()) {
std::cout << "Pointer file is nullptr" << std::endl;
return MSTensor();
}

std::ifstream ifs(file);
if (!ifs.good()) {
std::cout << "File: " << file << " is not exist" << std::endl;
return MSTensor();
}

if (!ifs.is_open()) {
std::cout << "File: " << file << "open failed" << std::endl;
return MSTensor();
}

ifs.seekg(0, std::ios::end);
size_t size = ifs.tellg();
MSTensor buffer(file, mindspore::DataType::kNumberTypeUInt8, {static_cast<int64_t>(size)}, nullptr, size);

ifs.seekg(0, std::ios::beg);
ifs.read(reinterpret_cast<char *>(buffer.MutableData()), size);
ifs.close();

return buffer;
}


DIR *OpenDir(std::string_view dirName) {
if (dirName.empty()) {
std::cout << " dirName is null ! " << std::endl;
return nullptr;
}
std::string realPath = RealPath(dirName);
struct stat s;
lstat(realPath.c_str(), &s);
if (!S_ISDIR(s.st_mode)) {
std::cout << "dirName is not a valid directory !" << std::endl;
return nullptr;
}
DIR *dir;
dir = opendir(realPath.c_str());
if (dir == nullptr) {
std::cout << "Can not open dir " << dirName << std::endl;
return nullptr;
}
std::cout << "Successfully opened the dir " << dirName << std::endl;
return dir;
}

std::string RealPath(std::string_view path) {
char realPathMem[PATH_MAX] = {0};
char *realPathRet = nullptr;
realPathRet = realpath(path.data(), realPathMem);

if (realPathRet == nullptr) {
std::cout << "File: " << path << " is not exist.";
return "";
}

std::string realPath(realPathMem);
std::cout << path << " realpath is: " << realPath << std::endl;
return realPath;
}

+ 10
- 8
model_zoo/official/cv/maskrcnn/postprocess.py View File

@@ -13,6 +13,7 @@
# limitations under the License. # limitations under the License.
# ============================================================================ # ============================================================================
"""post process for 310 inference""" """post process for 310 inference"""
import os
import argparse import argparse
import numpy as np import numpy as np
from PIL import Image from PIL import Image
@@ -27,6 +28,7 @@ dst_height = 768
parser = argparse.ArgumentParser(description="maskrcnn inference") parser = argparse.ArgumentParser(description="maskrcnn inference")
parser.add_argument("--ann_file", type=str, required=True, help="ann file.") parser.add_argument("--ann_file", type=str, required=True, help="ann file.")
parser.add_argument("--img_path", type=str, required=True, help="image file path.") parser.add_argument("--img_path", type=str, required=True, help="image file path.")
parser.add_argument("--result_path", type=str, required=True, help="result file path.")
args = parser.parse_args() args = parser.parse_args()


def get_img_size(file_name): def get_img_size(file_name):
@@ -41,10 +43,10 @@ def get_resize_ratio(img_size):


return resize_ratio return resize_ratio


def get_eval_result(ann_file, img_path):
def get_eval_result(ann_file, img_path, result_path):
""" Get metrics result according to the annotation file and result file""" """ Get metrics result according to the annotation file and result file"""
max_num = 128 max_num = 128
result_path = "./result_Files/"
result_path = result_path
outputs = [] outputs = []


dataset_coco = COCO(ann_file) dataset_coco = COCO(ann_file)
@@ -52,16 +54,16 @@ def get_eval_result(ann_file, img_path):


for img_id in img_ids: for img_id in img_ids:
file_id = str(img_id).zfill(12) file_id = str(img_id).zfill(12)
file = img_path + "/" + file_id + ".jpg"
file = os.path.join(img_path, file_id + ".jpg")
img_size = get_img_size(file) img_size = get_img_size(file)
resize_ratio = get_resize_ratio(img_size) resize_ratio = get_resize_ratio(img_size)


img_metas = np.array([img_size[1], img_size[0]] + [resize_ratio, resize_ratio]) img_metas = np.array([img_size[1], img_size[0]] + [resize_ratio, resize_ratio])


bbox_result_file = result_path + file_id + "_0.bin"
label_result_file = result_path + file_id + "_1.bin"
mask_result_file = result_path + file_id + "_2.bin"
mask_fb_result_file = result_path + file_id + "_3.bin"
bbox_result_file = os.path.join(result_path, file_id + "_0.bin")
label_result_file = os.path.join(result_path, file_id + "_1.bin")
mask_result_file = os.path.join(result_path, file_id + "_2.bin")
mask_fb_result_file = os.path.join(result_path, file_id + "_3.bin")


all_bbox = np.fromfile(bbox_result_file, dtype=np.float16).reshape(80000, 5) all_bbox = np.fromfile(bbox_result_file, dtype=np.float16).reshape(80000, 5)
all_label = np.fromfile(label_result_file, dtype=np.int32).reshape(80000, 1) all_label = np.fromfile(label_result_file, dtype=np.int32).reshape(80000, 1)
@@ -94,4 +96,4 @@ def get_eval_result(ann_file, img_path):
coco_eval(result_files, eval_types, dataset_coco, single_result=False) coco_eval(result_files, eval_types, dataset_coco, single_result=False)


if __name__ == '__main__': if __name__ == '__main__':
get_eval_result(args.ann_file, args.img_path)
get_eval_result(args.ann_file, args.img_path, args.result_path)

+ 21
- 35
model_zoo/official/cv/maskrcnn/scripts/run_infer_310.sh View File

@@ -14,60 +14,51 @@
# limitations under the License. # limitations under the License.
# ============================================================================ # ============================================================================


if [[ $# -lt 3 || $# -gt 4 ]]; then
echo "Usage: sh run_infer_310.sh [AIR_PATH] [DATA_PATH] [ANN_FILE_PATH] [DEVICE_ID]
if [[ $# -lt 3 || $# -gt 4 ]]; then
echo "Usage: bash run_infer_310.sh [MINDIR_PATH] [DATA_PATH] [ANN_FILE] [DEVICE_ID]
DEVICE_ID is optional, it can be set by environment variable device_id, otherwise the value is zero" DEVICE_ID is optional, it can be set by environment variable device_id, otherwise the value is zero"
exit 1 exit 1
fi fi


get_real_path(){ get_real_path(){
if [ "${1:0:1}" == "/" ]; then
echo "$1"
else
echo "$(realpath -m $PWD/$1)"
fi
if [ "${1:0:1}" == "/" ]; then
echo "$1"
else
echo "$(realpath -m $PWD/$1)"
fi
} }
model=$(get_real_path $1) model=$(get_real_path $1)
data_path=$(get_real_path $2) data_path=$(get_real_path $2)
ann_file=$(get_real_path $3) ann_file=$(get_real_path $3)

device_id=0
if [ $# == 4 ]; then if [ $# == 4 ]; then
device_id=$4 device_id=$4
elif [ $# == 3 ]; then
if [ -z $device_id ]; then
device_id=0
else
device_id=$device_id
fi
fi fi


echo $model
echo $data_path
echo $ann_file
echo $device_id
echo "mindir name: "$model
echo "dataset path: "$data_path
echo "ann file: "$ann_file
echo "device id: "$device_id


export ASCEND_HOME=/usr/local/Ascend/ export ASCEND_HOME=/usr/local/Ascend/
if [ -d ${ASCEND_HOME}/ascend-toolkit ]; then 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 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/acllib/lib64:$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/lib64:$ASCEND_HOME/driver/lib64:$ASCEND_HOME/add-ones:$LD_LIBRARY_PATH
export TBE_IMPL_PATH=${ASCEND_HOME}/ascend-toolkit/latest/opp/op_impl/built-in/ai_core/tbe
export LD_LIBRARY_PATH=/usr/local/lib:$ASCEND_HOME/ascend-toolkit/latest/atc/lib64:$ASCEND_HOME/ascend-toolkit/latest/acllib/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 PYTHONPATH=${TBE_IMPL_PATH}:$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/python/site-packages:$PYTHONPATH
export ASCEND_OPP_PATH=$ASCEND_HOME/ascend-toolkit/latest/opp export ASCEND_OPP_PATH=$ASCEND_HOME/ascend-toolkit/latest/opp
else else
export PATH=$ASCEND_HOME/atc/ccec_compiler/bin:$ASCEND_HOME/atc/bin:$PATH 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-ones:$LD_LIBRARY_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 PYTHONPATH=$ASCEND_HOME/atc/python/site-packages:$PYTHONPATH
export ASCEND_OPP_PATH=$ASCEND_HOME/opp export ASCEND_OPP_PATH=$ASCEND_HOME/opp
fi fi


function air_to_om()
{
atc --input_format=NCHW --framework=1 --model=$model --input_shape="x:1, 3, 768, 1280; im_info: 1, 4" --output=maskrcnn --insert_op_conf=../src/aipp.cfg --precision_mode=allow_fp32_to_fp16 --soc_version=Ascend310 &>atc.log
}

function compile_app() function compile_app()
{ {
cd ../ascend310_infer/src || exit
sh build.sh &> build.log
cd ../ascend310_infer || exit
bash build.sh &> build.log
cd - || exit cd - || exit
} }


@@ -76,24 +67,19 @@ function infer()
if [ -d result_Files ]; then if [ -d result_Files ]; then
rm -rf ./result_Files rm -rf ./result_Files
fi fi
if [ -d time_Result ]; then
if [ -d time_Result ]; then
rm -rf ./time_Result rm -rf ./time_Result
fi fi
mkdir result_Files mkdir result_Files
mkdir time_Result mkdir time_Result
../ascend310_infer/src/out/main --om_path=./maskrcnn.om --data_path=$data_path --device_id=$device_id &> infer.log
../ascend310_infer/out/main --mindir_path=$model --dataset_path=$data_path --device_id=$device_id &> infer.log
} }


function cal_acc() function cal_acc()
{ {
python ../postprocess.py --ann_file=$ann_file --img_path=$data_path &> acc.log &
python3.7 ../postprocess.py --ann_file=$ann_file --img_path=$data_path --result_path=./result_Files &> acc.log &
} }


air_to_om
if [ $? -ne 0 ]; then
echo "air to om failed"
exit 1
fi
compile_app compile_app
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "compile app code failed" echo "compile app code failed"


+ 0
- 26
model_zoo/official/cv/maskrcnn/src/aipp.cfg View File

@@ -1,26 +0,0 @@
aipp_op {
aipp_mode : static
input_format : YUV420SP_U8
related_input_rank : 0
csc_switch : true
rbuv_swap_switch : false
matrix_r0c0 : 256
matrix_r0c1 : 0
matrix_r0c2 : 359
matrix_r1c0 : 256
matrix_r1c1 : -88
matrix_r1c2 : -183
matrix_r2c0 : 256
matrix_r2c1 : 454
matrix_r2c2 : 0
input_bias_0 : 0
input_bias_1 : 128
input_bias_2 : 128
mean_chn_0 : 124
mean_chn_1 : 117
mean_chn_2 : 104
var_reci_chn_0 : 0.0171247538316637
var_reci_chn_1 : 0.0175070028011204
var_reci_chn_2 : 0.0174291938997821
}

Loading…
Cancel
Save