Gather: removed indices normalization pass and added some checks for Gather-8 -> Gather-7 conversion (#19666)
* Do not normalize negative indices for Gather v8 * code style fix * added transformation test with accuracy check for Gather-v8 * removed GatherNegativeConstIndicesNormalize transformation at all * ConvertGather8ToGather7 conversion: added more checks * Introduced shared Gather8withIndicesDataLayerTest: added CPU, GPU instances * code style fix * small fix * review fixes * do negative indices normalization if possible * code style fix * refactor cpu test instances * code style fix
This commit is contained in:
parent
001e114d64
commit
f76b6d661c
@ -1,29 +0,0 @@
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openvino/pass/graph_rewrite.hpp"
|
||||
#include "transformations_visibility.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace pass {
|
||||
|
||||
class TRANSFORMATIONS_API GatherNegativeConstIndicesNormalize;
|
||||
|
||||
} // namespace pass
|
||||
} // namespace ov
|
||||
|
||||
/**
|
||||
* @ingroup ie_transformation_common_api
|
||||
* @brief GatherNegativeConstIndicesNormalize checks if indices value is negative scalar and
|
||||
* normalizes it using ShapeOf->Add->Cast subgraph.
|
||||
* We need to remove this transformation after adding support of negative indices in
|
||||
* future version of Gather operation.
|
||||
*/
|
||||
class ov::pass::GatherNegativeConstIndicesNormalize : public ov::pass::MatcherPass {
|
||||
public:
|
||||
OPENVINO_RTTI("GatherNegativeConstIndicesNormalize", "0");
|
||||
GatherNegativeConstIndicesNormalize();
|
||||
};
|
@ -97,7 +97,6 @@
|
||||
#include "transformations/op_conversions/detection_output_upgrade.hpp"
|
||||
#include "transformations/op_conversions/einsum_decomposition.hpp"
|
||||
#include "transformations/op_conversions/eye_decomposition.hpp"
|
||||
#include "transformations/op_conversions/gather_normalize_negative_indices.hpp"
|
||||
#include "transformations/op_conversions/gelu7_downgrade.hpp"
|
||||
#include "transformations/op_conversions/group_normalization_decomposition.hpp"
|
||||
#include "transformations/op_conversions/hsigmoid_decomposition.hpp"
|
||||
@ -170,7 +169,6 @@ bool ov::pass::CommonOptimizations::run_on_model(const std::shared_ptr<ov::Model
|
||||
ADD_MATCHER(decomp, EinsumDecomposition)
|
||||
decomp->add_matcher<SoftmaxDecomposition, false>();
|
||||
ADD_MATCHER(decomp, SoftSignDecomposition)
|
||||
ADD_MATCHER(decomp, GatherNegativeConstIndicesNormalize)
|
||||
ADD_MATCHER(decomp, DropoutWithRandomUniformReplacer)
|
||||
ADD_MATCHER(decomp, TransposeReshapeEliminationForMatmul)
|
||||
ADD_MATCHER(decomp, EyeDecomposition)
|
||||
|
@ -48,8 +48,59 @@ pass::ConvertGather8ToGather7::ConvertGather8ToGather7() {
|
||||
if (!gather_v8_node)
|
||||
return false;
|
||||
|
||||
auto data = gather_v8_node->input_value(0);
|
||||
auto indices_constant =
|
||||
std::dynamic_pointer_cast<ov::op::v0::Constant>(gather_v8_node->input_value(1).get_node_shared_ptr());
|
||||
auto axis_constant =
|
||||
std::dynamic_pointer_cast<ov::op::v0::Constant>(gather_v8_node->input_value(2).get_node_shared_ptr());
|
||||
if (!indices_constant || !axis_constant)
|
||||
return false;
|
||||
|
||||
auto axis = axis_constant->cast_vector<int64_t>();
|
||||
if (axis.size() != 1) {
|
||||
return false;
|
||||
}
|
||||
auto axis_value = axis[0];
|
||||
// normalize `axis` value if it is negative
|
||||
if (axis_value < 0) {
|
||||
if (!data.get_partial_shape().rank().is_static()) {
|
||||
return false;
|
||||
}
|
||||
axis_value = axis_value + data.get_partial_shape().rank().get_length();
|
||||
}
|
||||
if (data.get_partial_shape().rank().get_length() < axis_value) {
|
||||
return false;
|
||||
}
|
||||
// check `axis` dimension of data tensor is static
|
||||
if (!data.get_partial_shape()[axis_value].is_static()) {
|
||||
return false;
|
||||
}
|
||||
auto axis_dim = data.get_partial_shape()[axis_value].get_length();
|
||||
|
||||
auto indices = indices_constant->cast_vector<int64_t>();
|
||||
// Check all the indices are not out of bound and check whether normalization is possible for negative values
|
||||
bool do_indices_normalization = false;
|
||||
for (size_t i = 0; i < indices.size(); i++) {
|
||||
if (indices[i] < -axis_dim || indices[i] >= axis_dim) {
|
||||
return false;
|
||||
}
|
||||
if (indices[i] < 0) {
|
||||
do_indices_normalization = true;
|
||||
indices[i] = indices[i] + axis_dim;
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<ov::Node> new_indices_constant;
|
||||
if (do_indices_normalization) {
|
||||
new_indices_constant = std::make_shared<ov::op::v0::Constant>(indices_constant->get_element_type(),
|
||||
indices_constant->get_shape(),
|
||||
indices);
|
||||
} else {
|
||||
new_indices_constant = indices_constant;
|
||||
}
|
||||
|
||||
auto gather_v7_node = make_shared<ov::op::v7::Gather>(gather_v8_node->input_value(0),
|
||||
gather_v8_node->input_value(1),
|
||||
new_indices_constant,
|
||||
gather_v8_node->input_value(2),
|
||||
gather_v8_node->get_batch_dims());
|
||||
|
||||
|
@ -1,86 +0,0 @@
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "transformations/op_conversions/gather_normalize_negative_indices.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "itt.hpp"
|
||||
#include "openvino/core/rt_info.hpp"
|
||||
#include "openvino/core/validation_util.hpp"
|
||||
#include "openvino/op/add.hpp"
|
||||
#include "openvino/op/constant.hpp"
|
||||
#include "openvino/op/gather.hpp"
|
||||
#include "openvino/op/shape_of.hpp"
|
||||
#include "openvino/pass/pattern/op/wrap_type.hpp"
|
||||
|
||||
ov::pass::GatherNegativeConstIndicesNormalize::GatherNegativeConstIndicesNormalize() {
|
||||
MATCHER_SCOPE(GatherNegativeConstIndicesNormalize);
|
||||
auto data_input = pattern::any_input(pattern::has_static_rank());
|
||||
auto axis_input = ov::pass::pattern::wrap_type<ov::op::v0::Constant>();
|
||||
auto indices_input = ov::pass::pattern::wrap_type<ov::op::v0::Constant>();
|
||||
auto gather_node = ov::pass::pattern::wrap_type<op::util::GatherBase>({data_input, indices_input, axis_input});
|
||||
|
||||
matcher_pass_callback callback = [=](ov::pass::pattern::Matcher& m) {
|
||||
auto& pattern_to_output = m.get_pattern_value_map();
|
||||
auto gather = pattern_to_output.at(gather_node).get_node_shared_ptr();
|
||||
auto data = pattern_to_output.at(data_input);
|
||||
auto axis_constant =
|
||||
std::dynamic_pointer_cast<ov::op::v0::Constant>(pattern_to_output.at(axis_input).get_node_shared_ptr());
|
||||
auto indices_constant =
|
||||
std::dynamic_pointer_cast<ov::op::v0::Constant>(pattern_to_output.at(indices_input).get_node_shared_ptr());
|
||||
|
||||
if (!gather || !axis_constant || !indices_constant) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto indices = indices_constant->cast_vector<int64_t>();
|
||||
if (indices.size() != 1 || indices[0] >= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto axis = axis_constant->cast_vector<int64_t>();
|
||||
if (axis.size() != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto axis_value = axis[0];
|
||||
|
||||
// normalize `axis` value if it is negative
|
||||
if (axis_value < 0) {
|
||||
axis_value = axis_value + data.get_partial_shape().rank().get_length();
|
||||
}
|
||||
|
||||
if (data.get_partial_shape().rank().get_length() < axis_value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check `axis` dimension of data tensor is static
|
||||
if (!data.get_partial_shape()[axis_value].is_static()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto input_type = indices_constant->get_element_type();
|
||||
auto shape_of = std::make_shared<ov::op::v3::ShapeOf>(data, input_type);
|
||||
auto input_gather =
|
||||
std::make_shared<ov::op::v7::Gather>(shape_of,
|
||||
ov::op::v0::Constant::create(input_type, Shape{}, {axis_value}),
|
||||
ov::op::v0::Constant::create(input_type, Shape{}, {0}));
|
||||
|
||||
std::shared_ptr<Node> add = std::make_shared<ov::op::v1::Add>(input_gather, indices_constant);
|
||||
OPENVINO_SUPPRESS_DEPRECATED_START
|
||||
if (auto folded_const = ov::get_constant_from_source(add)) {
|
||||
OPENVINO_SUPPRESS_DEPRECATED_END
|
||||
add = folded_const;
|
||||
}
|
||||
gather->input(1).replace_source_output(add);
|
||||
|
||||
ov::copy_runtime_info(gather, {shape_of, input_gather, add});
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto m = std::make_shared<ov::pass::pattern::Matcher>(gather_node, matcher_name);
|
||||
register_matcher(m, callback);
|
||||
}
|
@ -55,7 +55,7 @@ TEST_F(TransformationTestsF, ConvertGather7toGather1_nonzero_batch_dims) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, ConvertGather8toGather7) {
|
||||
TEST_F(TransformationTestsF, ConvertGather8toGather7_param_indices) {
|
||||
{
|
||||
auto data = std::make_shared<opset1::Parameter>(element::f32, Shape{2, 3});
|
||||
auto indices = std::make_shared<opset1::Parameter>(element::i32, Shape{2, 2});
|
||||
@ -68,15 +68,98 @@ TEST_F(TransformationTestsF, ConvertGather8toGather7) {
|
||||
|
||||
manager.register_pass<ov::pass::ConvertGather8ToGather7>();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, ConvertGather8toGather7_const_indices) {
|
||||
{
|
||||
auto data = std::make_shared<opset1::Parameter>(element::f32, Shape{2, 3});
|
||||
auto indices = opset8::Constant::create(element::i32, Shape{2, 2}, {0, 1, 2, 0});
|
||||
auto axis = opset1::Constant::create(element::i32, Shape{1}, {1});
|
||||
int64_t batch_dims = 1;
|
||||
|
||||
auto gather_v8 = std::make_shared<opset8::Gather>(data, indices, axis, batch_dims);
|
||||
|
||||
model = std::make_shared<ov::Model>(NodeVector{gather_v8}, ParameterVector{data});
|
||||
|
||||
manager.register_pass<ov::pass::ConvertGather8ToGather7>();
|
||||
}
|
||||
|
||||
{
|
||||
auto data = std::make_shared<opset1::Parameter>(element::f32, Shape{2, 3});
|
||||
auto indices = std::make_shared<opset1::Parameter>(element::i32, Shape{2, 2});
|
||||
auto indices = opset8::Constant::create(element::i32, Shape{2, 2}, {0, 1, 2, 0});
|
||||
auto axis = opset1::Constant::create(element::i32, Shape{1}, {1});
|
||||
int64_t batch_dims = 1;
|
||||
|
||||
auto gather_v7 = std::make_shared<opset7::Gather>(data, indices, axis, batch_dims);
|
||||
|
||||
model_ref = std::make_shared<ov::Model>(NodeVector{gather_v7}, ParameterVector{data, indices});
|
||||
model_ref = std::make_shared<ov::Model>(NodeVector{gather_v7}, ParameterVector{data});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, ConvertGather8toGather7_negative_indices) {
|
||||
{
|
||||
auto data = std::make_shared<opset1::Parameter>(element::f32, Shape{2, 3});
|
||||
auto indices = opset8::Constant::create(element::i32, Shape{2, 2}, {2, 1, 0, -1});
|
||||
auto axis = opset1::Constant::create(element::i32, Shape{1}, {1});
|
||||
int64_t batch_dims = 1;
|
||||
|
||||
auto gather_v8 = std::make_shared<opset8::Gather>(data, indices, axis, batch_dims);
|
||||
|
||||
model = std::make_shared<ov::Model>(NodeVector{gather_v8}, ParameterVector{data});
|
||||
|
||||
manager.register_pass<ov::pass::ConvertGather8ToGather7>();
|
||||
comparator.enable(FunctionsComparator::CONST_VALUES);
|
||||
}
|
||||
|
||||
{
|
||||
auto data = std::make_shared<opset1::Parameter>(element::f32, Shape{2, 3});
|
||||
auto indices = opset8::Constant::create(element::i32, Shape{2, 2}, {2, 1, 0, 2});
|
||||
auto axis = opset1::Constant::create(element::i32, Shape{1}, {1});
|
||||
int64_t batch_dims = 1;
|
||||
|
||||
auto gather_v7 = std::make_shared<opset7::Gather>(data, indices, axis, batch_dims);
|
||||
|
||||
model_ref = std::make_shared<ov::Model>(NodeVector{gather_v7}, ParameterVector{data});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, ConvertGather8toGather7_out_of_bound_indices) {
|
||||
{
|
||||
auto data = std::make_shared<opset1::Parameter>(element::f32, Shape{2, 3});
|
||||
auto indices = opset8::Constant::create(element::i32, Shape{2, 2}, {0, 1, 2, 3});
|
||||
auto axis = opset1::Constant::create(element::i32, Shape{1}, {1});
|
||||
int64_t batch_dims = 1;
|
||||
|
||||
auto gather_v8 = std::make_shared<opset8::Gather>(data, indices, axis, batch_dims);
|
||||
|
||||
model = std::make_shared<ov::Model>(NodeVector{gather_v8}, ParameterVector{data});
|
||||
|
||||
manager.register_pass<ov::pass::ConvertGather8ToGather7>();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, ConvertGather8toGather7_negative_axis) {
|
||||
{
|
||||
auto data = std::make_shared<opset1::Parameter>(element::f32, Shape{2, 3});
|
||||
auto indices = opset8::Constant::create(element::i32, Shape{2, 2}, {0, 1, 2, 0});
|
||||
auto axis = opset1::Constant::create(element::i32, Shape{1}, {-1});
|
||||
int64_t batch_dims = 1;
|
||||
|
||||
auto gather_v8 = std::make_shared<opset8::Gather>(data, indices, axis, batch_dims);
|
||||
|
||||
model = std::make_shared<ov::Model>(NodeVector{gather_v8}, ParameterVector{data});
|
||||
|
||||
manager.register_pass<ov::pass::ConvertGather8ToGather7>();
|
||||
}
|
||||
|
||||
{
|
||||
auto data = std::make_shared<opset1::Parameter>(element::f32, Shape{2, 3});
|
||||
auto indices = opset8::Constant::create(element::i32, Shape{2, 2}, {0, 1, 2, 0});
|
||||
auto axis = opset1::Constant::create(element::i32, Shape{1}, {-1});
|
||||
int64_t batch_dims = 1;
|
||||
|
||||
auto gather_v7 = std::make_shared<opset7::Gather>(data, indices, axis, batch_dims);
|
||||
|
||||
model_ref = std::make_shared<ov::Model>(NodeVector{gather_v7}, ParameterVector{data});
|
||||
}
|
||||
}
|
||||
|
@ -1,252 +0,0 @@
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "transformations/op_conversions/gather_normalize_negative_indices.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "common_test_utils/ov_test_utils.hpp"
|
||||
#include "openvino/core/model.hpp"
|
||||
#include "openvino/core/validation_util.hpp"
|
||||
#include "openvino/opsets/opset7.hpp"
|
||||
#include "openvino/pass/manager.hpp"
|
||||
#include "transformations/init_node_info.hpp"
|
||||
using namespace ov;
|
||||
using namespace testing;
|
||||
|
||||
TEST_F(TransformationTestsF, GatherNegativeIndicesNormalize) {
|
||||
{
|
||||
auto data = std::make_shared<opset7::Parameter>(element::f32, Shape{1, 15, 128});
|
||||
auto indices = opset7::Constant::create(element::i32, Shape{}, {-1});
|
||||
auto axis = opset7::Constant::create(element::i32, Shape{}, {1});
|
||||
|
||||
auto gather = std::make_shared<opset7::Gather>(data, indices, axis, 0);
|
||||
|
||||
model = std::make_shared<ov::Model>(NodeVector{gather}, ParameterVector{data});
|
||||
|
||||
manager.register_pass<ov::pass::GatherNegativeConstIndicesNormalize>();
|
||||
}
|
||||
|
||||
{
|
||||
auto indices_type = element::i32;
|
||||
|
||||
auto data = std::make_shared<opset7::Parameter>(element::f32, Shape{1, 15, 128});
|
||||
auto indices = opset7::Constant::create(indices_type, Shape{}, {-1});
|
||||
auto axis = opset7::Constant::create(element::i32, Shape{}, {1});
|
||||
|
||||
auto shape_of = std::make_shared<opset7::ShapeOf>(data, indices_type);
|
||||
auto input_gather = std::make_shared<opset7::Gather>(shape_of,
|
||||
opset7::Constant::create(indices_type, Shape{}, {1}),
|
||||
opset7::Constant::create(indices_type, Shape{}, {0}));
|
||||
auto add = std::make_shared<opset7::Add>(input_gather, indices);
|
||||
OPENVINO_SUPPRESS_DEPRECATED_START
|
||||
auto const_add = get_constant_from_source(add);
|
||||
OPENVINO_SUPPRESS_DEPRECATED_END
|
||||
if (const_add == nullptr)
|
||||
OPENVINO_THROW("indices should've been constant folded");
|
||||
auto gather = std::make_shared<opset7::Gather>(data, const_add, axis);
|
||||
|
||||
model_ref = std::make_shared<ov::Model>(NodeVector{gather}, ParameterVector{data});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, GatherNegativeIndicesNormalize_neg_axis) {
|
||||
{
|
||||
auto data = std::make_shared<opset7::Parameter>(element::f32, Shape{1, 15, 128});
|
||||
auto indices = opset7::Constant::create(element::i32, Shape{}, {-1});
|
||||
auto axis = opset7::Constant::create(element::i32, Shape{}, {-2});
|
||||
|
||||
auto gather = std::make_shared<opset7::Gather>(data, indices, axis, 0);
|
||||
|
||||
model = std::make_shared<ov::Model>(NodeVector{gather}, ParameterVector{data});
|
||||
|
||||
manager.register_pass<ov::pass::GatherNegativeConstIndicesNormalize>();
|
||||
}
|
||||
|
||||
{
|
||||
auto indices_type = element::i32;
|
||||
|
||||
auto data = std::make_shared<opset7::Parameter>(element::f32, Shape{1, 15, 128});
|
||||
auto indices = opset7::Constant::create(indices_type, Shape{}, {-1});
|
||||
auto axis = opset7::Constant::create(element::i32, Shape{}, {-2});
|
||||
|
||||
auto shape_of = std::make_shared<opset7::ShapeOf>(data, indices_type);
|
||||
auto input_gather = std::make_shared<opset7::Gather>(shape_of,
|
||||
opset7::Constant::create(indices_type, Shape{}, {1}),
|
||||
opset7::Constant::create(indices_type, Shape{}, {0}));
|
||||
auto add = std::make_shared<opset7::Add>(input_gather, indices);
|
||||
OPENVINO_SUPPRESS_DEPRECATED_START
|
||||
auto const_add = get_constant_from_source(add);
|
||||
OPENVINO_SUPPRESS_DEPRECATED_END
|
||||
if (const_add == nullptr)
|
||||
OPENVINO_THROW("indices should've been constant folded");
|
||||
auto gather = std::make_shared<opset7::Gather>(data, const_add, axis);
|
||||
|
||||
model_ref = std::make_shared<ov::Model>(NodeVector{gather}, ParameterVector{data});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, GatherNegativeIndicesNormalize_dif_input_types) {
|
||||
{
|
||||
auto data = std::make_shared<opset7::Parameter>(element::f32, Shape{1, 15, 128});
|
||||
auto indices = opset7::Constant::create(element::i32, Shape{}, {-1});
|
||||
auto axis = opset7::Constant::create(element::i64, Shape{}, {1});
|
||||
|
||||
auto gather = std::make_shared<opset7::Gather>(data, indices, axis, 0);
|
||||
|
||||
model = std::make_shared<ov::Model>(NodeVector{gather}, ParameterVector{data});
|
||||
|
||||
manager.register_pass<ov::pass::GatherNegativeConstIndicesNormalize>();
|
||||
}
|
||||
|
||||
{
|
||||
auto indices_type = element::i32;
|
||||
|
||||
auto data = std::make_shared<opset7::Parameter>(element::f32, Shape{1, 15, 128});
|
||||
auto indices = opset7::Constant::create(indices_type, Shape{}, {-1});
|
||||
auto axis = opset7::Constant::create(element::i64, Shape{}, {1});
|
||||
|
||||
auto shape_of = std::make_shared<opset7::ShapeOf>(data, indices_type);
|
||||
auto input_gather = std::make_shared<opset7::Gather>(shape_of,
|
||||
opset7::Constant::create(indices_type, Shape{}, {1}),
|
||||
opset7::Constant::create(indices_type, Shape{}, {0}));
|
||||
auto add = std::make_shared<opset7::Add>(input_gather, indices);
|
||||
OPENVINO_SUPPRESS_DEPRECATED_START
|
||||
auto const_add = get_constant_from_source(add);
|
||||
OPENVINO_SUPPRESS_DEPRECATED_END
|
||||
if (const_add == nullptr)
|
||||
OPENVINO_THROW("indices should've been constant folded");
|
||||
auto gather = std::make_shared<opset7::Gather>(data, const_add, axis);
|
||||
|
||||
model_ref = std::make_shared<ov::Model>(NodeVector{gather}, ParameterVector{data});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, GatherNegativeIndicesNormalize_static_axis_dim) {
|
||||
{
|
||||
auto data = std::make_shared<opset7::Parameter>(element::f32, PartialShape{DYN, 15, DYN});
|
||||
auto indices = opset7::Constant::create(element::i32, Shape{}, {-1});
|
||||
auto axis = opset7::Constant::create(element::i32, Shape{}, {1});
|
||||
|
||||
auto gather = std::make_shared<opset7::Gather>(data, indices, axis, 0);
|
||||
|
||||
model = std::make_shared<ov::Model>(NodeVector{gather}, ParameterVector{data});
|
||||
|
||||
manager.register_pass<ov::pass::GatherNegativeConstIndicesNormalize>();
|
||||
}
|
||||
|
||||
{
|
||||
auto indices_type = element::i32;
|
||||
|
||||
auto data = std::make_shared<opset7::Parameter>(element::f32, PartialShape{DYN, 15, DYN});
|
||||
auto indices = opset7::Constant::create(indices_type, Shape{}, {2});
|
||||
auto axis = opset7::Constant::create(element::i32, Shape{}, {1});
|
||||
|
||||
auto gather = std::make_shared<opset7::Gather>(data, indices, axis);
|
||||
model_ref = std::make_shared<ov::Model>(NodeVector{gather}, ParameterVector{data});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, GatherNegativeIndicesNormalize_static_axis_dim_neg_axis) {
|
||||
{
|
||||
auto data = std::make_shared<opset7::Parameter>(element::f32, PartialShape{DYN, 15, DYN});
|
||||
auto indices = opset7::Constant::create(element::i32, Shape{}, {-1});
|
||||
auto axis = opset7::Constant::create(element::i32, Shape{}, {-2});
|
||||
|
||||
auto gather = std::make_shared<opset7::Gather>(data, indices, axis, 0);
|
||||
|
||||
model = std::make_shared<ov::Model>(NodeVector{gather}, ParameterVector{data});
|
||||
|
||||
manager.register_pass<ov::pass::GatherNegativeConstIndicesNormalize>();
|
||||
}
|
||||
|
||||
{
|
||||
auto indices_type = element::i32;
|
||||
|
||||
auto data = std::make_shared<opset7::Parameter>(element::f32, PartialShape{DYN, 15, DYN});
|
||||
auto indices = opset7::Constant::create(indices_type, Shape{}, {2});
|
||||
auto axis = opset7::Constant::create(element::i32, Shape{}, {-2});
|
||||
|
||||
auto gather = std::make_shared<opset7::Gather>(data, indices, axis);
|
||||
|
||||
model_ref = std::make_shared<ov::Model>(NodeVector{gather}, ParameterVector{data});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, GatherNegativeIndicesNormalize_non_static_axis_dim) {
|
||||
{
|
||||
auto data = std::make_shared<opset7::Parameter>(element::f32, PartialShape{DYN, DYN, DYN});
|
||||
auto indices = opset7::Constant::create(element::i32, Shape{}, {-1});
|
||||
auto axis = opset7::Constant::create(element::i32, Shape{}, {1});
|
||||
|
||||
auto gather = std::make_shared<opset7::Gather>(data, indices, axis, 0);
|
||||
|
||||
model = std::make_shared<ov::Model>(NodeVector{gather}, ParameterVector{data});
|
||||
|
||||
manager.register_pass<ov::pass::GatherNegativeConstIndicesNormalize>();
|
||||
}
|
||||
|
||||
{
|
||||
auto indices_type = element::i32;
|
||||
|
||||
auto data = std::make_shared<opset7::Parameter>(element::f32, PartialShape{DYN, DYN, DYN});
|
||||
auto indices = opset7::Constant::create(indices_type, Shape{}, {-1});
|
||||
auto axis = opset7::Constant::create(element::i32, Shape{}, {1});
|
||||
|
||||
auto gather = std::make_shared<opset7::Gather>(data, indices, axis);
|
||||
|
||||
model_ref = std::make_shared<ov::Model>(NodeVector{gather}, ParameterVector{data});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, GatherNegativeIndicesNormalize_positive_ind) {
|
||||
{
|
||||
auto data = std::make_shared<opset7::Parameter>(element::f32, Shape{2, 3});
|
||||
auto indices = opset7::Constant::create(element::i32, Shape{}, {1});
|
||||
auto axis = opset7::Constant::create(element::i32, Shape{}, {0});
|
||||
|
||||
auto gather = std::make_shared<opset7::Gather>(data, indices, axis, 0);
|
||||
|
||||
model = std::make_shared<ov::Model>(NodeVector{gather}, ParameterVector{data});
|
||||
|
||||
manager.register_pass<ov::pass::GatherNegativeConstIndicesNormalize>();
|
||||
}
|
||||
|
||||
{
|
||||
auto data = std::make_shared<opset7::Parameter>(element::f32, Shape{2, 3});
|
||||
auto indices = opset7::Constant::create(element::i32, Shape{}, {1});
|
||||
auto axis = opset7::Constant::create(element::i32, Shape{}, {0});
|
||||
|
||||
auto gather = std::make_shared<opset7::Gather>(data, indices, axis);
|
||||
|
||||
model_ref = std::make_shared<ov::Model>(NodeVector{gather}, ParameterVector{data});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TransformationTestsF, GatherNegativeIndicesNormalize_non_static_rank) {
|
||||
{
|
||||
auto data = std::make_shared<opset7::Parameter>(element::f32, PartialShape::dynamic(Rank::dynamic()));
|
||||
auto indices = opset7::Constant::create(element::i32, Shape{}, {-1});
|
||||
auto axis = opset7::Constant::create(element::i32, Shape{}, {0});
|
||||
|
||||
auto gather = std::make_shared<opset7::Gather>(data, indices, axis, 0);
|
||||
|
||||
model = std::make_shared<ov::Model>(NodeVector{gather}, ParameterVector{data});
|
||||
|
||||
manager.register_pass<ov::pass::GatherNegativeConstIndicesNormalize>();
|
||||
}
|
||||
|
||||
{
|
||||
auto data = std::make_shared<opset7::Parameter>(element::f32, PartialShape::dynamic());
|
||||
auto indices = opset7::Constant::create(element::i32, Shape{}, {-1});
|
||||
auto axis = opset7::Constant::create(element::i32, Shape{}, {0});
|
||||
|
||||
auto gather = std::make_shared<opset7::Gather>(data, indices, axis);
|
||||
|
||||
model_ref = std::make_shared<ov::Model>(NodeVector{gather}, ParameterVector{data});
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@
|
||||
namespace {
|
||||
using ov::test::Gather7LayerTest;
|
||||
using ov::test::Gather8LayerTest;
|
||||
using ov::test::Gather8withIndicesDataLayerTest;
|
||||
|
||||
const std::vector<ov::element::Type> model_types = {
|
||||
ov::element::f32,
|
||||
@ -203,4 +204,29 @@ const auto gatherParamsVec3 = testing::Combine(
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(smoke_Vec3, Gather8LayerTest, gatherParamsVec3, Gather8LayerTest::getTestCaseName);
|
||||
|
||||
|
||||
const ov::test::gather7ParamsTuple dummyParams = {
|
||||
ov::test::static_shapes_to_test_representation(std::vector<ov::Shape>{{2, 3}}), // input shape
|
||||
ov::Shape{2, 2}, // indices shape
|
||||
std::tuple<int, int>{1, 1}, // axis, batch
|
||||
ov::element::f32, // model type
|
||||
ov::test::utils::DEVICE_CPU // device
|
||||
};
|
||||
|
||||
const std::vector<std::vector<int64_t>> indicesData = {
|
||||
{0, 1, 2, 0}, // positive in bound
|
||||
{-1, -2, -3, -1}, // negative in bound
|
||||
{-1, 0, 1, 2}, // positive and negative in bound
|
||||
{0, 1, 2, 3}, // positive out of bound
|
||||
{-1, -2, -3, -4}, // negative out of bound
|
||||
{0, 4, -4, 0}, // positive and negative out of bound
|
||||
};
|
||||
|
||||
const auto gatherWithIndicesParams = testing::Combine(
|
||||
testing::Values(dummyParams),
|
||||
testing::ValuesIn(indicesData)
|
||||
);
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(smoke, Gather8withIndicesDataLayerTest, gatherWithIndicesParams, Gather8withIndicesDataLayerTest::getTestCaseName);
|
||||
|
||||
} // namespace
|
||||
|
@ -177,8 +177,6 @@ std::vector<std::string> disabledTestPatterns() {
|
||||
R"(.*(Hetero).*InferRequestPreprocessTest.*SetPreProcessToInferRequest.*)",
|
||||
// TODO: for 22.2 (Issue 68949)
|
||||
R"(.*smoke_AutoBatching_CPU/AutoBatching_Test_DetectionOutput.*)",
|
||||
// Issue: 117837
|
||||
R"(.*smoke_4D_out_of_range/GatherInPlaceLayerTestCPU.*_indices=\(\-15\).*)",
|
||||
// Issue: 120222
|
||||
R"(.*smoke_TopK/TopKLayerTest.Inference.*_k=1_axis=3_.*_modelType=f16_trgDev=CPU.*)",
|
||||
R"(.*smoke_TopK/TopKLayerTest.Inference.*_k=7_axis=3_.*_modelType=f16_trgDev=CPU.*)",
|
||||
|
@ -578,4 +578,32 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
Gather8IndiceScalarLayerTest::getTestCaseName
|
||||
);
|
||||
|
||||
gather7ParamsTuple dummyParams = {
|
||||
std::vector<size_t>{2, 3},
|
||||
std::vector<size_t>{2, 2},
|
||||
std::tuple<int, int>{1, 1},
|
||||
InferenceEngine::Precision::FP32,
|
||||
InferenceEngine::Precision::UNSPECIFIED,
|
||||
InferenceEngine::Precision::UNSPECIFIED,
|
||||
InferenceEngine::Layout::ANY,
|
||||
InferenceEngine::Layout::ANY,
|
||||
ov::test::utils::DEVICE_GPU,
|
||||
};
|
||||
|
||||
std::vector<std::vector<int>> indicesData = {
|
||||
{0, 1, 2, 0}, // positive in bound
|
||||
{-1, -2, -3, -1}, // negative in bound
|
||||
{-1, 0, 1, 2}, // positive and negative in bound
|
||||
{0, 1, 2, 3}, // positive out of bound
|
||||
{-1, -2, -3, -4}, // negative out of bound
|
||||
{0, 4, -4, 0}, // positive and negative out of bound
|
||||
};
|
||||
|
||||
const auto gatherWithIndicesParams = testing::Combine(
|
||||
testing::Values(dummyParams),
|
||||
testing::ValuesIn(indicesData)
|
||||
);
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(smoke, Gather8withIndicesDataLayerTest, gatherWithIndicesParams, Gather8withIndicesDataLayerTest::getTestCaseName);
|
||||
|
||||
} // namespace
|
||||
|
@ -24,4 +24,8 @@ TEST_P(Gather8IndiceScalarLayerTest, CompareWithRefs) {
|
||||
Run();
|
||||
};
|
||||
|
||||
TEST_P(Gather8withIndicesDataLayerTest, CompareWithRefs) {
|
||||
Run();
|
||||
};
|
||||
|
||||
} // namespace LayerTestsDefinitions
|
||||
|
@ -23,5 +23,9 @@ TEST_P(Gather8LayerTest, Inference) {
|
||||
TEST_P(Gather8IndiceScalarLayerTest, Inference) {
|
||||
run();
|
||||
};
|
||||
|
||||
TEST_P(Gather8withIndicesDataLayerTest, Inference) {
|
||||
run();
|
||||
};
|
||||
} // namespace test
|
||||
} // namespace ov
|
||||
|
@ -83,4 +83,18 @@ protected:
|
||||
void SetUp() override;
|
||||
};
|
||||
|
||||
typedef std::tuple<
|
||||
gather7ParamsTuple,
|
||||
std::vector<int> // indices data
|
||||
> gather8withIndicesDataParamsTuple;
|
||||
|
||||
class Gather8withIndicesDataLayerTest : public testing::WithParamInterface<gather8withIndicesDataParamsTuple>,
|
||||
virtual public LayerTestsUtils::LayerTestsCommon {
|
||||
public:
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<gather8withIndicesDataParamsTuple>& obj);
|
||||
|
||||
protected:
|
||||
void SetUp() override;
|
||||
};
|
||||
|
||||
} // namespace LayerTestsDefinitions
|
||||
|
@ -63,5 +63,20 @@ public:
|
||||
protected:
|
||||
void SetUp() override;
|
||||
};
|
||||
|
||||
typedef std::tuple<
|
||||
gather7ParamsTuple,
|
||||
std::vector<int64_t> // indices data
|
||||
> gather8withIndicesDataParamsTuple;
|
||||
|
||||
class Gather8withIndicesDataLayerTest : public testing::WithParamInterface<gather8withIndicesDataParamsTuple>,
|
||||
virtual public ov::test::SubgraphBaseTest {
|
||||
public:
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<gather8withIndicesDataParamsTuple>& obj);
|
||||
|
||||
protected:
|
||||
void SetUp() override;
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
} // namespace ov
|
||||
|
@ -178,4 +178,56 @@ void Gather8IndiceScalarLayerTest::SetUp() {
|
||||
function = std::make_shared<ngraph::Function>(results, functionParams, "gather");
|
||||
}
|
||||
|
||||
std::string Gather8withIndicesDataLayerTest::getTestCaseName(const testing::TestParamInfo<gather8withIndicesDataParamsTuple>& obj) {
|
||||
gather7ParamsTuple basicParams;
|
||||
std::vector<int> indicesData;
|
||||
std::tie(basicParams, indicesData) = obj.param;
|
||||
|
||||
std::tuple<int, int> axis_batchIdx;
|
||||
std::vector<int> indices;
|
||||
std::vector<size_t> indicesShape, inputShape;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
InferenceEngine::Precision inPrc, outPrc;
|
||||
InferenceEngine::Layout inLayout, outLayout;
|
||||
std::string targetName;
|
||||
std::tie(inputShape, indicesShape, axis_batchIdx, netPrecision, inPrc, outPrc, inLayout, outLayout, targetName) = basicParams;
|
||||
std::ostringstream result;
|
||||
result << "IS=" << ov::test::utils::vec2str(inputShape) << "_";
|
||||
result << "indicesShape=" << ov::test::utils::vec2str(indicesShape) << "_";
|
||||
result << "axis=" << std::get<0>(axis_batchIdx) << "_";
|
||||
result << "batchIdx=" << std::get<1>(axis_batchIdx) << "_";
|
||||
result << "netPRC=" << netPrecision.name() << "_";
|
||||
result << "inPRC=" << inPrc.name() << "_";
|
||||
result << "outPRC=" << outPrc.name() << "_";
|
||||
result << "inL=" << inLayout << "_";
|
||||
result << "outL=" << outLayout << "_";
|
||||
result << "trgDev=" << targetName << "_";
|
||||
|
||||
result << "indicesData=" << ov::test::utils::vec2str(indicesData) << "_";
|
||||
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void Gather8withIndicesDataLayerTest::SetUp() {
|
||||
gather7ParamsTuple basicParams;
|
||||
std::vector<int> indicesData;
|
||||
std::tie(basicParams, indicesData) = GetParam();
|
||||
|
||||
std::tuple<int, int> axis_batchIdx;
|
||||
std::vector<size_t> indicesShape;
|
||||
std::vector<size_t> inputShape;
|
||||
InferenceEngine::Precision netPrecision;
|
||||
std::tie(inputShape, indicesShape, axis_batchIdx, netPrecision, inPrc, outPrc, inLayout, outLayout, targetDevice) = basicParams;
|
||||
int axis = std::get<0>(axis_batchIdx);
|
||||
int batchIdx = std::get<1>(axis_batchIdx);
|
||||
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
|
||||
ov::ParameterVector functionParams {std::make_shared<ov::op::v0::Parameter>(ngPrc, ov::Shape(inputShape))};
|
||||
auto paramOuts = ngraph::helpers::convert2OutputVector(ngraph::helpers::castOps2Nodes<ngraph::op::Parameter>(functionParams));
|
||||
auto indicesNode = ngraph::builder::makeConstant<int>(ngraph::element::i64, indicesShape, indicesData);
|
||||
auto axisNode = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape({}), { axis });
|
||||
auto gather = std::make_shared<ngraph::opset8::Gather>(paramOuts[0], indicesNode, axisNode, batchIdx);
|
||||
ngraph::ResultVector results{ std::make_shared<ngraph::opset8::Result>(gather) };
|
||||
function = std::make_shared<ngraph::Function>(results, functionParams, "gather");
|
||||
}
|
||||
|
||||
} // namespace LayerTestsDefinitions
|
||||
|
@ -167,5 +167,76 @@ void Gather8IndiceScalarLayerTest::SetUp() {
|
||||
auto result = std::make_shared<ov::op::v0::Result>(gather);
|
||||
function = std::make_shared<ov::Model>(result, ov::ParameterVector{param}, "gather");
|
||||
}
|
||||
|
||||
std::string Gather8withIndicesDataLayerTest::getTestCaseName(const testing::TestParamInfo<gather8withIndicesDataParamsTuple>& obj) {
|
||||
gather7ParamsTuple basicParams;
|
||||
std::vector<int64_t> indicesData;
|
||||
std::tie(basicParams, indicesData) = obj.param;
|
||||
|
||||
std::tuple<int, int> axis_batch_idx;
|
||||
std::vector<int> indices;
|
||||
ov::Shape indices_shape;
|
||||
std::vector<InputShape> shapes;
|
||||
ov::element::Type model_type;
|
||||
std::string device_name;
|
||||
std::tie(shapes, indices_shape, axis_batch_idx, model_type, device_name) = basicParams;
|
||||
|
||||
std::ostringstream result;
|
||||
result << "IS=(";
|
||||
for (size_t i = 0lu; i < shapes.size(); i++) {
|
||||
result << ov::test::utils::partialShape2str({shapes[i].first}) << (i < shapes.size() - 1lu ? "_" : "");
|
||||
}
|
||||
result << ")_TS=";
|
||||
for (size_t i = 0lu; i < shapes.front().second.size(); i++) {
|
||||
result << "{";
|
||||
for (size_t j = 0lu; j < shapes.size(); j++) {
|
||||
result << ov::test::utils::vec2str(shapes[j].second[i]) << (j < shapes.size() - 1lu ? "_" : "");
|
||||
}
|
||||
result << "}_";
|
||||
}
|
||||
result << "axis=" << std::get<0>(axis_batch_idx) << "_";
|
||||
result << "batch_idx=" << std::get<1>(axis_batch_idx) << "_";
|
||||
result << "indices_shape=" << ov::test::utils::vec2str(indices_shape) << "_";
|
||||
result << "netPRC=" << model_type.get_type_name() << "_";
|
||||
result << "trgDev=" << device_name << "_";
|
||||
|
||||
result << "indicesData=" << ov::test::utils::vec2str(indicesData) << "_";
|
||||
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void Gather8withIndicesDataLayerTest::SetUp() {
|
||||
gather7ParamsTuple basicParams;
|
||||
std::vector<int64_t> indicesData;
|
||||
std::tie(basicParams, indicesData) = GetParam();
|
||||
|
||||
std::tuple<int, int> axis_batch_idx;
|
||||
ov::Shape indices_shape;
|
||||
std::vector<InputShape> shapes;
|
||||
ov::element::Type model_type;
|
||||
std::tie(shapes, indices_shape, axis_batch_idx, model_type, targetDevice) = basicParams;
|
||||
init_input_shapes(shapes);
|
||||
|
||||
int axis = std::get<0>(axis_batch_idx);
|
||||
int batch_idx = std::get<1>(axis_batch_idx);
|
||||
|
||||
auto param = std::make_shared<ov::op::v0::Parameter>(model_type, inputDynamicShapes.front());
|
||||
|
||||
// create indices tensor and fill data
|
||||
ov::Tensor indices_node_tensor{ov::element::i64, indices_shape};
|
||||
auto indices_tensor_data = indices_node_tensor.data<int64_t>();
|
||||
for (size_t i = 0; i < shape_size(indices_shape); i++) {
|
||||
indices_tensor_data[i] = indicesData[i];
|
||||
}
|
||||
|
||||
auto indices_node = std::make_shared<ov::op::v0::Constant>(indices_node_tensor);
|
||||
auto axis_node = ov::op::v0::Constant::create(ov::element::i64, ov::Shape(), {axis});
|
||||
|
||||
auto gather = std::make_shared<ov::op::v8::Gather>(param, indices_node, axis_node, batch_idx);
|
||||
|
||||
auto result = std::make_shared<ov::op::v0::Result>(gather);
|
||||
function = std::make_shared<ov::Model>(result, ov::ParameterVector{param}, "gather");
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace ov
|
||||
|
Loading…
Reference in New Issue
Block a user