forked from mindspore-Ecosystem/mindspore
Dvpp refactor and 6 Dvpp operators
This commit is contained in:
parent
5f72693b4b
commit
e2d3495925
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "minddata/dataset/include/execute.h"
|
||||
#include "minddata/dataset/core/de_tensor.h"
|
||||
#include "minddata/dataset/core/device_tensor.h"
|
||||
#include "minddata/dataset/core/tensor_row.h"
|
||||
#include "minddata/dataset/include/tensor.h"
|
||||
#include "minddata/dataset/include/type_id.h"
|
||||
|
@ -25,53 +26,194 @@
|
|||
#else
|
||||
#include "mindspore/lite/src/common/log_adapter.h"
|
||||
#endif
|
||||
#ifdef ENABLE_ACL
|
||||
#include "acl/acl.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/ResourceManager.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/ErrorCode.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/MDAclProcess.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/CommonDataType.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/DvppCommon.h"
|
||||
#endif
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
#ifdef ENABLE_ACL
|
||||
class AscendResource {
|
||||
public:
|
||||
AscendResource();
|
||||
~AscendResource() = default;
|
||||
|
||||
Execute::Execute(std::shared_ptr<TensorOperation> op) { ops_.emplace_back(std::move(op)); }
|
||||
Status InitChipResource();
|
||||
|
||||
Execute::Execute(std::vector<std::shared_ptr<TensorOperation>> ops) : ops_(std::move(ops)) {}
|
||||
Status FinalizeChipResource();
|
||||
|
||||
Status Sink(const mindspore::MSTensor &host_input, std::shared_ptr<DeviceTensor> *device_input);
|
||||
|
||||
Status Pop(std::shared_ptr<DeviceTensor> device_output, std::shared_ptr<Tensor> *host_output);
|
||||
|
||||
Status DeviceDataRelease();
|
||||
|
||||
std::shared_ptr<MDAclProcess> processor_;
|
||||
std::shared_ptr<ResourceManager> ascend_resource_;
|
||||
};
|
||||
|
||||
AscendResource::AscendResource() { InitChipResource(); }
|
||||
|
||||
Status AscendResource::InitChipResource() {
|
||||
ResourceInfo resource;
|
||||
resource.aclConfigPath = "";
|
||||
resource.deviceIds.insert(mindspore::GlobalContext::GetGlobalDeviceID());
|
||||
ascend_resource_ = ResourceManager::GetInstance();
|
||||
APP_ERROR ret = ascend_resource_->InitResource(resource);
|
||||
if (ret != APP_ERR_OK) {
|
||||
ascend_resource_->Release();
|
||||
std::string err_msg = "Error in Init D-chip:" + std::to_string(ret);
|
||||
MS_LOG(ERROR) << err_msg;
|
||||
RETURN_STATUS_UNEXPECTED(err_msg);
|
||||
}
|
||||
int device_id = *(resource.deviceIds.begin());
|
||||
aclrtContext context = ascend_resource_->GetContext(device_id);
|
||||
processor_ = std::make_shared<MDAclProcess>(context, false);
|
||||
ret = processor_->InitResource();
|
||||
if (ret != APP_ERR_OK) {
|
||||
ascend_resource_->Release();
|
||||
std::string err_msg = "Error in Init resource:" + std::to_string(ret);
|
||||
MS_LOG(ERROR) << err_msg;
|
||||
RETURN_STATUS_UNEXPECTED(err_msg);
|
||||
}
|
||||
MS_LOG(INFO) << "Ascend resource all initialized!";
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status AscendResource::FinalizeChipResource() {
|
||||
processor_->Release();
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status AscendResource::Sink(const mindspore::MSTensor &host_input, std::shared_ptr<DeviceTensor> *device_input) {
|
||||
std::shared_ptr<mindspore::dataset::Tensor> de_input;
|
||||
Status rc = dataset::Tensor::CreateFromMemory(dataset::TensorShape(host_input.Shape()),
|
||||
MSTypeToDEType(static_cast<TypeId>(host_input.DataType())),
|
||||
(const uchar *)(host_input.Data().get()), &de_input);
|
||||
RETURN_IF_NOT_OK(rc);
|
||||
APP_ERROR ret = processor_->H2D_Sink(de_input, *device_input);
|
||||
if (ret != APP_ERR_OK) {
|
||||
ascend_resource_->Release();
|
||||
std::string err_msg = "Error in data sink process:" + std::to_string(ret);
|
||||
MS_LOG(ERROR) << err_msg;
|
||||
RETURN_STATUS_UNEXPECTED(err_msg);
|
||||
}
|
||||
MS_LOG(INFO) << "Process data sink successfully";
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status AscendResource::Pop(std::shared_ptr<DeviceTensor> device_output, std::shared_ptr<Tensor> *host_output) {
|
||||
APP_ERROR ret = processor_->D2H_Pop(device_output, *host_output);
|
||||
if (ret != APP_ERR_OK) {
|
||||
ascend_resource_->Release();
|
||||
std::string err_msg = "Error in data pop processing:" + std::to_string(ret);
|
||||
MS_LOG(ERROR) << err_msg;
|
||||
RETURN_STATUS_UNEXPECTED(err_msg);
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status AscendResource::DeviceDataRelease() {
|
||||
APP_ERROR ret = processor_->device_memory_release();
|
||||
if (ret != APP_ERR_OK) {
|
||||
ascend_resource_->Release();
|
||||
std::string err_msg = "Error in device data release:" + std::to_string(ret);
|
||||
MS_LOG(ERROR) << err_msg;
|
||||
RETURN_STATUS_UNEXPECTED(err_msg);
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
#endif
|
||||
|
||||
Execute::Execute(std::shared_ptr<TensorOperation> op, std::string deviceType) {
|
||||
ops_.emplace_back(std::move(op));
|
||||
device_type_ = deviceType;
|
||||
MS_LOG(INFO) << "Running Device: " << device_type_;
|
||||
#ifdef ENABLE_ACL
|
||||
if (device_type_ == "Ascend310") {
|
||||
D_resource_ = std::make_shared<AscendResource>();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Execute::Execute(std::vector<std::shared_ptr<TensorOperation>> ops, std::string deviceType)
|
||||
: ops_(std::move(ops)), device_type_(deviceType) {
|
||||
MS_LOG(INFO) << "Running Device: " << device_type_;
|
||||
#ifdef ENABLE_ACL
|
||||
if (device_type_ == "Ascend310") {
|
||||
D_resource_ = std::make_shared<AscendResource>();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Execute::~Execute() {
|
||||
#ifdef ENABLE_ACL
|
||||
if (device_type_ == "Ascend310") {
|
||||
D_resource_->FinalizeChipResource();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Status Execute::operator()(const mindspore::MSTensor &input, mindspore::MSTensor *output) {
|
||||
// Validate input tensor
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(input.DataSize() > 0, "Input Tensor has no data");
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(!ops_.empty(), "Input TensorOperation should be provided");
|
||||
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(validate_device_(), "Device Type should be 'Ascend310' or 'CPU'");
|
||||
// Validate and build runtime ops
|
||||
std::vector<std::shared_ptr<TensorOp>> transforms;
|
||||
std::vector<std::shared_ptr<TensorOp>> transforms; // record the transformations
|
||||
for (int32_t i = 0; i < ops_.size(); i++) {
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(ops_[i] != nullptr, "Input TensorOperation[" + std::to_string(i) + "] is null");
|
||||
RETURN_IF_NOT_OK(ops_[i]->ValidateParams());
|
||||
transforms.emplace_back(ops_[i]->Build());
|
||||
}
|
||||
|
||||
// Convert mindspore::Tensor to dataset::Tensor
|
||||
std::shared_ptr<dataset::Tensor> de_tensor;
|
||||
Status rc = dataset::Tensor::CreateFromMemory(dataset::TensorShape(input.Shape()),
|
||||
MSTypeToDEType(static_cast<TypeId>(input.DataType())),
|
||||
(const uchar *)(input.Data().get()), input.DataSize(), &de_tensor);
|
||||
if (rc.IsError()) {
|
||||
MS_LOG(ERROR) << rc;
|
||||
RETURN_IF_NOT_OK(rc);
|
||||
}
|
||||
|
||||
// Apply transforms on tensor
|
||||
for (auto &t : transforms) {
|
||||
std::shared_ptr<dataset::Tensor> de_output;
|
||||
Status rc_ = t->Compute(de_tensor, &de_output);
|
||||
if (rc_.IsError()) {
|
||||
MS_LOG(ERROR) << rc_;
|
||||
RETURN_IF_NOT_OK(rc_);
|
||||
if (device_type_ == "CPU") {
|
||||
// Convert mindspore::Tensor to dataset::Tensor
|
||||
std::shared_ptr<dataset::Tensor> de_tensor;
|
||||
Status rc = dataset::Tensor::CreateFromMemory(dataset::TensorShape(input.Shape()),
|
||||
MSTypeToDEType(static_cast<TypeId>(input.DataType())),
|
||||
(const uchar *)(input.Data().get()), input.DataSize(), &de_tensor);
|
||||
if (rc.IsError()) {
|
||||
MS_LOG(ERROR) << rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
// For next transform
|
||||
de_tensor = std::move(de_output);
|
||||
}
|
||||
// Apply transforms on tensor
|
||||
for (auto &t : transforms) {
|
||||
std::shared_ptr<dataset::Tensor> de_output;
|
||||
Status rc_ = t->Compute(de_tensor, &de_output);
|
||||
if (rc_.IsError()) {
|
||||
MS_LOG(ERROR) << rc_;
|
||||
return rc_;
|
||||
}
|
||||
|
||||
// Convert dataset::Tensor to mindspore::Tensor
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(de_tensor->HasData(), "Apply transform failed, output tensor has no data");
|
||||
*output = mindspore::MSTensor(std::make_shared<DETensor>(de_tensor));
|
||||
// For next transform
|
||||
de_tensor = std::move(de_output);
|
||||
}
|
||||
|
||||
// Convert dataset::Tensor to mindspore::Tensor
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(de_tensor->HasData(), "Apply transform failed, output tensor has no data");
|
||||
*output = mindspore::MSTensor(std::make_shared<DETensor>(de_tensor));
|
||||
} else { // Ascend310 case, where we must set Ascend resource on each operators
|
||||
#ifdef ENABLE_ACL
|
||||
std::shared_ptr<mindspore::dataset::DeviceTensor> device_input;
|
||||
RETURN_IF_NOT_OK(D_resource_->Sink(input, &device_input));
|
||||
for (auto &t : transforms) {
|
||||
std::shared_ptr<DeviceTensor> device_output;
|
||||
RETURN_IF_NOT_OK(t->SetAscendResource(D_resource_->processor_));
|
||||
RETURN_IF_NOT_OK(t->Compute(device_input, &device_output));
|
||||
|
||||
// For next transform
|
||||
device_input = std::move(device_output);
|
||||
}
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(device_input->HasDeviceData(), "Apply transform failed, output tensor has no data");
|
||||
*output = mindspore::MSTensor(std::make_shared<DETensor>(device_input, true));
|
||||
#endif
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
|
@ -82,6 +224,7 @@ Status Execute::operator()(const std::vector<MSTensor> &input_tensor_list, std::
|
|||
CHECK_FAIL_RETURN_UNEXPECTED(tensor.DataSize() > 0, "Input Tensor has no data");
|
||||
}
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(!ops_.empty(), "Input TensorOperation should be provided");
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(validate_device_(), "Device Type should be 'Ascend310' or 'CPU'");
|
||||
|
||||
// Validate and build runtime ops
|
||||
std::vector<std::shared_ptr<TensorOp>> transforms;
|
||||
|
@ -90,40 +233,81 @@ Status Execute::operator()(const std::vector<MSTensor> &input_tensor_list, std::
|
|||
RETURN_IF_NOT_OK(ops_[i]->ValidateParams());
|
||||
transforms.emplace_back(ops_[i]->Build());
|
||||
}
|
||||
|
||||
TensorRow de_tensor_list;
|
||||
for (auto &tensor : input_tensor_list) {
|
||||
std::shared_ptr<dataset::Tensor> de_tensor;
|
||||
Status rc = dataset::Tensor::CreateFromMemory(dataset::TensorShape(tensor.Shape()),
|
||||
MSTypeToDEType(static_cast<TypeId>(tensor.DataType())),
|
||||
(const uchar *)(tensor.Data().get()), tensor.DataSize(), &de_tensor);
|
||||
if (rc.IsError()) {
|
||||
MS_LOG(ERROR) << rc;
|
||||
RETURN_IF_NOT_OK(rc);
|
||||
if (device_type_ == "CPU") { // Case CPU
|
||||
TensorRow de_tensor_list;
|
||||
for (auto &tensor : input_tensor_list) {
|
||||
std::shared_ptr<dataset::Tensor> de_tensor;
|
||||
Status rc = dataset::Tensor::CreateFromMemory(
|
||||
dataset::TensorShape(tensor.Shape()), MSTypeToDEType(static_cast<TypeId>(tensor.DataType())),
|
||||
(const uchar *)(tensor.Data().get()), tensor.DataSize(), &de_tensor);
|
||||
if (rc.IsError()) {
|
||||
MS_LOG(ERROR) << rc;
|
||||
RETURN_IF_NOT_OK(rc);
|
||||
}
|
||||
de_tensor_list.emplace_back(std::move(de_tensor));
|
||||
}
|
||||
de_tensor_list.emplace_back(std::move(de_tensor));
|
||||
}
|
||||
|
||||
// Apply transforms on tensor
|
||||
for (auto &t : transforms) {
|
||||
TensorRow de_output_list;
|
||||
Status rc = t->Compute(de_tensor_list, &de_output_list);
|
||||
if (rc.IsError()) {
|
||||
MS_LOG(ERROR) << rc;
|
||||
RETURN_IF_NOT_OK(rc);
|
||||
// Apply transforms on tensor
|
||||
for (auto &t : transforms) {
|
||||
TensorRow de_output_list;
|
||||
RETURN_IF_NOT_OK(t->Compute(de_tensor_list, &de_output_list));
|
||||
// For next transform
|
||||
de_tensor_list = std::move(de_output_list);
|
||||
}
|
||||
// For next transform
|
||||
de_tensor_list = std::move(de_output_list);
|
||||
}
|
||||
|
||||
for (auto &tensor : de_tensor_list) {
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(tensor->HasData(), "Apply transform failed, output tensor has no data");
|
||||
auto ms_tensor = mindspore::MSTensor(std::make_shared<DETensor>(tensor));
|
||||
output_tensor_list->emplace_back(ms_tensor);
|
||||
for (auto &tensor : de_tensor_list) {
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(tensor->HasData(), "Apply transform failed, output tensor has no data");
|
||||
auto ms_tensor = mindspore::MSTensor(std::make_shared<DETensor>(tensor));
|
||||
output_tensor_list->emplace_back(ms_tensor);
|
||||
}
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(!output_tensor_list->empty(), "Output Tensor is not valid");
|
||||
} else { // Case Ascend310
|
||||
#ifdef ENABLE_ACL
|
||||
for (auto &input_tensor : input_tensor_list) {
|
||||
std::shared_ptr<dataset::DeviceTensor> device_input;
|
||||
RETURN_IF_NOT_OK(D_resource_->Sink(input_tensor, &device_input));
|
||||
for (auto &t : transforms) {
|
||||
std::shared_ptr<DeviceTensor> device_output;
|
||||
RETURN_IF_NOT_OK(t->SetAscendResource(D_resource_->processor_));
|
||||
RETURN_IF_NOT_OK(t->Compute(device_input, &device_output));
|
||||
|
||||
// For next transform
|
||||
device_input = std::move(device_output);
|
||||
}
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(device_input->HasDeviceData(), "Apply transform failed, output tensor has no data");
|
||||
// Due to the limitation of Ascend310 memory, we have to pop every data onto host memory
|
||||
// So the speed of this method is slower than solo mode
|
||||
std::shared_ptr<mindspore::dataset::Tensor> host_output;
|
||||
RETURN_IF_NOT_OK(D_resource_->Pop(device_input, &host_output));
|
||||
auto ms_tensor = mindspore::MSTensor(std::make_shared<DETensor>(host_output));
|
||||
output_tensor_list->emplace_back(ms_tensor);
|
||||
RETURN_IF_NOT_OK(D_resource_->DeviceDataRelease());
|
||||
}
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(!output_tensor_list->empty(), "Output Tensor vector is empty");
|
||||
#endif
|
||||
}
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(!output_tensor_list->empty(), "Output Tensor is not valid");
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status Execute::validate_device_() {
|
||||
if (device_type_ != "CPU" && device_type_ != "Ascend310") {
|
||||
std::string err_msg = device_type_ + " is not supported. (Option: CPU or Ascend310)";
|
||||
MS_LOG(ERROR) << err_msg;
|
||||
RETURN_STATUS_UNEXPECTED(err_msg);
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ACL
|
||||
Status Execute::DeviceMemoryRelease() {
|
||||
Status rc = D_resource_->DeviceDataRelease();
|
||||
if (rc.IsError()) {
|
||||
D_resource_->ascend_resource_->Release();
|
||||
std::string err_msg = "Error in device data release";
|
||||
MS_LOG(ERROR) << err_msg;
|
||||
RETURN_STATUS_UNEXPECTED(err_msg);
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
#endif
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
||||
|
|
|
@ -37,7 +37,13 @@
|
|||
#endif
|
||||
#include "minddata/dataset/kernels/image/decode_op.h"
|
||||
#ifdef ENABLE_ACL
|
||||
#include "minddata/dataset/include/vision_ascend.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/dvpp_crop_jpeg_op.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/dvpp_decode_resize_jpeg_op.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/dvpp_decode_resize_crop_jpeg_op.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/dvpp_decode_jpeg_op.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/dvpp_decode_png_op.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/dvpp_resize_jpeg_op.h"
|
||||
#endif
|
||||
#ifndef ENABLE_ANDROID
|
||||
#include "minddata/dataset/kernels/image/equalize_op.h"
|
||||
|
@ -143,6 +149,20 @@ std::shared_ptr<DecodeOperation> Decode(bool rgb) {
|
|||
}
|
||||
|
||||
#ifdef ENABLE_ACL
|
||||
// Function to create DvppResizeOperation.
|
||||
std::shared_ptr<DvppCropJpegOperation> DvppCropJpeg(std::vector<uint32_t> crop) {
|
||||
auto op = std::make_shared<DvppCropJpegOperation>(crop);
|
||||
// Input validation
|
||||
return op->ValidateParams() ? op : nullptr;
|
||||
}
|
||||
|
||||
// Function to create DvppDecodeResizeOperation.
|
||||
std::shared_ptr<DvppDecodeResizeOperation> DvppDecodeResizeJpeg(std::vector<uint32_t> resize) {
|
||||
auto op = std::make_shared<DvppDecodeResizeOperation>(resize);
|
||||
// Input validation
|
||||
return op->ValidateParams() ? op : nullptr;
|
||||
}
|
||||
|
||||
// Function to create DvppDecodeResizeCropOperation.
|
||||
std::shared_ptr<DvppDecodeResizeCropOperation> DvppDecodeResizeCropJpeg(std::vector<uint32_t> crop,
|
||||
std::vector<uint32_t> resize) {
|
||||
|
@ -150,6 +170,27 @@ std::shared_ptr<DvppDecodeResizeCropOperation> DvppDecodeResizeCropJpeg(std::vec
|
|||
// Input validation
|
||||
return op->ValidateParams() ? op : nullptr;
|
||||
}
|
||||
|
||||
// Function to create DvppDecodeJpegOperation.
|
||||
std::shared_ptr<DvppDecodeJpegOperation> DvppDecodeJpeg() {
|
||||
auto op = std::make_shared<DvppDecodeJpegOperation>();
|
||||
// Input validation
|
||||
return op->ValidateParams() ? op : nullptr;
|
||||
}
|
||||
|
||||
// Function to create DvppDecodePngOperation.
|
||||
std::shared_ptr<DvppDecodePngOperation> DvppDecodePng() {
|
||||
auto op = std::make_shared<DvppDecodePngOperation>();
|
||||
// Input validation
|
||||
return op->ValidateParams() ? op : nullptr;
|
||||
}
|
||||
|
||||
// Function to create DvppResizeOperation.
|
||||
std::shared_ptr<DvppResizeJpegOperation> DvppResizeJpeg(std::vector<uint32_t> resize) {
|
||||
auto op = std::make_shared<DvppResizeJpegOperation>(resize);
|
||||
// Input validation
|
||||
return op->ValidateParams() ? op : nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Function to create EqualizeOperation.
|
||||
|
@ -445,6 +486,232 @@ std::shared_ptr<UniformAugOperation> UniformAugment(std::vector<std::shared_ptr<
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ACL
|
||||
// DvppCropOperation
|
||||
DvppCropJpegOperation::DvppCropJpegOperation(const std::vector<uint32_t> &crop) : crop_(crop) {}
|
||||
|
||||
Status DvppCropJpegOperation::ValidateParams() {
|
||||
// size
|
||||
if (crop_.empty() || crop_.size() > 2) {
|
||||
std::string err_msg =
|
||||
"DvppCropJpeg: Crop resolution 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 (*min_element(crop_.begin(), crop_.end()) < 32 || *max_element(crop_.begin(), crop_.end()) > 2048) {
|
||||
std::string err_msg = "Dvpp module supports crop image with resolution in range [32, 2048], got crop Parameters: ";
|
||||
if (crop_.size() == 2) {
|
||||
MS_LOG(ERROR) << err_msg << "[" << crop_[0] << ", " << crop_[1] << "]";
|
||||
} else {
|
||||
MS_LOG(ERROR) << err_msg << "[" << crop_[0] << ", " << crop_[0] << "]";
|
||||
}
|
||||
RETURN_STATUS_SYNTAX_ERROR(err_msg);
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
std::shared_ptr<TensorOp> DvppCropJpegOperation::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;
|
||||
// User specified the width value.
|
||||
if (crop_.size() == 1) {
|
||||
cropHeight = crop_[0];
|
||||
cropWidth = crop_[0];
|
||||
} else {
|
||||
cropHeight = crop_[0];
|
||||
cropWidth = crop_[1];
|
||||
}
|
||||
std::shared_ptr<DvppCropJpegOp> tensor_op = std::make_shared<DvppCropJpegOp>(cropHeight, cropWidth);
|
||||
return tensor_op;
|
||||
}
|
||||
|
||||
// DvppDecodeResizeOperation
|
||||
DvppDecodeResizeOperation::DvppDecodeResizeOperation(const std::vector<uint32_t> &resize) : resize_(resize) {}
|
||||
|
||||
Status DvppDecodeResizeOperation::ValidateParams() {
|
||||
// size
|
||||
if (resize_.empty() || resize_.size() > 2) {
|
||||
std::string err_msg = "DvppDecodeResizeJpeg: resize resolution 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 (*min_element(resize_.begin(), resize_.end()) < 32 || *max_element(resize_.begin(), resize_.end()) > 2048) {
|
||||
std::string err_msg =
|
||||
"Dvpp module supports resize image with resolution in range [32, 2048], got resize Parameters: ";
|
||||
if (resize_.size() == 2) {
|
||||
MS_LOG(ERROR) << err_msg << "[" << resize_[0] << ", " << resize_[1] << "]";
|
||||
} else {
|
||||
MS_LOG(ERROR) << err_msg << "[" << resize_[0] << ", " << resize_[0] << "]";
|
||||
}
|
||||
RETURN_STATUS_SYNTAX_ERROR(err_msg);
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
std::shared_ptr<TensorOp> DvppDecodeResizeOperation::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 resizeHeight, resizeWidth;
|
||||
// User specified the width value.
|
||||
if (resize_.size() == 1) {
|
||||
resizeHeight = resize_[0];
|
||||
resizeWidth = 0;
|
||||
} else {
|
||||
resizeHeight = resize_[0];
|
||||
resizeWidth = resize_[1];
|
||||
}
|
||||
std::shared_ptr<DvppDecodeResizeJpegOp> tensor_op =
|
||||
std::make_shared<DvppDecodeResizeJpegOp>(resizeHeight, resizeWidth);
|
||||
return tensor_op;
|
||||
}
|
||||
|
||||
// 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 resolution 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 resolution 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 (*min_element(crop_.begin(), crop_.end()) < 32 || *max_element(crop_.begin(), crop_.end()) > 2048) {
|
||||
std::string err_msg = "Dvpp module supports crop image with resolution in range [32, 2048], got Crop Parameters: ";
|
||||
if (crop_.size() == 2) {
|
||||
MS_LOG(ERROR) << err_msg << "[" << crop_[0] << ", " << crop_[1] << "]";
|
||||
} else {
|
||||
MS_LOG(ERROR) << err_msg << "[" << crop_[0] << ", " << crop_[0] << "]";
|
||||
}
|
||||
RETURN_STATUS_SYNTAX_ERROR(err_msg);
|
||||
}
|
||||
if (*min_element(resize_.begin(), resize_.end()) < 32 || *max_element(resize_.begin(), resize_.end()) > 2048) {
|
||||
std::string err_msg =
|
||||
"Dvpp module supports resize image with resolution in range [32, 2048], got Crop Parameters: ";
|
||||
if (resize_.size() == 2) {
|
||||
MS_LOG(ERROR) << err_msg << "[" << resize_[0] << ", " << resize_[1] << "]";
|
||||
} else {
|
||||
MS_LOG(ERROR) << err_msg << "[" << resize_[0] << "]";
|
||||
}
|
||||
RETURN_STATUS_SYNTAX_ERROR(err_msg);
|
||||
}
|
||||
if (crop_.size() < resize_.size()) {
|
||||
if (crop_[0] > MIN(resize_[0], resize_[1])) {
|
||||
std::string err_msg =
|
||||
"Each value of crop parameter must be smaller than corresponding resize parameter, for example: x[0] <= "
|
||||
"y[0], and x[1] <= y[1], please verify your input parameters.";
|
||||
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 =
|
||||
"Each value of crop parameter must be smaller than corresponding resize parameter, for example: x[0] <= "
|
||||
"y[0], and x[1] <= y[1], please verify your input parameters.";
|
||||
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 =
|
||||
"Each value of crop parameter must be smaller than corresponding resize parameter, for example: x[0] <= "
|
||||
"y[0], and x[1] <= y[1], please verify your input parameters.";
|
||||
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 = 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;
|
||||
}
|
||||
|
||||
// DvppDecodeJPEG
|
||||
Status DvppDecodeJpegOperation::ValidateParams() { return Status::OK(); }
|
||||
|
||||
std::shared_ptr<TensorOp> DvppDecodeJpegOperation::Build() { return std::make_shared<DvppDecodeJpegOp>(); }
|
||||
|
||||
// DvppDecodePNG
|
||||
Status DvppDecodePngOperation::ValidateParams() { return Status::OK(); }
|
||||
|
||||
std::shared_ptr<TensorOp> DvppDecodePngOperation::Build() { return std::make_shared<DvppDecodePngOp>(); }
|
||||
|
||||
// DvppResizeOperation
|
||||
DvppResizeJpegOperation::DvppResizeJpegOperation(const std::vector<uint32_t> &resize) : resize_(resize) {}
|
||||
|
||||
Status DvppResizeJpegOperation::ValidateParams() {
|
||||
// size
|
||||
if (resize_.empty() || resize_.size() > 2) {
|
||||
std::string err_msg = "DvppResizeJpeg: resize resolution 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 (*min_element(resize_.begin(), resize_.end()) < 32 || *max_element(resize_.begin(), resize_.end()) > 2048) {
|
||||
std::string err_msg =
|
||||
"Dvpp module supports resize image with resolution in range [32, 2048], got resize Parameters: ";
|
||||
if (resize_.size() == 2) {
|
||||
MS_LOG(ERROR) << err_msg << "[" << resize_[0] << ", " << resize_[1] << "]";
|
||||
} else {
|
||||
MS_LOG(ERROR) << err_msg << "[" << resize_[0] << ", " << resize_[0] << "]";
|
||||
}
|
||||
RETURN_STATUS_SYNTAX_ERROR(err_msg);
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
std::shared_ptr<TensorOp> DvppResizeJpegOperation::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 resizeHeight, resizeWidth;
|
||||
// User specified the width value.
|
||||
if (resize_.size() == 1) {
|
||||
resizeHeight = resize_[0];
|
||||
resizeWidth = 0;
|
||||
} else {
|
||||
resizeHeight = resize_[0];
|
||||
resizeWidth = resize_[1];
|
||||
}
|
||||
std::shared_ptr<DvppResizeJpegOp> tensor_op = std::make_shared<DvppResizeJpegOp>(resizeHeight, resizeWidth);
|
||||
return tensor_op;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace vision
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
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(DATASET_CORE_SRC_FILES
|
||||
client.cc
|
||||
config_manager.cc
|
||||
cv_tensor.cc
|
||||
data_type.cc
|
||||
de_tensor.cc
|
||||
global_context.cc
|
||||
tensor.cc
|
||||
tensor_helpers.cc
|
||||
tensor_row.cc
|
||||
tensor_shape.cc
|
||||
)
|
||||
client.cc
|
||||
config_manager.cc
|
||||
cv_tensor.cc
|
||||
data_type.cc
|
||||
device_tensor.cc
|
||||
de_tensor.cc
|
||||
global_context.cc
|
||||
tensor.cc
|
||||
tensor_helpers.cc
|
||||
tensor_row.cc
|
||||
tensor_shape.cc
|
||||
)
|
||||
|
||||
ms_protobuf_generate(EXAMPLE_SRCS EXAMPLE_HDRS example.proto)
|
||||
ms_protobuf_generate(FEATURE_SRCS FEATURE_HDRS feature.proto)
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
|
||||
#include "minddata/dataset/core/de_tensor.h"
|
||||
#include "minddata/dataset/core/device_tensor.h"
|
||||
#include "minddata/dataset/core/constants.h"
|
||||
#include "minddata/dataset/core/data_type.h"
|
||||
#include "minddata/dataset/include/type_id.h"
|
||||
|
@ -35,7 +36,27 @@ DETensor::DETensor(std::shared_ptr<dataset::Tensor> tensor_impl)
|
|||
: tensor_impl_(tensor_impl),
|
||||
name_("MindDataTensor"),
|
||||
type_(static_cast<mindspore::DataType>(DETypeToMSType(tensor_impl_->type()))),
|
||||
shape_(tensor_impl_->shape().AsVector()) {}
|
||||
shape_(tensor_impl_->shape().AsVector()),
|
||||
is_device_(false) {}
|
||||
|
||||
#ifndef ENABLE_ANDROID
|
||||
DETensor::DETensor(std::shared_ptr<dataset::DeviceTensor> device_tensor_impl, bool is_device)
|
||||
: device_tensor_impl_(device_tensor_impl), name_("MindDataDeviceTensor"), is_device_(is_device) {
|
||||
// The sequence of shape_ is (width, widthStride, height, heightStride) in Dvpp module
|
||||
// We need to add [1]widthStride and [3]heightStride, which are actual YUV image shape, into shape_ attribute
|
||||
uint8_t flag = 0;
|
||||
for (auto &i : device_tensor_impl->GetYuvStrideShape()) {
|
||||
if (flag % 2 == 1) {
|
||||
int64_t j = static_cast<int64_t>(i);
|
||||
shape_.emplace_back(j);
|
||||
}
|
||||
++flag;
|
||||
}
|
||||
std::reverse(shape_.begin(), shape_.end());
|
||||
MS_LOG(INFO) << "This is a YUV420 format image, one pixel takes 1.5 bytes. Therefore, the shape of"
|
||||
<< " image is in (H, W) format. You can search for more information about YUV420 format";
|
||||
}
|
||||
#endif
|
||||
|
||||
const std::string &DETensor::Name() const { return name_; }
|
||||
|
||||
|
@ -45,6 +66,12 @@ enum mindspore::DataType DETensor::DataType() const {
|
|||
}
|
||||
|
||||
size_t DETensor::DataSize() const {
|
||||
#ifndef ENABLE_ANDROID
|
||||
if (is_device_) {
|
||||
ASSERT_NULL(device_tensor_impl_);
|
||||
return device_tensor_impl_->DeviceDataSize();
|
||||
}
|
||||
#endif
|
||||
ASSERT_NULL(tensor_impl_);
|
||||
return tensor_impl_->SizeInBytes();
|
||||
}
|
||||
|
@ -52,6 +79,11 @@ size_t DETensor::DataSize() const {
|
|||
const std::vector<int64_t> &DETensor::Shape() const { return shape_; }
|
||||
|
||||
std::shared_ptr<const void> DETensor::Data() const {
|
||||
#ifndef ENABLE_ANDROID
|
||||
if (is_device_) {
|
||||
return std::shared_ptr<const void>(device_tensor_impl_->GetDeviceBuffer(), [](const void *) {});
|
||||
}
|
||||
#endif
|
||||
return std::shared_ptr<const void>(tensor_impl_->GetBuffer(), [](const void *) {});
|
||||
}
|
||||
|
||||
|
@ -60,7 +92,7 @@ void *DETensor::MutableData() {
|
|||
return tensor_impl_->GetMutableBuffer();
|
||||
}
|
||||
|
||||
bool DETensor::IsDevice() const { return false; }
|
||||
bool DETensor::IsDevice() const { return is_device_; }
|
||||
|
||||
std::shared_ptr<mindspore::MSTensor::Impl> DETensor::Clone() const { return std::make_shared<DETensor>(tensor_impl_); }
|
||||
} // namespace dataset
|
||||
|
|
|
@ -31,7 +31,9 @@ class DETensor : public mindspore::MSTensor::Impl {
|
|||
DETensor() = default;
|
||||
~DETensor() override = default;
|
||||
explicit DETensor(std::shared_ptr<dataset::Tensor> tensor_impl);
|
||||
|
||||
#ifndef ENABLE_ANDROID
|
||||
explicit DETensor(std::shared_ptr<dataset::DeviceTensor> device_tensor_impl, bool is_device);
|
||||
#endif
|
||||
const std::string &Name() const override;
|
||||
|
||||
enum mindspore::DataType DataType() const override;
|
||||
|
@ -50,6 +52,10 @@ class DETensor : public mindspore::MSTensor::Impl {
|
|||
|
||||
private:
|
||||
std::shared_ptr<dataset::Tensor> tensor_impl_;
|
||||
#ifndef ENABLE_ANDROID
|
||||
std::shared_ptr<dataset::DeviceTensor> device_tensor_impl_;
|
||||
#endif
|
||||
bool is_device_;
|
||||
std::string name_;
|
||||
enum mindspore::DataType type_;
|
||||
std::vector<int64_t> shape_;
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "minddata/dataset/core/global_context.h"
|
||||
#include "minddata/dataset/core/tensor.h"
|
||||
#include "minddata/dataset/core/device_tensor.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
Status DeviceTensor::SetYuvStrideShape_(const uint32_t &width, const uint32_t &widthStride, const uint32_t &height,
|
||||
const uint32_t &heightStride) {
|
||||
YUV_shape_ = {width, widthStride, height, heightStride};
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
std::vector<uint32_t> DeviceTensor::GetYuvStrideShape() { return YUV_shape_; }
|
||||
|
||||
#ifdef ENABLE_ACL
|
||||
Status DeviceTensor::SetAttributes(const std::shared_ptr<DvppDataInfo> &data_ptr) {
|
||||
device_data_ = data_ptr->data;
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(device_data_ != nullptr, "Fail to get the device data.");
|
||||
SetSize_(data_ptr->dataSize);
|
||||
SetYuvStrideShape_(data_ptr->width, data_ptr->widthStride, data_ptr->height, data_ptr->heightStride);
|
||||
return Status::OK();
|
||||
}
|
||||
#endif
|
||||
|
||||
DeviceTensor::DeviceTensor(const TensorShape &shape, const DataType &type) : Tensor(shape, type) {
|
||||
// grab the mem pool from global context and create the allocator for char data area
|
||||
std::shared_ptr<MemoryPool> global_pool = GlobalContext::Instance()->mem_pool();
|
||||
data_allocator_ = std::make_unique<Allocator<unsigned char>>(global_pool);
|
||||
}
|
||||
|
||||
Status DeviceTensor::CreateEmpty(const TensorShape &shape, const DataType &type, std::shared_ptr<DeviceTensor> *out) {
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(shape.known(), "Invalid shape.");
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(type != DataType::DE_UNKNOWN, "Invalid data type.");
|
||||
const DeviceTensorAlloc *alloc = GlobalContext::Instance()->device_tensor_allocator();
|
||||
*out = std::allocate_shared<DeviceTensor>(*alloc, shape, type);
|
||||
// if it's a string tensor and it has no elements, Just initialize the shape and type.
|
||||
if (!type.IsNumeric() && shape.NumOfElements() == 0) {
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(type.IsNumeric(), "Number of elements is not 0. The type should be numeric.");
|
||||
|
||||
int64_t byte_size = (*out)->SizeInBytes();
|
||||
|
||||
// Don't allocate if we have a tensor with no elements.
|
||||
if (byte_size != 0) {
|
||||
RETURN_IF_NOT_OK((*out)->AllocateBuffer(byte_size));
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
uint8_t *DeviceTensor::GetDeviceBuffer() { return device_data_; }
|
||||
|
||||
uint32_t DeviceTensor::DeviceDataSize() { return size_; }
|
||||
|
||||
Status DeviceTensor::SetSize_(const uint32_t &new_size) {
|
||||
size_ = new_size;
|
||||
return Status::OK();
|
||||
}
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_DEVICE_TENSOR_H
|
||||
#define MINDSPORE_DEVICE_TENSOR_H
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "include/api/status.h"
|
||||
#include "minddata/dataset/core/tensor.h"
|
||||
#ifdef ENABLE_ACL
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/DvppCommon.h"
|
||||
#endif
|
||||
#include "minddata/dataset/core/constants.h"
|
||||
#include "minddata/dataset/core/data_type.h"
|
||||
#include "minddata/dataset/util/status.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
class Tensor;
|
||||
class DeviceTensor : public Tensor {
|
||||
public:
|
||||
DeviceTensor(const TensorShape &shape, const DataType &type);
|
||||
|
||||
~DeviceTensor() {}
|
||||
#ifdef ENABLE_ACL
|
||||
Status SetAttributes(const std::shared_ptr<DvppDataInfo> &data);
|
||||
#endif
|
||||
static Status CreateEmpty(const TensorShape &shape, const DataType &type, std::shared_ptr<DeviceTensor> *out);
|
||||
|
||||
uint8_t *GetDeviceBuffer();
|
||||
|
||||
std::vector<uint32_t> GetYuvStrideShape();
|
||||
|
||||
uint32_t DeviceDataSize();
|
||||
|
||||
bool HasDeviceData() { return device_data_ != nullptr; }
|
||||
|
||||
private:
|
||||
Status SetSize_(const uint32_t &new_size);
|
||||
|
||||
Status SetYuvStrideShape_(const uint32_t &width, const uint32_t &widthStride, const uint32_t &height,
|
||||
const uint32_t &heightStride);
|
||||
|
||||
std::vector<uint32_t> YUV_shape_;
|
||||
uint8_t *device_data_;
|
||||
uint32_t size_;
|
||||
};
|
||||
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
||||
#endif // MINDSPORE_DEVICE_TENSOR_H
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -22,6 +22,7 @@
|
|||
#ifndef ENABLE_ANDROID
|
||||
#include "minddata/dataset/core/cv_tensor.h"
|
||||
#endif
|
||||
#include "minddata/dataset/core/device_tensor.h"
|
||||
#include "minddata/dataset/core/tensor.h"
|
||||
#include "minddata/dataset/util/allocator.h"
|
||||
#include "minddata/dataset/util/circular_pool.h"
|
||||
|
@ -61,6 +62,7 @@ Status GlobalContext::Init() {
|
|||
#ifndef ENABLE_ANDROID
|
||||
cv_tensor_allocator_ = std::make_unique<Allocator<CVTensor>>(mem_pool_);
|
||||
#endif
|
||||
device_tensor_allocator_ = std::make_unique<Allocator<DeviceTensor>>(mem_pool_);
|
||||
int_allocator_ = std::make_unique<IntAlloc>(mem_pool_);
|
||||
return Status::OK();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -19,10 +19,10 @@
|
|||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
#include "include/api/status.h"
|
||||
#include "minddata/dataset/core/config_manager.h"
|
||||
#include "minddata/dataset/core/constants.h"
|
||||
#include "minddata/dataset/util/allocator.h"
|
||||
#include "minddata/dataset/util/status.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
|
@ -30,9 +30,11 @@ namespace dataset {
|
|||
class MemoryPool;
|
||||
class Tensor;
|
||||
class CVTensor;
|
||||
class DeviceTensor;
|
||||
|
||||
using TensorAlloc = Allocator<Tensor>; // An allocator for Tensors
|
||||
using CVTensorAlloc = Allocator<CVTensor>; // An allocator CVTensors
|
||||
using TensorAlloc = Allocator<Tensor>; // An allocator for Tensors
|
||||
using CVTensorAlloc = Allocator<CVTensor>; // An allocator CVTensors
|
||||
using DeviceTensorAlloc = Allocator<DeviceTensor>; // An allocator for Device_Tensors
|
||||
using IntAlloc = Allocator<dsize_t>;
|
||||
|
||||
class GlobalContext {
|
||||
|
@ -82,6 +84,10 @@ class GlobalContext {
|
|||
// @return the CVTensor allocator as raw pointer
|
||||
const CVTensorAlloc *cv_tensor_allocator() const { return cv_tensor_allocator_.get(); }
|
||||
|
||||
// Getter method
|
||||
// @return the DeviceTensor allocator as raw pointer
|
||||
const DeviceTensorAlloc *device_tensor_allocator() const { return device_tensor_allocator_.get(); }
|
||||
|
||||
// Getter method
|
||||
// @return the integer allocator as raw pointer
|
||||
const IntAlloc *int_allocator() const { return int_allocator_.get(); }
|
||||
|
@ -95,12 +101,13 @@ class GlobalContext {
|
|||
Status Init();
|
||||
|
||||
static std::once_flag init_instance_flag_;
|
||||
static std::unique_ptr<GlobalContext> global_context_; // The instance of the singleton (global)
|
||||
std::shared_ptr<MemoryPool> mem_pool_; // A global memory pool
|
||||
std::shared_ptr<ConfigManager> config_manager_; // The configs
|
||||
std::unique_ptr<TensorAlloc> tensor_allocator_; // An allocator for Tensors
|
||||
std::unique_ptr<CVTensorAlloc> cv_tensor_allocator_; // An allocator for CV Tensors
|
||||
std::unique_ptr<IntAlloc> int_allocator_; // An allocator for ints
|
||||
static std::unique_ptr<GlobalContext> global_context_; // The instance of the singleton (global)
|
||||
std::shared_ptr<MemoryPool> mem_pool_; // A global memory pool
|
||||
std::shared_ptr<ConfigManager> config_manager_; // The configs
|
||||
std::unique_ptr<TensorAlloc> tensor_allocator_; // An allocator for Tensors
|
||||
std::unique_ptr<CVTensorAlloc> cv_tensor_allocator_; // An allocator for CV Tensors
|
||||
std::unique_ptr<DeviceTensorAlloc> device_tensor_allocator_; // An allocator for Device Tensors
|
||||
std::unique_ptr<IntAlloc> int_allocator_; // An allocator for ints
|
||||
};
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
||||
|
|
|
@ -423,6 +423,17 @@ class Tensor {
|
|||
static Status GetBufferInfo(Tensor *t, py::buffer_info *out);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ACL
|
||||
Status SetYuvShape(const uint32_t &width, const uint32_t &widthStride, const uint32_t &height,
|
||||
const uint32_t &heightStride) {
|
||||
std::vector<uint32_t> tmp{width, widthStride, height, heightStride};
|
||||
yuv_shape_ = tmp;
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
std::vector<uint32_t> GetYuvShape() { return yuv_shape_; }
|
||||
#endif
|
||||
|
||||
/// TensorIterator is a linear iterator that can be used to iterate over the elements of the Tensor
|
||||
/// The order elements is as the memory layout (i.e., row-major) [[1,2,3],[4,5,6] --> 1,2,3,4,5,6
|
||||
/// \tparam T type of values in the Tensor Iterator
|
||||
|
@ -686,6 +697,11 @@ class Tensor {
|
|||
/// pointer to the end of the physical data
|
||||
unsigned char *data_end_ = nullptr;
|
||||
|
||||
#ifdef ENABLE_ACL
|
||||
/// shape for interpretation of YUV image
|
||||
std::vector<uint32_t> yuv_shape_;
|
||||
#endif
|
||||
|
||||
private:
|
||||
friend class DETensor;
|
||||
|
||||
|
|
|
@ -17,25 +17,28 @@
|
|||
#ifndef MINDSPORE_CCSRC_MINDDATA_DATASET_INCLUDE_EXECUTE_H_
|
||||
#define MINDSPORE_CCSRC_MINDDATA_DATASET_INCLUDE_EXECUTE_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "include/api/context.h"
|
||||
#include "include/api/types.h"
|
||||
#include "minddata/dataset/include/constants.h"
|
||||
#include "minddata/dataset/include/transforms.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
class AscendResource; // Class to manage the resource of Ascend310
|
||||
|
||||
// class to run tensor operations in eager mode
|
||||
class Execute {
|
||||
public:
|
||||
/// \brief Constructor
|
||||
explicit Execute(std::shared_ptr<TensorOperation> op);
|
||||
explicit Execute(std::shared_ptr<TensorOperation> op, std::string deviceType = "CPU");
|
||||
|
||||
explicit Execute(std::vector<std::shared_ptr<TensorOperation>> ops);
|
||||
explicit Execute(std::vector<std::shared_ptr<TensorOperation>> ops, std::string deviceType = "CPU");
|
||||
|
||||
/// \brief Destructor
|
||||
~Execute() = default;
|
||||
~Execute();
|
||||
|
||||
/// \brief callable function to execute the TensorOperation in eager mode
|
||||
/// \param[in] input Tensor to be transformed
|
||||
|
@ -48,9 +51,19 @@ class Execute {
|
|||
/// \param[out] out Result tensor after transform
|
||||
/// \return - Status
|
||||
Status operator()(const std::vector<mindspore::MSTensor> &input_tensor_list, std::vector<mindspore::MSTensor> *out);
|
||||
#ifdef ENABLE_ACL
|
||||
Status DeviceMemoryRelease();
|
||||
#endif
|
||||
|
||||
private:
|
||||
Status validate_device_();
|
||||
|
||||
std::vector<std::shared_ptr<TensorOperation>> ops_;
|
||||
|
||||
std::string device_type_;
|
||||
#ifdef ENABLE_ACL
|
||||
std::shared_ptr<AscendResource> D_resource_;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace dataset
|
||||
|
|
|
@ -39,7 +39,6 @@ class AutoContrastOperation;
|
|||
class BoundingBoxAugmentOperation;
|
||||
class CutMixBatchOperation;
|
||||
class CutOutOperation;
|
||||
class DvppDecodeResizeCropOperation;
|
||||
class EqualizeOperation;
|
||||
class HwcToChwOperation;
|
||||
class InvertOperation;
|
||||
|
@ -106,22 +105,6 @@ 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.
|
||||
|
|
|
@ -0,0 +1,219 @@
|
|||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_CCSRC_MINDDATA_DATASET_INCLUDE_VISION_ASCEND_H_
|
||||
#define MINDSPORE_CCSRC_MINDDATA_DATASET_INCLUDE_VISION_ASCEND_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "include/api/status.h"
|
||||
#include "minddata/dataset/include/constants.h"
|
||||
#include "minddata/dataset/include/transforms.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
|
||||
// Transform operations for performing computer vision.
|
||||
namespace vision {
|
||||
|
||||
// Char arrays storing name of corresponding classes (in alphabetical order)
|
||||
constexpr char kDvppCropJpegOperation[] = "DvppCropJpeg";
|
||||
constexpr char kDvppDecodeResizeOperation[] = "DvppDecodeResize";
|
||||
constexpr char kDvppDecodeResizeCropOperation[] = "DvppDecodeResizeCrop";
|
||||
constexpr char kDvppDecodeJpegOperation[] = "DvppDecodeJpeg";
|
||||
constexpr char kDvppDecodePngOperation[] = "DvppDecodePng";
|
||||
constexpr char kDvppResizeJpegOperation[] = "DvppResizeJpeg";
|
||||
|
||||
class DvppCropJpegOperation;
|
||||
class DvppDecodeResizeOperation;
|
||||
class DvppDecodeResizeCropOperation;
|
||||
class DvppDecodeJpegOperation;
|
||||
class DvppDecodePngOperation;
|
||||
class DvppResizeJpegOperation;
|
||||
|
||||
/// \brief Function to create a DvppCropJpeg TensorOperation.
|
||||
/// \notes Tensor operation to crop 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 [32*32, 2048*2048].
|
||||
/// 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, the shape will be a square. If size has 2 values, it should be (height, width).
|
||||
/// \return Shared pointer to the current TensorOperation.
|
||||
std::shared_ptr<DvppCropJpegOperation> DvppCropJpeg(std::vector<uint32_t> crop = {256, 256});
|
||||
|
||||
/// \brief Function to create a DvppDecodeResizeJpeg 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 [32*32, 2048*2048].
|
||||
/// 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<DvppDecodeResizeOperation> DvppDecodeResizeJpeg(std::vector<uint32_t> resize = {256, 256});
|
||||
|
||||
/// \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 [32*32, 2048*2048].
|
||||
/// 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] Resize 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 the 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 DvppDecodeJpeg TensorOperation.
|
||||
/// \notes Tensor operation to decode 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 [32*32, 2048*2048].
|
||||
/// Only images with an even resolution can be output. The output of odd resolution is not supported.
|
||||
/// \return Shared pointer to the current TensorOperation.
|
||||
std::shared_ptr<DvppDecodeJpegOperation> DvppDecodeJpeg();
|
||||
|
||||
/// \brief Function to create a DvppDecodePng TensorOperation.
|
||||
/// \notes Tensor operation to decode PNG 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 [32*32, 2048*2048].
|
||||
/// Only images with an even resolution can be output. The output of odd resolution is not supported.
|
||||
/// \return Shared pointer to the current TensorOperation.
|
||||
std::shared_ptr<DvppDecodePngOperation> DvppDecodePng();
|
||||
|
||||
/// \brief Function to create a DvppResizeJpeg TensorOperation.
|
||||
/// \notes Tensor operation to resize JPEG image using 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 [32*32, 2048*2048].
|
||||
/// Only images with an even resolution can be output. The output of odd resolution is not supported.
|
||||
/// \param[in] resize vector represents the shape of image after resize.
|
||||
/// \return Shared pointer to the current TensorOperation.
|
||||
std::shared_ptr<DvppResizeJpegOperation> DvppResizeJpeg(std::vector<uint32_t> resize = {256, 256});
|
||||
|
||||
class DvppCropJpegOperation : public TensorOperation {
|
||||
public:
|
||||
explicit DvppCropJpegOperation(const std::vector<uint32_t> &resize);
|
||||
|
||||
~DvppCropJpegOperation() = default;
|
||||
|
||||
std::shared_ptr<TensorOp> Build() override;
|
||||
|
||||
Status ValidateParams() override;
|
||||
|
||||
std::string Name() const override { return kDvppCropJpegOperation; }
|
||||
|
||||
private:
|
||||
std::vector<uint32_t> crop_;
|
||||
};
|
||||
|
||||
class DvppDecodeResizeOperation : public TensorOperation {
|
||||
public:
|
||||
explicit DvppDecodeResizeOperation(const std::vector<uint32_t> &resize);
|
||||
|
||||
~DvppDecodeResizeOperation() = default;
|
||||
|
||||
std::shared_ptr<TensorOp> Build() override;
|
||||
|
||||
Status ValidateParams() override;
|
||||
|
||||
std::string Name() const override { return kDvppDecodeResizeOperation; }
|
||||
|
||||
private:
|
||||
std::vector<uint32_t> resize_;
|
||||
};
|
||||
|
||||
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 DvppDecodeJpegOperation : public TensorOperation {
|
||||
public:
|
||||
~DvppDecodeJpegOperation() = default;
|
||||
|
||||
std::shared_ptr<TensorOp> Build() override;
|
||||
|
||||
Status ValidateParams() override;
|
||||
|
||||
std::string Name() const override { return kDvppDecodeJpegOperation; }
|
||||
};
|
||||
|
||||
class DvppDecodePngOperation : public TensorOperation {
|
||||
public:
|
||||
~DvppDecodePngOperation() = default;
|
||||
|
||||
std::shared_ptr<TensorOp> Build() override;
|
||||
|
||||
Status ValidateParams() override;
|
||||
|
||||
std::string Name() const override { return kDvppDecodePngOperation; }
|
||||
};
|
||||
|
||||
class DvppResizeJpegOperation : public TensorOperation {
|
||||
public:
|
||||
explicit DvppResizeJpegOperation(const std::vector<uint32_t> &resize);
|
||||
|
||||
~DvppResizeJpegOperation() = default;
|
||||
|
||||
std::shared_ptr<TensorOp> Build() override;
|
||||
|
||||
Status ValidateParams() override;
|
||||
|
||||
std::string Name() const override { return kDvppResizeJpegOperation; }
|
||||
|
||||
private:
|
||||
std::vector<uint32_t> resize_;
|
||||
};
|
||||
} // namespace vision
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
||||
|
||||
#endif // MINDSPORE_CCSRC_MINDDATA_DATASET_INCLUDE_VISION_ASCEND_H_
|
|
@ -2,5 +2,10 @@ 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)
|
||||
dvpp_crop_jpeg_op.cc
|
||||
dvpp_decode_resize_crop_jpeg_op.cc
|
||||
dvpp_decode_resize_jpeg_op.cc
|
||||
dvpp_decode_jpeg_op.cc
|
||||
dvpp_resize_jpeg_op.cc
|
||||
dvpp_decode_png_op.cc)
|
||||
add_dependencies(kernels-dvpp-image dvpp-utils)
|
|
@ -0,0 +1,145 @@
|
|||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "include/api/context.h"
|
||||
#include "minddata/dataset/core/data_type.h"
|
||||
#include "minddata/dataset/core/device_tensor.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/MDAclProcess.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/CommonDataType.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/dvpp_crop_jpeg_op.h"
|
||||
#include "minddata/dataset/kernels/image/image_utils.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
Status DvppCropJpegOp::Compute(const std::shared_ptr<DeviceTensor> &input, std::shared_ptr<DeviceTensor> *output) {
|
||||
IO_CHECK(input, output);
|
||||
try {
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(input->GetDeviceBuffer() != nullptr, "The input image buffer is empty.");
|
||||
std::string last_step = "Resize";
|
||||
std::shared_ptr<DvppDataInfo> imageinfo(processor_->Get_Resized_DeviceData());
|
||||
if (!imageinfo->data) {
|
||||
last_step = "Decode";
|
||||
}
|
||||
APP_ERROR ret = processor_->JPEG_C(last_step);
|
||||
if (ret != APP_ERR_OK) {
|
||||
processor_->Release();
|
||||
std::string error = "Error in dvpp crop processing:" + std::to_string(ret);
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
std::shared_ptr<DvppDataInfo> CropOut(processor_->Get_Croped_DeviceData());
|
||||
const TensorShape dvpp_shape({1, 1, 1});
|
||||
const DataType dvpp_data_type(DataType::DE_UINT8);
|
||||
mindspore::dataset::DeviceTensor::CreateEmpty(dvpp_shape, dvpp_data_type, output);
|
||||
(*output)->SetAttributes(CropOut);
|
||||
if (!((*output)->HasDeviceData())) {
|
||||
std::string error = "[ERROR] Fail to get the Output result from device memory!";
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
} catch (const cv::Exception &e) {
|
||||
std::string error = "[ERROR] Fail in DvppCropJpegOp:" + std::string(e.what());
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status DvppCropJpegOp::Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) {
|
||||
IO_CHECK(input, output);
|
||||
try {
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(input->GetBuffer() != nullptr, "The input image buffer is empty.");
|
||||
unsigned char *buffer = const_cast<unsigned char *>(input->GetBuffer());
|
||||
DvppDataInfo imageinfo;
|
||||
imageinfo.dataSize = input->SizeInBytes();
|
||||
imageinfo.data = static_cast<uint8_t *>(buffer);
|
||||
std::vector<uint32_t> yuv_shape_ = input->GetYuvShape();
|
||||
imageinfo.width = yuv_shape_[0];
|
||||
imageinfo.widthStride = yuv_shape_[1];
|
||||
imageinfo.height = yuv_shape_[2];
|
||||
imageinfo.heightStride = yuv_shape_[3];
|
||||
imageinfo.format = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
|
||||
ResourceInfo resource;
|
||||
resource.aclConfigPath = "";
|
||||
resource.deviceIds.insert(mindspore::GlobalContext::GetGlobalDeviceID());
|
||||
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
|
||||
MDAclProcess process(crop_width_, crop_height_, context, 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.JPEG_C(imageinfo);
|
||||
if (ret != APP_ERR_OK) {
|
||||
instance->Release();
|
||||
std::string error = "Error in dvpp crop 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_Croped_DeviceData());
|
||||
dsize_t dvpp_length = CropOut->dataSize;
|
||||
const TensorShape dvpp_shape({dvpp_length, 1, 1});
|
||||
uint32_t crop_height = CropOut->height;
|
||||
uint32_t crop_heightStride = CropOut->heightStride;
|
||||
uint32_t crop_width = CropOut->width;
|
||||
uint32_t crop_widthStride = CropOut->widthStride;
|
||||
const DataType dvpp_data_type(DataType::DE_UINT8);
|
||||
mindspore::dataset::Tensor::CreateFromMemory(dvpp_shape, dvpp_data_type, ret_ptr, output);
|
||||
(*output)->SetYuvShape(crop_width, crop_widthStride, crop_height, crop_heightStride);
|
||||
if (!((*output)->HasData())) {
|
||||
std::string error = "[ERROR] Fail to get the Output result from memory!";
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
process.device_memory_release();
|
||||
process.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 DvppCropJpegOp:" + std::string(e.what());
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status DvppCropJpegOp::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 1 channels
|
||||
if (inputs[0].Rank() == 1) outputs.emplace_back(out);
|
||||
if (!outputs.empty()) return Status::OK();
|
||||
return Status(StatusCode::kMDUnexpectedError, "Input has a wrong shape");
|
||||
}
|
||||
|
||||
Status DvppCropJpegOp::SetAscendResource(const std::shared_ptr<MDAclProcess> &processor) {
|
||||
processor_ = processor;
|
||||
processor_->SetCropParas(crop_width_, crop_height_);
|
||||
return Status::OK();
|
||||
}
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_CCSRC_MINDDATA_DATASET_KERNELS_IMAGE_DVPP_DVPP_CROP_JPEG_OP_H
|
||||
#define MINDSPORE_CCSRC_MINDDATA_DATASET_KERNELS_IMAGE_DVPP_DVPP_CROP_JPEG_OP_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "acl/acl.h"
|
||||
#include "mindspore/core/utils/log_adapter.h"
|
||||
#include "minddata/dataset/core/data_type.h"
|
||||
#include "minddata/dataset/core/device_tensor.h"
|
||||
#include "minddata/dataset/core/tensor.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/ErrorCode.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/ResourceManager.h"
|
||||
#include "minddata/dataset/kernels/tensor_op.h"
|
||||
#include "minddata/dataset/util/status.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
class DvppCropJpegOp : public TensorOp {
|
||||
public:
|
||||
DvppCropJpegOp(int32_t crop_height, int32_t crop_width) : crop_height_(crop_height), crop_width_(crop_width) {}
|
||||
|
||||
/// \brief Destructor
|
||||
~DvppCropJpegOp() = default;
|
||||
|
||||
Status Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) override;
|
||||
|
||||
Status Compute(const std::shared_ptr<DeviceTensor> &input, std::shared_ptr<DeviceTensor> *output) override;
|
||||
|
||||
Status OutputShape(const std::vector<TensorShape> &inputs, std::vector<TensorShape> &outputs) override;
|
||||
|
||||
std::string Name() const override { return kDvppCropJpegOp; }
|
||||
|
||||
Status SetAscendResource(const std::shared_ptr<MDAclProcess> &processor) override;
|
||||
|
||||
private:
|
||||
uint32_t crop_height_;
|
||||
uint32_t crop_width_;
|
||||
|
||||
std::shared_ptr<MDAclProcess> processor_;
|
||||
};
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
||||
|
||||
#endif // MINDSPORE_CCSRC_MINDDATA_DATASET_KERNELS_IMAGE_DVPP_DVPP_CROP_JPEG_OP_H
|
|
@ -0,0 +1,139 @@
|
|||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "include/api/context.h"
|
||||
#include "minddata/dataset/core/cv_tensor.h"
|
||||
#include "minddata/dataset/core/data_type.h"
|
||||
#include "minddata/dataset/core/device_tensor.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/dvpp_decode_resize_crop_jpeg_op.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/dvpp_decode_jpeg_op.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/CommonDataType.h"
|
||||
#include "minddata/dataset/kernels/image/image_utils.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
// Compute() will be called when context=="Ascend310"
|
||||
Status DvppDecodeJpegOp::Compute(const std::shared_ptr<DeviceTensor> &input, std::shared_ptr<DeviceTensor> *output) {
|
||||
IO_CHECK(input, output);
|
||||
try {
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(input->GetDeviceBuffer() != nullptr, "The input image buffer on device is empty");
|
||||
APP_ERROR ret = processor_->JPEG_D();
|
||||
if (ret != APP_ERR_OK) {
|
||||
processor_->Release();
|
||||
std::string error = "Error in dvpp processing:" + std::to_string(ret);
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
std::shared_ptr<DvppDataInfo> DecodeOut(processor_->Get_Decode_DeviceData());
|
||||
const TensorShape dvpp_shape({1, 1, 1});
|
||||
const DataType dvpp_data_type(DataType::DE_UINT8);
|
||||
mindspore::dataset::DeviceTensor::CreateEmpty(dvpp_shape, dvpp_data_type, output);
|
||||
(*output)->SetAttributes(DecodeOut);
|
||||
if (!((*output)->HasDeviceData())) {
|
||||
std::string error = "[ERROR] Fail to get the Output result from memory!";
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
} catch (const cv::Exception &e) {
|
||||
std::string error = "[ERROR] Fail in DvppDecodeJpegOp:" + std::string(e.what());
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
// Compute() will be called when context=="CPU"
|
||||
Status DvppDecodeJpegOp::Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) {
|
||||
IO_CHECK(input, output);
|
||||
if (!IsNonEmptyJPEG(input)) {
|
||||
RETURN_STATUS_UNEXPECTED("DvppDecodeJpegOp 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 = static_cast<void *>(buffer);
|
||||
ResourceInfo resource;
|
||||
resource.aclConfigPath = "";
|
||||
resource.deviceIds.insert(mindspore::GlobalContext::GetGlobalDeviceID());
|
||||
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
|
||||
MDAclProcess process(context, false);
|
||||
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.JPEG_D(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> DecodeOut(process.Get_Decode_DeviceData());
|
||||
dsize_t dvpp_length = DecodeOut->dataSize;
|
||||
uint32_t decoded_height = DecodeOut->height;
|
||||
uint32_t decoded_heightStride = DecodeOut->heightStride;
|
||||
uint32_t decoded_width = DecodeOut->width;
|
||||
uint32_t decoded_widthStride = DecodeOut->widthStride;
|
||||
// std::cout << "Decoded size: " << decoded_width << ", " << decoded_height << std::endl;
|
||||
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);
|
||||
(*output)->SetYuvShape(decoded_width, decoded_widthStride, decoded_height, decoded_heightStride);
|
||||
if (!((*output)->HasData())) {
|
||||
std::string error = "[ERROR] Fail to get the Output result from device memory!";
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
process.device_memory_release();
|
||||
process.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 DvppDecodeJpegOp:" + std::string(e.what());
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status DvppDecodeJpegOp::SetAscendResource(const std::shared_ptr<MDAclProcess> &processor) {
|
||||
processor_ = processor;
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status DvppDecodeJpegOp::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::kMDUnexpectedError, "Input has a wrong shape");
|
||||
}
|
||||
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_CCSRC_MINDDATA_DATASET_KERNELS_IMAGE_DVPP_DVPP_DECODE_JPEG_OP_H
|
||||
#define MINDSPORE_CCSRC_MINDDATA_DATASET_KERNELS_IMAGE_DVPP_DVPP_DECODE_JPEG_OP_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "acl/acl.h"
|
||||
#include "mindspore/core/utils/log_adapter.h"
|
||||
#include "minddata/dataset/core/data_type.h"
|
||||
#include "minddata/dataset/core/tensor.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/ErrorCode.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/MDAclProcess.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/ResourceManager.h"
|
||||
#include "minddata/dataset/kernels/tensor_op.h"
|
||||
#include "minddata/dataset/util/status.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
class DvppDecodeJpegOp : public TensorOp {
|
||||
public:
|
||||
DvppDecodeJpegOp() { processor_ = nullptr; }
|
||||
|
||||
/// \brief Destructor
|
||||
~DvppDecodeJpegOp() = default;
|
||||
|
||||
Status Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) override;
|
||||
|
||||
Status Compute(const std::shared_ptr<DeviceTensor> &input, std::shared_ptr<DeviceTensor> *output) override;
|
||||
|
||||
Status OutputShape(const std::vector<TensorShape> &inputs, std::vector<TensorShape> &outputs) override;
|
||||
|
||||
std::string Name() const override { return kDvppDecodeJpegOp; }
|
||||
|
||||
Status SetAscendResource(const std::shared_ptr<MDAclProcess> &processor) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<MDAclProcess> processor_;
|
||||
};
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
||||
|
||||
#endif // MINDSPORE_CCSRC_MINDDATA_DATASET_KERNELS_IMAGE_DVPP_DVPP_DECODE_JPEG_OP_H
|
|
@ -0,0 +1,138 @@
|
|||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "include/api/context.h"
|
||||
#include "minddata/dataset/core/cv_tensor.h"
|
||||
#include "minddata/dataset/core/data_type.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/dvpp_decode_resize_crop_jpeg_op.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/dvpp_decode_png_op.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/CommonDataType.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/MDAclProcess.h"
|
||||
#include "minddata/dataset/kernels/image/image_utils.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
Status DvppDecodePngOp::Compute(const std::shared_ptr<DeviceTensor> &input, std::shared_ptr<DeviceTensor> *output) {
|
||||
IO_CHECK(input, output);
|
||||
try {
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(input->GetDeviceBuffer() != nullptr, "The input image buffer on device is empty");
|
||||
APP_ERROR ret = processor_->PNG_D();
|
||||
if (ret != APP_ERR_OK) {
|
||||
processor_->Release();
|
||||
std::string error = "Error in dvpp processing:" + std::to_string(ret);
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
std::shared_ptr<DvppDataInfo> DecodeOut(processor_->Get_Decode_DeviceData());
|
||||
const TensorShape dvpp_shape({1, 1, 1});
|
||||
const DataType dvpp_data_type(DataType::DE_UINT8);
|
||||
mindspore::dataset::DeviceTensor::CreateEmpty(dvpp_shape, dvpp_data_type, output);
|
||||
(*output)->SetAttributes(DecodeOut);
|
||||
if (!((*output)->HasDeviceData())) {
|
||||
std::string error = "[ERROR] Fail to get the Output result from memory!";
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
} catch (const cv::Exception &e) {
|
||||
std::string error = "[ERROR] Fail in DvppDecodeJpegOp:" + std::string(e.what());
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status DvppDecodePngOp::Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) {
|
||||
IO_CHECK(input, output);
|
||||
if (!IsNonEmptyPNG(input)) {
|
||||
RETURN_STATUS_UNEXPECTED("DvppDecodePngOp only support process PNG 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 = static_cast<void *>(buffer);
|
||||
ResourceInfo resource;
|
||||
resource.aclConfigPath = "";
|
||||
resource.deviceIds.insert(mindspore::GlobalContext::GetGlobalDeviceID());
|
||||
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
|
||||
MDAclProcess process(context, false);
|
||||
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.PNG_D(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
|
||||
/* 测试Device内存
|
||||
*/
|
||||
auto data = std::static_pointer_cast<unsigned char>(process.Get_Memory_Data());
|
||||
unsigned char *ret_ptr = data.get();
|
||||
std::shared_ptr<DvppDataInfo> DecodeOut(process.Get_Decode_DeviceData());
|
||||
dsize_t dvpp_length = DecodeOut->dataSize;
|
||||
// dsize_t decode_height = DecodeOut->height;
|
||||
// dsize_t decode_width = DecodeOut->width;
|
||||
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();
|
||||
process.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 DvppDecodePngOp:" + std::string(e.what());
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status DvppDecodePngOp::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::kMDUnexpectedError, "Input has a wrong shape");
|
||||
}
|
||||
|
||||
Status DvppDecodePngOp::SetAscendResource(const std::shared_ptr<MDAclProcess> &processor) {
|
||||
processor_ = processor;
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_CCSRC_MINDDATA_DATASET_KERNELS_IMAGE_DVPP_DVPP_DECODE_PNG_OP_H
|
||||
#define MINDSPORE_CCSRC_MINDDATA_DATASET_KERNELS_IMAGE_DVPP_DVPP_DECODE_PNG_OP_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "acl/acl.h"
|
||||
#include "mindspore/core/utils/log_adapter.h"
|
||||
#include "minddata/dataset/core/data_type.h"
|
||||
#include "minddata/dataset/core/tensor.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/ErrorCode.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/ResourceManager.h"
|
||||
#include "minddata/dataset/kernels/tensor_op.h"
|
||||
#include "minddata/dataset/util/status.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
class DvppDecodePngOp : public TensorOp {
|
||||
public:
|
||||
DvppDecodePngOp() {}
|
||||
|
||||
/// \brief Destructor
|
||||
~DvppDecodePngOp() = default;
|
||||
|
||||
Status Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) override;
|
||||
|
||||
Status Compute(const std::shared_ptr<DeviceTensor> &input, std::shared_ptr<DeviceTensor> *output) override;
|
||||
|
||||
Status OutputShape(const std::vector<TensorShape> &inputs, std::vector<TensorShape> &outputs) override;
|
||||
|
||||
std::string Name() const override { return kDvppDecodePngOp; }
|
||||
|
||||
Status SetAscendResource(const std::shared_ptr<MDAclProcess> &processor) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<MDAclProcess> processor_;
|
||||
};
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
||||
|
||||
#endif // MINDSPORE_CCSRC_MINDDATA_DATASET_KERNELS_IMAGE_DVPP_DVPP_DECODE_PNG_OP_H
|
|
@ -17,20 +17,48 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/AclProcess.h"
|
||||
#include "include/api/context.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"
|
||||
#include "include/api/context.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/CommonDataType.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/MDAclProcess.h"
|
||||
#include "minddata/dataset/kernels/image/image_utils.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
Status DvppDecodeResizeCropJpegOp::Compute(const std::shared_ptr<DeviceTensor> &input,
|
||||
std::shared_ptr<DeviceTensor> *output) {
|
||||
IO_CHECK(input, output);
|
||||
try {
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(input->GetDeviceBuffer() != nullptr, "The input image buffer on device is empty");
|
||||
APP_ERROR ret = processor_->JPEG_DRC();
|
||||
if (ret != APP_ERR_OK) {
|
||||
processor_->Release();
|
||||
std::string error = "Error in dvpp processing:" + std::to_string(ret);
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
std::shared_ptr<DvppDataInfo> CropOut(processor_->Get_Croped_DeviceData());
|
||||
// std::cout << "Decoded size: " << decoded_width << ", " << decoded_height << std::endl;
|
||||
const TensorShape dvpp_shape({1, 1, 1});
|
||||
const DataType dvpp_data_type(DataType::DE_UINT8);
|
||||
mindspore::dataset::DeviceTensor::CreateEmpty(dvpp_shape, dvpp_data_type, output);
|
||||
(*output)->SetAttributes(CropOut);
|
||||
if (!((*output)->HasDeviceData())) {
|
||||
std::string error = "[ERROR] Fail to get the Output result from memory!";
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
} 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::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.");
|
||||
RETURN_STATUS_UNEXPECTED("DvppDecodeReiszeJpegOp only support process jpeg image.");
|
||||
}
|
||||
try {
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(input->GetBuffer() != nullptr, "The input image buffer is empty.");
|
||||
|
@ -38,11 +66,7 @@ Status DvppDecodeResizeCropJpegOp::Compute(const std::shared_ptr<Tensor> &input,
|
|||
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
|
||||
imageInfo.data = static_cast<void *>(buffer);
|
||||
ResourceInfo resource;
|
||||
resource.aclConfigPath = "";
|
||||
resource.deviceIds.insert(mindspore::GlobalContext::GetGlobalDeviceID());
|
||||
|
@ -56,25 +80,26 @@ Status DvppDecodeResizeCropJpegOp::Compute(const std::shared_ptr<Tensor> &input,
|
|||
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();
|
||||
MDAclProcess processor(resized_width_, resized_height_, crop_width_, crop_height_, context, true);
|
||||
ret = processor.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);
|
||||
|
||||
ret = processor.JPEG_DRC(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());
|
||||
auto data = std::static_pointer_cast<unsigned char>(processor.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;
|
||||
std::shared_ptr<DvppDataInfo> CropOut(processor.Get_Croped_DeviceData());
|
||||
uint32_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);
|
||||
|
@ -82,8 +107,8 @@ Status DvppDecodeResizeCropJpegOp::Compute(const std::shared_ptr<Tensor> &input,
|
|||
std::string error = "[ERROR] Fail to get the Output result from memory!";
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
process.device_memory_release();
|
||||
process.Release();
|
||||
processor.device_memory_release();
|
||||
processor.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());
|
||||
|
@ -102,5 +127,12 @@ Status DvppDecodeResizeCropJpegOp::OutputShape(const std::vector<TensorShape> &i
|
|||
return Status(StatusCode::kMDUnexpectedError, "Input has a wrong shape");
|
||||
}
|
||||
|
||||
Status DvppDecodeResizeCropJpegOp::SetAscendResource(const std::shared_ptr<MDAclProcess> &processor) {
|
||||
processor_ = processor;
|
||||
processor_->SetResizeParas(resized_width_, resized_height_);
|
||||
processor_->SetCropParas(crop_width_, crop_height_);
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
||||
|
|
|
@ -14,21 +14,21 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_DVPP_DECODE_RESIZE_CROP_JPEG_OP_H
|
||||
#define MINDSPORE_DVPP_DECODE_RESIZE_CROP_JPEG_OP_H
|
||||
#ifndef MINDSPORE_CCSRC_MINDDATA_DATASET_KERNELS_IMAGE_DVPP_DVPP_DECODE_RESIZE_CROP_JPEG_OP_H
|
||||
#define MINDSPORE_CCSRC_MINDDATA_DATASET_KERNELS_IMAGE_DVPP_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 "acl/acl.h"
|
||||
#include "mindspore/core/utils/log_adapter.h"
|
||||
#include "minddata/dataset/core/data_type.h"
|
||||
#include "minddata/dataset/core/tensor.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/ResourceManager.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/ErrorCode.h"
|
||||
#include "acl/acl.h"
|
||||
#include "minddata/dataset/kernels/tensor_op.h"
|
||||
#include "minddata/dataset/util/status.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
|
@ -44,17 +44,23 @@ class DvppDecodeResizeCropJpegOp : public TensorOp {
|
|||
~DvppDecodeResizeCropJpegOp() = default;
|
||||
|
||||
Status Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) override;
|
||||
|
||||
Status Compute(const std::shared_ptr<DeviceTensor> &input, std::shared_ptr<DeviceTensor> *output) override;
|
||||
|
||||
Status OutputShape(const std::vector<TensorShape> &inputs, std::vector<TensorShape> &outputs) override;
|
||||
|
||||
std::string Name() const override { return kDvppDecodeResizeCropJpegOp; }
|
||||
|
||||
Status SetAscendResource(const std::shared_ptr<MDAclProcess> &processor) override;
|
||||
|
||||
private:
|
||||
int32_t crop_height_;
|
||||
int32_t crop_width_;
|
||||
int32_t resized_height_;
|
||||
int32_t resized_width_;
|
||||
std::shared_ptr<MDAclProcess> processor_;
|
||||
};
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
||||
|
||||
#endif // MINDSPORE_DVPP_DECODE_RESIZE_CROP_JPEG_OP_H
|
||||
#endif // MINDSPORE_CCSRC_MINDDATA_DATASET_KERNELS_IMAGE_DVPP_DVPP_DECODE_RESIZE_CROP_JPEG_OP_H
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "include/api/context.h"
|
||||
#include "minddata/dataset/core/cv_tensor.h"
|
||||
#include "minddata/dataset/core/data_type.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/dvpp_decode_resize_jpeg_op.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/CommonDataType.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/MDAclProcess.h"
|
||||
#include "minddata/dataset/kernels/image/image_utils.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
Status DvppDecodeResizeJpegOp::Compute(const std::shared_ptr<DeviceTensor> &input,
|
||||
std::shared_ptr<DeviceTensor> *output) {
|
||||
IO_CHECK(input, output);
|
||||
try {
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(input->GetDeviceBuffer() != nullptr, "The input image buffer on device is empty");
|
||||
APP_ERROR ret = processor_->JPEG_DR();
|
||||
if (ret != APP_ERR_OK) {
|
||||
processor_->Release();
|
||||
std::string error = "Error in dvpp processing:" + std::to_string(ret);
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
std::shared_ptr<DvppDataInfo> ResizeOut(processor_->Get_Resized_DeviceData());
|
||||
const TensorShape dvpp_shape({1, 1, 1});
|
||||
const DataType dvpp_data_type(DataType::DE_UINT8);
|
||||
mindspore::dataset::DeviceTensor::CreateEmpty(dvpp_shape, dvpp_data_type, output);
|
||||
(*output)->SetAttributes(ResizeOut);
|
||||
if (!((*output)->HasDeviceData())) {
|
||||
std::string error = "[ERROR] Fail to get the Output result from memory!";
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
} catch (const cv::Exception &e) {
|
||||
std::string error = "[ERROR] Fail in DvppDecodeResizeJpegOp:" + std::string(e.what());
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status DvppDecodeResizeJpegOp::Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) {
|
||||
IO_CHECK(input, output);
|
||||
if (!IsNonEmptyJPEG(input)) {
|
||||
RETURN_STATUS_UNEXPECTED("DvppDecodeReiszeJpegOp 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 = static_cast<void *>(buffer);
|
||||
ResourceInfo resource;
|
||||
resource.aclConfigPath = "";
|
||||
resource.deviceIds.insert(mindspore::GlobalContext::GetGlobalDeviceID());
|
||||
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
|
||||
MDAclProcess process(resized_width_, resized_height_, context, false);
|
||||
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.JPEG_DR(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> ResizeOut(process.Get_Resized_DeviceData());
|
||||
dsize_t dvpp_length = ResizeOut->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();
|
||||
process.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 DvppDecodeResizeJpegOp:" + std::string(e.what());
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status DvppDecodeResizeJpegOp::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 1 channels
|
||||
if (inputs[0].Rank() == 1) outputs.emplace_back(out);
|
||||
if (!outputs.empty()) return Status::OK();
|
||||
return Status(StatusCode::kMDUnexpectedError, "Input has a wrong shape");
|
||||
}
|
||||
|
||||
Status DvppDecodeResizeJpegOp::SetAscendResource(const std::shared_ptr<MDAclProcess> &processor) {
|
||||
processor_ = processor;
|
||||
processor_->SetResizeParas(resized_width_, resized_height_);
|
||||
return Status::OK();
|
||||
}
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_CCSRC_MINDDATA_DATASET_KERNELS_IMAGE_DVPP_DVPP_DECODE_RESIZE_JPEG_OP_H
|
||||
#define MINDSPORE_CCSRC_MINDDATA_DATASET_KERNELS_IMAGE_DVPP_DVPP_DECODE_RESIZE_JPEG_OP_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "acl/acl.h"
|
||||
#include "mindspore/core/utils/log_adapter.h"
|
||||
#include "minddata/dataset/core/data_type.h"
|
||||
#include "minddata/dataset/core/tensor.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/ErrorCode.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/ResourceManager.h"
|
||||
#include "minddata/dataset/kernels/tensor_op.h"
|
||||
#include "minddata/dataset/util/status.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
class DvppDecodeResizeJpegOp : public TensorOp {
|
||||
public:
|
||||
DvppDecodeResizeJpegOp(int32_t resized_height, int32_t resized_width)
|
||||
: resized_height_(resized_height), resized_width_(resized_width) {}
|
||||
|
||||
/// \brief Destructor
|
||||
~DvppDecodeResizeJpegOp() = default;
|
||||
|
||||
Status Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) override;
|
||||
|
||||
Status Compute(const std::shared_ptr<DeviceTensor> &input, std::shared_ptr<DeviceTensor> *output) override;
|
||||
|
||||
Status OutputShape(const std::vector<TensorShape> &inputs, std::vector<TensorShape> &outputs) override;
|
||||
|
||||
std::string Name() const override { return kDvppDecodeResizeJpegOp; }
|
||||
|
||||
Status SetAscendResource(const std::shared_ptr<MDAclProcess> &processor) override;
|
||||
|
||||
private:
|
||||
int32_t resized_height_;
|
||||
int32_t resized_width_;
|
||||
|
||||
std::shared_ptr<MDAclProcess> processor_;
|
||||
};
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
||||
|
||||
#endif // MINDSPORE_CCSRC_MINDDATA_DATASET_KERNELS_IMAGE_DVPP_DVPP_DECODE_RESIZE_JPEG_OP_H
|
|
@ -0,0 +1,147 @@
|
|||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "include/api/context.h"
|
||||
#include "minddata/dataset/core/cv_tensor.h"
|
||||
#include "minddata/dataset/core/data_type.h"
|
||||
#include "minddata/dataset/core/device_tensor.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/dvpp_resize_jpeg_op.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/CommonDataType.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/MDAclProcess.h"
|
||||
#include "minddata/dataset/kernels/image/image_utils.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
Status DvppResizeJpegOp::Compute(const std::shared_ptr<DeviceTensor> &input, std::shared_ptr<DeviceTensor> *output) {
|
||||
IO_CHECK(input, output);
|
||||
try {
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(input->GetDeviceBuffer() != nullptr, "The input image buffer is empty.");
|
||||
std::string last_step = "Decode";
|
||||
std::shared_ptr<DvppDataInfo> imageinfo(processor_->Get_Decode_DeviceData());
|
||||
if (!imageinfo->data) {
|
||||
last_step = "Crop";
|
||||
}
|
||||
APP_ERROR ret = processor_->JPEG_R(last_step);
|
||||
if (ret != APP_ERR_OK) {
|
||||
processor_->Release();
|
||||
std::string error = "Error in dvpp processing:" + std::to_string(ret);
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
std::shared_ptr<DvppDataInfo> ResizeOut(processor_->Get_Resized_DeviceData());
|
||||
const TensorShape dvpp_shape({1, 1, 1});
|
||||
const DataType dvpp_data_type(DataType::DE_UINT8);
|
||||
mindspore::dataset::DeviceTensor::CreateEmpty(dvpp_shape, dvpp_data_type, output);
|
||||
(*output)->SetAttributes(ResizeOut); // Set attributes for output DeviceTensor
|
||||
if (!((*output)->HasDeviceData())) {
|
||||
std::string error = "[ERROR] Fail to get the Output result from device memory!";
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
} catch (const cv::Exception &e) {
|
||||
std::string error = "[ERROR] Fail in DvppResizeJpegOp:" + std::string(e.what());
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status DvppResizeJpegOp::Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) {
|
||||
IO_CHECK(input, output);
|
||||
try {
|
||||
CHECK_FAIL_RETURN_UNEXPECTED(input->GetBuffer() != nullptr, "The input image buffer is empty.");
|
||||
unsigned char *buffer = const_cast<unsigned char *>(input->GetBuffer());
|
||||
DvppDataInfo imageinfo;
|
||||
imageinfo.dataSize = input->SizeInBytes();
|
||||
imageinfo.data = static_cast<uint8_t *>(buffer);
|
||||
std::vector<uint32_t> yuv_shape_ = input->GetYuvShape();
|
||||
imageinfo.width = yuv_shape_[0];
|
||||
imageinfo.widthStride = yuv_shape_[1];
|
||||
imageinfo.height = yuv_shape_[2];
|
||||
imageinfo.heightStride = yuv_shape_[3];
|
||||
imageinfo.format = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
|
||||
ResourceInfo resource;
|
||||
resource.aclConfigPath = "";
|
||||
resource.deviceIds.insert(mindspore::GlobalContext::GetGlobalDeviceID());
|
||||
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
|
||||
MDAclProcess process(resized_width_, resized_height_, context, false);
|
||||
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.JPEG_R(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> ResizeOut(process.Get_Resized_DeviceData());
|
||||
dsize_t dvpp_length = ResizeOut->dataSize;
|
||||
const TensorShape dvpp_shape({dvpp_length, 1, 1});
|
||||
uint32_t resized_height = ResizeOut->height;
|
||||
uint32_t resized_heightStride = ResizeOut->heightStride;
|
||||
uint32_t resized_width = ResizeOut->width;
|
||||
uint32_t resized_widthStride = ResizeOut->widthStride;
|
||||
const DataType dvpp_data_type(DataType::DE_UINT8);
|
||||
mindspore::dataset::Tensor::CreateFromMemory(dvpp_shape, dvpp_data_type, ret_ptr, output);
|
||||
(*output)->SetYuvShape(resized_width, resized_widthStride, resized_height, resized_heightStride);
|
||||
if (!((*output)->HasData())) {
|
||||
std::string error = "[ERROR] Fail to get the Output result from memory!";
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
process.device_memory_release();
|
||||
process.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 DvppResizeJpegOp:" + std::string(e.what());
|
||||
RETURN_STATUS_UNEXPECTED(error);
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status DvppResizeJpegOp::SetAscendResource(const std::shared_ptr<MDAclProcess> &processor) {
|
||||
processor_ = processor;
|
||||
processor_->SetResizeParas(resized_width_, resized_height_);
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status DvppResizeJpegOp::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 1 channels
|
||||
if (inputs[0].Rank() == 1) outputs.emplace_back(out);
|
||||
if (!outputs.empty()) return Status::OK();
|
||||
return Status(StatusCode::kMDUnexpectedError, "Input has a wrong shape");
|
||||
}
|
||||
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_CCSRC_MINDDATA_DATASET_KERNELS_IMAGE_DVPP_DVPP_RESIZE_JPEG_OP_H
|
||||
#define MINDSPORE_CCSRC_MINDDATA_DATASET_KERNELS_IMAGE_DVPP_DVPP_RESIZE_JPEG_OP_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "acl/acl.h"
|
||||
#include "minddata/dataset/core/data_type.h"
|
||||
#include "minddata/dataset/core/device_tensor.h"
|
||||
#include "minddata/dataset/core/tensor.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/ErrorCode.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/ResourceManager.h"
|
||||
#include "minddata/dataset/kernels/tensor_op.h"
|
||||
#include "minddata/dataset/util/status.h"
|
||||
#include "mindspore/core/utils/log_adapter.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
class DvppResizeJpegOp : public TensorOp {
|
||||
public:
|
||||
DvppResizeJpegOp(int32_t resized_height, int32_t resized_width)
|
||||
: resized_height_(resized_height), resized_width_(resized_width) {}
|
||||
|
||||
/// \brief Destructor
|
||||
~DvppResizeJpegOp() = default;
|
||||
|
||||
Status Compute(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) override;
|
||||
|
||||
Status Compute(const std::shared_ptr<DeviceTensor> &input, std::shared_ptr<DeviceTensor> *output) override;
|
||||
|
||||
Status OutputShape(const std::vector<TensorShape> &inputs, std::vector<TensorShape> &outputs) override;
|
||||
|
||||
std::string Name() const override { return kDvppDecodeResizeJpegOp; }
|
||||
|
||||
Status SetAscendResource(const std::shared_ptr<MDAclProcess> &processor) override;
|
||||
|
||||
private:
|
||||
int32_t resized_height_;
|
||||
int32_t resized_width_;
|
||||
|
||||
std::shared_ptr<MDAclProcess> processor_;
|
||||
};
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
||||
|
||||
#endif // MINDSPORE_CCSRC_MINDDATA_DATASET_KERNELS_IMAGE_DVPP_DVPP_RESIZE_JPEG_OP_H
|
|
@ -1,255 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2020.Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "AclProcess.h"
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <thread>
|
||||
|
||||
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(const 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(const 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;
|
||||
}
|
||||
|
||||
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(); }
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2020.Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ACLMANAGER_H
|
||||
#define ACLMANAGER_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <climits>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include "acl/acl.h"
|
||||
#include "CommonDataType.h"
|
||||
#include "mindspore/core/utils/log_adapter.h"
|
||||
#include "ErrorCode.h"
|
||||
#include "DvppCommon.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(const 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();
|
||||
// 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(const RawData &ImageInfo);
|
||||
|
||||
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
|
|
@ -4,7 +4,7 @@ set_property(SOURCE ${_CURRENT_SRC_FILES} PROPERTY COMPILE_DEFINITIONS SUBMODULE
|
|||
add_definitions(-DENABLE_DVPP_INTERFACE)
|
||||
|
||||
add_library(dvpp-utils OBJECT
|
||||
AclProcess.cc
|
||||
MDAclProcess.cc
|
||||
DvppCommon.cc
|
||||
ErrorCode.cpp
|
||||
ResourceManager.cc
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "acl/acl.h"
|
||||
#include "acl/ops/acl_dvpp.h"
|
||||
|
@ -42,15 +41,6 @@ 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,
|
||||
|
@ -92,8 +82,8 @@ struct ImageInfo {
|
|||
|
||||
// Description of data in device
|
||||
struct RawData {
|
||||
size_t lenOfByte; // Size of memory, bytes
|
||||
std::shared_ptr<void> data; // Smart pointer of data
|
||||
size_t lenOfByte; // Size of memory, bytes
|
||||
void *data; // Pointer of data
|
||||
};
|
||||
|
||||
// Description of data in device
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
#include "mindspore/core/utils/log_adapter.h"
|
||||
#include "DvppCommon.h"
|
||||
#include "CommonDataType.h"
|
||||
|
@ -185,11 +186,16 @@ void DvppCommon::ReleaseDvppBuffer() {
|
|||
*/
|
||||
APP_ERROR DvppCommon::GetVpcDataSize(uint32_t width, uint32_t height, acldvppPixelFormat format, uint32_t &vpcSize) {
|
||||
// Check the invalid format of VPC function and calculate the output buffer size
|
||||
if (format != PIXEL_FORMAT_YUV_SEMIPLANAR_420 && format != PIXEL_FORMAT_YVU_SEMIPLANAR_420) {
|
||||
MS_LOG(ERROR) << "Format[" << format << "] for VPC is not supported, just support NV12 or NV21.";
|
||||
if (format != PIXEL_FORMAT_YUV_SEMIPLANAR_420 && format != PIXEL_FORMAT_YVU_SEMIPLANAR_420 &&
|
||||
format != PIXEL_FORMAT_RGB_888) {
|
||||
MS_LOG(ERROR) << "Format[" << format << "] for VPC is not supported, just support NV12 or NV21 or RGB888.";
|
||||
return APP_ERR_COMM_INVALID_PARAM;
|
||||
}
|
||||
uint32_t widthStride = DVPP_ALIGN_UP(width, VPC_WIDTH_ALIGN);
|
||||
if (format == PIXEL_FORMAT_RGB_888) {
|
||||
widthStride *= 3;
|
||||
}
|
||||
|
||||
uint32_t heightStride = DVPP_ALIGN_UP(height, VPC_HEIGHT_ALIGN);
|
||||
vpcSize = widthStride * heightStride * YUV_BGR_SIZE_CONVERT_3 / YUV_BGR_SIZE_CONVERT_2;
|
||||
return APP_ERR_OK;
|
||||
|
@ -254,12 +260,17 @@ APP_ERROR DvppCommon::GetVpcInputStrideSize(uint32_t width, uint32_t height, acl
|
|||
APP_ERROR DvppCommon::GetVpcOutputStrideSize(uint32_t width, uint32_t height, acldvppPixelFormat format,
|
||||
uint32_t &widthStride, uint32_t &heightStride) {
|
||||
// Check the invalidty of output format and calculate the output width and height
|
||||
if (format != PIXEL_FORMAT_YUV_SEMIPLANAR_420 && format != PIXEL_FORMAT_YVU_SEMIPLANAR_420) {
|
||||
MS_LOG(ERROR) << "Output format[" << format << "] for VPC is not supported, just support NV12 or NV21.";
|
||||
if (format != PIXEL_FORMAT_YUV_SEMIPLANAR_420 && format != PIXEL_FORMAT_YVU_SEMIPLANAR_420 &&
|
||||
format != PIXEL_FORMAT_RGB_888) {
|
||||
MS_LOG(ERROR) << "Output format[" << format << "] for VPC is not supported, just support NV12 or NV21 or RGB888.";
|
||||
return APP_ERR_COMM_INVALID_PARAM;
|
||||
}
|
||||
|
||||
widthStride = DVPP_ALIGN_UP(width, VPC_STRIDE_WIDTH);
|
||||
if (format == PIXEL_FORMAT_RGB_888) {
|
||||
widthStride *= 3;
|
||||
}
|
||||
|
||||
heightStride = DVPP_ALIGN_UP(height, VPC_STRIDE_HEIGHT);
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
@ -373,8 +384,9 @@ APP_ERROR DvppCommon::SetDvppPicDescData(const DvppDataInfo &dataInfo, acldvppPi
|
|||
* @return: APP_ERR_OK if success, other values if failure
|
||||
*/
|
||||
APP_ERROR DvppCommon::CheckResizeParams(const DvppDataInfo &input, const DvppDataInfo &output) {
|
||||
if (output.format != PIXEL_FORMAT_YUV_SEMIPLANAR_420 && output.format != PIXEL_FORMAT_YVU_SEMIPLANAR_420) {
|
||||
MS_LOG(ERROR) << "Output format[" << output.format << "] for VPC is not supported, just support NV12 or NV21.";
|
||||
if (output.format != PIXEL_FORMAT_YUV_SEMIPLANAR_420 && output.format != PIXEL_FORMAT_YVU_SEMIPLANAR_420 &&
|
||||
output.format != PIXEL_FORMAT_RGB_888) {
|
||||
MS_LOG(ERROR) << "Output format[" << output.format << "] for VPC is not supported, only NV12 or NV21 or RGB888.";
|
||||
return APP_ERR_COMM_INVALID_PARAM;
|
||||
}
|
||||
if (((float)output.height / input.height) < MIN_RESIZE_SCALE ||
|
||||
|
@ -419,6 +431,7 @@ APP_ERROR DvppCommon::ResizeProcess(acldvppPicDesc &inputDesc, acldvppPicDesc &o
|
|||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
|
@ -770,6 +783,7 @@ APP_ERROR DvppCommon::CombineCropProcess(DvppCropInputInfo &input, DvppDataInfo
|
|||
if (ret != APP_ERR_OK) {
|
||||
return ret;
|
||||
}
|
||||
// cropImage_所持有的成员变量 uint8_t *data通过acldvppMalloc()接口申请,位于Device上
|
||||
cropImage_ = std::make_shared<DvppDataInfo>();
|
||||
cropImage_->width = output.width;
|
||||
cropImage_->height = output.height;
|
||||
|
@ -839,6 +853,44 @@ APP_ERROR DvppCommon::JpegDecode(DvppDataInfo &input, DvppDataInfo &output, bool
|
|||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* @description: Set the description of the output image and decode
|
||||
* @param: input specifies the input image information
|
||||
* @param: output specifies the output image information
|
||||
* @param: withSynchronize specifies whether to execute synchronously
|
||||
* @return: APP_ERR_OK if success, other values if failure
|
||||
* @attention: This function can be called only when the DvppCommon object is initialized with Init
|
||||
*/
|
||||
APP_ERROR DvppCommon::PngDecode(DvppDataInfo &input, DvppDataInfo &output, bool withSynchronize) {
|
||||
// Return special error code when the DvppCommon object is initialized with InitVdec
|
||||
if (isVdec_) {
|
||||
MS_LOG(ERROR) << "PngDecode cannot be called by the DvppCommon object which is initialized with InitVdec.";
|
||||
return APP_ERR_DVPP_OBJ_FUNC_MISMATCH;
|
||||
}
|
||||
|
||||
acldvppPicDesc *outputDesc = acldvppCreatePicDesc();
|
||||
decodeOutputDesc_.reset(outputDesc, g_picDescDeleter);
|
||||
|
||||
APP_ERROR ret = SetDvppPicDescData(output, *decodeOutputDesc_);
|
||||
if (ret != APP_ERR_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = acldvppPngDecodeAsync(dvppChannelDesc_, input.data, input.dataSize, decodeOutputDesc_.get(), dvppStream_);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to decode png, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
if (withSynchronize) {
|
||||
ret = aclrtSynchronizeStream(dvppStream_);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to synchronize stream, ret = " << ret << ".";
|
||||
return APP_ERR_DVPP_JPEG_DECODE_FAIL;
|
||||
}
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* @description: Get the aligned width and height of the image after decoding
|
||||
* @param: width specifies the width before alignment
|
||||
|
@ -853,6 +905,17 @@ void DvppCommon::GetJpegDecodeStrideSize(uint32_t width, uint32_t height, uint32
|
|||
heightStride = DVPP_ALIGN_UP(height, JPEGD_STRIDE_HEIGHT);
|
||||
}
|
||||
|
||||
void DvppCommon::GetPngDecodeStrideSize(uint32_t width, uint32_t height, uint32_t &widthStride, uint32_t &heightStride,
|
||||
acldvppPixelFormat format) {
|
||||
if (format == PIXEL_FORMAT_RGB_888) {
|
||||
widthStride = DVPP_ALIGN_UP(width * 3, JPEGD_STRIDE_WIDTH);
|
||||
heightStride = DVPP_ALIGN_UP(height, JPEGD_STRIDE_HEIGHT);
|
||||
} else {
|
||||
widthStride = DVPP_ALIGN_UP(width * 4, JPEGD_STRIDE_WIDTH);
|
||||
heightStride = DVPP_ALIGN_UP(height, JPEGD_STRIDE_HEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @description: Get picture width and height and number of channels from image data
|
||||
* @param: data specifies the memory to store the image data
|
||||
|
@ -886,6 +949,39 @@ APP_ERROR DvppCommon::GetJpegImageInfo(const void *data, uint32_t dataSize, uint
|
|||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* @description: Get picture width and height and number of channels from PNG image data
|
||||
* @param: data specifies the memory to store the image data
|
||||
* @param: dataSize specifies the size of the image data
|
||||
* @param: width is used to save the image width
|
||||
* @param: height is used to save the image height
|
||||
* @param: components is used to save the number of channels
|
||||
* @return: APP_ERR_OK if success, other values if failure
|
||||
*/
|
||||
APP_ERROR DvppCommon::GetPngImageInfo(const void *data, uint32_t dataSize, uint32_t &width, uint32_t &height,
|
||||
int32_t &components) {
|
||||
uint32_t widthTmp;
|
||||
uint32_t heightTmp;
|
||||
int32_t componentsTmp;
|
||||
APP_ERROR ret = acldvppPngGetImageInfo(data, dataSize, &widthTmp, &heightTmp, &componentsTmp);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to get image info of PNG, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
if (widthTmp > MAX_PNGD_WIDTH || widthTmp < MIN_PNGD_WIDTH) {
|
||||
MS_LOG(ERROR) << "Input width is invalid, not in [" << MIN_PNGD_WIDTH << ", " << MAX_PNGD_WIDTH << "].";
|
||||
return APP_ERR_COMM_INVALID_PARAM;
|
||||
}
|
||||
if (heightTmp > MAX_PNGD_HEIGHT || heightTmp < MIN_PNGD_HEIGHT) {
|
||||
MS_LOG(ERROR) << "Input height is invalid, not in [" << MIN_PNGD_HEIGHT << ", " << MAX_PNGD_HEIGHT << "].";
|
||||
return APP_ERR_COMM_INVALID_PARAM;
|
||||
}
|
||||
width = widthTmp;
|
||||
height = heightTmp;
|
||||
components = componentsTmp;
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* @description: Get the size of the buffer for storing decoded images based on the image data, size, and format
|
||||
* @param: data specifies the memory to store the image data
|
||||
|
@ -906,6 +1002,26 @@ APP_ERROR DvppCommon::GetJpegDecodeDataSize(const void *data, uint32_t dataSize,
|
|||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* @description: Get the size of the buffer for storing decoded images based on the PNG image data, size, and format
|
||||
* @param: data specifies the memory to store the image data
|
||||
* @param: dataSize specifies the size of the image data
|
||||
* @param: format specifies the image format
|
||||
* @param: decSize is used to store the result size
|
||||
* @return: APP_ERR_OK if success, other values if failure
|
||||
*/
|
||||
APP_ERROR DvppCommon::GetPngDecodeDataSize(const void *data, uint32_t dataSize, acldvppPixelFormat format,
|
||||
uint32_t &decSize) {
|
||||
uint32_t outputSize;
|
||||
APP_ERROR ret = acldvppPngPredictDecSize(data, dataSize, format, &outputSize);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to predict decode size of png image, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
decSize = outputSize;
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* @description: Decode the image specified by imageInfo and save the result to member variable decodedImage_
|
||||
* @param: imageInfo specifies image information
|
||||
|
@ -923,24 +1039,27 @@ APP_ERROR DvppCommon::CombineJpegdProcess(const RawData &imageInfo, acldvppPixel
|
|||
}
|
||||
|
||||
int32_t components;
|
||||
// Member variable of inputImage_, uint8_t *data will be on device
|
||||
inputImage_ = std::make_shared<DvppDataInfo>();
|
||||
inputImage_->format = format;
|
||||
APP_ERROR ret =
|
||||
GetJpegImageInfo(imageInfo.data.get(), imageInfo.lenOfByte, inputImage_->width, inputImage_->height, components);
|
||||
// GetJpegImageInfo(imageInfo.data.get(), imageInfo.lenOfByte, inputImage_->width, inputImage_->height, components);
|
||||
GetJpegImageInfo(imageInfo.data, imageInfo.lenOfByte, inputImage_->width, inputImage_->height, components);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to get input image info, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Get the buffer size of decode output according to the input data and output format
|
||||
// Get the buffer size(On device) of decode output according to the input data and output format
|
||||
uint32_t outBuffSize;
|
||||
ret = GetJpegDecodeDataSize(imageInfo.data.get(), imageInfo.lenOfByte, format, outBuffSize);
|
||||
// ret = GetJpegDecodeDataSize(imageInfo.data.get(), imageInfo.lenOfByte, format, outBuffSize);
|
||||
ret = GetJpegDecodeDataSize(imageInfo.data, imageInfo.lenOfByte, format, outBuffSize);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to get size of decode output buffer, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
|
||||
// In TransferImageH2D function, device buffer will be alloced to store the input image
|
||||
// In TransferImageH2D function, device buffer will be alloced to store the input image before decode
|
||||
// Need to pay attention to release of the buffer
|
||||
ret = TransferImageH2D(imageInfo, inputImage_);
|
||||
if (ret != APP_ERR_OK) {
|
||||
|
@ -976,6 +1095,150 @@ APP_ERROR DvppCommon::CombineJpegdProcess(const RawData &imageInfo, acldvppPixel
|
|||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR DvppCommon::SinkCombineJpegdProcess(std::shared_ptr<DvppDataInfo> &input,
|
||||
std::shared_ptr<DvppDataInfo> &output, bool withSynchronize) {
|
||||
// Both input and output are locate on device, so we must release them if fail in decode
|
||||
APP_ERROR ret = JpegDecode(*input, *output, withSynchronize);
|
||||
if (ret != APP_ERR_OK) {
|
||||
// Release the output buffer when decode failed, otherwise release it after use
|
||||
RELEASE_DVPP_DATA(inputImage_->data);
|
||||
inputImage_->data = nullptr;
|
||||
RELEASE_DVPP_DATA(decodedImage_->data);
|
||||
decodedImage_->data = nullptr;
|
||||
return ret;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR DvppCommon::SinkCombinePngdProcess(std::shared_ptr<DvppDataInfo> &input,
|
||||
std::shared_ptr<DvppDataInfo> &output, bool withSynchronize) {
|
||||
// Both input and output are locate on device, so we must release them if fail in decode
|
||||
APP_ERROR ret = PngDecode(*input, *output, withSynchronize);
|
||||
if (ret != APP_ERR_OK) {
|
||||
// Release the output buffer when decode failed, otherwise release it after use
|
||||
RELEASE_DVPP_DATA(inputImage_->data);
|
||||
inputImage_->data = nullptr;
|
||||
RELEASE_DVPP_DATA(decodedImage_->data);
|
||||
decodedImage_->data = nullptr;
|
||||
return ret;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* @description: Decode the image specified by imageInfo and save the result to member variable decodedImage_
|
||||
* This function is for PNG format image
|
||||
* @param: imageInfo specifies image information
|
||||
* @param: format specifies the image format
|
||||
* @param: withSynchronize specifies whether to execute synchronously
|
||||
* @return: APP_ERR_OK if success, other values if failure
|
||||
* @attention: This function can be called only when the DvppCommon object is initialized with Init
|
||||
*/
|
||||
APP_ERROR DvppCommon::CombinePngdProcess(const RawData &imageInfo, acldvppPixelFormat format, bool withSynchronize) {
|
||||
// Return special error code when the DvppCommon object is initialized with InitVdec
|
||||
if (isVdec_) {
|
||||
MS_LOG(ERROR) << "CombinePngdProcess cannot be called by the DvppCommon object which is initialized with InitVdec.";
|
||||
return APP_ERR_DVPP_OBJ_FUNC_MISMATCH;
|
||||
}
|
||||
|
||||
int32_t components;
|
||||
inputImage_ = std::make_shared<DvppDataInfo>();
|
||||
inputImage_->format = format;
|
||||
APP_ERROR ret =
|
||||
// GetJpegImageInfo(imageInfo.data.get(), imageInfo.lenOfByte, inputImage_->width, inputImage_->height, components);
|
||||
GetPngImageInfo(imageInfo.data, imageInfo.lenOfByte, inputImage_->width, inputImage_->height, components);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to get input image info, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Get the buffer size of decode output according to the input data and output format
|
||||
uint32_t outBuffSize;
|
||||
// ret = GetJpegDecodeDataSize(imageInfo.data.get(), imageInfo.lenOfByte, format, outBuffSize);
|
||||
ret = GetPngDecodeDataSize(imageInfo.data, imageInfo.lenOfByte, format, outBuffSize);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to get size of decode output buffer, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
|
||||
// In TransferImageH2D function, device buffer will be alloced to store the input image
|
||||
// Need to pay attention to release of the buffer
|
||||
ret = TransferImageH2D(imageInfo, inputImage_);
|
||||
if (ret != APP_ERR_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
decodedImage_ = std::make_shared<DvppDataInfo>();
|
||||
decodedImage_->format = format;
|
||||
decodedImage_->width = inputImage_->width;
|
||||
decodedImage_->height = inputImage_->height;
|
||||
GetPngDecodeStrideSize(inputImage_->width, inputImage_->height, decodedImage_->widthStride,
|
||||
decodedImage_->heightStride, format);
|
||||
decodedImage_->dataSize = outBuffSize;
|
||||
// Malloc dvpp buffer to store the output data after decoding
|
||||
// Need to pay attention to release of the buffer
|
||||
ret = acldvppMalloc((void **)&decodedImage_->data, decodedImage_->dataSize);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to malloc memory on dvpp, ret = " << ret << ".";
|
||||
RELEASE_DVPP_DATA(inputImage_->data);
|
||||
return ret;
|
||||
}
|
||||
ret = PngDecode(*inputImage_, *decodedImage_, withSynchronize);
|
||||
if (ret != APP_ERR_OK) {
|
||||
// Release the output buffer when decode failed, otherwise release it after use
|
||||
RELEASE_DVPP_DATA(inputImage_->data);
|
||||
inputImage_->data = nullptr;
|
||||
RELEASE_DVPP_DATA(decodedImage_->data);
|
||||
decodedImage_->data = nullptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* @description: Transfer data from host to device
|
||||
* @param: imageInfo specifies the image data on the host
|
||||
* @return: APP_ERR_OK if success, other values if failure
|
||||
*/
|
||||
APP_ERROR DvppCommon::TransferYuvDataH2D(const DvppDataInfo &imageinfo) {
|
||||
if (imageinfo.dataSize <= 0) {
|
||||
MS_LOG(ERROR) << "The input buffer size on host should not be empty.";
|
||||
return APP_ERR_COMM_INVALID_PARAM;
|
||||
}
|
||||
uint8_t *device_ptr = nullptr;
|
||||
APP_ERROR ret = acldvppMalloc((void **)&device_ptr, imageinfo.dataSize);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to malloc " << imageinfo.dataSize << " bytes on dvpp, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
ret = aclrtMemcpyAsync(device_ptr, imageinfo.dataSize, imageinfo.data, imageinfo.dataSize, ACL_MEMCPY_HOST_TO_DEVICE,
|
||||
dvppStream_);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to copy " << imageinfo.dataSize << " bytes from host to device, ret = " << ret << ".";
|
||||
RELEASE_DVPP_DATA(device_ptr);
|
||||
return ret;
|
||||
}
|
||||
ret = aclrtSynchronizeStream(dvppStream_);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to synchronize stream, ret = " << ret << ".";
|
||||
RELEASE_DVPP_DATA(device_ptr);
|
||||
return ret;
|
||||
}
|
||||
/* Important!!! decodedImage_ speifies the image in deocded format(RGB OR YUV)
|
||||
* Not essentailly to be the image after decode.(Specifies the data not in RAW encode format)
|
||||
* It can also be the image after resize(Very important)
|
||||
*/
|
||||
decodedImage_ = std::make_shared<DvppDataInfo>();
|
||||
decodedImage_->data = device_ptr;
|
||||
decodedImage_->dataSize = imageinfo.dataSize;
|
||||
decodedImage_->height = imageinfo.height;
|
||||
decodedImage_->heightStride = imageinfo.heightStride;
|
||||
decodedImage_->width = imageinfo.width;
|
||||
decodedImage_->widthStride = imageinfo.widthStride;
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* @description: Transfer data from host to device
|
||||
* @param: imageInfo specifies the image data on the host
|
||||
|
@ -983,7 +1246,13 @@ APP_ERROR DvppCommon::CombineJpegdProcess(const RawData &imageInfo, acldvppPixel
|
|||
* @return: APP_ERR_OK if success, other values if failure
|
||||
*/
|
||||
APP_ERROR DvppCommon::TransferImageH2D(const RawData &imageInfo, const std::shared_ptr<DvppDataInfo> &jpegInput) {
|
||||
uint8_t *inDevBuff = nullptr;
|
||||
// Check image buffer size validity
|
||||
if (imageInfo.lenOfByte <= 0) {
|
||||
MS_LOG(ERROR) << "The input buffer size on host should not be empty.";
|
||||
return APP_ERR_COMM_INVALID_PARAM;
|
||||
}
|
||||
|
||||
uint8_t *inDevBuff = nullptr; // This pointer will be on device
|
||||
APP_ERROR ret = acldvppMalloc((void **)&inDevBuff, imageInfo.lenOfByte);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to malloc " << imageInfo.lenOfByte << " bytes on dvpp, ret = " << ret << ".";
|
||||
|
@ -991,8 +1260,10 @@ APP_ERROR DvppCommon::TransferImageH2D(const RawData &imageInfo, const std::shar
|
|||
}
|
||||
|
||||
// Copy the image data from host to device
|
||||
ret = aclrtMemcpyAsync(inDevBuff, imageInfo.lenOfByte, imageInfo.data.get(), imageInfo.lenOfByte,
|
||||
ACL_MEMCPY_HOST_TO_DEVICE, dvppStream_);
|
||||
// ret = aclrtMemcpyAsync(inDevBuff, imageInfo.lenOfByte, imageInfo.data.get(), imageInfo.lenOfByte,
|
||||
// ACL_MEMCPY_HOST_TO_DEVICE, dvppStream_);
|
||||
ret = aclrtMemcpyAsync(inDevBuff, imageInfo.lenOfByte, imageInfo.data, imageInfo.lenOfByte, ACL_MEMCPY_HOST_TO_DEVICE,
|
||||
dvppStream_);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to copy " << imageInfo.lenOfByte << " bytes from host to device, ret = " << ret << ".";
|
||||
RELEASE_DVPP_DATA(inDevBuff);
|
||||
|
@ -1011,6 +1282,114 @@ APP_ERROR DvppCommon::TransferImageH2D(const RawData &imageInfo, const std::shar
|
|||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sink RawData(On host) into DvppDataInfo(On device)
|
||||
*/
|
||||
APP_ERROR DvppCommon::SinkImageH2D(const RawData &imageInfo, acldvppPixelFormat format) {
|
||||
if (isVdec_) {
|
||||
MS_LOG(ERROR)
|
||||
<< "CombineJpegdProcess cannot be called by the DvppCommon object which is initialized with InitVdec.";
|
||||
return APP_ERR_DVPP_OBJ_FUNC_MISMATCH;
|
||||
}
|
||||
|
||||
int32_t components;
|
||||
// Member variable of inputImage_, uint8_t *data will be on device
|
||||
inputImage_ = std::make_shared<DvppDataInfo>();
|
||||
inputImage_->format = format;
|
||||
APP_ERROR ret =
|
||||
// GetJpegImageInfo(imageInfo.data.get(), imageInfo.lenOfByte, inputImage_->width, inputImage_->height, components);
|
||||
GetJpegImageInfo(imageInfo.data, imageInfo.lenOfByte, inputImage_->width, inputImage_->height, components);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to get input image info, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Get the buffer size(On device) of decode output according to the input data and output format
|
||||
uint32_t outBufferSize;
|
||||
// ret = GetJpegDecodeDataSize(imageInfo.data.get(), imageInfo.lenOfByte, format, outBuffSize);
|
||||
ret = GetJpegDecodeDataSize(imageInfo.data, imageInfo.lenOfByte, format, outBufferSize);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to get size of decode output buffer, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
// In TransferImageH2D function, device buffer will be alloced to store the input image before decode
|
||||
// Need to pay attention to release of the buffer
|
||||
ret = TransferImageH2D(imageInfo, inputImage_);
|
||||
if (ret != APP_ERR_OK) {
|
||||
return ret;
|
||||
}
|
||||
// This part is to define the data after decode (MALLOC ON DEVICE!!)
|
||||
decodedImage_ = std::make_shared<DvppDataInfo>();
|
||||
decodedImage_->format = format;
|
||||
decodedImage_->width = inputImage_->width;
|
||||
decodedImage_->height = inputImage_->height;
|
||||
GetJpegDecodeStrideSize(inputImage_->width, inputImage_->height, decodedImage_->widthStride,
|
||||
decodedImage_->heightStride);
|
||||
// Obtain all the attributes of inputImage_
|
||||
GetJpegDecodeStrideSize(inputImage_->width, inputImage_->height, inputImage_->widthStride, inputImage_->heightStride);
|
||||
decodedImage_->dataSize = outBufferSize;
|
||||
// Malloc dvpp buffer to store the output data after decoding
|
||||
// Need to pay attention to release of the buffer
|
||||
ret = acldvppMalloc((void **)&decodedImage_->data, decodedImage_->dataSize);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to malloc memory on dvpp, ret = " << ret << ".";
|
||||
RELEASE_DVPP_DATA(inputImage_->data);
|
||||
return ret;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR DvppCommon::SinkImageH2D(const RawData &imageInfo) {
|
||||
if (isVdec_) {
|
||||
MS_LOG(ERROR) << "CombinePngdProcess cannot be called by the DvppCommon object which is initialized with InitVdec.";
|
||||
return APP_ERR_DVPP_OBJ_FUNC_MISMATCH;
|
||||
}
|
||||
|
||||
int32_t components;
|
||||
inputImage_ = std::make_shared<DvppDataInfo>();
|
||||
acldvppPixelFormat format = PIXEL_FORMAT_RGB_888;
|
||||
inputImage_->format = format;
|
||||
APP_ERROR ret =
|
||||
GetPngImageInfo(imageInfo.data, imageInfo.lenOfByte, inputImage_->width, inputImage_->height, components);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to get input image info, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Get the buffer size of decode output according to the input data and output format
|
||||
uint32_t outBuffSize;
|
||||
// ret = GetJpegDecodeDataSize(imageInfo.data.get(), imageInfo.lenOfByte, format, outBuffSize);
|
||||
ret = GetPngDecodeDataSize(imageInfo.data, imageInfo.lenOfByte, format, outBuffSize);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to get size of decode output buffer, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
|
||||
// In TransferImageH2D function, device buffer will be alloced to store the input image
|
||||
// Need to pay attention to release of the buffer
|
||||
ret = TransferImageH2D(imageInfo, inputImage_);
|
||||
if (ret != APP_ERR_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
decodedImage_ = std::make_shared<DvppDataInfo>();
|
||||
decodedImage_->format = format;
|
||||
decodedImage_->width = inputImage_->width;
|
||||
decodedImage_->height = inputImage_->height;
|
||||
GetPngDecodeStrideSize(inputImage_->width, inputImage_->height, decodedImage_->widthStride,
|
||||
decodedImage_->heightStride, format);
|
||||
decodedImage_->dataSize = outBuffSize;
|
||||
// Malloc dvpp buffer to store the output data after decoding
|
||||
// Need to pay attention to release of the buffer
|
||||
ret = acldvppMalloc((void **)&decodedImage_->data, decodedImage_->dataSize);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to malloc memory on dvpp, ret = " << ret << ".";
|
||||
RELEASE_DVPP_DATA(inputImage_->data);
|
||||
return ret;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* @description: Create and set the description of a video stream
|
||||
* @param: data specifies the information about the video stream
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
#ifndef DVPP_COMMON_H
|
||||
#define DVPP_COMMON_H
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "CommonDataType.h"
|
||||
#include "ErrorCode.h"
|
||||
#include "acl/ops/acl_dvpp.h"
|
||||
|
@ -61,6 +59,8 @@ struct DeviceStreamData {
|
|||
|
||||
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 PNGD_STRIDE_WIDTH = 128; // Pngd module output width need to align up to 128
|
||||
const uint32_t PNGD_STRIDE_HEIGHT = 16; // Pngd 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
|
||||
|
@ -77,6 +77,10 @@ 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_PNGD_WIDTH = 4096; // Max width of pngd module
|
||||
const uint32_t MAX_PNGD_HEIGHT = 4096; // Max height of pngd module
|
||||
const uint32_t MIN_PNGD_WIDTH = 32; // Min width of pngd module
|
||||
const uint32_t MIN_PNGD_HEIGHT = 32; // Min height of pngd 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
|
||||
|
@ -126,10 +130,16 @@ class DvppCommon {
|
|||
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 void GetPngDecodeStrideSize(uint32_t width, uint32_t height, uint32_t &widthStride, uint32_t &heightStride,
|
||||
acldvppPixelFormat format);
|
||||
static APP_ERROR GetJpegImageInfo(const void *data, uint32_t dataSize, uint32_t &width, uint32_t &height,
|
||||
int32_t &components);
|
||||
static APP_ERROR GetPngImageInfo(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 GetPngDecodeDataSize(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,
|
||||
|
@ -143,6 +153,8 @@ class DvppCommon {
|
|||
APP_ERROR VpcCrop(const DvppCropInputInfo &input, const DvppDataInfo &output, bool withSynchronize);
|
||||
APP_ERROR JpegDecode(DvppDataInfo &input, DvppDataInfo &output, bool withSynchronize);
|
||||
|
||||
APP_ERROR PngDecode(DvppDataInfo &input, DvppDataInfo &output, bool withSynchronize);
|
||||
|
||||
APP_ERROR JpegEncode(DvppDataInfo &input, DvppDataInfo &output, acldvppJpegeConfig *jpegeConfig,
|
||||
bool withSynchronize);
|
||||
|
||||
|
@ -156,8 +168,17 @@ class DvppCommon {
|
|||
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 SinkCombineJpegdProcess(std::shared_ptr<DvppDataInfo> &input, std::shared_ptr<DvppDataInfo> &output,
|
||||
bool withSynchronize);
|
||||
APP_ERROR SinkCombinePngdProcess(std::shared_ptr<DvppDataInfo> &input, std::shared_ptr<DvppDataInfo> &output,
|
||||
bool withSynchronize);
|
||||
|
||||
APP_ERROR CombineJpegeProcess(const RawData &imageInfo, uint32_t width, uint32_t height, acldvppPixelFormat format,
|
||||
bool withSynchronize);
|
||||
// New feature for PNG format image decode
|
||||
APP_ERROR CombinePngdProcess(const RawData &imageInfo, 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);
|
||||
|
||||
|
@ -168,6 +189,15 @@ class DvppCommon {
|
|||
std::shared_ptr<DvppDataInfo> GetEncodedImage();
|
||||
std::shared_ptr<DvppDataInfo> GetCropedImage();
|
||||
|
||||
// Transfer DvppDataInfo from host to device, aim at resize and crop
|
||||
APP_ERROR TransferYuvDataH2D(const DvppDataInfo &imageinfo);
|
||||
// Transfer RawData(image) from host to device, aim at decode
|
||||
APP_ERROR TransferImageH2D(const RawData &imageInfo, const std::shared_ptr<DvppDataInfo> &jpegInput);
|
||||
// Transfer RawData(image on host) to inputImage_(data on device), this is for data sink mode
|
||||
APP_ERROR SinkImageH2D(const RawData &imageInfo, acldvppPixelFormat format);
|
||||
// This overload function is for PNG image sink, hence we ignore the pixel format
|
||||
APP_ERROR SinkImageH2D(const RawData &imageInfo);
|
||||
|
||||
// Release the memory that is allocated in the interfaces which are started with "Combine"
|
||||
void ReleaseDvppBuffer();
|
||||
APP_ERROR VdecSendEosFrame() const;
|
||||
|
@ -185,7 +215,6 @@ class DvppCommon {
|
|||
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();
|
||||
|
||||
|
|
|
@ -37,13 +37,14 @@ std::string GetAppErrCodeInfo(const APP_ERROR err) {
|
|||
}
|
||||
}
|
||||
|
||||
void AssertErrorCode(const int code, const std::string &file, const std::string &function, const int line) {
|
||||
void AssertErrorCode(const int code, const std::string file, const std::string function, const int line) {
|
||||
if (code != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed at " << file << "->" << function << "->" << line << ": error code=" << code;
|
||||
exit(code);
|
||||
}
|
||||
}
|
||||
|
||||
void CheckErrorCode(const int code, const std::string &file, const std::string &function, const int line) {
|
||||
void CheckErrorCode(const int code, const std::string file, const std::string function, const int line) {
|
||||
if (code != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed at " << file << "->" << function << "->" << line << ": error code=" << code;
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ enum {
|
|||
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
|
||||
// error code
|
||||
};
|
||||
const std::string APP_ERR_ACL_LOG_STRING[] = {
|
||||
[APP_ERR_OK] = "Success",
|
||||
|
@ -249,10 +249,10 @@ const std::string APP_ERR_FACE_LOG_STRING[] = {
|
|||
};
|
||||
|
||||
std::string GetAppErrCodeInfo(APP_ERROR err);
|
||||
void AssertErrorCode(const int code, const std::string &file, const std::string &function, const int line);
|
||||
void CheckErrorCode(const int code, const std::string &file, const std::string &function, const int line);
|
||||
void AssertErrorCode(const int code, const std::string file, const std::string function, const int line);
|
||||
void CheckErrorCode(const int code, const std::string file, const std::string function, const int line);
|
||||
|
||||
#define RtAssert(code) AssertErrorCode(code, __FILE__, __FUNCTION__, __LINE__);
|
||||
#define RtCheckError(code) CheckErrorCode(code, __FILE__, __FUNCTION__, __LINE__);
|
||||
|
||||
#endif // ERROR_CODE_H_
|
||||
#endif // ERROR_CODE_H_
|
|
@ -0,0 +1,966 @@
|
|||
/*
|
||||
* 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 "minddata/dataset/core/constants.h"
|
||||
#include "minddata/dataset/core/tensor_shape.h"
|
||||
#include "minddata/dataset/kernels/image/image_utils.h"
|
||||
#include "MDAclProcess.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
|
||||
*/
|
||||
MDAclProcess::MDAclProcess(uint32_t resizeWidth, uint32_t resizeHeight, uint32_t cropWidth, uint32_t cropHeight,
|
||||
aclrtContext context, bool is_crop, aclrtStream stream,
|
||||
std::shared_ptr<DvppCommon> dvppCommon)
|
||||
: resizeWidth_(resizeWidth),
|
||||
resizeHeight_(resizeHeight),
|
||||
cropWidth_(cropWidth),
|
||||
cropHeight_(cropHeight),
|
||||
context_(context),
|
||||
stream_(stream),
|
||||
contain_crop_(is_crop),
|
||||
dvppCommon_(dvppCommon),
|
||||
processedInfo_(nullptr) {}
|
||||
|
||||
MDAclProcess::MDAclProcess(uint32_t ParaWidth, uint32_t ParaHeight, aclrtContext context, bool is_crop,
|
||||
aclrtStream stream, std::shared_ptr<DvppCommon> dvppCommon)
|
||||
: contain_crop_(is_crop), context_(context), stream_(stream), dvppCommon_(dvppCommon), processedInfo_(nullptr) {
|
||||
if (is_crop) {
|
||||
resizeWidth_ = 0;
|
||||
resizeHeight_ = 0;
|
||||
cropWidth_ = ParaWidth;
|
||||
cropHeight_ = ParaHeight;
|
||||
} else {
|
||||
resizeWidth_ = ParaWidth;
|
||||
resizeHeight_ = ParaHeight;
|
||||
cropWidth_ = 0;
|
||||
cropHeight_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
MDAclProcess::MDAclProcess(aclrtContext context, bool is_crop, aclrtStream stream,
|
||||
std::shared_ptr<DvppCommon> dvppCommon)
|
||||
: resizeWidth_(0),
|
||||
resizeHeight_(0),
|
||||
cropWidth_(0),
|
||||
cropHeight_(0),
|
||||
contain_crop_(is_crop),
|
||||
context_(context),
|
||||
stream_(stream),
|
||||
dvppCommon_(dvppCommon),
|
||||
processedInfo_(nullptr) {}
|
||||
/*
|
||||
* @description: Release MDAclProcess resources
|
||||
* @return: aclError which is error code of ACL API
|
||||
*/
|
||||
APP_ERROR MDAclProcess::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 MDAclProcess::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 MDAclProcess resources
|
||||
* @return: aclError which is error code of ACL API
|
||||
*/
|
||||
APP_ERROR MDAclProcess::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;
|
||||
}
|
||||
|
||||
std::shared_ptr<DvppCommon> MDAclProcess::GetDeviceModule() { return dvppCommon_; }
|
||||
|
||||
/*
|
||||
* Sink data from Tensor(On host) to DeviceTensor(On device)
|
||||
* Two cases are different, jpeg and png
|
||||
*/
|
||||
APP_ERROR MDAclProcess::H2D_Sink(std::shared_ptr<mindspore::dataset::Tensor> &input,
|
||||
std::shared_ptr<mindspore::dataset::DeviceTensor> &device_input) {
|
||||
RawData imageinfo;
|
||||
uint32_t filesize = input->SizeInBytes();
|
||||
// MS_LOG(INFO) << "Filesize on host is: " << filesize;
|
||||
imageinfo.lenOfByte = filesize;
|
||||
unsigned char *buffer = const_cast<unsigned char *>(input->GetBuffer());
|
||||
imageinfo.data = static_cast<void *>(buffer);
|
||||
// Transfer RawData(Raw image) from host to device, which we call sink
|
||||
APP_ERROR ret;
|
||||
if (IsNonEmptyJPEG(input)) { // case JPEG
|
||||
ret = dvppCommon_->SinkImageH2D(imageinfo, PIXEL_FORMAT_YUV_SEMIPLANAR_420);
|
||||
} else { // case PNG
|
||||
ret = dvppCommon_->SinkImageH2D(imageinfo);
|
||||
}
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to transport Tensor to device, ret = " << ret;
|
||||
return ret;
|
||||
}
|
||||
auto deviceInputData = dvppCommon_->GetInputImage();
|
||||
// std::cout << "[DEBUG]Sink data sunccessfully, Filesize on device is: " << deviceInputData->dataSize << std::endl;
|
||||
const mindspore::dataset::DataType dvpp_data_type(mindspore::dataset::DataType::DE_UINT8);
|
||||
const mindspore::dataset::TensorShape dvpp_shape({1, 1, 1});
|
||||
mindspore::dataset::DeviceTensor::CreateEmpty(dvpp_shape, dvpp_data_type, &device_input);
|
||||
device_input->SetAttributes(deviceInputData);
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::D2H_Pop(std::shared_ptr<mindspore::dataset::DeviceTensor> &device_output,
|
||||
std::shared_ptr<mindspore::dataset::Tensor> &output) {
|
||||
void *resHostBuf = nullptr;
|
||||
APP_ERROR ret = aclrtMallocHost(&resHostBuf, device_output->DeviceDataSize());
|
||||
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(), device_output->DeviceDataSize(), device_output->GetDeviceBuffer(),
|
||||
device_output->DeviceDataSize(), 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;
|
||||
}
|
||||
auto data = std::static_pointer_cast<unsigned char>(processedInfo_);
|
||||
unsigned char *ret_ptr = data.get();
|
||||
|
||||
mindspore::dataset::dsize_t dvppDataSize = device_output->DeviceDataSize();
|
||||
const mindspore::dataset::TensorShape dvpp_shape({dvppDataSize, 1, 1});
|
||||
uint32_t _output_width_ = device_output->GetYuvStrideShape()[0];
|
||||
uint32_t _output_widthStride_ = device_output->GetYuvStrideShape()[1];
|
||||
uint32_t _output_height_ = device_output->GetYuvStrideShape()[2];
|
||||
uint32_t _output_heightStride_ = device_output->GetYuvStrideShape()[3];
|
||||
const mindspore::dataset::DataType dvpp_data_type(mindspore::dataset::DataType::DE_UINT8);
|
||||
mindspore::dataset::Tensor::CreateFromMemory(dvpp_shape, dvpp_data_type, ret_ptr, &output);
|
||||
output->SetYuvShape(_output_width_, _output_widthStride_, _output_height_, _output_heightStride_);
|
||||
if (!output->HasData()) {
|
||||
return APP_ERR_COMM_ALLOC_MEM;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::JPEG_D(const RawData &ImageInfo) {
|
||||
struct timeval begin = {0};
|
||||
struct timeval end = {0};
|
||||
gettimeofday(&begin, nullptr);
|
||||
// deal with image
|
||||
APP_ERROR ret = JPEG_D_(ImageInfo);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to decode, 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 decode Delay] cost: " << costMs << "ms\tfps: " << fps;
|
||||
// Get output of resize module
|
||||
std::shared_ptr<DvppDataInfo> DecodeOutData = dvppCommon_->GetDecodedImage();
|
||||
if (!DecodeOutData) {
|
||||
MS_LOG(ERROR) << "Decode Data returns 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, DecodeOutData->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(), DecodeOutData->dataSize, DecodeOutData->data, DecodeOutData->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;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::JPEG_D() {
|
||||
struct timeval begin = {0};
|
||||
struct timeval end = {0};
|
||||
gettimeofday(&begin, nullptr);
|
||||
// deal with image
|
||||
APP_ERROR ret = JPEG_D_();
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to decode, 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 decode Delay] cost: " << costMs << "ms\tfps: " << fps;
|
||||
// Get output of resize module
|
||||
std::shared_ptr<DvppDataInfo> DecodeOutData = dvppCommon_->GetDecodedImage();
|
||||
if (!DecodeOutData) {
|
||||
MS_LOG(ERROR) << "Decode Data returns NULL";
|
||||
return APP_ERR_COMM_INVALID_POINTER;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::JPEG_D_(const RawData &ImageInfo) {
|
||||
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;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::JPEG_D_() {
|
||||
auto input_ = dvppCommon_->GetInputImage();
|
||||
auto decode_output_ = dvppCommon_->GetDecodedImage();
|
||||
APP_ERROR ret = dvppCommon_->SinkCombineJpegdProcess(input_, decode_output_, true);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to process decode, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::JPEG_R(const DvppDataInfo &ImageInfo) {
|
||||
struct timeval begin = {0};
|
||||
struct timeval end = {0};
|
||||
gettimeofday(&begin, nullptr);
|
||||
// deal with image
|
||||
APP_ERROR ret = JPEG_R_(ImageInfo);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to resize, 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 resize Delay] cost: " << costMs << "ms\tfps: " << fps;
|
||||
// Get output of resize module
|
||||
std::shared_ptr<DvppDataInfo> ResizeOutData = dvppCommon_->GetResizedImage();
|
||||
if (!ResizeOutData) {
|
||||
MS_LOG(ERROR) << "Resize Data returns 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, ResizeOutData->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(), ResizeOutData->dataSize, ResizeOutData->data, ResizeOutData->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;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::JPEG_R(std::string &last_step) {
|
||||
struct timeval begin = {0};
|
||||
struct timeval end = {0};
|
||||
gettimeofday(&begin, nullptr);
|
||||
// deal with image
|
||||
APP_ERROR ret = JPEG_R_(last_step);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to resize, 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 resize Delay] cost: " << costMs << "ms\tfps: " << fps;
|
||||
// Get output of resize module
|
||||
std::shared_ptr<DvppDataInfo> ResizeOutData = dvppCommon_->GetResizedImage();
|
||||
if (!ResizeOutData) {
|
||||
MS_LOG(ERROR) << "Resize Data returns NULL";
|
||||
return APP_ERR_COMM_INVALID_POINTER;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::JPEG_R_(const DvppDataInfo &ImageInfo) {
|
||||
APP_ERROR ret = dvppCommon_->TransferYuvDataH2D(ImageInfo);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to copy data from host to device, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
std::shared_ptr<DvppDataInfo> decoded_image = dvppCommon_->GetDecodedImage();
|
||||
uint32_t pri_h = decoded_image->heightStride;
|
||||
uint32_t pri_w = decoded_image->widthStride;
|
||||
// Define the resize shape
|
||||
DvppDataInfo resizeOut;
|
||||
ResizeConfigFilter(resizeOut, pri_w, pri_h);
|
||||
ret = dvppCommon_->CombineResizeProcess(*decoded_image, resizeOut, true);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to process resize, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::JPEG_R_(std::string &last_step) {
|
||||
std::shared_ptr<DvppDataInfo> input_image = std::make_shared<DvppDataInfo>();
|
||||
if (last_step == "Decode") {
|
||||
input_image = dvppCommon_->GetDecodedImage();
|
||||
} else {
|
||||
input_image = dvppCommon_->GetCropedImage();
|
||||
}
|
||||
if (!input_image->data) {
|
||||
MS_LOG(ERROR) << "Failed to get data for resize, please verify last step operation";
|
||||
return APP_ERR_DVPP_RESIZE_FAIL;
|
||||
}
|
||||
uint32_t pri_h = input_image->heightStride;
|
||||
uint32_t pri_w = input_image->widthStride;
|
||||
DvppDataInfo resizeOut;
|
||||
ResizeConfigFilter(resizeOut, pri_w, pri_h);
|
||||
APP_ERROR ret = dvppCommon_->CombineResizeProcess(*input_image, resizeOut, true);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to process resize, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::JPEG_C(const DvppDataInfo &ImageInfo) {
|
||||
struct timeval begin = {0};
|
||||
struct timeval end = {0};
|
||||
gettimeofday(&begin, nullptr);
|
||||
// deal with image
|
||||
APP_ERROR ret = JPEG_C_(ImageInfo);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to crop image, 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 crop Delay] cost: " << costMs << "ms\tfps: " << fps;
|
||||
// Get output of resize module
|
||||
std::shared_ptr<DvppDataInfo> CropOutData = dvppCommon_->GetCropedImage();
|
||||
if (!CropOutData) {
|
||||
MS_LOG(ERROR) << "Crop Data returns 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;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::JPEG_C(std::string &last_step) {
|
||||
struct timeval begin = {0};
|
||||
struct timeval end = {0};
|
||||
gettimeofday(&begin, nullptr);
|
||||
// deal with image
|
||||
APP_ERROR ret = JPEG_C_(last_step);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to crop image, 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 crop Delay] cost: " << costMs << "ms\tfps: " << fps;
|
||||
// Get output of resize module
|
||||
std::shared_ptr<DvppDataInfo> CropOutData = dvppCommon_->GetCropedImage();
|
||||
if (!CropOutData) {
|
||||
MS_LOG(ERROR) << "Crop Data returns NULL";
|
||||
return APP_ERR_COMM_INVALID_POINTER;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::JPEG_C_(const DvppDataInfo &ImageInfo) {
|
||||
APP_ERROR ret = dvppCommon_->TransferYuvDataH2D(ImageInfo);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to copy data from host to device, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
// Unneccessary to be image after resize, maybe after decode, we store both of them in DecodedImage()
|
||||
std::shared_ptr<DvppDataInfo> resized_image = dvppCommon_->GetDecodedImage();
|
||||
uint32_t pri_h = resized_image->heightStride;
|
||||
uint32_t pri_w = resized_image->widthStride;
|
||||
// Validate the crop shape
|
||||
DvppDataInfo cropOut;
|
||||
cropOut.width = cropWidth_;
|
||||
cropOut.height = cropHeight_;
|
||||
if (cropOut.width > pri_w || cropOut.height > pri_h) {
|
||||
MS_LOG(ERROR) << "Crop size can not excceed resize, please verify your input [CROP SIZE] parameters";
|
||||
return APP_ERR_COMM_INVALID_PARAM;
|
||||
}
|
||||
cropOut.format = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
|
||||
DvppCropInputInfo cropInfo;
|
||||
cropInfo.dataInfo = *resized_image;
|
||||
// Define crop area
|
||||
CropRoiConfig cropCfg;
|
||||
CropConfigFilter(cropCfg, cropInfo, *resized_image);
|
||||
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;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::JPEG_C_(std::string &last_step) {
|
||||
std::shared_ptr<DvppDataInfo> input_image = std::make_shared<DvppDataInfo>();
|
||||
if (last_step == "Resize") {
|
||||
input_image = dvppCommon_->GetResizedImage();
|
||||
} else {
|
||||
input_image = dvppCommon_->GetDecodedImage();
|
||||
}
|
||||
if (!input_image->data) {
|
||||
MS_LOG(ERROR) << "Failed to get input data for crop, please verify last step operation";
|
||||
return APP_ERR_DVPP_CROP_FAIL;
|
||||
}
|
||||
uint32_t pri_h = input_image->heightStride;
|
||||
uint32_t pri_w = input_image->widthStride;
|
||||
DvppDataInfo cropOut;
|
||||
cropOut.width = cropWidth_;
|
||||
cropOut.height = cropHeight_;
|
||||
if (cropOut.width > pri_w || cropOut.height > pri_h) {
|
||||
MS_LOG(ERROR) << "Crop size can not excceed resize, please verify your input [CROP SIZE] parameters";
|
||||
return APP_ERR_COMM_INVALID_PARAM;
|
||||
}
|
||||
cropOut.format = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
|
||||
DvppCropInputInfo cropInfo;
|
||||
cropInfo.dataInfo = *input_image;
|
||||
// Define crop area
|
||||
CropRoiConfig cropCfg;
|
||||
CropConfigFilter(cropCfg, cropInfo, *input_image);
|
||||
APP_ERROR 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;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::PNG_D(const RawData &ImageInfo) {
|
||||
struct timeval begin = {0};
|
||||
struct timeval end = {0};
|
||||
gettimeofday(&begin, nullptr);
|
||||
// deal with image
|
||||
APP_ERROR ret = PNG_D_(ImageInfo);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to decode, 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> DecodeOutData = dvppCommon_->GetDecodedImage();
|
||||
if (!DecodeOutData) {
|
||||
MS_LOG(ERROR) << "ResizedOutData returns 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, DecodeOutData->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(), DecodeOutData->dataSize, DecodeOutData->data, DecodeOutData->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;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::PNG_D() {
|
||||
struct timeval begin = {0};
|
||||
struct timeval end = {0};
|
||||
gettimeofday(&begin, nullptr);
|
||||
// deal with image
|
||||
APP_ERROR ret = PNG_D_();
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to decode, 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 decode Delay] cost: " << costMs << "ms\tfps: " << fps;
|
||||
// Get output of resize module
|
||||
std::shared_ptr<DvppDataInfo> DecodeOutData = dvppCommon_->GetDecodedImage();
|
||||
if (!DecodeOutData) {
|
||||
MS_LOG(ERROR) << "Decode Data returns NULL";
|
||||
return APP_ERR_COMM_INVALID_POINTER;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::PNG_D_(const RawData &ImageInfo) {
|
||||
APP_ERROR ret = dvppCommon_->CombinePngdProcess(ImageInfo, PIXEL_FORMAT_RGB_888, true);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to process decode, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::PNG_D_() {
|
||||
auto input_ = dvppCommon_->GetInputImage();
|
||||
auto decode_output_ = dvppCommon_->GetDecodedImage();
|
||||
APP_ERROR ret = dvppCommon_->SinkCombinePngdProcess(input_, decode_output_, true);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to process decode, 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 MDAclProcess::JPEG_DRC(const RawData &ImageInfo) {
|
||||
struct timeval begin = {0};
|
||||
struct timeval end = {0};
|
||||
gettimeofday(&begin, nullptr);
|
||||
// deal with image
|
||||
APP_ERROR ret = JPEG_DRC_(ImageInfo);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to decode or resize or crop, 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
|
||||
/* 测试Device内存
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::JPEG_DRC() {
|
||||
struct timeval begin = {0};
|
||||
struct timeval end = {0};
|
||||
gettimeofday(&begin, nullptr);
|
||||
// deal with image
|
||||
APP_ERROR ret = JPEG_D_();
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to decode, ret = " << ret;
|
||||
return ret;
|
||||
}
|
||||
std::string last_step = "Decode";
|
||||
ret = JPEG_R_(last_step);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to resize, ret = " << ret;
|
||||
return ret;
|
||||
}
|
||||
last_step = "Resize";
|
||||
ret = JPEG_C_(last_step);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to crop, ret = " << ret;
|
||||
return ret;
|
||||
}
|
||||
// Get output of crop module
|
||||
std::shared_ptr<DvppDataInfo> CropOutData = dvppCommon_->GetCropedImage();
|
||||
if (!CropOutData) {
|
||||
MS_LOG(ERROR) << "Decode Data returns NULL";
|
||||
return APP_ERR_COMM_INVALID_POINTER;
|
||||
}
|
||||
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 (Decode + Resize + Crop) Delay] cost: " << costMs << "ms\tfps: " << fps;
|
||||
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 MDAclProcess::JPEG_DRC_(const 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, decodeOutData locates on device
|
||||
std::shared_ptr<DvppDataInfo> decodeOutData = dvppCommon_->GetDecodedImage();
|
||||
|
||||
if (decodeOutData == nullptr) {
|
||||
MS_LOG(ERROR) << "Decode output buffer is null.";
|
||||
return APP_ERR_COMM_INVALID_POINTER;
|
||||
}
|
||||
uint32_t pri_h = decodeOutData->heightStride;
|
||||
uint32_t pri_w = decodeOutData->widthStride;
|
||||
// Define output of resize jpeg image
|
||||
DvppDataInfo resizeOut;
|
||||
ResizeConfigFilter(resizeOut, pri_w, pri_h);
|
||||
// Run resize application function
|
||||
ret = dvppCommon_->CombineResizeProcess(*decodeOutData, resizeOut, true);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to process resize, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
// Get output of resize jpeg image, resizeOutData locates on device
|
||||
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;
|
||||
// Define crop area
|
||||
CropRoiConfig cropCfg;
|
||||
CropConfigFilter(cropCfg, cropInfo, resizeOut);
|
||||
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;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::JPEG_DR(const RawData &ImageInfo) {
|
||||
struct timeval begin = {0};
|
||||
struct timeval end = {0};
|
||||
gettimeofday(&begin, nullptr);
|
||||
// deal with image
|
||||
APP_ERROR ret = JPEG_DR_(ImageInfo);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to decode or resize, 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> ResizeOutData = dvppCommon_->GetResizedImage();
|
||||
if (!ResizeOutData) {
|
||||
MS_LOG(ERROR) << "ResizedOutData returns 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, ResizeOutData->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(), ResizeOutData->dataSize, ResizeOutData->data, ResizeOutData->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;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::JPEG_DR() {
|
||||
struct timeval begin = {0};
|
||||
struct timeval end = {0};
|
||||
gettimeofday(&begin, nullptr);
|
||||
// deal with image
|
||||
APP_ERROR ret = JPEG_D_();
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to decode, ret = " << ret;
|
||||
return ret;
|
||||
}
|
||||
std::string last_step = "Decode";
|
||||
ret = JPEG_R_(last_step);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to resize, ret = " << ret;
|
||||
return ret;
|
||||
}
|
||||
// Get output of resize module
|
||||
std::shared_ptr<DvppDataInfo> ResizeOutData = dvppCommon_->GetResizedImage();
|
||||
if (!ResizeOutData) {
|
||||
MS_LOG(ERROR) << "Decode Data returns NULL";
|
||||
return APP_ERR_COMM_INVALID_POINTER;
|
||||
}
|
||||
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 (Decode + Resize) Delay] cost: " << costMs << "ms\tfps: " << fps;
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::JPEG_DR_(const 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
|
||||
uint32_t pri_h = decodeOutData->heightStride;
|
||||
uint32_t pri_w = decodeOutData->widthStride;
|
||||
DvppDataInfo resizeOut;
|
||||
ResizeConfigFilter(resizeOut, pri_w, pri_h);
|
||||
// Run resize application function
|
||||
ret = dvppCommon_->CombineResizeProcess(*decodeOutData, resizeOut, true);
|
||||
if (ret != APP_ERR_OK) {
|
||||
MS_LOG(ERROR) << "Failed to process resize, ret = " << ret << ".";
|
||||
return ret;
|
||||
}
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
void MDAclProcess::CropConfigFilter(CropRoiConfig &cfg, DvppCropInputInfo &cropinfo, DvppDataInfo &resizeinfo) {
|
||||
if (resizeHeight_ != 0) {
|
||||
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--;
|
||||
}
|
||||
} else {
|
||||
cfg.up = (resizeinfo.height - cropHeight_) / 2;
|
||||
if (cfg.up % 2 != 0) {
|
||||
cfg.up++;
|
||||
}
|
||||
cfg.down = resizeinfo.height - (resizeinfo.height - cropHeight_) / 2;
|
||||
if (cfg.down % 2 == 0) {
|
||||
cfg.down--;
|
||||
}
|
||||
}
|
||||
if (resizeWidth_ != 0) {
|
||||
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--;
|
||||
}
|
||||
} else {
|
||||
cfg.left = (resizeinfo.width - cropWidth_) / 2;
|
||||
if (cfg.left % 2 != 0) {
|
||||
cfg.left++;
|
||||
}
|
||||
cfg.right = resizeinfo.width - (resizeinfo.width - cropWidth_) / 2;
|
||||
if (cfg.right % 2 == 0) {
|
||||
cfg.right--;
|
||||
}
|
||||
}
|
||||
cropinfo.roi = cfg;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::ResizeConfigFilter(DvppDataInfo &resizeinfo, const uint32_t pri_w_, const uint32_t pri_h_) {
|
||||
if (resizeWidth_ != 0) { // 如果输入参数个数为2,按指定参数缩放
|
||||
resizeinfo.width = resizeWidth_;
|
||||
resizeinfo.widthStride = DVPP_ALIGN_UP(resizeWidth_, VPC_STRIDE_WIDTH);
|
||||
resizeinfo.height = resizeHeight_;
|
||||
resizeinfo.heightStride = DVPP_ALIGN_UP(resizeHeight_, VPC_STRIDE_HEIGHT);
|
||||
} else { // 如果输入参数个数为1,保持原图片比例缩放
|
||||
if (pri_h_ >= pri_w_) {
|
||||
resizeinfo.width = resizeHeight_; // 若输入参数个数为1,则只有resizeHeight_有值
|
||||
resizeinfo.widthStride = DVPP_ALIGN_UP(resizeinfo.width, VPC_STRIDE_WIDTH);
|
||||
resizeinfo.height = uint32_t(resizeHeight_ * pri_h_ / pri_w_);
|
||||
resizeinfo.heightStride = DVPP_ALIGN_UP(resizeinfo.height, VPC_STRIDE_HEIGHT);
|
||||
} else {
|
||||
resizeinfo.width = uint32_t(resizeHeight_ * pri_w_ / pri_h_);
|
||||
resizeinfo.widthStride = DVPP_ALIGN_UP(resizeinfo.width, VPC_STRIDE_WIDTH);
|
||||
resizeinfo.height = resizeHeight_;
|
||||
resizeinfo.heightStride = DVPP_ALIGN_UP(resizeinfo.height, VPC_STRIDE_HEIGHT);
|
||||
}
|
||||
}
|
||||
resizeinfo.format = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
/*
|
||||
* @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> MDAclProcess::Get_Memory_Data() { return processedInfo_; }
|
||||
|
||||
std::shared_ptr<DvppDataInfo> MDAclProcess::Get_Croped_DeviceData() { return dvppCommon_->GetCropedImage(); }
|
||||
|
||||
std::shared_ptr<DvppDataInfo> MDAclProcess::Get_Resized_DeviceData() { return dvppCommon_->GetResizedImage(); }
|
||||
|
||||
std::shared_ptr<DvppDataInfo> MDAclProcess::Get_Decode_DeviceData() { return dvppCommon_->GetDecodedImage(); }
|
||||
|
||||
APP_ERROR MDAclProcess::SetResizeParas(uint32_t width, uint32_t height) {
|
||||
resizeWidth_ = width;
|
||||
resizeHeight_ = height;
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::SetCropParas(uint32_t width, uint32_t height) {
|
||||
cropWidth_ = width;
|
||||
cropHeight_ = height;
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
APP_ERROR MDAclProcess::device_memory_release() {
|
||||
dvppCommon_->ReleaseDvppBuffer();
|
||||
MS_LOG(INFO) << "Device memory release successfully";
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
std::vector<uint32_t> MDAclProcess::Get_Primary_Shape() {
|
||||
std::vector<uint32_t> pri_shape;
|
||||
if (!dvppCommon_) {
|
||||
pri_shape.emplace_back(dvppCommon_->GetDecodedImage()->heightStride);
|
||||
pri_shape.emplace_back(dvppCommon_->GetDecodedImage()->widthStride);
|
||||
}
|
||||
return pri_shape;
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* 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 MDACLMANAGER_H
|
||||
#define MDACLMANAGER_H
|
||||
|
||||
#include <climits>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include "acl/acl.h"
|
||||
#include "CommonDataType.h"
|
||||
#include "minddata/dataset/core/tensor_shape.h"
|
||||
#include "minddata/dataset/core/data_type.h"
|
||||
#include "mindspore/ccsrc/minddata/dataset/core/device_tensor.h"
|
||||
#include "mindspore/ccsrc/minddata/dataset/core/tensor.h"
|
||||
#include "mindspore/core/utils/log_adapter.h"
|
||||
#include "mindspore/ccsrc/minddata/dataset/util/status.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 MDAclProcess {
|
||||
public:
|
||||
MDAclProcess(uint32_t resizeWidth, uint32_t resizeHeight, uint32_t cropWidth, uint32_t cropHeight,
|
||||
aclrtContext context, bool is_crop = true, aclrtStream stream = nullptr,
|
||||
std::shared_ptr<DvppCommon> dvppCommon = nullptr);
|
||||
|
||||
MDAclProcess(uint32_t ParaWidth, uint32_t ParaHeight, aclrtContext context, bool is_crop = false,
|
||||
aclrtStream stream = nullptr, std::shared_ptr<DvppCommon> dvppCommon = nullptr);
|
||||
|
||||
MDAclProcess(aclrtContext context, bool is_crop = false, aclrtStream stream = nullptr,
|
||||
std::shared_ptr<DvppCommon> dvppCommon = nullptr);
|
||||
|
||||
~MDAclProcess(){};
|
||||
|
||||
// Release all the resource
|
||||
APP_ERROR Release();
|
||||
// Create resource for this sample
|
||||
APP_ERROR InitResource();
|
||||
// Process the result
|
||||
APP_ERROR JPEG_DRC(const RawData &ImageInfo);
|
||||
APP_ERROR JPEG_DRC();
|
||||
// Procss the image without crop
|
||||
APP_ERROR JPEG_DR(const RawData &ImageInfo);
|
||||
APP_ERROR JPEG_DR();
|
||||
// Process the JPEG image only with decode
|
||||
APP_ERROR JPEG_D(const RawData &ImageInfo);
|
||||
APP_ERROR JPEG_D();
|
||||
// Process the JPEG image only with resize
|
||||
APP_ERROR JPEG_R(const DvppDataInfo &ImageInfo);
|
||||
APP_ERROR JPEG_R(std::string &last_step);
|
||||
// Process the JPEG image only with crop
|
||||
APP_ERROR JPEG_C(const DvppDataInfo &ImageInfo);
|
||||
APP_ERROR JPEG_C(std::string &last_step);
|
||||
// Process the PNG image only with decode
|
||||
APP_ERROR PNG_D(const RawData &ImageInfo);
|
||||
APP_ERROR PNG_D();
|
||||
// API for access memory
|
||||
std::shared_ptr<void> Get_Memory_Data();
|
||||
// API for access device memory of croped data
|
||||
std::shared_ptr<DvppDataInfo> Get_Croped_DeviceData();
|
||||
// API for access device memory of resized data
|
||||
std::shared_ptr<DvppDataInfo> Get_Resized_DeviceData();
|
||||
// API for access device memory of decode data
|
||||
std::shared_ptr<DvppDataInfo> Get_Decode_DeviceData();
|
||||
|
||||
APP_ERROR H2D_Sink(std::shared_ptr<mindspore::dataset::Tensor> &input,
|
||||
std::shared_ptr<mindspore::dataset::DeviceTensor> &device_input);
|
||||
|
||||
APP_ERROR D2H_Pop(std::shared_ptr<mindspore::dataset::DeviceTensor> &device_output,
|
||||
std::shared_ptr<mindspore::dataset::Tensor> &output);
|
||||
|
||||
// D-chip memory release
|
||||
APP_ERROR device_memory_release();
|
||||
|
||||
std::shared_ptr<DvppCommon> GetDeviceModule();
|
||||
|
||||
std::vector<uint32_t> Get_Primary_Shape();
|
||||
|
||||
// Set Dvpp parameters
|
||||
APP_ERROR SetResizeParas(uint32_t width, uint32_t height);
|
||||
APP_ERROR SetCropParas(uint32_t width, uint32_t height);
|
||||
|
||||
private:
|
||||
// Crop definition
|
||||
void CropConfigFilter(CropRoiConfig &cfg, DvppCropInputInfo &cropinfo, DvppDataInfo &resizeinfo);
|
||||
// Resize definition
|
||||
APP_ERROR ResizeConfigFilter(DvppDataInfo &resizeinfo, const uint32_t pri_w_, const uint32_t pri_h_);
|
||||
// Initialize DVPP modules used by this sample
|
||||
APP_ERROR InitModule();
|
||||
// Dvpp process with crop
|
||||
APP_ERROR JPEG_DRC_(const RawData &ImageInfo);
|
||||
// Dvpp process without crop
|
||||
APP_ERROR JPEG_DR_(const RawData &ImageInfo);
|
||||
// Impl of JPEG_D
|
||||
APP_ERROR JPEG_D_(const RawData &ImageInfo);
|
||||
APP_ERROR JPEG_D_();
|
||||
// Impl of JPEG_R
|
||||
APP_ERROR JPEG_R_(const DvppDataInfo &ImageInfo);
|
||||
APP_ERROR JPEG_R_(std::string &last_step);
|
||||
// Impl of JPEG_C
|
||||
APP_ERROR JPEG_C_(const DvppDataInfo &ImageInfo);
|
||||
APP_ERROR JPEG_C_(std::string &last_step);
|
||||
// Impl of PNG_D
|
||||
APP_ERROR PNG_D_(const RawData &ImageInfo);
|
||||
APP_ERROR PNG_D_();
|
||||
|
||||
aclrtContext context_;
|
||||
aclrtStream stream_;
|
||||
std::shared_ptr<DvppCommon> dvppCommon_; // dvpp object
|
||||
std::shared_ptr<void> processedInfo_; // processed data (On host)
|
||||
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 contain_crop_; // Initialize with crop or not
|
||||
};
|
||||
|
||||
#endif
|
|
@ -29,15 +29,15 @@ std::shared_ptr<ResourceManager> ResourceManager::ptr_ = nullptr;
|
|||
*/
|
||||
APP_ERROR ExistFile(const std::string &filePath) {
|
||||
struct stat fileSat = {0};
|
||||
char c[PATH_MAX_ASCEND + 1] = {0x00};
|
||||
size_t count = filePath.copy(c, PATH_MAX_ASCEND + 1);
|
||||
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_ASCEND + 1] = {0x00};
|
||||
if ((strlen(c) > PATH_MAX_ASCEND) || (realpath(c, path) == nullptr)) {
|
||||
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;
|
||||
}
|
||||
|
@ -85,7 +85,6 @@ APP_ERROR ResourceManager::InitResource(ResourceInfo &resourceInfo) {
|
|||
MS_LOG(INFO) << "Acl has been initialized, skip.";
|
||||
return APP_ERR_OK;
|
||||
}
|
||||
|
||||
std::string &aclConfigPath = resourceInfo.aclConfigPath;
|
||||
APP_ERROR ret;
|
||||
if (aclConfigPath.length() == 0) {
|
||||
|
|
|
@ -16,20 +16,18 @@
|
|||
#ifndef RESOURCEMANAGER_H
|
||||
#define RESOURCEMANAGER_H
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include "CommonDataType.h"
|
||||
#include "ErrorCode.h"
|
||||
#include <sys/stat.h>
|
||||
#include "mindspore/core/utils/log_adapter.h"
|
||||
#include "mindspore/ccsrc/cxx_api/graph/acl/acl_env_guard.h"
|
||||
|
||||
#define PATH_MAX_ASCEND 4096
|
||||
#define PATH_MAX 4096
|
||||
|
||||
enum ModelLoadMethod {
|
||||
LOAD_FROM_FILE = 0, // Loading from file, memory of model and weights are managed by ACL
|
||||
|
@ -63,10 +61,12 @@ struct ResourceInfo {
|
|||
APP_ERROR ExistFile(const std::string &filePath);
|
||||
|
||||
class ResourceManager {
|
||||
public:
|
||||
ResourceManager() {}
|
||||
friend APP_ERROR ExistFile(const std::string &filePath);
|
||||
|
||||
~ResourceManager() {}
|
||||
public:
|
||||
ResourceManager(){};
|
||||
|
||||
~ResourceManager(){};
|
||||
|
||||
// Get the Instance of resource manager
|
||||
static std::shared_ptr<ResourceManager> GetInstance();
|
||||
|
@ -89,4 +89,4 @@ class ResourceManager {
|
|||
std::shared_ptr<mindspore::AclEnvGuard> acl_env_;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -142,6 +142,12 @@ bool IsNonEmptyJPEG(const std::shared_ptr<Tensor> &input) {
|
|||
return input->SizeInBytes() > kJpegMagicLen && memcmp(input->GetBuffer(), kJpegMagic, kJpegMagicLen) == 0;
|
||||
}
|
||||
|
||||
bool IsNonEmptyPNG(const std::shared_ptr<Tensor> &input) {
|
||||
const unsigned char *kPngMagic = (unsigned char *)"\x89\x50\x4E\x47";
|
||||
constexpr size_t kPngMagicLen = 4;
|
||||
return input->SizeInBytes() > kPngMagicLen && memcmp(input->GetBuffer(), kPngMagic, kPngMagicLen) == 0;
|
||||
}
|
||||
|
||||
Status Decode(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output) {
|
||||
if (IsNonEmptyJPEG(input)) {
|
||||
return JpegCropAndDecode(input, output);
|
||||
|
@ -953,7 +959,7 @@ Status Erase(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *outp
|
|||
RETURN_STATUS_UNEXPECTED("CutOut: load image failed.");
|
||||
}
|
||||
if (input_cv->Rank() != 3 || num_channels != 3) {
|
||||
RETURN_STATUS_UNEXPECTED("CutOut: image shape is not <H,W,C>.");
|
||||
RETURN_STATUS_UNEXPECTED("CutOut: image shape is not <H,W,C> or <H,W>.");
|
||||
}
|
||||
cv::Mat input_img = input_cv->mat();
|
||||
int32_t image_h = input_cv->shape()[0];
|
||||
|
|
|
@ -103,6 +103,8 @@ Status DecodeCv(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *o
|
|||
|
||||
bool IsNonEmptyJPEG(const std::shared_ptr<Tensor> &input);
|
||||
|
||||
bool IsNonEmptyPNG(const std::shared_ptr<Tensor> &input);
|
||||
|
||||
void JpegSetSource(j_decompress_ptr c_info, const void *data, int64_t data_size);
|
||||
|
||||
Status JpegCropAndDecode(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output, int x = 0, int y = 0,
|
||||
|
|
|
@ -32,9 +32,6 @@
|
|||
#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"
|
||||
|
@ -305,102 +302,6 @@ Status MixUpBatchOperation::to_json(nlohmann::json *out_json) {
|
|||
|
||||
#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 resolution 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 resolution 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 (*min_element(crop_.begin(), crop_.end()) < 32 || *max_element(crop_.begin(), crop_.end()) > 2048) {
|
||||
std::string err_msg = "Dvpp module supports crop image with resolution in range [32, 2048], got Crop Parameters: ";
|
||||
if (crop_.size() == 2) {
|
||||
MS_LOG(ERROR) << err_msg << "[" << crop_[0] << ", " << crop_[1] << "]";
|
||||
} else {
|
||||
MS_LOG(ERROR) << err_msg << "[" << crop_[0] << ", " << crop_[0] << "]";
|
||||
}
|
||||
RETURN_STATUS_SYNTAX_ERROR(err_msg);
|
||||
}
|
||||
if (*min_element(resize_.begin(), resize_.end()) < 32 || *max_element(resize_.begin(), resize_.end()) > 2048) {
|
||||
std::string err_msg =
|
||||
"Dvpp module supports resize image with resolution in range [32, 2048], got Crop Parameters: ";
|
||||
if (resize_.size() == 2) {
|
||||
MS_LOG(ERROR) << err_msg << "[" << resize_[0] << ", " << resize_[1] << "]";
|
||||
} else {
|
||||
MS_LOG(ERROR) << err_msg << "[" << resize_[0] << ", " << resize_[0] << "]";
|
||||
}
|
||||
RETURN_STATUS_SYNTAX_ERROR(err_msg);
|
||||
}
|
||||
if (crop_.size() < resize_.size()) {
|
||||
if (crop_[0] > MIN(resize_[0], resize_[1])) {
|
||||
std::string err_msg =
|
||||
"Each value of crop parameter must be smaller than corresponding resize parameter, for example: x[0] <= "
|
||||
"y[0], and x[1] <= y[1], please verify your input parameters.";
|
||||
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 =
|
||||
"Each value of crop parameter must be smaller than corresponding resize parameter, for example: x[0] <= "
|
||||
"y[0], and x[1] <= y[1], please verify your input parameters.";
|
||||
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 =
|
||||
"Each value of crop parameter must be smaller than corresponding resize parameter, for example: x[0] <= "
|
||||
"y[0], and x[1] <= y[1], please verify your input parameters.";
|
||||
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) {}
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@ constexpr char kCropOperation[] = "Crop";
|
|||
constexpr char kCutMixBatchOperation[] = "CutMixBatch";
|
||||
constexpr char kCutOutOperation[] = "CutOut";
|
||||
constexpr char kDecodeOperation[] = "Decode";
|
||||
constexpr char kDvppDecodeResizeCropOperation[] = "DvppDecodeResizeCrop";
|
||||
constexpr char kEqualizeOperation[] = "Equalize";
|
||||
constexpr char kHwcToChwOperation[] = "HwcToChw";
|
||||
constexpr char kInvertOperation[] = "Invert";
|
||||
|
@ -88,7 +87,6 @@ class CropOperation;
|
|||
class CutMixBatchOperation;
|
||||
class CutOutOperation;
|
||||
class DecodeOperation;
|
||||
class DvppDecodeResizeCropOperation;
|
||||
class EqualizeOperation;
|
||||
class HwcToChwOperation;
|
||||
class InvertOperation;
|
||||
|
@ -258,23 +256,6 @@ class DecodeOperation : public TensorOperation {
|
|||
bool rgb_;
|
||||
};
|
||||
|
||||
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;
|
||||
|
|
|
@ -48,6 +48,13 @@ Status TensorOp::Compute(const TensorRow &input, TensorRow *output) {
|
|||
"Is this TensorOp oneToOne? If no, please implement this Compute() in the derived class.");
|
||||
}
|
||||
|
||||
Status TensorOp::Compute(const std::shared_ptr<DeviceTensor> &input, std::shared_ptr<DeviceTensor> *output) {
|
||||
IO_CHECK(input, output);
|
||||
return Status(StatusCode::kMDUnexpectedError,
|
||||
"Wrong Compute() function is called. This is a function for operators which can be executed by"
|
||||
"different device. If so, please implement it in the derived class.");
|
||||
}
|
||||
|
||||
Status TensorOp::OutputShape(const std::vector<TensorShape> &inputs, std::vector<TensorShape> &outputs) {
|
||||
if (inputs.size() != NumInput())
|
||||
return Status(StatusCode::kMDUnexpectedError,
|
||||
|
@ -63,5 +70,11 @@ Status TensorOp::OutputType(const std::vector<DataType> &inputs, std::vector<Dat
|
|||
outputs = inputs;
|
||||
return Status::OK();
|
||||
}
|
||||
#ifdef ENABLE_ACL
|
||||
Status TensorOp::SetAscendResource(const std::shared_ptr<MDAclProcess> &processor) {
|
||||
return Status(StatusCode::kMDUnexpectedError,
|
||||
"This is a CPU operator which doesn't have Ascend Resource. Please verify your context");
|
||||
}
|
||||
#endif
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
#include "minddata/dataset/core/tensor.h"
|
||||
#include "minddata/dataset/core/tensor_row.h"
|
||||
#include "minddata/dataset/util/status.h"
|
||||
#include "minddata/dataset/core/device_tensor.h"
|
||||
#ifdef ENABLE_ACL
|
||||
#include "minddata/dataset/kernels/image/dvpp/utils/MDAclProcess.h"
|
||||
#endif
|
||||
|
||||
#define IO_CHECK(input, output) \
|
||||
do { \
|
||||
|
@ -58,7 +62,12 @@ constexpr char kCenterCropOp[] = "CenterCropOp";
|
|||
constexpr char kCutMixBatchOp[] = "CutMixBatchOp";
|
||||
constexpr char kCutOutOp[] = "CutOutOp";
|
||||
constexpr char kCropOp[] = "CropOp";
|
||||
constexpr char kDvppCropJpegOp[] = "DvppCropJpegOp";
|
||||
constexpr char kDvppDecodeResizeCropJpegOp[] = "DvppDecodeResizeCropJpegOp";
|
||||
constexpr char kDvppDecodeResizeJpegOp[] = "DvppDecodeResizeJpegOp";
|
||||
constexpr char kDvppDecodeJpegOp[] = "DvppDecodeJpegOp";
|
||||
constexpr char kDvppDecodePngOp[] = "DvppDecodePngOp";
|
||||
constexpr char kDvppResizeJpegOp[] = "DvppResizeJpegOp";
|
||||
constexpr char kEqualizeOp[] = "EqualizeOp";
|
||||
constexpr char kHwcToChwOp[] = "HWC2CHWOp";
|
||||
constexpr char kInvertOp[] = "InvertOp";
|
||||
|
@ -168,6 +177,12 @@ class TensorOp {
|
|||
// @return Status
|
||||
virtual Status Compute(const TensorRow &input, TensorRow *output);
|
||||
|
||||
// Perform an operation on one DeviceTensor and produce one DeviceTensor. This is for 1-to-1 column MapOp
|
||||
// @param input shares the ownership of the Tensor (increase the ref count).
|
||||
// @param output the address to a shared_ptr where the result will be placed.
|
||||
// @return Status
|
||||
virtual Status Compute(const std::shared_ptr<DeviceTensor> &input, std::shared_ptr<DeviceTensor> *output);
|
||||
|
||||
// Returns true oif the TensorOp takes one input and returns one output.
|
||||
// @return true/false
|
||||
bool OneToOne() { return NumInput() == 1 && NumOutput() == 1; }
|
||||
|
@ -201,6 +216,9 @@ class TensorOp {
|
|||
virtual std::string Name() const = 0;
|
||||
|
||||
virtual Status to_json(nlohmann::json *out_json) { return Status::OK(); }
|
||||
#ifdef ENABLE_ACL
|
||||
virtual Status SetAscendResource(const std::shared_ptr<MDAclProcess> &processor);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
bool is_deterministic_{true};
|
||||
|
|
|
@ -7,6 +7,9 @@ include_directories(${CMAKE_SOURCE_DIR}/mindspore/core)
|
|||
include_directories(${CMAKE_BINARY_DIR})
|
||||
include_directories(${CUDA_INCLUDE_DIRS})
|
||||
|
||||
if(ENABLE_ACL)
|
||||
add_definitions(-D ENABLE_ACL)
|
||||
endif()
|
||||
file(GLOB_RECURSE CXX_ST_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cc)
|
||||
add_executable(st_tests ${CXX_ST_SRC})
|
||||
target_link_libraries(st_tests PRIVATE mindspore_shared_lib _c_dataengine mindspore::gtest)
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
#include "include/api/types.h"
|
||||
#include "minddata/dataset/include/execute.h"
|
||||
#include "minddata/dataset/include/vision.h"
|
||||
#ifdef ENABLE_ACL
|
||||
#include "minddata/dataset/include/vision_ascend.h"
|
||||
#endif
|
||||
#include "minddata/dataset/kernels/tensor_op.h"
|
||||
#include "include/api/model.h"
|
||||
#include "include/api/serialization.h"
|
||||
|
@ -39,10 +42,9 @@ TEST_F(TestDE, TestResNetPreprocess) {
|
|||
auto image = mindspore::MSTensor(std::make_shared<mindspore::dataset::DETensor>(de_tensor));
|
||||
|
||||
// Define transform operations
|
||||
mindspore::dataset::Execute Transform({
|
||||
Decode(), Resize({224, 224}),
|
||||
Normalize({0.485 * 255, 0.456 * 255, 0.406 * 255}, {0.229 * 255, 0.224 * 255, 0.225 * 255}),
|
||||
HWC2CHW()});
|
||||
mindspore::dataset::Execute Transform(
|
||||
{Decode(), Resize({224, 224}),
|
||||
Normalize({0.485 * 255, 0.456 * 255, 0.406 * 255}, {0.229 * 255, 0.224 * 255, 0.225 * 255}), HWC2CHW()});
|
||||
|
||||
// Apply transform on images
|
||||
Status rc = Transform(image, &image);
|
||||
|
@ -63,9 +65,9 @@ TEST_F(TestDE, TestDvpp) {
|
|||
auto image = MSTensor(std::make_shared<mindspore::dataset::DETensor>(de_tensor));
|
||||
|
||||
// Define dvpp transform
|
||||
std::vector<uint32_t> crop_size = {224, 224};
|
||||
std::vector<uint32_t> resize_size = {256, 256};
|
||||
mindspore::dataset::Execute Transform(DvppDecodeResizeCropJpeg(crop_size, resize_size));
|
||||
std::vector<uint32_t> crop_paras = {224, 224};
|
||||
std::vector<uint32_t> resize_paras = {256, 256};
|
||||
mindspore::dataset::Execute Transform(DvppDecodeResizeCropJpeg(crop_paras, resize_paras));
|
||||
|
||||
// Apply transform on images
|
||||
Status rc = Transform(image, &image);
|
||||
|
@ -75,16 +77,52 @@ TEST_F(TestDE, TestDvpp) {
|
|||
ASSERT_EQ(image.Shape().size(), 3);
|
||||
int32_t real_h = 0;
|
||||
int32_t real_w = 0;
|
||||
int32_t remainder = crop_size[crop_size.size() - 1] % 16;
|
||||
if (crop_size.size() == 1) {
|
||||
real_h = (crop_size[0] % 2 == 0) ? crop_size[0] : crop_size[0] + 1;
|
||||
real_w = (remainder == 0) ? crop_size[0] : crop_size[0] + 16 - remainder;
|
||||
int32_t remainder = crop_paras[crop_paras.size() - 1] % 16;
|
||||
if (crop_paras.size() == 1) {
|
||||
real_h = (crop_paras[0] % 2 == 0) ? crop_paras[0] : crop_paras[0] + 1;
|
||||
real_w = (remainder == 0) ? crop_paras[0] : crop_paras[0] + 16 - remainder;
|
||||
} else {
|
||||
real_h = (crop_size[0] % 2 == 0) ? crop_size[0] : crop_size[0] + 1;
|
||||
real_w = (remainder == 0) ? crop_size[1] : crop_size[1] + 16 - remainder;
|
||||
real_h = (crop_paras[0] % 2 == 0) ? crop_paras[0] : crop_paras[0] + 1;
|
||||
real_w = (remainder == 0) ? crop_paras[1] : crop_paras[1] + 16 - remainder;
|
||||
}
|
||||
ASSERT_EQ(image.Shape()[0], real_h * real_w * 1.5); // For image in YUV format, each pixel takes 1.5 byte
|
||||
ASSERT_EQ(image.Shape()[1], 1);
|
||||
ASSERT_EQ(image.Shape()[2], 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(TestDE, TestDvppSinkMode) {
|
||||
#ifdef ENABLE_ACL
|
||||
// Read images from target directory
|
||||
std::shared_ptr<mindspore::dataset::Tensor> de_tensor;
|
||||
mindspore::dataset::Tensor::CreateFromFile("./data/dataset/apple.jpg", &de_tensor);
|
||||
auto image = MSTensor(std::make_shared<mindspore::dataset::DETensor>(de_tensor));
|
||||
|
||||
// Define dvpp transform
|
||||
std::vector<uint32_t> crop_paras = {224, 224};
|
||||
std::vector<uint32_t> resize_paras = {256};
|
||||
mindspore::dataset::Execute Transform({DvppDecodeJpeg(), DvppResizeJpeg(resize_paras), DvppCropJpeg(crop_paras)},
|
||||
"Ascend310");
|
||||
|
||||
// Apply transform on images
|
||||
Status rc = Transform(image, &image);
|
||||
|
||||
// Check image info
|
||||
ASSERT_TRUE(rc.IsOk());
|
||||
ASSERT_EQ(image.Shape().size(), 2);
|
||||
int32_t real_h = 0;
|
||||
int32_t real_w = 0;
|
||||
int32_t remainder = crop_paras[crop_paras.size() - 1] % 16;
|
||||
if (crop_paras.size() == 1) {
|
||||
real_h = (crop_paras[0] % 2 == 0) ? crop_paras[0] : crop_paras[0] + 1;
|
||||
real_w = (remainder == 0) ? crop_paras[0] : crop_paras[0] + 16 - remainder;
|
||||
} else {
|
||||
real_h = (crop_paras[0] % 2 == 0) ? crop_paras[0] : crop_paras[0] + 1;
|
||||
real_w = (remainder == 0) ? crop_paras[1] : crop_paras[1] + 16 - remainder;
|
||||
}
|
||||
ASSERT_EQ(image.Shape()[0], real_h); // For image in YUV format, each pixel takes 1.5 byte
|
||||
ASSERT_EQ(image.Shape()[1], real_w);
|
||||
ASSERT_EQ(image.DataSize(), 1.5 * real_w * real_h);
|
||||
Transform.DeviceMemoryRelease();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -70,6 +70,13 @@ if(ENABLE_MINDDATA)
|
|||
)
|
||||
list(REMOVE_ITEM UT_SRCS ${PYTHON_RELATED_SRCS})
|
||||
endif()
|
||||
|
||||
if(NOT ENABLE_ACL)
|
||||
set(ASCEND310_RELATED_SRCS
|
||||
dataset/dvpp_decode_jpeg_test.cc
|
||||
)
|
||||
list(REMOVE_ITEM UT_SRCS ${ASCEND310_RELATED_SRCS})
|
||||
endif()
|
||||
else()
|
||||
file(GLOB_RECURSE TEMP_UT_SRCS ./*.cc)
|
||||
foreach(OBJ ${TEMP_UT_SRCS})
|
||||
|
|
|
@ -149,6 +149,12 @@ if(ENABLE_PYTHON)
|
|||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_ACL)
|
||||
set(DE_UT_SRCS
|
||||
${DE_UT_SRCS}
|
||||
dvpp_decode_jpeg_test.cc)
|
||||
endif()
|
||||
|
||||
add_executable(de_ut_tests ${DE_UT_SRCS})
|
||||
|
||||
set_target_properties(de_ut_tests PROPERTIES INSTALL_RPATH "$ORIGIN/../lib:$ORIGIN/../lib64")
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* Copyright 2021Huawei 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 "common/common.h"
|
||||
#include "common/cvop_common.h"
|
||||
#include "minddata/dataset/include/vision_ascend.h"
|
||||
#include "minddata/dataset/kernels/image/dvpp/dvpp_decode_jpeg_op.h"
|
||||
#include "utils/log_adapter.h"
|
||||
|
||||
using namespace mindspore::dataset;
|
||||
using mindspore::LogStream;
|
||||
using mindspore::ExceptionType::NoExceptionType;
|
||||
using mindspore::MsLogLevel::INFO;
|
||||
|
||||
class MindDataTestDvppDecodeJpeg : public UT::CVOP::CVOpCommon {
|
||||
protected:
|
||||
MindDataTestDvppDecodeJpeg() : CVOpCommon() {}
|
||||
|
||||
std::shared_ptr<Tensor> output_tensor_;
|
||||
};
|
||||
|
||||
TEST_F(MindDataTestDvppDecodeJpeg, TestOp1) {
|
||||
MS_LOG(INFO) << "Doing testDvppDecodeJpeg.";
|
||||
std::unique_ptr<DvppDecodeJpegOp> op(new DvppDecodeJpegOp());
|
||||
EXPECT_TRUE(op->OneToOne());
|
||||
Status s = op->Compute(input_tensor_, &output_tensor_);
|
||||
EXPECT_EQ(s, Status::OK());
|
||||
}
|
Loading…
Reference in New Issue