From 9ccbb264f7c8f294990d29567dca6f7a02d1bc94 Mon Sep 17 00:00:00 2001 From: Pawel Raasz Date: Wed, 11 Oct 2023 11:50:29 +0200 Subject: [PATCH] [core]Migrate Eye to new API (#20258) * Migrate Eye to new API * Fix `matrix_offset` initialization * get_tensors_shapes -> get_tensors_partial_shapes --- src/core/include/openvino/op/eye.hpp | 4 +- .../openvino/op/util/evaluate_helpers.hpp | 23 +++ .../include/openvino/reference/eye.hpp | 32 ++-- src/core/src/op/eye.cpp | 152 ++++++++---------- src/core/src/op/util/evaluate_helpers.cpp | 17 ++ 5 files changed, 127 insertions(+), 101 deletions(-) create mode 100644 src/core/include/openvino/op/util/evaluate_helpers.hpp diff --git a/src/core/include/openvino/op/eye.hpp b/src/core/include/openvino/op/eye.hpp index feaebafca82264..1096e488aa13eb 100644 --- a/src/core/include/openvino/op/eye.hpp +++ b/src/core/include/openvino/op/eye.hpp @@ -55,9 +55,7 @@ class OPENVINO_API Eye : public Op { m_output_type = output_type; } - OPENVINO_SUPPRESS_DEPRECATED_START - bool evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs) const override; - OPENVINO_SUPPRESS_DEPRECATED_END + bool evaluate(TensorVector& outputs, const TensorVector& inputs) const override; bool has_evaluate() const override; protected: diff --git a/src/core/include/openvino/op/util/evaluate_helpers.hpp b/src/core/include/openvino/op/util/evaluate_helpers.hpp new file mode 100644 index 00000000000000..616528adf60d08 --- /dev/null +++ b/src/core/include/openvino/op/util/evaluate_helpers.hpp @@ -0,0 +1,23 @@ +// Copyright (C) 2018-2023 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 +// + +#pragma once + +#include "openvino/core/partial_shape.hpp" +#include "openvino/runtime/tensor.hpp" + +namespace ov { +namespace op { +namespace util { + +/** + * @brief Get the tensors shapes as ov::PartialShape. + * + * @param tensors Input tensors vector to get its shapes. + * @return Vector of partial shapes sam size as input tensor vector. + */ +std::vector get_tensors_partial_shapes(const TensorVector& tensors); +} // namespace util +} // namespace op +} // namespace ov diff --git a/src/core/reference/include/openvino/reference/eye.hpp b/src/core/reference/include/openvino/reference/eye.hpp index 0991637031538f..2cb997c03f0817 100644 --- a/src/core/reference/include/openvino/reference/eye.hpp +++ b/src/core/reference/include/openvino/reference/eye.hpp @@ -7,31 +7,41 @@ #include #include "openvino/core/shape.hpp" -#include "utils/span.hpp" namespace ov { namespace reference { + +/** + * @brief Reference implementation of Eye operator + * + * @param data Pointer to output data. + * @param out_shape Output data size. + * @param diagonal_index Eye diagonal index to populate matrix with ones + */ template void eye(T* data, const Shape& out_shape, const int64_t diagonal_index) { - const int64_t num_matrices = shape_size(span(out_shape).subspan(0, out_shape.size() - 2)); - const int64_t num_rows = out_shape[out_shape.size() - 2]; - const int64_t num_columns = out_shape[out_shape.size() - 1]; + const auto spatial_dims_offset = out_shape.size() - 2; + const int64_t num_columns = out_shape.back(); + const int64_t num_rows = out_shape[spatial_dims_offset]; const int64_t matrix_size = num_rows * num_columns; + const int64_t out_size = shape_size(out_shape); // fill tensor by zero - std::fill(data, data + num_matrices * matrix_size, T(0)); + std::fill(data, std::next(data, out_size), T(0)); // set ones on diagonal - const int64_t shift_by_columns = std::max(diagonal_index, int64_t(0)); - const int64_t count_by_columns = std::max(num_columns - std::abs(diagonal_index), int64_t(0)); - const int64_t count_by_rows = std::max(num_rows - std::abs(diagonal_index), int64_t(0)); + constexpr int64_t zero{0}; + const auto abs_diag_idx = static_cast(std::abs(diagonal_index)); + const int64_t shift_by_columns = std::max(diagonal_index, zero); + const int64_t count_by_columns = std::max(num_columns - abs_diag_idx, zero); + const int64_t count_by_rows = std::max(num_rows - abs_diag_idx, zero); const int64_t count = diagonal_index > 0 ? std::min(count_by_columns, num_rows) : std::min(count_by_rows, num_columns); - for (auto i = 0; i < num_matrices; i++) { - for (auto j = 0; j < count; j++) { + for (auto matrix_offset = zero; matrix_offset < out_size; matrix_offset += matrix_size) { + for (auto j = 0; j < count; ++j) { const int64_t index = (j + shift_by_columns - diagonal_index) * num_columns + j + shift_by_columns; - data[index + i * matrix_size] = static_cast(1); + data[matrix_offset + index] = T{1}; } } } diff --git a/src/core/src/op/eye.cpp b/src/core/src/op/eye.cpp index 77e4082792e2f6..edf9abbb06f4c4 100644 --- a/src/core/src/op/eye.cpp +++ b/src/core/src/op/eye.cpp @@ -4,62 +4,49 @@ #include "openvino/op/eye.hpp" +#include "element_visitor.hpp" #include "eye_shape_inference.hpp" #include "itt.hpp" -#include "ngraph/validation_util.hpp" +#include "openvino/core/validation_util.hpp" +#include "openvino/op/util/evaluate_helpers.hpp" #include "openvino/reference/eye.hpp" -OPENVINO_SUPPRESS_DEPRECATED_START namespace ov { namespace op { namespace eye { -namespace { -template -bool evaluate(const ngraph::HostTensorPtr& out, const int64_t diagonal_index) { - ov::reference::eye(out->get_data_ptr(), out->get_shape(), diagonal_index); - return true; -} -bool evaluate_eye(const ngraph::HostTensorPtr& out, const int64_t diagonal_index) { - bool rc = true; - switch (out->get_element_type()) { - OPENVINO_TYPE_CASE(evaluate, i8, out, diagonal_index); - OPENVINO_TYPE_CASE(evaluate, u8, out, diagonal_index); - OPENVINO_TYPE_CASE(evaluate, f16, out, diagonal_index); - OPENVINO_TYPE_CASE(evaluate, bf16, out, diagonal_index); - OPENVINO_TYPE_CASE(evaluate, i32, out, diagonal_index); - OPENVINO_TYPE_CASE(evaluate, f32, out, diagonal_index); - OPENVINO_TYPE_CASE(evaluate, f64, out, diagonal_index); - OPENVINO_TYPE_CASE(evaluate, i64, out, diagonal_index); - default: - rc = false; - break; +struct Evaluate : element::NoAction { + using element::NoAction::visit; + + template > + static result_type visit(Tensor& out, const Shape& out_shape, const int64_t diagonal_idx) { + reference::eye(out.data(), out_shape, diagonal_idx); + return true; } - return rc; -} -} // namespace +}; } // namespace eye -ov::op::v9::Eye::Eye(const Output& num_rows, - const Output& num_columns, - const Output& diagonal_index, - const Output& batch_shape, - const ov::element::Type& out_type) +namespace v9 { +Eye::Eye(const Output& num_rows, + const Output& num_columns, + const Output& diagonal_index, + const Output& batch_shape, + const ov::element::Type& out_type) : Op({num_rows, num_columns, diagonal_index, batch_shape}), m_output_type(out_type) { constructor_validate_and_infer_types(); } -ov::op::v9::Eye::Eye(const Output& num_rows, - const Output& num_columns, - const Output& diagonal_index, - const ov::element::Type& out_type) +Eye::Eye(const Output& num_rows, + const Output& num_columns, + const Output& diagonal_index, + const ov::element::Type& out_type) : Op({num_rows, num_columns, diagonal_index}), m_output_type(out_type) { constructor_validate_and_infer_types(); } -void ov::op::v9::Eye::validate_and_infer_types() { +void Eye::validate_and_infer_types() { OV_OP_SCOPE(v9_Eye_validate_and_infer_types); for (size_t i = 0; i < get_input_size(); ++i) { @@ -78,81 +65,72 @@ void ov::op::v9::Eye::validate_and_infer_types() { set_output_type(0, get_out_type(), output_shape); } -bool ov::op::v9::Eye::visit_attributes(ov::AttributeVisitor& visitor) { +bool Eye::visit_attributes(ov::AttributeVisitor& visitor) { OV_OP_SCOPE(v9_Eye_visit_attributes); visitor.on_attribute("output_type", m_output_type); return true; } -std::shared_ptr ov::op::v9::Eye::clone_with_new_inputs(const ov::OutputVector& new_args) const { +std::shared_ptr Eye::clone_with_new_inputs(const ov::OutputVector& new_args) const { OV_OP_SCOPE(v9_Eye_clone_with_new_inputs); check_new_args_count(this, new_args); - if (new_args.size() == 3) { - return std::make_shared(new_args[0], new_args[1], new_args[2], m_output_type); - } else if (new_args.size() == 4) { - return std::make_shared(new_args[0], new_args[1], new_args[2], new_args[3], m_output_type); - } else { + + switch (new_args.size()) { + case 3: + return std::make_shared(new_args[0], new_args[1], new_args[2], m_output_type); + case 4: + return std::make_shared(new_args[0], new_args[1], new_args[2], new_args[3], m_output_type); + default: OPENVINO_THROW("Eye has incorrect input number: ", new_args.size()); } } -bool ov::op::v9::Eye::has_evaluate() const { +bool Eye::has_evaluate() const { OV_OP_SCOPE(v9_Eye_has_evaluate); switch (m_output_type) { - case ov::element::i8: - case ov::element::u8: - case ov::element::f16: - case ov::element::bf16: - case ov::element::i32: - case ov::element::f32: - case ov::element::i64: + case element::bf16: + case element::f16: + case element::f32: + case element::f64: + case element::i8: + case element::i32: + case element::i64: + case element::u8: return true; default: - break; + return false; } - return false; } -bool ov::op::v9::Eye::evaluate(const ngraph::HostTensorVector& outputs, const ngraph::HostTensorVector& inputs) const { +bool Eye::evaluate(TensorVector& outputs, const TensorVector& inputs) const { OV_OP_SCOPE(v9_Eye_evaluate); - OPENVINO_SUPPRESS_DEPRECATED_START - OPENVINO_ASSERT(ngraph::validate_host_tensor_vector(inputs, get_input_size()), "Invalid Eye input TensorVector."); - OPENVINO_ASSERT(ngraph::validate_host_tensor_vector(outputs, 1), "Invalid Eye output TensorVector."); - OPENVINO_SUPPRESS_DEPRECATED_END - - int64_t diagonal_index; - - if (get_input_size() > 1) { - const auto& diagonal_index_data = inputs[2]; - - switch (diagonal_index_data->get_element_type()) { - case element::i32: - diagonal_index = diagonal_index_data->get_data_ptr()[0]; - break; - case element::i64: - diagonal_index = diagonal_index_data->get_data_ptr()[0]; - break; - default: - OPENVINO_THROW("Unsupported type of input `diagonal_index` in Eye operation: ", - diagonal_index_data->get_element_type().to_string()); - } - } else { - diagonal_index = 0; - } - - std::vector input_shapes; - input_shapes.reserve(inputs.size()); - - for (size_t i = 0; i < inputs.size(); ++i) { - input_shapes.push_back(inputs[i]->get_partial_shape()); - } + OPENVINO_ASSERT(outputs.size() == 1); + // Inputs size and shapes checked by shape_infer + const auto input_shapes = util::get_tensors_partial_shapes(inputs); const auto output_shape = shape_infer(this, input_shapes, make_tensor_accessor(inputs)).front().to_shape(); - outputs[0]->set_element_type(get_out_type()); - outputs[0]->set_shape(output_shape); + int64_t diagonal_index; + const auto& diagonal_tensor = inputs[2]; + switch (diagonal_tensor.get_element_type()) { + case element::i32: + diagonal_index = diagonal_tensor.data>()[0]; + break; + case element::i64: + diagonal_index = diagonal_tensor.data>()[0]; + break; + default: + OPENVINO_THROW("Unsupported type of input `diagonal_index` in Eye operation: ", + diagonal_tensor.get_element_type().to_string()); + } - return eye::evaluate_eye(outputs[0], diagonal_index); + outputs[0].set_shape(output_shape); + using namespace ov::element; + return IfTypeOf::apply(outputs[0].get_element_type(), + outputs[0], + output_shape, + diagonal_index); } +} // namespace v9 } // namespace op } // namespace ov diff --git a/src/core/src/op/util/evaluate_helpers.cpp b/src/core/src/op/util/evaluate_helpers.cpp index cffc57e6fbd87c..4e21da40bfe013 100644 --- a/src/core/src/op/util/evaluate_helpers.cpp +++ b/src/core/src/op/util/evaluate_helpers.cpp @@ -4,6 +4,8 @@ #include "ngraph/op/util/evaluate_helpers.hpp" +#include "openvino/op/util/evaluate_helpers.hpp" + namespace ngraph { AxisSet get_normalized_axes_from_tensor(const HostTensorPtr tensor, const ngraph::Rank& rank, @@ -15,3 +17,18 @@ AxisSet get_normalized_axes_from_tensor(const HostTensorPtr tensor, return AxisSet{normalized_axes}; } } // namespace ngraph + +namespace ov { +namespace op { +namespace util { +std::vector get_tensors_partial_shapes(const TensorVector& tensors) { + std::vector shapes; + shapes.reserve(tensors.size()); + for (const auto& t : tensors) { + shapes.emplace_back(t.get_shape()); + } + return shapes; +} +} // namespace util +} // namespace op +} // namespace ov