From 519f13a177c76e5e01331b554b8aa8c0feb5f8f4 Mon Sep 17 00:00:00 2001 From: Pawel Raasz Date: Tue, 26 Sep 2023 14:45:19 +0200 Subject: [PATCH] [core]Api 2.0/migrate logical reduce ops to new API (#20043) * Migrate ReduceLogicalOr to new API * Migrate ReduceLogicalAnd to new API --- .../openvino/op/reduce_logical_and.hpp | 4 +- .../include/openvino/op/reduce_logical_or.hpp | 4 +- .../openvino/reference/logical_reduction.hpp | 46 ++++++---- .../reference/utils/coordinate_index.hpp | 11 +++ .../reference/src/utils/coordinate_index.cpp | 4 + src/core/src/op/reduce_logical_and.cpp | 89 ++++++++---------- src/core/src/op/reduce_logical_or.cpp | 91 ++++++++----------- 7 files changed, 122 insertions(+), 127 deletions(-) diff --git a/src/core/include/openvino/op/reduce_logical_and.hpp b/src/core/include/openvino/op/reduce_logical_and.hpp index 1358702a1fd..2fb2341a8c3 100644 --- a/src/core/include/openvino/op/reduce_logical_and.hpp +++ b/src/core/include/openvino/op/reduce_logical_and.hpp @@ -28,9 +28,7 @@ public: std::shared_ptr clone_with_new_inputs(const OutputVector& new_args) const override; - 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; }; } // namespace v1 diff --git a/src/core/include/openvino/op/reduce_logical_or.hpp b/src/core/include/openvino/op/reduce_logical_or.hpp index 36a3fd34759..6d61e2f0a8a 100644 --- a/src/core/include/openvino/op/reduce_logical_or.hpp +++ b/src/core/include/openvino/op/reduce_logical_or.hpp @@ -28,9 +28,7 @@ public: std::shared_ptr clone_with_new_inputs(const OutputVector& new_args) const override; - 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; }; } // namespace v1 diff --git a/src/core/reference/include/openvino/reference/logical_reduction.hpp b/src/core/reference/include/openvino/reference/logical_reduction.hpp index 7fd88db5eaa..97be74d1122 100644 --- a/src/core/reference/include/openvino/reference/logical_reduction.hpp +++ b/src/core/reference/include/openvino/reference/logical_reduction.hpp @@ -8,54 +8,66 @@ #include #include "ngraph/shape_util.hpp" +#include "openvino/core/shape_util.hpp" +#include "openvino/reference/utils/coordinate_index.hpp" #include "openvino/reference/utils/coordinate_transform.hpp" namespace ov { namespace reference { -OPENVINO_SUPPRESS_DEPRECATED_START + +/** + * @brief Reference implementation of ReduceLogicalAnd operator. + * + * @param in Input pointer to data. + * @param out Output pointer to results. + * @param in_shape Input shape. + * @param reduction_axes Axes on which reduction is applied. + */ static inline void reduce_logical_and(const char* arg, char* out, const Shape& in_shape, const AxisSet& reduction_axes) { - constexpr bool dont_keep_dims_in_output = false; - const auto out_shape = ngraph::reduce(in_shape, reduction_axes, dont_keep_dims_in_output); + const auto out_shape = ov::util::reduce(in_shape, reduction_axes); std::fill(out, out + shape_size(out_shape), 1); const auto in_strides = row_major_strides(in_shape); const auto out_strides = row_major_strides(out_shape); CoordinateTransformBasic input_transform(in_shape); - for (const Coordinate& input_coord : input_transform) { - const Coordinate output_coord = ngraph::reduce(input_coord, reduction_axes, dont_keep_dims_in_output); + for (const auto& in_coord : input_transform) { + const auto out_coord = ov::util::reduce(in_coord, reduction_axes); - const size_t in_idx = - std::inner_product(input_coord.begin(), input_coord.end(), in_strides.begin(), uint64_t(0)); - const size_t out_idx = - std::inner_product(output_coord.begin(), output_coord.end(), out_strides.begin(), uint64_t(0)); + const auto in_idx = ov::coordinate_offset(in_coord, in_strides); + const auto out_idx = ov::coordinate_offset(out_coord, out_strides); out[out_idx] = out[out_idx] && arg[in_idx]; } } +/** + * @brief Reference implementation of ReduceLogicalOr operator. + * + * @param in Input pointer to data. + * @param out Output pointer to results. + * @param in_shape Input shape. + * @param reduction_axes Axes on which reduction is applied. + */ static inline void reduce_logical_or(const char* arg, char* out, const Shape& in_shape, const AxisSet& reduction_axes) { - const auto out_shape = ngraph::reduce(in_shape, reduction_axes, false); + const auto out_shape = ov::util::reduce(in_shape, reduction_axes); std::fill(out, out + shape_size(out_shape), 0); const auto in_strides = row_major_strides(in_shape); const auto out_strides = row_major_strides(out_shape); CoordinateTransformBasic input_transform(in_shape); - for (const Coordinate& input_coord : input_transform) { - const Coordinate output_coord = ngraph::reduce(input_coord, reduction_axes, false); + for (const auto& in_coord : input_transform) { + const auto out_coord = ov::util::reduce(in_coord, reduction_axes); - const size_t in_idx = - std::inner_product(input_coord.begin(), input_coord.end(), in_strides.begin(), uint64_t(0)); - const size_t out_idx = - std::inner_product(output_coord.begin(), output_coord.end(), out_strides.begin(), uint64_t(0)); + const auto in_idx = ov::coordinate_offset(in_coord, in_strides); + const auto out_idx = ov::coordinate_offset(out_coord, out_strides); out[out_idx] = out[out_idx] || arg[in_idx]; } } -OPENVINO_SUPPRESS_DEPRECATED_END } // namespace reference } // namespace ov diff --git a/src/core/reference/include/openvino/reference/utils/coordinate_index.hpp b/src/core/reference/include/openvino/reference/utils/coordinate_index.hpp index 7408e548cdb..573fa708728 100644 --- a/src/core/reference/include/openvino/reference/utils/coordinate_index.hpp +++ b/src/core/reference/include/openvino/reference/utils/coordinate_index.hpp @@ -11,4 +11,15 @@ namespace ov { std::size_t coordinate_index(const Coordinate& c, const Shape& s); +/** + * @brief Calculate offset from begin of buffer based on coordinate and strides. + * + * If coordinates and strides have different sizes then result is undefined behaviour. + * + * @param coordinate Vector with multi-dimension coordinates. + * @param strides Vector with multi-dimension strides + * @return Offset of element from start of buffer. + */ +size_t coordinate_offset(const std::vector& coordinate, const std::vector& strides); + } // namespace ov diff --git a/src/core/reference/src/utils/coordinate_index.cpp b/src/core/reference/src/utils/coordinate_index.cpp index a8654d49169..72232d62e35 100644 --- a/src/core/reference/src/utils/coordinate_index.cpp +++ b/src/core/reference/src/utils/coordinate_index.cpp @@ -25,4 +25,8 @@ std::size_t coordinate_index(const Coordinate& c, const Shape& s) { return index; } + +size_t coordinate_offset(const std::vector& coordinate, const std::vector& strides) { + return std::inner_product(coordinate.cbegin(), coordinate.cend(), strides.cbegin(), static_cast(0)); +} } // namespace ov diff --git a/src/core/src/op/reduce_logical_and.cpp b/src/core/src/op/reduce_logical_and.cpp index 6ca1444fd90..adcfed43626 100644 --- a/src/core/src/op/reduce_logical_and.cpp +++ b/src/core/src/op/reduce_logical_and.cpp @@ -2,76 +2,61 @@ // SPDX-License-Identifier: Apache-2.0 // -#include "ngraph/op/reduce_logical_and.hpp" - -#include +#include "openvino/op/reduce_logical_and.hpp" +#include "element_visitor.hpp" #include "itt.hpp" -#include "ngraph/log.hpp" -#include "ngraph/op/util/evaluate_helpers.hpp" -#include "ngraph/runtime/host_tensor.hpp" +#include "openvino/core/shape_util.hpp" +#include "openvino/op/util/axes_util.hpp" #include "openvino/reference/logical_reduction.hpp" -#include "openvino/util/log.hpp" -using namespace ngraph; -using namespace std; +namespace ov { +namespace op { +namespace reduce_and { +struct Evaluate : element::NoAction { + using element::NoAction::visit; -op::v1::ReduceLogicalAnd::ReduceLogicalAnd(const Output& data, - const Output& reduction_axes, - const bool keep_dims) + template + static result_type visit(const Tensor& in, Tensor& out, const AxisSet& reduction_axes) { + using T = fundamental_type_for; + reference::reduce_logical_and(in.data(), out.data(), in.get_shape(), reduction_axes); + return true; + } +}; +} // namespace reduce_and + +namespace v1 { +ReduceLogicalAnd::ReduceLogicalAnd(const Output& data, const Output& reduction_axes, const bool keep_dims) : LogicalReductionKeepDims(data, reduction_axes, keep_dims) { constructor_validate_and_infer_types(); } -shared_ptr op::v1::ReduceLogicalAnd::clone_with_new_inputs(const OutputVector& new_args) const { +std::shared_ptr ReduceLogicalAnd::clone_with_new_inputs(const OutputVector& new_args) const { OV_OP_SCOPE(v1_ReduceLogicalAnd_clone_with_new_inputs); check_new_args_count(this, new_args); - return make_shared(new_args.at(0), new_args.at(1), get_keep_dims()); + return std::make_shared(new_args.at(0), new_args.at(1), get_keep_dims()); } -OPENVINO_SUPPRESS_DEPRECATED_START -namespace reduce_and { -namespace { -bool evaluate_reduce_logical_and(const HostTensorPtr& data, - const HostTensorPtr& out, - const AxisSet& reduction_axes, - bool keep_dims) { - OPENVINO_SUPPRESS_DEPRECATED_START - out->set_shape(reduce(data->get_shape(), reduction_axes, keep_dims)); - try { - ov::reference::reduce_logical_and(data->get_data_ptr(), - out->get_data_ptr(), - data->get_shape(), - reduction_axes); - return true; - } catch (const ngraph_error& e) { - OPENVINO_WARN << e.what(); - return false; - } - OPENVINO_SUPPRESS_DEPRECATED_END -} -} // namespace -} // namespace reduce_and - -bool op::v1::ReduceLogicalAnd::evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs) const { +bool ReduceLogicalAnd::evaluate(TensorVector& outputs, const TensorVector& inputs) const { OV_OP_SCOPE(v1_ReduceLogicalAnd_evaluate); OPENVINO_SUPPRESS_DEPRECATED_START - OPENVINO_ASSERT(validate_host_tensor_vector(inputs, 2)); - OPENVINO_ASSERT(validate_host_tensor_vector(outputs, 1)); + OPENVINO_ASSERT(inputs.size() == 2); + OPENVINO_ASSERT(outputs.size() == 1); - const auto& data = inputs[0]; - const auto& axes = inputs[1]; - const auto& out = outputs[0]; - if (data->get_element_type() != element::boolean || !axes->get_element_type().is_integral_number()) { - return false; - } - const auto reduction_axes = - get_normalized_axes_from_tensor(axes, data->get_partial_shape().rank(), get_friendly_name()); - OPENVINO_SUPPRESS_DEPRECATED_END - return reduce_and::evaluate_reduce_logical_and(data, out, reduction_axes, get_keep_dims()); + const auto reduction_axes = get_normalized_axes_from_tensor(this, inputs[1], inputs[0].get_shape().size()); + outputs[0].set_shape(ov::util::reduce(inputs[0].get_shape(), reduction_axes, get_keep_dims())); + + using namespace ov::element; + return IfTypeOf::apply(inputs[0].get_element_type(), + inputs[0], + outputs[0], + reduction_axes); } -bool op::v1::ReduceLogicalAnd::has_evaluate() const { +bool ReduceLogicalAnd::has_evaluate() const { OV_OP_SCOPE(v1_ReduceLogicalAnd_has_evaluate); return get_input_element_type(0) == element::boolean && get_input_element_type(1).is_integral_number(); } +} // namespace v1 +} // namespace op +} // namespace ov diff --git a/src/core/src/op/reduce_logical_or.cpp b/src/core/src/op/reduce_logical_or.cpp index dce03e81e40..a2e84d420e6 100644 --- a/src/core/src/op/reduce_logical_or.cpp +++ b/src/core/src/op/reduce_logical_or.cpp @@ -2,76 +2,63 @@ // SPDX-License-Identifier: Apache-2.0 // -#include "ngraph/op/reduce_logical_or.hpp" - -#include +#include "openvino/op/reduce_logical_or.hpp" +#include "element_visitor.hpp" #include "itt.hpp" -#include "ngraph/log.hpp" -#include "ngraph/op/util/evaluate_helpers.hpp" -#include "ngraph/runtime/host_tensor.hpp" +#include "openvino/core/shape_util.hpp" +#include "openvino/op/util/axes_util.hpp" #include "openvino/reference/logical_reduction.hpp" #include "openvino/util/log.hpp" -using namespace ngraph; -using namespace std; +namespace ov { +namespace op { +namespace reduce_or { +struct Evaluate : element::NoAction { + using element::NoAction::visit; -op::v1::ReduceLogicalOr::ReduceLogicalOr(const Output& data, - const Output& reduction_axes, - const bool keep_dims) + template + static result_type visit(const Tensor& in, Tensor& out, const AxisSet& reduction_axes) { + using T = fundamental_type_for; + reference::reduce_logical_or(in.data(), out.data(), in.get_shape(), reduction_axes); + return true; + } +}; +} // namespace reduce_or + +namespace v1 { +ReduceLogicalOr::ReduceLogicalOr(const Output& data, const Output& reduction_axes, const bool keep_dims) : LogicalReductionKeepDims(data, reduction_axes, keep_dims) { constructor_validate_and_infer_types(); } -shared_ptr op::v1::ReduceLogicalOr::clone_with_new_inputs(const OutputVector& new_args) const { +std::shared_ptr ReduceLogicalOr::clone_with_new_inputs(const OutputVector& new_args) const { OV_OP_SCOPE(v1_ReduceLogicalOr_clone_with_new_inputs); check_new_args_count(this, new_args); - return make_shared(new_args.at(0), new_args.at(1), get_keep_dims()); + return std::make_shared(new_args.at(0), new_args.at(1), get_keep_dims()); } -OPENVINO_SUPPRESS_DEPRECATED_START -namespace reduce_or { -namespace { -bool evaluate_reduce_logical_or(const HostTensorPtr& data, - const HostTensorPtr& out, - const AxisSet& reduction_axes, - bool keep_dims) { - OPENVINO_SUPPRESS_DEPRECATED_START - out->set_shape(reduce(data->get_shape(), reduction_axes, keep_dims)); - try { - ov::reference::reduce_logical_or(data->get_data_ptr(), - out->get_data_ptr(), - data->get_shape(), - reduction_axes); - return true; - } catch (const ngraph_error& e) { - OPENVINO_WARN << e.what(); - return false; - } - OPENVINO_SUPPRESS_DEPRECATED_END -} -} // namespace -} // namespace reduce_or - -bool op::v1::ReduceLogicalOr::evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs) const { +bool ReduceLogicalOr::evaluate(TensorVector& outputs, const TensorVector& inputs) const { OV_OP_SCOPE(v1_ReduceLogicalOr_evaluate); - OPENVINO_SUPPRESS_DEPRECATED_START - OPENVINO_ASSERT(validate_host_tensor_vector(inputs, 2)); - OPENVINO_ASSERT(validate_host_tensor_vector(outputs, 1)); - const auto& data = inputs[0]; - const auto& axes = inputs[1]; - const auto& out = outputs[0]; - if (data->get_element_type() != element::boolean || !axes->get_element_type().is_integral_number()) { - return false; - } - const auto reduction_axes = - get_normalized_axes_from_tensor(axes, data->get_partial_shape().rank(), get_friendly_name()); - OPENVINO_SUPPRESS_DEPRECATED_END - return reduce_or::evaluate_reduce_logical_or(data, out, reduction_axes, get_keep_dims()); + OPENVINO_ASSERT(inputs.size() == 2); + OPENVINO_ASSERT(outputs.size() == 1); + + const auto reduction_axes = get_normalized_axes_from_tensor(this, inputs[1], inputs[0].get_shape().size()); + outputs[0].set_shape(ov::util::reduce(inputs[0].get_shape(), reduction_axes, get_keep_dims())); + + using namespace ov::element; + return IfTypeOf::apply(inputs[0].get_element_type(), + inputs[0], + outputs[0], + reduction_axes); } -bool op::v1::ReduceLogicalOr::has_evaluate() const { +bool ReduceLogicalOr::has_evaluate() const { OV_OP_SCOPE(v1_ReduceLogicalOr_has_evaluate); return get_input_element_type(0) == element::boolean && get_input_element_type(1).is_integral_number(); } + +} // namespace v1 +} // namespace op +} // namespace ov