update output size calculation for resize (#2366)

* change how output size is calculated for resize op

* add tests for ver 10 resize
This commit is contained in:
Ashwini Khade 2019-11-12 10:06:17 -08:00 committed by GitHub
parent 192dcfaa8e
commit 437772d5bc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 276 additions and 78 deletions

View file

@ -287,6 +287,8 @@ void UpsampleBilinear(int64_t batch_size,
int64_t num_channels,
int64_t input_height,
int64_t input_width,
int64_t output_height,
int64_t output_width,
float height_scale,
float width_scale,
const std::vector<float>& roi,
@ -296,8 +298,6 @@ void UpsampleBilinear(int64_t batch_size,
T* Ydata,
AllocatorPtr& alloc,
GetOriginalCoordinateFunc get_original_coordinate) {
auto output_width = static_cast<int64_t>(input_width * width_scale);
auto output_height = static_cast<int64_t>(input_height * height_scale);
std::vector<float> y_original;
std::vector<float> x_original;
@ -435,7 +435,7 @@ float CubicInterpolation1D(const T* Xdata,
float result = 0;
for (int i = 0, j = -1; i < static_cast<int>(CubicModeGridLength); i++, j++) {
auto orig_data = GetDataForCoordinate(Xdata, x + j, y, input_height, input_width);
result += coeff_array[i]/coeff_sum * orig_data;
result += coeff_array[i] / coeff_sum * orig_data;
}
cache[grid_start_pos] = result;
@ -448,6 +448,8 @@ void ResizeBiCubic(
int64_t num_channels,
int64_t input_height,
int64_t input_width,
int64_t output_height,
int64_t output_width,
float height_scale,
float width_scale,
float cubic_coeff_a,
@ -458,9 +460,6 @@ void ResizeBiCubic(
const T* Xdata,
T* Ydata,
GetOriginalCoordinateFunc get_original_coordinate) {
auto output_width = static_cast<int64_t>(input_width * width_scale);
auto output_height = static_cast<int64_t>(input_height * height_scale);
std::vector<float> y_original;
std::vector<float> x_original;
std::unordered_map<float, std::array<float, CubicModeGridLength>> cubic_coeffs;
@ -582,11 +581,17 @@ void ResizeBiCubic(
}
template <typename T>
Status Upsample<T>::BaseCompute(OpKernelContext* context, const std::vector<float>& scales, const std::vector<float>& roi) const {
Status Upsample<T>::BaseCompute(OpKernelContext* context,
const std::vector<float>& roi,
const std::vector<float>& scales,
const std::vector<int64_t>& output_dims) const {
const auto* X = context->Input<Tensor>(0);
ORT_ENFORCE(X != nullptr);
const std::vector<int64_t>& dims = X->Shape().GetDims();
ORT_ENFORCE(output_dims.size() == dims.size(), "Rank of input and output tensor should be same.");
Tensor* Y = context->Output(0, output_dims);
if (dims.size() != scales.size())
return Status(ONNXRUNTIME, INVALID_ARGUMENT,
is_resize ? "Resize: input tensor's dimension does not match the scales."
@ -597,14 +602,9 @@ Status Upsample<T>::BaseCompute(OpKernelContext* context, const std::vector<floa
"Resize: size of roi array should be 2 * N where N is the rank of input tensor X.");
bool no_scale = true;
std::vector<int64_t> Y_dims;
Y_dims.reserve(dims.size());
for (std::size_t i = 0; i < dims.size(); i++) {
int64_t dim_y = static_cast<int64_t>(scales[i] * dims[i]);
if (no_scale && dim_y != dims[i]) no_scale = false;
Y_dims.push_back(dim_y);
for (std::size_t i = 0, end = output_dims.size(); i < end; i++) {
if (no_scale && output_dims[i] != dims[i]) no_scale = false;
}
Tensor* Y = context->Output(0, Y_dims);
if (no_scale) {
memcpy(Y->MutableDataRaw(), X->DataRaw(), Y->SizeInBytes());
@ -632,10 +632,12 @@ Status Upsample<T>::BaseCompute(OpKernelContext* context, const std::vector<floa
const int64_t num_channels = is_2D ? 1 : dims[1];
const int64_t input_height = is_2D ? dims[0] : dims[2];
const int64_t input_width = is_2D ? dims[1] : dims[3];
const int64_t output_height = is_2D ? output_dims[0] : output_dims[2];
const int64_t output_width = is_2D ? output_dims[1] : output_dims[3];
AllocatorPtr alloc;
ORT_RETURN_IF_ERROR(context->GetTempSpaceAllocator(&alloc));
UpsampleBilinear(batch_size, num_channels, input_height, input_width,
UpsampleBilinear(batch_size, num_channels, input_height, input_width, output_height, output_width,
is_2D ? scales[0] : scales[2], is_2D ? scales[1] : scales[3], roi,
use_extrapolation_, extrapolation_value_, X->template Data<T>(),
Y->template MutableData<T>(), alloc, get_original_coordinate_);
@ -647,8 +649,10 @@ Status Upsample<T>::BaseCompute(OpKernelContext* context, const std::vector<floa
const int64_t num_channels = is_2D ? 1 : dims[1];
const int64_t input_height = is_2D ? dims[0] : dims[2];
const int64_t input_width = is_2D ? dims[1] : dims[3];
const int64_t output_height = is_2D ? output_dims[0] : output_dims[2];
const int64_t output_width = is_2D ? output_dims[1] : output_dims[3];
ResizeBiCubic(batch_size, num_channels, input_height, input_width,
ResizeBiCubic(batch_size, num_channels, input_height, input_width, output_height, output_width,
is_2D ? scales[0] : scales[2], is_2D ? scales[1] : scales[3], cubic_coeff_a_, use_extrapolation_,
extrapolation_value_, exclude_outside_, roi, X->template Data<float>(), Y->template MutableData<float>(),
get_original_coordinate_);
@ -664,36 +668,7 @@ Status Upsample<T>::Compute(OpKernelContext* context) const {
const auto* X = context->Input<Tensor>(0);
ORT_ENFORCE(X != nullptr);
if (OpKernel::Node().InputDefs().size() == 1) {
std::vector<float> roi_array(X->Shape().GetDims().size() * 2, 0.0f);
return BaseCompute(context, scales_, roi_array);
}
// Both Roi and Scales are constant inputs
if (roi_cached_ && scales_cached_) {
return BaseCompute(context, scales_, roi_);
}
// Get scales data
std::vector<float> scales_array;
const std::vector<float>* scales_ptr = scales_cached_ ? &scales_ : &scales_array;
if (!scales_cached_) {
const auto* scales = context->Input<Tensor>(scales_input_idx_);
const auto* sizes = context->Input<Tensor>(sizes_input_idx_);
ORT_ENFORCE(scales != nullptr);
// User must provide either the scales or sizes
if (scales->Shape().Size() == 0) {
ORT_ENFORCE(sizes != nullptr && sizes->Shape().Size() != 0,
"Either scales input or sizes input must be provided and the number of elements of scales or sizes should be the same as the rank of the input.");
ParseScalesDataFromSizes(sizes, X->Shape().GetDims(), scales_array);
} else {
ORT_ENFORCE(sizes == nullptr);
ParseScalesData(scales, scales_array);
}
}
std::vector<int64_t> output_dims(X->Shape().GetDims().size());
// Get roi data
// Initialize the roi array to all zeros as this will be the most common case
@ -714,6 +689,47 @@ Status Upsample<T>::Compute(OpKernelContext* context) const {
}
}
return BaseCompute(context, *scales_ptr, *roi_ptr);
if (OpKernel::Node().InputDefs().size() == 1) {
// Compute output shape from scales and input dims
ComputeOutputShape(scales_, X->Shape().GetDims(), output_dims);
return BaseCompute(context, *roi_ptr, scales_, output_dims);
}
const auto* scales = context->Input<Tensor>(scales_input_idx_);
const auto* sizes = context->Input<Tensor>(sizes_input_idx_);
ORT_ENFORCE(scales != nullptr);
if (scales_cached_) {
ORT_ENFORCE(sizes == nullptr, "Only one of scales or sizes must be provided as input.");
// Compute output shape from scales and input dims
ComputeOutputShape(scales_, X->Shape().GetDims(), output_dims);
return BaseCompute(context, *roi_ptr, scales_, output_dims);
}
// Get scales data
std::vector<float> scales_array(X->Shape().GetDims().size());
if (scales != nullptr && scales->Shape().Size() != 0) {
ORT_ENFORCE(sizes == nullptr,
"Only one of scales or sizes must be provided as input.");
ParseScalesData(scales, scales_array);
// Compute output shape from scales and input dims
ComputeOutputShape(scales_array, X->Shape().GetDims(), output_dims);
} else {
ORT_ENFORCE(sizes != nullptr && sizes->Shape().Size() != 0,
"Either scales or sizes MUST be provided as input.");
// When sizes input is available directly populate it into the output_dims array.
memcpy(output_dims.data(), sizes->template Data<int64_t>(), sizes->Shape().Size() * sizeof(int64_t));
ORT_ENFORCE(X->Shape().GetDims().size() == output_dims.size(),
"Resize: input tensor's rank does not match the output tensor's rank.");
ParseScalesDataFromOutputSize(output_dims, X->Shape().GetDims(), scales_array);
}
return BaseCompute(context, *roi_ptr, scales_array, output_dims);
}
} // namespace onnxruntime

View file

@ -216,7 +216,7 @@ class UpsampleBase {
if (UpsampleMode::LINEAR == mode || UpsampleMode::CUBIC == mode) {
ORT_ENFORCE(scales.size() == 2 || (scales.size() == 4 && scales[0] == 1 && scales[1] == 1),
"'Linear' mode only support 2-D inputs ('Bilinear') or 4-D inputs "
"'Linear' mode and 'Cubic' mode only support 2-D inputs ('Bilinear', 'Bicubic') or 4-D inputs "
"with the corresponding outermost 2 scale values being 1 in the ",
is_resize ? "Resize operator" : "Upsample operator");
}
@ -233,18 +233,6 @@ class UpsampleBase {
ScalesValidation(scales, mode_);
}
void ParseScalesDataFromSizes(const Tensor* sizes, const std::vector<int64_t>& dims, std::vector<float>& scales) const {
const auto* sizes_data = sizes->template Data<int64_t>();
int64_t scales_size = sizes->Shape().Size();
if (scales.empty()) {
scales.resize(scales_size);
}
for (size_t i = 0, end = dims.size(); i < end; ++i) {
scales[i] = static_cast<float>(sizes_data[i]) / static_cast<float>(dims[i]);
}
ScalesValidation(scales, mode_);
}
void ParseRoiData(const Tensor* roi, std::vector<float>& roi_array) const {
int64_t roi_size = roi->Shape().Size();
if (roi_size > 0) {
@ -252,6 +240,23 @@ class UpsampleBase {
memcpy(roi_array.data(), roi->template Data<float>(), roi_size * sizeof(float));
}
}
void ParseScalesDataFromOutputSize(const std::vector<int64_t>& output_dims,
const std::vector<int64_t>& intput_dims,
std::vector<float>& scales) const {
for (size_t i = 0, end = intput_dims.size(); i < end; ++i) {
scales[i] = static_cast<float>(output_dims[i]) / static_cast<float>(intput_dims[i]);
}
ScalesValidation(scales, mode_);
}
void ComputeOutputShape(const std::vector<float>& scales,
const std::vector<int64_t>& input_dims,
std::vector<int64_t>& output_dims) const {
for (std::size_t i = 0; i < input_dims.size(); i++) {
output_dims[i] = static_cast<int64_t>(scales[i] * input_dims[i]);
}
}
};
template <typename T>
@ -262,7 +267,8 @@ class Upsample : public UpsampleBase, public OpKernel {
Status Compute(OpKernelContext* context) const override;
Status BaseCompute(OpKernelContext* context, const std::vector<float>& scales, const std::vector<float>& roi) const;
Status BaseCompute(OpKernelContext* context, const std::vector<float>& roi, const std::vector<float>& scales,
const std::vector<int64_t>& output_dims) const;
};
} // namespace onnxruntime

View file

@ -61,7 +61,7 @@ TEST(ResizeOpTest, ResizeOpLinearDownSampleTest_tf_crop_and_resize_with_extrapol
12.4f, 10.f, 10.0f,
10.0f, 10.0f, 10.0f};
test.AddOutput<float>("Y", {N, C, (int64_t)(H * scales[2]), (int64_t)(W * scales[3])}, Y);
test.AddOutput<float>("Y", {N, C, static_cast<int64_t>(H * scales[2]), static_cast<int64_t>(W * scales[3])}, Y);
test.Run();
}
@ -83,7 +83,7 @@ TEST(ResizeOpTest, ResizeOpLineartDownSampleTest_4DBilinear) {
std::vector<float> Y = {2.66666651f, 4.3333331f};
test.AddOutput<float>("Y", {N, C, (int64_t)(H * scales[2]), (int64_t)(W * scales[3])}, Y);
test.AddOutput<float>("Y", {N, C, static_cast<int64_t>(H * scales[2]), static_cast<int64_t>(W * scales[3])}, Y);
test.Run();
}
@ -106,7 +106,7 @@ TEST(ResizeOpTest, ResizeOpLineartDownSampleTest_4DBilinear_align_corners) {
std::vector<float> Y = {1.0f, 4.0f};
test.AddOutput<float>("Y", {N, C, (int64_t)(H * scales[2]), (int64_t)(W * scales[3])}, Y);
test.AddOutput<float>("Y", {N, C, static_cast<int64_t>(H * scales[2]), static_cast<int64_t>(W * scales[3])}, Y);
test.Run();
}
@ -169,7 +169,7 @@ TEST(ResizeOpTest, ResizeOpLineartUpSampleTest_4DBilinear_asymmetric) {
7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 11.0f, 11.0f, 11.0f,
7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 11.0f, 11.0f, 11.0f};
test.AddOutput<float>("Y", {N, C, (int64_t)(H * scales[2]), (int64_t)(W * scales[3])}, Y);
test.AddOutput<float>("Y", {N, C, static_cast<int64_t>(H * scales[2]), static_cast<int64_t>(W * scales[3])}, Y);
test.Run();
}
@ -194,7 +194,7 @@ TEST(ResizeOpTest, ResizeOpLineartUpSampleTest_2DBilinear_align_corners) {
3.0f, 3.4761906f, 3.952381f, 4.428571f, 4.904762f, 5.3809524f, 5.857143f, 6.33333f,
4.0f, 4.5714290f, 5.142857f, 5.714286f, 6.285714f, 6.8571430f, 7.428571f, 8.0f};
test.AddOutput<float>("Y", {(int64_t)(H * scales[0]), (int64_t)(W * scales[1])}, Y);
test.AddOutput<float>("Y", {static_cast<int64_t>(H * scales[0]), static_cast<int64_t>(W * scales[1])}, Y);
test.Run();
}
@ -243,7 +243,7 @@ TEST(ResizeOpTest, ResizeOpNearestDownSampleTest) {
std::vector<float> Y = {1.0f, 3.0f};
test.AddOutput<float>("Y", {N, C, (int64_t)(H * scales[2]), (int64_t)(W * scales[3])}, Y);
test.AddOutput<float>("Y", {N, C, static_cast<int64_t>(H * scales[2]), static_cast<int64_t>(W * scales[3])}, Y);
test.Run();
}
@ -325,7 +325,7 @@ TEST(ResizeOpTest, ResizeOpNearestDownSampleTest_tf_crop_and_resize_with_extrapo
11.0f, 10.f, 10.0f,
10.0f, 10.0f, 10.0f};
test.AddOutput<float>("Y", {N, C, (int64_t)(H * scales[2]), (int64_t)(W * scales[3])}, Y);
test.AddOutput<float>("Y", {N, C, static_cast<int64_t>(H * scales[2]), static_cast<int64_t>(W * scales[3])}, Y);
test.Run();
}
@ -348,7 +348,7 @@ TEST(ResizeOpTest, ResizeOpNearestUpSampleTest) {
3.0f, 3.0f, 3.0f, 4.0f, 4.0f, 4.0f,
3.0f, 3.0f, 3.0f, 4.0f, 4.0f, 4.0f};
test.AddOutput<float>("Y", {N, C, (int64_t)(H * scales[2]), (int64_t)(W * scales[3])}, Y);
test.AddOutput<float>("Y", {N, C, static_cast<int64_t>(H * scales[2]), static_cast<int64_t>(W * scales[3])}, Y);
test.Run();
}
@ -411,7 +411,7 @@ TEST(ResizeOpTest, ResizeOpNearestUpSample_Floor_Align_Corners) {
9.0f, 9.0f, 9.0f, 10.0f, 10.0f, 11.0f, 11.0f, 12.0f,
13.0f, 13.0f, 13.0f, 14.0f, 14.0f, 15.0f, 15.0f, 16.0f};
test.AddOutput<float>("Y", {N, C, (int64_t)(H * scales[2]), (int64_t)(W * scales[3])}, Y);
test.AddOutput<float>("Y", {N, C, static_cast<int64_t>(H * scales[2]), static_cast<int64_t>(W * scales[3])}, Y);
test.Run();
}
@ -437,7 +437,7 @@ TEST(ResizeOpTest, ResizeOpCubicDownSampleTest) {
6.71143f, 8.02148f, 9.32275f,
11.9165f, 13.2266f, 14.5278f};
test.AddOutput<float>("Y", {N, C, (int64_t)(H * scales[2]), (int64_t)(W * scales[3])}, Y);
test.AddOutput<float>("Y", {N, C, static_cast<int64_t>(H * scales[2]), static_cast<int64_t>(W * scales[3])}, Y);
test.Run();
}
@ -467,7 +467,7 @@ TEST(ResizeOpTest, ResizeOpLineartDownSampleTest_exclude_outside) {
6.57363f, 7.875f, 9.21884f,
11.949f, 13.2503f, 14.5942f};
test.AddOutput<float>("Y", {(int64_t)(H * scales[0]), (int64_t)(W * scales[1])}, Y);
test.AddOutput<float>("Y", {static_cast<int64_t>(H * scales[0]), static_cast<int64_t>(W * scales[1])}, Y);
test.Run();
}
@ -494,7 +494,7 @@ TEST(ResizeOpTest, ResizeOpCubicDownSampleTest_coeff) {
6.57715f, 7.875f, 9.19824f,
11.8701f, 13.168f, 14.4912f,};
test.AddOutput<float>("Y", {N, C, (int64_t)(H * scales[2]), (int64_t)(W * scales[3])}, Y);
test.AddOutput<float>("Y", {N, C, static_cast<int64_t>(H * scales[2]), static_cast<int64_t>(W * scales[3])}, Y);
test.Run();
}
@ -521,7 +521,7 @@ TEST(ResizeOpTest, ResizeOpCubicDownSampleTest_with_roi) {
8.752f, 9.14275f, 9.496f,
9.76f, 10.1507f, 10.504f};
test.AddOutput<float>("Y", {N, C, (int64_t)(H * scales[2]), (int64_t)(W * scales[3])}, Y);
test.AddOutput<float>("Y", {N, C, static_cast<int64_t>(H * scales[2]), static_cast<int64_t>(W * scales[3])}, Y);
test.Run();
}
@ -548,7 +548,7 @@ TEST(ResizeOpTest, ResizeOpCubicDownSampleTest_asymmetric) {
6.1875f, 7.48438f, 8.78125f,
11.375f, 12.6719f, 13.9688f};
test.AddOutput<float>("Y", {N, C, (int64_t)(H * scales[2]), (int64_t)(W * scales[3])}, Y);
test.AddOutput<float>("Y", {N, C, static_cast<int64_t>(H * scales[2]), static_cast<int64_t>(W * scales[3])}, Y);
test.Run();
}
@ -580,7 +580,7 @@ TEST(ResizeOpTest, ResizeOpCubicUpSampleTest) {
13.0f, 13.4063f, 14.0f, 14.5f, 15.0f, 15.5938f, 16.0f, 16.0938f,
13.375f, 13.7813f, 14.375f, 14.875f, 15.375f, 15.9688f, 16.375f, 16.4688f,};
test.AddOutput<float>("Y", {N, C, (int64_t)(H * scales[2]), (int64_t)(W * scales[3])}, Y);
test.AddOutput<float>("Y", {N, C, static_cast<int64_t>(H * scales[2]), static_cast<int64_t>(W * scales[3])}, Y);
test.Run();
}
@ -661,7 +661,183 @@ TEST(ResizeOpTest, ResizeOpCubicUpSampleTest_tf_half_pixel_for_nn) {
13.6133f, 14.0898f, 14.7188f, 15.125f, 15.7539f, 16.2305f, 16.5273f, 16.457f,
13.332f, 13.8086f, 14.4375f, 14.8438f, 15.4727f, 15.9492f, 16.2461f, 16.1758f,};
test.AddOutput<float>("Y", {N, C, (int64_t)(H * scales[2]), (int64_t)(W * scales[3])}, Y);
test.AddOutput<float>("Y", {N, C, static_cast<int64_t>(H * scales[2]), static_cast<int64_t>(W * scales[3])}, Y);
test.Run();
}
TEST(ResizeOpTest, ResizeOpLineartDownSampleTest_4DBilinear_Ver10) {
OpTester test("Resize", 10);
std::vector<float> scales{1.0f, 1.0f, 0.6f, 0.6f};
test.AddAttribute("mode", "linear");
const int64_t N = 1, C = 1, H = 2, W = 4;
std::vector<float> X = {
1.0f, 2.0f, 3.0f, 4.0f,
5.0f, 6.0f, 7.0f, 8.0f};
test.AddInput<float>("X", {N, C, H, W}, X);
test.AddInput<float>("scales", {4}, scales);
std::vector<float> Y = {1.0f, 2.66666651f};
test.AddOutput<float>("Y", {N, C, static_cast<int64_t>(H * scales[2]), static_cast<int64_t>(W * scales[3])}, Y);
test.Run();
}
TEST(ResizeOpTest, ResizeOpLineartDownSampleTest_2DBilinear_Ver10) {
OpTester test("Resize", 10);
std::vector<float> scales{0.6f, 0.6f};
test.AddAttribute("mode", "linear");
const int64_t H = 2, W = 4;
std::vector<float> X = {
1.0f, 2.0f, 3.0f, 4.0f,
5.0f, 6.0f, 7.0f, 8.0f};
test.AddInput<float>("X", {H, W}, X);
test.AddInput<float>("scales", {2}, scales);
std::vector<float> Y = {1.0f, 2.66666651f};
test.AddOutput<float>("Y", {static_cast<int64_t>(H * scales[0]), static_cast<int64_t>(W * scales[1])}, Y);
test.Run();
}
TEST(ResizeOpTest, ResizeOpLineartUpSampleTest_4DBilinear_Ver10) {
OpTester test("Resize", 10);
std::vector<float> scales{1.0f, 1.0f, 2.0f, 4.0f};
test.AddAttribute("mode", "linear");
const int64_t N = 2, C = 1, H = 2, W = 2;
std::vector<float> X = {1.0f, 3.0f,
4.0f, 8.0f,
6.0f, 2.0f,
7.0f, 11.0f};
test.AddInput<float>("X", {N, C, H, W}, X);
test.AddInput<float>("scales", {4}, scales);
std::vector<float> Y = {
1.0f, 1.5f, 2.0f, 2.5f, 3.0f, 3.0f, 3.0f, 3.0f,
2.5f, 3.25f, 4.0f, 4.75f, 5.5f, 5.5f, 5.5f, 5.5f,
4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 8.0f, 8.0f, 8.0f,
4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 8.0f, 8.0f, 8.0f,
6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 2.0f, 2.0f, 2.0f,
6.5f, 6.5f, 6.5f, 6.5f, 6.5f, 6.5f, 6.5f, 6.5f,
7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 11.0f, 11.0f, 11.0f,
7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 11.0f, 11.0f, 11.0f};
test.AddOutput<float>("Y", {N, C, static_cast<int64_t>(H * scales[2]), static_cast<int64_t>(W * scales[3])}, Y);
test.Run();
}
TEST(ResizeOpTest, ResizeOpLineartUpSampleTest_2DBilinear_Ver10) {
OpTester test("Resize", 10);
std::vector<float> scales{2.0f, 4.0f};
test.AddAttribute("mode", "linear");
const int64_t H = 2, W = 2;
std::vector<float> X = {1.0f, 3.0f,
4.0f, 8.0f};
test.AddInput<float>("X", {H, W}, X);
test.AddInput<float>("scales", {2}, scales);
std::vector<float> Y = {
1.0f, 1.5f, 2.0f, 2.5f, 3.0f, 3.0f, 3.0f, 3.0f,
2.5f, 3.25f, 4.0f, 4.75f, 5.5f, 5.5f, 5.5f, 5.5f,
4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 8.0f, 8.0f, 8.0f,
4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 8.0f, 8.0f, 8.0f};
test.AddOutput<float>("Y", {static_cast<int64_t>(H * scales[0]), static_cast<int64_t>(W * scales[1])}, Y);
test.Run();
}
TEST(ResizeOpTest, ResizeOpLineartScalesNoOpTest_Ver10) {
OpTester test("Resize", 10);
std::vector<float> scales{1.0f, 1.0f, 1.0f, 1.0f};
test.AddAttribute("mode", "linear");
const int64_t N = 2, C = 1, H = 2, W = 2;
std::vector<float> X = {1.0f, 3.0f,
4.0f, 8.0f,
6.0f, 2.0f,
7.0f, 11.0f};
test.AddInput<float>("X", {N, C, H, W}, X);
test.AddInput<float>("scales", {4}, scales);
std::vector<float> Y = {1.0f, 3.0f,
4.0f, 8.0f,
6.0f, 2.0f,
7.0f, 11.0f};
test.AddOutput<float>("Y", {N, C, H, W}, Y);
test.Run();
}
TEST(ResizeOpTest, ResizeOpNearestDownSampleTest_Ver10) {
OpTester test("Resize", 10);
std::vector<float> scales{1.0f, 1.0f, 0.6f, 0.6f};
test.AddAttribute("mode", "nearest");
const int64_t N = 1, C = 1, H = 2, W = 4;
std::vector<float> X = {
1.0f, 2.0f, 3.0f, 4.0f,
5.0f, 6.0f, 7.0f, 8.0f};
test.AddInput<float>("X", {N, C, H, W}, X);
test.AddInput<float>("scales", {4}, scales);
std::vector<float> Y = {1.0f, 3.0f};
test.AddOutput<float>("Y", {N, C, static_cast<int64_t>(H * scales[2]), static_cast<int64_t>(W * scales[3])}, Y);
test.Run();
}
TEST(ResizeOpTest, ResizeOpNearestUpSampleTest_Ver10) {
OpTester test("Resize", 10);
std::vector<float> scales{1.0f, 1.0f, 2.0f, 3.0f};
test.AddAttribute("mode", "nearest");
const int64_t N = 1, C = 1, H = 2, W = 2;
std::vector<float> X = {1.0f, 2.0f, 3.0f, 4.0f};
test.AddInput<float>("X", {N, C, H, W}, X);
test.AddInput<float>("scales", {4}, scales);
std::vector<float> Y = {1.0f, 1.0f, 1.0f, 2.0f, 2.0f, 2.0f,
1.0f, 1.0f, 1.0f, 2.0f, 2.0f, 2.0f,
3.0f, 3.0f, 3.0f, 4.0f, 4.0f, 4.0f,
3.0f, 3.0f, 3.0f, 4.0f, 4.0f, 4.0f};
test.AddOutput<float>("Y", {N, C, static_cast<int64_t>(H * scales[2]), static_cast<int64_t>(W * scales[3])}, Y);
test.Run();
}
TEST(UpsampleOpTest, ResizeOpNearestNoScaleTest_Ver10) {
OpTester test("Resize", 10);
std::vector<float> scales{1.0f, 1.0f, 1.0f, 1.0f};
test.AddAttribute("mode", "nearest");
const int64_t N = 1, C = 1, H = 2, W = 2;
std::vector<float> X = {1.0f, 2.0f, 3.0f, 4.0f};
test.AddInput<float>("X", {N, C, H, W}, X);
test.AddInput<float>("scales", {4}, scales);
std::vector<float> Y = {1.0f, 2.0f, 3.0f, 4.0f};
test.AddOutput<float>("Y", {N, C, H, W}, Y);
test.Run();
}