forked from mindspore-Ecosystem/mindspore
Complete development of Dvpp feature which can be deployed on Ascend 310 Device, the function of this operation is decode + resize + center crop, the output is in format of YUV color space.
This commit is contained in:
parent
f914fa80f9
commit
48a4f31c9b
|
@ -3,6 +3,13 @@ include_directories(${CMAKE_SOURCE_DIR}/mindspore/core)
|
|||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
include_directories(${CMAKE_BINARY_DIR})
|
||||
|
||||
if (ENABLE_ACL)
|
||||
set(ASCEND_PATH /usr/local/Ascend)
|
||||
include_directories(${ASCEND_PATH}/acllib/include)
|
||||
link_directories(${ASCEND_PATH}/acllib/lib64/)
|
||||
find_library(ascendcl acl_dvpp ${ASCEND_PATH}/acllib/lib64)
|
||||
endif ()
|
||||
|
||||
if (NOT(CMAKE_SYSTEM_NAME MATCHES "Darwin"))
|
||||
link_directories(${CMAKE_SOURCE_DIR}/build/mindspore/graphengine)
|
||||
endif ()
|
||||
|
|
|
@ -14,6 +14,10 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-attributes")
|
|||
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
add_definitions(-D _CRT_RAND_S)
|
||||
endif ()
|
||||
if (ENABLE_ACL)
|
||||
add_definitions(-D ENABLE_ACL)
|
||||
message(STATUS "ACL module is enabled")
|
||||
endif ()
|
||||
if (ENABLE_GPUQUE)
|
||||
add_definitions(-D ENABLE_GPUQUE)
|
||||
message(STATUS "GPU queue is enabled")
|
||||
|
@ -91,6 +95,10 @@ if (NOT(${CMAKE_SYSTEM_NAME} MATCHES "Darwin"))
|
|||
add_dependencies(text-kernels core)
|
||||
endif ()
|
||||
|
||||
if (ENABLE_ACL)
|
||||
add_dependencies(kernels-dvpp-image core dvpp-utils)
|
||||
endif ()
|
||||
|
||||
if (ENABLE_PYTHON)
|
||||
add_dependencies(APItoPython core)
|
||||
endif ()
|
||||
|
@ -140,6 +148,13 @@ if (NOT(${CMAKE_SYSTEM_NAME} MATCHES "Darwin"))
|
|||
)
|
||||
endif ()
|
||||
|
||||
if (ENABLE_ACL)
|
||||
set(submodules
|
||||
${submodules}
|
||||
$<TARGET_OBJECTS:kernels-dvpp-image>
|
||||
$<TARGET_OBJECTS:dvpp-utils>)
|
||||
endif ()
|
||||
|
||||
if (ENABLE_PYTHON)
|
||||
set(submodules
|
||||
${submodules}
|
||||
|
@ -163,6 +178,11 @@ endif ()
|
|||
|
||||
################# Link with external libraries ########################
|
||||
target_link_libraries(_c_dataengine PRIVATE mindspore mindspore_gvar)
|
||||
|
||||
if (ENABLE_ACL)
|
||||
target_link_libraries(_c_dataengine PRIVATE ascendcl acl_dvpp)
|
||||
endif ()
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
if (ENABLE_PYTHON)
|
||||
target_link_libraries(_c_dataengine PRIVATE mindspore::pybind11_module ${PYTHON_LIBRARIES} ${SECUREC_LIBRARY})
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
#include "minddata/dataset/kernels/image/cut_out_op.h"
|
||||
#endif
|
||||
#include "minddata/dataset/kernels/image/decode_op.h"
|
||||
#ifdef ENABLE_ACL
|
||||
#include "minddata/dataset/kernels/image/dvpp/dvpp_decode_resize_crop_jpeg_op.h"
|
||||
#endif
|
||||
#ifndef ENABLE_ANDROID
|
||||
#include "minddata/dataset/kernels/image/equalize_op.h"
|
||||
#include "minddata/dataset/kernels/image/hwc_to_chw_op.h"
|
||||
|
@ -132,6 +135,16 @@ std::shared_ptr<DecodeOperation> Decode(bool rgb) {
|
|||
return op->ValidateParams() ? op : nullptr;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ACL
|
||||
// Function to create DvppDecodeResizeCropOperation.
|
||||
std::shared_ptr<DvppDecodeResizeCropOperation> DvppDecodeResizeCropJpeg(std::vector<uint32_t> crop,
|
||||
std::vector<uint32_t> resize) {
|
||||
auto op = std::make_shared<DvppDecodeResizeCropOperation>(crop, resize);
|
||||
// Input validation
|
||||
return op->ValidateParams() ? op : nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Function to create EqualizeOperation.
|
||||
std::shared_ptr<EqualizeOperation> Equalize() {
|
||||
auto op = std::make_shared<EqualizeOperation>();
|
||||
|
@ -647,6 +660,78 @@ Status MixUpBatchOperation::ValidateParams() {
|
|||
std::shared_ptr<TensorOp> MixUpBatchOperation::Build() { return std::make_shared<MixUpBatchOp>(alpha_); }
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ACL
|
||||
// DvppDecodeResizeCropOperation
|
||||
DvppDecodeResizeCropOperation::DvppDecodeResizeCropOperation(const std::vector<uint32_t> &crop,
|
||||
const std::vector<uint32_t> &resize)
|
||||
: crop_(crop), resize_(resize) {}
|
||||
|
||||
Status DvppDecodeResizeCropOperation::ValidateParams() {
|
||||
// size
|
||||
if (crop_.empty() || crop_.size() > 2) {
|
||||
std::string err_msg = "DvppDecodeResizeCropJpeg: crop size must be a vector of one or two elements, got: " +
|
||||
std::to_string(crop_.size());
|
||||
MS_LOG(ERROR) << err_msg;
|
||||
RETURN_STATUS_SYNTAX_ERROR(err_msg);
|
||||
}
|
||||
if (resize_.empty() || resize_.size() > 2) {
|
||||
std::string err_msg = "DvppDecodeResizeCropJpeg: resize size must be a vector of one or two elements, got: " +
|
||||
std::to_string(resize_.size());
|
||||
MS_LOG(ERROR) << err_msg;
|
||||
RETURN_STATUS_SYNTAX_ERROR(err_msg);
|
||||
}
|
||||
if (crop_.size() < resize_.size()) {
|
||||
if (crop_[0] >= MIN(resize_[0], resize_[1])) {
|
||||
std::string err_msg = "crop size must be smaller than resize size";
|
||||
MS_LOG(ERROR) << err_msg;
|
||||
RETURN_STATUS_SYNTAX_ERROR(err_msg);
|
||||
}
|
||||
}
|
||||
if (crop_.size() > resize_.size()) {
|
||||
if (MAX(crop_[0], crop_[1]) >= resize_[0]) {
|
||||
std::string err_msg = "crop size must be smaller than resize size";
|
||||
MS_LOG(ERROR) << err_msg;
|
||||
RETURN_STATUS_SYNTAX_ERROR(err_msg);
|
||||
}
|
||||
}
|
||||
if (crop_.size() == resize_.size()) {
|
||||
for (int32_t i = 0; i < crop_.size(); ++i) {
|
||||
if (crop_[i] >= resize_[i]) {
|
||||
std::string err_msg = "crop size must be smaller than resize size";
|
||||
MS_LOG(ERROR) << err_msg;
|
||||
RETURN_STATUS_SYNTAX_ERROR(err_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
std::shared_ptr<TensorOp> DvppDecodeResizeCropOperation::Build() {
|
||||
// If size is a single value, the smaller edge of the image will be
|
||||
// resized to this value with the same image aspect ratio.
|
||||
uint32_t cropHeight, cropWidth, resizeHeight, resizeWidth;
|
||||
if (crop_.size() == 1) {
|
||||
cropHeight = crop_[0];
|
||||
cropWidth = crop_[0];
|
||||
} else {
|
||||
cropHeight = crop_[0];
|
||||
cropWidth = crop_[1];
|
||||
}
|
||||
// User specified the width value.
|
||||
if (resize_.size() == 1) {
|
||||
resizeHeight = resize_[0];
|
||||
resizeWidth = resize_[0];
|
||||
} else {
|
||||
resizeHeight = resize_[0];
|
||||
resizeWidth = resize_[1];
|
||||
}
|
||||
std::shared_ptr<DvppDecodeResizeCropJpegOp> tensor_op =
|
||||
std::make_shared<DvppDecodeResizeCropJpegOp>(cropHeight, cropWidth, resizeHeight, resizeWidth);
|
||||
return tensor_op;
|
||||
}
|
||||
#endif
|
||||
|
||||
// NormalizeOperation
|
||||
NormalizeOperation::NormalizeOperation(std::vector<float> mean, std::vector<float> std) : mean_(mean), std_(std) {}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ constexpr char kAutoContrastOperation[] = "AutoContrast";
|
|||
constexpr char kBoundingBoxAugmentOperation[] = "BoundingBoxAugment";
|
||||
constexpr char kCutMixBatchOperation[] = "CutMixBatch";
|
||||
constexpr char kCutOutOperation[] = "CutOut";
|
||||
constexpr char kDvppDecodeResizeCropOperation[] = "DvppDecodeResizeCrop";
|
||||
constexpr char kEqualizeOperation[] = "Equalize";
|
||||
constexpr char kHwcToChwOperation[] = "HwcToChw";
|
||||
constexpr char kInvertOperation[] = "Invert";
|
||||
|
@ -75,6 +76,7 @@ class AutoContrastOperation;
|
|||
class BoundingBoxAugmentOperation;
|
||||
class CutMixBatchOperation;
|
||||
class CutOutOperation;
|
||||
class DvppDecodeResizeCropOperation;
|
||||
class EqualizeOperation;
|
||||
class HwcToChwOperation;
|
||||
class InvertOperation;
|
||||
|
@ -140,6 +142,22 @@ std::shared_ptr<CutMixBatchOperation> CutMixBatch(ImageBatchFormat image_batch_f
|
|||
/// \return Shared pointer to the current TensorOp
|
||||
std::shared_ptr<CutOutOperation> CutOut(int32_t length, int32_t num_patches = 1);
|
||||
|
||||
/// \brief Function to create a DvppDecodeResizeCropJpeg TensorOperation.
|
||||
/// \notes Tensor operation to decode and resize JPEG image using the simulation algorithm of Ascend series
|
||||
/// chip DVPP module. It is recommended to use this algorithm in the following scenarios:
|
||||
/// When training, the DVPP of the Ascend chip is not used,
|
||||
/// and the DVPP of the Ascend chip is used during inference,
|
||||
/// and the accuracy of inference is lower than the accuracy of training;
|
||||
/// and the input image size should be in range [16*16, 4096*4096].
|
||||
/// Only images with an even resolution can be output. The output of odd resolution is not supported.
|
||||
/// \param[in] crop vector representing the output size of the final crop image.
|
||||
/// \param[in] size A vector representing the output size of the intermediate resized image.
|
||||
/// If size is a single value, smaller edge of the image will be resized to this value with
|
||||
/// the same image aspect ratio. If size has 2 values, it should be (height, width).
|
||||
/// \return Shared pointer to the current TensorOperation.
|
||||
std::shared_ptr<DvppDecodeResizeCropOperation> DvppDecodeResizeCropJpeg(std::vector<uint32_t> crop = {224, 224},
|
||||
std::vector<uint32_t> resize = {256, 256});
|
||||
|
||||
/// \brief Function to create a Equalize TensorOperation.
|
||||
/// \notes Apply histogram equalization on input image.
|
||||
/// \return Shared pointer to the current TensorOperation.
|
||||
|
@ -538,6 +556,23 @@ class CutOutOperation : public TensorOperation {
|
|||
ImageBatchFormat image_batch_format_;
|
||||
};
|
||||
|
||||
class DvppDecodeResizeCropOperation : public TensorOperation {
|
||||
public:
|
||||
explicit DvppDecodeResizeCropOperation(const std::vector<uint32_t> &crop, const std::vector<uint32_t> &resize);
|
||||
|
||||
~DvppDecodeResizeCropOperation() = default;
|
||||
|
||||
std::shared_ptr<TensorOp> Build() override;
|
||||
|
||||
Status ValidateParams() override;
|
||||
|
||||
std::string Name() const override { return kDvppDecodeResizeCropOperation; }
|
||||
|
||||
private:
|
||||
std::vector<uint32_t> crop_;
|
||||
std::vector<uint32_t> resize_;
|
||||
};
|
||||
|
||||
class EqualizeOperation : public TensorOperation {
|
||||
public:
|
||||
~EqualizeOperation() = default;
|
||||
|
|
|
@ -2,6 +2,9 @@ file(GLOB_RECURSE _CURRENT_SRC_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cc"
|
|||
set_property(SOURCE ${_CURRENT_SRC_FILES} PROPERTY COMPILE_DEFINITIONS SUBMODULE_ID=mindspore::SubModuleId::SM_MD)
|
||||
add_subdirectory(soft_dvpp)
|
||||
add_subdirectory(lite_cv)
|
||||
if (ENABLE_ACL)
|
||||
add_subdirectory(dvpp)
|
||||
endif ()
|
||||
add_library(kernels-image OBJECT
|
||||
affine_op.cc
|
||||
auto_contrast_op.cc
|
||||
|
@ -50,4 +53,8 @@ add_library(kernels-image OBJECT
|
|||
random_resize_with_bbox_op.cc
|
||||
random_color_op.cc
|
||||
)
|
||||
add_dependencies(kernels-image kernels-soft-dvpp-image )
|
||||
if (ENABLE_ACL)
|
||||
add_dependencies(kernels-image kernels-soft-dvpp-image kernels-dvpp-image)
|
||||
else()
|
||||
add_dependencies(kernels-image kernels-soft-dvpp-image)
|
||||
endif ()
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
file(GLOB_RECURSE _CURRENT_SRC_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cc")
|
||||
set_property(SOURCE ${_CURRENT_SRC_FILES} PROPERTY COMPILE_DEFINITIONS SUBMODULE_ID=mindspore::SubModuleId::SM_MD)
|
||||
add_subdirectory(utils)
|
||||
add_library(kernels-dvpp-image OBJECT
|
||||
dvpp_decode_resize_crop_jpeg_op.cc)
|
||||
add_dependencies(kernels-dvpp-image dvpp-utils)
|
|
@ -0,0 +1,104 @@
|
|||
/**
|
||||
* Copyright 2020 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/AclProcess.h"
|
||||
#include "minddata/dataset/core/cv_tensor.h"
|
||||
#include "minddata/dataset/kernels/image/image_utils.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/CommonDataType.h"
|
||||
#include "minddata/dataset/core/data_type.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/dvpp_decode_resize_crop_jpeg_op.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
Status DvppDecodeResizeCropJpegOp::Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) {
|
||||
IO_CHECK(input, output);
|
||||
if (!IsNonEmptyJPEG(input)) {
|
||||
RETURN_STATUS_UNEXPECTED("SoftDvppDecodeReiszeJpegOp only support process jpeg image.");
|
||||
}
|
||||
try {
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(input->GetBuffer() != nullptr, "The input image buffer is empty.");
|
||||
unsigned char *buffer = const_cast<unsigned char *>(input->GetBuffer());
|
||||
RawData imageInfo;
|
||||
uint32_t filesize = input->SizeInBytes();
|
||||
imageInfo.lenOfByte = filesize;
|
||||
imageInfo.data = std::make_shared<uint8_t>();
|
||||
imageInfo.data.reset(new uint8_t[filesize], std::default_delete<uint8_t[]>());
|
||||
memcpy_s(imageInfo.data.get(), filesize, buffer, filesize);
|
||||
// First part end, whose function is to transform data from a Tensor to imageinfo data structure which can be
|
||||
// applied on device
|
||||
ResourceInfo resource;
|
||||
resource.aclConfigPath = "";
|
||||
resource.deviceIds.insert(0); // 0 is device id which should be refined later!
|
||||
std::shared_ptr<ResourceManager> instance = ResourceManager::GetInstance();
|
||||
APP_ERROR ret = instance->InitResource(resource);
|
||||
if (ret != APP_ERR_OK) {
|
||||
instance->Release();
|
||||
std::string error = "Error in Init D-chip:" + std::to_string(ret);
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
int deviceId = *(resource.deviceIds.begin());
|
||||
aclrtContext context = instance->GetContext(deviceId);
|
||||
// Second part end where we initialize the resource of D chip and set up all configures
|
||||
AclProcess process(resized_width_, resized_height_, crop_width_, crop_height_, context);
|
||||
process.set_mode(true);
|
||||
ret = process.InitResource();
|
||||
if (ret != APP_ERR_OK) {
|
||||
instance->Release();
|
||||
std::string error = "Error in Init resource:" + std::to_string(ret);
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
ret = process.Process(imageInfo);
|
||||
if (ret != APP_ERR_OK) {
|
||||
instance->Release();
|
||||
std::string error = "Error in dvpp processing:" + std::to_string(ret);
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
// Third part end where we execute the core function of dvpp
|
||||
auto data = std::static_pointer_cast<unsigned char>(process.Get_Memory_Data());
|
||||
unsigned char *ret_ptr = data.get();
|
||||
std::shared_ptr(DvppDataInfo) CropOut = process.Get_Device_Memory_Data();
|
||||
dsize_t dvpp_length = CropOut->dataSize;
|
||||
const TensorShape dvpp_shape({dvpp_length, 1, 1});
|
||||
const DataType dvpp_data_type(DataType::DE_UINT8);
|
||||
mindspore::dataset::Tensor::CreateFromMemory(dvpp_shape, dvpp_data_type, ret_ptr, output);
|
||||
if (!((*output)->HasData())) {
|
||||
std::string error = "[ERROR] Fail to get the Output result from memory!";
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
process.device_memory_release();
|
||||
// Last part end where we transform the processed data into a tensor which can be applied in later units.
|
||||
} catch (const cv::Exception &e) {
|
||||
std::string error = "[ERROR] Fail in DvppDecodeResizeCropJpegOp:" + std::string(e.what());
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status DvppDecodeResizeCropJpegOp::OutputShape(const std::vector<TensorShape> &inputs,
|
||||
std::vector<TensorShape> &outputs) {
|
||||
RETURN_IF_NOT_OK(TensorOp::OutputShape(inputs, outputs));
|
||||
outputs.clear();
|
||||
TensorShape out({-1, 1, 1}); // we don't know what is output image size, but we know it should be 3 channels
|
||||
if (inputs[0].Rank() == 1) outputs.emplace_back(out);
|
||||
if (!outputs.empty()) return Status::OK();
|
||||
return Status(StatusCode::kUnexpectedError, "Input has a wrong shape");
|
||||
}
|
||||
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* Copyright 2020 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_DVPP_DECODE_RESIZE_CROP_JPEG_OP_H
|
||||
#define MINDSPORE_DVPP_DECODE_RESIZE_CROP_JPEG_OP_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "minddata/dataset/core/tensor.h"
|
||||
#include "minddata/dataset/kernels/tensor_op.h"
|
||||
#include "minddata/dataset/util/status.h"
|
||||
#include "minddata/dataset/core/data_type.h"
|
||||
#include "mindspore/core/utils/log_adapter.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/ResourceManager.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/ErrorCode.h"
|
||||
#include "acl/acl.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
class DvppDecodeResizeCropJpegOp : public TensorOp {
|
||||
public:
|
||||
DvppDecodeResizeCropJpegOp(int32_t crop_height, int32_t crop_width, int32_t resized_height, int32_t resized_width)
|
||||
: crop_height_(crop_height),
|
||||
crop_width_(crop_width),
|
||||
resized_height_(resized_height),
|
||||
resized_width_(resized_width) {}
|
||||
|
||||
/// \brief Destructor
|
||||
~DvppDecodeResizeCropJpegOp() = default;
|
||||
|
||||
Status Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) override;
|
||||
Status OutputShape(const std::vector<TensorShape> &inputs, std::vector<TensorShape> &outputs) override;
|
||||
|
||||
std::string Name() const override { return kDvppDecodeResizeCropJpegOp; }
|
||||
|
||||
private:
|
||||
int32_t crop_height_;
|
||||
int32_t crop_width_;
|
||||
int32_t resized_height_;
|
||||
int32_t resized_width_;
|
||||
};
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
||||
|
||||
#endif // MINDSPORE_DVPP_DECODE_RESIZE_CROP_JPEG_OP_H
|
|
@ -0,0 +1,355 @@
|
|||
/*
|
||||
* 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 <sys/stat.h>
|
||||
|
||||
namespace {
|
||||
const int BUFFER_SIZE = 2048;
|
||||
const mode_t DEFAULT_FILE_PERMISSION = 0077;
|
||||
} // namespace
|
||||
|
||||
mode_t SetFileDefaultUmask() { return umask(DEFAULT_FILE_PERMISSION); }
|
||||
|
||||
/*
|
||||
* @description: Constructor
|
||||
* @param: resizeWidth specifies the resized width
|
||||
* @param: resizeHeight specifies the resized hegiht
|
||||
* @param: stream is used to maintain the execution order of operations
|
||||
* @param: context is used to manage the life cycle of objects
|
||||
* @param: dvppCommon is a class for decoding and resizing
|
||||
*/
|
||||
AclProcess::AclProcess(uint32_t resizeWidth, uint32_t resizeHeight, uint32_t cropWidth, uint32_t cropHeight,
|
||||
aclrtContext context, aclrtStream stream, std::shared_ptr<DvppCommon> dvppCommon)
|
||||
: resizeWidth_(resizeWidth),
|
||||
resizeHeight_(resizeHeight),
|
||||
cropWidth_(cropWidth),
|
||||
cropHeight_(cropHeight),
|
||||
context_(context),
|
||||
stream_(stream),
|
||||
dvppCommon_(dvppCommon) {
|
||||
repeat_ = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* @description: Release AclProcess resources
|
||||
* @return: aclError which is error code of ACL API
|
||||
*/
|
||||
APP_ERROR AclProcess::Release() {
|
||||
// Release objects resource
|
||||
APP_ERROR ret = dvppCommon_->DeInit();
|
||||
dvppCommon_->ReleaseDvppBuffer();
|
||||
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to deinitialize dvppCommon_, ret = " << ret;
|
||||
return ret;
|
||||
}
|
||||
MS_LOG(INFO) << "dvppCommon_ object deinitialized successfully";
|
||||
dvppCommon_.reset();
|
||||
|
||||
// Release stream
|
||||
if (stream_ != nullptr) {
|
||||
ret = aclrtDestroyStream(stream_);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to destroy stream, ret = " << ret;
|
||||
stream_ = nullptr;
|
||||
return ret;
|
||||
}
|
||||
stream_ = nullptr;
|
||||
}
|
||||
MS_LOG(INFO) << "The stream is destroyed successfully";
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* @description: Initialize DvppCommon object
|
||||
* @return: aclError which is error code of ACL API
|
||||
*/
|
||||
APP_ERROR AclProcess::InitModule() {
|
||||
// Create Dvpp JpegD object
|
||||
dvppCommon_ = std::make_shared<DvppCommon>(stream_);
|
||||
if (dvppCommon_ == nullptr) {
|
||||
MS_LOG(ERROR) << "Failed to create dvppCommon_ object";
|
||||
return APP_ERR_COMM_INIT_FAIL;
|
||||
}
|
||||
MS_LOG(INFO) << "DvppCommon object created successfully";
|
||||
APP_ERROR ret = dvppCommon_->Init();
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to initialize dvppCommon_ object, ret = " << ret;
|
||||
return ret;
|
||||
}
|
||||
MS_LOG(INFO) << "DvppCommon object initialized successfully";
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* @description: Initialize AclProcess resources
|
||||
* @return: aclError which is error code of ACL API
|
||||
*/
|
||||
APP_ERROR AclProcess::InitResource() {
|
||||
APP_ERROR ret = aclrtSetCurrentContext(context_);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to get ACL context, ret = " << ret;
|
||||
return ret;
|
||||
}
|
||||
MS_LOG(INFO) << "The context is created successfully";
|
||||
ret = aclrtCreateStream(&stream_); // Create stream for application
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to create ACL stream, ret = " << ret;
|
||||
return ret;
|
||||
}
|
||||
MS_LOG(INFO) << "The stream is created successfully";
|
||||
// Initialize dvpp module
|
||||
if (InitModule() != APP_ERR_OK) {
|
||||
return APP_ERR_COMM_INIT_FAIL;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* @description: Read image files, and perform decoding and scaling
|
||||
* @param: imageFile specifies the image path to be processed
|
||||
* @return: aclError which is error code of ACL API
|
||||
*/
|
||||
APP_ERROR AclProcess::Preprocess(RawData &ImageInfo) {
|
||||
// Decode process
|
||||
APP_ERROR ret = dvppCommon_->CombineJpegdProcess(ImageInfo, PIXEL_FORMAT_YUV_SEMIPLANAR_420, true);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to process decode, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
// Get output of decoded jpeg image
|
||||
std::shared_ptr<DvppDataInfo> decodeOutData = dvppCommon_->GetDecodedImage();
|
||||
if (decodeOutData == nullptr) {
|
||||
MS_LOG(ERROR) << "Decode output buffer is null.";
|
||||
return APP_ERR_COMM_INVALID_POINTER;
|
||||
}
|
||||
// Define output of resize jpeg image
|
||||
DvppDataInfo resizeOut;
|
||||
resizeOut.width = resizeWidth_;
|
||||
resizeOut.height = resizeHeight_;
|
||||
resizeOut.format = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
|
||||
// Run resize application function
|
||||
ret = dvppCommon_->CombineResizeProcess(*(decodeOutData.get()), resizeOut, true);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to process resize, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
// Get output of resize jpeg image
|
||||
std::shared_ptr<DvppDataInfo> resizeOutData = dvppCommon_->GetResizedImage();
|
||||
if (resizeOutData == nullptr) {
|
||||
MS_LOG(ERROR) << "resize output buffer is null.";
|
||||
return APP_ERR_COMM_INVALID_POINTER;
|
||||
}
|
||||
// Define output of crop jpeg image
|
||||
DvppDataInfo cropOut;
|
||||
cropOut.width = cropWidth_;
|
||||
cropOut.height = cropHeight_;
|
||||
cropOut.format = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
|
||||
// Define input of crop jpeg image
|
||||
DvppCropInputInfo cropInfo;
|
||||
cropInfo.dataInfo = *(resizeOutData.get());
|
||||
// Define crop parameters
|
||||
CropRoiConfig cropCfg;
|
||||
CropConfigFilter(cropCfg, cropInfo);
|
||||
ret = dvppCommon_->CombineCropProcess(cropInfo, cropOut, true);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to process center crop, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* @description: Decode and scale the picture, and write the result to a file
|
||||
* @param: imageFile specifies the image path to be processed
|
||||
* @return: aclError which is error code of ACL API
|
||||
*/
|
||||
APP_ERROR AclProcess::Process(RawData &ImageInfo) {
|
||||
struct timeval begin = {0};
|
||||
struct timeval end = {0};
|
||||
gettimeofday(&begin, nullptr);
|
||||
// deal with image
|
||||
APP_ERROR ret = Preprocess(ImageInfo);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to preprocess, ret = " << ret;
|
||||
return ret;
|
||||
}
|
||||
gettimeofday(&end, nullptr);
|
||||
// Calculate the time cost of preprocess
|
||||
const double costMs = SEC2MS * (end.tv_sec - begin.tv_sec) + (end.tv_usec - begin.tv_usec) / SEC2MS;
|
||||
const double fps = 1 * SEC2MS / costMs;
|
||||
MS_LOG(INFO) << "[dvpp Delay] cost: " << costMs << "ms\tfps: " << fps;
|
||||
// Get output of resize module
|
||||
std::shared_ptr<DvppDataInfo> CropOutData = dvppCommon_->GetCropedImage();
|
||||
if (CropOutData->dataSize == 0) {
|
||||
MS_LOG(ERROR) << "CropOutData return NULL";
|
||||
return APP_ERR_COMM_INVALID_POINTER;
|
||||
}
|
||||
// Alloc host memory for the inference output according to the size of output
|
||||
void *resHostBuf = nullptr;
|
||||
ret = aclrtMallocHost(&resHostBuf, CropOutData->dataSize);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to allocate memory from host ret = " << ret;
|
||||
return ret;
|
||||
}
|
||||
std::shared_ptr<void> outBuf(resHostBuf, aclrtFreeHost);
|
||||
processedInfo_ = outBuf;
|
||||
// Memcpy the output data from device to host
|
||||
ret = aclrtMemcpy(outBuf.get(), CropOutData->dataSize, CropOutData->data, CropOutData->dataSize,
|
||||
ACL_MEMCPY_DEVICE_TO_HOST);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to copy memory from device to host, ret = " << ret;
|
||||
return ret;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* @description: Rename the image for saving
|
||||
* @Param: primary name of image
|
||||
* @return: aclError which is error code of ACL API
|
||||
*/
|
||||
APP_ERROR AclProcess::RenameFile(std::string &filename) {
|
||||
std::string delimiter = "/";
|
||||
size_t pos = 0;
|
||||
std::string token;
|
||||
while ((pos = filename.find(delimiter)) != std::string::npos) {
|
||||
token = filename.substr(0, pos);
|
||||
filename.erase(0, pos + delimiter.length());
|
||||
}
|
||||
delimiter = ".";
|
||||
pos = filename.find(delimiter);
|
||||
filename = filename.substr(0, pos);
|
||||
if (filename.length() == 0) {
|
||||
return APP_ERR_COMM_WRITE_FAIL;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* @description: Write result image to file
|
||||
* @param: resultSize specifies the size of the result image
|
||||
* @param: outBuf specifies the memory on the host to save the result image
|
||||
* @return: aclError which is error code of ACL API
|
||||
*/
|
||||
APP_ERROR AclProcess::WriteResult(uint32_t resultSize, std::shared_ptr<void> outBuf, std::string filename) {
|
||||
std::string resultPathName = "result";
|
||||
// Create result directory when it does not exist
|
||||
if (access(resultPathName.c_str(), 0) != 0) {
|
||||
int ret = mkdir(resultPathName.c_str(), S_IRUSR | S_IWUSR | S_IXUSR); // for linux
|
||||
if (ret != 0) {
|
||||
MS_LOG(ERROR) << "Failed to create result directory: " << resultPathName << ", ret = " << ret;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
APP_ERROR ret = RenameFile(filename);
|
||||
if (ret != 0) {
|
||||
MS_LOG(ERROR) << "Failed to rename file: " << resultPathName << ", ret = " << ret;
|
||||
return ret;
|
||||
}
|
||||
resultPathName = resultPathName + "/" + filename + ".bin";
|
||||
SetFileDefaultUmask();
|
||||
FILE *fp = fopen(resultPathName.c_str(), "wb");
|
||||
if (fp == nullptr) {
|
||||
MS_LOG(ERROR) << "Failed to open file";
|
||||
return APP_ERR_COMM_OPEN_FAIL;
|
||||
}
|
||||
uint32_t result = fwrite(outBuf.get(), 1, resultSize, fp);
|
||||
if (result != resultSize) {
|
||||
MS_LOG(ERROR) << "Failed to write file";
|
||||
return APP_ERR_COMM_WRITE_FAIL;
|
||||
}
|
||||
MS_LOG(INFO) << "Write result to file successfully";
|
||||
// After write info onto desk, release the memory on device
|
||||
dvppCommon_->ReleaseDvppBuffer();
|
||||
uint32_t ff = fflush(fp);
|
||||
if (ff != 0) {
|
||||
MS_LOG(ERROR) << "Failed to fflush file";
|
||||
return APP_ERR_COMM_DESTORY_FAIL;
|
||||
}
|
||||
uint32_t fc = fclose(fp);
|
||||
if (fc != 0) {
|
||||
MS_LOG(ERROR) << "Failed to fclose file";
|
||||
return APP_ERR_COMM_DESTORY_FAIL;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
void AclProcess::YUV420TOYUV444(unsigned char *inputBuffer, unsigned char *outputBuffer, int w, int h) {
|
||||
unsigned char *srcY = nullptr, *srcU = nullptr, *srcV = nullptr;
|
||||
unsigned char *desY = nullptr, *desU = nullptr, *desV = nullptr;
|
||||
srcY = inputBuffer; // Y
|
||||
if (srcY == nullptr) std::cout << "Failure pointer transfer!";
|
||||
srcU = srcY + w * h; // U
|
||||
srcV = srcU + w * h / 4;
|
||||
; // V
|
||||
|
||||
desY = outputBuffer;
|
||||
desU = desY + w * h;
|
||||
desV = desU + w * h;
|
||||
memcpy(desY, srcY, w * h * sizeof(unsigned char));
|
||||
for (int i = 0; i < h; i += 2) { //行
|
||||
for (int j = 0; j < w; j += 2) { //列
|
||||
// U
|
||||
desU[i * w + j] = srcU[i / 2 * w / 2 + j / 2];
|
||||
desU[i * w + j + 1] = srcU[i / 2 * w / 2 + j / 2];
|
||||
desU[(i + 1) * w + j] = srcU[i / 2 * w / 2 + j / 2];
|
||||
desU[(i + 1) * w + j + 1] = srcU[i / 2 * w / 2 + j / 2];
|
||||
// V
|
||||
desV[i * w + j] = srcV[i / 2 * w / 2 + j / 2];
|
||||
desV[i * w + j + 1] = srcV[i / 2 * w / 2 + j / 2];
|
||||
desV[(i + 1) * w + j] = srcV[i / 2 * w / 2 + j / 2];
|
||||
desV[(i + 1) * w + j + 1] = srcV[i / 2 * w / 2 + j / 2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AclProcess::CropConfigFilter(CropRoiConfig &cfg, DvppCropInputInfo &cropinfo) {
|
||||
cfg.up = (resizeHeight_ - cropHeight_) / 2;
|
||||
if (cfg.up % 2 != 0) {
|
||||
cfg.up++;
|
||||
}
|
||||
cfg.down = resizeHeight_ - (resizeHeight_ - cropHeight_) / 2;
|
||||
if (cfg.down % 2 == 0) {
|
||||
cfg.down--;
|
||||
}
|
||||
cfg.left = (resizeWidth_ - cropWidth_) / 2;
|
||||
if (cfg.left % 2 != 0) {
|
||||
cfg.left++;
|
||||
}
|
||||
cfg.right = resizeWidth_ - (resizeWidth_ - cropWidth_) / 2;
|
||||
if (cfg.right % 2 == 0) {
|
||||
cfg.right--;
|
||||
}
|
||||
cropinfo.roi = cfg;
|
||||
}
|
||||
|
||||
/*
|
||||
* @description: Obtain result data of memory
|
||||
* @param: processed_data is result data info pointer
|
||||
* @return: Address of data in the memory
|
||||
*/
|
||||
std::shared_ptr<void> AclProcess::Get_Memory_Data() { return processedInfo_; }
|
||||
|
||||
std::shared_ptr<DvppDataInfo> AclProcess::Get_Device_Memory_Data() { return dvppCommon_->GetCropedImage(); }
|
||||
|
||||
void AclProcess::set_mode(bool flag) { repeat_ = flag; }
|
||||
|
||||
bool AclProcess::get_mode() { return repeat_; }
|
||||
|
||||
void AclProcess::device_memory_release() { dvppCommon_->ReleaseDvppBuffer(); }
|
|
@ -0,0 +1,86 @@
|
|||
#include <climits>
|
||||
/*
|
||||
* 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 <string>
|
||||
#include <string.h>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include "acl/acl.h"
|
||||
#include "CommonDataType.h"
|
||||
#include "mindspore/core/utils/log_adapter.h"
|
||||
#include "ErrorCode.h"
|
||||
#include "DvppCommon.h"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
mode_t SetFileDefaultUmask();
|
||||
|
||||
class AclProcess {
|
||||
public:
|
||||
AclProcess(uint32_t resizeWidth, uint32_t resizeHeight, uint32_t cropWidth, uint32_t cropHeight, aclrtContext context,
|
||||
aclrtStream stream = nullptr, std::shared_ptr<DvppCommon> dvppCommon = nullptr);
|
||||
|
||||
~AclProcess(){};
|
||||
|
||||
// Release all the resource
|
||||
APP_ERROR Release();
|
||||
// Create resource for this sample
|
||||
APP_ERROR InitResource();
|
||||
// Process the result
|
||||
APP_ERROR Process(RawData &ImageInfo);
|
||||
// API for access memory
|
||||
std::shared_ptr<void> Get_Memory_Data();
|
||||
// API for access device memory
|
||||
std::shared_ptr<DvppDataInfo> Get_Device_Memory_Data();
|
||||
// change output method
|
||||
void set_mode(bool flag);
|
||||
// Get the mode of Acl process
|
||||
bool get_mode();
|
||||
// Save the result
|
||||
APP_ERROR WriteResult(uint32_t fileSize, std::shared_ptr<void> outBuf, std::string filename);
|
||||
// Color space reform
|
||||
void YUV420TOYUV444(unsigned char *inputBuffer, unsigned char *outputBuffer, int w, int h);
|
||||
// Crop definition
|
||||
void CropConfigFilter(CropRoiConfig &cfg, DvppCropInputInfo &cropinfo);
|
||||
// D-chip memory release
|
||||
void device_memory_release();
|
||||
|
||||
private:
|
||||
// Initialize the modules used by this sample
|
||||
APP_ERROR InitModule();
|
||||
// Preprocess the input image
|
||||
APP_ERROR Preprocess(RawData &ImageInfo);
|
||||
// Filename process
|
||||
APP_ERROR RenameFile(std::string &filename);
|
||||
|
||||
aclrtContext context_;
|
||||
aclrtStream stream_;
|
||||
std::shared_ptr<DvppCommon> dvppCommon_; // dvpp object
|
||||
std::shared_ptr<void> processedInfo_; // processed data
|
||||
uint32_t resizeWidth_; // dvpp resize width
|
||||
uint32_t resizeHeight_; // dvpp resize height
|
||||
uint32_t cropWidth_; // dvpp crop width
|
||||
uint32_t cropHeight_; // dvpp crop height
|
||||
bool repeat_; // Repeatly process image or not
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,11 @@
|
|||
file(GLOB_RECURSE _CURRENT_SRC_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cc")
|
||||
set_property(SOURCE ${_CURRENT_SRC_FILES} PROPERTY COMPILE_DEFINITIONS SUBMODULE_ID=mindspore::SubModuleId::SM_MD)
|
||||
|
||||
add_definitions(-DENABLE_DVPP_INTERFACE)
|
||||
|
||||
add_library(dvpp-utils OBJECT
|
||||
AclProcess.cc
|
||||
DvppCommon.cc
|
||||
ErrorCode.cpp
|
||||
ResourceManager.cc
|
||||
)
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* 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
|
||||
#ifndef ENABLE_DVPP_INTERFACE
|
||||
#define ENABLE_DVPP_INTERFACE
|
||||
#endif
|
||||
#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))
|
||||
|
||||
const uint32_t VIDEO_H264 = 0;
|
||||
const uint32_t VIDEO_H265 = 1;
|
||||
|
||||
const float SEC2MS = 1000.0;
|
||||
const uint32_t VIDEO_PROCESS_THREAD = 16;
|
||||
const int YUV_BGR_SIZE_CONVERT_3 = 3;
|
||||
const int YUV_BGR_SIZE_CONVERT_2 = 2;
|
||||
const int DVPP_JPEG_OFFSET = 8;
|
||||
const int VPC_WIDTH_ALIGN = 16;
|
||||
const int VPC_HEIGHT_ALIGN = 2;
|
||||
const int JPEG_WIDTH_ALIGN = 128;
|
||||
const int JPEG_HEIGHT_ALIGN = 16;
|
||||
const int VPC_OFFSET_ALIGN = 2;
|
||||
|
||||
// Tensor Descriptor
|
||||
struct Tensor {
|
||||
aclDataType dataType; // Tensor data type
|
||||
int numDim; // Number of dimensions of Tensor
|
||||
std::vector<int64_t> dims; // Dimension vector
|
||||
aclFormat format; // Format of tensor, e.g. ND, NCHW, NC1HWC0
|
||||
std::string name; // Name of tensor
|
||||
};
|
||||
|
||||
// Data type of tensor
|
||||
enum OpAttrType {
|
||||
BOOL = 0,
|
||||
INT = 1,
|
||||
FLOAT = 2,
|
||||
STRING = 3,
|
||||
LIST_BOOL = 4,
|
||||
LIST_INT = 6,
|
||||
LIST_FLOAT = 7,
|
||||
LIST_STRING = 8,
|
||||
LIST_LIST_INT = 9,
|
||||
};
|
||||
|
||||
// operator attribution describe
|
||||
// type decide whether the other attribute needed to set a value
|
||||
struct OpAttr {
|
||||
std::string name;
|
||||
OpAttrType type;
|
||||
int num; // LIST_BOOL/INT/FLOAT/STRING/LIST_LIST_INT need
|
||||
uint8_t numBool; // BOOL need
|
||||
int64_t numInt; // INT need
|
||||
float numFloat; // FLOAT need
|
||||
std::string numString; // STRING need
|
||||
std::vector<uint8_t> valuesBool; // LIST_BOOL need
|
||||
std::vector<int64_t> valuesInt; // LIST_INT need
|
||||
std::vector<float> valuesFloat; // LIST_FLOAT need
|
||||
std::vector<std::string> valuesString; // LIST_STRING need
|
||||
std::vector<int> numLists; // LIST_LIST_INT need
|
||||
std::vector<std::vector<int64_t>> valuesListList; // LIST_LIST_INT need
|
||||
};
|
||||
|
||||
// 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
|
||||
};
|
||||
|
||||
// Description of data in device
|
||||
struct StreamData {
|
||||
size_t size; // Size of memory, bytes
|
||||
std::shared_ptr<void> data; // Smart pointer of data
|
||||
};
|
||||
|
||||
// Description of stream data
|
||||
struct StreamInfo {
|
||||
std::string format;
|
||||
uint32_t height;
|
||||
uint32_t width;
|
||||
uint32_t channelId;
|
||||
std::string streamPath;
|
||||
};
|
||||
|
||||
// define the structure of an rectangle
|
||||
struct Rectangle {
|
||||
uint32_t leftTopX;
|
||||
uint32_t leftTopY;
|
||||
uint32_t rightBottomX;
|
||||
uint32_t rightBottomY;
|
||||
};
|
||||
|
||||
struct ObjectDetectInfo {
|
||||
int32_t classId;
|
||||
float confidence;
|
||||
Rectangle location;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
// Description of matrix info
|
||||
struct MatrixInfo {
|
||||
uint32_t row = 0; // row of matrix
|
||||
uint32_t col = 0; // col of matrix
|
||||
uint32_t dataSize = 0; // size of memory, bytes
|
||||
std::shared_ptr<void> data = nullptr; // data of matrix
|
||||
aclDataType dataType = ACL_FLOAT16; // data Type of matrix
|
||||
};
|
||||
|
||||
// Description of coefficient info
|
||||
struct CoefficientInfo {
|
||||
std::shared_ptr<void> data = nullptr; // data of coefficient
|
||||
aclDataType dataType = ACL_FLOAT16; // dataType
|
||||
};
|
||||
|
||||
// define the input of BLAS operator such as producing:
|
||||
// C = alpha * A * B + beta * C
|
||||
struct BlasInput {
|
||||
MatrixInfo A;
|
||||
MatrixInfo B;
|
||||
MatrixInfo C;
|
||||
CoefficientInfo alpha;
|
||||
CoefficientInfo beta;
|
||||
};
|
||||
|
||||
extern bool g_vdecNotified[VIDEO_PROCESS_THREAD];
|
||||
extern bool g_vpcNotified[VIDEO_PROCESS_THREAD];
|
||||
extern bool g_inferNotified[VIDEO_PROCESS_THREAD];
|
||||
extern bool g_postNotified[VIDEO_PROCESS_THREAD];
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* 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 "CommonDataType.h"
|
||||
#include "ErrorCode.h"
|
||||
|
||||
#include "acl/ops/acl_dvpp.h"
|
||||
|
||||
const int MODULUS_NUM_2 = 2;
|
||||
const uint32_t ODD_NUM_1 = 1;
|
||||
|
||||
struct Rect {
|
||||
/* left location of the rectangle */
|
||||
uint32_t x;
|
||||
/* top location of the rectangle */
|
||||
uint32_t y;
|
||||
/* with of the rectangle */
|
||||
uint32_t width;
|
||||
/* height of the rectangle */
|
||||
uint32_t height;
|
||||
};
|
||||
|
||||
struct DvppBaseData {
|
||||
uint32_t dataSize; // Size of data in byte
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
struct VdecConfig {
|
||||
int inputWidth = 0;
|
||||
int inputHeight = 0;
|
||||
acldvppStreamFormat inFormat = H264_MAIN_LEVEL; // stream format renference acldvppStreamFormat
|
||||
acldvppPixelFormat outFormat = PIXEL_FORMAT_YUV_SEMIPLANAR_420; // output format renference acldvppPixelFormat
|
||||
uint32_t channelId = 0; // user define channelId: 0-15
|
||||
uint32_t deviceId = 0;
|
||||
pthread_t threadId = 0; // thread for callback
|
||||
aclvdecCallback callback = {0}; // user define how to process vdec out data
|
||||
bool runflag = true;
|
||||
};
|
||||
|
||||
struct DeviceStreamData {
|
||||
std::vector<ObjectDetectInfo> detectResult;
|
||||
uint32_t framId;
|
||||
uint32_t channelId;
|
||||
};
|
||||
|
||||
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 JPEGE_STRIDE_WIDTH = 16; // Jpege module input width need to align up to 16
|
||||
const uint32_t JPEGE_STRIDE_HEIGHT = 1; // Jpege module input height remains unchanged
|
||||
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 VDEC_STRIDE_WIDTH = 16; // Vdec module output width need to align up to 16
|
||||
const uint32_t VDEC_STRIDE_HEIGHT = 2; // Vdec module output width need to align up to 2
|
||||
const uint32_t YUV_BYTES_NU = 3; // Numerator of yuv image, H x W x 3 / 2
|
||||
const uint32_t YUV_BYTES_DE = 2; // Denominator of yuv image, H x W x 3 / 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_JPEGE_WIDTH = 8192; // Max width of jpege module
|
||||
const uint32_t MAX_JPEGE_HEIGHT = 8192; // Max height of jpege module
|
||||
const uint32_t MIN_JPEGE_WIDTH = 32; // Min width of jpege module
|
||||
const uint32_t MIN_JPEGE_HEIGHT = 32; // Min height of jpege 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)) // Convert the input to odd num
|
||||
#define CONVERT_TO_EVEN(NUM) (((NUM) % MODULUS_NUM_2 == 0) ? (NUM) : ((NUM)-1)) // Convert the input to even num
|
||||
#define CHECK_ODD(num) ((num) % MODULUS_NUM_2 != 0)
|
||||
#define CHECK_EVEN(num) ((num) % MODULUS_NUM_2 == 0)
|
||||
#define RELEASE_DVPP_DATA(dvppDataPtr) \
|
||||
do { \
|
||||
APP_ERROR retMacro; \
|
||||
if (dvppDataPtr != nullptr) { \
|
||||
retMacro = acldvppFree(dvppDataPtr); \
|
||||
if (retMacro != APP_ERR_OK) { \
|
||||
MS_LOG(ERROR) << "Failed to free memory on dvpp, ret = " << retMacro << "."; \
|
||||
} \
|
||||
dvppDataPtr = nullptr; \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
class DvppCommon {
|
||||
public:
|
||||
explicit DvppCommon(aclrtStream dvppStream);
|
||||
explicit DvppCommon(const VdecConfig &vdecConfig); // Need by vdec
|
||||
~DvppCommon();
|
||||
APP_ERROR Init(void);
|
||||
APP_ERROR InitVdec(); // Needed by vdec
|
||||
APP_ERROR DeInit(void);
|
||||
|
||||
static APP_ERROR GetVpcDataSize(uint32_t widthVpc, uint32_t heightVpc, acldvppPixelFormat format, uint32_t &vpcSize);
|
||||
static APP_ERROR GetVpcInputStrideSize(uint32_t width, uint32_t height, acldvppPixelFormat format,
|
||||
uint32_t &widthStride, uint32_t &heightStride);
|
||||
static APP_ERROR 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 APP_ERROR GetJpegImageInfo(const void *data, uint32_t dataSize, uint32_t &width, uint32_t &height,
|
||||
int32_t &components);
|
||||
static APP_ERROR GetJpegDecodeDataSize(const void *data, uint32_t dataSize, acldvppPixelFormat format,
|
||||
uint32_t &decSize);
|
||||
static APP_ERROR GetJpegEncodeStrideSize(std::shared_ptr<DvppDataInfo> &input);
|
||||
static APP_ERROR SetEncodeLevel(uint32_t level, acldvppJpegeConfig &jpegeConfig);
|
||||
static APP_ERROR GetVideoDecodeStrideSize(uint32_t width, uint32_t height, acldvppPixelFormat format,
|
||||
uint32_t &widthStride, uint32_t &heightStride);
|
||||
static APP_ERROR GetVideoDecodeDataSize(uint32_t width, uint32_t height, acldvppPixelFormat format,
|
||||
uint32_t &vdecSize);
|
||||
|
||||
// The following interfaces can be called only when the DvppCommon object is initialized with Init
|
||||
APP_ERROR VpcResize(DvppDataInfo &input, DvppDataInfo &output, bool withSynchronize,
|
||||
VpcProcessType processType = VPC_PT_DEFAULT);
|
||||
APP_ERROR VpcCrop(const DvppCropInputInfo &input, const DvppDataInfo &output, bool withSynchronize);
|
||||
APP_ERROR JpegDecode(DvppDataInfo &input, DvppDataInfo &output, bool withSynchronize);
|
||||
|
||||
APP_ERROR JpegEncode(DvppDataInfo &input, DvppDataInfo &output, acldvppJpegeConfig *jpegeConfig,
|
||||
bool withSynchronize);
|
||||
|
||||
APP_ERROR GetJpegEncodeDataSize(DvppDataInfo &input, acldvppJpegeConfig *jpegeConfig, uint32_t &encSize);
|
||||
|
||||
// These functions started with "Combine" encapsulate the DVPP process together, malloc DVPP memory,
|
||||
// transfer pictures from host to device, and then execute the DVPP operation.
|
||||
// The caller needs to pay attention to the release of the memory alloced in these functions.
|
||||
// You can call the ReleaseDvppBuffer function to release memory after use completely.
|
||||
APP_ERROR CombineResizeProcess(DvppDataInfo &input, DvppDataInfo &output, bool withSynchronize,
|
||||
VpcProcessType processType = VPC_PT_DEFAULT);
|
||||
APP_ERROR CombineCropProcess(DvppCropInputInfo &input, DvppDataInfo &output, bool withSynchronize);
|
||||
APP_ERROR CombineJpegdProcess(const RawData &imageInfo, acldvppPixelFormat format, bool withSynchronize);
|
||||
APP_ERROR CombineJpegeProcess(const RawData &imageInfo, uint32_t width, uint32_t height, acldvppPixelFormat format,
|
||||
bool withSynchronize);
|
||||
// The following interface can be called only when the DvppCommon object is initialized with InitVdec
|
||||
APP_ERROR CombineVdecProcess(std::shared_ptr<DvppDataInfo> data, void *userData);
|
||||
|
||||
// Get the private member variables which are assigned in the interfaces which are started with "Combine"
|
||||
std::shared_ptr<DvppDataInfo> GetInputImage();
|
||||
std::shared_ptr<DvppDataInfo> GetDecodedImage();
|
||||
std::shared_ptr<DvppDataInfo> GetResizedImage();
|
||||
std::shared_ptr<DvppDataInfo> GetEncodedImage();
|
||||
std::shared_ptr<DvppDataInfo> GetCropedImage();
|
||||
|
||||
// Release the memory that is allocated in the interfaces which are started with "Combine"
|
||||
void ReleaseDvppBuffer();
|
||||
APP_ERROR VdecSendEosFrame() const;
|
||||
|
||||
private:
|
||||
APP_ERROR SetDvppPicDescData(const DvppDataInfo &dataInfo, acldvppPicDesc &picDesc);
|
||||
APP_ERROR ResizeProcess(acldvppPicDesc &inputDesc, acldvppPicDesc &outputDesc, bool withSynchronize);
|
||||
APP_ERROR ResizeWithPadding(acldvppPicDesc &inputDesc, acldvppPicDesc &outputDesc, CropRoiConfig &cropRoi,
|
||||
CropRoiConfig &pasteRoi, bool withSynchronize);
|
||||
void GetCropRoi(const DvppDataInfo &input, const DvppDataInfo &output, VpcProcessType processType,
|
||||
CropRoiConfig &cropRoi);
|
||||
void GetPasteRoi(const DvppDataInfo &input, const DvppDataInfo &output, VpcProcessType processType,
|
||||
CropRoiConfig &pasteRoi);
|
||||
APP_ERROR CropProcess(acldvppPicDesc &inputDesc, acldvppPicDesc &outputDesc, const CropRoiConfig &cropArea,
|
||||
bool withSynchronize);
|
||||
APP_ERROR CheckResizeParams(const DvppDataInfo &input, const DvppDataInfo &output);
|
||||
APP_ERROR CheckCropParams(const DvppCropInputInfo &input);
|
||||
APP_ERROR TransferImageH2D(const RawData &imageInfo, const std::shared_ptr<DvppDataInfo> &jpegInput);
|
||||
APP_ERROR CreateStreamDesc(std::shared_ptr<DvppDataInfo> data);
|
||||
APP_ERROR DestroyResource();
|
||||
|
||||
std::shared_ptr<acldvppRoiConfig> cropAreaConfig_ = nullptr;
|
||||
std::shared_ptr<acldvppRoiConfig> pasteAreaConfig_ = nullptr;
|
||||
|
||||
std::shared_ptr<acldvppPicDesc> cropInputDesc_ = nullptr;
|
||||
std::shared_ptr<acldvppPicDesc> cropOutputDesc_ = nullptr;
|
||||
std::shared_ptr<acldvppRoiConfig> cropRoiConfig_ = nullptr;
|
||||
|
||||
std::shared_ptr<acldvppPicDesc> encodeInputDesc_ = nullptr;
|
||||
std::shared_ptr<acldvppJpegeConfig> jpegeConfig_ = nullptr;
|
||||
|
||||
std::shared_ptr<acldvppPicDesc> resizeInputDesc_ = nullptr;
|
||||
std::shared_ptr<acldvppPicDesc> resizeOutputDesc_ = nullptr;
|
||||
std::shared_ptr<acldvppResizeConfig> resizeConfig_ = nullptr;
|
||||
|
||||
std::shared_ptr<acldvppPicDesc> decodeOutputDesc_ = nullptr;
|
||||
|
||||
acldvppChannelDesc *dvppChannelDesc_ = nullptr;
|
||||
aclrtStream dvppStream_ = nullptr;
|
||||
std::shared_ptr<DvppDataInfo> inputImage_ = nullptr;
|
||||
std::shared_ptr<DvppDataInfo> decodedImage_ = nullptr;
|
||||
std::shared_ptr<DvppDataInfo> encodedImage_ = nullptr;
|
||||
std::shared_ptr<DvppDataInfo> resizedImage_ = nullptr;
|
||||
std::shared_ptr<DvppDataInfo> cropImage_ = nullptr;
|
||||
bool isVdec_ = false;
|
||||
aclvdecChannelDesc *vdecChannelDesc_ = nullptr;
|
||||
acldvppStreamDesc *streamInputDesc_ = nullptr;
|
||||
acldvppPicDesc *picOutputDesc_ = nullptr;
|
||||
VdecConfig vdecConfig_;
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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 "mindspore/core/utils/log_adapter.h"
|
||||
#include "ErrorCode.h"
|
||||
|
||||
std::string GetAppErrCodeInfo(const APP_ERROR err) {
|
||||
if ((err < APP_ERR_ACL_END) && (err >= APP_ERR_ACL_FAILURE)) {
|
||||
return APP_ERR_ACL_LOG_STRING[((err < 0) ? (err + APP_ERR_ACL_END + 1) : err)];
|
||||
} else if ((err < APP_ERR_COMM_END) && (err > APP_ERR_COMM_BASE)) {
|
||||
return (err - APP_ERR_COMM_BASE) <
|
||||
(int)sizeof(APP_ERR_COMMON_LOG_STRING) / (int)sizeof(APP_ERR_COMMON_LOG_STRING[0])
|
||||
? APP_ERR_COMMON_LOG_STRING[err - APP_ERR_COMM_BASE]
|
||||
: "Undefine the error code information";
|
||||
} else if ((err < APP_ERR_DVPP_END) && (err > APP_ERR_DVPP_BASE)) {
|
||||
return (err - APP_ERR_DVPP_BASE) < (int)sizeof(APP_ERR_DVPP_LOG_STRING) / (int)sizeof(APP_ERR_DVPP_LOG_STRING[0])
|
||||
? APP_ERR_DVPP_LOG_STRING[err - APP_ERR_DVPP_BASE]
|
||||
: "Undefine the error code information";
|
||||
} else if ((err < APP_ERR_QUEUE_END) && (err > APP_ERR_QUEUE_BASE)) {
|
||||
return (err - APP_ERR_QUEUE_BASE) < (int)sizeof(APP_ERR_QUEUE_LOG_STRING) / (int)sizeof(APP_ERR_QUEUE_LOG_STRING[0])
|
||||
? APP_ERR_QUEUE_LOG_STRING[err - APP_ERR_QUEUE_BASE]
|
||||
: "Undefine the error code information";
|
||||
} else {
|
||||
return "Error code unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void AssertErrorCode(int code, std::string file, std::string function, int line) {
|
||||
if (code != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed at " << file << "->" << function << "->" << line << ": error code=" << code;
|
||||
exit(code);
|
||||
}
|
||||
}
|
||||
|
||||
void CheckErrorCode(int code, std::string file, std::string function, int line) {
|
||||
if (code != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed at " << file << "->" << function << "->" << line << ": error code=" << code;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,258 @@
|
|||
/*
|
||||
* 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 ERROR_CODE_H
|
||||
#define ERROR_CODE_H
|
||||
#include <string>
|
||||
|
||||
using APP_ERROR = int;
|
||||
// define the data tpye of error code
|
||||
enum {
|
||||
APP_ERR_OK = 0,
|
||||
|
||||
// define the error code of ACL model, this is same with the aclError which is
|
||||
// error code of ACL API Error codes 1~999 are reserved for the ACL. Do not
|
||||
// add other error codes. Add it after APP_ERR_COMMON_ERR_BASE.
|
||||
APP_ERR_ACL_FAILURE = -1, // ACL: general error
|
||||
APP_ERR_ACL_ERR_BASE = 0,
|
||||
APP_ERR_ACL_INVALID_PARAM = 1, // ACL: invalid parameter
|
||||
APP_ERR_ACL_BAD_ALLOC = 2, // ACL: memory allocation fail
|
||||
APP_ERR_ACL_RT_FAILURE = 3, // ACL: runtime failure
|
||||
APP_ERR_ACL_GE_FAILURE = 4, // ACL: Graph Engine failure
|
||||
APP_ERR_ACL_OP_NOT_FOUND = 5, // ACL: operator not found
|
||||
APP_ERR_ACL_OP_LOAD_FAILED = 6, // ACL: fail to load operator
|
||||
APP_ERR_ACL_READ_MODEL_FAILURE = 7, // ACL: fail to read model
|
||||
APP_ERR_ACL_PARSE_MODEL = 8, // ACL: parse model failure
|
||||
APP_ERR_ACL_MODEL_MISSING_ATTR = 9, // ACL: model missing attribute
|
||||
APP_ERR_ACL_DESERIALIZE_MODEL = 10, // ACL: deserialize model failure
|
||||
APP_ERR_ACL_EVENT_NOT_READY = 12, // ACL: event not ready
|
||||
APP_ERR_ACL_EVENT_COMPLETE = 13, // ACL: event complete
|
||||
APP_ERR_ACL_UNSUPPORTED_DATA_TYPE = 14, // ACL: unsupported data type
|
||||
APP_ERR_ACL_REPEAT_INITIALIZE = 15, // ACL: repeat initialize
|
||||
APP_ERR_ACL_COMPILER_NOT_REGISTERED = 16, // ACL: compiler not registered
|
||||
APP_ERR_ACL_IO = 17, // ACL: IO failed
|
||||
APP_ERR_ACL_INVALID_FILE = 18, // ACL: invalid file
|
||||
APP_ERR_ACL_INVALID_DUMP_CONFIG = 19, // ACL: invalid dump comfig
|
||||
APP_ERR_ACL_INVALID_PROFILING_CONFIG = 20, // ACL: invalid profiling config
|
||||
APP_ERR_ACL_OP_TYPE_NOT_MATCH = 21, // ACL: operator type not match
|
||||
APP_ERR_ACL_OP_INPUT_NOT_MATCH = 22, // ACL: operator input not match
|
||||
APP_ERR_ACL_OP_OUTPUT_NOT_MATCH = 23, // ACL: operator output not match
|
||||
APP_ERR_ACL_OP_ATTR_NOT_MATCH = 24, // ACL: operator attribute not match
|
||||
APP_ERR_ACL_API_NOT_SUPPORT = 25, // ACL: API not support
|
||||
APP_ERR_ACL_CREATE_DATA_BUF_FAILED = 26, // ACL: create data buffer fail
|
||||
APP_ERR_ACL_END, // Not an error code, define the range of ACL error code
|
||||
|
||||
// define the common error code, range: 1001~1999
|
||||
APP_ERR_COMM_BASE = 1000,
|
||||
APP_ERR_COMM_FAILURE = APP_ERR_COMM_BASE + 1, // General Failed
|
||||
APP_ERR_COMM_INNER = APP_ERR_COMM_BASE + 2, // Internal error
|
||||
APP_ERR_COMM_INVALID_POINTER = APP_ERR_COMM_BASE + 3, // Invalid Pointer
|
||||
APP_ERR_COMM_INVALID_PARAM = APP_ERR_COMM_BASE + 4, // Invalid parameter
|
||||
APP_ERR_COMM_UNREALIZED = APP_ERR_COMM_BASE + 5, // Not implemented
|
||||
APP_ERR_COMM_OUT_OF_MEM = APP_ERR_COMM_BASE + 6, // Out of memory
|
||||
APP_ERR_COMM_ALLOC_MEM = APP_ERR_COMM_BASE + 7, // memory allocation error
|
||||
APP_ERR_COMM_FREE_MEM = APP_ERR_COMM_BASE + 8, // free memory error
|
||||
APP_ERR_COMM_OUT_OF_RANGE = APP_ERR_COMM_BASE + 9, // out of range
|
||||
APP_ERR_COMM_NO_PERMISSION = APP_ERR_COMM_BASE + 10, // NO Permission
|
||||
APP_ERR_COMM_TIMEOUT = APP_ERR_COMM_BASE + 11, // Timed out
|
||||
APP_ERR_COMM_NOT_INIT = APP_ERR_COMM_BASE + 12, // Not initialized
|
||||
APP_ERR_COMM_INIT_FAIL = APP_ERR_COMM_BASE + 13, // initialize failed
|
||||
APP_ERR_COMM_INPROGRESS = APP_ERR_COMM_BASE + 14, // Operation now in progress
|
||||
APP_ERR_COMM_EXIST = APP_ERR_COMM_BASE + 15, // Object, file or other resource already exist
|
||||
APP_ERR_COMM_NO_EXIST = APP_ERR_COMM_BASE + 16, // Object, file or other resource doesn't exist
|
||||
APP_ERR_COMM_BUSY = APP_ERR_COMM_BASE + 17, // Object, file or other resource is in use
|
||||
APP_ERR_COMM_FULL = APP_ERR_COMM_BASE + 18, // No available Device or resource
|
||||
APP_ERR_COMM_OPEN_FAIL = APP_ERR_COMM_BASE + 19, // Device, file or resource open failed
|
||||
APP_ERR_COMM_READ_FAIL = APP_ERR_COMM_BASE + 20, // Device, file or resource read failed
|
||||
APP_ERR_COMM_WRITE_FAIL = APP_ERR_COMM_BASE + 21, // Device, file or resource write failed
|
||||
APP_ERR_COMM_DESTORY_FAIL = APP_ERR_COMM_BASE + 22, // Device, file or resource destory failed
|
||||
APP_ERR_COMM_EXIT = APP_ERR_COMM_BASE + 23, // End of data stream, stop the application
|
||||
APP_ERR_COMM_CONNECTION_CLOSE = APP_ERR_COMM_BASE + 24, // Out of connection, Communication shutdown
|
||||
APP_ERR_COMM_CONNECTION_FAILURE = APP_ERR_COMM_BASE + 25, // connection fail
|
||||
APP_ERR_COMM_STREAM_INVALID = APP_ERR_COMM_BASE + 26, // ACL stream is null pointer
|
||||
APP_ERR_COMM_END, // Not an error code, define the range of common error code
|
||||
|
||||
// define the error code of DVPP
|
||||
APP_ERR_DVPP_BASE = 2000,
|
||||
APP_ERR_DVPP_CROP_FAIL = APP_ERR_DVPP_BASE + 1, // DVPP: crop fail
|
||||
APP_ERR_DVPP_RESIZE_FAIL = APP_ERR_DVPP_BASE + 2, // DVPP: resize fail
|
||||
APP_ERR_DVPP_CROP_RESIZE_FAIL = APP_ERR_DVPP_BASE + 3, // DVPP: corp and resize fail
|
||||
APP_ERR_DVPP_CONVERT_FROMAT_FAIL = APP_ERR_DVPP_BASE + 4, // DVPP: convert image fromat fail
|
||||
APP_ERR_DVPP_VPC_FAIL = APP_ERR_DVPP_BASE + 5, // DVPP: VPC(crop, resize, convert fromat) fail
|
||||
APP_ERR_DVPP_JPEG_DECODE_FAIL = APP_ERR_DVPP_BASE + 6, // DVPP: decode jpeg or jpg fail
|
||||
APP_ERR_DVPP_JPEG_ENCODE_FAIL = APP_ERR_DVPP_BASE + 7, // DVPP: encode jpeg or jpg fail
|
||||
APP_ERR_DVPP_PNG_DECODE_FAIL = APP_ERR_DVPP_BASE + 8, // DVPP: encode png fail
|
||||
APP_ERR_DVPP_H26X_DECODE_FAIL = APP_ERR_DVPP_BASE + 9, // DVPP: decode H264 or H265 fail
|
||||
APP_ERR_DVPP_H26X_ENCODE_FAIL = APP_ERR_DVPP_BASE + 10, // DVPP: encode H264 or H265 fail
|
||||
APP_ERR_DVPP_HANDLE_NULL = APP_ERR_DVPP_BASE + 11, // DVPP: acldvppChannelDesc is nullptr
|
||||
APP_ERR_DVPP_PICDESC_FAIL = APP_ERR_DVPP_BASE + 12, // DVPP: fail to create acldvppCreatePicDesc or
|
||||
// fail to set acldvppCreatePicDesc
|
||||
APP_ERR_DVPP_CONFIG_FAIL = APP_ERR_DVPP_BASE + 13, // DVPP: fail to set dvpp configuration,such as
|
||||
// resize configuration,crop configuration
|
||||
APP_ERR_DVPP_OBJ_FUNC_MISMATCH = APP_ERR_DVPP_BASE + 14, // DVPP: DvppCommon object mismatch the function
|
||||
APP_ERR_DVPP_END, // Not an error code, define the range of common error code
|
||||
|
||||
// define the error code of inference
|
||||
APP_ERR_INFER_BASE = 3000,
|
||||
APP_ERR_INFER_SET_INPUT_FAIL = APP_ERR_INFER_BASE + 1, // Infer: set input fail
|
||||
APP_ERR_INFER_SET_OUTPUT_FAIL = APP_ERR_INFER_BASE + 2, // Infer: set output fail
|
||||
APP_ERR_INFER_CREATE_OUTPUT_FAIL = APP_ERR_INFER_BASE + 3, // Infer: create output fail
|
||||
APP_ERR_INFER_OP_SET_ATTR_FAIL = APP_ERR_INFER_BASE + 4, // Infer: set op attribute fail
|
||||
APP_ERR_INFER_GET_OUTPUT_FAIL = APP_ERR_INFER_BASE + 5, // Infer: get model output fail
|
||||
APP_ERR_INFER_FIND_MODEL_ID_FAIL = APP_ERR_INFER_BASE + 6, // Infer: find model id fail
|
||||
APP_ERR_INFER_FIND_MODEL_DESC_FAIL = APP_ERR_INFER_BASE + 7, // Infer: find model description fail
|
||||
APP_ERR_INFER_FIND_MODEL_MEM_FAIL = APP_ERR_INFER_BASE + 8, // Infer: find model memory fail
|
||||
APP_ERR_INFER_FIND_MODEL_WEIGHT_FAIL = APP_ERR_INFER_BASE + 9, // Infer: find model weight fail
|
||||
|
||||
APP_ERR_INFER_END, // Not an error code, define the range of inference error
|
||||
// code
|
||||
|
||||
// define the error code of transmission
|
||||
APP_ERR_TRANS_BASE = 4000,
|
||||
|
||||
APP_ERR_TRANS_END, // Not an error code, define the range of transmission
|
||||
// error code
|
||||
|
||||
// define the error code of blocking queue
|
||||
APP_ERR_QUEUE_BASE = 5000,
|
||||
APP_ERR_QUEUE_EMPTY = APP_ERR_QUEUE_BASE + 1, // Queue: empty queue
|
||||
APP_ERR_QUEUE_STOPED = APP_ERR_QUEUE_BASE + 2, // Queue: queue stoped
|
||||
APP_ERROR_QUEUE_FULL = APP_ERR_QUEUE_BASE + 3, // Queue: full queue
|
||||
|
||||
// define the idrecognition web error code
|
||||
APP_ERROR_FACE_WEB_USE_BASE = 10000,
|
||||
APP_ERROR_FACE_WEB_USE_SYSTEM_ERROR = APP_ERROR_FACE_WEB_USE_BASE + 1, // Web: system error
|
||||
APP_ERROR_FACE_WEB_USE_MUL_FACE = APP_ERROR_FACE_WEB_USE_BASE + 2, // Web: multiple faces
|
||||
APP_ERROR_FACE_WEB_USE_REPEAT_REG = APP_ERROR_FACE_WEB_USE_BASE + 3, // Web: repeat registration
|
||||
APP_ERROR_FACE_WEB_USE_PART_SUCCESS = APP_ERROR_FACE_WEB_USE_BASE + 4, // Web: partial search succeeded
|
||||
APP_ERROR_FACE_WEB_USE_NO_FACE = APP_ERROR_FACE_WEB_USE_BASE + 5, // Web: no face detected
|
||||
APP_ERR_QUEUE_END, // Not an error code, define the range of blocking queue
|
||||
// error code
|
||||
};
|
||||
const std::string APP_ERR_ACL_LOG_STRING[] = {
|
||||
[APP_ERR_OK] = "Success",
|
||||
[APP_ERR_ACL_INVALID_PARAM] = "ACL: invalid parameter",
|
||||
[APP_ERR_ACL_BAD_ALLOC] = "ACL: memory allocation fail",
|
||||
[APP_ERR_ACL_RT_FAILURE] = "ACL: runtime failure",
|
||||
[APP_ERR_ACL_GE_FAILURE] = "ACL: Graph Engine failure",
|
||||
[APP_ERR_ACL_OP_NOT_FOUND] = "ACL: operator not found",
|
||||
[APP_ERR_ACL_OP_LOAD_FAILED] = "ACL: fail to load operator",
|
||||
[APP_ERR_ACL_READ_MODEL_FAILURE] = "ACL: fail to read model",
|
||||
[APP_ERR_ACL_PARSE_MODEL] = "ACL: parse model failure",
|
||||
[APP_ERR_ACL_MODEL_MISSING_ATTR] = "ACL: model missing attribute",
|
||||
[APP_ERR_ACL_DESERIALIZE_MODEL] = "ACL: deserialize model failure",
|
||||
[11] = "Placeholder",
|
||||
[APP_ERR_ACL_EVENT_NOT_READY] = "ACL: event not ready",
|
||||
[APP_ERR_ACL_EVENT_COMPLETE] = "ACL: event complete",
|
||||
[APP_ERR_ACL_UNSUPPORTED_DATA_TYPE] = "ACL: unsupported data type",
|
||||
[APP_ERR_ACL_REPEAT_INITIALIZE] = "ACL: repeat initialize",
|
||||
[APP_ERR_ACL_COMPILER_NOT_REGISTERED] = "ACL: compiler not registered",
|
||||
[APP_ERR_ACL_IO] = "ACL: IO failed",
|
||||
[APP_ERR_ACL_INVALID_FILE] = "ACL: invalid file",
|
||||
[APP_ERR_ACL_INVALID_DUMP_CONFIG] = "ACL: invalid dump comfig",
|
||||
[APP_ERR_ACL_INVALID_PROFILING_CONFIG] = "ACL: invalid profiling config",
|
||||
[APP_ERR_ACL_OP_TYPE_NOT_MATCH] = "ACL: operator type not match",
|
||||
[APP_ERR_ACL_OP_INPUT_NOT_MATCH] = "ACL: operator input not match",
|
||||
[APP_ERR_ACL_OP_OUTPUT_NOT_MATCH] = "ACL: operator output not match",
|
||||
[APP_ERR_ACL_OP_ATTR_NOT_MATCH] = "ACL: operator attribute not match",
|
||||
[APP_ERR_ACL_API_NOT_SUPPORT] = "ACL: API not supported",
|
||||
[APP_ERR_ACL_CREATE_DATA_BUF_FAILED] = "ACL: create data buffer fail",
|
||||
};
|
||||
|
||||
const std::string APP_ERR_COMMON_LOG_STRING[] = {
|
||||
[0] = "Placeholder",
|
||||
[1] = "General Failed",
|
||||
[2] = "Internal error",
|
||||
[3] = "Invalid Pointer",
|
||||
[4] = "Invalid parameter",
|
||||
[5] = "Not implemented",
|
||||
[6] = "Out of memory",
|
||||
[7] = "memory allocation error",
|
||||
[8] = "free memory error",
|
||||
[9] = "out of range",
|
||||
[10] = "NO Permission ",
|
||||
[11] = "Timed out",
|
||||
[12] = "Not initialized",
|
||||
[13] = "initialize failed",
|
||||
[14] = "Operation now in progress ",
|
||||
[15] = "Object, file or other resource already exist",
|
||||
[16] = "Object, file or other resource already doesn't exist",
|
||||
[17] = "Object, file or other resource is in use",
|
||||
[18] = "No available Device or resource",
|
||||
[19] = "Device, file or resource open failed",
|
||||
[20] = "Device, file or resource read failed",
|
||||
[21] = "Device, file or resource write failed",
|
||||
[22] = "Device, file or resource destory failed",
|
||||
[23] = " ",
|
||||
[24] = "Out of connection, Communication shutdown",
|
||||
[25] = "connection fail",
|
||||
[26] = "ACL stream is null pointer",
|
||||
};
|
||||
|
||||
const std::string APP_ERR_DVPP_LOG_STRING[] = {
|
||||
[0] = "Placeholder",
|
||||
[1] = "DVPP: crop fail",
|
||||
[2] = "DVPP: resize fail",
|
||||
[3] = "DVPP: corp and resize fail",
|
||||
[4] = "DVPP: convert image format fail",
|
||||
[5] = "DVPP: VPC(crop, resize, convert format) fail",
|
||||
[6] = "DVPP: decode jpeg or jpg fail",
|
||||
[7] = "DVPP: encode jpeg or jpg fail",
|
||||
[8] = "DVPP: encode png fail",
|
||||
[9] = "DVPP: decode H264 or H265 fail",
|
||||
[10] = "DVPP: encode H264 or H265 fail",
|
||||
[11] = "DVPP: acldvppChannelDesc is nullptr",
|
||||
[12] = "DVPP: fail to create or set acldvppCreatePicDesc",
|
||||
[13] = "DVPP: fail to set dvpp configuration",
|
||||
[14] = "DVPP: DvppCommon object mismatch the function",
|
||||
};
|
||||
|
||||
const std::string APP_ERR_INFER_LOG_STRING[] = {
|
||||
[0] = "Placeholder",
|
||||
[1] = "Infer: set input fail",
|
||||
[2] = "Infer: set output fail",
|
||||
[3] = "Infer: create output fail",
|
||||
[4] = "Infer: set op attribute fail",
|
||||
[5] = "Infer: get model output fail",
|
||||
[6] = "Infer: find model id fail",
|
||||
[7] = "Infer: find model description fail",
|
||||
[8] = "Infer: find model memory fail",
|
||||
[9] = "Infer: find model weight fail",
|
||||
};
|
||||
|
||||
const std::string APP_ERR_QUEUE_LOG_STRING[] = {
|
||||
[0] = "Placeholder",
|
||||
[1] = "empty queue",
|
||||
[2] = "queue stoped",
|
||||
[3] = "full queue",
|
||||
};
|
||||
|
||||
const std::string APP_ERR_FACE_LOG_STRING[] = {
|
||||
[0] = "Placeholder",
|
||||
[1] = "system error",
|
||||
[2] = "multiple faces",
|
||||
[3] = "repeat registration",
|
||||
[4] = "partial search succeeded",
|
||||
[5] = "no face detected",
|
||||
};
|
||||
|
||||
std::string GetAppErrCodeInfo(APP_ERROR err);
|
||||
void AssertErrorCode(int code, std::string file, std::string function, int line);
|
||||
void CheckErrorCode(int code, std::string file, std::string function, int line);
|
||||
|
||||
#define RtAssert(code) AssertErrorCode(code, __FILE__, __FUNCTION__, __LINE__);
|
||||
#define RtCheckError(code) CheckErrorCode(code, __FILE__, __FUNCTION__, __LINE__);
|
||||
|
||||
#endif // ERROR_CODE_H_
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* 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 "ResourceManager.h"
|
||||
#include <algorithm>
|
||||
|
||||
bool ResourceManager::initFlag_ = true;
|
||||
std::shared_ptr<ResourceManager> ResourceManager::ptr_ = nullptr;
|
||||
|
||||
/**
|
||||
* Check whether the file exists.
|
||||
*
|
||||
* @param filePath the file path we want to check
|
||||
* @return APP_ERR_OK if file exists, error code otherwise
|
||||
*/
|
||||
APP_ERROR ExistFile(const std::string &filePath) {
|
||||
struct stat fileSat = {0};
|
||||
char c[PATH_MAX + 1] = {0x00};
|
||||
size_t count = filePath.copy(c, PATH_MAX + 1);
|
||||
if (count != filePath.length()) {
|
||||
MS_LOG(ERROR) << "Failed to strcpy" << c;
|
||||
return APP_ERR_COMM_FAILURE;
|
||||
}
|
||||
// Get the absolute path of input directory
|
||||
char path[PATH_MAX + 1] = {0x00};
|
||||
if ((strlen(c) > PATH_MAX) || (realpath(c, path) == nullptr)) {
|
||||
MS_LOG(ERROR) << "Failed to get canonicalize path";
|
||||
return APP_ERR_COMM_EXIST;
|
||||
}
|
||||
if (stat(c, &fileSat) == 0 && S_ISREG(fileSat.st_mode)) {
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
return APP_ERR_COMM_FAILURE;
|
||||
}
|
||||
|
||||
void ResourceManager::Release() {
|
||||
APP_ERROR ret;
|
||||
for (size_t i = 0; i < deviceIds_.size(); i++) {
|
||||
if (contexts_[i] != nullptr) {
|
||||
ret = aclrtDestroyContext(contexts_[i]); // Destroy context
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to destroy context, ret = " << ret << ".";
|
||||
return;
|
||||
}
|
||||
contexts_[i] = nullptr;
|
||||
}
|
||||
ret = aclrtResetDevice(deviceIds_[i]); // Reset device
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to reset device, ret = " << ret << ".";
|
||||
return;
|
||||
}
|
||||
}
|
||||
ret = aclFinalize();
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to finalize acl, ret = " << ret << ".";
|
||||
return;
|
||||
}
|
||||
MS_LOG(INFO) << "Finalized acl successfully.";
|
||||
}
|
||||
|
||||
std::shared_ptr<ResourceManager> ResourceManager::GetInstance() {
|
||||
if (ptr_ == nullptr) {
|
||||
ResourceManager *temp = new ResourceManager();
|
||||
ptr_.reset(temp);
|
||||
}
|
||||
return ptr_;
|
||||
}
|
||||
|
||||
APP_ERROR ResourceManager::InitResource(ResourceInfo &resourceInfo) {
|
||||
if (!GetInitStatus()) {
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
std::string &aclConfigPath = resourceInfo.aclConfigPath;
|
||||
APP_ERROR ret;
|
||||
if (aclConfigPath.length() == 0) {
|
||||
// Init acl without aclconfig
|
||||
ret = aclInit(nullptr);
|
||||
} else {
|
||||
ret = ExistFile(aclConfigPath);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Acl config file not exist, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
ret = aclInit(aclConfigPath.c_str()); // Initialize ACL
|
||||
}
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to init acl, ret = " << ret;
|
||||
return ret;
|
||||
}
|
||||
std::copy(resourceInfo.deviceIds.begin(), resourceInfo.deviceIds.end(), std::back_inserter(deviceIds_));
|
||||
MS_LOG(INFO) << "Initialized acl successfully.";
|
||||
// Open device and create context for each chip, note: it create one context for each chip
|
||||
for (size_t i = 0; i < deviceIds_.size(); i++) {
|
||||
deviceIdMap_[deviceIds_[i]] = i;
|
||||
ret = aclrtSetDevice(deviceIds_[i]);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to open acl device: " << deviceIds_[i];
|
||||
return ret;
|
||||
}
|
||||
MS_LOG(INFO) << "Open device " << deviceIds_[i] << " successfully.";
|
||||
aclrtContext context;
|
||||
ret = aclrtCreateContext(&context, deviceIds_[i]);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to create acl context, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
MS_LOG(INFO) << "Created context for device " << deviceIds_[i] << " successfully";
|
||||
contexts_.push_back(context);
|
||||
}
|
||||
std::string singleOpPath = resourceInfo.singleOpFolderPath;
|
||||
if (!singleOpPath.empty()) {
|
||||
ret = aclopSetModelDir(singleOpPath.c_str()); // Set operator model directory for application
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to aclopSetModelDir, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
MS_LOG(INFO) << "Init resource successfully.";
|
||||
ResourceManager::initFlag_ = false;
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
aclrtContext ResourceManager::GetContext(int deviceId) { return contexts_[deviceIdMap_[deviceId]]; }
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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 RESOURCEMANAGER_H
|
||||
#define RESOURCEMANAGER_H
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <cstring>
|
||||
#include <unordered_map>
|
||||
#include <mutex>
|
||||
#include "CommonDataType.h"
|
||||
#include "ErrorCode.h"
|
||||
#include <sys/stat.h>
|
||||
#include "mindspore/core/utils/log_adapter.h"
|
||||
|
||||
#define PATH_MAX 4096
|
||||
|
||||
enum ModelLoadMethod {
|
||||
LOAD_FROM_FILE = 0, // Loading from file, memory of model and weights are managed by ACL
|
||||
LOAD_FROM_MEM, // Loading from memory, memory of model and weights are managed by ACL
|
||||
LOAD_FROM_FILE_WITH_MEM, // Loading from file, memory of model and weight are managed by user
|
||||
LOAD_FROM_MEM_WITH_MEM // Loading from memory, memory of model and weight are managed by user
|
||||
};
|
||||
|
||||
struct ModelInfo {
|
||||
std::string modelName;
|
||||
std::string modelPath; // Path of om model file
|
||||
size_t modelFileSize; // Size of om model file
|
||||
std::shared_ptr<void> modelFilePtr; // Smart pointer of model file data
|
||||
uint32_t modelWidth; // Input width of model
|
||||
uint32_t modelHeight; // Input height of model
|
||||
ModelLoadMethod method; // Loading method of model
|
||||
};
|
||||
|
||||
// Device resource info, such as model infos, etc
|
||||
struct DeviceResInfo {
|
||||
std::vector<ModelInfo> modelInfos;
|
||||
};
|
||||
|
||||
struct ResourceInfo {
|
||||
std::set<int> deviceIds;
|
||||
std::string aclConfigPath;
|
||||
std::string singleOpFolderPath;
|
||||
std::unordered_map<int, DeviceResInfo> deviceResInfos; // map <deviceId, deviceResourceInfo>
|
||||
};
|
||||
|
||||
APP_ERROR ExistFile(const std::string &filePath);
|
||||
|
||||
class ResourceManager {
|
||||
public:
|
||||
ResourceManager(){};
|
||||
|
||||
~ResourceManager(){};
|
||||
|
||||
// Get the Instance of resource manager
|
||||
static std::shared_ptr<ResourceManager> GetInstance();
|
||||
|
||||
// Init the resource of resource manager
|
||||
APP_ERROR InitResource(ResourceInfo &resourceInfo);
|
||||
|
||||
aclrtContext GetContext(int deviceId);
|
||||
|
||||
void Release();
|
||||
|
||||
static bool GetInitStatus() { return initFlag_; }
|
||||
|
||||
private:
|
||||
static std::shared_ptr<ResourceManager> ptr_;
|
||||
static bool initFlag_;
|
||||
std::vector<int> deviceIds_;
|
||||
std::vector<aclrtContext> contexts_;
|
||||
std::unordered_map<int, int> deviceIdMap_; // Map of device to index
|
||||
};
|
||||
|
||||
#endif
|
|
@ -57,6 +57,7 @@ constexpr char kCenterCropOp[] = "CenterCropOp";
|
|||
constexpr char kCutMixBatchOp[] = "CutMixBatchOp";
|
||||
constexpr char kCutOutOp[] = "CutOutOp";
|
||||
constexpr char kCropOp[] = "CropOp";
|
||||
constexpr char kDvppDecodeResizeCropJpegOp[] = "DvppDecodeResizeCropJpegOp";
|
||||
constexpr char kEqualizeOp[] = "EqualizeOp";
|
||||
constexpr char kHwcToChwOp[] = "HwcToChwOp";
|
||||
constexpr char kInvertOp[] = "InvertOp";
|
||||
|
|
|
@ -31,10 +31,10 @@ class TestDE : public ST::Common {
|
|||
|
||||
TEST_F(TestDE, ResNetPreprocess) {
|
||||
std::vector<std::shared_ptr<Tensor>> images;
|
||||
MindDataEager::LoadImageFromDir("/home/workspace/mindspore_dataset/imagenet/imagenet_original/val/n01440764", &images);
|
||||
MindDataEager::LoadImageFromDir("/home/workspace/mindspore_dataset/imagenet/imagenet_original/val/n01440764",
|
||||
&images);
|
||||
|
||||
MindDataEager Compose({Decode(),
|
||||
Resize({224, 224}),
|
||||
MindDataEager Compose({Decode(), Resize({224, 224}),
|
||||
Normalize({0.485 * 255, 0.456 * 255, 0.406 * 255}, {0.229 * 255, 0.224 * 255, 0.225 * 255}),
|
||||
HWC2CHW()});
|
||||
|
||||
|
@ -47,3 +47,19 @@ TEST_F(TestDE, ResNetPreprocess) {
|
|||
ASSERT_EQ(images[0]->Shape()[1], 224);
|
||||
ASSERT_EQ(images[0]->Shape()[2], 224);
|
||||
}
|
||||
|
||||
TEST_F(TestDE, TestDvpp) {
|
||||
std::vector<std::shared_ptr<Tensor>> images;
|
||||
MindDataEager::LoadImageFromDir("/root/Dvpp_Unit_Dev/val2014_test/", &images);
|
||||
|
||||
MindDataEager Solo({DvppDecodeResizeCropJpeg({224, 224}, {256, 256})});
|
||||
|
||||
for (auto &img : images) {
|
||||
img = Solo(img);
|
||||
}
|
||||
|
||||
ASSERT_EQ(images[0]->Shape().size(), 3);
|
||||
ASSERT_EQ(images[0]->Shape()[0], 224 * 224 * 1.5);
|
||||
ASSERT_EQ(images[0]->Shape()[1], 1);
|
||||
ASSERT_EQ(images[0]->Shape()[2], 1);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue