Skip to content

Commit

Permalink
[Ref][Core][Opset16] Identity operation (#26716)
Browse files Browse the repository at this point in the history
### Details:
 - Add Identity Operation Core & Ref
- Spec available here:
#26718
- Opset16 initialization files should disappear after merging:
#27458

### Tickets:
 - 152727
 - 152726

---------

Co-authored-by: Mateusz Mikolajczyk <mateusz.mikolajczyk@intel.com>
  • Loading branch information
PiotrKrzem and mmikolajcz authored Nov 8, 2024
1 parent 6ae3f9f commit 6aaddd5
Show file tree
Hide file tree
Showing 15 changed files with 300 additions and 4 deletions.
30 changes: 30 additions & 0 deletions src/core/include/openvino/op/identity.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (C) 2018-2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#pragma once

#include "openvino/op/op.hpp"

namespace ov {
namespace op {
namespace v16 {
/// \brief Identity operation is used as a placeholder op.
///
/// \ingroup ov_ops_cpp_api
class OPENVINO_API Identity : public Op {
public:
OPENVINO_OP("Identity", "opset16");
Identity() = default;
/**
* @brief Identity operation is used as a placeholder. It copies the tensor data to the output.
*/
Identity(const Output<Node>& data);

bool visit_attributes(AttributeVisitor& visitor) override;
void validate_and_infer_types() override;
std::shared_ptr<Node> clone_with_new_inputs(const OutputVector& new_args) const override;
};
} // namespace v16
} // namespace op
} // namespace ov
1 change: 1 addition & 0 deletions src/core/include/openvino/op/ops.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
#include "openvino/op/hswish.hpp"
#include "openvino/op/i420_to_bgr.hpp"
#include "openvino/op/i420_to_rgb.hpp"
#include "openvino/op/identity.hpp"
#include "openvino/op/idft.hpp"
#include "openvino/op/if.hpp"
#include "openvino/op/interpolate.hpp"
Expand Down
4 changes: 2 additions & 2 deletions src/core/include/openvino/opsets/opset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,12 @@ const OPENVINO_API OpSet& get_opset13();
*/
const OPENVINO_API OpSet& get_opset14();
/**
* @brief Returns map of available opsets
* @brief Returns opset15
* @ingroup ov_opset_cpp_api
*/
const OPENVINO_API OpSet& get_opset15();
/**
* @brief Returns map of available opsets
* @brief Returns opset16
* @ingroup ov_opset_cpp_api
*/
const OPENVINO_API OpSet& get_opset16();
Expand Down
1 change: 1 addition & 0 deletions src/core/include/openvino/opsets/opset16_tbl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ _OPENVINO_OP_REG(Convert, ov::op::v0)
_OPENVINO_OP_REG(ShapeOf, ov::op::v3)

// New operations added in opset16
_OPENVINO_OP_REG(Identity, ov::op::v16)
26 changes: 26 additions & 0 deletions src/core/reference/include/openvino/reference/identity.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (C) 2018-2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#pragma once

#include <cstring>

namespace ov {
namespace reference {
/**
* @brief Identity operation computes the identity of the input tensor.
*
* @param input Input matrix (matrices) pointer.
* @param output Output matrix (matrices) pointer.
* @param size_in_bytes Size of the input tensor in bytes.
**/
static inline void identity(const char* input, char* output, const size_t size_in_bytes) {
if (input == output) {
return;
} else {
std::memcpy(output, input, size_in_bytes);
}
}
} // namespace reference
} // namespace ov
44 changes: 44 additions & 0 deletions src/core/src/op/identity.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (C) 2018-2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include "openvino/op/identity.hpp"

#include <cstring>

#include "itt.hpp"
#include "openvino/core/attribute_visitor.hpp"
#include "openvino/core/validation_util.hpp"
#include "openvino/op/util/op_types.hpp"
#include "openvino/reference/identity.hpp"

namespace ov {
namespace op {
namespace v16 {

Identity::Identity(const Output<Node>& data) : Op({data}) {
constructor_validate_and_infer_types();
}

bool Identity::Identity::visit_attributes(AttributeVisitor& visitor) {
OV_OP_SCOPE(v16_Identity_visit_attributes);
return true;
}

void Identity::Identity::validate_and_infer_types() {
OV_OP_SCOPE(v16_Identity_validate_and_infer_types);

NODE_VALIDATION_CHECK(this, get_input_size() == 1);

set_output_type(0, get_input_element_type(0), get_input_partial_shape(0));
}

std::shared_ptr<Node> Identity::Identity::clone_with_new_inputs(const OutputVector& new_args) const {
OV_OP_SCOPE(v16_Identity_clone_with_new_inputs);
check_new_args_count(this, new_args);

return std::make_shared<Identity>(new_args.at(0));
}
} // namespace v16
} // namespace op
} // namespace ov
2 changes: 1 addition & 1 deletion src/core/tests/opset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ INSTANTIATE_TEST_SUITE_P(opset,
OpsetTestParams{ov::get_opset13, 186},
OpsetTestParams{ov::get_opset14, 188},
OpsetTestParams{ov::get_opset15, 199},
OpsetTestParams{ov::get_opset16, 3}),
OpsetTestParams{ov::get_opset16, 4}),
OpsetTestNameGenerator{});

class MyOpOld : public ov::op::Op {
Expand Down
42 changes: 42 additions & 0 deletions src/core/tests/type_prop/identity.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (C) 2018-2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include "openvino/op/identity.hpp"

#include <gtest/gtest.h>

#include "common_test_utils/test_assertions.hpp"
#include "common_test_utils/type_prop.hpp"
#include "openvino/op/constant.hpp"

using namespace testing;

namespace ov {
namespace test {

class TypePropIdentityV16Test : public TypePropOpTest<op::v16::Identity> {};

TEST_F(TypePropIdentityV16Test, default_ctor) {
const auto data = op::v0::Constant::create(element::f64, Shape{2, 2}, {1.0f, 1.0f, 1.0f, 1.0f});
const auto op = make_op();
op->set_arguments(OutputVector{data});
op->validate_and_infer_types();

EXPECT_EQ(op->get_input_size(), 1);
EXPECT_EQ(op->get_output_size(), 1);
EXPECT_EQ(op->get_output_element_type(0), element::f64);
EXPECT_EQ(op->get_output_partial_shape(0), PartialShape({2, 2}));
}

TEST_F(TypePropIdentityV16Test, input_data_ctor) {
const auto data = op::v0::Constant::create(element::i64, Shape{1, 2}, {1.0f, 1.0f});
const auto op = make_op(data);

EXPECT_EQ(op->get_input_size(), 1);
EXPECT_EQ(op->get_output_size(), 1);
EXPECT_EQ(op->get_output_element_type(0), element::i64);
EXPECT_EQ(op->get_output_partial_shape(0), PartialShape({1, 2}));
}
} // namespace test
} // namespace ov
11 changes: 11 additions & 0 deletions src/core/tests/visitors/op/identity.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (C) 2018-2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include "openvino/op/identity.hpp"

#include "unary_ops.hpp"

using Type = ::testing::Types<UnaryOperatorType<ov::op::v16::Identity, ov::element::f32>>;

INSTANTIATE_TYPED_TEST_SUITE_P(visitor_without_attribute, UnaryOperatorVisitor, Type, UnaryOperatorTypeName);
22 changes: 22 additions & 0 deletions src/plugins/template/backend/ops/identity.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (C) 2018-2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include "openvino/reference/identity.hpp"

#include "evaluate_node.hpp"
#include "openvino/core/type/element_iterator.hpp"

template <>
bool evaluate_node<ov::op::v16::Identity>(std::shared_ptr<ov::Node> node,
ov::TensorVector& outputs,
const ov::TensorVector& inputs) {
const auto input_shape = inputs[0].get_shape();

outputs[0].set_shape(input_shape);

ov::reference::identity(static_cast<const char*>(inputs[0].data()),
static_cast<char*>(outputs[0].data()),
inputs[0].get_byte_size());
return true;
}
4 changes: 4 additions & 0 deletions src/plugins/template/backend/ops/ops_evaluates.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,3 +550,7 @@ extern template bool evaluate_node<ov::op::v15::StringTensorPack>(std::shared_pt
extern template bool evaluate_node<ov::op::v15::SearchSorted>(std::shared_ptr<ov::Node> node,
ov::TensorVector& outputs,
const ov::TensorVector& inputs);

extern template bool evaluate_node<ov::op::v16::Identity>(std::shared_ptr<ov::Node> node,
ov::TensorVector& outputs,
const ov::TensorVector& inputs);
3 changes: 2 additions & 1 deletion src/plugins/template/backend/opset_int_tbl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,6 @@ _OPENVINO_OP_REG(AvgPool, ov::op::v14)
_OPENVINO_OP_REG(MaxPool, ov::op::v14)

_OPENVINO_OP_REG(ROIAlignRotated, ov::op::v15)

_OPENVINO_OP_REG(EmbeddingBagOffsets, op::v15)
_OPENVINO_OP_REG(EmbeddingBagPacked, op::v15)
_OPENVINO_OP_REG(Col2Im, ov::op::v15)
Expand All @@ -176,6 +175,8 @@ _OPENVINO_OP_REG(BitwiseRightShift, ov::op::v15)
_OPENVINO_OP_REG(SliceScatter, ov::op::v15)
_OPENVINO_OP_REG(SearchSorted, ov::op::v15)

_OPENVINO_OP_REG(Identity, ov::op::v16)

_OPENVINO_OP_REG(AUGRUCell, ov::op::internal)
_OPENVINO_OP_REG(AUGRUSequence, ov::op::internal)
_OPENVINO_OP_REG(RMS, ov::op::internal)
Expand Down
92 changes: 92 additions & 0 deletions src/plugins/template/tests/functional/op_reference/identity.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright (C) 2018-2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include "openvino/op/identity.hpp"

#include "base_reference_test.hpp"
#include "gtest/gtest.h"
#include "openvino/op/parameter.hpp"

namespace {
using IdentityParams = std::tuple<reference_tests::Tensor, std::string>;

class ReferenceIdentity : public testing::TestWithParam<IdentityParams>, public reference_tests::CommonReferenceTest {
public:
void SetUp() override {
const auto& params = GetParam();
const auto& matrices = std::get<0>(params);
function = CreateFunction(params);
inputData = {matrices.data};
refOutData = {matrices.data};
}

static std::string getTestCaseName(const testing::TestParamInfo<IdentityParams>& obj) {
std::ostringstream name;
const auto& matrices = std::get<0>(obj.param);
name << std::get<1>(obj.param);
name << "_input_type_";
name << matrices.type;
name << "_shape_";
name << matrices.shape;
return name.str();
}

private:
static std::shared_ptr<ov::Model> CreateFunction(const IdentityParams& params) {
const auto& matrices = std::get<0>(params);
const auto in_matrices = std::make_shared<ov::op::v0::Parameter>(matrices.type, matrices.shape);
const auto identity = std::make_shared<ov::op::v16::Identity>(in_matrices);
return std::make_shared<ov::Model>(identity->outputs(), ov::ParameterVector{in_matrices});
}
};

template <ov::element::Type_t ET>
std::vector<IdentityParams> generateIdentityParams() {
using VT = typename ov::element_type_traits<ET>::value_type;

const ov::Shape matrices_2_2_shape{2, 2};
const ov::Shape matrices_2_3_3_shape{2, 3, 3};

reference_tests::Tensor matrices_2_2(matrices_2_2_shape, ET, std::vector<VT>{1, 2, 4, 5});

reference_tests::Tensor matrices_2_3_3(matrices_2_3_3_shape,
ET,
std::vector<VT>{1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 8, 7, 4, 5, 3, 1, 2, 6});

std::vector<IdentityParams> params;
params.emplace_back(matrices_2_2, "single");
params.emplace_back(matrices_2_3_3, "many");

return params;
}

std::vector<IdentityParams> generateIdentityParams() {
std::vector<std::vector<IdentityParams>> combo_params{generateIdentityParams<ov::element::boolean>(),
generateIdentityParams<ov::element::bf16>(),
generateIdentityParams<ov::element::f16>(),
generateIdentityParams<ov::element::f64>(),
generateIdentityParams<ov::element::f32>(),
generateIdentityParams<ov::element::i8>(),
generateIdentityParams<ov::element::i16>(),
generateIdentityParams<ov::element::i32>(),
generateIdentityParams<ov::element::i64>(),
generateIdentityParams<ov::element::u8>(),
generateIdentityParams<ov::element::u16>(),
generateIdentityParams<ov::element::u32>(),
generateIdentityParams<ov::element::u64>()};
std::vector<IdentityParams> test_params;
for (auto& params : combo_params)
std::move(params.begin(), params.end(), std::back_inserter(test_params));
return test_params;
}
} // namespace

TEST_P(ReferenceIdentity, CompareWithRefs) {
Exec();
}

INSTANTIATE_TEST_SUITE_P(smoke,
ReferenceIdentity,
::testing::ValuesIn(generateIdentityParams()),
ReferenceIdentity::getTestCaseName);
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,13 @@ std::shared_ptr<ov::Model> generate(const std::shared_ptr<ov::op::v0::Interpolat
return std::make_shared<ov::Model>(results, params, "Interpolat-1");
}

std::shared_ptr<ov::Model> generate(const std::shared_ptr<ov::op::v16::Identity>& node) {
ov::ParameterVector params{std::make_shared<ov::op::v0::Parameter>(ov::element::f32, ov::Shape{4, 4, 4})};
const auto identity = std::make_shared<ov::op::v16::Identity>(params[0]);
ov::ResultVector results{std::make_shared<ov::op::v0::Result>(identity)};
return std::make_shared<ov::Model>(results, params, "Identity");
}

std::shared_ptr<ov::Model> generate(const std::shared_ptr<ov::op::v4::Interpolate> &node) {
using InterpolateAttrs = op::v4::Interpolate::InterpolateAttrs;
using InterpolateMode = op::v4::Interpolate::InterpolateMode;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (C) 2018-2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#pragma once

#include "shared_test_classes/single_op/identity.hpp"

namespace ov {
namespace test {
TEST_P(IdentityLayerTest, Inference) {
run();
};
} // namespace test
} // namespace ov

0 comments on commit 6aaddd5

Please sign in to comment.