[Op][Core] Add ScatterNDUpdate-14 core and reference (#23754)
### Details: - *Add core implementation for ScatterNDUpdates-14* - *Add reference implementation for ScatterNDUpdates-14* ### Tickets: - *111098* - *111091* - *111093*
This commit is contained in:
parent
9331eb54da
commit
345a31ce7e
|
|
@ -29,5 +29,55 @@ public:
|
|||
bool has_evaluate() const override;
|
||||
};
|
||||
} // namespace v3
|
||||
namespace v14 {
|
||||
/// \brief Add updates to slices from inputs addressed by indices
|
||||
/// \ingroup ov_ops_cpp_api
|
||||
class OPENVINO_API ScatterNDUpdate : public util::ScatterNDBase {
|
||||
public:
|
||||
OPENVINO_OP("ScatterNDUpdate", "opset14", util::ScatterNDBase);
|
||||
|
||||
/// \brief Lists the supported reduction types for this version of the operator.
|
||||
/// See the specification for the description of how reduction works with ScatterNDUpdate.
|
||||
enum class Reduction { NONE, SUM, SUB, PROD, MIN, MAX };
|
||||
|
||||
ScatterNDUpdate() = default;
|
||||
/// \param inputs Tensor
|
||||
/// \param indices Index tensor: Data type must be `element::i32` or `element::i64`
|
||||
/// \param updates Tensor: Must have same type as inputs
|
||||
/// \param reduction Reduction: Type of operation to perform on inputs
|
||||
ScatterNDUpdate(const Output<Node>& inputs,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& updates,
|
||||
const Reduction reduction = Reduction::NONE);
|
||||
|
||||
std::shared_ptr<Node> clone_with_new_inputs(const OutputVector& new_args) const override;
|
||||
bool visit_attributes(AttributeVisitor& visitor) override;
|
||||
bool evaluate(TensorVector& outputs, const TensorVector& inputs) const override;
|
||||
bool evaluate_lower(TensorVector& output_values) const override;
|
||||
bool evaluate_upper(TensorVector& output_values) const override;
|
||||
bool evaluate_symbol(TensorSymbolVector& output_symbols) const override;
|
||||
bool has_evaluate() const override;
|
||||
|
||||
Reduction get_reduction() const;
|
||||
|
||||
void set_reduction(const Reduction reduction);
|
||||
|
||||
private:
|
||||
Reduction m_reduction = Reduction::NONE;
|
||||
};
|
||||
} // namespace v14
|
||||
} // namespace op
|
||||
|
||||
OPENVINO_API
|
||||
std::ostream& operator<<(std::ostream& s, const op::v14::ScatterNDUpdate::Reduction& reduction);
|
||||
|
||||
template <>
|
||||
class OPENVINO_API AttributeAdapter<op::v14::ScatterNDUpdate::Reduction>
|
||||
: public EnumAttributeAdapterBase<op::v14::ScatterNDUpdate::Reduction> {
|
||||
public:
|
||||
AttributeAdapter(op::v14::ScatterNDUpdate::Reduction& value)
|
||||
: EnumAttributeAdapterBase<op::v14::ScatterNDUpdate::Reduction>(value) {}
|
||||
|
||||
OPENVINO_RTTI("AttributeAdapter<v14::ScatterNDUpdate::Reduction>");
|
||||
};
|
||||
} // namespace ov
|
||||
|
|
|
|||
|
|
@ -87,7 +87,6 @@ _OPENVINO_OP_REG(Reshape, ov::op::v1)
|
|||
_OPENVINO_OP_REG(Result, ov::op::v0)
|
||||
_OPENVINO_OP_REG(ReverseSequence, ov::op::v0)
|
||||
_OPENVINO_OP_REG(ROIPooling, ov::op::v0)
|
||||
_OPENVINO_OP_REG(ScatterNDUpdate, ov::op::v3)
|
||||
_OPENVINO_OP_REG(Select, ov::op::v1)
|
||||
_OPENVINO_OP_REG(Selu, ov::op::v0)
|
||||
_OPENVINO_OP_REG(Sign, ov::op::v0)
|
||||
|
|
@ -221,3 +220,4 @@ _OPENVINO_OP_REG(FakeConvert, ov::op::v13)
|
|||
// New operations added in opset14
|
||||
_OPENVINO_OP_REG(ConvertPromoteTypes, ov::op::v14)
|
||||
_OPENVINO_OP_REG(Inverse, ov::op::v14)
|
||||
_OPENVINO_OP_REG(ScatterNDUpdate, ov::op::v14)
|
||||
|
|
|
|||
|
|
@ -8,10 +8,82 @@
|
|||
#include <numeric>
|
||||
|
||||
#include "openvino/core/shape.hpp"
|
||||
#include "openvino/op/scatter_nd_update.hpp"
|
||||
#include "openvino/reference/maximum.hpp"
|
||||
#include "openvino/reference/minimum.hpp"
|
||||
#include "openvino/reference/multiply.hpp"
|
||||
#include "openvino/reference/xor.hpp"
|
||||
#include "utils/span.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace reference {
|
||||
using Reduction = ov::op::v14::ScatterNDUpdate::Reduction;
|
||||
template <typename T>
|
||||
using reduction_function = T (*)(const T, const T);
|
||||
|
||||
namespace func {
|
||||
// TODO move this functions to other reference implementations to reduce binary size. Binary for
|
||||
// ScatterElementsUpdate-12 can also be updated. Ticket: CVS-138266
|
||||
template <class T>
|
||||
constexpr T add(const T a, const T b) {
|
||||
return a + b;
|
||||
}
|
||||
template <class T>
|
||||
constexpr T subtract(const T a, const T b) {
|
||||
return a - b;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
constexpr T logical_and(const T a, const T b) {
|
||||
return static_cast<bool>(a) && static_cast<bool>(b);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
constexpr T logical_or(const T a, const T b) {
|
||||
return static_cast<bool>(a) || static_cast<bool>(b);
|
||||
}
|
||||
|
||||
} // namespace func
|
||||
|
||||
template <typename T,
|
||||
typename std::enable_if<!std::is_same<typename std::decay<T>::type, char>::value>::type* = nullptr>
|
||||
reduction_function<T> reduction_functor_for(const Reduction reduction_type) {
|
||||
using U = typename std::decay<T>::type;
|
||||
switch (reduction_type) {
|
||||
case Reduction::MAX:
|
||||
return func::max<U>;
|
||||
case Reduction::MIN:
|
||||
return func::min<U>;
|
||||
case Reduction::PROD:
|
||||
return func::multiply<U>;
|
||||
case Reduction::SUM:
|
||||
return func::add<U>;
|
||||
case Reduction::SUB:
|
||||
return func::subtract<U>;
|
||||
case Reduction::NONE:
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<std::is_same<typename std::decay<T>::type, char>::value>::type* = nullptr>
|
||||
reduction_function<T> reduction_functor_for(const Reduction reduction_type) {
|
||||
using U = typename std::decay<T>::type;
|
||||
switch (reduction_type) {
|
||||
case Reduction::MIN:
|
||||
case Reduction::PROD:
|
||||
return func::logical_and<U>;
|
||||
case Reduction::SUM:
|
||||
case Reduction::MAX:
|
||||
return func::logical_or<U>;
|
||||
case Reduction::SUB:
|
||||
return func::logical_xor<U>;
|
||||
case Reduction::NONE:
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename dataType, typename indicesType>
|
||||
void scatterNdUpdate(const dataType* const inputData,
|
||||
const indicesType* const indices,
|
||||
|
|
@ -19,7 +91,8 @@ void scatterNdUpdate(const dataType* const inputData,
|
|||
dataType* const outBuf,
|
||||
const Shape& dataShape,
|
||||
const Shape& indicesShape,
|
||||
const Shape& updatesShape) {
|
||||
const Shape& updatesShape,
|
||||
const Reduction reduction_type = Reduction::NONE) {
|
||||
const auto update_chunk_shape = span(dataShape).drop_front(indicesShape.back());
|
||||
const auto update_el_number = shape_size(update_chunk_shape);
|
||||
|
||||
|
|
@ -32,9 +105,8 @@ void scatterNdUpdate(const dataType* const inputData,
|
|||
};
|
||||
return padding;
|
||||
}();
|
||||
|
||||
const auto reduction = reduction_functor_for<dataType>(reduction_type);
|
||||
std::vector<indicesType> indicesCopy(indices, indices + shape_size(indicesShape));
|
||||
|
||||
const auto num_of_updates = shape_size(span(indicesShape).drop_back(1));
|
||||
for (size_t i = 0; i != num_of_updates; ++i) {
|
||||
const auto indices_coord = indicesCopy.data() + i * indicesShape.back();
|
||||
|
|
@ -52,10 +124,17 @@ void scatterNdUpdate(const dataType* const inputData,
|
|||
const auto out_index = std::inner_product(begin(coord), end(coord), begin(input_data_dim_pading), uint64_t(0));
|
||||
|
||||
const auto update_data = updates + i * update_el_number;
|
||||
const auto update_mem_size = update_el_number * sizeof(dataType);
|
||||
OPENVINO_ASSERT(out_index >= 0 && out_index + update_el_number <= shape_size(dataShape),
|
||||
"Index is out of bounds");
|
||||
std::memcpy(outBuf + out_index, update_data, update_mem_size);
|
||||
if (reduction) {
|
||||
std::transform(outBuf + out_index,
|
||||
outBuf + out_index + update_el_number,
|
||||
update_data,
|
||||
outBuf + out_index,
|
||||
reduction);
|
||||
} else {
|
||||
std::memcpy(outBuf + out_index, update_data, update_el_number * sizeof(dataType));
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace reference
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ struct Evaluate : public element::NoAction<bool> {
|
|||
Tensor& output,
|
||||
const Shape& data_shape,
|
||||
const Shape& indices_shape,
|
||||
const Shape& updates_shape) {
|
||||
const Shape& updates_shape,
|
||||
const v14::ScatterNDUpdate::Reduction reduction) {
|
||||
using namespace ov::element;
|
||||
return IF_TYPE_OF(sctter_nd_eval_idx_type,
|
||||
OV_PP_ET_LIST(i32, i64),
|
||||
|
|
@ -34,7 +35,8 @@ struct Evaluate : public element::NoAction<bool> {
|
|||
output.data<DT>(),
|
||||
data_shape,
|
||||
indices_shape,
|
||||
updates_shape);
|
||||
updates_shape,
|
||||
reduction);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -48,31 +50,25 @@ private:
|
|||
DT* const output,
|
||||
const Shape& data_shape,
|
||||
const Shape& indices_shape,
|
||||
const Shape& updates_shape) {
|
||||
const Shape& updates_shape,
|
||||
const v14::ScatterNDUpdate::Reduction reduction) {
|
||||
reference::scatterNdUpdate(data,
|
||||
indices.data<IT>(),
|
||||
updates,
|
||||
output,
|
||||
data_shape,
|
||||
indices_shape,
|
||||
updates_shape);
|
||||
updates_shape,
|
||||
reduction);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
};
|
||||
} // namespace scatter_nd_update
|
||||
|
||||
namespace v3 {
|
||||
std::shared_ptr<Node> ScatterNDUpdate::clone_with_new_inputs(const OutputVector& new_args) const {
|
||||
OV_OP_SCOPE(v3_ScatterNDUpdate_clone_with_new_inputs);
|
||||
check_new_args_count(this, new_args);
|
||||
return std::make_shared<ScatterNDUpdate>(new_args.at(util::ScatterNDBase::INPUTS),
|
||||
new_args.at(util::ScatterNDBase::INDICES),
|
||||
new_args.at(util::ScatterNDBase::UPDATES));
|
||||
}
|
||||
|
||||
bool ScatterNDUpdate::evaluate(TensorVector& outputs, const TensorVector& inputs) const {
|
||||
OV_OP_SCOPE(v3_ScatterNDUpdate_evaluate);
|
||||
namespace {
|
||||
bool evaluate(const op::util::ScatterNDBase* node,
|
||||
TensorVector& outputs,
|
||||
const TensorVector& inputs,
|
||||
const op::v14::ScatterNDUpdate::Reduction reduction) {
|
||||
OPENVINO_ASSERT(inputs.size() == 3);
|
||||
OPENVINO_ASSERT(outputs.size() == 1);
|
||||
|
||||
|
|
@ -85,8 +81,8 @@ bool ScatterNDUpdate::evaluate(TensorVector& outputs, const TensorVector& inputs
|
|||
const auto& updates_shape = updates.get_shape();
|
||||
output.set_shape(data_shape);
|
||||
using namespace ov::element;
|
||||
return IF_TYPE_OF_CONVERT_TENSORS(v3_ScatterNDUpdate_evaluate,
|
||||
this,
|
||||
return IF_TYPE_OF_CONVERT_TENSORS(scatter_evaluate,
|
||||
node,
|
||||
outputs,
|
||||
inputs,
|
||||
OV_PP_ET_LIST(boolean, f32, i32, i64, u32, u64),
|
||||
|
|
@ -98,13 +94,11 @@ bool ScatterNDUpdate::evaluate(TensorVector& outputs, const TensorVector& inputs
|
|||
output,
|
||||
data_shape,
|
||||
indices_shape,
|
||||
updates_shape);
|
||||
updates_shape,
|
||||
reduction);
|
||||
}
|
||||
|
||||
bool ScatterNDUpdate::has_evaluate() const {
|
||||
OV_OP_SCOPE(v3_ScatterNDUpdate_has_evaluate);
|
||||
|
||||
switch (get_output_element_type(0)) {
|
||||
bool has_evaluate(const op::util::ScatterNDBase* node) {
|
||||
switch (node->get_output_element_type(0)) {
|
||||
case element::boolean:
|
||||
case element::f16:
|
||||
case element::f32:
|
||||
|
|
@ -116,7 +110,7 @@ bool ScatterNDUpdate::has_evaluate() const {
|
|||
default:
|
||||
return false;
|
||||
}
|
||||
switch (get_input_element_type(1)) {
|
||||
switch (node->get_input_element_type(1)) {
|
||||
case element::i32:
|
||||
case element::i64:
|
||||
return true;
|
||||
|
|
@ -124,6 +118,27 @@ bool ScatterNDUpdate::has_evaluate() const {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
} // namespace scatter_nd_update
|
||||
namespace v3 {
|
||||
std::shared_ptr<Node> ScatterNDUpdate::clone_with_new_inputs(const OutputVector& new_args) const {
|
||||
OV_OP_SCOPE(v3_ScatterNDUpdate_clone_with_new_inputs);
|
||||
check_new_args_count(this, new_args);
|
||||
return std::make_shared<ScatterNDUpdate>(new_args.at(util::ScatterNDBase::INPUTS),
|
||||
new_args.at(util::ScatterNDBase::INDICES),
|
||||
new_args.at(util::ScatterNDBase::UPDATES));
|
||||
}
|
||||
|
||||
bool ScatterNDUpdate::evaluate(TensorVector& outputs, const TensorVector& inputs) const {
|
||||
OV_OP_SCOPE(v3_ScatterNDUpdate_evaluate);
|
||||
constexpr auto reduction = op::v14::ScatterNDUpdate::Reduction::NONE;
|
||||
return scatter_nd_update::evaluate(this, outputs, inputs, reduction);
|
||||
}
|
||||
|
||||
bool ScatterNDUpdate::has_evaluate() const {
|
||||
OV_OP_SCOPE(v3_ScatterNDUpdate_has_evaluate);
|
||||
return scatter_nd_update::has_evaluate(this);
|
||||
}
|
||||
|
||||
bool ScatterNDUpdate::evaluate_lower(TensorVector& output_values) const {
|
||||
OV_OP_SCOPE(v3_ScatterNDUpdate_evaluate_lower);
|
||||
|
|
@ -140,5 +155,75 @@ bool ScatterNDUpdate::evaluate_symbol(TensorSymbolVector& output_symbols) const
|
|||
return default_symbol_evaluator(this, {0, 2}, output_symbols);
|
||||
}
|
||||
} // namespace v3
|
||||
|
||||
namespace v14 {
|
||||
ScatterNDUpdate::ScatterNDUpdate(const Output<Node>& inputs,
|
||||
const Output<Node>& indices,
|
||||
const Output<Node>& updates,
|
||||
const ScatterNDUpdate::Reduction reduction)
|
||||
: op::util::ScatterNDBase(inputs, indices, updates),
|
||||
m_reduction{reduction} {
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
std::shared_ptr<Node> ScatterNDUpdate::clone_with_new_inputs(const OutputVector& new_args) const {
|
||||
OV_OP_SCOPE(v14_ScatterNDUpdate_clone_with_new_inputs);
|
||||
check_new_args_count(this, new_args);
|
||||
return std::make_shared<ScatterNDUpdate>(new_args.at(0), new_args.at(1), new_args.at(2), m_reduction);
|
||||
}
|
||||
|
||||
bool ScatterNDUpdate::visit_attributes(AttributeVisitor& visitor) {
|
||||
OV_OP_SCOPE(v14_ScatterNDUpdate_visit_attributes);
|
||||
visitor.on_attribute("reduction", m_reduction);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScatterNDUpdate::evaluate(TensorVector& outputs, const TensorVector& inputs) const {
|
||||
OV_OP_SCOPE(v14_ScatterNDUpdate_evaluate);
|
||||
return scatter_nd_update::evaluate(this, outputs, inputs, m_reduction);
|
||||
}
|
||||
|
||||
bool ScatterNDUpdate::has_evaluate() const {
|
||||
OV_OP_SCOPE(v14_ScatterNDUpdate_has_evaluate);
|
||||
return scatter_nd_update::has_evaluate(this);
|
||||
}
|
||||
|
||||
ScatterNDUpdate::Reduction ScatterNDUpdate::get_reduction() const {
|
||||
return m_reduction;
|
||||
}
|
||||
|
||||
void ScatterNDUpdate::set_reduction(const ScatterNDUpdate::Reduction reduction) {
|
||||
m_reduction = reduction;
|
||||
}
|
||||
bool ScatterNDUpdate::evaluate_lower(TensorVector& output_values) const {
|
||||
OV_OP_SCOPE(v14_ScatterNDUpdate_evaluate_lower);
|
||||
return get_input_tensor(1).has_and_set_bound() && default_lower_bound_evaluator(this, output_values);
|
||||
}
|
||||
|
||||
bool ScatterNDUpdate::evaluate_upper(TensorVector& output_values) const {
|
||||
OV_OP_SCOPE(v14_ScatterNDUpdate_evaluate_upper);
|
||||
return get_input_tensor(1).has_and_set_bound() && default_upper_bound_evaluator(this, output_values);
|
||||
}
|
||||
|
||||
bool ScatterNDUpdate::evaluate_symbol(TensorSymbolVector& output_symbols) const {
|
||||
OV_OP_SCOPE(v14_ScatterNDUpdate_evaluate_symbol);
|
||||
return default_symbol_evaluator(this, {0, 2}, output_symbols);
|
||||
}
|
||||
|
||||
} // namespace v14
|
||||
} // namespace op
|
||||
std::ostream& operator<<(std::ostream& s, const op::v14::ScatterNDUpdate::Reduction& reduction) {
|
||||
return s << as_string(reduction);
|
||||
}
|
||||
template <>
|
||||
OPENVINO_API EnumNames<op::v14::ScatterNDUpdate::Reduction>& EnumNames<op::v14::ScatterNDUpdate::Reduction>::get() {
|
||||
static auto enum_names =
|
||||
EnumNames<op::v14::ScatterNDUpdate::Reduction>("op::v14::ScatterNDUpdate::Reduction",
|
||||
{{"none", op::v14::ScatterNDUpdate::Reduction::NONE},
|
||||
{"sum", op::v14::ScatterNDUpdate::Reduction::SUM},
|
||||
{"sub", op::v14::ScatterNDUpdate::Reduction::SUB},
|
||||
{"prod", op::v14::ScatterNDUpdate::Reduction::PROD},
|
||||
{"min", op::v14::ScatterNDUpdate::Reduction::MIN},
|
||||
{"max", op::v14::ScatterNDUpdate::Reduction::MAX}});
|
||||
return enum_names;
|
||||
}
|
||||
} // namespace ov
|
||||
|
|
|
|||
|
|
@ -5,21 +5,33 @@
|
|||
#include "openvino/op/scatter_nd_update.hpp"
|
||||
|
||||
#include "common_test_utils/type_prop.hpp"
|
||||
#include "openvino/op/broadcast.hpp"
|
||||
#include "openvino/op/constant.hpp"
|
||||
#include "openvino/op/shape_of.hpp"
|
||||
#include "openvino/opsets/opset10.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace ov;
|
||||
using namespace testing;
|
||||
|
||||
TEST(type_prop, scatter_nd_update_v3_fail_indices_element_type) {
|
||||
template <class T>
|
||||
class TypePropScatterNDUpdateTest : public TypePropOpTest<T> {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
set_shape_symbols(data_3d_dynamic);
|
||||
}
|
||||
PartialShape data_3d_dynamic{{2, 5}, 2, {4, 10}};
|
||||
};
|
||||
|
||||
TYPED_TEST_SUITE_P(TypePropScatterNDUpdateTest);
|
||||
|
||||
TYPED_TEST_P(TypePropScatterNDUpdateTest, scatter_nd_update_v3_fail_indices_element_type) {
|
||||
Shape ref_shape{2, 3, 4};
|
||||
Shape indices_shape{2, 1};
|
||||
Shape updates_shape{2, 2, 1, 4};
|
||||
auto R = make_shared<ov::op::v0::Parameter>(element::f32, ref_shape);
|
||||
auto I = make_shared<ov::op::v0::Parameter>(element::f16, indices_shape);
|
||||
auto U = make_shared<ov::op::v0::Parameter>(element::f32, updates_shape);
|
||||
auto R = std::make_shared<op::v0::Parameter>(element::f32, ref_shape);
|
||||
auto I = std::make_shared<op::v0::Parameter>(element::f16, indices_shape);
|
||||
auto U = std::make_shared<op::v0::Parameter>(element::f32, updates_shape);
|
||||
try {
|
||||
auto G = make_shared<op::v3::ScatterNDUpdate>(R, I, U);
|
||||
auto G = this->make_op(R, I, U);
|
||||
// Should have thrown, so fail if it didn't
|
||||
FAIL() << "Incorrect indices element type";
|
||||
} catch (const NodeValidationFailure& error) {
|
||||
|
|
@ -29,16 +41,16 @@ TEST(type_prop, scatter_nd_update_v3_fail_indices_element_type) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_nd_update_v3_fail_updates_rank) {
|
||||
TYPED_TEST_P(TypePropScatterNDUpdateTest, scatter_nd_update_v3_fail_updates_rank) {
|
||||
Shape ref_shape{3, 3, 3};
|
||||
Shape indices_shape{1};
|
||||
Shape updates_shape{3, 3, 3};
|
||||
Shape out_shape{3, 3, 3};
|
||||
auto R = make_shared<ov::op::v0::Parameter>(element::f32, ref_shape);
|
||||
auto I = make_shared<ov::op::v0::Parameter>(element::i32, indices_shape);
|
||||
auto U = make_shared<ov::op::v0::Parameter>(element::f32, updates_shape);
|
||||
auto R = std::make_shared<op::v0::Parameter>(element::f32, ref_shape);
|
||||
auto I = std::make_shared<op::v0::Parameter>(element::i32, indices_shape);
|
||||
auto U = std::make_shared<op::v0::Parameter>(element::f32, updates_shape);
|
||||
try {
|
||||
auto G = make_shared<op::v3::ScatterNDUpdate>(R, I, U);
|
||||
auto G = this->make_op(R, I, U);
|
||||
// Should have thrown, so fail if it didn't
|
||||
FAIL() << "Incorrect updates rank";
|
||||
} catch (const NodeValidationFailure& error) {
|
||||
|
|
@ -50,16 +62,16 @@ TEST(type_prop, scatter_nd_update_v3_fail_updates_rank) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_nd_update_fail_updates_element_type) {
|
||||
TYPED_TEST_P(TypePropScatterNDUpdateTest, scatter_nd_update_fail_updates_element_type) {
|
||||
Shape ref_shape{3, 3, 3};
|
||||
Shape indices_shape{1};
|
||||
Shape updates_shape{3, 3};
|
||||
Shape out_shape{3, 3, 3};
|
||||
auto R = make_shared<ov::op::v0::Parameter>(element::f32, ref_shape);
|
||||
auto I = make_shared<ov::op::v0::Parameter>(element::i32, indices_shape);
|
||||
auto U = make_shared<ov::op::v0::Parameter>(element::i32, updates_shape);
|
||||
auto R = std::make_shared<op::v0::Parameter>(element::f32, ref_shape);
|
||||
auto I = std::make_shared<op::v0::Parameter>(element::i32, indices_shape);
|
||||
auto U = std::make_shared<op::v0::Parameter>(element::i32, updates_shape);
|
||||
try {
|
||||
auto G = make_shared<op::v3::ScatterNDUpdate>(R, I, U);
|
||||
auto G = this->make_op(R, I, U);
|
||||
// Should have thrown, so fail if it didn't
|
||||
FAIL() << "Created ScatterND op with incorrect updates element type.";
|
||||
} catch (const NodeValidationFailure& error) {
|
||||
|
|
@ -69,16 +81,16 @@ TEST(type_prop, scatter_nd_update_fail_updates_element_type) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_nd_update_fail_updates_shape) {
|
||||
TYPED_TEST_P(TypePropScatterNDUpdateTest, scatter_nd_update_fail_updates_shape) {
|
||||
Shape ref_shape{3, 3, 3};
|
||||
Shape indices_shape{1};
|
||||
Shape updates_shape{2, 3};
|
||||
Shape out_shape{3, 3, 3};
|
||||
auto R = make_shared<ov::op::v0::Parameter>(element::f32, ref_shape);
|
||||
auto I = make_shared<ov::op::v0::Parameter>(element::i32, indices_shape);
|
||||
auto U = make_shared<ov::op::v0::Parameter>(element::f32, updates_shape);
|
||||
auto R = std::make_shared<op::v0::Parameter>(element::f32, ref_shape);
|
||||
auto I = std::make_shared<op::v0::Parameter>(element::i32, indices_shape);
|
||||
auto U = std::make_shared<op::v0::Parameter>(element::f32, updates_shape);
|
||||
try {
|
||||
auto G = make_shared<op::v3::ScatterNDUpdate>(R, I, U);
|
||||
auto G = this->make_op(R, I, U);
|
||||
// Should have thrown, so fail if it didn't
|
||||
FAIL() << "Incorrect updates shape";
|
||||
} catch (const NodeValidationFailure& error) {
|
||||
|
|
@ -90,16 +102,16 @@ TEST(type_prop, scatter_nd_update_fail_updates_shape) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_nd_update_fail_indices_last_dim) {
|
||||
TYPED_TEST_P(TypePropScatterNDUpdateTest, scatter_nd_update_fail_indices_last_dim) {
|
||||
Shape ref_shape{3, 3, 3};
|
||||
Shape indices_shape{2, 4};
|
||||
Shape updates_shape{2, 3, 3};
|
||||
Shape out_shape{3, 3, 3};
|
||||
auto R = make_shared<ov::op::v0::Parameter>(element::f32, ref_shape);
|
||||
auto I = make_shared<ov::op::v0::Parameter>(element::i32, indices_shape);
|
||||
auto U = make_shared<ov::op::v0::Parameter>(element::f32, updates_shape);
|
||||
auto R = std::make_shared<op::v0::Parameter>(element::f32, ref_shape);
|
||||
auto I = std::make_shared<op::v0::Parameter>(element::i32, indices_shape);
|
||||
auto U = std::make_shared<op::v0::Parameter>(element::f32, updates_shape);
|
||||
try {
|
||||
auto G = make_shared<op::v3::ScatterNDUpdate>(R, I, U);
|
||||
auto G = this->make_op(R, I, U);
|
||||
// Should have thrown, so fail if it didn't
|
||||
FAIL() << "Incorrect indices innermost dim";
|
||||
} catch (const NodeValidationFailure& error) {
|
||||
|
|
@ -109,84 +121,73 @@ TEST(type_prop, scatter_nd_update_fail_indices_last_dim) {
|
|||
}
|
||||
}
|
||||
|
||||
using namespace ov::opset10;
|
||||
using namespace testing;
|
||||
TYPED_TEST_P(TypePropScatterNDUpdateTest, data_input_partial_shape_and_symbols_propagation) {
|
||||
const auto d = std::make_shared<op::v0::Parameter>(element::f32, this->data_3d_dynamic);
|
||||
const auto i = std::make_shared<op::v0::Parameter>(element::i32, PartialShape{3, 2});
|
||||
const auto u = std::make_shared<op::v0::Parameter>(element::f32, PartialShape{3, 5});
|
||||
|
||||
class TypePropScatterUpdateNDV3Test : public TypePropOpTest<op::v3::ScatterNDUpdate> {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
set_shape_symbols(data_3d_dynamic);
|
||||
}
|
||||
PartialShape data_3d_dynamic{{2, 5}, 2, {4, 10}};
|
||||
};
|
||||
|
||||
TEST_F(TypePropScatterUpdateNDV3Test, data_input_partial_shape_and_symbols_propagation) {
|
||||
const auto d = std::make_shared<Parameter>(element::f32, data_3d_dynamic);
|
||||
const auto i = std::make_shared<Parameter>(element::i32, PartialShape{3, 2});
|
||||
const auto u = std::make_shared<Parameter>(element::f32, PartialShape{3, 5});
|
||||
|
||||
const auto op = make_op(d, i, u);
|
||||
const auto op = this->make_op(d, i, u);
|
||||
|
||||
EXPECT_EQ(op->get_input_size(), 3);
|
||||
EXPECT_EQ(op->get_output_size(), 1);
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::f32);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), data_3d_dynamic);
|
||||
EXPECT_THAT(get_shape_symbols(op->get_output_partial_shape(0)), get_shape_symbols(data_3d_dynamic));
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), this->data_3d_dynamic);
|
||||
EXPECT_THAT(get_shape_symbols(op->get_output_partial_shape(0)), get_shape_symbols(this->data_3d_dynamic));
|
||||
}
|
||||
|
||||
TEST_F(TypePropScatterUpdateNDV3Test, indicies_input_is_dynamic) {
|
||||
const auto d = std::make_shared<Parameter>(element::f64, data_3d_dynamic);
|
||||
const auto i = std::make_shared<Parameter>(element::i32, PartialShape::dynamic());
|
||||
const auto u = std::make_shared<Parameter>(element::f64, PartialShape{3, 5});
|
||||
TYPED_TEST_P(TypePropScatterNDUpdateTest, indicies_input_is_dynamic) {
|
||||
const auto d = std::make_shared<op::v0::Parameter>(element::f64, this->data_3d_dynamic);
|
||||
const auto i = std::make_shared<op::v0::Parameter>(element::i32, PartialShape::dynamic());
|
||||
const auto u = std::make_shared<op::v0::Parameter>(element::f64, PartialShape{3, 5});
|
||||
|
||||
const auto op = make_op(d, i, u);
|
||||
const auto op = this->make_op(d, i, u);
|
||||
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::f64);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), data_3d_dynamic);
|
||||
EXPECT_THAT(get_shape_symbols(op->get_output_partial_shape(0)), get_shape_symbols(data_3d_dynamic));
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), this->data_3d_dynamic);
|
||||
EXPECT_THAT(get_shape_symbols(op->get_output_partial_shape(0)), get_shape_symbols(this->data_3d_dynamic));
|
||||
}
|
||||
|
||||
TEST_F(TypePropScatterUpdateNDV3Test, updates_input_is_dynamic) {
|
||||
const auto d = std::make_shared<Parameter>(element::f64, data_3d_dynamic);
|
||||
const auto i = std::make_shared<Parameter>(element::i32, PartialShape{3, 2});
|
||||
const auto u = std::make_shared<Parameter>(element::f64, PartialShape::dynamic());
|
||||
TYPED_TEST_P(TypePropScatterNDUpdateTest, updates_input_is_dynamic) {
|
||||
const auto d = std::make_shared<op::v0::Parameter>(element::f64, this->data_3d_dynamic);
|
||||
const auto i = std::make_shared<op::v0::Parameter>(element::i32, PartialShape{3, 2});
|
||||
const auto u = std::make_shared<op::v0::Parameter>(element::f64, PartialShape::dynamic());
|
||||
|
||||
const auto op = make_op(d, i, u);
|
||||
const auto op = this->make_op(d, i, u);
|
||||
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::f64);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), data_3d_dynamic);
|
||||
EXPECT_THAT(get_shape_symbols(op->get_output_partial_shape(0)), get_shape_symbols(data_3d_dynamic));
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), this->data_3d_dynamic);
|
||||
EXPECT_THAT(get_shape_symbols(op->get_output_partial_shape(0)), get_shape_symbols(this->data_3d_dynamic));
|
||||
}
|
||||
|
||||
TEST_F(TypePropScatterUpdateNDV3Test, indicies_input_has_interval_dimensions) {
|
||||
const auto d = std::make_shared<Parameter>(element::i64, data_3d_dynamic);
|
||||
const auto i = std::make_shared<Parameter>(element::i32, PartialShape{{0, 3}, 1});
|
||||
const auto u = std::make_shared<Parameter>(element::i64, PartialShape{3, 2, {8, 10}});
|
||||
TYPED_TEST_P(TypePropScatterNDUpdateTest, indicies_input_has_interval_dimensions) {
|
||||
const auto d = std::make_shared<op::v0::Parameter>(element::i64, this->data_3d_dynamic);
|
||||
const auto i = std::make_shared<op::v0::Parameter>(element::i32, PartialShape{{0, 3}, 1});
|
||||
const auto u = std::make_shared<op::v0::Parameter>(element::i64, PartialShape{3, 2, {8, 10}});
|
||||
|
||||
const auto op = make_op(d, i, u);
|
||||
const auto op = this->make_op(d, i, u);
|
||||
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::i64);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), data_3d_dynamic);
|
||||
EXPECT_THAT(get_shape_symbols(op->get_output_partial_shape(0)), get_shape_symbols(data_3d_dynamic));
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), this->data_3d_dynamic);
|
||||
EXPECT_THAT(get_shape_symbols(op->get_output_partial_shape(0)), get_shape_symbols(this->data_3d_dynamic));
|
||||
}
|
||||
|
||||
TEST_F(TypePropScatterUpdateNDV3Test, updates_input_is_scalar) {
|
||||
const auto d = std::make_shared<Parameter>(element::i8, data_3d_dynamic);
|
||||
const auto i = std::make_shared<Parameter>(element::i32, PartialShape{3});
|
||||
const auto u = std::make_shared<Parameter>(element::i8, PartialShape{});
|
||||
TYPED_TEST_P(TypePropScatterNDUpdateTest, updates_input_is_scalar) {
|
||||
const auto d = std::make_shared<op::v0::Parameter>(element::i8, this->data_3d_dynamic);
|
||||
const auto i = std::make_shared<op::v0::Parameter>(element::i32, PartialShape{3});
|
||||
const auto u = std::make_shared<op::v0::Parameter>(element::i8, PartialShape{});
|
||||
|
||||
const auto op = make_op(d, i, u);
|
||||
const auto op = this->make_op(d, i, u);
|
||||
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::i8);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), data_3d_dynamic);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), this->data_3d_dynamic);
|
||||
}
|
||||
|
||||
TEST_F(TypePropScatterUpdateNDV3Test, default_ctor) {
|
||||
const auto d = std::make_shared<Parameter>(element::i64, PartialShape{2, 3, 5, 1});
|
||||
const auto i = std::make_shared<Parameter>(element::i32, PartialShape{1, 3});
|
||||
const auto u = std::make_shared<Parameter>(element::i64, PartialShape{1, 1});
|
||||
TYPED_TEST_P(TypePropScatterNDUpdateTest, default_ctor) {
|
||||
const auto d = std::make_shared<op::v0::Parameter>(element::i64, PartialShape{2, 3, 5, 1});
|
||||
const auto i = std::make_shared<op::v0::Parameter>(element::i32, PartialShape{1, 3});
|
||||
const auto u = std::make_shared<op::v0::Parameter>(element::i64, PartialShape{1, 1});
|
||||
|
||||
const auto op = make_op();
|
||||
const auto op = this->make_op();
|
||||
op->set_arguments(OutputVector{d, i, u});
|
||||
op->validate_and_infer_types();
|
||||
|
||||
|
|
@ -195,16 +196,17 @@ TEST_F(TypePropScatterUpdateNDV3Test, default_ctor) {
|
|||
EXPECT_THAT(get_shape_symbols(op->get_output_partial_shape(0)), Each(nullptr));
|
||||
}
|
||||
|
||||
TEST_F(TypePropScatterUpdateNDV3Test, preserve_partial_values_and_symbols_via_evaluates_bounds) {
|
||||
const auto d = Constant::create(element::i64, Shape{4}, {2, 3, 15, 4});
|
||||
const auto i = Constant::create(element::i64, Shape{2, 1}, {2, 0});
|
||||
TYPED_TEST_P(TypePropScatterNDUpdateTest, preserve_partial_values_and_symbols_via_evaluates_bounds) {
|
||||
const auto d = op::v0::Constant::create(element::i64, Shape{4}, {2, 3, 15, 4});
|
||||
const auto i = op::v0::Constant::create(element::i64, Shape{2, 1}, {2, 0});
|
||||
auto u_shape = PartialShape{{10, 20}, {3, 4}};
|
||||
auto symbols = set_shape_symbols(u_shape);
|
||||
|
||||
const auto shape_of_u = std::make_shared<op::v0::ShapeOf>(std::make_shared<Parameter>(element::i64, u_shape));
|
||||
const auto op = make_op(d, i, shape_of_u);
|
||||
const auto shape_of_u =
|
||||
std::make_shared<op::v0::ShapeOf>(std::make_shared<op::v0::Parameter>(element::i64, u_shape));
|
||||
const auto op = this->make_op(d, i, shape_of_u);
|
||||
|
||||
auto param = std::make_shared<ov::op::v0::Parameter>(element::f32, PartialShape{1});
|
||||
auto param = std::make_shared<op::v0::Parameter>(element::f32, PartialShape{1});
|
||||
auto bc = std::make_shared<op::v3::Broadcast>(param, op, op::BroadcastType::BIDIRECTIONAL);
|
||||
|
||||
EXPECT_EQ(bc->get_output_partial_shape(0), PartialShape({{3, 4}, 3, {10, 20}, 4}));
|
||||
|
|
@ -212,35 +214,98 @@ TEST_F(TypePropScatterUpdateNDV3Test, preserve_partial_values_and_symbols_via_ev
|
|||
ElementsAre(symbols[1], nullptr, symbols[0], nullptr));
|
||||
}
|
||||
|
||||
TEST_F(TypePropScatterUpdateNDV3Test, indices_dynamic_type) {
|
||||
const auto d = std::make_shared<Parameter>(element::f32, data_3d_dynamic);
|
||||
const auto i = std::make_shared<Parameter>(element::dynamic, PartialShape{3, 2});
|
||||
const auto u = std::make_shared<Parameter>(element::f32, PartialShape{3, 5});
|
||||
TYPED_TEST_P(TypePropScatterNDUpdateTest, indices_dynamic_type) {
|
||||
const auto d = std::make_shared<op::v0::Parameter>(element::f32, this->data_3d_dynamic);
|
||||
const auto i = std::make_shared<op::v0::Parameter>(element::dynamic, PartialShape{3, 2});
|
||||
const auto u = std::make_shared<op::v0::Parameter>(element::f32, PartialShape{3, 5});
|
||||
|
||||
const auto op = make_op(d, i, u);
|
||||
const auto op = this->make_op(d, i, u);
|
||||
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::f32);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), data_3d_dynamic);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), this->data_3d_dynamic);
|
||||
}
|
||||
|
||||
TEST_F(TypePropScatterUpdateNDV3Test, updates_dynamic_type) {
|
||||
const auto d = std::make_shared<Parameter>(element::i64, data_3d_dynamic);
|
||||
const auto i = std::make_shared<Parameter>(element::i32, PartialShape{3, 2});
|
||||
const auto u = std::make_shared<Parameter>(element::dynamic, PartialShape{3, 5});
|
||||
TYPED_TEST_P(TypePropScatterNDUpdateTest, updates_dynamic_type) {
|
||||
const auto d = std::make_shared<op::v0::Parameter>(element::i64, this->data_3d_dynamic);
|
||||
const auto i = std::make_shared<op::v0::Parameter>(element::i32, PartialShape{3, 2});
|
||||
const auto u = std::make_shared<op::v0::Parameter>(element::dynamic, PartialShape{3, 5});
|
||||
|
||||
const auto op = make_op(d, i, u);
|
||||
const auto op = this->make_op(d, i, u);
|
||||
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::i64);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), data_3d_dynamic);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), this->data_3d_dynamic);
|
||||
}
|
||||
|
||||
TEST_F(TypePropScatterUpdateNDV3Test, all_dynamic_type) {
|
||||
const auto d = std::make_shared<Parameter>(element::dynamic, data_3d_dynamic);
|
||||
const auto i = std::make_shared<Parameter>(element::i64, PartialShape{3, 2});
|
||||
const auto u = std::make_shared<Parameter>(element::dynamic, PartialShape{3, 5});
|
||||
TYPED_TEST_P(TypePropScatterNDUpdateTest, all_dynamic_type) {
|
||||
const auto d = std::make_shared<op::v0::Parameter>(element::dynamic, this->data_3d_dynamic);
|
||||
const auto i = std::make_shared<op::v0::Parameter>(element::i64, PartialShape{3, 2});
|
||||
const auto u = std::make_shared<op::v0::Parameter>(element::dynamic, PartialShape{3, 5});
|
||||
|
||||
const auto op = make_op(d, i, u);
|
||||
const auto op = this->make_op(d, i, u);
|
||||
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::dynamic);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), data_3d_dynamic);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), this->data_3d_dynamic);
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_nd_update_v14_default_attribute) {
|
||||
const auto d = std::make_shared<op::v0::Parameter>(element::i64, PartialShape{2, 3, 5, 1});
|
||||
const auto i = std::make_shared<op::v0::Parameter>(element::i32, PartialShape{1, 3});
|
||||
const auto u = std::make_shared<op::v0::Parameter>(element::i64, PartialShape{1, 1});
|
||||
|
||||
const auto op = std::make_shared<op::v14::ScatterNDUpdate>();
|
||||
op->set_arguments(OutputVector{d, i, u});
|
||||
op->validate_and_infer_types();
|
||||
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::i64);
|
||||
EXPECT_EQ(op->get_reduction(), op::v14::ScatterNDUpdate::Reduction::NONE);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), PartialShape({2, 3, 5, 1}));
|
||||
EXPECT_THAT(get_shape_symbols(op->get_output_partial_shape(0)), Each(nullptr));
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_nd_update_v14_attribute_setter_enum) {
|
||||
const auto d = std::make_shared<op::v0::Parameter>(element::i64, PartialShape{2, 3, 5, 1});
|
||||
const auto i = std::make_shared<op::v0::Parameter>(element::i32, PartialShape{1, 3});
|
||||
const auto u = std::make_shared<op::v0::Parameter>(element::i64, PartialShape{1, 1});
|
||||
|
||||
const auto op = std::make_shared<op::v14::ScatterNDUpdate>();
|
||||
op->set_arguments(OutputVector{d, i, u});
|
||||
op->set_reduction(op::v14::ScatterNDUpdate::Reduction::PROD);
|
||||
op->validate_and_infer_types();
|
||||
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::i64);
|
||||
EXPECT_EQ(op->get_reduction(), op::v14::ScatterNDUpdate::Reduction::PROD);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), PartialShape({2, 3, 5, 1}));
|
||||
EXPECT_THAT(get_shape_symbols(op->get_output_partial_shape(0)), Each(nullptr));
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_nd_update_v14_attribute_constructor) {
|
||||
const auto d = std::make_shared<op::v0::Parameter>(element::i64, PartialShape{2, 3, 5, 1});
|
||||
const auto i = std::make_shared<op::v0::Parameter>(element::i32, PartialShape{1, 3});
|
||||
const auto u = std::make_shared<op::v0::Parameter>(element::i64, PartialShape{1, 1});
|
||||
|
||||
const auto op = std::make_shared<op::v14::ScatterNDUpdate>(d, i, u, op::v14::ScatterNDUpdate::Reduction::MAX);
|
||||
|
||||
EXPECT_EQ(op->get_output_element_type(0), element::i64);
|
||||
EXPECT_EQ(op->get_reduction(), op::v14::ScatterNDUpdate::Reduction::MAX);
|
||||
EXPECT_EQ(op->get_output_partial_shape(0), PartialShape({2, 3, 5, 1}));
|
||||
EXPECT_THAT(get_shape_symbols(op->get_output_partial_shape(0)), Each(nullptr));
|
||||
}
|
||||
|
||||
REGISTER_TYPED_TEST_SUITE_P(TypePropScatterNDUpdateTest,
|
||||
default_ctor,
|
||||
indices_dynamic_type,
|
||||
indicies_input_has_interval_dimensions,
|
||||
data_input_partial_shape_and_symbols_propagation,
|
||||
indicies_input_is_dynamic,
|
||||
preserve_partial_values_and_symbols_via_evaluates_bounds,
|
||||
scatter_nd_update_fail_indices_last_dim,
|
||||
scatter_nd_update_fail_updates_element_type,
|
||||
scatter_nd_update_fail_updates_shape,
|
||||
scatter_nd_update_v3_fail_indices_element_type,
|
||||
scatter_nd_update_v3_fail_updates_rank,
|
||||
updates_dynamic_type,
|
||||
updates_input_is_dynamic,
|
||||
updates_input_is_scalar,
|
||||
all_dynamic_type);
|
||||
using OpVersions = ::testing::Types<op::v3::ScatterNDUpdate, op::v14::ScatterNDUpdate>;
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(type_prop, TypePropScatterNDUpdateTest, OpVersions);
|
||||
|
|
|
|||
|
|
@ -25,3 +25,22 @@ TEST(attributes, scatter_nd_update) {
|
|||
const auto expected_attr_count = 0;
|
||||
EXPECT_EQ(builder.get_value_map_size(), expected_attr_count);
|
||||
}
|
||||
|
||||
TEST(attributes, scatter_nd_update_v14) {
|
||||
NodeBuilder::opset().insert<ov::op::v14::ScatterNDUpdate>();
|
||||
|
||||
auto data = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{1000, 256, 10, 15});
|
||||
auto indices = std::make_shared<ov::op::v0::Parameter>(element::i32, Shape{25, 125, 3});
|
||||
auto updates = std::make_shared<ov::op::v0::Parameter>(element::f32, Shape{25, 125, 15});
|
||||
|
||||
auto scatter = std::make_shared<ov::op::v14::ScatterNDUpdate>(data,
|
||||
indices,
|
||||
updates,
|
||||
op::v14::ScatterNDUpdate::Reduction::PROD);
|
||||
NodeBuilder builder(scatter, {data, indices, updates});
|
||||
const auto g_scatter = ov::as_type_ptr<ov::op::v14::ScatterNDUpdate>(builder.create());
|
||||
|
||||
const auto expected_attr_count = 1;
|
||||
EXPECT_EQ(builder.get_value_map_size(), expected_attr_count);
|
||||
EXPECT_EQ(g_scatter->get_reduction(), scatter->get_reduction());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
using namespace reference_tests;
|
||||
using namespace ov;
|
||||
using Reduction = ov::op::v14::ScatterNDUpdate::Reduction;
|
||||
|
||||
namespace {
|
||||
struct ScatterNDUpdateParams {
|
||||
|
|
@ -23,25 +24,41 @@ struct ScatterNDUpdateParams {
|
|||
indexTensor(indexTensor),
|
||||
updateTensor(updateTensor),
|
||||
expectedTensor(expectedTensor),
|
||||
reduction(Reduction::NONE),
|
||||
testcaseName(testcaseName) {}
|
||||
|
||||
ScatterNDUpdateParams(const reference_tests::Tensor& dataTensor,
|
||||
const reference_tests::Tensor& indexTensor,
|
||||
const reference_tests::Tensor& updateTensor,
|
||||
const reference_tests::Tensor& expectedTensor,
|
||||
const Reduction paramReduction,
|
||||
const std::string& testcaseName)
|
||||
: dataTensor(dataTensor),
|
||||
indexTensor(indexTensor),
|
||||
updateTensor(updateTensor),
|
||||
expectedTensor(expectedTensor),
|
||||
reduction{paramReduction},
|
||||
testcaseName(testcaseName) {}
|
||||
|
||||
reference_tests::Tensor dataTensor;
|
||||
reference_tests::Tensor indexTensor;
|
||||
reference_tests::Tensor updateTensor;
|
||||
reference_tests::Tensor expectedTensor;
|
||||
Reduction reduction;
|
||||
std::string testcaseName;
|
||||
};
|
||||
|
||||
class ReferenceScatterNDUpdateLayerTest : public testing::TestWithParam<ScatterNDUpdateParams>,
|
||||
public CommonReferenceTest {
|
||||
public:
|
||||
class ReferenceScatterNDUpdateV3LayerTest : public testing::TestWithParam<ScatterNDUpdateParams>,
|
||||
public CommonReferenceTest {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
auto params = GetParam();
|
||||
const auto& params = GetParam();
|
||||
function = CreateFunction(params);
|
||||
inputData = {params.dataTensor.data};
|
||||
refOutData = {params.expectedTensor.data};
|
||||
}
|
||||
|
||||
public:
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<ScatterNDUpdateParams>& obj) {
|
||||
auto param = obj.param;
|
||||
std::ostringstream result;
|
||||
|
|
@ -75,7 +92,44 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
TEST_P(ReferenceScatterNDUpdateLayerTest, CompareWithRefs) {
|
||||
class ReferenceScatterNDUpdateV14LayerTest : public testing::TestWithParam<ScatterNDUpdateParams>,
|
||||
public CommonReferenceTest {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
const auto& params = GetParam();
|
||||
function = CreateFunction(params);
|
||||
inputData = {params.dataTensor.data};
|
||||
refOutData = {params.expectedTensor.data};
|
||||
}
|
||||
|
||||
public:
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<ScatterNDUpdateParams>& obj) {
|
||||
const auto& param = obj.param;
|
||||
std::ostringstream result;
|
||||
result << ReferenceScatterNDUpdateV3LayerTest::getTestCaseName(obj);
|
||||
result << "_reduction=" << param.reduction;
|
||||
return result.str();
|
||||
}
|
||||
|
||||
private:
|
||||
static std::shared_ptr<Model> CreateFunction(const ScatterNDUpdateParams& params) {
|
||||
const auto data = std::make_shared<op::v0::Parameter>(params.dataTensor.type, params.dataTensor.shape);
|
||||
const auto indices = std::make_shared<op::v0::Constant>(params.indexTensor.type,
|
||||
params.indexTensor.shape,
|
||||
params.indexTensor.data.data());
|
||||
const auto updates = std::make_shared<op::v0::Constant>(params.updateTensor.type,
|
||||
params.updateTensor.shape,
|
||||
params.updateTensor.data.data());
|
||||
const auto scatter = std::make_shared<op::v14::ScatterNDUpdate>(data, indices, updates, params.reduction);
|
||||
return std::make_shared<ov::Model>(NodeVector{scatter}, ParameterVector{data});
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(ReferenceScatterNDUpdateV3LayerTest, CompareWithRefs) {
|
||||
Exec();
|
||||
}
|
||||
|
||||
TEST_P(ReferenceScatterNDUpdateV14LayerTest, CompareWithRefs) {
|
||||
Exec();
|
||||
}
|
||||
|
||||
|
|
@ -87,8 +141,8 @@ std::vector<ScatterNDUpdateParams> generateScatterNDUpdateParams() {
|
|||
// scatter_nd_update_1x1
|
||||
ScatterNDUpdateParams(reference_tests::Tensor({1}, IN_ET, std::vector<T>{1}),
|
||||
reference_tests::Tensor({1}, IU_ET, std::vector<U>{0}),
|
||||
reference_tests::Tensor({1}, IN_ET, std::vector<T>{20}),
|
||||
reference_tests::Tensor({1}, IN_ET, std::vector<T>{20}),
|
||||
reference_tests::Tensor({1}, IN_ET, std::vector<T>{40}),
|
||||
reference_tests::Tensor({1}, IN_ET, std::vector<T>{40}),
|
||||
"scatter_nd_update_1x1"),
|
||||
// scatter_nd_update_2x2_by_1
|
||||
ScatterNDUpdateParams(reference_tests::Tensor({2, 2}, IN_ET, std::vector<T>{1, 2, 3, 4}),
|
||||
|
|
@ -189,7 +243,335 @@ std::vector<ScatterNDUpdateParams> generateScatterNDUpdateParams() {
|
|||
return scatterParams;
|
||||
}
|
||||
|
||||
std::vector<ScatterNDUpdateParams> generateScatterNDUpdateCombinedParams() {
|
||||
template <element::Type_t IN_ET, element::Type_t IU_ET>
|
||||
std::vector<ScatterNDUpdateParams> generateScatterNDUpdateV14Params() {
|
||||
using T = typename element_type_traits<IN_ET>::value_type;
|
||||
using U = typename element_type_traits<IU_ET>::value_type;
|
||||
std::vector<ScatterNDUpdateParams> scatterParams{
|
||||
// Duplicated indices tests:
|
||||
ScatterNDUpdateParams(reference_tests::Tensor({1}, IN_ET, std::vector<T>{1}),
|
||||
reference_tests::Tensor({2, 1}, IU_ET, std::vector<U>{0, 0}),
|
||||
reference_tests::Tensor({2}, IN_ET, std::vector<T>{40, 50}),
|
||||
reference_tests::Tensor({1}, IN_ET, std::vector<T>{50}),
|
||||
"scatter_nd_update_1x1_duplicated_indices"),
|
||||
ScatterNDUpdateParams(reference_tests::Tensor({3, 2}, IN_ET, std::vector<T>{1, 1, 1, 1, 1, 1}),
|
||||
reference_tests::Tensor({2, 2}, IU_ET, std::vector<U>{0, 1, 0, 1}),
|
||||
reference_tests::Tensor({2}, IN_ET, std::vector<T>{5, 10}),
|
||||
reference_tests::Tensor({3, 2}, IN_ET, std::vector<T>{1, 10, 1, 1, 1, 1}),
|
||||
"scatter_nd_update_tf_example_duplicated_indices"),
|
||||
ScatterNDUpdateParams(
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{8, 12, 1, 5, 3, 19, 2, 4, 13,
|
||||
7, 6, 25, 5, 12, 11, 23, 17, 2,
|
||||
18, 23, 16, 17, 11, 22, 0, 10, 20}),
|
||||
reference_tests::Tensor({2, 1}, IU_ET, std::vector<U>{2, 2}),
|
||||
reference_tests::Tensor({2, 3, 3},
|
||||
IN_ET,
|
||||
std::vector<T>{4, 15, 11, 13, 15, 23, 1, 4, 4, 11, 2, 10, 1, 25, 25, 19, 23, 10}),
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{8, 12, 1, 5, 3, 19, 2, 4, 13,
|
||||
7, 6, 25, 5, 12, 11, 23, 17, 2,
|
||||
11, 2, 10, 1, 25, 25, 19, 23, 10}),
|
||||
"scatter_nd_update_3x3_by_1_duplicated_indices"),
|
||||
|
||||
ScatterNDUpdateParams(
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
31, 32, 33, 34, 35, 36, 37, 38, 39}),
|
||||
reference_tests::Tensor({3, 3}, IU_ET, std::vector<U>{0, 0, 0, 2, -1, 2, -1, 2, -1}),
|
||||
reference_tests::Tensor({3}, IN_ET, std::vector<T>{91, 99, 100}),
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{91, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
31, 32, 33, 34, 35, 36, 37, 38, 100}),
|
||||
"scatter_nd_update_3x3_by_3_duplicated_indices"),
|
||||
ScatterNDUpdateParams(reference_tests::Tensor({8}, IN_ET, std::vector<T>{1, 2, 3, 4, 5, 6, 7, 8}),
|
||||
reference_tests::Tensor({5, 1}, IU_ET, std::vector<U>{4, 3, 1, 7, 1}),
|
||||
reference_tests::Tensor({5}, IN_ET, std::vector<T>{9, 10, 11, 12, 22}),
|
||||
reference_tests::Tensor({8}, IN_ET, std::vector<T>{1, 22, 3, 10, 9, 6, 7, 12}),
|
||||
"scatter_nd_update_1d_from_examples_duplicated_indices"),
|
||||
ScatterNDUpdateParams(
|
||||
reference_tests::Tensor({4, 4, 4}, IN_ET, std::vector<T>{1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1,
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1,
|
||||
8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8,
|
||||
8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8}),
|
||||
reference_tests::Tensor({3, 1}, IU_ET, std::vector<U>{0, 2, -2}),
|
||||
reference_tests::Tensor({3, 4, 4}, IN_ET, std::vector<T>{5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
|
||||
8, 8, 8, 8, 1, 1, 1, 1, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 4, 4, 4, 4, 10, 10, 10, 10,
|
||||
11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13}),
|
||||
reference_tests::Tensor({4, 4, 4}, IN_ET, std::vector<T>{5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8,
|
||||
8, 8, 8, 1, 2, 3, 4, 5, 6, 7, 8, 8, 7,
|
||||
6, 5, 4, 3, 2, 1, 10, 10, 10, 10, 11, 11, 11,
|
||||
11, 12, 12, 12, 12, 13, 13, 13, 13, 8, 7, 6, 5,
|
||||
4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8}),
|
||||
"scatter_nd_update_4x4_shape_from_examples_duplicated_indices"),
|
||||
ScatterNDUpdateParams(
|
||||
reference_tests::Tensor({4, 4, 4}, IN_ET, std::vector<T>{1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1,
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1,
|
||||
8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8,
|
||||
8, 7, 6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 7, 8}),
|
||||
reference_tests::Tensor({3, 2, 2}, IU_ET, std::vector<U>{0, 0, 2, 2, 1, 1, 3, 3, 0, 0, 2, 2}),
|
||||
reference_tests::Tensor({3, 2, 4}, IN_ET, std::vector<T>{15, 16, 17, 18, 25, 26, 27, 28, 35, 36, 37, 38,
|
||||
45, 46, 47, 48, 55, 56, 57, 58, 65, 66, 67, 68}),
|
||||
reference_tests::Tensor({4, 4, 4}, IN_ET, std::vector<T>{55, 56, 57, 58, 5, 6, 7, 8, 8, 7, 6, 5, 4,
|
||||
3, 2, 1, 1, 2, 3, 4, 35, 36, 37, 38, 8, 7,
|
||||
6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2,
|
||||
1, 65, 66, 67, 68, 5, 6, 7, 8, 8, 7, 6, 5,
|
||||
4, 3, 2, 1, 1, 2, 3, 4, 45, 46, 47, 48}),
|
||||
"scatter_nd_update_4x4_v2_duplicated_indices"),
|
||||
// Reduction tests:
|
||||
// scatter_nd_update_1x1
|
||||
ScatterNDUpdateParams(reference_tests::Tensor({1}, IN_ET, std::vector<T>{1}),
|
||||
reference_tests::Tensor({1}, IU_ET, std::vector<U>{0}),
|
||||
reference_tests::Tensor({1}, IN_ET, std::vector<T>{40}),
|
||||
reference_tests::Tensor({1}, IN_ET, std::vector<T>{41}),
|
||||
Reduction::SUM,
|
||||
"scatter_nd_update_1x1_SUM"),
|
||||
ScatterNDUpdateParams(reference_tests::Tensor({1}, IN_ET, std::vector<T>{40}),
|
||||
reference_tests::Tensor({1}, IU_ET, std::vector<U>{0}),
|
||||
reference_tests::Tensor({1}, IN_ET, std::vector<T>{40}),
|
||||
reference_tests::Tensor({1}, IN_ET, std::vector<T>{0}),
|
||||
Reduction::SUB,
|
||||
"scatter_nd_update_1x1_SUB"),
|
||||
ScatterNDUpdateParams(reference_tests::Tensor({1}, IN_ET, std::vector<T>{2}),
|
||||
reference_tests::Tensor({1}, IU_ET, std::vector<U>{0}),
|
||||
reference_tests::Tensor({1}, IN_ET, std::vector<T>{40}),
|
||||
reference_tests::Tensor({1}, IN_ET, std::vector<T>{80}),
|
||||
Reduction::PROD,
|
||||
"scatter_nd_update_1x1_PROD"),
|
||||
ScatterNDUpdateParams(reference_tests::Tensor({1}, IN_ET, std::vector<T>{2}),
|
||||
reference_tests::Tensor({1}, IU_ET, std::vector<U>{0}),
|
||||
reference_tests::Tensor({1}, IN_ET, std::vector<T>{40}),
|
||||
reference_tests::Tensor({1}, IN_ET, std::vector<T>{40}),
|
||||
Reduction::MAX,
|
||||
"scatter_nd_update_1x1_MAX"),
|
||||
ScatterNDUpdateParams(reference_tests::Tensor({1}, IN_ET, std::vector<T>{2}),
|
||||
reference_tests::Tensor({1}, IU_ET, std::vector<U>{0}),
|
||||
reference_tests::Tensor({1}, IN_ET, std::vector<T>{40}),
|
||||
reference_tests::Tensor({1}, IN_ET, std::vector<T>{2}),
|
||||
Reduction::MIN,
|
||||
"scatter_nd_update_1x1_MIN"),
|
||||
// scatter_nd_update_tf_example
|
||||
ScatterNDUpdateParams(reference_tests::Tensor({3, 2}, IN_ET, std::vector<T>{1, 1, 1, 1, 1, 1}),
|
||||
reference_tests::Tensor({2, 2}, IU_ET, std::vector<U>{0, 1, 2, 0}),
|
||||
reference_tests::Tensor({2}, IN_ET, std::vector<T>{5, 10}),
|
||||
reference_tests::Tensor({3, 2}, IN_ET, std::vector<T>{1, 6, 1, 1, 11, 1}),
|
||||
Reduction::SUM,
|
||||
"scatter_nd_update_tf_example"),
|
||||
ScatterNDUpdateParams(reference_tests::Tensor({3, 2}, IN_ET, std::vector<T>{1, 6, 1, 1, 11, 1}),
|
||||
reference_tests::Tensor({2, 2}, IU_ET, std::vector<U>{0, 1, 2, 0}),
|
||||
reference_tests::Tensor({2}, IN_ET, std::vector<T>{5, 10}),
|
||||
reference_tests::Tensor({3, 2}, IN_ET, std::vector<T>{1, 1, 1, 1, 1, 1}),
|
||||
Reduction::SUB,
|
||||
"scatter_nd_update_tf_example"),
|
||||
ScatterNDUpdateParams(reference_tests::Tensor({3, 2}, IN_ET, std::vector<T>{1, 2, 1, 1, 2, 1}),
|
||||
reference_tests::Tensor({2, 2}, IU_ET, std::vector<U>{0, 1, 2, 0}),
|
||||
reference_tests::Tensor({2}, IN_ET, std::vector<T>{5, 10}),
|
||||
reference_tests::Tensor({3, 2}, IN_ET, std::vector<T>{1, 10, 1, 1, 20, 1}),
|
||||
Reduction::PROD,
|
||||
"scatter_nd_update_tf_example"),
|
||||
ScatterNDUpdateParams(reference_tests::Tensor({3, 2}, IN_ET, std::vector<T>{1, 1, 1, 1, 1, 1}),
|
||||
reference_tests::Tensor({2, 2}, IU_ET, std::vector<U>{0, 1, 2, 0}),
|
||||
reference_tests::Tensor({2}, IN_ET, std::vector<T>{5, 10}),
|
||||
reference_tests::Tensor({3, 2}, IN_ET, std::vector<T>{1, 5, 1, 1, 10, 1}),
|
||||
Reduction::MAX,
|
||||
"scatter_nd_update_tf_example"),
|
||||
ScatterNDUpdateParams(reference_tests::Tensor({3, 2}, IN_ET, std::vector<T>{15, 15, 15, 15, 15, 15}),
|
||||
reference_tests::Tensor({2, 2}, IU_ET, std::vector<U>{0, 1, 2, 0}),
|
||||
reference_tests::Tensor({2}, IN_ET, std::vector<T>{5, 10}),
|
||||
reference_tests::Tensor({3, 2}, IN_ET, std::vector<T>{15, 5, 15, 15, 10, 15}),
|
||||
Reduction::MIN,
|
||||
"scatter_nd_update_tf_example"),
|
||||
// scatter_nd_update_3x3_by_1
|
||||
ScatterNDUpdateParams(
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{8, 12, 1, 5, 3, 19, 2, 4, 13,
|
||||
7, 6, 25, 5, 12, 11, 23, 17, 2,
|
||||
18, 23, 16, 17, 11, 22, 0, 10, 20}),
|
||||
reference_tests::Tensor({2, 1}, IU_ET, std::vector<U>{0, 2}),
|
||||
reference_tests::Tensor({2, 3, 3},
|
||||
IN_ET,
|
||||
std::vector<T>{4, 15, 11, 13, 15, 23, 1, 4, 4, 11, 2, 10, 1, 25, 25, 19, 23, 10}),
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{12, 27, 12, 18, 18, 42, 3, 8, 17,
|
||||
7, 6, 25, 5, 12, 11, 23, 17, 2,
|
||||
29, 25, 26, 18, 36, 47, 19, 33, 30}),
|
||||
Reduction::SUM,
|
||||
"scatter_nd_update_3x3_by_1"),
|
||||
ScatterNDUpdateParams(
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{8, 12, 1, 5, 3, 19, 2, 4, 13,
|
||||
7, 6, 25, 5, 12, 11, 23, 17, 2,
|
||||
18, 23, 16, 17, 11, 22, 0, 10, 20}),
|
||||
reference_tests::Tensor({2, 1}, IU_ET, std::vector<U>{0, 2}),
|
||||
reference_tests::Tensor({2, 3, 3},
|
||||
IN_ET,
|
||||
std::vector<T>{4, 15, 11, 13, 15, 23, 1, 4, 4, 11, 2, 10, 1, 25, 25, 19, 23, 10}),
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{32, 180, 11, 65, 45, 437, 2, 16, 52,
|
||||
7, 6, 25, 5, 12, 11, 23, 17, 2,
|
||||
198, 46, 160, 17, 275, 550, 0, 230, 200}),
|
||||
Reduction::PROD,
|
||||
"scatter_nd_update_3x3_by_1"),
|
||||
ScatterNDUpdateParams(
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{8, 12, 1, 5, 3, 19, 2, 4, 13,
|
||||
7, 6, 25, 5, 12, 11, 23, 17, 2,
|
||||
18, 23, 16, 17, 11, 22, 0, 10, 20}),
|
||||
reference_tests::Tensor({2, 1}, IU_ET, std::vector<U>{0, 2}),
|
||||
reference_tests::Tensor({2, 3, 3},
|
||||
IN_ET,
|
||||
std::vector<T>{4, 15, 11, 13, 15, 23, 1, 4, 4, 11, 2, 10, 1, 25, 25, 19, 23, 10}),
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{8, 15, 11, 13, 15, 23, 2, 4, 13,
|
||||
7, 6, 25, 5, 12, 11, 23, 17, 2,
|
||||
18, 23, 16, 17, 25, 25, 19, 23, 20}),
|
||||
Reduction::MAX,
|
||||
"scatter_nd_update_3x3_by_1"),
|
||||
ScatterNDUpdateParams(
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{8, 12, 1, 5, 3, 19, 2, 4, 13,
|
||||
7, 6, 25, 5, 12, 11, 23, 17, 2,
|
||||
18, 23, 16, 17, 11, 22, 0, 10, 20}),
|
||||
reference_tests::Tensor({2, 1}, IU_ET, std::vector<U>{0, 2}),
|
||||
reference_tests::Tensor({2, 3, 3},
|
||||
IN_ET,
|
||||
std::vector<T>{4, 15, 11, 13, 15, 23, 1, 4, 4, 11, 2, 10, 1, 25, 25, 19, 23, 10}),
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{4, 12, 1, 5, 3, 19, 1, 4, 4, 7, 6, 25, 5, 12,
|
||||
11, 23, 17, 2, 11, 2, 10, 1, 11, 22, 0, 10, 10}),
|
||||
Reduction::MIN,
|
||||
"scatter_nd_update_3x3_by_1"),
|
||||
ScatterNDUpdateParams(
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{37, 29, 48, 48, 27, 29, 26, 42, 42,
|
||||
48, 49, 25, 39, 36, 47, 34, 49, 42,
|
||||
35, 37, 49, 42, 46, 26, 41, 31, 41}),
|
||||
reference_tests::Tensor({2, 1}, IU_ET, std::vector<U>{0, 2}),
|
||||
reference_tests::Tensor(
|
||||
{2, 3, 3},
|
||||
IN_ET,
|
||||
std::vector<T>{18, 13, 13, 19, 13, 1, 25, 24, 15, 6, 12, 17, 12, 10, 8, 18, 16, 19}),
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{19, 16, 35, 29, 14, 28, 1, 18, 27,
|
||||
48, 49, 25, 39, 36, 47, 34, 49, 42,
|
||||
29, 25, 32, 30, 36, 18, 23, 15, 22}),
|
||||
Reduction::SUB,
|
||||
"scatter_nd_update_3x3_by_1"),
|
||||
ScatterNDUpdateParams(
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
31, 32, 33, 34, 35, 36, 37, 38, 39}),
|
||||
reference_tests::Tensor({3, 3}, IU_ET, std::vector<U>{0, 0, 0, 2, -1, 2, -1, 2, -1}),
|
||||
reference_tests::Tensor({3}, IN_ET, std::vector<T>{2, 4, 6}),
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{13, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
31, 32, 33, 34, 35, 36, 37, 38, 49}),
|
||||
Reduction::SUM,
|
||||
"scatter_nd_update_3x3_by_3_duplicated_indices"),
|
||||
ScatterNDUpdateParams(
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
31, 32, 33, 34, 35, 36, 37, 38, 39}),
|
||||
reference_tests::Tensor({3, 3}, IU_ET, std::vector<U>{0, 0, 0, 2, -1, 2, -1, 2, -1}),
|
||||
reference_tests::Tensor({3}, IN_ET, std::vector<T>{2, 4, 6}),
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{9, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
31, 32, 33, 34, 35, 36, 37, 38, 29}),
|
||||
Reduction::SUB,
|
||||
"scatter_nd_update_3x3_by_3_duplicated_indices"),
|
||||
ScatterNDUpdateParams(
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
31, 32, 33, 34, 35, 36, 37, 38, 39}),
|
||||
reference_tests::Tensor({3, 3}, IU_ET, std::vector<U>{0, 0, 0, 2, -1, 2, -1, 2, -1}),
|
||||
reference_tests::Tensor({3}, IN_ET, std::vector<T>{2, 4, 6}),
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{22, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
31, 32, 33, 34, 35, 36, 37, 38, 936}),
|
||||
Reduction::PROD,
|
||||
"scatter_nd_update_3x3_by_3_duplicated_indices"),
|
||||
ScatterNDUpdateParams(
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
31, 32, 33, 34, 35, 36, 37, 38, 39}),
|
||||
reference_tests::Tensor({3, 3}, IU_ET, std::vector<U>{0, 0, 0, 2, -1, 2, -1, 2, -1}),
|
||||
reference_tests::Tensor({3}, IN_ET, std::vector<T>{2, 4, 6}),
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
31, 32, 33, 34, 35, 36, 37, 38, 39}),
|
||||
Reduction::MAX,
|
||||
"scatter_nd_update_3x3_by_3_duplicated_indices"),
|
||||
ScatterNDUpdateParams(
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
31, 32, 33, 34, 35, 36, 37, 38, 39}),
|
||||
reference_tests::Tensor({3, 3}, IU_ET, std::vector<U>{0, 0, 0, 2, -1, 2, -1, 2, -1}),
|
||||
reference_tests::Tensor({3}, IN_ET, std::vector<T>{2, 4, 6}),
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{2, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
31, 32, 33, 34, 35, 36, 37, 38, 4}),
|
||||
Reduction::MIN,
|
||||
"scatter_nd_update_3x3_by_3_duplicated_indices"),
|
||||
};
|
||||
return scatterParams;
|
||||
}
|
||||
|
||||
template <element::Type_t IU_ET>
|
||||
std::vector<ScatterNDUpdateParams> generateScatterNDUpdateV14ParamsReductionsBoolean() {
|
||||
const auto IN_ET = element::Type_t::boolean;
|
||||
using T = typename element_type_traits<IN_ET>::value_type;
|
||||
using U = typename element_type_traits<IU_ET>::value_type;
|
||||
std::vector<ScatterNDUpdateParams> scatterParams{
|
||||
// scatter_nd_update_3x3_by_1
|
||||
ScatterNDUpdateParams(
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0,
|
||||
1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0}),
|
||||
reference_tests::Tensor({2, 1}, IU_ET, std::vector<U>{0, 2}),
|
||||
reference_tests::Tensor({2, 3, 3},
|
||||
IN_ET,
|
||||
std::vector<T>{0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0}),
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0,
|
||||
1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0}),
|
||||
Reduction::SUM,
|
||||
"scatter_nd_update_3x3_by_1"),
|
||||
ScatterNDUpdateParams(
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0,
|
||||
1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0}),
|
||||
reference_tests::Tensor({2, 1}, IU_ET, std::vector<U>{0, 2}),
|
||||
reference_tests::Tensor({2, 3, 3},
|
||||
IN_ET,
|
||||
std::vector<T>{0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0}),
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0,
|
||||
1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0}),
|
||||
Reduction::PROD,
|
||||
"scatter_nd_update_3x3_by_1"),
|
||||
ScatterNDUpdateParams(
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0,
|
||||
1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0}),
|
||||
reference_tests::Tensor({2, 1}, IU_ET, std::vector<U>{0, 2}),
|
||||
reference_tests::Tensor({2, 3, 3},
|
||||
IN_ET,
|
||||
std::vector<T>{0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0}),
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0,
|
||||
1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0}),
|
||||
Reduction::MAX,
|
||||
"scatter_nd_update_3x3_by_1"),
|
||||
ScatterNDUpdateParams(
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0,
|
||||
1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0}),
|
||||
reference_tests::Tensor({2, 1}, IU_ET, std::vector<U>{0, 2}),
|
||||
reference_tests::Tensor({2, 3, 3},
|
||||
IN_ET,
|
||||
std::vector<T>{0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0}),
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0,
|
||||
1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0}),
|
||||
Reduction::MIN,
|
||||
"scatter_nd_update_3x3_by_1"),
|
||||
ScatterNDUpdateParams(
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0,
|
||||
1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0}),
|
||||
reference_tests::Tensor({2, 1}, IU_ET, std::vector<U>{0, 2}),
|
||||
reference_tests::Tensor({2, 3, 3},
|
||||
IN_ET,
|
||||
std::vector<T>{0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0}),
|
||||
reference_tests::Tensor({3, 3, 3}, IN_ET, std::vector<T>{1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0,
|
||||
1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0}),
|
||||
Reduction::SUB,
|
||||
"scatter_nd_update_3x3_by_1"),
|
||||
};
|
||||
return scatterParams;
|
||||
}
|
||||
|
||||
std::vector<ScatterNDUpdateParams> generateScatterNDUpdateV3CombinedParams() {
|
||||
const std::vector<std::vector<ScatterNDUpdateParams>> scatterTypeParams{
|
||||
generateScatterNDUpdateParams<element::Type_t::i32, element::Type_t::i32>(),
|
||||
generateScatterNDUpdateParams<element::Type_t::i64, element::Type_t::i32>(),
|
||||
|
|
@ -214,12 +596,42 @@ std::vector<ScatterNDUpdateParams> generateScatterNDUpdateCombinedParams() {
|
|||
return combinedParams;
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_ScatterNDUpdate_With_Hardcoded_Refs,
|
||||
ReferenceScatterNDUpdateLayerTest,
|
||||
testing::ValuesIn(generateScatterNDUpdateCombinedParams()),
|
||||
ReferenceScatterNDUpdateLayerTest::getTestCaseName);
|
||||
std::vector<ScatterNDUpdateParams> generateScatterNDUpdateV14CombinedParams() {
|
||||
const std::vector<std::vector<ScatterNDUpdateParams>> scatterTypeParams{
|
||||
generateScatterNDUpdateV14Params<element::Type_t::i32, element::Type_t::i32>(),
|
||||
generateScatterNDUpdateV14Params<element::Type_t::i64, element::Type_t::i32>(),
|
||||
generateScatterNDUpdateV14Params<element::Type_t::u32, element::Type_t::i32>(),
|
||||
generateScatterNDUpdateV14Params<element::Type_t::u64, element::Type_t::i32>(),
|
||||
generateScatterNDUpdateV14Params<element::Type_t::f16, element::Type_t::i32>(),
|
||||
generateScatterNDUpdateV14Params<element::Type_t::f32, element::Type_t::i32>(),
|
||||
generateScatterNDUpdateV14Params<element::Type_t::i32, element::Type_t::i64>(),
|
||||
generateScatterNDUpdateV14Params<element::Type_t::i64, element::Type_t::i64>(),
|
||||
generateScatterNDUpdateV14Params<element::Type_t::u32, element::Type_t::i64>(),
|
||||
generateScatterNDUpdateV14Params<element::Type_t::u64, element::Type_t::i64>(),
|
||||
generateScatterNDUpdateV14Params<element::Type_t::f16, element::Type_t::i64>(),
|
||||
generateScatterNDUpdateV14Params<element::Type_t::f32, element::Type_t::i64>(),
|
||||
generateScatterNDUpdateV14ParamsReductionsBoolean<element::Type_t::i32>(),
|
||||
generateScatterNDUpdateV14ParamsReductionsBoolean<element::Type_t::i64>(),
|
||||
};
|
||||
std::vector<ScatterNDUpdateParams> combinedParams = generateScatterNDUpdateV3CombinedParams();
|
||||
|
||||
class ReferenceScatterNDUpdateLayerNegativeTest : public ReferenceScatterNDUpdateLayerTest {};
|
||||
for (const auto& params : scatterTypeParams) {
|
||||
combinedParams.insert(combinedParams.end(), params.begin(), params.end());
|
||||
}
|
||||
return combinedParams;
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_ScatterNDUpdate_With_Hardcoded_Refs,
|
||||
ReferenceScatterNDUpdateV3LayerTest,
|
||||
testing::ValuesIn(generateScatterNDUpdateV3CombinedParams()),
|
||||
ReferenceScatterNDUpdateV3LayerTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_ScatterNDUpdate_With_Hardcoded_Refs,
|
||||
ReferenceScatterNDUpdateV14LayerTest,
|
||||
testing::ValuesIn(generateScatterNDUpdateV14CombinedParams()),
|
||||
ReferenceScatterNDUpdateV14LayerTest::getTestCaseName);
|
||||
|
||||
class ReferenceScatterNDUpdateLayerNegativeTest : public ReferenceScatterNDUpdateV3LayerTest {};
|
||||
|
||||
TEST_P(ReferenceScatterNDUpdateLayerNegativeTest, CompareWithRefsNegative) {
|
||||
LoadNetwork();
|
||||
|
|
|
|||
|
|
@ -1426,6 +1426,8 @@ std::shared_ptr<ov::Model> generateScatterNDBase(const std::shared_ptr<ov::op::O
|
|||
std::shared_ptr<ov::Node> scatterNode;
|
||||
if (ov::is_type<ov::op::v3::ScatterNDUpdate>(node)) {
|
||||
scatterNode = std::make_shared<ov::op::v3::ScatterNDUpdate>(data, indices, updates);
|
||||
} else if (ov::is_type<ov::op::v14::ScatterNDUpdate>(node)) {
|
||||
scatterNode = std::make_shared<ov::op::v14::ScatterNDUpdate>(data, indices, updates, ov::op::v14::ScatterNDUpdate::Reduction::SUM);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue