[core]Migrate VariadicSplit op to new API (#20416)
* Migrate VariadicSlice to new API - refactor to reduce bin size * Move `get_tensors_partial_shapes` to dev API * Use get_tensors_partial_shapes in VariadicSplit * Remove `visit_attributes` is same as base
This commit is contained in:
@@ -29,25 +29,17 @@ public:
|
||||
/// outputs. The sum of split_lengths must match data.shape[axis]
|
||||
VariadicSplit(const Output<Node>& data, const Output<Node>& axis, const Output<Node>& split_lengths);
|
||||
|
||||
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;
|
||||
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
|
||||
|
||||
@@ -2,33 +2,69 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "ngraph/op/variadic_split.hpp"
|
||||
#include "openvino/op/variadic_split.hpp"
|
||||
|
||||
#include <numeric>
|
||||
|
||||
#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<Node>& data,
|
||||
const Output<Node>& axis,
|
||||
const Output<Node>& split_lengths)
|
||||
bool has_axis_and_splits_bound_set(const Node* const node) {
|
||||
return have_node_inputs_bounds_set(node, 1, 2);
|
||||
}
|
||||
|
||||
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<int64_t>(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<size_t>(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<const char*>(data_tensor.data()),
|
||||
static_cast<char*>(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
|
||||
|
||||
namespace v1 {
|
||||
VariadicSplit::VariadicSplit(const Output<Node>& data, const Output<Node>& axis, const Output<Node>& split_lengths)
|
||||
: Op({data, axis, split_lengths}) {
|
||||
constructor_validate_and_infer_types();
|
||||
}
|
||||
|
||||
bool ngraph::op::v1::VariadicSplit::visit_attributes(AttributeVisitor& visitor) {
|
||||
OV_OP_SCOPE(v1_VariadicSplit_visit_attributes);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ngraph::op::v1::VariadicSplit::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<Node> op::v1::VariadicSplit::clone_with_new_inputs(const OutputVector& new_args) const {
|
||||
std::shared_ptr<Node> 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<v1::VariadicSplit>(new_args.at(0), new_args.at(1), new_args.at(2));
|
||||
return std::make_shared<VariadicSplit>(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<size_t>(0));
|
||||
|
||||
if (has_nonzero_dims) {
|
||||
ov::reference::slice(in->get_data_ptr<const char>(),
|
||||
out->get_data_ptr<char>(),
|
||||
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<int64_t>(axis_tensor)[0];
|
||||
axis = ngraph::normalize_axis(this, axis, data_tensor->get_partial_shape().rank());
|
||||
OPENVINO_SUPPRESS_DEPRECATED_END
|
||||
|
||||
std::vector<ov::PartialShape> 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));
|
||||
|
||||
const auto data_shape = data_tensor->get_shape();
|
||||
std::vector<size_t> lower_bounds(data_shape.size(), 0);
|
||||
std::vector<size_t> upper_bounds = data_shape;
|
||||
upper_bounds[axis] = 0;
|
||||
|
||||
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 true;
|
||||
}
|
||||
bool op::v1::VariadicSplit::evaluate(const HostTensorVector& outputs, const HostTensorVector& inputs) const {
|
||||
bool VariadicSplit::evaluate(TensorVector& outputs, const TensorVector& inputs) const {
|
||||
OV_OP_SCOPE(v1_VariadicSplit_evaluate);
|
||||
return evaluate_variadic_split(inputs, outputs);
|
||||
|
||||
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());
|
||||
|
||||
auto out_partial_shape = output_shapes.cbegin();
|
||||
for (auto& output : outputs) {
|
||||
output.set_shape(out_partial_shape->to_shape());
|
||||
++out_partial_shape;
|
||||
}
|
||||
|
||||
return variadic_split::evaluate(outputs, inputs);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user