Browse Source

!9788 [MD]Memory optimization for lite

From: @xulei2020
Reviewed-by: @HilbertDavid,@liucunwei
Signed-off-by: @HilbertDavid
tags/v1.1.0
mindspore-ci-bot Gitee 5 years ago
parent
commit
841cc05b61
3 changed files with 130 additions and 45 deletions
  1. +71
    -15
      mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/image_process.cc
  2. +2
    -2
      mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/lite_mat.cc
  3. +57
    -28
      mindspore/ccsrc/minddata/dataset/kernels/image/lite_image_utils.cc

+ 71
- 15
mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/image_process.cc View File

@@ -222,18 +222,26 @@ bool ResizeBilinear(const LiteMat &src, LiteMat &dst, int dst_w, int dst_h) {
if (src.data_type_ != LDataType::UINT8) {
return false;
}
if (src.channel_ != 3 && src.channel_ != 1) {
return false;
}
if (dst.IsEmpty()) {
(void)dst.Init(dst_w, dst_h, src.channel_, LDataType::UINT8);
} else if (dst.height_ != dst_h || dst.width_ != dst_w || dst.channel_ != src.channel_) {
return false;
} else if (dst.data_type_ != LDataType::UINT8) {
return false;
} else {
}

if (src.channel_ == 3) {
(void)dst.Init(dst_w, dst_h, 3, LDataType::UINT8);
const unsigned char *src_start_p = src;
unsigned char *dst_start_p = dst;
(void)ResizeBilinear3C(src_start_p, src.width_, src.height_, dst_start_p, dst_w, dst_h);
} else if (src.channel_ == 1) {
(void)dst.Init(dst_w, dst_h, 1, LDataType::UINT8);
} else { // channel == 1
const unsigned char *src_start_p = src;
unsigned char *dst_start_p = dst;
(void)ResizeBilinear1C(src_start_p, src.width_, src.height_, dst_start_p, dst_w, dst_h);
} else {
return false;
}
return true;
}
@@ -418,7 +426,13 @@ bool ConvertTo(const LiteMat &src, LiteMat &dst, double scale) {
if (scale < 0.0 || scale > 100) {
return false;
}
(void)dst.Init(src.width_, src.height_, src.channel_, LDataType::FLOAT32);
if (dst.IsEmpty()) {
(void)dst.Init(src.width_, src.height_, src.channel_, LDataType::FLOAT32);
} else if (dst.height_ != src.height_ || dst.width_ != src.width_ || dst.channel_ != src.channel_) {
return false;
} else if (dst.data_type_ != LDataType::FLOAT32) {
return false;
}
const unsigned char *src_start_p = src;
float *dst_start_p = dst;
for (int h = 0; h < src.height_; h++) {
@@ -433,11 +447,17 @@ bool ConvertTo(const LiteMat &src, LiteMat &dst, double scale) {
}

template <typename T>
static void CropInternal(const LiteMat &src, LiteMat &dst, int x, int y, int w, int h) {
static bool CropInternal(const LiteMat &src, LiteMat &dst, int x, int y, int w, int h) {
int dst_h = h;
int dst_w = w;
int dst_c = src.channel_;
dst.Init(dst_w, dst_h, dst_c, src.data_type_);
if (dst.IsEmpty()) {
dst.Init(dst_w, dst_h, dst_c, src.data_type_);
} else if (dst.height_ != h || dst.width_ != w || dst.channel_ != src.channel_) {
return false;
} else if (dst.data_type_ != src.data_type_) {
return false;
}
const T *src_start_p = src;
T *dst_start_p = dst;
for (int i_h = 0; i_h < dst_h; i_h++) {
@@ -445,6 +465,7 @@ static void CropInternal(const LiteMat &src, LiteMat &dst, int x, int y, int w,
T *dst_index_p = dst_start_p + i_h * dst_w * dst_c;
(void)memcpy(dst_index_p, src_index_p, dst_w * dst_c * sizeof(T));
}
return true;
}

bool Crop(const LiteMat &src, LiteMat &dst, int x, int y, int w, int h) {
@@ -456,9 +477,9 @@ bool Crop(const LiteMat &src, LiteMat &dst, int x, int y, int w, int h) {
}

if (src.data_type_ == LDataType::UINT8) {
CropInternal<uint8_t>(src, dst, x, y, w, h);
return CropInternal<uint8_t>(src, dst, x, y, w, h);
} else if (src.data_type_ == LDataType::FLOAT32) {
CropInternal<float>(src, dst, x, y, w, h);
return CropInternal<float>(src, dst, x, y, w, h);
} else {
return false;
}
@@ -511,8 +532,13 @@ bool SubStractMeanNormalize(const LiteMat &src, LiteMat &dst, const std::vector<
if (!CheckMeanAndStd(src.channel_, mean, std)) {
return false;
}

dst.Init(src.width_, src.height_, src.channel_, LDataType::FLOAT32);
if (dst.IsEmpty()) {
dst.Init(src.width_, src.height_, src.channel_, LDataType::FLOAT32);
} else if (dst.height_ != src.height_ || dst.width_ != src.width_ || dst.channel_ != src.channel_) {
return false;
} else if (dst.data_type_ != LDataType::FLOAT32) {
return false;
}

const float *src_start_p = src;
float *dst_start_p = dst;
@@ -880,8 +906,14 @@ bool ImplementAffine(LiteMat &src, LiteMat &out_img, const double M[6], std::vec
double b2 = -IM[3] * IM[2] - IM[4] * IM[5];
IM[2] = b1;
IM[5] = b2;
if (out_img.IsEmpty()) {
out_img.Init(dsize[0], dsize[1], sizeof(Pixel_Type), src.data_type_);
} else if (out_img.height_ != dsize[1] || out_img.width_ != dsize[0] || out_img.channel_ != src.channel_) {
return false;
} else if (out_img.data_type_ != src.data_type_) {
return false;
}

out_img.Init(dsize[0], dsize[1], sizeof(Pixel_Type));
for (int y = 0; y < out_img.height_; y++) {
for (int x = 0; x < out_img.width_; x++) {
int src_x = IM[0] * x + IM[1] * y + IM[2];
@@ -899,11 +931,35 @@ bool ImplementAffine(LiteMat &src, LiteMat &out_img, const double M[6], std::vec
}

bool Affine(LiteMat &src, LiteMat &out_img, const double M[6], std::vector<size_t> dsize, UINT8_C1 borderValue) {
return ImplementAffine(src, out_img, M, dsize, borderValue);
if (src.channel_ == 1 && src.data_type_ == LDataType::UINT8) {
return ImplementAffine(src, out_img, M, dsize, borderValue);
} else {
return false;
}
}

bool Affine(LiteMat &src, LiteMat &out_img, const double M[6], std::vector<size_t> dsize, UINT8_C3 borderValue) {
return ImplementAffine(src, out_img, M, dsize, borderValue);
if (src.channel_ == 3 && src.data_type_ == LDataType::UINT8) {
return ImplementAffine(src, out_img, M, dsize, borderValue);
} else {
return false;
}
}

bool Affine(LiteMat &src, LiteMat &out_img, const double M[6], std::vector<size_t> dsize, FLOAT32_C1 borderValue) {
if (src.channel_ == 1 && src.data_type_ == LDataType::FLOAT32) {
return ImplementAffine(src, out_img, M, dsize, borderValue);
} else {
return false;
}
}

bool Affine(LiteMat &src, LiteMat &out_img, const double M[6], std::vector<size_t> dsize, FLOAT32_C3 borderValue) {
if (src.channel_ == 3 && src.data_type_ == LDataType::FLOAT32) {
return ImplementAffine(src, out_img, M, dsize, borderValue);
} else {
return false;
}
}

} // namespace dataset


+ 2
- 2
mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/lite_mat.cc View File

@@ -229,7 +229,7 @@ void LiteMat::Init(int width, int height, int channel, void *p_data, LDataType d
ref_count_ = nullptr;
}

bool LiteMat::IsEmpty() const { return data_ptr_ == 0 || data_ptr_ == nullptr || c_step_ * channel_ == 0; }
bool LiteMat::IsEmpty() const { return data_ptr_ == nullptr || c_step_ * channel_ == 0; }

void LiteMat::Release() {
if (ref_count_ && (addRef(ref_count_, -1) == 1)) {
@@ -240,7 +240,7 @@ void LiteMat::Release() {
delete[] ref_count_;
}
}
data_ptr_ = 0;
data_ptr_ = nullptr;
elem_size_ = 0;
width_ = 0;
height_ = 0;


+ 57
- 28
mindspore/ccsrc/minddata/dataset/kernels/image/lite_image_utils.cc View File

@@ -267,13 +267,18 @@ Status Crop(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *outpu
int num_channels = input->shape()[2];
shape = shape.AppendDim(num_channels);
}

std::shared_ptr<Tensor> output_tensor;
RETURN_IF_NOT_OK(Tensor::CreateEmpty(shape, input->type(), &output_tensor));

uint8_t *buffer = reinterpret_cast<uint8_t *>(&(*output_tensor->begin<uint8_t>()));
LiteMat lite_mat_cut;

lite_mat_cut.Init(w, h, lite_mat_rgb.channel_, reinterpret_cast<void *>(buffer), GetLiteCVDataType(input->type()));

bool ret = Crop(lite_mat_rgb, lite_mat_cut, x, y, w, h);
CHECK_FAIL_RETURN_UNEXPECTED(ret, "Crop failed in lite cv");
// create output Tensor based off of lite_mat_cut
std::shared_ptr<Tensor> output_tensor;
RETURN_IF_NOT_OK(
Tensor::CreateFromMemory(shape, input->type(), static_cast<uchar *>(lite_mat_cut.data_ptr_), &output_tensor));

*output = output_tensor;
return Status::OK();
} catch (std::runtime_error &e) {
@@ -340,6 +345,14 @@ Status Normalize(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *
const_cast<void *>(reinterpret_cast<const void *>(input->GetBuffer())),
GetLiteCVDataType(input->type()));

std::shared_ptr<Tensor> output_tensor;
RETURN_IF_NOT_OK(Tensor::CreateEmpty(input->shape(), DataType(DataType::DE_FLOAT32), &output_tensor));

uint8_t *buffer = reinterpret_cast<uint8_t *>(&(*output_tensor->begin<uint8_t>()));

lite_mat_norm.Init(lite_mat_rgb.width_, lite_mat_rgb.height_, lite_mat_rgb.channel_,
reinterpret_cast<void *>(buffer), GetLiteCVDataType(input->type()));

if (input->type() == DataType::DE_UINT8) {
LiteMat lite_mat_float;
// change input to float
@@ -351,10 +364,6 @@ Status Normalize(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *
}
CHECK_FAIL_RETURN_UNEXPECTED(ret, "Normalize in lite cv failed");

// create output Tensor based off of lite_mat_cut
std::shared_ptr<Tensor> output_tensor;
RETURN_IF_NOT_OK(Tensor::CreateFromMemory(input->shape(), DataType(DataType::DE_FLOAT32),
static_cast<uchar *>(lite_mat_norm.data_ptr_), &output_tensor));
*output = output_tensor;
} catch (std::runtime_error &e) {
RETURN_STATUS_UNEXPECTED("Unexpected error in normalize.");
@@ -394,11 +403,17 @@ Status Resize(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *out
}

LiteMat lite_mat_resize;
std::shared_ptr<Tensor> output_tensor;
RETURN_IF_NOT_OK(Tensor::CreateEmpty(shape, input->type(), &output_tensor));

uint8_t *buffer = reinterpret_cast<uint8_t *>(&(*output_tensor->begin<uint8_t>()));

lite_mat_resize.Init(output_width, output_height, lite_mat_rgb.channel_, reinterpret_cast<void *>(buffer),
GetLiteCVDataType(input->type()));

bool ret = ResizeBilinear(lite_mat_rgb, lite_mat_resize, output_width, output_height);
CHECK_FAIL_RETURN_UNEXPECTED(ret, "Resize failed in lite cv");
std::shared_ptr<Tensor> output_tensor;
RETURN_IF_NOT_OK(
Tensor::CreateFromMemory(shape, input->type(), static_cast<uchar *>(lite_mat_resize.data_ptr_), &output_tensor));

*output = output_tensor;
} catch (std::runtime_error &e) {
RETURN_STATUS_UNEXPECTED("Error in image resize.");
@@ -426,14 +441,23 @@ Status Pad(const std::shared_ptr<Tensor> &input, std::shared_ptr<Tensor> *output
const_cast<void *>(reinterpret_cast<const void *>(input->GetBuffer())),
GetLiteCVDataType(input->type()));
LiteMat lite_mat_pad;

std::shared_ptr<Tensor> output_tensor;

int pad_width = lite_mat_rgb.width_ + pad_left + pad_right;
int pad_height = lite_mat_rgb.height_ + pad_top + pad_bottom;
TensorShape new_shape = TensorShape({pad_height, pad_width, input->shape()[2]});
RETURN_IF_NOT_OK(Tensor::CreateEmpty(new_shape, input->type(), &output_tensor));

uint8_t *buffer = reinterpret_cast<uint8_t *>(&(*output_tensor->begin<uint8_t>()));

lite_mat_pad.Init(pad_width, pad_height, lite_mat_rgb.channel_, reinterpret_cast<void *>(buffer),
GetLiteCVDataType(input->type()));

bool ret = Pad(lite_mat_rgb, lite_mat_pad, pad_top, pad_bottom, pad_left, pad_right,
PaddBorderType::PADD_BORDER_CONSTANT, fill_r, fill_g, fill_b);
CHECK_FAIL_RETURN_UNEXPECTED(ret, "Pad failed in lite cv");
// new shape for output tensor
TensorShape new_shape = TensorShape({lite_mat_pad.height_, lite_mat_pad.width_, input->shape()[2]});
std::shared_ptr<Tensor> output_tensor;
RETURN_IF_NOT_OK(
Tensor::CreateFromMemory(new_shape, input->type(), static_cast<uchar *>(lite_mat_pad.data_ptr_), &output_tensor));

*output = output_tensor;
} catch (std::runtime_error &e) {
RETURN_STATUS_UNEXPECTED("Error in image Pad.");
@@ -451,7 +475,6 @@ static Status RotateAngleWithOutMirror(const std::shared_ptr<Tensor> &input, std
LiteMat lite_mat_rgb(input->shape()[1], input->shape()[0], input->shape()[2],
const_cast<void *>(reinterpret_cast<const void *>(input->GetBuffer())),
GetLiteCVDataType(input->type()));
LiteMat lite_mat_affine;

if (orientation == 3) {
height = lite_mat_rgb.height_;
@@ -486,14 +509,17 @@ static Status RotateAngleWithOutMirror(const std::shared_ptr<Tensor> &input, std
std::vector<size_t> dsize;
dsize.push_back(width);
dsize.push_back(height);
LiteMat lite_mat_affine;
std::shared_ptr<Tensor> output_tensor;
TensorShape new_shape = TensorShape({height, width, input->shape()[2]});
RETURN_IF_NOT_OK(Tensor::CreateEmpty(new_shape, input->type(), &output_tensor));
uint8_t *buffer = reinterpret_cast<uint8_t *>(&(*output_tensor->begin<uint8_t>()));
lite_mat_affine.Init(width, height, lite_mat_rgb.channel_, reinterpret_cast<void *>(buffer),
GetLiteCVDataType(input->type()));

bool ret = Affine(lite_mat_rgb, lite_mat_affine, M, dsize, UINT8_C3(0, 0, 0));
CHECK_FAIL_RETURN_UNEXPECTED(ret, "Rotate failed in lite cv");

// new shape for output tensor
TensorShape new_shape = TensorShape({lite_mat_affine.height_, lite_mat_affine.width_, input->shape()[2]});
std::shared_ptr<Tensor> output_tensor;
RETURN_IF_NOT_OK(Tensor::CreateFromMemory(new_shape, input->type(), static_cast<uchar *>(lite_mat_affine.data_ptr_),
&output_tensor));
*output = output_tensor;
} catch (std::runtime_error &e) {
RETURN_STATUS_UNEXPECTED("Error in image Rotate.");
@@ -511,7 +537,7 @@ static Status RotateAngleWithMirror(const std::shared_ptr<Tensor> &input, std::s
LiteMat lite_mat_rgb(input->shape()[1], input->shape()[0], input->shape()[2],
const_cast<void *>(reinterpret_cast<const void *>(input->GetBuffer())),
GetLiteCVDataType(input->type()));
LiteMat lite_mat_affine;
if (orientation == 2) {
height = lite_mat_rgb.height_;
width = lite_mat_rgb.width_;
@@ -553,14 +579,17 @@ static Status RotateAngleWithMirror(const std::shared_ptr<Tensor> &input, std::s
std::vector<size_t> dsize;
dsize.push_back(width);
dsize.push_back(height);
LiteMat lite_mat_affine;
std::shared_ptr<Tensor> output_tensor;
TensorShape new_shape = TensorShape({height, width, input->shape()[2]});
RETURN_IF_NOT_OK(Tensor::CreateEmpty(new_shape, input->type(), &output_tensor));
uint8_t *buffer = reinterpret_cast<uint8_t *>(&(*output_tensor->begin<uint8_t>()));
lite_mat_affine.Init(width, height, lite_mat_rgb.channel_, reinterpret_cast<void *>(buffer),
GetLiteCVDataType(input->type()));

bool ret = Affine(lite_mat_rgb, lite_mat_affine, M, dsize, UINT8_C3(0, 0, 0));
CHECK_FAIL_RETURN_UNEXPECTED(ret, "Rotate failed in lite cv");

// new shape for output tensor
TensorShape new_shape = TensorShape({lite_mat_affine.height_, lite_mat_affine.width_, input->shape()[2]});
std::shared_ptr<Tensor> output_tensor;
RETURN_IF_NOT_OK(Tensor::CreateFromMemory(new_shape, input->type(), static_cast<uchar *>(lite_mat_affine.data_ptr_),
&output_tensor));
*output = output_tensor;
} catch (std::runtime_error &e) {
RETURN_STATUS_UNEXPECTED("Error in image Rotate.");


Loading…
Cancel
Save