Insert Transpose layers around the Interpolate layer with axes that are unsupported in MKLDNN (#8204)

* Started to write transformation that allows MKLDNN Interpolate to work with axes {1,2} or {1,2,3}.

* Written the transformation that wraps Interpolate into Transposes.

* Some fixes.

* Written transformation tests.

* Added debug prints.

* Fixed order inputs calculations for inserted Transposes.

* Fixed the transformation tests.

* Deleted commented code.

* Fixed includes.

* Small fix.

* In some places, int64_t was replaced by size_t.

* Small change.

* Small fix.

* The function transformation_is_applicable() was inlined.

* Inlined the helper function get_non_interpolated_axes().

* Inlined the function create_set_of_all_axes().

* Code style fix.

* Small fix.

* Added test.

* Some fixes.

* Fixed shapes of start, stop, step inputs of Range in the test.

* Added more tests.

* Small fix.

* Added TransposeSinking after WrapInterpolateIntoTransposes (in MKLDNN plugin).
This commit is contained in:
Vladimir Gavrilov 2021-11-17 10:41:26 +03:00 committed by GitHub
parent 4c27bdb2ee
commit 2017667543
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 703 additions and 2 deletions

View File

@ -30,6 +30,8 @@
#include <transformations/common_optimizations/weights_dequantize_to_fake_quantize.hpp>
#include "transformations/common_optimizations/convert_quantize_dequantize.hpp"
#include <transformations/common_optimizations/nop_elimination.hpp>
#include <transformations/common_optimizations/wrap_interpolate_into_transposes.hpp>
#include <transformations/common_optimizations/transpose_sinking.hpp>
#include <transformations/op_conversions/convert_depth_to_space.hpp>
#include <transformations/op_conversions/convert_shuffle_channels3.hpp>
#include <transformations/op_conversions/convert_space_to_depth.hpp>
@ -159,6 +161,8 @@ static void TransformationUpToCPUSpecificOpSet(std::shared_ptr<ngraph::Function>
static const auto precisions = get_convert_precisions();
manager.register_pass<ngraph::pass::CommonOptimizations>();
manager.register_pass<ngraph::pass::WrapInterpolateIntoTransposes>();
manager.register_pass<ngraph::pass::TransposeSinking>();
manager.register_pass<ngraph::pass::ConvertRNNSequenceToTensorIterator>();
manager.register_pass<ngraph::pass::ConvertGRUSequenceToTensorIterator>();
manager.register_pass<ngraph::pass::ConvertLSTMSequenceToTensorIterator>();

View File

@ -0,0 +1,40 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include <vector>
#include <memory>
#include <transformations_visibility.hpp>
#include <ngraph/pass/graph_rewrite.hpp>
namespace ngraph {
namespace pass {
class TRANSFORMATIONS_API WrapInterpolateIntoTransposes;
} // namespace pass
} // namespace ngraph
/**
* @ingroup ie_transformation_common_api
* @brief WrapInterpolateIntoTransposes transformation replaces
* Interpolate
* with
* Transpose -> Interpolate -> Transpose
* when
* 1) the source Interpolate has the static input rank;
* 2) 'axes' input is a Constant;
* 3) number of axes is equal to input rank minus 2;
* 4) axes contain 0 or 1.
* The reason of this transformation is that now CPU plugin supports interpolation only
* with respect to spatial dimensions, but TensorFlow frontend gives Interpolate with
* axes {1, 2} for 4D tensors.
*/
class ngraph::pass::WrapInterpolateIntoTransposes: public ngraph::pass::MatcherPass {
public:
NGRAPH_RTTI_DECLARATION;
WrapInterpolateIntoTransposes();
};

View File

@ -0,0 +1,95 @@
// Copyright (C) 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "itt.hpp"
#include "transformations/common_optimizations/wrap_interpolate_into_transposes.hpp"
#include <algorithm>
#include <memory>
#include <numeric>
#include <tuple>
#include <set>
#include <utility>
#include <vector>
#include <ngraph/rt_info.hpp>
#include <openvino/opsets/opset8.hpp>
#include <openvino/pass/pattern/op/wrap_type.hpp>
namespace {
std::vector<int64_t> reverse_permutation(const std::vector<int64_t>& perm) {
if (perm.empty()) return {};
std::vector<int64_t> result(perm.size());
for (int64_t i = 0; i < static_cast<int64_t>(perm.size()); ++i) {
result[perm[i]] = i;
}
return result;
}
std::vector<int64_t> build_transposition_for_axes(const std::vector<int64_t>& axes, size_t input_rank) {
std::set<int64_t> non_interpolated_axes_set;
for (size_t i = 0; i < input_rank; ++i) {
non_interpolated_axes_set.insert(static_cast<int64_t>(i));
}
for (const auto& axis : axes) {
non_interpolated_axes_set.erase(axis);
}
std::vector<int64_t> result(non_interpolated_axes_set.begin(), non_interpolated_axes_set.end());
result.insert(result.end(), axes.begin(), axes.end());
return result;
}
std::vector<int64_t> build_new_axes(size_t num_of_axes, size_t rank) {
std::vector<int64_t> result(num_of_axes);
std::iota(result.begin(), result.end(), static_cast<int64_t>(rank - num_of_axes));
return result;
}
} // namespace
NGRAPH_RTTI_DEFINITION(ngraph::pass::WrapInterpolateIntoTransposes, "WrapInterpolateIntoTransposes", 0);
ngraph::pass::WrapInterpolateIntoTransposes::WrapInterpolateIntoTransposes() {
MATCHER_SCOPE(WrapInterpolateIntoTransposes);
auto interpolate_pattern = ov::pass::pattern::wrap_type<ov::opset8::Interpolate>();
ngraph::matcher_pass_callback callback = [=](ngraph::pattern::Matcher& m) {
auto interpolate = std::dynamic_pointer_cast<ov::opset8::Interpolate>(m.get_match_root());
if (!interpolate || interpolate->get_input_partial_shape(0).rank().is_dynamic() || interpolate->inputs().size() != 4) return false;
int64_t input_rank = interpolate->get_input_partial_shape(0).rank().get_length();
// If the input rank is equal to 1 or 2, then such Interpolate is supported by MKLDNN.
if (input_rank < 3) return false;
auto axes_node = std::dynamic_pointer_cast<ov::opset8::Constant>(interpolate->input_value(3).get_node_shared_ptr());
if (!axes_node) return false;
const auto axes = axes_node->cast_vector<int64_t>();
if (static_cast<int64_t>(axes.size()) > input_rank - 2 ||
std::all_of(axes.begin(), axes.end(), [](int64_t axis){ return axis != 0 && axis != 1; })) {
return false;
}
const auto first_perm = build_transposition_for_axes(axes, input_rank);
const auto last_perm = reverse_permutation(first_perm);
auto first_transpose_perm = ov::opset8::Constant::create(element::i64, {first_perm.size()}, first_perm);
auto first_transpose = std::make_shared<ov::opset8::Transpose>(interpolate->input_value(0), first_transpose_perm);
auto new_axes = build_new_axes(axes.size(), input_rank);
auto new_axes_node = ov::opset8::Constant::create(element::i64, {new_axes.size()}, new_axes);
auto new_interpolate = interpolate->clone_with_new_inputs({first_transpose, interpolate->input_value(1), interpolate->input_value(2), new_axes_node});
auto last_transpose_perm = ov::opset8::Constant::create(element::i64, {last_perm.size()}, last_perm);
auto last_transpose = std::make_shared<ov::opset8::Transpose>(new_interpolate, last_transpose_perm);
last_transpose->set_friendly_name(interpolate->get_friendly_name());
copy_runtime_info(interpolate, {first_transpose_perm, first_transpose, new_axes_node, new_interpolate, last_transpose_perm, last_transpose});
replace_node(interpolate, last_transpose);
return true;
};
auto m = std::make_shared<ngraph::pattern::Matcher>(interpolate_pattern, matcher_name);
register_matcher(m, callback);
}

View File

@ -0,0 +1,564 @@
// Copyright (C) 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <gtest/gtest.h>
#include <string>
#include <memory>
#include <ngraph/function.hpp>
#include <ngraph/opsets/opset8.hpp>
#include <ngraph/pass/manager.hpp>
#include <ngraph/pass/visualize_tree.hpp>
#include <transformations/common_optimizations/wrap_interpolate_into_transposes.hpp>
#include <transformations/init_node_info.hpp>
#include <transformations/utils/utils.hpp>
#include "common_test_utils/ngraph_test_utils.hpp"
using namespace testing;
TEST_F(TransformationTestsF, WrapInterpolateIntoTransposes4DScales) {
ngraph::opset8::Interpolate::InterpolateAttrs attrs;
attrs.mode = ngraph::opset8::Interpolate::InterpolateMode::NEAREST;
attrs.shape_calculation_mode = ngraph::opset8::Interpolate::ShapeCalcMode::SCALES;
attrs.nearest_mode = ngraph::opset8::Interpolate::NearestMode::ROUND_PREFER_FLOOR;
attrs.pads_begin = std::vector<size_t>{0};
attrs.pads_end = std::vector<size_t>{0};
attrs.antialias = false;
attrs.coordinate_transformation_mode = ngraph::opset8::Interpolate::CoordinateTransformMode::HALF_PIXEL;
attrs.cube_coeff = -0.75f;
ngraph::Shape input_shape { 1, 100, 120, 150 };
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{2}, { 50, 60 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{2}, { 0.5, 0.5 });
auto axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {2}, std::vector<int64_t>{1, 2});
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(input, sizes_node, scales_node, axis_node, attrs);
function = std::make_shared<ngraph::Function>(ngraph::NodeVector{ interpolate }, ngraph::ParameterVector{ input });
manager.register_pass<ngraph::pass::WrapInterpolateIntoTransposes>();
}
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{2}, { 50, 60 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{2}, { 0.5, 0.5 });
auto axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {2}, std::vector<int64_t>{2, 3});
auto first_transpose_perm = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{4}, { 0, 3, 1, 2 });
auto last_transpose_perm = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{4}, { 0, 2, 3, 1 });
auto first_transpose = std::make_shared<ngraph::opset8::Transpose>(input, first_transpose_perm);
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(first_transpose, sizes_node, scales_node, axis_node, attrs);
auto last_transpose = std::make_shared<ngraph::opset8::Transpose>(interpolate, last_transpose_perm);
function_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{ last_transpose }, ngraph::ParameterVector{ input });
}
}
TEST_F(TransformationTestsF, WrapInterpolateIntoTransposes4DSizes) {
ngraph::opset8::Interpolate::InterpolateAttrs attrs;
attrs.mode = ngraph::opset8::Interpolate::InterpolateMode::NEAREST;
attrs.shape_calculation_mode = ngraph::opset8::Interpolate::ShapeCalcMode::SIZES;
attrs.nearest_mode = ngraph::opset8::Interpolate::NearestMode::ROUND_PREFER_FLOOR;
attrs.pads_begin = std::vector<size_t>{0};
attrs.pads_end = std::vector<size_t>{0};
attrs.antialias = false;
attrs.coordinate_transformation_mode = ngraph::opset8::Interpolate::CoordinateTransformMode::HALF_PIXEL;
attrs.cube_coeff = -0.75f;
ngraph::Shape input_shape { 1, 100, 120, 150 };
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{2}, { 50, 60 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{2}, { 0.5, 0.5 });
auto axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {2}, std::vector<int64_t>{1, 2});
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(input, sizes_node, scales_node, axis_node, attrs);
function = std::make_shared<ngraph::Function>(ngraph::NodeVector{ interpolate }, ngraph::ParameterVector{ input });
manager.register_pass<ngraph::pass::WrapInterpolateIntoTransposes>();
}
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{2}, { 50, 60 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{2}, { 0.5, 0.5 });
auto axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {2}, std::vector<int64_t>{2, 3});
auto first_transpose_perm = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{4}, { 0, 3, 1, 2 });
auto last_transpose_perm = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{4}, { 0, 2, 3, 1 });
auto first_transpose = std::make_shared<ngraph::opset8::Transpose>(input, first_transpose_perm);
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(first_transpose, sizes_node, scales_node, axis_node, attrs);
auto last_transpose = std::make_shared<ngraph::opset8::Transpose>(interpolate, last_transpose_perm);
function_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{ last_transpose }, ngraph::ParameterVector{ input });
}
}
TEST_F(TransformationTestsF, WrapInterpolateIntoTransposes5DScales) {
ngraph::opset8::Interpolate::InterpolateAttrs attrs;
attrs.mode = ngraph::opset8::Interpolate::InterpolateMode::NEAREST;
attrs.shape_calculation_mode = ngraph::opset8::Interpolate::ShapeCalcMode::SCALES;
attrs.nearest_mode = ngraph::opset8::Interpolate::NearestMode::ROUND_PREFER_FLOOR;
attrs.pads_begin = std::vector<size_t>{0};
attrs.pads_end = std::vector<size_t>{0};
attrs.antialias = false;
attrs.coordinate_transformation_mode = ngraph::opset8::Interpolate::CoordinateTransformMode::HALF_PIXEL;
attrs.cube_coeff = -0.75f;
ngraph::Shape input_shape { 1, 100, 120, 150, 18 };
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{3}, { 60, 240, 75 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{3}, { 0.6, 2.0, 0.5 });
auto axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {3}, std::vector<int64_t>{1, 2, 3});
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(input, sizes_node, scales_node, axis_node, attrs);
function = std::make_shared<ngraph::Function>(ngraph::NodeVector{ interpolate }, ngraph::ParameterVector{ input });
manager.register_pass<ngraph::pass::WrapInterpolateIntoTransposes>();
}
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{3}, { 60, 240, 75 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{3}, { 0.6, 2.0, 0.5 });
auto axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {3}, std::vector<int64_t>{2, 3, 4});
auto first_transpose_perm = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{5}, { 0, 4, 1, 2, 3 });
auto last_transpose_perm = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{5}, { 0, 2, 3, 4, 1 });
auto first_transpose = std::make_shared<ngraph::opset8::Transpose>(input, first_transpose_perm);
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(first_transpose, sizes_node, scales_node, axis_node, attrs);
auto last_transpose = std::make_shared<ngraph::opset8::Transpose>(interpolate, last_transpose_perm);
function_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{ last_transpose }, ngraph::ParameterVector{ input });
}
}
TEST_F(TransformationTestsF, WrapInterpolateIntoTransposes5DSizes) {
ngraph::opset8::Interpolate::InterpolateAttrs attrs;
attrs.mode = ngraph::opset8::Interpolate::InterpolateMode::NEAREST;
attrs.shape_calculation_mode = ngraph::opset8::Interpolate::ShapeCalcMode::SIZES;
attrs.nearest_mode = ngraph::opset8::Interpolate::NearestMode::ROUND_PREFER_FLOOR;
attrs.pads_begin = std::vector<size_t>{0};
attrs.pads_end = std::vector<size_t>{0};
attrs.antialias = false;
attrs.coordinate_transformation_mode = ngraph::opset8::Interpolate::CoordinateTransformMode::HALF_PIXEL;
attrs.cube_coeff = -0.75f;
ngraph::Shape input_shape { 1, 100, 120, 150, 18 };
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{3}, { 60, 240, 75 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{3}, { 0.6, 2.0, 0.5 });
auto axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {3}, std::vector<int64_t>{1, 2, 3});
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(input, sizes_node, scales_node, axis_node, attrs);
function = std::make_shared<ngraph::Function>(ngraph::NodeVector{ interpolate }, ngraph::ParameterVector{ input });
manager.register_pass<ngraph::pass::WrapInterpolateIntoTransposes>();
}
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{3}, { 60, 240, 75 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{3}, { 0.6, 2.0, 0.5 });
auto axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {3}, std::vector<int64_t>{2, 3, 4});
auto first_transpose_perm = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{5}, { 0, 4, 1, 2, 3 });
auto last_transpose_perm = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{5}, { 0, 2, 3, 4, 1 });
auto first_transpose = std::make_shared<ngraph::opset8::Transpose>(input, first_transpose_perm);
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(first_transpose, sizes_node, scales_node, axis_node, attrs);
auto last_transpose = std::make_shared<ngraph::opset8::Transpose>(interpolate, last_transpose_perm);
function_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{ last_transpose }, ngraph::ParameterVector{ input });
}
}
TEST_F(TransformationTestsF, WrapInterpolateIntoTransposes4DScalesDynamic) {
ngraph::opset8::Interpolate::InterpolateAttrs attrs;
attrs.mode = ngraph::opset8::Interpolate::InterpolateMode::NEAREST;
attrs.shape_calculation_mode = ngraph::opset8::Interpolate::ShapeCalcMode::SCALES;
attrs.nearest_mode = ngraph::opset8::Interpolate::NearestMode::ROUND_PREFER_FLOOR;
attrs.pads_begin = std::vector<size_t>{0};
attrs.pads_end = std::vector<size_t>{0};
attrs.antialias = false;
attrs.coordinate_transformation_mode = ngraph::opset8::Interpolate::CoordinateTransformMode::HALF_PIXEL;
attrs.cube_coeff = -0.75f;
ngraph::PartialShape input_shape { 1, ngraph::Dimension::dynamic(), 120, ngraph::Dimension::dynamic() };
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{2}, { 50, 60 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{2}, { 0.5, 0.5 });
auto axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {2}, std::vector<int64_t>{1, 2});
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(input, sizes_node, scales_node, axis_node, attrs);
function = std::make_shared<ngraph::Function>(ngraph::NodeVector{ interpolate }, ngraph::ParameterVector{ input });
manager.register_pass<ngraph::pass::WrapInterpolateIntoTransposes>();
}
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{2}, { 50, 60 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{2}, { 0.5, 0.5 });
auto axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {2}, std::vector<int64_t>{2, 3});
auto first_transpose_perm = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{4}, { 0, 3, 1, 2 });
auto last_transpose_perm = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{4}, { 0, 2, 3, 1 });
auto first_transpose = std::make_shared<ngraph::opset8::Transpose>(input, first_transpose_perm);
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(first_transpose, sizes_node, scales_node, axis_node, attrs);
auto last_transpose = std::make_shared<ngraph::opset8::Transpose>(interpolate, last_transpose_perm);
function_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{ last_transpose }, ngraph::ParameterVector{ input });
}
}
TEST_F(TransformationTestsF, WrapInterpolateIntoTransposes4DSizesDynamic) {
ngraph::opset8::Interpolate::InterpolateAttrs attrs;
attrs.mode = ngraph::opset8::Interpolate::InterpolateMode::NEAREST;
attrs.shape_calculation_mode = ngraph::opset8::Interpolate::ShapeCalcMode::SIZES;
attrs.nearest_mode = ngraph::opset8::Interpolate::NearestMode::ROUND_PREFER_FLOOR;
attrs.pads_begin = std::vector<size_t>{0};
attrs.pads_end = std::vector<size_t>{0};
attrs.antialias = false;
attrs.coordinate_transformation_mode = ngraph::opset8::Interpolate::CoordinateTransformMode::HALF_PIXEL;
attrs.cube_coeff = -0.75f;
ngraph::PartialShape input_shape { 1, ngraph::Dimension::dynamic(), 120, ngraph::Dimension::dynamic() };
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{2}, { 50, 60 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{2}, { 0.5, 0.5 });
auto axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {2}, std::vector<int64_t>{1, 2});
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(input, sizes_node, scales_node, axis_node, attrs);
function = std::make_shared<ngraph::Function>(ngraph::NodeVector{ interpolate }, ngraph::ParameterVector{ input });
manager.register_pass<ngraph::pass::WrapInterpolateIntoTransposes>();
}
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{2}, { 50, 60 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{2}, { 0.5, 0.5 });
auto axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {2}, std::vector<int64_t>{2, 3});
auto first_transpose_perm = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{4}, { 0, 3, 1, 2 });
auto last_transpose_perm = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{4}, { 0, 2, 3, 1 });
auto first_transpose = std::make_shared<ngraph::opset8::Transpose>(input, first_transpose_perm);
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(first_transpose, sizes_node, scales_node, axis_node, attrs);
auto last_transpose = std::make_shared<ngraph::opset8::Transpose>(interpolate, last_transpose_perm);
function_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{ last_transpose }, ngraph::ParameterVector{ input });
}
}
TEST_F(TransformationTestsF, WrapInterpolateIntoTransposes5DScalesDynamic) {
ngraph::opset8::Interpolate::InterpolateAttrs attrs;
attrs.mode = ngraph::opset8::Interpolate::InterpolateMode::NEAREST;
attrs.shape_calculation_mode = ngraph::opset8::Interpolate::ShapeCalcMode::SCALES;
attrs.nearest_mode = ngraph::opset8::Interpolate::NearestMode::ROUND_PREFER_FLOOR;
attrs.pads_begin = std::vector<size_t>{0};
attrs.pads_end = std::vector<size_t>{0};
attrs.antialias = false;
attrs.coordinate_transformation_mode = ngraph::opset8::Interpolate::CoordinateTransformMode::HALF_PIXEL;
attrs.cube_coeff = -0.75f;
ngraph::PartialShape input_shape { ngraph::Dimension::dynamic(), 100, ngraph::Dimension::dynamic(), ngraph::Dimension::dynamic(), 18 };
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{3}, { 60, 240, 75 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{3}, { 0.6, 2.0, 0.5 });
auto axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {3}, std::vector<int64_t>{1, 2, 3});
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(input, sizes_node, scales_node, axis_node, attrs);
function = std::make_shared<ngraph::Function>(ngraph::NodeVector{ interpolate }, ngraph::ParameterVector{ input });
manager.register_pass<ngraph::pass::WrapInterpolateIntoTransposes>();
}
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{3}, { 60, 240, 75 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{3}, { 0.6, 2.0, 0.5 });
auto axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {3}, std::vector<int64_t>{2, 3, 4});
auto first_transpose_perm = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{5}, { 0, 4, 1, 2, 3 });
auto last_transpose_perm = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{5}, { 0, 2, 3, 4, 1 });
auto first_transpose = std::make_shared<ngraph::opset8::Transpose>(input, first_transpose_perm);
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(first_transpose, sizes_node, scales_node, axis_node, attrs);
auto last_transpose = std::make_shared<ngraph::opset8::Transpose>(interpolate, last_transpose_perm);
function_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{ last_transpose }, ngraph::ParameterVector{ input });
}
}
TEST_F(TransformationTestsF, WrapInterpolateIntoTransposes5DSizesDynamic) {
ngraph::opset8::Interpolate::InterpolateAttrs attrs;
attrs.mode = ngraph::opset8::Interpolate::InterpolateMode::NEAREST;
attrs.shape_calculation_mode = ngraph::opset8::Interpolate::ShapeCalcMode::SIZES;
attrs.nearest_mode = ngraph::opset8::Interpolate::NearestMode::ROUND_PREFER_FLOOR;
attrs.pads_begin = std::vector<size_t>{0};
attrs.pads_end = std::vector<size_t>{0};
attrs.antialias = false;
attrs.coordinate_transformation_mode = ngraph::opset8::Interpolate::CoordinateTransformMode::HALF_PIXEL;
attrs.cube_coeff = -0.75f;
ngraph::PartialShape input_shape { ngraph::Dimension::dynamic(), 100, ngraph::Dimension::dynamic(), ngraph::Dimension::dynamic(), 18 };
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{3}, { 60, 240, 75 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{3}, { 0.6, 2.0, 0.5 });
auto axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {3}, std::vector<int64_t>{1, 2, 3});
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(input, sizes_node, scales_node, axis_node, attrs);
function = std::make_shared<ngraph::Function>(ngraph::NodeVector{ interpolate }, ngraph::ParameterVector{ input });
manager.register_pass<ngraph::pass::WrapInterpolateIntoTransposes>();
}
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{3}, { 60, 240, 75 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{3}, { 0.6, 2.0, 0.5 });
auto axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {3}, std::vector<int64_t>{2, 3, 4});
auto first_transpose_perm = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{5}, { 0, 4, 1, 2, 3 });
auto last_transpose_perm = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{5}, { 0, 2, 3, 4, 1 });
auto first_transpose = std::make_shared<ngraph::opset8::Transpose>(input, first_transpose_perm);
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(first_transpose, sizes_node, scales_node, axis_node, attrs);
auto last_transpose = std::make_shared<ngraph::opset8::Transpose>(interpolate, last_transpose_perm);
function_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{ last_transpose }, ngraph::ParameterVector{ input });
}
}
TEST_F(TransformationTestsF, WrapInterpolateIntoTransposes4DScalesNotApplicable) {
ngraph::opset8::Interpolate::InterpolateAttrs attrs;
attrs.mode = ngraph::opset8::Interpolate::InterpolateMode::NEAREST;
attrs.shape_calculation_mode = ngraph::opset8::Interpolate::ShapeCalcMode::SCALES;
attrs.nearest_mode = ngraph::opset8::Interpolate::NearestMode::ROUND_PREFER_FLOOR;
attrs.pads_begin = std::vector<size_t>{0};
attrs.pads_end = std::vector<size_t>{0};
attrs.antialias = false;
attrs.coordinate_transformation_mode = ngraph::opset8::Interpolate::CoordinateTransformMode::HALF_PIXEL;
attrs.cube_coeff = -0.75f;
ngraph::Shape input_shape { 1, 100, 120, 150 };
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{2}, { 50, 75 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{2}, { 0.5, 0.5 });
auto range_start = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 0 });
auto range_stop = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 4 });
auto range_step = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 1 });
auto range = std::make_shared<ngraph::opset8::Range>(range_start, range_stop, range_step, ngraph::element::i64);
auto indices = ngraph::opset8::Constant::create(ngraph::element::i64, {2}, std::vector<int64_t>{1, 3});
auto gather_axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {1}, std::vector<int64_t>{0});
auto gather_node = std::make_shared<ngraph::opset8::Gather>(range, indices, gather_axis_node);
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(input, sizes_node, scales_node, gather_node, attrs);
function = std::make_shared<ngraph::Function>(ngraph::NodeVector{ interpolate }, ngraph::ParameterVector{ input });
manager.register_pass<ngraph::pass::WrapInterpolateIntoTransposes>();
}
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{2}, { 50, 75 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{2}, { 0.5, 0.5 });
auto range_start = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 0 });
auto range_stop = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 4 });
auto range_step = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 1 });
auto range = std::make_shared<ngraph::opset8::Range>(range_start, range_stop, range_step, ngraph::element::i64);
auto indices = ngraph::opset8::Constant::create(ngraph::element::i64, {2}, std::vector<int64_t>{1, 3});
auto gather_axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {1}, std::vector<int64_t>{0});
auto gather_node = std::make_shared<ngraph::opset8::Gather>(range, indices, gather_axis_node);
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(input, sizes_node, scales_node, gather_node, attrs);
function_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{ interpolate }, ngraph::ParameterVector{ input });
}
}
TEST_F(TransformationTestsF, WrapInterpolateIntoTransposes4DSizesNotApplicable) {
ngraph::opset8::Interpolate::InterpolateAttrs attrs;
attrs.mode = ngraph::opset8::Interpolate::InterpolateMode::NEAREST;
attrs.shape_calculation_mode = ngraph::opset8::Interpolate::ShapeCalcMode::SIZES;
attrs.nearest_mode = ngraph::opset8::Interpolate::NearestMode::ROUND_PREFER_FLOOR;
attrs.pads_begin = std::vector<size_t>{0};
attrs.pads_end = std::vector<size_t>{0};
attrs.antialias = false;
attrs.coordinate_transformation_mode = ngraph::opset8::Interpolate::CoordinateTransformMode::HALF_PIXEL;
attrs.cube_coeff = -0.75f;
ngraph::Shape input_shape { 1, 100, 120, 150 };
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{2}, { 50, 75 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{2}, { 0.5, 0.5 });
auto range_start = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 0 });
auto range_stop = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 4 });
auto range_step = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 1 });
auto range = std::make_shared<ngraph::opset8::Range>(range_start, range_stop, range_step, ngraph::element::i64);
auto indices = ngraph::opset8::Constant::create(ngraph::element::i64, {2}, std::vector<int64_t>{1, 3});
auto gather_axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {1}, std::vector<int64_t>{0});
auto gather_node = std::make_shared<ngraph::opset8::Gather>(range, indices, gather_axis_node);
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(input, sizes_node, scales_node, gather_node, attrs);
function = std::make_shared<ngraph::Function>(ngraph::NodeVector{ interpolate }, ngraph::ParameterVector{ input });
manager.register_pass<ngraph::pass::WrapInterpolateIntoTransposes>();
}
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{2}, { 50, 75 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{2}, { 0.5, 0.5 });
auto range_start = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 0 });
auto range_stop = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 4 });
auto range_step = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 1 });
auto range = std::make_shared<ngraph::opset8::Range>(range_start, range_stop, range_step, ngraph::element::i64);
auto indices = ngraph::opset8::Constant::create(ngraph::element::i64, {2}, std::vector<int64_t>{1, 3});
auto gather_axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {1}, std::vector<int64_t>{0});
auto gather_node = std::make_shared<ngraph::opset8::Gather>(range, indices, gather_axis_node);
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(input, sizes_node, scales_node, gather_node, attrs);
function_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{ interpolate }, ngraph::ParameterVector{ input });
}
}
TEST_F(TransformationTestsF, WrapInterpolateIntoTransposes5DScalesNotApplicable) {
ngraph::opset8::Interpolate::InterpolateAttrs attrs;
attrs.mode = ngraph::opset8::Interpolate::InterpolateMode::NEAREST;
attrs.shape_calculation_mode = ngraph::opset8::Interpolate::ShapeCalcMode::SCALES;
attrs.nearest_mode = ngraph::opset8::Interpolate::NearestMode::ROUND_PREFER_FLOOR;
attrs.pads_begin = std::vector<size_t>{0};
attrs.pads_end = std::vector<size_t>{0};
attrs.antialias = false;
attrs.coordinate_transformation_mode = ngraph::opset8::Interpolate::CoordinateTransformMode::HALF_PIXEL;
attrs.cube_coeff = -0.75f;
ngraph::Shape input_shape { 1, 100, 120, 150, 800 };
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{3}, { 50, 75, 600 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{3}, { 0.5, 0.5, 0.75 });
auto range_start = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 0 });
auto range_stop = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 5 });
auto range_step = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 1 });
auto range = std::make_shared<ngraph::opset8::Range>(range_start, range_stop, range_step, ngraph::element::i64);
auto indices = ngraph::opset8::Constant::create(ngraph::element::i64, {3}, std::vector<int64_t>{1, 3, 4});
auto gather_axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {1}, std::vector<int64_t>{0});
auto gather_node = std::make_shared<ngraph::opset8::Gather>(range, indices, gather_axis_node);
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(input, sizes_node, scales_node, gather_node, attrs);
function = std::make_shared<ngraph::Function>(ngraph::NodeVector{ interpolate }, ngraph::ParameterVector{ input });
manager.register_pass<ngraph::pass::WrapInterpolateIntoTransposes>();
}
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{3}, { 50, 75, 600 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{3}, { 0.5, 0.5, 0.75 });
auto range_start = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 0 });
auto range_stop = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 5 });
auto range_step = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 1 });
auto range = std::make_shared<ngraph::opset8::Range>(range_start, range_stop, range_step, ngraph::element::i64);
auto indices = ngraph::opset8::Constant::create(ngraph::element::i64, {3}, std::vector<int64_t>{1, 3, 4});
auto gather_axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {1}, std::vector<int64_t>{0});
auto gather_node = std::make_shared<ngraph::opset8::Gather>(range, indices, gather_axis_node);
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(input, sizes_node, scales_node, gather_node, attrs);
function_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{ interpolate }, ngraph::ParameterVector{ input });
}
}
TEST_F(TransformationTestsF, WrapInterpolateIntoTransposes5DSizesNotApplicable) {
ngraph::opset8::Interpolate::InterpolateAttrs attrs;
attrs.mode = ngraph::opset8::Interpolate::InterpolateMode::NEAREST;
attrs.shape_calculation_mode = ngraph::opset8::Interpolate::ShapeCalcMode::SIZES;
attrs.nearest_mode = ngraph::opset8::Interpolate::NearestMode::ROUND_PREFER_FLOOR;
attrs.pads_begin = std::vector<size_t>{0};
attrs.pads_end = std::vector<size_t>{0};
attrs.antialias = false;
attrs.coordinate_transformation_mode = ngraph::opset8::Interpolate::CoordinateTransformMode::HALF_PIXEL;
attrs.cube_coeff = -0.75f;
ngraph::Shape input_shape { 1, 100, 120, 150, 800 };
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{3}, { 50, 75, 600 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{3}, { 0.5, 0.5, 0.75 });
auto range_start = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 0 });
auto range_stop = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 5 });
auto range_step = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 1 });
auto range = std::make_shared<ngraph::opset8::Range>(range_start, range_stop, range_step, ngraph::element::i64);
auto indices = ngraph::opset8::Constant::create(ngraph::element::i64, {3}, std::vector<int64_t>{1, 3, 4});
auto gather_axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {1}, std::vector<int64_t>{0});
auto gather_node = std::make_shared<ngraph::opset8::Gather>(range, indices, gather_axis_node);
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(input, sizes_node, scales_node, gather_node, attrs);
function = std::make_shared<ngraph::Function>(ngraph::NodeVector{ interpolate }, ngraph::ParameterVector{ input });
manager.register_pass<ngraph::pass::WrapInterpolateIntoTransposes>();
}
{
auto input = std::make_shared<ngraph::opset8::Parameter>(ngraph::element::f32, input_shape);
auto sizes_node = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{3}, { 50, 75, 600 });
auto scales_node = ngraph::opset8::Constant::create(ngraph::element::f32, ngraph::Shape{3}, { 0.5, 0.5, 0.75 });
auto range_start = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 0 });
auto range_stop = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 5 });
auto range_step = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape{}, { 1 });
auto range = std::make_shared<ngraph::opset8::Range>(range_start, range_stop, range_step, ngraph::element::i64);
auto indices = ngraph::opset8::Constant::create(ngraph::element::i64, {3}, std::vector<int64_t>{1, 3, 4});
auto gather_axis_node = ngraph::opset8::Constant::create(ngraph::element::i64, {1}, std::vector<int64_t>{0});
auto gather_node = std::make_shared<ngraph::opset8::Gather>(range, indices, gather_axis_node);
auto interpolate = std::make_shared<ngraph::opset8::Interpolate>(input, sizes_node, scales_node, gather_node, attrs);
function_ref = std::make_shared<ngraph::Function>(ngraph::NodeVector{ interpolate }, ngraph::ParameterVector{ input });
}
}

View File

@ -101,8 +101,6 @@ std::vector<std::string> disabledTestPatterns() {
// CPU plugin does not support some precisions
R"(smoke_CachingSupportCase_CPU/LoadNetworkCacheTestBase.CompareWithRefImpl/ReadConcatSplitAssign_f32_batch1_CPU)",
// Issue 66685
R"(smoke_PrePostProcess.*resize_linear_nhwc.*)",
// CPU plugin does not support some precisions
R"(.*Behavior.*OVExecGraphImportExportTest.*elementType=(i8|u32).*)",
R"(.*Behavior.*OVExecGraphImportExportTest.*elementType=(f16).*)",