[OV2.0] Preprocessing - resize (#7583)

* Initial version

* Added 'network' layout to preprocessing info
Moved existing resize tests to template plugin

* Fix clang

* More tests for 'resize' reference implementation + CPU tests + error cases
Coverage is 100%

* Align with new base_reference_test implementation

* Fixed comments

* Add assert to check that desired size is not out of bounds

* CPU: skip failed test
This commit is contained in:
Mikhail Nosov authored and GitHub committed 2021-09-30 11:41:25 +03:00
1 parent c00b0b6ae4
commit 414c3dc133
14 files changed
+749 -15

No files matched your search

@@ -38,7 +38,12 @@ void CommonReferenceTest::FillInputs() {
for (size_t i = 0; i < functionParams.size(); i++) {
const auto& param = functionParams[i];
ov::runtime::Tensor blob(param->get_element_type(), param->get_shape());
ov::runtime::Tensor blob;
if (param->get_partial_shape().is_static()) {
blob = ov::runtime::Tensor(param->get_element_type(), param->get_shape());
} else {
blob = ov::runtime::Tensor(param->get_element_type(), inputData[i].get_shape());
}
ASSERT_EQ(blob.get_byte_size(), inputData[i].get_byte_size());
std::memcpy(blob.data(), inputData[i].data(), inputData[i].get_byte_size());
@@ -36,7 +36,9 @@ protected:
};
template <class T>
ov::runtime::Tensor CreateTensor(const ov::element::Type& element_type, const std::vector<T>& values, size_t size = 0) {
ov::runtime::Tensor CreateTensor(const ov::element::Type& element_type,
const std::vector<T>& values,
size_t size = 0) {
size_t real_size = size ? size : values.size() * sizeof(T) / element_type.size();
ov::runtime::Tensor tensor { element_type, {real_size} };
std::memcpy(tensor.data(), values.data(), std::min(real_size * element_type.size(), sizeof(T) * values.size()));
@@ -44,6 +46,17 @@ ov::runtime::Tensor CreateTensor(const ov::element::Type& element_type, const st
return tensor;
}
// Create blob with correct input shape (not 1-dimensional). Will be used in tests with dynamic input shapes
template <class T>
ov::runtime::Tensor CreateTensor(const ov::Shape& shape,
const ov::element::Type& element_type,
const std::vector<T>& values) {
ov::runtime::Tensor tensor { element_type, shape };
std::memcpy(tensor.data(), values.data(), sizeof(T) * values.size());
return tensor;
}
///
/// Class which should help to build data for single input
///
@@ -56,6 +69,11 @@ struct Tensor {
Tensor(const ov::Shape& shape, ov::element::Type type, const std::vector<T>& data_elements)
: Tensor {shape, type, CreateTensor(type, data_elements)} {}
// Temporary constructor to create blob with passed input shape (not 1-dimensional)
template <typename T>
Tensor(ov::element::Type type, const ov::Shape& shape, const std::vector<T>& data_elements)
: Tensor {shape, type, CreateTensor(shape, type, data_elements)} {}
ov::Shape shape;
ov::element::Type type;
ov::runtime::Tensor data;
@@ -271,6 +271,155 @@ static RefPreprocessParams mean_scale_dynamic_layout() {
return res;
}
static RefPreprocessParams resize_to_network_height() {
RefPreprocessParams res("resize_to_network_height");
res.function = []() {
auto f = create_simple_function(element::f32, PartialShape{1, 2, 1, 1});
f = PrePostProcessor()
.input(InputInfo()
.tensor(InputTensorInfo().set_spatial_dynamic_shape())
.preprocess(PreProcessSteps().resize(ResizeAlgorithm::RESIZE_LINEAR))
.network(InputNetworkInfo().set_layout("NHWC"))
)
.build(f);
return f;
};
res.inputs.emplace_back(element::f32, Shape{1, 4, 1, 1}, std::vector<float>{0., 2., 4., 6.});
res.expected.emplace_back(Shape{1, 2, 1, 1}, element::f32, std::vector<float>{1., 5.});
return res;
}
static RefPreprocessParams resize_to_network_width() {
RefPreprocessParams res("resize_to_network_width");
res.function = []() {
auto f = create_simple_function(element::f32, PartialShape{Dimension::dynamic(), 1, 2, 2});
f = PrePostProcessor()
.input(InputInfo()
.tensor(InputTensorInfo().set_spatial_dynamic_shape())
.preprocess(PreProcessSteps().resize(ResizeAlgorithm::RESIZE_LINEAR))
.network(InputNetworkInfo().set_layout("NCHW")))
.build(f);
return f;
};
res.inputs.emplace_back(element::f32, Shape{1, 1, 2, 6}, std::vector<float>{0., 1., 2., 3., 4., 5.,
0., 1., 2., 3., 4., 5.});
res.expected.emplace_back(Shape{1, 1, 2, 2}, element::f32, std::vector<float>{1., 4., 1., 4.});
return res;
}
static RefPreprocessParams resize_from_spatial_dims() {
RefPreprocessParams res("resize_from_spatial_dims");
res.function = []() {
auto f = create_simple_function(element::f32, PartialShape{Dimension::dynamic(), 1, 1, 1});
auto t = InputTensorInfo();
t.set_spatial_static_shape(1, 4);
f = PrePostProcessor()
.input(InputInfo()
.tensor(std::move(t))
.preprocess(PreProcessSteps().resize(ResizeAlgorithm::RESIZE_CUBIC))
.network(InputNetworkInfo().set_layout("NCHW")))
.build(f);
return f;
};
res.inputs.emplace_back(element::f32, Shape{1, 1, 1, 7}, std::vector<float>{0., 0.25, 1., 2.25, 4., 6.25, 9});
res.expected.emplace_back(Shape{1, 1, 1, 1}, element::f32, std::vector<float>{2.25});
return res;
}
static RefPreprocessParams resize_to_network_width_height() {
RefPreprocessParams res("resize_to_network_width_height");
res.function = []() {
auto f = create_simple_function(element::f32, PartialShape{1, 1, 4, 4});
f = PrePostProcessor()
.input(InputInfo()
.tensor(InputTensorInfo().set_spatial_static_shape(5, 5))
.preprocess(PreProcessSteps().resize(ResizeAlgorithm::RESIZE_NEAREST))
.network(InputNetworkInfo().set_layout("...HW")))
.build(f);
return f;
};
auto result = std::make_shared<HostTensor>();
// clang-format off
std::vector<float> input = {0., 1., 2., 3., 4.,
1., 2., 3., 4., 5.,
2., 3., 4., 5., 6.,
3., 4., 5., 6., 7.,
2., 3., 4., 5., 6.};
std::vector<float> expected = {0., 1., 3., 4.,
1., 2., 4., 5.,
3., 4., 6., 7.,
2., 3., 5., 6.};
// clang-format on
res.inputs.emplace_back(element::f32, Shape{1, 1, 5, 5}, input);
res.expected.emplace_back(Shape{1, 1, 4, 4}, element::f32, expected);
return res;
}
static RefPreprocessParams resize_to_specified_width_height() {
RefPreprocessParams res("resize_to_specified_width_height");
res.function = []() {
auto f = create_simple_function(element::f32, PartialShape{1, 1, Dimension::dynamic(), Dimension::dynamic()});
f = PrePostProcessor()
.input(InputInfo()
.tensor(InputTensorInfo().set_spatial_dynamic_shape())
.preprocess(PreProcessSteps().resize(ResizeAlgorithm::RESIZE_NEAREST, 4, 4))
.network(InputNetworkInfo().set_layout("...HW")))
.build(f);
return f;
};
auto result = std::make_shared<HostTensor>();
// clang-format off
std::vector<float> input = {0., 1., 2., 3., 4.,
1., 2., 3., 4., 5.,
2., 3., 4., 5., 6.,
3., 4., 5., 6., 7.,
2., 3., 4., 5., 6.};
std::vector<float> expected = {0., 1., 3., 4.,
1., 2., 4., 5.,
3., 4., 6., 7.,
2., 3., 5., 6.};
// clang-format on
res.inputs.emplace_back(element::f32, Shape{1, 1, 5, 5}, input);
res.expected.emplace_back(Shape{1, 1, 4, 4}, element::f32, expected);
return res;
}
static RefPreprocessParams resize_lvalues() {
RefPreprocessParams res("resize_lvalues");
res.function = []() {
auto f = create_simple_function(element::f32, PartialShape{Dimension::dynamic(), 1, 1, 2});
f->get_parameters().front()->set_layout("NCHW");
auto t = InputTensorInfo();
t.set_spatial_dynamic_shape();
auto s = PreProcessSteps();
s.resize(ResizeAlgorithm::RESIZE_LINEAR, 1, 6); // to specified shape
s.resize(ResizeAlgorithm::RESIZE_LINEAR); // to network's shape
auto n = InputNetworkInfo();
n.set_layout("NCHW");
auto i = InputInfo();
i.tensor(std::move(t));
i.preprocess(std::move(s));
i.network(std::move(n));
f = PrePostProcessor()
.input(std::move(i))
.build(f);
return f;
};
// clang-format off
res.inputs.emplace_back(element::f32, Shape{1, 1, 1, 18}, std::vector<float>{0., 0., 0.,
1., 1., 1.,
2., 2., 2.,
3., 3., 3.,
4., 4., 4.,
5., 5., 5.});
// clang-format on
res.expected.emplace_back(Shape{1, 1, 2, 1}, element::f32, std::vector<float>{1., 4.});
return res;
}
std::vector<RefPreprocessParams> allPreprocessTests() {
return std::vector<RefPreprocessParams> {
simple_mean_scale(),
@@ -282,7 +431,13 @@ std::vector<RefPreprocessParams> allPreprocessTests() {
test_lvalue(),
test_2_inputs_basic(),
mean_scale_vector_tensor_layout(),
mean_scale_dynamic_layout()
mean_scale_dynamic_layout(),
resize_to_network_height(),
resize_to_network_width(),
resize_from_spatial_dims(),
resize_to_network_width_height(),
resize_to_specified_width_height(),
resize_lvalues()
};
}