diff --git a/src/core/include/openvino/op/variadic_split.hpp b/src/core/include/openvino/op/variadic_split.hpp index 2d6f751d48d3ba..49cb5dcc714502 100644 --- a/src/core/include/openvino/op/variadic_split.hpp +++ b/src/core/include/openvino/op/variadic_split.hpp @@ -29,25 +29,17 @@ class OPENVINO_API VariadicSplit : public Op { /// outputs. The sum of split_lengths must match data.shape[axis] VariadicSplit(const Output& data, const Output& axis, const Output& split_lengths); - bool visit_attributes(AttributeVisitor& visitor) override; - void validate_and_infer_types() override; std::shared_ptr clone_with_new_inputs(const OutputVector& new_args) const override; size_t get_default_output_index() const override { return no_default_index(); } - 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 evaluate_lower(TensorVector& outputs) const override; bool evaluate_upper(TensorVector& outputs) const override; bool has_evaluate() const override; bool evaluate_label(TensorLabelVector& output_labels) const override; - -private: - bool evaluate_variadic_split(const HostTensorVector& outputs, const HostTensorVector& inputs) const; - bool has_axis_and_splits_bound_set() const; }; } // namespace v1 } // namespace op diff --git a/src/core/src/op/variadic_split.cpp b/src/core/src/op/variadic_split.cpp index ab94af3fd8345f..38b309325fe16a 100644 --- a/src/core/src/op/variadic_split.cpp +++ b/src/core/src/op/variadic_split.cpp @@ -2,33 +2,69 @@ // SPDX-License-Identifier: Apache-2.0 // -#include "ngraph/op/variadic_split.hpp" +#include "openvino/op/variadic_split.hpp" #include #include "bound_evaluate.hpp" #include "compare.hpp" #include "itt.hpp" -#include "ngraph/validation_util.hpp" +#include "openvino/core/validation_util.hpp" #include "openvino/reference/slice.hpp" #include "variadic_split_shape_inference.hpp" -using namespace std; -using namespace ngraph; +namespace ov { +namespace op { +namespace variadic_split { +namespace { -op::v1::VariadicSplit::VariadicSplit(const Output& data, - const Output& axis, - const Output& split_lengths) - : Op({data, axis, split_lengths}) { - constructor_validate_and_infer_types(); +bool has_axis_and_splits_bound_set(const Node* const node) { + return have_node_inputs_bounds_set(node, 1, 2); } -bool ngraph::op::v1::VariadicSplit::visit_attributes(AttributeVisitor& visitor) { - OV_OP_SCOPE(v1_VariadicSplit_visit_attributes); +bool evaluate(TensorVector& outputs, const TensorVector& inputs) { + const auto& data_tensor = inputs[0]; + const auto& axis_tensor = inputs[1]; + const auto axis = + ov::util::normalize(get_tensor_data_as(axis_tensor).front(), data_tensor.get_shape().size()); + + ov::Coordinate upper_bounds(data_tensor.get_shape()); + ov::Coordinate lower_bounds(upper_bounds.size()); + upper_bounds[axis] = 0; + + const Strides default_strides(upper_bounds.size(), 1); + constexpr auto is_zero_dim = ov::cmp::Equal(0); + + for (auto& output : outputs) { + const auto& out_shape = output.get_shape(); + upper_bounds[axis] += out_shape[axis]; + + if (std::none_of(out_shape.cbegin(), out_shape.cend(), is_zero_dim)) { + reference::slice(static_cast(data_tensor.data()), + static_cast(output.data()), + data_tensor.get_shape(), + lower_bounds, + upper_bounds, + default_strides, + out_shape, + data_tensor.get_element_type().size()); + } + + lower_bounds[axis] = upper_bounds[axis]; + } + return true; } +} // namespace +} // namespace variadic_split -void ngraph::op::v1::VariadicSplit::validate_and_infer_types() { +namespace v1 { +VariadicSplit::VariadicSplit(const Output& data, const Output& axis, const Output& split_lengths) + : Op({data, axis, split_lengths}) { + constructor_validate_and_infer_types(); +} + +void VariadicSplit::validate_and_infer_types() { OV_OP_SCOPE(v1_VariadicSplit_validate_and_infer_types); for (size_t i = 0; i < get_input_size(); ++i) { set_input_is_relevant_to_value(i); @@ -45,107 +81,52 @@ void ngraph::op::v1::VariadicSplit::validate_and_infer_types() { } } -shared_ptr op::v1::VariadicSplit::clone_with_new_inputs(const OutputVector& new_args) const { +std::shared_ptr VariadicSplit::clone_with_new_inputs(const OutputVector& new_args) const { OV_OP_SCOPE(v1_VariadicSplit_clone_with_new_inputs); check_new_args_count(this, new_args); - return make_shared(new_args.at(0), new_args.at(1), new_args.at(2)); + return std::make_shared(new_args.at(0), new_args.at(1), new_args.at(2)); } -OPENVINO_SUPPRESS_DEPRECATED_START -namespace variadic_split { -namespace { -inline bool evaluate(const HostTensorPtr& in, - const HostTensorPtr& out, - const Coordinate& lower_bounds, - const Coordinate& upper_bounds) { - const auto& output_shape = out->get_shape(); - const auto has_nonzero_dims = std::none_of(output_shape.begin(), output_shape.end(), ov::cmp::Equal(0)); - - if (has_nonzero_dims) { - ov::reference::slice(in->get_data_ptr(), - out->get_data_ptr(), - in->get_shape(), - lower_bounds, - upper_bounds, - Strides(lower_bounds.size(), 1), - out->get_shape(), - in->get_element_type().size()); - return true; - } - return false; -} -} // namespace -} // namespace variadic_split - -bool op::v1::VariadicSplit::evaluate_variadic_split(const HostTensorVector& inputs, - const HostTensorVector& outputs) const { - const auto& data_tensor = inputs[0]; - const auto& axis_tensor = inputs[1]; - const auto& split_lengths_tensor = inputs[2]; - OPENVINO_ASSERT(axis_tensor->get_element_type().is_integral_number(), - "axis element type is not integral data type"); - OPENVINO_ASSERT(split_lengths_tensor->get_element_type().is_integral_number(), - "split_lengths element type is not integral data type"); - - OPENVINO_SUPPRESS_DEPRECATED_START - int64_t axis = host_tensor_2_vector(axis_tensor)[0]; - axis = ngraph::normalize_axis(this, axis, data_tensor->get_partial_shape().rank()); - OPENVINO_SUPPRESS_DEPRECATED_END +bool VariadicSplit::evaluate(TensorVector& outputs, const TensorVector& inputs) const { + OV_OP_SCOPE(v1_VariadicSplit_evaluate); - std::vector input_shapes = {data_tensor->get_partial_shape(), - axis_tensor->get_partial_shape(), - split_lengths_tensor->get_partial_shape()}; - auto output_shapes = shape_infer(this, input_shapes, make_tensor_accessor(inputs)); + if (inputs[1].get_element_type().is_integral_number() && inputs[2].get_element_type().is_integral_number()) { + const auto output_shapes = + shape_infer(this, ov::util::get_tensors_partial_shapes(inputs), make_tensor_accessor(inputs)); + OPENVINO_ASSERT(outputs.size() == output_shapes.size()); - const auto data_shape = data_tensor->get_shape(); - std::vector lower_bounds(data_shape.size(), 0); - std::vector upper_bounds = data_shape; - upper_bounds[axis] = 0; + auto out_partial_shape = output_shapes.cbegin(); + for (auto& output : outputs) { + output.set_shape(out_partial_shape->to_shape()); + ++out_partial_shape; + } - size_t split_pos = 0; - for (const auto& output : outputs) { - ov::Shape output_shape = output_shapes[split_pos++].get_shape(); - upper_bounds[axis] += output_shape[axis]; - output->set_shape(output_shape); - variadic_split::evaluate(data_tensor, output, lower_bounds, upper_bounds); - lower_bounds.at(axis) = upper_bounds.at(axis); + return variadic_split::evaluate(outputs, inputs); + } else { + return false; } - - return true; -} -bool op::v1::VariadicSplit::evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs) const { - OV_OP_SCOPE(v1_VariadicSplit_evaluate); - return evaluate_variadic_split(inputs, outputs); } -bool op::v1::VariadicSplit::has_evaluate() const { +bool VariadicSplit::has_evaluate() const { OV_OP_SCOPE(v1_VariadicSplit_has_evaluate); return get_input_element_type(1).is_integral_number() && get_input_element_type(2).is_integral_number(); } -bool op::v1::VariadicSplit::has_axis_and_splits_bound_set() const { - for (size_t i = 1; i < get_input_size(); ++i) { - if (!get_input_tensor(i).has_and_set_bound()) { - return false; - } - } - return true; -} - -bool op::v1::VariadicSplit::evaluate_lower(ov::TensorVector& output_values) const { +bool VariadicSplit::evaluate_lower(TensorVector& output_values) const { OV_OP_SCOPE(v1_Split_evaluate_lower); - - return has_axis_and_splits_bound_set() && default_lower_bound_evaluator(this, output_values); + return variadic_split::has_axis_and_splits_bound_set(this) && default_lower_bound_evaluator(this, output_values); } -bool op::v1::VariadicSplit::evaluate_upper(ov::TensorVector& output_values) const { +bool VariadicSplit::evaluate_upper(TensorVector& output_values) const { OV_OP_SCOPE(v1_Split_evaluate_upper); - - return has_axis_and_splits_bound_set() && default_upper_bound_evaluator(this, output_values); + return variadic_split::has_axis_and_splits_bound_set(this) && default_upper_bound_evaluator(this, output_values); } -bool op::v1::VariadicSplit::evaluate_label(TensorLabelVector& output_labels) const { +bool VariadicSplit::evaluate_label(TensorLabelVector& output_labels) const { OPENVINO_SUPPRESS_DEPRECATED_START - return has_axis_and_splits_bound_set() && default_label_evaluator(this, output_labels); + return variadic_split::has_axis_and_splits_bound_set(this) && default_label_evaluator(this, output_labels); OPENVINO_SUPPRESS_DEPRECATED_END } +} // namespace v1 +} // namespace op +} // namespace ov