ScatterUpdate ng op shell revision (#7375)
* add visitors, type_prop tests, update ngrap op class * update NGRPH_RTTI for scatter_update * add proper formatting for error message * update opset
This commit is contained in:
+51
@@ -0,0 +1,51 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
#include <ngraph/opsets/opset8.hpp>
|
||||
|
||||
#include "shared_test_classes/single_layer/scatter_update.hpp"
|
||||
#include "common_test_utils/test_constants.hpp"
|
||||
|
||||
using namespace LayerTestsDefinitions;
|
||||
using namespace ngraph::opset8;
|
||||
|
||||
namespace {
|
||||
TEST_P(ScatterUpdateLayerTest, Serialize) {
|
||||
Serialize();
|
||||
}
|
||||
|
||||
const std::vector<InferenceEngine::Precision> inputPrecisions = {
|
||||
InferenceEngine::Precision::FP32,
|
||||
InferenceEngine::Precision::FP16,
|
||||
InferenceEngine::Precision::I32,
|
||||
};
|
||||
|
||||
const std::vector<InferenceEngine::Precision> idxPrecisions = {
|
||||
InferenceEngine::Precision::I32,
|
||||
InferenceEngine::Precision::I64,
|
||||
};
|
||||
|
||||
// map<inputShape, map<indicesShape, axis>>
|
||||
std::map<std::vector<size_t>, std::map<std::vector<size_t>, std::vector<int>>> axesShapeInShape {
|
||||
{{10, 16, 12, 15}, {{{2, 4}, {0, 1, 2, 3}}, {{8}, {-1, -2, -3, -4}}}},
|
||||
{{10, 9, 10, 9, 10}, {{{8}, {-3, -1, 0, 2, 4}}, {{4, 2}, {-2, 2}}}},
|
||||
};
|
||||
//indices should not be random value
|
||||
const std::vector<std::vector<int64_t>> idxValue = {
|
||||
{0, 2, 4, 6, 1, 3, 5, 7}
|
||||
};
|
||||
|
||||
const auto ScatterUpdateCase = ::testing::Combine(
|
||||
::testing::ValuesIn(ScatterUpdateLayerTest::combineShapes(axesShapeInShape)),
|
||||
::testing::ValuesIn(idxValue),
|
||||
::testing::ValuesIn(inputPrecisions),
|
||||
::testing::ValuesIn(idxPrecisions),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU)
|
||||
);
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_ScatterUpdate, ScatterUpdateLayerTest, ScatterUpdateCase, ScatterUpdateLayerTest::getTestCaseName);
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -59,7 +59,13 @@ void ov::op::util::ScatterBase::validate_and_infer_types() {
|
||||
this,
|
||||
data_shape.rank().is_dynamic() || indices_shape.rank().is_dynamic() || updates_shape.rank().is_dynamic() ||
|
||||
updates_shape.rank().get_length() == indices_shape.rank().get_length() + data_shape.rank().get_length() - 1,
|
||||
"Updates rank is expected to be indices rank + data rank - 1.");
|
||||
"Updates rank is expected to be rank(indices) + rank(data) - 1.",
|
||||
" Got: rank(data) = ",
|
||||
data_shape.rank().get_length(),
|
||||
", rank(indices) = ",
|
||||
indices_shape.rank().get_length(),
|
||||
", rank(updates) = ",
|
||||
updates_shape.rank().get_length());
|
||||
|
||||
if (data_shape.is_dynamic()) {
|
||||
set_input_is_relevant_to_shape(0);
|
||||
@@ -73,20 +79,21 @@ void ov::op::util::ScatterBase::validate_and_infer_types() {
|
||||
if (const auto& axis_const_input = get_constant_from_source(input_value(AXIS))) {
|
||||
bool compatible = true;
|
||||
int64_t axis = axis_const_input->cast_vector<int64_t>().at(0);
|
||||
axis = ngraph::normalize_axis(this, axis, data_shape.rank().get_length());
|
||||
int64_t data_rank = data_shape.rank().get_length();
|
||||
axis = ngraph::normalize_axis(this, axis, data_rank);
|
||||
|
||||
if (indices_shape.rank().is_static() && updates_shape.rank().is_static()) {
|
||||
for (int64_t i = 0; i < indices_shape.rank().get_length(); ++i) {
|
||||
int64_t indices_rank = indices_shape.rank().get_length();
|
||||
for (int64_t i = 0; i < indices_rank; ++i) {
|
||||
compatible = compatible && updates_shape[axis + i].compatible(indices_shape[i]);
|
||||
}
|
||||
|
||||
int64_t indices_rank = indices_shape.rank().get_length();
|
||||
// Check [d_0, d_1, ... d_(axis - 1)] updates dimensions
|
||||
for (int64_t i = 0; i < axis; ++i) {
|
||||
compatible = compatible && updates_shape[i].compatible(data_shape[i]);
|
||||
}
|
||||
// Check [d_(axis + k + 1), ..., d_n] updates dimensions
|
||||
for (int64_t i = axis + 1; i < data_shape.rank().get_length(); ++i) {
|
||||
for (int64_t i = axis + 1; i < data_rank; ++i) {
|
||||
compatible = compatible && updates_shape[indices_rank - 1 + i].compatible(data_shape[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,6 +339,7 @@ set(SRC
|
||||
visitors/op/roi_pooling.cpp
|
||||
visitors/op/round.cpp
|
||||
visitors/op/scatter_elements_update.cpp
|
||||
visitors/op/scatter_update.cpp
|
||||
visitors/op/select.cpp
|
||||
visitors/op/space_to_depth.cpp
|
||||
visitors/op/selu.cpp
|
||||
|
||||
@@ -9,197 +9,189 @@
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
|
||||
TEST(type_prop, scatter_update_v3_fail_indices_element_type) {
|
||||
namespace {
|
||||
using type = ngraph::element::Type;
|
||||
void type_check(const type& refType) {
|
||||
Shape ref_shape{2, 3, 4};
|
||||
Shape indices_shape{2, 1};
|
||||
Shape updates_shape{2, 2, 1, 4};
|
||||
auto R = make_shared<op::Parameter>(element::f32, ref_shape);
|
||||
auto I = make_shared<op::Parameter>(element::f16, indices_shape);
|
||||
auto U = make_shared<op::Parameter>(element::f32, updates_shape);
|
||||
auto A = op::Constant::create(element::i64, Shape{}, {1});
|
||||
auto R = make_shared<op::Parameter>(refType, ref_shape);
|
||||
auto I = make_shared<op::Parameter>(element::i32, indices_shape);
|
||||
auto U = make_shared<op::Parameter>(refType, updates_shape);
|
||||
auto A = op::Constant::create(element::i32, Shape{1}, {1});
|
||||
auto scatter_update = make_shared<op::v3::ScatterUpdate>(R, I, U, A);
|
||||
EXPECT_EQ(scatter_update->get_output_element_type(0), refType);
|
||||
EXPECT_EQ(scatter_update->get_output_shape(0), ref_shape);
|
||||
}
|
||||
|
||||
void incorrect_type_check(const type& refType,
|
||||
const type& indicesType,
|
||||
const type& updatesType,
|
||||
const type& axisType,
|
||||
const std::string& errorStr) {
|
||||
Shape ref_shape{2, 3, 4};
|
||||
Shape indices_shape{2, 1};
|
||||
Shape updates_shape{2, 2, 1, 4};
|
||||
auto R = make_shared<op::Parameter>(refType, ref_shape);
|
||||
auto I = make_shared<op::Parameter>(indicesType, indices_shape);
|
||||
auto U = make_shared<op::Parameter>(updatesType, updates_shape);
|
||||
auto A = op::Constant::create(axisType, Shape{1}, {1});
|
||||
try {
|
||||
auto G = make_shared<op::v3::ScatterUpdate>(R, I, U, A);
|
||||
// Should have thrown, so fail if it didn't
|
||||
FAIL() << "Incorrect indices element type";
|
||||
FAIL() << "Incorrect element type of the input";
|
||||
} catch (const NodeValidationFailure& error) {
|
||||
EXPECT_HAS_SUBSTRING(error.what(), std::string("Indices element type must be of an integral number type"));
|
||||
EXPECT_HAS_SUBSTRING(error.what(), errorStr);
|
||||
} catch (...) {
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
}
|
||||
|
||||
void incorrect_shape_check(const Shape& refShape,
|
||||
const Shape& indicesShape,
|
||||
const Shape& updatesShape,
|
||||
const Shape& axisShape,
|
||||
const float axisVal,
|
||||
const std::string& errorStr) {
|
||||
Shape ref_shape{2, 3, 4};
|
||||
Shape indices_shape{2, 1};
|
||||
Shape updates_shape{2, 2, 1, 4};
|
||||
auto R = make_shared<op::Parameter>(element::f32, refShape);
|
||||
auto I = make_shared<op::Parameter>(element::i32, indicesShape);
|
||||
auto U = make_shared<op::Parameter>(element::f32, updatesShape);
|
||||
auto A = op::Constant::create(element::i32, axisShape, {axisVal});
|
||||
try {
|
||||
auto G = make_shared<op::v3::ScatterUpdate>(R, I, U, A);
|
||||
// Should have thrown, so fail if it didn't
|
||||
FAIL() << "Incorrect shape of the input";
|
||||
} catch (const NodeValidationFailure& error) {
|
||||
EXPECT_HAS_SUBSTRING(error.what(), errorStr);
|
||||
} catch (...) {
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST(type_prop, scatter_update_output_type_check_f16) {
|
||||
type_check(element::f16);
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_output_type_check_f32) {
|
||||
type_check(element::f32);
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_output_type_check_bf16) {
|
||||
type_check(element::bf16);
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_output_type_check_i8) {
|
||||
type_check(element::i8);
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_output_type_check_i16) {
|
||||
type_check(element::i16);
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_output_type_check_i32) {
|
||||
type_check(element::i32);
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_output_type_check_i64) {
|
||||
type_check(element::i64);
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_output_type_check_u8) {
|
||||
type_check(element::u8);
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_output_type_check_u16) {
|
||||
type_check(element::u16);
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_output_type_check_u32) {
|
||||
type_check(element::u32);
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_output_type_check_u64) {
|
||||
type_check(element::u64);
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_v3_fail_updates_data_et_not_equal) {
|
||||
Shape ref_shape{2, 3, 4};
|
||||
Shape indices_shape{2, 1};
|
||||
Shape updates_shape{2, 2, 1, 4};
|
||||
auto R = make_shared<op::Parameter>(element::f32, ref_shape);
|
||||
auto I = make_shared<op::Parameter>(element::i16, indices_shape);
|
||||
auto U = make_shared<op::Parameter>(element::u32, updates_shape);
|
||||
auto A = op::Constant::create(element::u32, Shape{1}, {1});
|
||||
try {
|
||||
auto G = make_shared<op::v3::ScatterUpdate>(R, I, U, A);
|
||||
// Should have thrown, so fail if it didn't
|
||||
FAIL() << "Incorrect updates element type";
|
||||
} catch (const NodeValidationFailure& error) {
|
||||
EXPECT_HAS_SUBSTRING(error.what(), std::string("Element types for input data and updates do not match"));
|
||||
} catch (...) {
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
incorrect_type_check(element::f32,
|
||||
element::i32,
|
||||
element::u32,
|
||||
element::i32,
|
||||
"Element types for input data and updates do not match");
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_v3_fail_indices_element_type) {
|
||||
incorrect_type_check(element::f32,
|
||||
element::f16,
|
||||
element::f32,
|
||||
element::i64,
|
||||
"Indices element type must be of an integral number type");
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_v3_fail_axis_element_type) {
|
||||
Shape ref_shape{2, 3, 4};
|
||||
Shape indices_shape{2, 1};
|
||||
Shape updates_shape{2, 2, 1, 4};
|
||||
auto R = make_shared<op::Parameter>(element::i16, ref_shape);
|
||||
auto I = make_shared<op::Parameter>(element::u64, indices_shape);
|
||||
auto U = make_shared<op::Parameter>(element::i16, updates_shape);
|
||||
auto A = op::Constant::create(element::f32, Shape{1}, {1.5f});
|
||||
try {
|
||||
auto G = make_shared<op::v3::ScatterUpdate>(R, I, U, A);
|
||||
// Should have thrown, so fail if it didn't
|
||||
FAIL() << "Incorrect updates element type";
|
||||
} catch (const NodeValidationFailure& error) {
|
||||
EXPECT_HAS_SUBSTRING(error.what(), std::string("Axis element type must be of an integral number type"));
|
||||
} catch (...) {
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_v3_fail_axis_shape) {
|
||||
Shape ref_shape{2, 3, 4};
|
||||
Shape indices_shape{2, 1};
|
||||
Shape updates_shape{2, 2, 1, 4};
|
||||
auto R = make_shared<op::Parameter>(element::u8, ref_shape);
|
||||
auto I = make_shared<op::Parameter>(element::u16, indices_shape);
|
||||
auto U = make_shared<op::Parameter>(element::u8, updates_shape);
|
||||
auto A = op::Constant::create(element::u8, Shape{2}, {1, 5});
|
||||
try {
|
||||
auto G = make_shared<op::v3::ScatterUpdate>(R, I, U, A);
|
||||
// Should have thrown, so fail if it didn't
|
||||
FAIL() << "Incorrect updates element type";
|
||||
} catch (const NodeValidationFailure& error) {
|
||||
EXPECT_HAS_SUBSTRING(error.what(), std::string("Axis input shape is required to be scalar or 1D tensor"));
|
||||
} catch (...) {
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
incorrect_type_check(element::i16,
|
||||
element::u64,
|
||||
element::i16,
|
||||
element::f32,
|
||||
"Axis element type must be of an integral number type");
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_v3_fail_updates_rank) {
|
||||
Shape ref_shape{2, 3, 4};
|
||||
Shape indices_shape{2, 1};
|
||||
Shape updates_shape{2, 1, 4};
|
||||
auto R = make_shared<op::Parameter>(element::f64, ref_shape);
|
||||
auto I = make_shared<op::Parameter>(element::i16, indices_shape);
|
||||
auto U = make_shared<op::Parameter>(element::f64, updates_shape);
|
||||
auto A = op::Constant::create(element::u8, Shape{}, {0});
|
||||
try {
|
||||
auto G = make_shared<op::v3::ScatterUpdate>(R, I, U, A);
|
||||
// Should have thrown, so fail if it didn't
|
||||
FAIL() << "Incorrect updates element type";
|
||||
} catch (const NodeValidationFailure& error) {
|
||||
EXPECT_HAS_SUBSTRING(error.what(), std::string("Updates rank is expected to be indices rank + data rank - 1"));
|
||||
} catch (...) {
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
incorrect_shape_check({2, 3, 4},
|
||||
{2, 1},
|
||||
{2, 1, 4},
|
||||
{},
|
||||
0,
|
||||
"Updates rank is expected to be rank(indices) + rank(data) - 1");
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_v3_fail_updates_shape_axis) {
|
||||
Shape ref_shape{2, 3, 4};
|
||||
Shape indices_shape{2, 1};
|
||||
Shape updates_shape{2, 2, 1, 4};
|
||||
auto R = make_shared<op::Parameter>(element::u64, ref_shape);
|
||||
auto I = make_shared<op::Parameter>(element::i16, indices_shape);
|
||||
auto U = make_shared<op::Parameter>(element::u64, updates_shape);
|
||||
auto A = op::Constant::create(element::u16, Shape{}, {0});
|
||||
try {
|
||||
auto G = make_shared<op::v3::ScatterUpdate>(R, I, U, A);
|
||||
// Should have thrown, so fail if it didn't
|
||||
FAIL() << "Incorrect updates element type";
|
||||
} catch (const NodeValidationFailure& error) {
|
||||
EXPECT_HAS_SUBSTRING(error.what(),
|
||||
std::string("Updates shape must have appropriate dimensions equal to indices and "
|
||||
"data dimensions"));
|
||||
} catch (...) {
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
incorrect_shape_check({2, 3, 4},
|
||||
{2, 1},
|
||||
{2, 2, 1, 4},
|
||||
{},
|
||||
0,
|
||||
"Updates shape must have appropriate dimensions equal to indices and data dimensions");
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_v3_fail_updates_shape_indices) {
|
||||
Shape ref_shape{2, 3, 4};
|
||||
Shape indices_shape{2, 1};
|
||||
Shape updates_shape{2, 3, 1, 4};
|
||||
auto R = make_shared<op::Parameter>(element::u32, ref_shape);
|
||||
auto I = make_shared<op::Parameter>(element::i16, indices_shape);
|
||||
auto U = make_shared<op::Parameter>(element::u32, updates_shape);
|
||||
auto A = op::Constant::create(element::i32, Shape{}, {1});
|
||||
try {
|
||||
auto G = make_shared<op::v3::ScatterUpdate>(R, I, U, A);
|
||||
// Should have thrown, so fail if it didn't
|
||||
FAIL() << "Incorrect updates element type";
|
||||
} catch (const NodeValidationFailure& error) {
|
||||
EXPECT_HAS_SUBSTRING(error.what(),
|
||||
std::string("Updates shape must have appropriate dimensions equal to indices and "
|
||||
"data dimensions"));
|
||||
} catch (...) {
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
incorrect_shape_check({2, 3, 4},
|
||||
{2, 1},
|
||||
{2, 3, 1, 4},
|
||||
{},
|
||||
1,
|
||||
"Updates shape must have appropriate dimensions equal to indices and data dimensions");
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_v3_fail_updates_shape_data_before_axis) {
|
||||
Shape ref_shape{2, 3, 4};
|
||||
Shape indices_shape{2, 1};
|
||||
Shape updates_shape{3, 2, 1, 4};
|
||||
auto R = make_shared<op::Parameter>(element::u16, ref_shape);
|
||||
auto I = make_shared<op::Parameter>(element::i16, indices_shape);
|
||||
auto U = make_shared<op::Parameter>(element::u16, updates_shape);
|
||||
auto A = op::Constant::create(element::i8, Shape{}, {1});
|
||||
try {
|
||||
auto G = make_shared<op::v3::ScatterUpdate>(R, I, U, A);
|
||||
// Should have thrown, so fail if it didn't
|
||||
FAIL() << "Incorrect updates element type";
|
||||
} catch (const NodeValidationFailure& error) {
|
||||
EXPECT_HAS_SUBSTRING(error.what(),
|
||||
std::string("Updates shape must have appropriate dimensions equal to indices and "
|
||||
"data dimensions"));
|
||||
} catch (...) {
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
incorrect_shape_check({2, 3, 4},
|
||||
{2, 1},
|
||||
{3, 2, 1, 4},
|
||||
{},
|
||||
1,
|
||||
"Updates shape must have appropriate dimensions equal to indices and data dimensions");
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_v3_fail_updates_shape_data_after_axis) {
|
||||
Shape ref_shape{2, 3, 4};
|
||||
Shape indices_shape{2, 1};
|
||||
Shape updates_shape{2, 2, 1, 5};
|
||||
auto R = make_shared<op::Parameter>(element::i8, ref_shape);
|
||||
auto I = make_shared<op::Parameter>(element::i16, indices_shape);
|
||||
auto U = make_shared<op::Parameter>(element::i8, updates_shape);
|
||||
auto A = op::Constant::create(element::i16, Shape{}, {1});
|
||||
try {
|
||||
auto G = make_shared<op::v3::ScatterUpdate>(R, I, U, A);
|
||||
// Should have thrown, so fail if it didn't
|
||||
FAIL() << "Incorrect updates element type";
|
||||
} catch (const NodeValidationFailure& error) {
|
||||
EXPECT_HAS_SUBSTRING(error.what(),
|
||||
std::string("Updates shape must have appropriate dimensions equal to indices and "
|
||||
"data dimensions"));
|
||||
} catch (...) {
|
||||
FAIL() << "Deduced type check failed for unexpected reason";
|
||||
}
|
||||
incorrect_shape_check({2, 3, 4},
|
||||
{2, 1},
|
||||
{2, 2, 1, 5},
|
||||
{},
|
||||
1,
|
||||
"Updates shape must have appropriate dimensions equal to indices and data dimensions");
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_v3) {
|
||||
Shape ref_shape{2, 3, 4};
|
||||
Shape indices_shape{2, 1};
|
||||
Shape updates_shape{2, 2, 1, 4};
|
||||
auto R = make_shared<op::Parameter>(element::i8, ref_shape);
|
||||
auto I = make_shared<op::Parameter>(element::i16, indices_shape);
|
||||
auto U = make_shared<op::Parameter>(element::i8, updates_shape);
|
||||
auto A = op::Constant::create(element::i16, Shape{}, {1});
|
||||
|
||||
auto scatter_update = make_shared<op::v3::ScatterUpdate>(R, I, U, A);
|
||||
EXPECT_EQ(scatter_update->get_output_element_type(0), element::i8);
|
||||
EXPECT_EQ(scatter_update->get_output_shape(0), ref_shape);
|
||||
TEST(type_prop, scatter_update_v3_fail_axis_shape) {
|
||||
incorrect_shape_check({2, 3, 4},
|
||||
{2, 1},
|
||||
{2, 2, 1, 4},
|
||||
{2},
|
||||
1,
|
||||
"Axis input shape is required to be scalar or 1D tensor");
|
||||
}
|
||||
|
||||
TEST(type_prop, scatter_update_v3_dynamic_data_shape) {
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "ngraph/ngraph.hpp"
|
||||
#include "ngraph/op/util/attr_types.hpp"
|
||||
#include "ngraph/opsets/opset1.hpp"
|
||||
#include "ngraph/opsets/opset3.hpp"
|
||||
#include "ngraph/opsets/opset4.hpp"
|
||||
#include "ngraph/opsets/opset5.hpp"
|
||||
#include "util/visitor.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace ngraph;
|
||||
using ngraph::test::NodeBuilder;
|
||||
using ngraph::test::ValueMap;
|
||||
|
||||
TEST(attributes, scatter_update_op) {
|
||||
using namespace opset3;
|
||||
|
||||
NodeBuilder::get_ops().register_factory<ScatterUpdate>();
|
||||
Shape ref_shape{2, 3, 4};
|
||||
Shape indices_shape{2, 1};
|
||||
Shape updates_shape{2, 2, 1, 4};
|
||||
auto R = make_shared<op::Parameter>(element::i8, ref_shape);
|
||||
auto I = make_shared<op::Parameter>(element::i16, indices_shape);
|
||||
auto U = make_shared<op::Parameter>(element::i8, updates_shape);
|
||||
auto A = op::Constant::create(element::i16, Shape{}, {1});
|
||||
auto op = make_shared<ScatterUpdate>(R, I, U, A);
|
||||
|
||||
NodeBuilder builder(op);
|
||||
const auto expected_attr_count = 0;
|
||||
|
||||
EXPECT_EQ(builder.get_value_map_size(), expected_attr_count);
|
||||
}
|
||||
Reference in New Issue
Block a user