[nGraph] Gather 7 evaluate (#5088)
* initial working solution * constant_folding for Gather-7 successfully enabled * successfuuly added remaining unittests * removed redundant evaluate from private * fixed evaluate for dynamic axis * fix pre-commit for KMB: added default batch_dims=0 to runtime/reference * clang_format_fix * added include ngraph/shape.hpp to fix compilation for onednn-plugin * temporary removed out of bound check for gather * removed optional argument for batch_dims * added const * finally successfully run on ARM: removed redundant declaration * style fix * changed argument types from size_t -> int64_t * changed back to size_t
This commit is contained in:
parent
1662ee0647
commit
6d2740a335
@ -81,6 +81,16 @@ namespace ngraph
|
|||||||
int64_t get_axis() const;
|
int64_t get_axis() const;
|
||||||
bool is_axis_set() const;
|
bool is_axis_set() const;
|
||||||
|
|
||||||
|
bool evaluate_gather(const HostTensorVector& outputs,
|
||||||
|
const HostTensorVector& inputs) const;
|
||||||
|
bool evaluate(const HostTensorVector& outputs,
|
||||||
|
const HostTensorVector& inputs) const override;
|
||||||
|
bool evaluate_lower(const HostTensorVector& outputs) const override;
|
||||||
|
bool evaluate_upper(const HostTensorVector& outputs) const override;
|
||||||
|
|
||||||
|
bool constant_fold(OutputVector& output_values,
|
||||||
|
const OutputVector& inputs_values) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int64_t m_batch_dims = 0;
|
int64_t m_batch_dims = 0;
|
||||||
};
|
};
|
||||||
|
@ -6,9 +6,7 @@
|
|||||||
|
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
#include "ngraph/coordinate_range.hpp"
|
#include "ngraph/shape.hpp"
|
||||||
#include "ngraph/coordinate_transform.hpp"
|
|
||||||
#include "ngraph/runtime/reference/gather_nd.hpp"
|
|
||||||
#include "utils/span.hpp"
|
#include "utils/span.hpp"
|
||||||
|
|
||||||
namespace ngraph
|
namespace ngraph
|
||||||
@ -17,107 +15,54 @@ namespace ngraph
|
|||||||
{
|
{
|
||||||
namespace reference
|
namespace reference
|
||||||
{
|
{
|
||||||
namespace
|
|
||||||
{
|
|
||||||
template <typename Container>
|
|
||||||
Shape to_shape(const Container& c)
|
|
||||||
{
|
|
||||||
return Shape(begin(c), end(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Container>
|
|
||||||
std::vector<size_t>
|
|
||||||
join(const Container& c1, const Container& c2, const Container& c3)
|
|
||||||
{
|
|
||||||
using container_value_type =
|
|
||||||
typename std::remove_cv<typename Container::value_type>::type;
|
|
||||||
static_assert(std::is_same<container_value_type, size_t>::value,
|
|
||||||
"Expect same type in container");
|
|
||||||
std::vector<size_t> ret;
|
|
||||||
ret.reserve(c1.size() + c2.size() + c3.size());
|
|
||||||
std::copy(begin(c1), end(c1), std::back_inserter(ret));
|
|
||||||
std::copy(begin(c2), end(c2), std::back_inserter(ret));
|
|
||||||
std::copy(begin(c3), end(c3), std::back_inserter(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto only_one = [] { return coordinates::index(Shape{1}); };
|
|
||||||
} // namespace
|
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
void gather(const T* const params,
|
void gather(const T* const data,
|
||||||
const U* const indices,
|
const U* const indices,
|
||||||
T* const out,
|
T* out,
|
||||||
const Shape& params_shape,
|
const Shape& data_shape,
|
||||||
const Shape& indices_shape,
|
const Shape& indices_shape,
|
||||||
const Shape& out_shape,
|
const Shape& out_shape,
|
||||||
size_t axis)
|
size_t axis,
|
||||||
|
size_t batch_dims = 0)
|
||||||
{
|
{
|
||||||
using std::next;
|
// flattened shapes
|
||||||
assert(std::memset(out, 0, shape_size(out_shape) * sizeof(T)));
|
int64_t batch_size = shape_size(span(data_shape).subspan(0, batch_dims));
|
||||||
|
int64_t outer_size =
|
||||||
|
shape_size(span(data_shape).subspan(batch_dims, axis - batch_dims));
|
||||||
|
int64_t indices_size = shape_size(span(indices_shape).subspan(batch_dims));
|
||||||
|
int64_t inner_size = shape_size(span(data_shape).subspan(axis + 1));
|
||||||
|
|
||||||
const auto params_axes_part = span(params_shape).subspan(0, axis);
|
int64_t batch_data_mul = shape_size(span(data_shape).subspan(batch_dims));
|
||||||
|
int64_t batch_out_mul = shape_size(span(out_shape).subspan(batch_dims));
|
||||||
|
int64_t batch_indices_mul = shape_size(span(indices_shape).subspan(batch_dims));
|
||||||
|
|
||||||
NGRAPH_CHECK(params_shape.size() >= axis, "Not enough axes in param_shape.");
|
int64_t axis_size = data_shape[axis];
|
||||||
|
int64_t data_offset, out_offset, idx;
|
||||||
|
|
||||||
const auto remainder_part_shape = span(params_shape).subspan(axis + 1);
|
for (int64_t batch = 0; batch < batch_size; batch++)
|
||||||
|
for (int64_t outer_idx = 0; outer_idx < outer_size; outer_idx++)
|
||||||
const auto found_out_shape =
|
|
||||||
join(params_axes_part, span(indices_shape), remainder_part_shape);
|
|
||||||
|
|
||||||
NGRAPH_CHECK(found_out_shape == out_shape,
|
|
||||||
"Output shape mismatch with calculations");
|
|
||||||
|
|
||||||
const auto batch_shape = span(params_shape).subspan(axis);
|
|
||||||
|
|
||||||
const auto batch_size = shape_size(batch_shape);
|
|
||||||
|
|
||||||
const auto copy_size = shape_size(remainder_part_shape);
|
|
||||||
|
|
||||||
const size_t copy_round_in_batch =
|
|
||||||
indices_shape.size() > 1
|
|
||||||
? shape_size(span(indices_shape.data(), indices_shape.size() - 1))
|
|
||||||
: 1;
|
|
||||||
const size_t round_batch_offset = indices_shape.empty() ? 1 : indices_shape.back();
|
|
||||||
|
|
||||||
auto dst = out;
|
|
||||||
|
|
||||||
auto gather_range = params_axes_part.empty()
|
|
||||||
? only_one()
|
|
||||||
: coordinates::index(to_shape(params_axes_part));
|
|
||||||
for (auto i : gather_range)
|
|
||||||
{
|
{
|
||||||
auto batch_index = i.begin_index;
|
data_offset = batch_data_mul * batch + inner_size * axis_size * outer_idx;
|
||||||
for (size_t batch = 0; batch != i.element_number;
|
out_offset = batch_out_mul * batch + indices_size * inner_size * outer_idx;
|
||||||
batch_index += i.step, ++batch)
|
for (int64_t i = 0; i < indices_size; i++)
|
||||||
{
|
{
|
||||||
const auto batch_offset = batch_index * batch_size;
|
idx = indices[i + batch_indices_mul * batch];
|
||||||
assert(batch_offset < shape_size(params_shape));
|
// clang-format off
|
||||||
for (size_t round = 0; round != copy_round_in_batch; ++round)
|
// todo: check if bound check is needed
|
||||||
{
|
// if (idx >= axis_size || (idx < 0 && -idx >= axis_size))
|
||||||
const U* input_indices = indices + round * round_batch_offset;
|
// throw std::domain_error{"indices values of Gather exceed size along axis"};
|
||||||
const auto indices_no =
|
// clang-format on
|
||||||
indices_shape.empty() ? 1 : indices_shape.back();
|
if (idx < 0)
|
||||||
|
idx += axis_size;
|
||||||
|
|
||||||
assert(!batch_shape.empty());
|
const auto src_begin = std::next(data, data_offset + inner_size * idx);
|
||||||
for (size_t ii = 0; ii != indices_no; ++ii)
|
const auto src_end = std::next(src_begin, inner_size);
|
||||||
{
|
const auto out_ptr = std::next(out, out_offset + inner_size * i);
|
||||||
const auto positive_input_index =
|
std::copy(src_begin, src_end, out_ptr);
|
||||||
input_indices[ii] < 0 ? batch_shape.front() + input_indices[ii]
|
|
||||||
: input_indices[ii];
|
|
||||||
|
|
||||||
const auto src_offset =
|
|
||||||
batch_offset + copy_size * positive_input_index;
|
|
||||||
|
|
||||||
const auto src_begin = next(params, src_offset);
|
|
||||||
const auto src_end = next(src_begin, copy_size);
|
|
||||||
|
|
||||||
std::copy(src_begin, src_end, dst);
|
|
||||||
dst += copy_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace reference
|
} // namespace reference
|
||||||
} // namespace runtime
|
} // namespace runtime
|
||||||
} // namespace ngraph
|
} // namespace ngraph
|
||||||
|
@ -202,8 +202,8 @@ void op::v7::Gather::validate_and_infer_types()
|
|||||||
{
|
{
|
||||||
NODE_VALIDATION_CHECK(
|
NODE_VALIDATION_CHECK(
|
||||||
this,
|
this,
|
||||||
batch_dims < indices_rank.get_length(),
|
batch_dims <= indices_rank.get_length(),
|
||||||
"The batch_dims must be < indices_rank. But instead got: batch_dims = ",
|
"The batch_dims must be <= indices_rank. But instead got: batch_dims = ",
|
||||||
batch_dims,
|
batch_dims,
|
||||||
", indices_rank = ",
|
", indices_rank = ",
|
||||||
indices_rank.get_length());
|
indices_rank.get_length());
|
||||||
@ -315,18 +315,19 @@ namespace gather
|
|||||||
bool evaluate(const HostTensorPtr& arg0,
|
bool evaluate(const HostTensorPtr& arg0,
|
||||||
const HostTensorPtr& arg1,
|
const HostTensorPtr& arg1,
|
||||||
const HostTensorPtr& out,
|
const HostTensorPtr& out,
|
||||||
size_t axis)
|
size_t axis,
|
||||||
|
size_t batch_dims)
|
||||||
{
|
{
|
||||||
using T = typename element_type_traits<ET>::value_type;
|
using T = typename element_type_traits<ET>::value_type;
|
||||||
Shape params_shape = arg0->get_shape();
|
Shape params_shape = arg0->get_shape();
|
||||||
Shape indices_shape = arg1->get_shape();
|
Shape indices_shape = arg1->get_shape();
|
||||||
Shape out_shape(params_shape.size() + indices_shape.size() - 1);
|
Shape out_shape(params_shape.size() + indices_shape.size() - 1 - batch_dims);
|
||||||
uint64_t i = 0;
|
uint64_t i = 0;
|
||||||
for (; i < axis; i++)
|
for (; i < axis; i++)
|
||||||
{
|
{
|
||||||
out_shape[i] = params_shape[i];
|
out_shape[i] = params_shape[i];
|
||||||
}
|
}
|
||||||
for (uint64_t j = 0; j < indices_shape.size(); i++, j++)
|
for (uint64_t j = batch_dims; j < indices_shape.size(); i++, j++)
|
||||||
{
|
{
|
||||||
out_shape[i] = indices_shape[j];
|
out_shape[i] = indices_shape[j];
|
||||||
}
|
}
|
||||||
@ -345,7 +346,8 @@ namespace gather
|
|||||||
arg0->get_shape(),
|
arg0->get_shape(),
|
||||||
arg1->get_shape(),
|
arg1->get_shape(),
|
||||||
out->get_shape(),
|
out->get_shape(),
|
||||||
axis);
|
axis,
|
||||||
|
batch_dims);
|
||||||
}
|
}
|
||||||
else if (arg1->get_element_type() == element::i32)
|
else if (arg1->get_element_type() == element::i32)
|
||||||
{
|
{
|
||||||
@ -355,7 +357,8 @@ namespace gather
|
|||||||
arg0->get_shape(),
|
arg0->get_shape(),
|
||||||
arg1->get_shape(),
|
arg1->get_shape(),
|
||||||
out->get_shape(),
|
out->get_shape(),
|
||||||
axis);
|
axis,
|
||||||
|
batch_dims);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -368,19 +371,20 @@ namespace gather
|
|||||||
bool evaluate_gather(const HostTensorPtr& arg0,
|
bool evaluate_gather(const HostTensorPtr& arg0,
|
||||||
const HostTensorPtr& arg1,
|
const HostTensorPtr& arg1,
|
||||||
const HostTensorPtr& out,
|
const HostTensorPtr& out,
|
||||||
size_t axis)
|
size_t axis,
|
||||||
|
size_t batch_dims = 0)
|
||||||
{
|
{
|
||||||
bool rc = true;
|
bool rc = true;
|
||||||
|
|
||||||
switch (out->get_element_type())
|
switch (out->get_element_type())
|
||||||
{
|
{
|
||||||
NGRAPH_TYPE_CASE(evaluate_gather, i32, arg0, arg1, out, axis);
|
NGRAPH_TYPE_CASE(evaluate_gather, i32, arg0, arg1, out, axis, batch_dims);
|
||||||
NGRAPH_TYPE_CASE(evaluate_gather, i64, arg0, arg1, out, axis);
|
NGRAPH_TYPE_CASE(evaluate_gather, i64, arg0, arg1, out, axis, batch_dims);
|
||||||
NGRAPH_TYPE_CASE(evaluate_gather, u32, arg0, arg1, out, axis);
|
NGRAPH_TYPE_CASE(evaluate_gather, u32, arg0, arg1, out, axis, batch_dims);
|
||||||
NGRAPH_TYPE_CASE(evaluate_gather, u64, arg0, arg1, out, axis);
|
NGRAPH_TYPE_CASE(evaluate_gather, u64, arg0, arg1, out, axis, batch_dims);
|
||||||
NGRAPH_TYPE_CASE(evaluate_gather, f16, arg0, arg1, out, axis);
|
NGRAPH_TYPE_CASE(evaluate_gather, f16, arg0, arg1, out, axis, batch_dims);
|
||||||
NGRAPH_TYPE_CASE(evaluate_gather, f32, arg0, arg1, out, axis);
|
NGRAPH_TYPE_CASE(evaluate_gather, f32, arg0, arg1, out, axis, batch_dims);
|
||||||
NGRAPH_TYPE_CASE(evaluate_gather, boolean, arg0, arg1, out, axis);
|
NGRAPH_TYPE_CASE(evaluate_gather, boolean, arg0, arg1, out, axis, batch_dims);
|
||||||
default: rc = false; break;
|
default: rc = false; break;
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
@ -518,3 +522,63 @@ bool op::v1::Gather::constant_fold(OutputVector& output_values, const OutputVect
|
|||||||
output_values, input_values, get_output_partial_shape(0));
|
output_values, input_values, get_output_partial_shape(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool op::v7::Gather::evaluate_gather(const HostTensorVector& outputs,
|
||||||
|
const HostTensorVector& inputs) const
|
||||||
|
{
|
||||||
|
int64_t axis = 0;
|
||||||
|
switch (inputs[2]->get_element_type())
|
||||||
|
{
|
||||||
|
case element::Type_t::i32: axis = inputs[2]->get_data_ptr<element::Type_t::i32>()[0]; break;
|
||||||
|
case element::Type_t::i64: axis = inputs[2]->get_data_ptr<element::Type_t::i64>()[0]; break;
|
||||||
|
default: throw ngraph_error("axis must be of int32 or int64 type.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (axis < 0)
|
||||||
|
{
|
||||||
|
const auto& input_rank = get_input_partial_shape(0).rank();
|
||||||
|
if (input_rank.is_static())
|
||||||
|
{
|
||||||
|
axis += input_rank.get_length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gather::evaluate_gather(inputs[0], inputs[1], outputs[0], axis, get_batch_dims());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool op::v7::Gather::evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs) const
|
||||||
|
{
|
||||||
|
NGRAPH_OP_SCOPE(v7_Gather_evaluate);
|
||||||
|
NGRAPH_CHECK(this, validate_host_tensor_vector(inputs, 3));
|
||||||
|
NGRAPH_CHECK(this, validate_host_tensor_vector(outputs, 1));
|
||||||
|
return evaluate_gather(outputs, inputs);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool op::v7::Gather::evaluate_lower(const HostTensorVector& output_values) const
|
||||||
|
{
|
||||||
|
if (!input_value(1).get_tensor().has_and_set_bound() ||
|
||||||
|
!input_value(2).get_tensor().has_and_set_bound())
|
||||||
|
return false;
|
||||||
|
return default_lower_bound_evaluator(this, output_values);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool op::v7::Gather::evaluate_upper(const HostTensorVector& output_values) const
|
||||||
|
{
|
||||||
|
if (!input_value(1).get_tensor().has_and_set_bound() ||
|
||||||
|
!input_value(2).get_tensor().has_and_set_bound())
|
||||||
|
return false;
|
||||||
|
return default_upper_bound_evaluator(this, output_values);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool op::v7::Gather::constant_fold(OutputVector& output_values, const OutputVector& input_values)
|
||||||
|
{
|
||||||
|
// try the regular constant folding just for the Gather node
|
||||||
|
if (Node::constant_fold(output_values, input_values))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return gather::cf_gather_with_subgraph(
|
||||||
|
output_values, input_values, get_output_partial_shape(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -450,11 +450,19 @@ NGRAPH_TEST(${BACKEND_NAME}, gather_axis_0_int32)
|
|||||||
auto A = op::Constant::create(element::i64, Shape{}, {0});
|
auto A = op::Constant::create(element::i64, Shape{}, {0});
|
||||||
auto G = make_shared<op::v1::Gather>(P, I, A);
|
auto G = make_shared<op::v1::Gather>(P, I, A);
|
||||||
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
// clang-format off
|
||||||
auto test_case = test::TestCase<TestEngine>(f);
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
test_case.add_input<int32_t>({10, 11, 20, 21, 30, 31});
|
test_case.add_input<int32_t>({10, 11,
|
||||||
test_case.add_input<int32_t>({0, 1, 1, 2});
|
20, 21,
|
||||||
test_case.add_expected_output<int32_t>(out_shape, {10, 11, 20, 21, 20, 21, 30, 31});
|
30, 31});
|
||||||
|
test_case.add_input<int32_t>({0, 1,
|
||||||
|
1, 2});
|
||||||
|
test_case.add_expected_output<int32_t>(out_shape, {10, 11,
|
||||||
|
20, 21,
|
||||||
|
|
||||||
|
20, 21,
|
||||||
|
30, 31});
|
||||||
|
// clang-format on
|
||||||
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -548,7 +556,560 @@ NGRAPH_TEST(${BACKEND_NAME}, gather_axis_0_uint64)
|
|||||||
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
NGRAPH_TEST(${BACKEND_NAME}, gather_axis_0_bool)
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_4d_indices_axis_0_uint8)
|
||||||
|
{
|
||||||
|
Shape data_shape{3, 2};
|
||||||
|
Shape indices_shape{2, 2, 3, 4};
|
||||||
|
Shape out_shape{2, 2, 3, 4, 2};
|
||||||
|
auto P = make_shared<op::Parameter>(element::u8, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i32, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {0});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
test_case.add_input<uint8_t>({10, 11, 20, 21, 30, 31});
|
||||||
|
test_case.add_input<int32_t>({0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2,
|
||||||
|
0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2,
|
||||||
|
0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2});
|
||||||
|
test_case.add_expected_output<uint8_t>(
|
||||||
|
out_shape, {10, 11, 20, 21, 20, 21, 30, 31, 10, 11, 20, 21, 20, 21, 30, 31, 10, 11, 20, 21,
|
||||||
|
20, 21, 30, 31, 10, 11, 20, 21, 20, 21, 30, 31, 10, 11, 20, 21, 20, 21, 30, 31,
|
||||||
|
10, 11, 20, 21, 20, 21, 30, 31, 10, 11, 20, 21, 20, 21, 30, 31, 10, 11, 20, 21,
|
||||||
|
20, 21, 30, 31, 10, 11, 20, 21, 20, 21, 30, 31, 10, 11, 20, 21, 20, 21, 30, 31,
|
||||||
|
10, 11, 20, 21, 20, 21, 30, 31, 10, 11, 20, 21, 20, 21, 30, 31});
|
||||||
|
test_case.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_4d_indices_axis_0_2d_input)
|
||||||
|
{
|
||||||
|
Shape data_shape{3, 2};
|
||||||
|
Shape indices_shape{2, 2, 3, 4};
|
||||||
|
Shape out_shape{2, 2, 3, 4, 2};
|
||||||
|
auto P = make_shared<op::Parameter>(element::f32, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i32, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {0});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
test_case.add_input<float>({1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f});
|
||||||
|
|
||||||
|
test_case.add_input<int32_t>({0, 1, 1, 2,
|
||||||
|
0, 1, 1, 2,
|
||||||
|
0, 1, 1, 2,
|
||||||
|
|
||||||
|
0, 1, 1, 2,
|
||||||
|
0, 1, 1, 2,
|
||||||
|
0, 1, 1, 2,
|
||||||
|
|
||||||
|
|
||||||
|
0, 1, 1, 2,
|
||||||
|
0, 1, 1, 2,
|
||||||
|
0, 1, 1, 2,
|
||||||
|
|
||||||
|
0, 1, 1, 2,
|
||||||
|
0, 1, 1, 2,
|
||||||
|
0, 1, 1, 2});
|
||||||
|
test_case.add_expected_output<float>(
|
||||||
|
out_shape,
|
||||||
|
{ 1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f,
|
||||||
|
|
||||||
|
1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f,
|
||||||
|
|
||||||
|
1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f,
|
||||||
|
|
||||||
|
|
||||||
|
1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f,
|
||||||
|
|
||||||
|
1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f,
|
||||||
|
|
||||||
|
1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f,
|
||||||
|
|
||||||
|
|
||||||
|
1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f,
|
||||||
|
|
||||||
|
1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f,
|
||||||
|
|
||||||
|
|
||||||
|
1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f,
|
||||||
|
|
||||||
|
1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f,
|
||||||
|
|
||||||
|
1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f});
|
||||||
|
// clang-format on
|
||||||
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_3d_indices_axis_0_2d_input)
|
||||||
|
{
|
||||||
|
Shape data_shape{3, 2};
|
||||||
|
Shape indices_shape{2, 3, 4};
|
||||||
|
Shape out_shape{2, 3, 4, 2};
|
||||||
|
auto P = make_shared<op::Parameter>(element::f32, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i32, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {0});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
// clang-format off
|
||||||
|
test_case.add_input<float>({1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f});
|
||||||
|
test_case.add_input<int32_t>(
|
||||||
|
{0, 1, 1, 2,
|
||||||
|
0, 1, 1, 2,
|
||||||
|
0, 1, 1, 2,
|
||||||
|
|
||||||
|
0, 1, 1, 2,
|
||||||
|
0, 1, 1, 2,
|
||||||
|
0, 1, 1, 2});
|
||||||
|
test_case.add_expected_output<float>(
|
||||||
|
out_shape, {1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f,
|
||||||
|
|
||||||
|
1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f,
|
||||||
|
|
||||||
|
1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f,
|
||||||
|
|
||||||
|
|
||||||
|
1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f,
|
||||||
|
|
||||||
|
1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f,
|
||||||
|
|
||||||
|
1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f});
|
||||||
|
// clang-format on
|
||||||
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_1d_int32)
|
||||||
|
{
|
||||||
|
Shape data_shape{3};
|
||||||
|
Shape indices_shape{2};
|
||||||
|
Shape out_shape{2};
|
||||||
|
auto P = make_shared<op::Parameter>(element::i32, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i32, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {0});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
// clang-format off
|
||||||
|
test_case.add_input<int32_t>({1, 2, 3});
|
||||||
|
test_case.add_input<int32_t>({2, 0});
|
||||||
|
test_case.add_expected_output<int32_t>(out_shape, {3, 1});
|
||||||
|
// clang-format on
|
||||||
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_2d_indices_axis_0_2d_input)
|
||||||
|
{
|
||||||
|
Shape data_shape{3, 2};
|
||||||
|
Shape indices_shape{2, 2};
|
||||||
|
Shape out_shape{2, 2, 2};
|
||||||
|
auto P = make_shared<op::Parameter>(element::f32, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i32, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {0});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
// clang-format off
|
||||||
|
test_case.add_input<float>({1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f});
|
||||||
|
// clang-format on
|
||||||
|
test_case.add_input<int32_t>({0, 1, 1, 2});
|
||||||
|
// clang-format off
|
||||||
|
test_case.add_expected_output<float>(out_shape,
|
||||||
|
{1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f});
|
||||||
|
// clang-format on
|
||||||
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_2d_negative_and_positive_indices_axis_0_2d_input)
|
||||||
|
{
|
||||||
|
Shape data_shape{3, 2};
|
||||||
|
Shape indices_shape{2, 2};
|
||||||
|
Shape out_shape{2, 2, 2};
|
||||||
|
auto P = make_shared<op::Parameter>(element::f32, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i32, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {0});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
test_case.add_input<float>({1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f});
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
test_case.add_input<int32_t>({0, -2, 1, 2});
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
test_case.add_expected_output<float>(out_shape,
|
||||||
|
{1.0f, 1.1f,
|
||||||
|
2.0f, 2.1f,
|
||||||
|
|
||||||
|
2.0f, 2.1f,
|
||||||
|
3.0f, 3.1f});
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_1d_indices_axis_0_1d_input)
|
||||||
|
{
|
||||||
|
Shape data_shape{3};
|
||||||
|
Shape indices_shape{2};
|
||||||
|
Shape out_shape{2};
|
||||||
|
auto P = make_shared<op::Parameter>(element::f32, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i32, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {0});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
test_case.add_input<float>({1.0f, 2.0f, 3.0f});
|
||||||
|
test_case.add_input<int32_t>({1, 0});
|
||||||
|
test_case.add_expected_output<float>(out_shape, {2.0f, 1.0f});
|
||||||
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_scalar_indices_axis_0_2d_input)
|
||||||
|
{
|
||||||
|
Shape data_shape{3, 2};
|
||||||
|
Shape indices_shape{};
|
||||||
|
Shape out_shape{2};
|
||||||
|
auto P = make_shared<op::Parameter>(element::f32, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i32, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {0});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
test_case.add_input<float>({1.0f, 1.1f, 2.0f, 2.1f, 3.0f, 3.1f});
|
||||||
|
test_case.add_input<int32_t>({1});
|
||||||
|
test_case.add_expected_output<float>(out_shape, {2.0f, 2.1f});
|
||||||
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_2d_indices_axis_1_2d_input)
|
||||||
|
{
|
||||||
|
Shape data_shape{3, 3};
|
||||||
|
Shape indices_shape{1, 2};
|
||||||
|
Shape out_shape{3, 1, 2};
|
||||||
|
auto P = make_shared<op::Parameter>(element::f32, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i32, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {1});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
test_case.add_input<float>({1.0f, 1.1f, 1.2f,
|
||||||
|
2.0f, 2.1f, 2.2f,
|
||||||
|
3.0f, 3.1f, 3.2f});
|
||||||
|
// clang-format on
|
||||||
|
test_case.add_input<int32_t>({0, 2});
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
test_case.add_expected_output<float>(out_shape, {1.0f, 1.2f,
|
||||||
|
2.0f, 2.2f,
|
||||||
|
3.0f, 3.2f});
|
||||||
|
// clang-format on
|
||||||
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_1d_indices_axis_2_4d_input)
|
||||||
|
{
|
||||||
|
Shape data_shape{2, 2, 3, 3};
|
||||||
|
Shape indices_shape{2};
|
||||||
|
Shape out_shape{2, 2, 2, 3};
|
||||||
|
auto P = make_shared<op::Parameter>(element::f32, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i32, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {2});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
// clang-format off
|
||||||
|
test_case.add_input<float>({ 1.0f, 1.1f, 1.2f,
|
||||||
|
2.0f, 2.1f, 2.2f,
|
||||||
|
3.0f, 3.1f, 3.2f,
|
||||||
|
|
||||||
|
11.0f, 11.1f, 11.2f,
|
||||||
|
12.0f, 12.1f, 12.2f,
|
||||||
|
13.0f, 13.1f, 13.2f,
|
||||||
|
|
||||||
|
|
||||||
|
101.0f, 101.1f, 101.2f,
|
||||||
|
102.0f, 102.1f, 102.2f,
|
||||||
|
103.0f, 103.1f, 103.2f,
|
||||||
|
|
||||||
|
111.0f, 111.1f, 111.2f,
|
||||||
|
112.0f, 112.1f, 112.2f,
|
||||||
|
113.0f, 113.1f, 113.2f});
|
||||||
|
// clang-format on
|
||||||
|
test_case.add_input<int32_t>({0, 2});
|
||||||
|
// clang-format off
|
||||||
|
test_case.add_expected_output<float>(
|
||||||
|
out_shape, { 1.0f, 1.1f, 1.2f,
|
||||||
|
3.0f, 3.1f, 3.2f,
|
||||||
|
|
||||||
|
11.0f, 11.1f, 11.2f,
|
||||||
|
13.0f, 13.1f, 13.2f,
|
||||||
|
|
||||||
|
|
||||||
|
101.0f, 101.1f, 101.2f,
|
||||||
|
103.0f, 103.1f, 103.2f,
|
||||||
|
|
||||||
|
111.0f, 111.1f, 111.2f,
|
||||||
|
113.0f, 113.1f, 113.2f});
|
||||||
|
// clang-format on
|
||||||
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_scalar_indices_axis_1_2d_input)
|
||||||
|
{
|
||||||
|
Shape data_shape{3, 3};
|
||||||
|
Shape indices_shape{};
|
||||||
|
Shape out_shape{3};
|
||||||
|
auto P = make_shared<op::Parameter>(element::f32, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i32, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {1});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
test_case.add_input<float>({1.0f, 1.1f, 1.2f, 2.0f, 2.1f, 2.2f, 3.0f, 3.1f, 3.2f});
|
||||||
|
test_case.add_input<int32_t>({0});
|
||||||
|
test_case.add_expected_output<float>(out_shape, {1.0f, 2.0f, 3.0f});
|
||||||
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_axis_0_int8)
|
||||||
|
{
|
||||||
|
Shape data_shape{3, 2};
|
||||||
|
Shape indices_shape{2, 2};
|
||||||
|
Shape out_shape{2, 2, 2};
|
||||||
|
auto P = make_shared<op::Parameter>(element::i8, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i32, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {0});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
test_case.add_input<int8_t>({10, 11, 20, 21, 30, 31});
|
||||||
|
test_case.add_input<int32_t>({0, 1, 1, 2});
|
||||||
|
test_case.add_expected_output<int8_t>(out_shape, {10, 11, 20, 21, 20, 21, 30, 31});
|
||||||
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_axis_0_int16)
|
||||||
|
{
|
||||||
|
Shape data_shape{3, 2};
|
||||||
|
Shape indices_shape{2, 2};
|
||||||
|
Shape out_shape{2, 2, 2};
|
||||||
|
auto P = make_shared<op::Parameter>(element::i16, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i64, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {0});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
test_case.add_input<int16_t>({10, 11, 20, 21, 30, 31});
|
||||||
|
test_case.add_input<int64_t>({0, 1, 1, 2});
|
||||||
|
test_case.add_expected_output<int16_t>(out_shape, {10, 11, 20, 21, 20, 21, 30, 31});
|
||||||
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_axis_0_int32)
|
||||||
|
{
|
||||||
|
Shape data_shape{3, 2};
|
||||||
|
Shape indices_shape{2, 2};
|
||||||
|
Shape out_shape{2, 2, 2};
|
||||||
|
auto P = make_shared<op::Parameter>(element::i32, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i32, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {0});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
// clang-format off
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
test_case.add_input<int32_t>({10, 11,
|
||||||
|
20, 21,
|
||||||
|
30, 31});
|
||||||
|
test_case.add_input<int32_t>({0, 1,
|
||||||
|
1, 2});
|
||||||
|
test_case.add_expected_output<int32_t>(out_shape, {10, 11,
|
||||||
|
20, 21,
|
||||||
|
|
||||||
|
20, 21,
|
||||||
|
30, 31});
|
||||||
|
// clang-format on
|
||||||
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_axis_0_int64)
|
||||||
|
{
|
||||||
|
Shape data_shape{3, 2};
|
||||||
|
Shape indices_shape{2, 2};
|
||||||
|
Shape out_shape{2, 2, 2};
|
||||||
|
auto P = make_shared<op::Parameter>(element::i64, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i64, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {0});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
test_case.add_input<int64_t>({10, 11, 20, 21, 30, 31});
|
||||||
|
test_case.add_input<int64_t>({0, 1, 1, 2});
|
||||||
|
test_case.add_expected_output<int64_t>(out_shape, {10, 11, 20, 21, 20, 21, 30, 31});
|
||||||
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_axis_0_uint8)
|
||||||
|
{
|
||||||
|
Shape data_shape{3, 2};
|
||||||
|
Shape indices_shape{2, 2};
|
||||||
|
Shape out_shape{2, 2, 2};
|
||||||
|
auto P = make_shared<op::Parameter>(element::u8, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i32, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {0});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
test_case.add_input<uint8_t>({10, 11, 20, 21, 30, 31});
|
||||||
|
test_case.add_input<int32_t>({0, 1, 1, 2});
|
||||||
|
test_case.add_expected_output<uint8_t>(out_shape, {10, 11, 20, 21, 20, 21, 30, 31});
|
||||||
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_axis_0_uint16)
|
||||||
|
{
|
||||||
|
Shape data_shape{3, 2};
|
||||||
|
Shape indices_shape{2, 2};
|
||||||
|
Shape out_shape{2, 2, 2};
|
||||||
|
auto P = make_shared<op::Parameter>(element::u16, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i64, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {0});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
test_case.add_input<uint16_t>({10, 11, 20, 21, 30, 31});
|
||||||
|
test_case.add_input<int64_t>({0, 1, 1, 2});
|
||||||
|
test_case.add_expected_output<uint16_t>(out_shape, {10, 11, 20, 21, 20, 21, 30, 31});
|
||||||
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_axis_0_uint32)
|
||||||
|
{
|
||||||
|
Shape data_shape{3, 2};
|
||||||
|
Shape indices_shape{2, 2};
|
||||||
|
Shape out_shape{2, 2, 2};
|
||||||
|
auto P = make_shared<op::Parameter>(element::u32, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i32, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {0});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
test_case.add_input<uint32_t>({10, 11, 20, 21, 30, 31});
|
||||||
|
test_case.add_input<int32_t>({0, 1, 1, 2});
|
||||||
|
test_case.add_expected_output<uint32_t>(out_shape, {10, 11, 20, 21, 20, 21, 30, 31});
|
||||||
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_axis_0_uint64)
|
||||||
|
{
|
||||||
|
Shape data_shape{3, 2};
|
||||||
|
Shape indices_shape{2, 2};
|
||||||
|
Shape out_shape{2, 2, 2};
|
||||||
|
auto P = make_shared<op::Parameter>(element::u64, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i64, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {0});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
test_case.add_input<uint64_t>({10, 11, 20, 21, 30, 31});
|
||||||
|
test_case.add_input<int64_t>({0, 1, 1, 2});
|
||||||
|
test_case.add_expected_output<uint64_t>(out_shape, {10, 11, 20, 21, 20, 21, 30, 31});
|
||||||
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_axis_0_bool)
|
||||||
{
|
{
|
||||||
Shape data_shape{3, 2};
|
Shape data_shape{3, 2};
|
||||||
Shape indices_shape{2, 2};
|
Shape indices_shape{2, 2};
|
||||||
@ -556,7 +1117,7 @@ NGRAPH_TEST(${BACKEND_NAME}, gather_axis_0_bool)
|
|||||||
auto P = make_shared<op::Parameter>(element::boolean, data_shape);
|
auto P = make_shared<op::Parameter>(element::boolean, data_shape);
|
||||||
auto I = make_shared<op::Parameter>(element::i64, indices_shape);
|
auto I = make_shared<op::Parameter>(element::i64, indices_shape);
|
||||||
auto A = op::Constant::create(element::i64, Shape{}, {0});
|
auto A = op::Constant::create(element::i64, Shape{}, {0});
|
||||||
auto G = make_shared<op::v1::Gather>(P, I, A);
|
auto G = make_shared<op::v7::Gather>(P, I, A);
|
||||||
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
auto test_case = test::TestCase<TestEngine>(f);
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
@ -565,3 +1126,165 @@ NGRAPH_TEST(${BACKEND_NAME}, gather_axis_0_bool)
|
|||||||
test_case.add_expected_output<char>(out_shape, {1, 1, 1, 0, 1, 0, 0, 1});
|
test_case.add_expected_output<char>(out_shape, {1, 1, 1, 0, 1, 0, 0, 1});
|
||||||
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_data_int32_3d_indices_axis_1_batch_dims_1)
|
||||||
|
{
|
||||||
|
Shape data_shape{2, 3};
|
||||||
|
Shape indices_shape{2, 2, 2};
|
||||||
|
Shape out_shape{2, 2, 2};
|
||||||
|
int64_t batch_dims = 1;
|
||||||
|
int64_t axis = 1;
|
||||||
|
|
||||||
|
auto P = make_shared<op::Parameter>(element::i32, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i64, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {axis});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A, batch_dims);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
test_case.add_input<int32_t>({1, 2, 3, // batch 0
|
||||||
|
4, 5, 6}); // batch 1
|
||||||
|
|
||||||
|
test_case.add_input<int64_t>({0, 1, // batch 0
|
||||||
|
1, 2,
|
||||||
|
|
||||||
|
2, 0, // batch 1
|
||||||
|
1, 2});
|
||||||
|
test_case.add_expected_output<int32_t>(out_shape, {1, 2, // batch 1
|
||||||
|
2, 3,
|
||||||
|
|
||||||
|
6, 4, // batch 1
|
||||||
|
5, 6});
|
||||||
|
test_case.run();
|
||||||
|
// clang-format on
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_data_int32_2d_indices_axis_1_batch_dims_1)
|
||||||
|
{
|
||||||
|
Shape data_shape{2, 5};
|
||||||
|
Shape indices_shape{2, 3};
|
||||||
|
Shape out_shape{2, 3};
|
||||||
|
int64_t batch_dims = 1;
|
||||||
|
int64_t axis = 1;
|
||||||
|
|
||||||
|
auto P = make_shared<op::Parameter>(element::i32, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i64, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {axis});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A, batch_dims);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
test_case.add_input<int32_t>({1, 2, 3, 4, 5, // batch 0
|
||||||
|
6, 7, 8, 9, 10}); // batch 1
|
||||||
|
|
||||||
|
test_case.add_input<int64_t>({0, 0, 4, // batch 0
|
||||||
|
4, 0, 0}); // batch 1
|
||||||
|
test_case.add_expected_output<int32_t>(out_shape, {1, 1, 5, // batch 0
|
||||||
|
10, 6, 6}); // batch 1
|
||||||
|
test_case.run();
|
||||||
|
// clang-format on
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_4d_data_axis_2_batch_dims_1_int32)
|
||||||
|
{
|
||||||
|
Shape data_shape{2, 1, 5, 4};
|
||||||
|
Shape indices_shape{2, 3};
|
||||||
|
Shape out_shape{2, 1, 3, 4};
|
||||||
|
int64_t batch_dims = 1;
|
||||||
|
int64_t axis = 2;
|
||||||
|
|
||||||
|
auto P = make_shared<op::Parameter>(element::i32, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i64, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {axis});
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A, batch_dims);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
test_case.add_input<int32_t>({
|
||||||
|
1, 2, 3, 4, // first batch
|
||||||
|
5, 6, 7, 8,
|
||||||
|
9, 10, 11, 12,
|
||||||
|
13, 14, 15, 16,
|
||||||
|
17, 18, 19, 20,
|
||||||
|
|
||||||
|
21, 22, 23, 24, // second batch
|
||||||
|
25, 26, 27, 28,
|
||||||
|
29, 30, 31, 32,
|
||||||
|
33, 34, 35, 36,
|
||||||
|
37, 38, 39, 40
|
||||||
|
});
|
||||||
|
|
||||||
|
test_case.add_input<int64_t>({
|
||||||
|
1, 2, 4, // first batch
|
||||||
|
4, 3, 2 // second batch
|
||||||
|
});
|
||||||
|
test_case.add_expected_output<int32_t>(out_shape, {
|
||||||
|
5, 6, 7, 8,
|
||||||
|
9, 10, 11, 12,
|
||||||
|
17, 18, 19, 20,
|
||||||
|
|
||||||
|
37, 38, 39, 40,
|
||||||
|
33, 34, 35, 36,
|
||||||
|
29, 30, 31, 32
|
||||||
|
});
|
||||||
|
test_case.run();
|
||||||
|
// clang-format on
|
||||||
|
}
|
||||||
|
|
||||||
|
NGRAPH_TEST(${BACKEND_NAME}, gather_v7_3d_indices_axis_1_batch_dims_1)
|
||||||
|
{
|
||||||
|
Shape data_shape{2, 5, 2};
|
||||||
|
Shape indices_shape{2, 2, 3};
|
||||||
|
Shape out_shape{2, 2, 3, 2};
|
||||||
|
int64_t batch_dims = 1;
|
||||||
|
int64_t axis = 1;
|
||||||
|
|
||||||
|
auto P = make_shared<op::Parameter>(element::f32, data_shape);
|
||||||
|
auto I = make_shared<op::Parameter>(element::i32, indices_shape);
|
||||||
|
auto A = op::Constant::create(element::i64, Shape{}, {axis});
|
||||||
|
|
||||||
|
auto G = make_shared<op::v7::Gather>(P, I, A, batch_dims);
|
||||||
|
auto f = make_shared<Function>(G, ParameterVector{P, I});
|
||||||
|
|
||||||
|
auto test_case = test::TestCase<TestEngine>(f);
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
test_case.add_input<float>({1.0f, 2.0f,
|
||||||
|
3.0f, 4.0f,
|
||||||
|
5.0f, 6.0f,
|
||||||
|
7.0f, 8.0f,
|
||||||
|
9.0f, 10.0f,
|
||||||
|
|
||||||
|
11.0f, 12.0f,
|
||||||
|
13.0f, 14.0f,
|
||||||
|
15.0f, 16.0f,
|
||||||
|
17.0f, 18.0f,
|
||||||
|
19.0f, 20.0f});
|
||||||
|
|
||||||
|
test_case.add_input<int32_t>({0, 0, 4,
|
||||||
|
4, 0, 0,
|
||||||
|
|
||||||
|
1, 2, 4,
|
||||||
|
4, 3, 2});
|
||||||
|
test_case.add_expected_output<float>({1.0f, 2.0f,
|
||||||
|
1.0f, 2.0f,
|
||||||
|
9.0f, 10.0f,
|
||||||
|
|
||||||
|
9.0f, 10.0f,
|
||||||
|
1.0f, 2.0f,
|
||||||
|
1.0f, 2.0f,
|
||||||
|
|
||||||
|
|
||||||
|
13.0f, 14.0f,
|
||||||
|
15.0f, 16.0f,
|
||||||
|
19.0f, 20.0f,
|
||||||
|
|
||||||
|
19.0f, 20.0f,
|
||||||
|
17.0f, 18.0f,
|
||||||
|
15.0f, 16.0f});
|
||||||
|
// clang-format on
|
||||||
|
test_case.run(MIN_FLOAT_TOLERANCE_BITS);
|
||||||
|
}
|
||||||
|
@ -1917,6 +1917,276 @@ TEST(constant_folding, const_gather_v1_subgraph_skip_if_not_single_input)
|
|||||||
ASSERT_EQ(count_ops_of_type<op::v1::Gather>(f), 1);
|
ASSERT_EQ(count_ops_of_type<op::v1::Gather>(f), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(constant_folding, const_gather_v7)
|
||||||
|
{
|
||||||
|
auto constant_data = op::Constant::create(
|
||||||
|
element::f32,
|
||||||
|
Shape{2, 5},
|
||||||
|
vector<float>{1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f});
|
||||||
|
auto constant_indices =
|
||||||
|
op::Constant::create(element::i64, Shape{4}, vector<int64_t>{0, 3, 2, 2});
|
||||||
|
auto constant_axis = op::Constant::create(element::i64, Shape{1}, vector<int64_t>{1});
|
||||||
|
auto gather = make_shared<op::v7::Gather>(constant_data, constant_indices, constant_axis);
|
||||||
|
gather->set_friendly_name("test");
|
||||||
|
auto f = make_shared<Function>(gather, ParameterVector{});
|
||||||
|
|
||||||
|
pass::Manager pass_manager;
|
||||||
|
pass_manager.register_pass<pass::ConstantFolding>();
|
||||||
|
pass_manager.run_passes(f);
|
||||||
|
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::v7::Gather>(f), 0);
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::Constant>(f), 1);
|
||||||
|
|
||||||
|
auto new_const =
|
||||||
|
as_type_ptr<op::Constant>(f->get_results().at(0)->input_value(0).get_node_shared_ptr());
|
||||||
|
ASSERT_TRUE(new_const);
|
||||||
|
ASSERT_EQ(new_const->get_friendly_name(), "test");
|
||||||
|
auto values_out = new_const->get_vector<float>();
|
||||||
|
|
||||||
|
vector<float> values_expected{1.0f, 4.0f, 3.0f, 3.0f, 6.0f, 9.0f, 8.0f, 8.0f};
|
||||||
|
|
||||||
|
ASSERT_TRUE(test::all_close_f(values_out, values_expected, MIN_FLOAT_TOLERANCE_BITS));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(constant_folding, const_gather_v7_scalar)
|
||||||
|
{
|
||||||
|
auto constant_data = op::Constant::create(
|
||||||
|
element::f32,
|
||||||
|
Shape{2, 5},
|
||||||
|
vector<float>{1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f});
|
||||||
|
auto constant_indices =
|
||||||
|
op::Constant::create(element::i64, Shape{4}, vector<int64_t>{0, 3, 2, 2});
|
||||||
|
auto constant_axis = op::Constant::create(element::i64, Shape{}, vector<int64_t>{1});
|
||||||
|
auto gather = make_shared<op::v7::Gather>(constant_data, constant_indices, constant_axis);
|
||||||
|
gather->set_friendly_name("test");
|
||||||
|
auto f = make_shared<Function>(gather, ParameterVector{});
|
||||||
|
|
||||||
|
pass::Manager pass_manager;
|
||||||
|
pass_manager.register_pass<pass::ConstantFolding>();
|
||||||
|
pass_manager.run_passes(f);
|
||||||
|
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::v7::Gather>(f), 0);
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::Constant>(f), 1);
|
||||||
|
|
||||||
|
auto new_const =
|
||||||
|
as_type_ptr<op::Constant>(f->get_results().at(0)->input_value(0).get_node_shared_ptr());
|
||||||
|
ASSERT_TRUE(new_const);
|
||||||
|
ASSERT_EQ(new_const->get_friendly_name(), "test");
|
||||||
|
auto values_out = new_const->get_vector<float>();
|
||||||
|
|
||||||
|
vector<float> values_expected{1.0f, 4.0f, 3.0f, 3.0f, 6.0f, 9.0f, 8.0f, 8.0f};
|
||||||
|
|
||||||
|
ASSERT_TRUE(test::all_close_f(values_out, values_expected, MIN_FLOAT_TOLERANCE_BITS));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(constant_folding, const_gather_v7_subgraph)
|
||||||
|
{
|
||||||
|
const auto A = make_shared<op::Parameter>(element::f32, Shape{1});
|
||||||
|
const float b_value = 3.21f;
|
||||||
|
const auto B_const = op::Constant::create(element::f32, {1}, {b_value});
|
||||||
|
const auto C = make_shared<op::Parameter>(element::f32, Shape{1});
|
||||||
|
const int64_t axis = 0;
|
||||||
|
const auto axis_const = op::Constant::create(element::i64, {}, {axis});
|
||||||
|
|
||||||
|
const auto concat = make_shared<op::Concat>(NodeVector{A, B_const, C}, axis);
|
||||||
|
|
||||||
|
const vector<int64_t> indices{1};
|
||||||
|
const auto indices_const = op::Constant::create(element::i64, {indices.size()}, indices);
|
||||||
|
const auto gather = make_shared<op::v7::Gather>(concat, indices_const, axis_const);
|
||||||
|
gather->set_friendly_name("test");
|
||||||
|
auto f = make_shared<Function>(gather, ParameterVector{A, C});
|
||||||
|
|
||||||
|
pass::Manager pass_manager;
|
||||||
|
pass_manager.register_pass<pass::ConstantFolding>();
|
||||||
|
pass_manager.run_passes(f);
|
||||||
|
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::Concat>(f), 0);
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::v7::Gather>(f), 0);
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::Constant>(f), 1);
|
||||||
|
|
||||||
|
const auto new_const =
|
||||||
|
as_type_ptr<op::Constant>(f->get_results().at(0)->input_value(0).get_node_shared_ptr());
|
||||||
|
ASSERT_TRUE(new_const);
|
||||||
|
ASSERT_EQ(new_const->get_friendly_name(), "test");
|
||||||
|
|
||||||
|
const auto values_out = new_const->get_vector<float>();
|
||||||
|
ASSERT_TRUE(test::all_close_f(values_out, {b_value}, MIN_FLOAT_TOLERANCE_BITS));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(constant_folding, const_gather_v7_subgraph_neg_axis)
|
||||||
|
{
|
||||||
|
const auto A = make_shared<op::Parameter>(element::f32, Shape{1});
|
||||||
|
const float b_value = 1.23f;
|
||||||
|
const auto B = make_shared<op::Parameter>(element::f32, Shape{1});
|
||||||
|
const auto C_const = op::Constant::create(element::f32, {1}, {b_value});
|
||||||
|
const int64_t axis = 0;
|
||||||
|
const auto axis_const = op::Constant::create(element::i64, {}, {axis});
|
||||||
|
|
||||||
|
const auto concat = make_shared<op::Concat>(NodeVector{A, B, C_const}, axis);
|
||||||
|
|
||||||
|
const vector<int64_t> indices{-1};
|
||||||
|
const auto indices_const = op::Constant::create(element::i64, {indices.size()}, indices);
|
||||||
|
const auto gather = make_shared<op::v7::Gather>(concat, indices_const, axis_const);
|
||||||
|
gather->set_friendly_name("test");
|
||||||
|
auto f = make_shared<Function>(gather, ParameterVector{A, B});
|
||||||
|
|
||||||
|
pass::Manager pass_manager;
|
||||||
|
pass_manager.register_pass<pass::ConstantFolding>();
|
||||||
|
pass_manager.run_passes(f);
|
||||||
|
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::Concat>(f), 0);
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::v7::Gather>(f), 0);
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::Constant>(f), 1);
|
||||||
|
|
||||||
|
const auto new_const =
|
||||||
|
as_type_ptr<op::Constant>(f->get_results().at(0)->input_value(0).get_node_shared_ptr());
|
||||||
|
ASSERT_TRUE(new_const);
|
||||||
|
ASSERT_EQ(new_const->get_friendly_name(), "test");
|
||||||
|
|
||||||
|
const auto values_out = new_const->get_vector<float>();
|
||||||
|
ASSERT_TRUE(test::all_close_f(values_out, {b_value}, MIN_FLOAT_TOLERANCE_BITS));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(constant_folding, const_gather_v7_subgraph_no_constant_input)
|
||||||
|
{
|
||||||
|
const auto A = make_shared<op::Parameter>(element::f32, Shape{1});
|
||||||
|
const auto B = make_shared<op::Parameter>(element::f32, Shape{1});
|
||||||
|
const auto C = make_shared<op::Parameter>(element::f32, Shape{1});
|
||||||
|
const int64_t axis = 0;
|
||||||
|
const auto axis_const = op::Constant::create(element::i64, {}, {axis});
|
||||||
|
|
||||||
|
const auto concat = make_shared<op::Concat>(NodeVector{A, B, C}, axis);
|
||||||
|
|
||||||
|
const vector<int64_t> indices{1};
|
||||||
|
const auto indices_const = op::Constant::create(element::i64, {indices.size()}, indices);
|
||||||
|
const auto gather = make_shared<op::v7::Gather>(concat, indices_const, axis_const);
|
||||||
|
gather->set_friendly_name("test");
|
||||||
|
auto f = make_shared<Function>(gather, ParameterVector{A, B, C});
|
||||||
|
|
||||||
|
pass::Manager pass_manager;
|
||||||
|
pass_manager.register_pass<pass::ConstantFolding>();
|
||||||
|
pass_manager.run_passes(f);
|
||||||
|
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::Concat>(f), 0);
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::v7::Gather>(f), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(constant_folding, const_gather_v7_subgraph_no_constant_input_scalar)
|
||||||
|
{
|
||||||
|
const auto A = make_shared<op::Parameter>(element::f32, Shape{1});
|
||||||
|
const auto B = make_shared<op::Parameter>(element::f32, Shape{1});
|
||||||
|
const auto C = make_shared<op::Parameter>(element::f32, Shape{1});
|
||||||
|
const int64_t axis = 0;
|
||||||
|
const auto axis_const = op::Constant::create(element::i64, {}, {axis});
|
||||||
|
|
||||||
|
const auto concat = make_shared<op::Concat>(NodeVector{A, B, C}, axis);
|
||||||
|
|
||||||
|
const vector<int64_t> indices{1};
|
||||||
|
const auto indices_const = op::Constant::create(element::i64, {}, indices);
|
||||||
|
const auto gather = make_shared<op::v7::Gather>(concat, indices_const, axis_const);
|
||||||
|
auto f = make_shared<Function>(gather, ParameterVector{A, B, C});
|
||||||
|
|
||||||
|
pass::Manager pass_manager;
|
||||||
|
pass_manager.register_pass<pass::ConstantFolding>();
|
||||||
|
pass_manager.run_passes(f);
|
||||||
|
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::Concat>(f), 0);
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::v7::Gather>(f), 0);
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::v0::Squeeze>(f), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(constant_folding, const_gather_v7_subgraph_skip_if_non_zero_axis)
|
||||||
|
{
|
||||||
|
const auto A = make_shared<op::Parameter>(element::f32, Shape{2, 2});
|
||||||
|
const auto B = make_shared<op::Parameter>(element::f32, Shape{2, 2});
|
||||||
|
const auto C = make_shared<op::Parameter>(element::f32, Shape{2, 2});
|
||||||
|
const int64_t axis = 1;
|
||||||
|
const auto axis_const = op::Constant::create(element::i64, {}, {axis});
|
||||||
|
|
||||||
|
const auto concat = make_shared<op::Concat>(NodeVector{A, B, C}, axis);
|
||||||
|
|
||||||
|
const vector<int64_t> indices{1};
|
||||||
|
const auto indices_const = op::Constant::create(element::i64, {indices.size()}, indices);
|
||||||
|
const auto gather = make_shared<op::v7::Gather>(concat, indices_const, axis_const);
|
||||||
|
auto f = make_shared<Function>(gather, ParameterVector{A, B, C});
|
||||||
|
|
||||||
|
pass::Manager pass_manager;
|
||||||
|
pass_manager.register_pass<pass::ConstantFolding>();
|
||||||
|
pass_manager.run_passes(f);
|
||||||
|
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::Concat>(f), 1);
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::v7::Gather>(f), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(constant_folding, const_gather_v7_subgraph_skip_if_non_single_indices)
|
||||||
|
{
|
||||||
|
const auto A = make_shared<op::Parameter>(element::f32, Shape{1});
|
||||||
|
const auto B = make_shared<op::Parameter>(element::f32, Shape{1});
|
||||||
|
const auto C = make_shared<op::Parameter>(element::f32, Shape{1});
|
||||||
|
const int64_t axis = 0;
|
||||||
|
const auto axis_const = op::Constant::create(element::i64, {}, {axis});
|
||||||
|
|
||||||
|
const auto concat = make_shared<op::Concat>(NodeVector{A, B, C}, axis);
|
||||||
|
|
||||||
|
const vector<int64_t> indices{0, 1};
|
||||||
|
const auto indices_const = op::Constant::create(element::i64, {indices.size()}, indices);
|
||||||
|
const auto gather = make_shared<op::v7::Gather>(concat, indices_const, axis_const);
|
||||||
|
auto f = make_shared<Function>(gather, ParameterVector{A, B, C});
|
||||||
|
|
||||||
|
pass::Manager pass_manager;
|
||||||
|
pass_manager.register_pass<pass::ConstantFolding>();
|
||||||
|
pass_manager.run_passes(f);
|
||||||
|
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::Concat>(f), 1);
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::v7::Gather>(f), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(constant_folding, const_gather_v7_subgraph_skip_if_concat_output_shape_dynamic)
|
||||||
|
{
|
||||||
|
const auto A = make_shared<op::Parameter>(element::f32, PartialShape::dynamic());
|
||||||
|
const auto B = make_shared<op::Parameter>(element::f32, Shape{1});
|
||||||
|
const auto C = make_shared<op::Parameter>(element::f32, Shape{1});
|
||||||
|
const int64_t axis = 0;
|
||||||
|
const auto axis_const = op::Constant::create(element::i64, {}, {axis});
|
||||||
|
|
||||||
|
const auto concat = make_shared<op::Concat>(NodeVector{A, B, C}, axis);
|
||||||
|
|
||||||
|
const vector<int64_t> indices{1};
|
||||||
|
const auto indices_const = op::Constant::create(element::i64, {indices.size()}, indices);
|
||||||
|
const auto gather = make_shared<op::v7::Gather>(concat, indices_const, axis_const);
|
||||||
|
auto f = make_shared<Function>(gather, ParameterVector{A, B, C});
|
||||||
|
|
||||||
|
pass::Manager pass_manager;
|
||||||
|
pass_manager.register_pass<pass::ConstantFolding>();
|
||||||
|
pass_manager.run_passes(f);
|
||||||
|
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::Concat>(f), 1);
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::v7::Gather>(f), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(constant_folding, const_gather_v7_subgraph_skip_if_not_single_input)
|
||||||
|
{
|
||||||
|
const auto A = make_shared<op::Parameter>(element::f32, Shape{2});
|
||||||
|
const auto B = make_shared<op::Parameter>(element::f32, Shape{1});
|
||||||
|
const auto C = make_shared<op::Parameter>(element::f32, Shape{1});
|
||||||
|
const int64_t axis = 0;
|
||||||
|
const auto axis_const = op::Constant::create(element::i64, {}, {axis});
|
||||||
|
|
||||||
|
const auto concat = make_shared<op::Concat>(NodeVector{A, B, C}, axis);
|
||||||
|
|
||||||
|
const vector<int64_t> indices{1};
|
||||||
|
const auto indices_const = op::Constant::create(element::i64, {indices.size()}, indices);
|
||||||
|
const auto gather = make_shared<op::v7::Gather>(concat, indices_const, axis_const);
|
||||||
|
auto f = make_shared<Function>(gather, ParameterVector{A, B, C});
|
||||||
|
|
||||||
|
pass::Manager pass_manager;
|
||||||
|
pass_manager.register_pass<pass::ConstantFolding>();
|
||||||
|
pass_manager.run_passes(f);
|
||||||
|
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::Concat>(f), 1);
|
||||||
|
ASSERT_EQ(count_ops_of_type<op::v7::Gather>(f), 1);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(constant_folding, const_strided_slice)
|
TEST(constant_folding, const_strided_slice)
|
||||||
{
|
{
|
||||||
Shape shape_in{16};
|
Shape shape_in{16};
|
||||||
|
@ -1197,7 +1197,7 @@ TEST(eval, evaluate_logical_not)
|
|||||||
ASSERT_EQ(result_val, expec);
|
ASSERT_EQ(result_val, expec);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(eval, evaluate_dynamic_gather)
|
TEST(eval, evaluate_dynamic_gather_v1)
|
||||||
{
|
{
|
||||||
auto arg1 = make_shared<op::Parameter>(element::f32, PartialShape::dynamic());
|
auto arg1 = make_shared<op::Parameter>(element::f32, PartialShape::dynamic());
|
||||||
auto arg2 = make_shared<op::Parameter>(element::i32, PartialShape::dynamic());
|
auto arg2 = make_shared<op::Parameter>(element::i32, PartialShape::dynamic());
|
||||||
@ -1216,7 +1216,7 @@ TEST(eval, evaluate_dynamic_gather)
|
|||||||
ASSERT_EQ(cval, out);
|
ASSERT_EQ(cval, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(eval, evaluate_dynamic_axis_gather)
|
TEST(eval, evaluate_dynamic_gather_v1_scalar_axis)
|
||||||
{
|
{
|
||||||
auto arg1 = make_shared<op::Parameter>(element::f32, PartialShape::dynamic());
|
auto arg1 = make_shared<op::Parameter>(element::f32, PartialShape::dynamic());
|
||||||
auto arg2 = make_shared<op::Parameter>(element::i32, PartialShape::dynamic());
|
auto arg2 = make_shared<op::Parameter>(element::i32, PartialShape::dynamic());
|
||||||
@ -1236,6 +1236,49 @@ TEST(eval, evaluate_dynamic_axis_gather)
|
|||||||
ASSERT_EQ(cval, out);
|
ASSERT_EQ(cval, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(eval, evaluate_dynamic_gather_v7)
|
||||||
|
{
|
||||||
|
auto arg1 = make_shared<op::Parameter>(element::f32, PartialShape::dynamic());
|
||||||
|
auto arg2 = make_shared<op::Parameter>(element::i32, PartialShape::dynamic());
|
||||||
|
auto arg3 = make_shared<op::Parameter>(element::i32, PartialShape::dynamic());
|
||||||
|
int64_t batch_dims = 1;
|
||||||
|
int32_t axis = 1;
|
||||||
|
auto gather = make_shared<op::v7::Gather>(arg1, arg2, arg3, batch_dims);
|
||||||
|
auto fun = make_shared<Function>(OutputVector{gather}, ParameterVector{arg1, arg2, arg3});
|
||||||
|
auto result_tensor = make_shared<HostTensor>();
|
||||||
|
ASSERT_TRUE(fun->evaluate({result_tensor},
|
||||||
|
{make_host_tensor<element::Type_t::f32>({2, 3}, {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}),
|
||||||
|
make_host_tensor<element::Type_t::i32>({2, 2}, {1, 0, 1, 0}),
|
||||||
|
make_host_tensor<element::Type_t::i32>({1}, {axis})}));
|
||||||
|
EXPECT_EQ(result_tensor->get_element_type(), element::f32);
|
||||||
|
EXPECT_EQ(result_tensor->get_partial_shape(), (PartialShape{2, 2}));
|
||||||
|
auto cval = read_vector<float>(result_tensor);
|
||||||
|
vector<float> out{2.0f, 1.0f, 5.0f, 4.0f};
|
||||||
|
ASSERT_EQ(cval, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(eval, evaluate_dynamic_gather_v7_axis_scalar)
|
||||||
|
{
|
||||||
|
auto arg1 = make_shared<op::Parameter>(element::f32, PartialShape::dynamic());
|
||||||
|
auto arg2 = make_shared<op::Parameter>(element::i32, PartialShape::dynamic());
|
||||||
|
auto arg3 = make_shared<op::Parameter>(element::i64, PartialShape::dynamic());
|
||||||
|
int64_t batch_dims = 0;
|
||||||
|
int64_t axis = 1;
|
||||||
|
auto gather = make_shared<op::v7::Gather>(arg1, arg2, arg3, batch_dims);
|
||||||
|
auto fun = make_shared<Function>(OutputVector{gather}, ParameterVector{arg1, arg2, arg3});
|
||||||
|
auto result_tensor = make_shared<HostTensor>();
|
||||||
|
ASSERT_TRUE(fun->evaluate({result_tensor},
|
||||||
|
{make_host_tensor<element::Type_t::f32>(
|
||||||
|
{3, 3}, {1.0f, 1.1f, 1.2f, 2.0f, 2.1f, 2.2f, 3.0f, 3.1f, 3.2f}),
|
||||||
|
make_host_tensor<element::Type_t::i32>({1, 2}, {0, 2}),
|
||||||
|
make_host_tensor<element::Type_t::i64>({}, {axis})}));
|
||||||
|
EXPECT_EQ(result_tensor->get_element_type(), element::f32);
|
||||||
|
EXPECT_EQ(result_tensor->get_partial_shape(), (PartialShape{3, 1, 2}));
|
||||||
|
auto cval = read_vector<float>(result_tensor);
|
||||||
|
vector<float> out{1.0f, 1.2f, 2.0f, 2.2f, 3.0f, 3.2f};
|
||||||
|
ASSERT_EQ(cval, out);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(eval, evaluate_dynamic_concat)
|
TEST(eval, evaluate_dynamic_concat)
|
||||||
{
|
{
|
||||||
auto arg1 = make_shared<op::Parameter>(element::f32, PartialShape::dynamic());
|
auto arg1 = make_shared<op::Parameter>(element::f32, PartialShape::dynamic());
|
||||||
|
@ -883,8 +883,9 @@ dyn_group_convolution_backprop_data
|
|||||||
dynamic_transpose
|
dynamic_transpose
|
||||||
transpose
|
transpose
|
||||||
|
|
||||||
# Failing from new reason after unblocking more Blob types
|
# todo: check negative indices implementation
|
||||||
gather_2d_negative_and_positive_indices_axis_0_2d_input
|
gather_2d_negative_and_positive_indices_axis_0_2d_input
|
||||||
|
# Failing from new reason after unblocking more Blob types
|
||||||
gather_axis_0_int8
|
gather_axis_0_int8
|
||||||
gather_axis_0_uint8
|
gather_axis_0_uint8
|
||||||
gather_axis_0_uint32
|
gather_axis_0_uint32
|
||||||
@ -1582,6 +1583,33 @@ evaluate_mvn_6_across_chanells
|
|||||||
evaluate_mvn_6_across_batch
|
evaluate_mvn_6_across_batch
|
||||||
IE_CPU.onnx_mvn_v6
|
IE_CPU.onnx_mvn_v6
|
||||||
|
|
||||||
|
# not yet implemented on CPU/GPU Gather 7
|
||||||
|
gather_v7_1d_int32
|
||||||
|
gather_v7_data_int32_3d_indices_axis_1_batch_dims_1
|
||||||
|
gather_v7_data_int32_2d_indices_axis_1_batch_dims_1
|
||||||
|
gather_v7_3d_indices_axis_1_batch_dims_1
|
||||||
|
gather_v7_4d_indices_axis_0_uint8
|
||||||
|
gather_v7_4d_indices_axis_0_2d_input
|
||||||
|
gather_v7_3d_indices_axis_0_2d_input
|
||||||
|
gather_v7_2d_indices_axis_0_2d_input
|
||||||
|
gather_v7_2d_negative_and_positive_indices_axis_0_2d_input
|
||||||
|
gather_v7_1d_indices_axis_0_1d_input
|
||||||
|
gather_v7_scalar_indices_axis_0_2d_input
|
||||||
|
gather_v7_2d_indices_axis_1_2d_input
|
||||||
|
gather_v7_1d_indices_axis_2_4d_input
|
||||||
|
gather_v7_scalar_indices_axis_1_2d_input
|
||||||
|
gather_v7_axis_0_int8
|
||||||
|
gather_v7_axis_0_int16
|
||||||
|
gather_v7_axis_0_int32
|
||||||
|
gather_v7_axis_0_int64
|
||||||
|
gather_v7_axis_0_uint8
|
||||||
|
gather_v7_axis_0_uint16
|
||||||
|
gather_v7_axis_0_uint32
|
||||||
|
gather_v7_axis_0_uint64
|
||||||
|
gather_v7_axis_0_bool
|
||||||
|
gather_v7_3d_indices_axis_1_batch_dims_1_int32
|
||||||
|
gather_v7_4d_data_axis_2_batch_dims_1_int32
|
||||||
|
|
||||||
# Issue 49621: Incorrect blob sizes for node BinaryConvolution_X
|
# Issue 49621: Incorrect blob sizes for node BinaryConvolution_X
|
||||||
bin_convolution_2D_1batch_1channel
|
bin_convolution_2D_1batch_1channel
|
||||||
bin_convolution_2D_1batch_1channel_padding_pad_val_0
|
bin_convolution_2D_1batch_1channel_padding_pad_val_0
|
||||||
|
@ -65,6 +65,11 @@ INTERPRETER.gather_axis_0_int8
|
|||||||
INTERPRETER.gather_axis_0_int16
|
INTERPRETER.gather_axis_0_int16
|
||||||
INTERPRETER.gather_axis_0_uint8
|
INTERPRETER.gather_axis_0_uint8
|
||||||
INTERPRETER.gather_axis_0_uint16
|
INTERPRETER.gather_axis_0_uint16
|
||||||
|
INTERPRETER.gather_v7_4d_indices_axis_0_uint8
|
||||||
|
INTERPRETER.gather_v7_axis_0_int8
|
||||||
|
INTERPRETER.gather_v7_axis_0_int16
|
||||||
|
INTERPRETER.gather_v7_axis_0_uint8
|
||||||
|
INTERPRETER.gather_v7_axis_0_uint16
|
||||||
INTERPRETER.auto_bcast_binary_elementwise
|
INTERPRETER.auto_bcast_binary_elementwise
|
||||||
INTERPRETER.auto_bcast_binary_elementwise_pdpd
|
INTERPRETER.auto_bcast_binary_elementwise_pdpd
|
||||||
|
|
||||||
|
@ -395,7 +395,7 @@ TEST(type_prop, gather_7_batch_dims_less_check)
|
|||||||
TEST(type_prop, gather_7_batch_dims_less_indices_rank_check)
|
TEST(type_prop, gather_7_batch_dims_less_indices_rank_check)
|
||||||
{
|
{
|
||||||
PartialShape data_shape{1, 20, 20, 22, 22};
|
PartialShape data_shape{1, 20, 20, 22, 22};
|
||||||
PartialShape indices_shape{1, 3, 8};
|
PartialShape indices_shape{1, 3};
|
||||||
|
|
||||||
auto D = make_shared<op::Parameter>(element::f32, data_shape);
|
auto D = make_shared<op::Parameter>(element::f32, data_shape);
|
||||||
auto I = make_shared<op::Parameter>(element::i64, indices_shape);
|
auto I = make_shared<op::Parameter>(element::i64, indices_shape);
|
||||||
@ -413,7 +413,7 @@ TEST(type_prop, gather_7_batch_dims_less_indices_rank_check)
|
|||||||
{
|
{
|
||||||
EXPECT_HAS_SUBSTRING(
|
EXPECT_HAS_SUBSTRING(
|
||||||
error.what(),
|
error.what(),
|
||||||
std::string("batch_dims must be < indices_rank"));
|
std::string("batch_dims must be <= indices_rank"));
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user