[Core] Move SlicePlan to Dev API (#19971)

* Move SlicePlan to Dev API

* Recover legacy API

---------

Co-authored-by: Evgenya Nugmanova <evgeniia.nugmanova@intel.com>
This commit is contained in:
Tomasz Jankowski 2023-09-21 14:41:01 +02:00 committed by GitHub
parent e5acf880ad
commit c4adf80ec6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 176 additions and 72 deletions

View File

@ -8,12 +8,12 @@
#include <vector>
#include "itt.hpp"
#include "ngraph/slice_plan.hpp"
#include "openvino/core/rt_info.hpp"
#include "openvino/op/constant.hpp"
#include "openvino/op/result.hpp"
#include "openvino/op/slice.hpp"
#include "openvino/op/strided_slice.hpp"
#include "openvino/op/util/slice_plan.hpp"
#include "openvino/op/util/sub_graph_base.hpp"
#include "openvino/op/variadic_split.hpp"
#include "openvino/pass/manager.hpp"
@ -51,10 +51,9 @@ bool ov::pass::UselessSliceEraser::run_on_model(const std::shared_ptr<ov::Model>
return rewritten;
}
OPENVINO_SUPPRESS_DEPRECATED_START
namespace {
ngraph::SlicePlan get_slice_plan(std::shared_ptr<ov::op::v1::StridedSlice> slice) {
op::util::SlicePlan get_slice_plan(std::shared_ptr<ov::op::v1::StridedSlice> slice) {
auto convert_mask_to_axis_set = [](const std::vector<int64_t>& mask) {
ov::AxisSet axis_set{};
for (size_t i = 0; i < static_cast<size_t>(mask.size()); ++i) {
@ -69,7 +68,7 @@ ngraph::SlicePlan get_slice_plan(std::shared_ptr<ov::op::v1::StridedSlice> slice
auto end = std::dynamic_pointer_cast<ov::op::v0::Constant>(slice->input_value(2).get_node_shared_ptr());
auto strides = std::dynamic_pointer_cast<ov::op::v0::Constant>(slice->input_value(3).get_node_shared_ptr());
if (!begin || !end || !strides || slice->input(0).get_partial_shape().is_dynamic())
return ngraph::SlicePlan();
return op::util::SlicePlan();
auto begin_vec = begin->cast_vector<int64_t>();
auto end_vec = end->cast_vector<int64_t>();
@ -77,15 +76,15 @@ ngraph::SlicePlan get_slice_plan(std::shared_ptr<ov::op::v1::StridedSlice> slice
const auto begin_mask = convert_mask_to_axis_set(slice->get_begin_mask());
const auto end_mask = convert_mask_to_axis_set(slice->get_end_mask());
ngraph::SlicePlan plan = ngraph::make_slice_plan(slice->input(0).get_shape(),
begin_vec,
end_vec,
strides_vec,
begin_mask,
end_mask,
convert_mask_to_axis_set(slice->get_new_axis_mask()),
convert_mask_to_axis_set(slice->get_shrink_axis_mask()),
convert_mask_to_axis_set(slice->get_ellipsis_mask()));
const auto plan = op::util::make_slice_plan(slice->input(0).get_shape(),
begin_vec,
end_vec,
strides_vec,
begin_mask,
end_mask,
convert_mask_to_axis_set(slice->get_new_axis_mask()),
convert_mask_to_axis_set(slice->get_shrink_axis_mask()),
convert_mask_to_axis_set(slice->get_ellipsis_mask()));
return plan;
}
@ -94,7 +93,7 @@ bool strided_slices_perform_the_same(std::shared_ptr<ov::op::v1::StridedSlice> l
auto lhs_plan = get_slice_plan(lhs);
auto rhs_plan = get_slice_plan(rhs);
auto empty_plan = ngraph::SlicePlan();
const auto empty_plan = op::util::SlicePlan();
if (lhs_plan == empty_plan || rhs_plan == empty_plan)
return false;
return lhs_plan == rhs_plan;
@ -138,7 +137,7 @@ bool ov::pass::GroupedStridedSliceOptimizer::run_on_model(const std::shared_ptr<
bool graph_rewritten = false;
struct planned_slice {
std::shared_ptr<ov::op::v1::StridedSlice> ptr;
ngraph::SlicePlan plan;
op::util::SlicePlan plan;
};
std::map<ov::Output<Node>, std::vector<planned_slice>> source_to_ss_with_plan;
@ -151,7 +150,7 @@ bool ov::pass::GroupedStridedSliceOptimizer::run_on_model(const std::shared_ptr<
}
if (auto ss = std::dynamic_pointer_cast<ov::op::v1::StridedSlice>(node)) {
auto slice_plan = get_slice_plan(ss);
if (slice_plan == ngraph::SlicePlan())
if (slice_plan == op::util::SlicePlan())
continue;
source_to_ss_with_plan[ss->input_value(0)].push_back({ss, slice_plan});
}

View File

@ -0,0 +1,62 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include "openvino/core/axis_set.hpp"
#include "openvino/core/shape.hpp"
namespace ov {
namespace op {
namespace util {
/**
* @brief A collection of parameters for advanced slicing
* @details In various places, like ConstantFolding, it is useful to transform DynSlice by converting it to a sequence
* of ops:
*
* Slice (to do the basic slicing)
* |
* v
* Reshape (non-transposing, to handle shrinks)
* |
* v
* Reverse (to emulate backwards stride)
*
* (The Reshape, Reverse, or both may be omitted if they would just be identities.)
*
* A SlicePlan is used to collect parameters for these ops.
**/
struct OPENVINO_API SlicePlan {
// Parameters for the Slice
std::vector<int64_t> begins;
std::vector<int64_t> ends;
std::vector<int64_t> strides;
// Shapes coming into, and going out of, the Reshape.
Shape reshape_in_shape;
Shape reshape_out_shape;
// Parameters for the Reverse
AxisSet reverse_axes;
bool operator==(const SlicePlan& other) const;
bool operator!=(const SlicePlan& other) const;
};
/**
* @brief Prepares slice plan for strided slicing
**/
SlicePlan OPENVINO_API make_slice_plan(const Shape& input_shape,
const std::vector<int64_t>& begins,
const std::vector<int64_t>& ends,
const std::vector<int64_t>& strides,
const AxisSet& lower_bounds_mask,
const AxisSet& upper_bounds_mask,
const AxisSet& new_axis_mask,
const AxisSet& shrink_axis_mask,
const AxisSet& ellipsis_mask);
} // namespace util
} // namespace op
} // namespace ov

View File

@ -42,7 +42,7 @@ target_include_directories(${TARGET_NAME} SYSTEM PRIVATE
$<BUILD_INTERFACE:$<$<TARGET_EXISTS:xbyak::xbyak>:$<TARGET_PROPERTY:xbyak::xbyak,INTERFACE_INCLUDE_DIRECTORIES>>>)
find_package(Threads REQUIRED)
target_link_libraries(${TARGET_NAME} PRIVATE Threads::Threads)
target_link_libraries(${TARGET_NAME} PRIVATE Threads::Threads openvino::core::dev)
ov_add_clang_format_target(${TARGET_NAME}_clang FOR_TARGETS ${TARGET_NAME})

View File

@ -6,18 +6,13 @@
#include <cmath>
#include "ngraph/check.hpp"
#include "ngraph/runtime/host_tensor.hpp"
#include "ngraph/runtime/opt_kernel/reshape.hpp"
#include "ngraph/slice_plan.hpp"
#include "openvino/op/util/slice_plan.hpp"
#include "openvino/reference/reverse.hpp"
#include "openvino/reference/slice.hpp"
#include "openvino/reference/utils/coordinate_transform.hpp"
namespace ov {
namespace reference {
NGRAPH_SUPPRESS_DEPRECATED_START
void strided_slice(const char* arg, char* out, const Shape& arg_shape, const ngraph::SlicePlan& sp, size_t elem_type);
NGRAPH_SUPPRESS_DEPRECATED_END
void strided_slice(const char* arg, char* out, const Shape& arg_shape, const op::util::SlicePlan& sp, size_t elem_type);
} // namespace reference
} // namespace ov

View File

@ -10,6 +10,7 @@
#include "ngraph/check.hpp"
#include "ngraph/runtime/aligned_buffer.hpp"
#include "ngraph/runtime/opt_kernel/reshape.hpp"
using namespace ov;
NGRAPH_SUPPRESS_DEPRECATED_START
@ -17,7 +18,7 @@ NGRAPH_SUPPRESS_DEPRECATED_START
void reference::strided_slice(const char* arg,
char* out,
const Shape& arg_shape,
const ngraph::SlicePlan& sp,
const op::util::SlicePlan& sp,
size_t elem_type) {
auto hasZeroDims = [](const ov::Shape& shape) -> bool {
return std::any_of(shape.begin(), shape.end(), [](const size_t& dim) {

View File

@ -18,8 +18,8 @@
#include "ngraph/opsets/opset3.hpp"
#include "ngraph/runtime/opt_kernel/reshape.hpp"
#include "ngraph/shape.hpp"
#include "ngraph/slice_plan.hpp"
#include "openvino/op/util/precision_sensitive_attribute.hpp"
#include "openvino/op/util/slice_plan.hpp"
#include "openvino/reference/strided_slice.hpp"
using namespace std;
@ -160,18 +160,16 @@ bool batch_to_space_evaluate(const HostTensorVector& outputs, const HostTensorVe
begins.assign(crops_begin_values, crops_begin_values + shape_size(inputs[2]->get_shape()));
std::vector<int64_t> default_strides(begins.size(), 1);
OPENVINO_SUPPRESS_DEPRECATED_START
SlicePlan slice_plan = make_slice_plan(data_shape,
begins,
upperbounds_values,
default_strides,
begin_mask,
end_mask,
AxisSet(),
AxisSet(),
AxisSet());
const auto slice_plan = ov::op::util::make_slice_plan(data_shape,
begins,
upperbounds_values,
default_strides,
begin_mask,
end_mask,
AxisSet(),
AxisSet(),
AxisSet());
ov::reference::strided_slice(flat_data, outputs[0]->get_data_ptr<char>(), data_shape, slice_plan, elem_size);
OPENVINO_SUPPRESS_DEPRECATED_END
return true;
}
} // namespace

View File

@ -14,13 +14,13 @@
#include "ngraph/op/constant.hpp"
#include "ngraph/op/shape_of.hpp"
#include "ngraph/runtime/host_tensor.hpp"
#include "ngraph/slice_plan.hpp"
#include "ngraph/type/element_type_traits.hpp"
#include "ngraph/util.hpp"
#include "ngraph/validation_util.hpp"
#include "openvino/core/rt_info.hpp"
#include "openvino/core/validation_util.hpp"
#include "openvino/op/util/precision_sensitive_attribute.hpp"
#include "openvino/op/util/slice_plan.hpp"
#include "openvino/pass/constant_folding.hpp"
#include "openvino/reference/strided_slice.hpp"
#include "strided_slice_shape_inference.hpp"
@ -189,11 +189,10 @@ shared_ptr<Node> op::v1::StridedSlice::clone_with_new_inputs(const OutputVector&
m_ellipsis_mask);
}
OPENVINO_SUPPRESS_DEPRECATED_START
namespace strided_slice {
namespace {
OPENVINO_SUPPRESS_DEPRECATED_START
inline bool evaluate(const HostTensorPtr& in, const SlicePlan& sp, const HostTensorPtr& out)
inline bool evaluate(const HostTensorPtr& in, const ov::op::util::SlicePlan& sp, const HostTensorPtr& out)
{
auto in_shape = in->get_shape();
@ -219,15 +218,15 @@ bool evaluate_strided_slice(const HostTensorPtr& in,
std::vector<int64_t> begin_const = host_tensor_2_vector<int64_t>(begin);
std::vector<int64_t> end_const = host_tensor_2_vector<int64_t>(end);
std::vector<int64_t> stride_const = host_tensor_2_vector<int64_t>(stride);
SlicePlan slice_plan = make_slice_plan(in->get_shape(),
begin_const,
end_const,
stride_const,
begin_mask,
end_mask,
new_axis_mask,
shrink_axis_mask,
ellipsis_mask);
const auto slice_plan = ov::op::util::make_slice_plan(in->get_shape(),
begin_const,
end_const,
stride_const,
begin_mask,
end_mask,
new_axis_mask,
shrink_axis_mask,
ellipsis_mask);
return evaluate(in, slice_plan, out);
}
OPENVINO_SUPPRESS_DEPRECATED_END

View File

@ -2,26 +2,28 @@
// SPDX-License-Identifier: Apache-2.0
//
#include "ngraph/slice_plan.hpp"
#include "openvino/op/util/slice_plan.hpp"
#include <algorithm>
#include "ngraph/check.hpp"
#include "ngraph/op/util/slice_plan.hpp"
#include "openvino/core/except.hpp"
using namespace ngraph;
NGRAPH_SUPPRESS_DEPRECATED_START
namespace ov {
namespace op {
namespace util {
SlicePlan ngraph::make_slice_plan(const Shape& input_shape,
const std::vector<int64_t>& begins,
const std::vector<int64_t>& ends,
const std::vector<int64_t>& strides,
const AxisSet& lower_bounds_mask,
const AxisSet& upper_bounds_mask,
const AxisSet& new_axis_mask,
const AxisSet& shrink_axis_mask,
const AxisSet& ellipsis_mask) {
NGRAPH_CHECK(begins.size() == ends.size());
NGRAPH_CHECK(ends.size() == strides.size());
SlicePlan make_slice_plan(const Shape& input_shape,
const std::vector<int64_t>& begins,
const std::vector<int64_t>& ends,
const std::vector<int64_t>& strides,
const AxisSet& lower_bounds_mask,
const AxisSet& upper_bounds_mask,
const AxisSet& new_axis_mask,
const AxisSet& shrink_axis_mask,
const AxisSet& ellipsis_mask) {
OPENVINO_ASSERT(begins.size() == ends.size());
OPENVINO_ASSERT(ends.size() == strides.size());
size_t num_slice_indices = begins.size();
size_t num_real_axes = 0;
@ -35,7 +37,7 @@ SlicePlan ngraph::make_slice_plan(const Shape& input_shape,
// and are not the ellipsis).
for (size_t i = 0; i < num_slice_indices; i++) {
if (ellipsis_mask.count(i)) {
NGRAPH_CHECK(!ellipsis_found);
OPENVINO_ASSERT(!ellipsis_found);
ellipsis_found = true;
} else if (new_axis_mask.count(i)) {
num_new_axes++;
@ -47,7 +49,11 @@ SlicePlan ngraph::make_slice_plan(const Shape& input_shape,
}
}
NGRAPH_CHECK(num_real_axes <= input_shape.size(), "num_real_axes=", num_real_axes, ", input_shape=", input_shape);
OPENVINO_ASSERT(num_real_axes <= input_shape.size(),
"num_real_axes=",
num_real_axes,
", input_shape=",
input_shape);
// Figure out how many axes need to be inserted when the ellipsis (which
// may be an implicit ellipsis at the end) is expanded.
@ -100,7 +106,7 @@ SlicePlan ngraph::make_slice_plan(const Shape& input_shape,
// Note that clipping is not used for "shrunken" axes: an
// out-of-bounds index is an error.
NGRAPH_CHECK(begin >= -(int64_t(input_shape[i_in])) && begin < int64_t(input_shape[i_in]));
OPENVINO_ASSERT(begin >= -(int64_t(input_shape[i_in])) && begin < int64_t(input_shape[i_in]));
if (begin < 0) {
begin += int64_t(input_shape[i_in]);
@ -142,7 +148,7 @@ SlicePlan ngraph::make_slice_plan(const Shape& input_shape,
real_end = std::max(min_real_end, std::min(int64_t(input_shape[i_in]), real_end));
// Ensure stride is not zero, and adjust it for backwards slicing.
NGRAPH_CHECK(strides[i] != 0);
OPENVINO_ASSERT(strides[i] != 0);
int64_t real_stride = std::abs(strides[i]);
// Adjust for reversal if needed. This isn't quite as simple as swapping begin and
@ -157,8 +163,7 @@ SlicePlan ngraph::make_slice_plan(const Shape& input_shape,
p.reverse_axes.insert(i_out);
}
// nGraph's slice op does not like it when end < begin, so we truncate for that case
// here.
// ov slice op does not like it when end < begin, so we truncate for that case here.
if (real_end < real_begin) {
real_end = real_begin;
}
@ -194,7 +199,7 @@ SlicePlan ngraph::make_slice_plan(const Shape& input_shape,
return p;
}
bool SlicePlan::operator==(const ngraph::SlicePlan& other) const {
bool SlicePlan::operator==(const SlicePlan& other) const {
bool equal = true;
equal &= begins == other.begins;
equal &= ends == other.ends;
@ -206,6 +211,51 @@ bool SlicePlan::operator==(const ngraph::SlicePlan& other) const {
return equal;
}
bool SlicePlan::operator!=(const ngraph::SlicePlan& other) const {
bool SlicePlan::operator!=(const SlicePlan& other) const {
return !(*this == other);
}
} // namespace util
} // namespace op
} // namespace ov
NGRAPH_SUPPRESS_DEPRECATED_START
namespace ngraph {
SlicePlan make_slice_plan(const Shape& input_shape,
const std::vector<int64_t>& begins,
const std::vector<int64_t>& ends,
const std::vector<int64_t>& strides,
const AxisSet& lower_bounds_mask,
const AxisSet& upper_bounds_mask,
const AxisSet& new_axis_mask,
const AxisSet& shrink_axis_mask,
const AxisSet& ellipsis_mask) {
const auto sp = ov::op::util::make_slice_plan(input_shape,
begins,
ends,
strides,
lower_bounds_mask,
upper_bounds_mask,
new_axis_mask,
shrink_axis_mask,
ellipsis_mask);
return SlicePlan{sp.begins, sp.ends, sp.strides, sp.reshape_in_shape, sp.reshape_out_shape, sp.reverse_axes};
}
bool SlicePlan::operator==(const SlicePlan& other) const {
bool equal = true;
equal &= begins == other.begins;
equal &= ends == other.ends;
equal &= strides == other.strides;
equal &= reshape_in_shape == other.reshape_in_shape;
equal &= reshape_out_shape == other.reshape_out_shape;
equal &= reverse_axes == other.reverse_axes;
return equal;
}
bool SlicePlan::operator!=(const SlicePlan& other) const {
return !(*this == other);
}
} // namespace ngraph
NGRAPH_SUPPRESS_DEPRECATED_END