!11015 fix resize and shape

From: @yeyunpeng2020
Reviewed-by: 
Signed-off-by:
This commit is contained in:
mindspore-ci-bot 2021-01-08 15:40:25 +08:00 committed by Gitee
commit 8ce17ba568
25 changed files with 175 additions and 217 deletions

View File

@ -17,8 +17,10 @@
#include "nnacl/fp32/resize_fp32.h"
#include "nnacl/common_func.h"
#include "nnacl/errorcode.h"
int PrepareResizeBilinear(const int *input_shape, const int *output_shape, bool align_corners, int *y_bottoms,
int *y_tops, int *x_lefts, int *x_rights, float *y_bottom_weights, float *x_left_weights) {
int PrepareResizeBilinear(const int *input_shape, const int *output_shape, CalculateOriginalCoordinate calculate,
int *y_bottoms, int *y_tops, int *x_lefts, int *x_rights, float *y_bottom_weights,
float *x_left_weights) {
if (input_shape == NULL || output_shape == NULL || y_bottoms == NULL || y_tops == NULL || x_lefts == NULL ||
x_rights == NULL || y_bottom_weights == NULL || x_left_weights == NULL) {
return NNACL_NULL_PTR;
@ -29,18 +31,10 @@ int PrepareResizeBilinear(const int *input_shape, const int *output_shape, bool
int new_height = output_shape[1];
int new_width = output_shape[2];
float height_scale = (float)(in_h) / new_height;
float width_scale = (float)(in_w) / new_width;
if (align_corners && new_height > 1) {
height_scale = (float)(in_h - 1) / (new_height - 1);
}
if (align_corners && new_width > 1) {
width_scale = (float)(in_w - 1) / (new_width - 1);
}
int h, w;
for (h = 0; h < new_height; h++) {
float actual_y = (float)h * height_scale;
float actual_y = calculate(h, in_h, new_height);
int y_bottom = (int)(floor(actual_y));
int y_top = y_bottom + 1 < in_h ? (y_bottom + 1) : (in_h - 1);
float y_top_weight = actual_y - (float)(y_bottom);
@ -51,7 +45,7 @@ int PrepareResizeBilinear(const int *input_shape, const int *output_shape, bool
y_bottom_weights[h] = y_bottom_weight;
}
for (w = 0; w < new_width; w++) {
float actual_x = (float)(w)*width_scale;
float actual_x = calculate(w, in_w, new_width);
int x_left = (int)(floor(actual_x));
int x_right = x_left + 1 < in_w ? (x_left + 1) : (in_w - 1);
float x_right_weight = actual_x - (float)(x_left);
@ -64,96 +58,6 @@ int PrepareResizeBilinear(const int *input_shape, const int *output_shape, bool
return NNACL_OK;
}
int ResizeBilinear(const float *input_data, float *output_data, const int *input_shape, const int *output_shape,
const int *y_bottoms, const int *y_tops, const int *x_lefts, const int *x_rights,
const float *y_bottom_weights, const float *x_left_weights, const int n_h_begin, const int n_h_end) {
if (input_data == NULL || output_data == NULL || input_shape == NULL || output_shape == NULL || y_bottoms == NULL ||
y_tops == NULL || x_lefts == NULL || x_rights == NULL || y_bottom_weights == NULL || x_left_weights == NULL) {
return NNACL_NULL_PTR;
}
int in_w = input_shape[2];
int in_c = input_shape[3];
int new_height = output_shape[1];
int new_width = output_shape[2];
int n_h, n, h, w, c;
n = n_h_begin / new_height;
h = n_h_begin % new_height;
int n_h_stride = new_width * in_c;
int out_offset = n_h_begin * n_h_stride;
for (n_h = n_h_begin; n_h < n_h_end; n_h++, h++) {
if (h == new_height) {
h = 0;
n++;
}
int y_bottom = y_bottoms[h];
int y_top = y_tops[h];
float y_bottom_weight = y_bottom_weights[h];
const float y_top_weight = 1.0f - y_bottom_weight;
for (w = 0; w < new_width; w++) {
int x_left = x_lefts[w];
int x_right = x_rights[w];
float x_left_weight = x_left_weights[w];
const float x_right_weight = 1.0f - x_left_weight;
float top_left_weight = y_top_weight * x_left_weight;
float top_right_weight = y_top_weight * x_right_weight;
float bottom_left_weight = y_bottom_weight * x_left_weight;
float bottom_right_weight = y_bottom_weight * x_right_weight;
c = 0;
int in_bottom_left_offset = offset(input_shape, n, y_bottom, x_left, c);
int in_bottom_right_offset = in_bottom_left_offset + (x_right - x_left) * in_c;
int in_top_left_offset = in_bottom_left_offset + (y_top - y_bottom) * in_w * in_c;
int in_top_right_offset = in_bottom_right_offset + (y_top - y_bottom) * in_w * in_c;
#ifdef ENABLE_NEON
float32x4_t top_left_w = vdupq_n_f32(top_left_weight);
float32x4_t top_right_w = vdupq_n_f32(top_right_weight);
float32x4_t bottom_left_w = vdupq_n_f32(bottom_left_weight);
float32x4_t bottom_right_w = vdupq_n_f32(bottom_right_weight);
for (; c <= in_c - 4; c += 4) {
float32x4_t bottom_left = vld1q_f32(input_data + in_bottom_left_offset + c);
float32x4_t bottom_right = vld1q_f32(input_data + in_bottom_right_offset + c);
float32x4_t top_left = vld1q_f32(input_data + in_top_left_offset + c);
float32x4_t top_right = vld1q_f32(input_data + in_top_right_offset + c);
float32x4_t interp_value = vdupq_n_f32(0.0);
float32x4_t tmp = vmulq_f32(bottom_left, bottom_left_w);
interp_value = vaddq_f32(interp_value, tmp);
tmp = vmulq_f32(bottom_right, bottom_right_w);
interp_value = vaddq_f32(interp_value, tmp);
tmp = vmulq_f32(top_left, top_left_w);
interp_value = vaddq_f32(interp_value, tmp);
tmp = vmulq_f32(top_right, top_right_w);
interp_value = vaddq_f32(interp_value, tmp);
vst1q_f32(output_data + out_offset, interp_value);
out_offset += 4;
}
#endif
for (; c < in_c; c++) {
float bottom_left = input_data[in_bottom_left_offset + c];
float bottom_right = input_data[in_bottom_right_offset + c];
float top_left = input_data[in_top_left_offset + c];
float top_right = input_data[in_top_right_offset + c];
float interp_value = bottom_left * bottom_left_weight + bottom_right * bottom_right_weight +
top_left * top_left_weight + top_right * top_right_weight;
output_data[out_offset] = interp_value;
out_offset++;
}
}
}
return NNACL_OK;
}
int InterpRow(const float *src_line, float *linear_output, int new_width, const float *x_left_weights,
const int *x_lefts, const int *x_rights, int in_c) {
int w;
@ -207,10 +111,10 @@ int InterpCol(const float *bottom_line, const float *top_line, float *output, in
return 0;
}
int ResizeBilinear2(const float *input_data, float *output_data, const int *input_shape, const int *output_shape,
const int *y_bottoms, const int *y_tops, const int *x_lefts, const int *x_rights,
const float *y_bottom_weights, const float *x_left_weights, float *line0, float *line1,
const int n_h_begin, const int n_h_end) {
int ResizeBilinear(const float *input_data, float *output_data, const int *input_shape, const int *output_shape,
const int *y_bottoms, const int *y_tops, const int *x_lefts, const int *x_rights,
const float *y_bottom_weights, const float *x_left_weights, float *line0, float *line1,
const int n_h_begin, const int n_h_end) {
if (input_data == NULL || output_data == NULL || input_shape == NULL || output_shape == NULL || y_bottoms == NULL ||
y_tops == NULL || x_lefts == NULL || x_rights == NULL || y_bottom_weights == NULL || x_left_weights == NULL) {
return NNACL_NULL_PTR;
@ -278,36 +182,29 @@ int ResizeBilinear2(const float *input_data, float *output_data, const int *inpu
return NNACL_OK;
}
int CalcNearestNeighbor(const int out_position, const int in_size, const float scale, const bool align_corners) {
int actual_v;
if (align_corners) {
actual_v = (int)(round((float)out_position * scale));
} else {
actual_v = (int)(floor((float)out_position * scale));
}
int input_position = actual_v < in_size ? actual_v : in_size - 1;
return input_position;
}
int ResizeNearestNeighbor(const float *input_data, float *output_data, const int *input_shape, const int *output_shape,
bool align_corners, int tid, int thread_num) {
CalculateOriginalCoordinate calculate, int coordinate_transform_mode, int tid,
int thread_num) {
int batch, y, x, c;
c = input_shape[3];
float height_scale = (float)(input_shape[1]) / (float)(output_shape[1]);
float width_scale = (float)(input_shape[2]) / (float)(output_shape[2]);
if (align_corners && output_shape[1] > 1) {
height_scale = (float)(input_shape[1] - 1) / (output_shape[1] - 1);
}
if (align_corners && output_shape[2] > 1) {
width_scale = (float)(input_shape[2] - 1) / (output_shape[2] - 1);
}
bool align_corners = coordinate_transform_mode == 1;
for (batch = 0; batch < output_shape[0]; batch++) {
for (y = tid; y < output_shape[1]; y += thread_num) {
int input_y = CalcNearestNeighbor(y, input_shape[1], height_scale, align_corners);
float actual_y = calculate(y, input_shape[1], output_shape[1]);
int input_y;
if (align_corners) {
input_y = (int)(round(actual_y));
} else {
input_y = (int)(floor(actual_y));
}
for (x = 0; x < output_shape[2]; x++) {
int input_x = CalcNearestNeighbor(x, input_shape[2], width_scale, align_corners);
float actual_x = calculate(x, input_shape[2], output_shape[2]);
int input_x;
if (align_corners) {
input_x = (int)(round(actual_x));
} else {
input_x = (int)(floor(actual_x));
}
int in_offset = offset(input_shape, batch, input_y, input_x, 0);
int out_offset = offset(output_shape, batch, y, x, 0);
memcpy(output_data + out_offset, input_data + in_offset, c * sizeof(float));
@ -317,3 +214,19 @@ int ResizeNearestNeighbor(const float *input_data, float *output_data, const int
return NNACL_OK;
}
float CalculateAsymmetric(int x_resized, int length_original, int length_resized) {
float scale = (float)(length_resized) / length_original;
return (float)(x_resized) / scale;
}
float CalculateAlignCorners(int x_resized, int length_original, int length_resized) {
float scale = (float)(length_resized - 1) / (length_original - 1);
return (float)(x_resized) / scale;
}
float CalculateHalfPixel(int x_resized, int length_original, int length_resized) {
float scale = (float)(length_resized) / length_original;
float actual = (float)(x_resized + 0.5) / scale - 0.5;
return actual > 0 ? actual : 0;
}

View File

@ -25,21 +25,27 @@
#ifdef __cplusplus
extern "C" {
#endif
typedef float (*CalculateOriginalCoordinate)(int x_resized, int length_original, int length_resized);
int PrepareResizeBilinear(const int *input_shape, const int *output_shape, bool align_corners, int *y_bottoms,
int *y_tops, int *x_lefts, int *x_rights, float *y_bottom_weights, float *x_left_weights);
int PrepareResizeBilinear(const int *input_shape, const int *output_shape, CalculateOriginalCoordinate calculate,
int *y_bottoms, int *y_tops, int *x_lefts, int *x_rights, float *y_bottom_weights,
float *x_left_weights);
int ResizeBilinear(const float *input_data, float *output_data, const int *input_shape, const int *output_shape,
const int *y_bottoms, const int *y_tops, const int *x_lefts, const int *x_rights,
const float *y_bottom_weights, const float *x_left_weights, const int n_h_begin, const int n_h_end);
int ResizeBilinear2(const float *input_data, float *output_data, const int *input_shape, const int *output_shape,
const int *y_bottoms, const int *y_tops, const int *x_lefts, const int *x_rights,
const float *y_bottom_weights, const float *x_left_weights, float *line0, float *line1,
const int n_h_begin, const int n_h_end);
const float *y_bottom_weights, const float *x_left_weights, float *line0, float *line1,
const int n_h_begin, const int n_h_end);
int ResizeNearestNeighbor(const float *input_data, float *output_data, const int *input_shape, const int *output_shape,
bool align_corners, int tid, int thread_num);
CalculateOriginalCoordinate calculate, int coordinate_transform_mode, int tid,
int thread_num);
float CalculateAsymmetric(int x_resized, int length_original, int length_resized);
float CalculateAlignCorners(int x_resized, int length_original, int length_resized);
float CalculateHalfPixel(int x_resized, int length_original, int length_resized);
#ifdef __cplusplus
}
#endif

View File

@ -23,7 +23,7 @@ typedef struct ResizeParameter {
int method_;
int64_t new_height_;
int64_t new_width_;
bool align_corners_;
int coordinate_transform_mode_;
bool preserve_aspect_ratio_;
} ResizeParameter;
#endif // MINDSPORE_LITE_NNACL_RESIZE_PARAMETER_H_

View File

@ -24,14 +24,10 @@ enum ResizeMethod: byte {
}
enum CoordinateTransformMode: byte {
COMMON = 0,
HALF_PIXEL = 1,
PYTORCH_HALF_PIXEL = 2,
TF_HALF_PIXEL = 3,
TF_CROP_AND_RESIZE = 4,
ALIGN_CORNERS = 5,
ASYMMETRIC = 6,
ALIGN_CORNERS_WITH_HALF_PIEXL = 7
ASYMMETRIC = 0,
ALIGN_CORNERS = 1,
HALF_PIXEL = 2,
CROP_AND_RESIZE = 3
}
enum NearestMode : byte {

View File

@ -34,7 +34,7 @@ OpParameter *PopulateResizeParameter(const mindspore::lite::PrimitiveC *primitiv
resize_param->method_ = static_cast<int>(param->GetMethod());
resize_param->new_height_ = param->GetNewHeight();
resize_param->new_width_ = param->GetNewWidth();
resize_param->align_corners_ = param->GetAlignCorners();
resize_param->coordinate_transform_mode_ = param->GetCoordinateTransformMode();
resize_param->preserve_aspect_ratio_ = param->GetPreserveAspectRatio();
return reinterpret_cast<OpParameter *>(resize_param);
}

View File

@ -27,14 +27,17 @@ int Resize::GetFormat() const { return this->primitive_->value.AsResize()->forma
int Resize::GetMethod() const { return this->primitive_->value.AsResize()->method; }
int64_t Resize::GetNewHeight() const { return this->primitive_->value.AsResize()->newHeight; }
int64_t Resize::GetNewWidth() const { return this->primitive_->value.AsResize()->newWidth; }
bool Resize::GetAlignCorners() const { return this->primitive_->value.AsResize()->alignCorners; }
bool Resize::GetPreserveAspectRatio() const { return this->primitive_->value.AsResize()->preserveAspectRatio; }
int Resize::GetCoordinateTransformMode() const { return this->primitive_->value.AsResize()->coordinateTransformMode; }
void Resize::SetFormat(int format) { this->primitive_->value.AsResize()->format = (schema::Format)format; }
void Resize::SetMethod(int method) { this->primitive_->value.AsResize()->method = (schema::ResizeMethod)method; }
void Resize::SetNewHeight(int64_t new_height) { this->primitive_->value.AsResize()->newHeight = new_height; }
void Resize::SetNewWidth(int64_t new_width) { this->primitive_->value.AsResize()->newWidth = new_width; }
void Resize::SetAlignCorners(bool align_corners) { this->primitive_->value.AsResize()->alignCorners = align_corners; }
void Resize::SetCoordinateTransformMode(int coordinate_transform_mode) {
this->primitive_->value.AsResize()->coordinateTransformMode =
static_cast<schema::CoordinateTransformMode>(coordinate_transform_mode);
}
void Resize::SetPreserveAspectRatio(bool preserve_aspect_ratio) {
this->primitive_->value.AsResize()->preserveAspectRatio = preserve_aspect_ratio;
}
@ -71,7 +74,9 @@ int Resize::UnPackAttr(const Primitive &prim, const std::vector<AnfNodePtr> &inp
attr->newHeight = targetSize.at(0);
attr->newWidth = targetSize.at(1);
attr->alignCorners = GetValue<bool>(prim.GetAttr("align_corners"));
if (attr->alignCorners) {
attr->coordinateTransformMode = schema::CoordinateTransformMode_ALIGN_CORNERS;
}
this->primitive_->value.value = attr;
if (this->primitive_->value.value == nullptr) {
if (attr != nullptr) {
@ -89,7 +94,9 @@ int Resize::GetFormat() const { return this->primitive_->value_as_Resize()->form
int Resize::GetMethod() const { return this->primitive_->value_as_Resize()->method(); }
int64_t Resize::GetNewHeight() const { return this->primitive_->value_as_Resize()->newHeight(); }
int64_t Resize::GetNewWidth() const { return this->primitive_->value_as_Resize()->newWidth(); }
bool Resize::GetAlignCorners() const { return this->primitive_->value_as_Resize()->alignCorners(); }
int Resize::GetCoordinateTransformMode() const {
return this->primitive_->value_as_Resize()->coordinateTransformMode();
}
bool Resize::GetPreserveAspectRatio() const { return this->primitive_->value_as_Resize()->preserveAspectRatio(); }
int Resize::UnPackToFlatBuilder(const schema::Primitive *primitive, flatbuffers::FlatBufferBuilder *fbb) {
MS_ASSERT(nullptr != primitive);
@ -99,8 +106,10 @@ int Resize::UnPackToFlatBuilder(const schema::Primitive *primitive, flatbuffers:
MS_LOG(ERROR) << "value_as_Resize return nullptr";
return RET_ERROR;
}
auto val_offset = schema::CreateResize(*fbb, attr->format(), attr->method(), attr->newHeight(), attr->newWidth(),
attr->alignCorners(), attr->preserveAspectRatio());
auto val_offset =
schema::CreateResize(*fbb, attr->format(), attr->method(), attr->newHeight(), attr->newWidth(),
attr->alignCorners(), attr->preserveAspectRatio(), attr->coordinateTransformMode(),
attr->cubicCoeff(), attr->excludeOutside(), attr->extrapolationValue(), attr->nearestMode());
auto prim_offset = schema::CreatePrimitive(*fbb, schema::PrimitiveType_Resize, val_offset.o);
fbb->Finish(prim_offset);
return RET_OK;
@ -153,12 +162,12 @@ int Resize::InferShape(std::vector<lite::Tensor *> inputs_, std::vector<lite::Te
}
switch (shape_tensor->format()) {
case schema::Format_NCHW:
output_shape.push_back(data[2] * input->Height());
output_shape.push_back(data[3] * input->Width());
output_shape.push_back(data[2]);
output_shape.push_back(data[3]);
break;
case schema::Format_NHWC:
output_shape.push_back(data[1] * input->Height());
output_shape.push_back(data[2] * input->Width());
output_shape.push_back(data[1]);
output_shape.push_back(data[2]);
break;
default:
MS_LOG(INFO) << "Resize don't support tensor format.";

View File

@ -36,8 +36,8 @@ class Resize : public PrimitiveC {
void SetMethod(int method);
void SetNewHeight(int64_t new_height);
void SetNewWidth(int64_t new_width);
void SetAlignCorners(bool align_corners);
void SetPreserveAspectRatio(bool preserve_aspect_ratio);
void SetCoordinateTransformMode(int coordinate_transform_mode);
int UnPackAttr(const Primitive &prim, const std::vector<AnfNodePtr> &inputs);
#else
int UnPackToFlatBuilder(const schema::Primitive *primitive, flatbuffers::FlatBufferBuilder *fbb) override;
@ -47,8 +47,8 @@ class Resize : public PrimitiveC {
int GetMethod() const;
int64_t GetNewHeight() const;
int64_t GetNewWidth() const;
bool GetAlignCorners() const;
bool GetPreserveAspectRatio() const;
int GetCoordinateTransformMode() const;
};
} // namespace lite
} // namespace mindspore

View File

@ -42,7 +42,7 @@ int Shape::InferShape(std::vector<Tensor *> inputs_, std::vector<Tensor *> outpu
auto in_tensor = inputs_.front();
auto out_tensor = outputs_.front();
out_tensor->set_data_type(kNumberTypeInt32);
out_tensor->set_format(schema::Format::Format_NHWC);
out_tensor->set_format(in_tensor->format());
if (!infer_flag()) {
return RET_INFER_INVALID;
}

View File

@ -75,9 +75,9 @@ int ResizeBaseCPUKernel::CheckParameters() {
const_shape_ = true;
}
}
align_corners_ = parameter->align_corners_;
preserve_aspect_ratio = parameter->preserve_aspect_ratio_;
if (preserve_aspect_ratio) {
coordinate_transform_mode_ = parameter->coordinate_transform_mode_;
preserve_aspect_ratio_ = parameter->preserve_aspect_ratio_;
if (preserve_aspect_ratio_) {
MS_LOG(ERROR) << "Resize currently not support preserve_aspect_ratio true";
return RET_ERROR;
}

View File

@ -40,8 +40,8 @@ class ResizeBaseCPUKernel : public LiteKernel {
int method_ = 0;
int64_t new_height_ = 0;
int64_t new_width_ = 0;
bool align_corners_ = false;
bool preserve_aspect_ratio = false;
int coordinate_transform_mode_;
bool preserve_aspect_ratio_ = false;
bool const_shape_ = false;
private:

View File

@ -30,6 +30,21 @@ using mindspore::schema::PrimitiveType_Resize;
namespace mindspore::kernel {
int ResizeCPUKernel::Init() {
auto ret = ResizeBaseCPUKernel::Init();
switch (coordinate_transform_mode_) {
case schema::CoordinateTransformMode_ASYMMETRIC:
calculate_ = CalculateAsymmetric;
break;
case schema::CoordinateTransformMode_ALIGN_CORNERS:
calculate_ = CalculateAlignCorners;
break;
case schema::CoordinateTransformMode_HALF_PIXEL:
calculate_ = CalculateHalfPixel;
break;
default:
MS_LOG(ERROR) << "Do not support coordinate transform mode. Mode is"
<< schema::EnumNameCoordinateTransformMode(
static_cast<schema::CoordinateTransformMode>(coordinate_transform_mode_));
}
if (ret != RET_OK) {
return ret;
}
@ -55,8 +70,8 @@ int ResizeCPUKernel::ReSize() {
auto input = in_tensors_.at(0);
auto input_shape = input->shape();
ret = PrepareResizeBilinear(input_shape.data(), out_tensors_.at(0)->shape().data(), align_corners_, y_bottoms_,
y_tops_, x_lefts_, x_rights_, y_bottom_weights_, x_left_weights_);
ret = PrepareResizeBilinear(input_shape.data(), out_tensors_.at(0)->shape().data(), calculate_, y_bottoms_, y_tops_,
x_lefts_, x_rights_, y_bottom_weights_, x_left_weights_);
if (ret != RET_OK) {
FreeTmpBuffer();
}
@ -163,7 +178,6 @@ int ResizeCPUKernel::RunImpl(int task_id) {
if (context_ == nullptr) {
return RET_NULL_PTR;
}
int ret = 0;
switch (method_) {
case static_cast<int>(schema::ResizeMethod_LINEAR): {
@ -176,9 +190,10 @@ int ResizeCPUKernel::RunImpl(int task_id) {
int c = in_tensors_.at(0)->shape().at(3);
float *line0 = line_buffer_ + new_width_ * c * 2 * task_id;
float *line1 = line0 + new_width_ * c;
ret = ResizeBilinear2(input_data, output_data, input_shape.data(), out_tensors_.at(0)->shape().data(), y_bottoms_,
y_tops_, x_lefts_, x_rights_, y_bottom_weights_, x_left_weights_, line0, line1, n_h_begin,
n_h_end);
ret = ResizeBilinear(input_data, output_data, input_shape.data(), out_tensors_.at(0)->shape().data(), y_bottoms_,
y_tops_, x_lefts_, x_rights_, y_bottom_weights_, x_left_weights_, line0, line1, n_h_begin,
n_h_end);
break;
}
@ -195,7 +210,7 @@ int ResizeCPUKernel::RunImpl(int task_id) {
}
}
ret = ResizeNearestNeighbor(input_data, output_data, input_shape.data(), out_tensors_[0]->shape().data(),
align_corners_, task_id, context_->thread_num_);
calculate_, coordinate_transform_mode_, task_id, context_->thread_num_);
break;
}
case schema::ResizeMethod_UNKNOW:

View File

@ -51,6 +51,7 @@ class ResizeCPUKernel : public ResizeBaseCPUKernel {
float *y_bottom_weights_ = nullptr;
float *x_left_weights_ = nullptr;
float *line_buffer_ = nullptr;
CalculateOriginalCoordinate calculate_ = nullptr;
};
} // namespace mindspore::kernel

View File

@ -61,8 +61,8 @@ int UpsampleCPUKernel::ReSize() {
auto output = out_tensors().at(0);
MS_ASSERT(output);
auto output_shape = output->shape();
ret = PrepareResizeBilinear(input_shape.data(), output_shape.data(), align_corners_, y_bottoms_, y_tops_, x_lefts_,
x_rights_, y_bottom_weights_, x_left_weights_);
ret = PrepareResizeBilinear(input_shape.data(), output_shape.data(), CalculateAsymmetric, y_bottoms_, y_tops_,
x_lefts_, x_rights_, y_bottom_weights_, x_left_weights_);
if (ret != RET_OK) {
FreeTmpBuffer();
}
@ -104,16 +104,14 @@ int UpsampleCPUKernel::RunImpl(int task_id) {
int c = in_tensors_.at(0)->shape().at(3);
float *line0 = line_buffer_ + new_width_ * c * 2 * task_id;
float *line1 = line0 + new_width_ * c;
ret =
ResizeBilinear2(input_data, output_data, input_shape.data(), out_tensor->shape().data(), y_bottoms_, y_tops_,
x_lefts_, x_rights_, y_bottom_weights_, x_left_weights_, line0, line1, n_h_begin, n_h_end);
ret = ResizeBilinear(input_data, output_data, input_shape.data(), out_tensor->shape().data(), y_bottoms_, y_tops_,
x_lefts_, x_rights_, y_bottom_weights_, x_left_weights_, line0, line1, n_h_begin, n_h_end);
break;
}
case static_cast<int>(schema::ResizeMethod_NEAREST): {
align_corners_ = false;
ret = ResizeNearestNeighbor(input_data, output_data, input_shape.data(), out_tensor->shape().data(),
align_corners_, task_id, context_->thread_num_);
CalculateAsymmetric, coordinate_transform_mode_, task_id, context_->thread_num_);
break;
}
default: {

View File

@ -138,10 +138,11 @@ int ResizeInt8CPUKernel::CalRatio() {
auto out_height = out_tensor->Height();
resize_quant_arg_.ratio_x_ = ((1 << 10) * in_width + out_width / 2) / out_width;
resize_quant_arg_.ratio_y_ = ((1 << 10) * in_height + out_height / 2) / out_height;
if (align_corners_ && out_width > 1) {
bool align_corners = coordinate_transform_mode_ == 1;
if (align_corners && out_width > 1) {
resize_quant_arg_.ratio_x_ = ((1 << 10) * (in_width - 1) + (out_width - 1) / 2) / (out_width - 1);
}
if (align_corners_ && out_height > 1) {
if (align_corners && out_height > 1) {
resize_quant_arg_.ratio_y_ = ((1 << 10) * (in_height - 1) + (out_height - 1) / 2) / (out_height - 1);
}
return RET_OK;
@ -207,10 +208,11 @@ int ResizeInt8CPUKernel::CalFloatRatio() {
auto out_height = out_tensor->Height();
resize_float_quant_arg_.ratio_x_ = static_cast<float>(in_width) / out_width;
resize_float_quant_arg_.ratio_y_ = static_cast<float>(in_height) / out_height;
if (align_corners_ && out_width > 1) {
bool align_corners = coordinate_transform_mode_ == 1;
if (align_corners && out_width > 1) {
resize_float_quant_arg_.ratio_x_ = static_cast<float>(in_width - 1) / (out_width - 1);
}
if (align_corners_ && out_height > 1) {
if (align_corners && out_height > 1) {
resize_float_quant_arg_.ratio_y_ = static_cast<float>(in_height - 1) / (out_height - 1);
}
return RET_OK;
@ -335,14 +337,15 @@ int ResizeInt8CPUKernel::RunImpl(int task_id) {
case static_cast<int>(schema::ResizeMethod_NEAREST): {
bool same_zp = quant_in_->zp_ == quant_out_->zp_;
bool same_scale = abs(quant_out_->scale_ - quant_in_->scale_) < 1e-6;
bool align_corners = coordinate_transform_mode_ == 1;
if (same_zp && same_scale) {
ret =
ResizeNearestNeighborInt8Simple(input_data, output_data, input_shape.data(), out_tensors_[0]->shape().data(),
align_corners_, task_id, context_->thread_num_);
align_corners, task_id, context_->thread_num_);
} else {
ret =
ResizeNearestNeighborInt8(input_data, output_data, input_shape.data(), out_tensors_[0]->shape().data(),
align_corners_, multiplier_, quant_in_, quant_out_, task_id, context_->thread_num_);
align_corners, multiplier_, quant_in_, quant_out_, task_id, context_->thread_num_);
}
break;
}

View File

@ -50,7 +50,7 @@ int ResizeNPUKernel::SetNPUInputs(const std::vector<lite::Tensor *> &inputs, con
MS_LOG(ERROR) << " op is nullptr.";
return RET_ERROR;
}
op->set_attr_align_corners(resize_parameter_->align_corners_);
op->set_attr_align_corners(resize_parameter_->coordinate_transform_mode_ == 1);
op->set_input_x(*npu_inputs[0]);
op->set_input_size(*out_size);
op->set_attr_half_pixel_centers(resize_parameter_->preserve_aspect_ratio_);
@ -61,7 +61,7 @@ int ResizeNPUKernel::SetNPUInputs(const std::vector<lite::Tensor *> &inputs, con
MS_LOG(ERROR) << " op is nullptr.";
return RET_ERROR;
}
op->set_attr_align_corners(resize_parameter_->align_corners_);
op->set_attr_align_corners(resize_parameter_->coordinate_transform_mode_ == 1);
op->set_input_x(*npu_inputs[0]);
op->set_input_size(*out_size);
op_ = op;

View File

@ -53,7 +53,7 @@ int ResizeOpenCLKernel::CheckSpecs() {
int ResizeOpenCLKernel::Prepare() {
auto resize_param = reinterpret_cast<ResizeParameter *>(op_parameter_);
alignCorner = resize_param->align_corners_;
alignCorner = resize_param->coordinate_transform_mode_ == 1;
preserveAspectRatio = resize_param->preserve_aspect_ratio_;
auto in_shape = in_tensors_[0]->shape();
auto out_shape = out_tensors_[0]->shape();

View File

@ -71,7 +71,9 @@ void TestResizeBilinearInt8::Prepare(const std::vector<int> &in_shape, const std
param_.method_ = static_cast<int>(schema::ResizeMethod_LINEAR);
param_.new_width_ = out_shape[2];
param_.new_height_ = out_shape[1];
param_.align_corners_ = align_corners;
if (align_corners) {
param_.coordinate_transform_mode_ = 1;
}
creator_ = lite::KernelRegistry::GetInstance()->GetCreator(desc_);

View File

@ -66,7 +66,9 @@ void TestResizeNearestNeighborInt8::Prepare(const std::vector<int> &in_shape, co
param_.method_ = static_cast<int>(schema::ResizeMethod_NEAREST);
param_.new_width_ = out_shape[2];
param_.new_height_ = out_shape[1];
param_.align_corners_ = align_corners;
if (align_corners) {
param_.coordinate_transform_mode_ = 1;
}
creator_ = lite::KernelRegistry::GetInstance()->GetCreator(desc_);

View File

@ -26,7 +26,9 @@ OpParameter *CreateParameter(schema::ResizeMethod method, int new_height, int ne
auto *param = test::CreateParameter<ResizeParameter>(schema::PrimitiveType_Resize);
param->new_height_ = new_height;
param->new_width_ = new_width;
param->align_corners_ = align_corners;
if (align_corners) {
param->coordinate_transform_mode_ = 1;
}
param->method_ = method;
param->preserve_aspect_ratio_ = false;
return reinterpret_cast<OpParameter *>(param);

View File

@ -45,8 +45,8 @@ PrimitiveC *CaffeInterpParser::ParseLitePrimitive(const caffe::LayerParameter &p
}
attr->newWidth = width;
}
attr->alignCorners = true;
attr->method = schema::ResizeMethod_LINEAR;
attr->coordinateTransformMode = schema::CoordinateTransformMode_ALIGN_CORNERS;
auto primitive = std::make_unique<schema::PrimitiveT>();
primitive->value.type = schema::PrimitiveType_Resize;
primitive->value.value = attr.release();

View File

@ -36,17 +36,19 @@ lite::PrimitiveC *OnnxResizeParser::ParseLitePrimitive(const onnx::GraphProto &o
for (const auto &onnx_node_attr : onnx_node.attribute()) {
const auto &attribute_name = onnx_node_attr.name();
if (attribute_name == "coordinate_transformation_mode") {
attr->coordinateTransformMode = [&]() {
std::map<std::string, schema::CoordinateTransformMode> transform_map = {
{"half_pixel", schema::CoordinateTransformMode_HALF_PIXEL},
{"pytorch_half_pixel", schema::CoordinateTransformMode_PYTORCH_HALF_PIXEL},
{"align_corners", schema::CoordinateTransformMode_ALIGN_CORNERS},
{"asymmetric", schema::CoordinateTransformMode_ASYMMETRIC},
{"tf_half_pixel_for_nn", schema::CoordinateTransformMode_TF_HALF_PIXEL},
{"tf_crop_and_resize", schema::CoordinateTransformMode_TF_CROP_AND_RESIZE},
};
return transform_map[onnx_node_attr.s()];
}();
std::map<std::string, schema::CoordinateTransformMode> transform_map = {
{"half_pixel", schema::CoordinateTransformMode_HALF_PIXEL},
{"pytorch_half_pixel", schema::CoordinateTransformMode_HALF_PIXEL},
{"align_corners", schema::CoordinateTransformMode_ALIGN_CORNERS},
{"asymmetric", schema::CoordinateTransformMode_ASYMMETRIC},
{"tf_crop_and_resize", schema::CoordinateTransformMode_CROP_AND_RESIZE},
};
if (transform_map.find(onnx_node_attr.s()) != transform_map.end()) {
attr->coordinateTransformMode = transform_map[onnx_node_attr.s()];
} else {
MS_LOG(ERROR) << "Unsupport coordinate transform mode: " << attribute_name;
return nullptr;
}
} else if (attribute_name == "cubic_coeff_a") {
attr->cubicCoeff = onnx_node_attr.f();
} else if (attribute_name == "exclude_outside") {

View File

@ -39,6 +39,7 @@ lite::PrimitiveC *OnnxUpsampleParser::ParseLitePrimitive(const onnx::GraphProto
attr->method = onnx_node_attr.s() == "nearest" ? schema::ResizeMethod_NEAREST : schema::ResizeMethod_LINEAR;
}
}
attr->coordinateTransformMode = schema::CoordinateTransformMode_ASYMMETRIC;
auto primitive = std::make_unique<schema::PrimitiveT>();
if (primitive == nullptr) {
MS_LOG(ERROR) << "new primitive failed";

View File

@ -47,7 +47,11 @@ STATUS TFResizeParser::Parse(const tensorflow::NodeDef &tf_op,
MS_LOG(ERROR) << "The align_corners attr should be specified";
return RET_ERROR;
}
attr->alignCorners = attr_value.b();
if (attr_value.b()) {
attr->coordinateTransformMode = schema::CoordinateTransformMode_ALIGN_CORNERS;
} else {
attr->coordinateTransformMode = schema::CoordinateTransformMode_ASYMMETRIC;
}
if (tf_op.op() == "ResizeBilinear") {
attr->method = schema::ResizeMethod_LINEAR;
} else if (tf_op.op() == "ResizeNearestNeighbor") {

View File

@ -36,7 +36,7 @@ PrimitiveC *TfliteResizeParser::ParseLitePrimitive(const std::unique_ptr<tflite:
MS_LOG(ERROR) << "new op failed";
return nullptr;
}
attr->coordinateTransformMode = schema::CoordinateTransformMode_COMMON;
attr->coordinateTransformMode = schema::CoordinateTransformMode_ASYMMETRIC;
auto tflite_op_type = (tflite_model->operator_codes[tflite_op->opcode_index])->builtin_code;
if (tflite_op_type == tflite::BuiltinOperator_RESIZE_BILINEAR) {
MS_LOG(DEBUG) << "parse TfliteResizeBilinearParser";
@ -46,13 +46,11 @@ PrimitiveC *TfliteResizeParser::ParseLitePrimitive(const std::unique_ptr<tflite:
return nullptr;
}
if (tfliteAttr->align_corners) {
attr->alignCorners = tfliteAttr->align_corners;
attr->coordinateTransformMode = schema::CoordinateTransformMode_ALIGN_CORNERS;
}
if (tfliteAttr->half_pixel_centers) {
attr->coordinateTransformMode = (attr->coordinateTransformMode == schema::CoordinateTransformMode_COMMON
? schema::CoordinateTransformMode_TF_HALF_PIXEL
: schema::CoordinateTransformMode_ALIGN_CORNERS_WITH_HALF_PIEXL);
MS_LOG(ERROR) << "Does not support half pixel centers";
return nullptr;
}
attr->method = schema::ResizeMethod_LINEAR;
} else if (tflite_op_type == tflite::BuiltinOperator_RESIZE_NEAREST_NEIGHBOR) {
@ -63,13 +61,11 @@ PrimitiveC *TfliteResizeParser::ParseLitePrimitive(const std::unique_ptr<tflite:
return nullptr;
}
if (tfliteAttr->align_corners) {
attr->alignCorners = tfliteAttr->align_corners;
attr->coordinateTransformMode = schema::CoordinateTransformMode_ALIGN_CORNERS;
}
if (tfliteAttr->half_pixel_centers) {
attr->coordinateTransformMode = (attr->coordinateTransformMode == schema::CoordinateTransformMode_COMMON
? schema::CoordinateTransformMode_TF_HALF_PIXEL
: schema::CoordinateTransformMode_ALIGN_CORNERS_WITH_HALF_PIEXL);
MS_LOG(ERROR) << "Does not support half pixel centers";
return nullptr;
}
attr->method = schema::ResizeMethod_NEAREST;
attr->nearestMode = schema::NearestMode_NORMAL;

View File

@ -326,12 +326,18 @@ STATUS OnnxInputAdjustOpPass::AdjustResize(const CNodePtr &cnode) {
return lite::RET_ERROR;
}
auto attr = reinterpret_cast<schema::ResizeT *>(value);
if (cnode->inputs().size() > 3 &&
attr->coordinateTransformMode == schema::CoordinateTransformMode_TF_CROP_AND_RESIZE) {
if (cnode->inputs().size() > 3 && attr->coordinateTransformMode == schema::CoordinateTransformMode_CROP_AND_RESIZE) {
auto new_resize_inputs = cnode->inputs();
new_resize_inputs.erase(new_resize_inputs.begin() + 1);
cnode->set_inputs(new_resize_inputs);
}
if (cnode->inputs().size() > 3 && attr->coordinateTransformMode == schema::CoordinateTransformMode_HALF_PIXEL) {
std::vector<AnfNodePtr> new_resize_inputs;
new_resize_inputs.push_back(cnode->inputs()[0]);
new_resize_inputs.push_back(cnode->inputs()[1]);
new_resize_inputs.push_back(cnode->inputs()[4]);
cnode->set_inputs(new_resize_inputs);
}
return lite::RET_OK;
}
@ -588,6 +594,8 @@ bool OnnxInputAdjustOpPass::Run(const FuncGraphPtr &func_graph) {
status = AdjustCast(cnode);
} else if (type == schema::PrimitiveType_Transpose) {
status = ReplaceTransposeWithGraphInput(func_graph, cnode);
} else if (type == schema::PrimitiveType_Resize) {
status = AdjustResize(cnode);
}
if (status != lite::RET_OK && status != lite::RET_NO_CHANGE) {
MS_LOG(ERROR) << "adjust input pass is failed.";