From: @lizhenglong1992 Reviewed-by: Signed-off-by:tags/v1.1.0
| @@ -3,6 +3,13 @@ include_directories(${CMAKE_SOURCE_DIR}/mindspore/core) | |||||
| include_directories(${CMAKE_CURRENT_SOURCE_DIR}) | include_directories(${CMAKE_CURRENT_SOURCE_DIR}) | ||||
| include_directories(${CMAKE_BINARY_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")) | if (NOT(CMAKE_SYSTEM_NAME MATCHES "Darwin")) | ||||
| link_directories(${CMAKE_SOURCE_DIR}/build/mindspore/graphengine) | link_directories(${CMAKE_SOURCE_DIR}/build/mindspore/graphengine) | ||||
| endif () | endif () | ||||
| @@ -17,6 +17,10 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-attributes") | |||||
| if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") | if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") | ||||
| add_definitions(-D _CRT_RAND_S) | add_definitions(-D _CRT_RAND_S) | ||||
| endif () | endif () | ||||
| if (ENABLE_ACL) | |||||
| add_definitions(-D ENABLE_ACL) | |||||
| message(STATUS "ACL module is enabled") | |||||
| endif () | |||||
| if (ENABLE_GPUQUE) | if (ENABLE_GPUQUE) | ||||
| add_definitions(-D ENABLE_GPUQUE) | add_definitions(-D ENABLE_GPUQUE) | ||||
| message(STATUS "GPU queue is enabled") | message(STATUS "GPU queue is enabled") | ||||
| @@ -114,6 +118,10 @@ if (NOT(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")) | |||||
| add_dependencies(text-kernels core) | add_dependencies(text-kernels core) | ||||
| endif () | endif () | ||||
| if (ENABLE_ACL) | |||||
| add_dependencies(kernels-dvpp-image core dvpp-utils) | |||||
| endif () | |||||
| if (ENABLE_PYTHON) | if (ENABLE_PYTHON) | ||||
| add_dependencies(APItoPython core) | add_dependencies(APItoPython core) | ||||
| endif () | endif () | ||||
| @@ -163,6 +171,13 @@ if (NOT(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")) | |||||
| ) | ) | ||||
| endif () | endif () | ||||
| if (ENABLE_ACL) | |||||
| set(submodules | |||||
| ${submodules} | |||||
| $<TARGET_OBJECTS:kernels-dvpp-image> | |||||
| $<TARGET_OBJECTS:dvpp-utils>) | |||||
| endif () | |||||
| if (ENABLE_PYTHON) | if (ENABLE_PYTHON) | ||||
| set(submodules | set(submodules | ||||
| ${submodules} | ${submodules} | ||||
| @@ -186,6 +201,11 @@ endif () | |||||
| ################# Link with external libraries ######################## | ################# Link with external libraries ######################## | ||||
| target_link_libraries(_c_dataengine PRIVATE mindspore mindspore_gvar) | 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 (${CMAKE_SYSTEM_NAME} MATCHES "Windows") | ||||
| if (ENABLE_PYTHON) | if (ENABLE_PYTHON) | ||||
| target_link_libraries(_c_dataengine PRIVATE mindspore::pybind11_module ${PYTHON_LIBRARIES} ${SECUREC_LIBRARY}) | 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" | #include "minddata/dataset/kernels/image/cut_out_op.h" | ||||
| #endif | #endif | ||||
| #include "minddata/dataset/kernels/image/decode_op.h" | #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 | #ifndef ENABLE_ANDROID | ||||
| #include "minddata/dataset/kernels/image/equalize_op.h" | #include "minddata/dataset/kernels/image/equalize_op.h" | ||||
| #include "minddata/dataset/kernels/image/hwc_to_chw_op.h" | #include "minddata/dataset/kernels/image/hwc_to_chw_op.h" | ||||
| @@ -133,6 +136,16 @@ std::shared_ptr<DecodeOperation> Decode(bool rgb) { | |||||
| return op->ValidateParams() ? op : nullptr; | 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. | // Function to create EqualizeOperation. | ||||
| std::shared_ptr<EqualizeOperation> Equalize() { | std::shared_ptr<EqualizeOperation> Equalize() { | ||||
| auto op = std::make_shared<EqualizeOperation>(); | auto op = std::make_shared<EqualizeOperation>(); | ||||
| @@ -656,6 +669,78 @@ Status MixUpBatchOperation::ValidateParams() { | |||||
| std::shared_ptr<TensorOp> MixUpBatchOperation::Build() { return std::make_shared<MixUpBatchOp>(alpha_); } | std::shared_ptr<TensorOp> MixUpBatchOperation::Build() { return std::make_shared<MixUpBatchOp>(alpha_); } | ||||
| #endif | #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::NormalizeOperation(std::vector<float> mean, std::vector<float> std) : mean_(mean), std_(std) {} | 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 kBoundingBoxAugmentOperation[] = "BoundingBoxAugment"; | ||||
| constexpr char kCutMixBatchOperation[] = "CutMixBatch"; | constexpr char kCutMixBatchOperation[] = "CutMixBatch"; | ||||
| constexpr char kCutOutOperation[] = "CutOut"; | constexpr char kCutOutOperation[] = "CutOut"; | ||||
| constexpr char kDvppDecodeResizeCropOperation[] = "DvppDecodeResizeCrop"; | |||||
| constexpr char kEqualizeOperation[] = "Equalize"; | constexpr char kEqualizeOperation[] = "Equalize"; | ||||
| constexpr char kHwcToChwOperation[] = "HwcToChw"; | constexpr char kHwcToChwOperation[] = "HwcToChw"; | ||||
| constexpr char kInvertOperation[] = "Invert"; | constexpr char kInvertOperation[] = "Invert"; | ||||
| @@ -76,6 +77,7 @@ class AutoContrastOperation; | |||||
| class BoundingBoxAugmentOperation; | class BoundingBoxAugmentOperation; | ||||
| class CutMixBatchOperation; | class CutMixBatchOperation; | ||||
| class CutOutOperation; | class CutOutOperation; | ||||
| class DvppDecodeResizeCropOperation; | |||||
| class EqualizeOperation; | class EqualizeOperation; | ||||
| class HwcToChwOperation; | class HwcToChwOperation; | ||||
| class InvertOperation; | class InvertOperation; | ||||
| @@ -142,6 +144,22 @@ std::shared_ptr<CutMixBatchOperation> CutMixBatch(ImageBatchFormat image_batch_f | |||||
| /// \return Shared pointer to the current TensorOp | /// \return Shared pointer to the current TensorOp | ||||
| std::shared_ptr<CutOutOperation> CutOut(int32_t length, int32_t num_patches = 1); | 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. | /// \brief Function to create a Equalize TensorOperation. | ||||
| /// \notes Apply histogram equalization on input image. | /// \notes Apply histogram equalization on input image. | ||||
| /// \return Shared pointer to the current TensorOperation. | /// \return Shared pointer to the current TensorOperation. | ||||
| @@ -553,6 +571,23 @@ class CutOutOperation : public TensorOperation { | |||||
| ImageBatchFormat image_batch_format_; | 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 { | class EqualizeOperation : public TensorOperation { | ||||
| public: | public: | ||||
| ~EqualizeOperation() = default; | ~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) | set_property(SOURCE ${_CURRENT_SRC_FILES} PROPERTY COMPILE_DEFINITIONS SUBMODULE_ID=mindspore::SubModuleId::SM_MD) | ||||
| add_subdirectory(soft_dvpp) | add_subdirectory(soft_dvpp) | ||||
| add_subdirectory(lite_cv) | add_subdirectory(lite_cv) | ||||
| if (ENABLE_ACL) | |||||
| add_subdirectory(dvpp) | |||||
| endif () | |||||
| add_library(kernels-image OBJECT | add_library(kernels-image OBJECT | ||||
| affine_op.cc | affine_op.cc | ||||
| auto_contrast_op.cc | auto_contrast_op.cc | ||||
| @@ -51,4 +54,8 @@ add_library(kernels-image OBJECT | |||||
| random_resize_with_bbox_op.cc | random_resize_with_bbox_op.cc | ||||
| random_color_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 | |||||
| @@ -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 kCutMixBatchOp[] = "CutMixBatchOp"; | ||||
| constexpr char kCutOutOp[] = "CutOutOp"; | constexpr char kCutOutOp[] = "CutOutOp"; | ||||
| constexpr char kCropOp[] = "CropOp"; | constexpr char kCropOp[] = "CropOp"; | ||||
| constexpr char kDvppDecodeResizeCropJpegOp[] = "DvppDecodeResizeCropJpegOp"; | |||||
| constexpr char kEqualizeOp[] = "EqualizeOp"; | constexpr char kEqualizeOp[] = "EqualizeOp"; | ||||
| constexpr char kHwcToChwOp[] = "HwcToChwOp"; | constexpr char kHwcToChwOp[] = "HwcToChwOp"; | ||||
| constexpr char kInvertOp[] = "InvertOp"; | constexpr char kInvertOp[] = "InvertOp"; | ||||
| @@ -31,10 +31,10 @@ class TestDE : public ST::Common { | |||||
| TEST_F(TestDE, ResNetPreprocess) { | TEST_F(TestDE, ResNetPreprocess) { | ||||
| std::vector<std::shared_ptr<Tensor>> images; | 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}), | Normalize({0.485 * 255, 0.456 * 255, 0.406 * 255}, {0.229 * 255, 0.224 * 255, 0.225 * 255}), | ||||
| HWC2CHW()}); | HWC2CHW()}); | ||||
| @@ -47,3 +47,19 @@ TEST_F(TestDE, ResNetPreprocess) { | |||||
| ASSERT_EQ(images[0]->Shape()[1], 224); | ASSERT_EQ(images[0]->Shape()[1], 224); | ||||
| ASSERT_EQ(images[0]->Shape()[2], 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); | |||||
| } | |||||