Correct inf bound check for 32-bit in shape infer (#17047)
This commit is contained in:
@@ -14,6 +14,49 @@ namespace dim {
|
||||
|
||||
constexpr auto inf_bound = -1; //!< Infinite bound value for dimension.
|
||||
|
||||
/**
|
||||
* @brief Checks if dimension length is infinite bound (undefined).
|
||||
*
|
||||
* @tparam T Type of dimension length.
|
||||
* @param dim Dimension length value.
|
||||
* @return True if dimension length has infinite bound, otherwise false.
|
||||
*/
|
||||
template <class T>
|
||||
constexpr bool is_inf_bound(const T dim) {
|
||||
return dim == static_cast<T>(inf_bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert static dimension length to ov::Dimension::value_type.
|
||||
*
|
||||
* As static dimension length type is size_t (bit-length depends on architecture) the maximum value (undefined)
|
||||
* is convert to ov::Dimension infinite bound.
|
||||
*
|
||||
* @tparam T Static dimension type (size_t)
|
||||
* @tparam U ov::Dimension::value_type
|
||||
* @param dim Dimension length to convert.
|
||||
* @return Converted input value to ov::Dimension::value_type.
|
||||
*/
|
||||
template <class T, class U = typename Dimension::value_type>
|
||||
constexpr typename std::enable_if<std::is_same<T, size_t>::value, U>::type value_convert(const T dim) {
|
||||
return is_inf_bound(dim) ? inf_bound : static_cast<U>(dim);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Conversion of dimension when input type is same as ov::Dimension::value_type.
|
||||
*
|
||||
* Return value as it is.
|
||||
*
|
||||
* @tparam T Dimension type same as ov::Dimension::value_type.
|
||||
* @tparam U Dimension::value_type.
|
||||
* @param dim Dimension length to convert.
|
||||
* @return Same value as input.
|
||||
*/
|
||||
template <class T, class U = typename Dimension::value_type>
|
||||
constexpr typename std::enable_if<std::is_same<T, U>::value, U>::type value_convert(const T dim) {
|
||||
return dim;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculate dilated dimension value.
|
||||
*
|
||||
@@ -50,7 +93,7 @@ constexpr auto dilated(const TDim& dim, const typename TDim::value_type dilation
|
||||
template <class TDim>
|
||||
constexpr typename std::enable_if<std::is_arithmetic<TDim>::value, TDim>::type padded(const TDim dim,
|
||||
const int64_t pad_num) {
|
||||
return ((dim == inf_bound) || (dim + pad_num < 0)) ? inf_bound : dim + pad_num;
|
||||
return (is_inf_bound(dim) || (dim + pad_num < 0)) ? inf_bound : dim + pad_num;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,19 +7,12 @@
|
||||
#include <openvino/core/validation_util.hpp>
|
||||
#include <openvino/op/pad.hpp>
|
||||
|
||||
#include "dimension_util.hpp"
|
||||
#include "utils.hpp"
|
||||
namespace ov {
|
||||
namespace op {
|
||||
namespace v1 {
|
||||
|
||||
namespace pad {
|
||||
inline auto calc_dim(const int64_t dim, const int64_t pad_dim_diff) -> int64_t {
|
||||
constexpr auto inf_bound = -1;
|
||||
const auto padded_dim = dim + pad_dim_diff;
|
||||
return ((dim == inf_bound) || (padded_dim < 0)) ? inf_bound : padded_dim;
|
||||
};
|
||||
} // namespace pad
|
||||
|
||||
template <class TShape>
|
||||
std::vector<TShape> shape_infer(const Pad* op,
|
||||
const std::vector<TShape>& input_shapes,
|
||||
@@ -117,8 +110,9 @@ std::vector<TShape> shape_infer(const Pad* op,
|
||||
const auto pad_dim_diff_lb = begin_lb + end_lb;
|
||||
const auto pad_dim_diff_ub = begin.second + end.second;
|
||||
if ((pad_dim_diff_lb != 0) || (pad_dim_diff_ub != 0)) {
|
||||
const auto lb = pad::calc_dim(dim_lb, pad_dim_diff_lb);
|
||||
const auto ub = pad::calc_dim(arg_shape[i].get_max_length(), pad_dim_diff_ub);
|
||||
using namespace ov::util;
|
||||
const auto lb = dim::padded(dim_lb, pad_dim_diff_lb);
|
||||
const auto ub = dim::padded(arg_shape[i].get_max_length(), pad_dim_diff_ub);
|
||||
output_shape.emplace_back(lb, ub);
|
||||
} else {
|
||||
output_shape.push_back(arg_shape[i]);
|
||||
|
||||
@@ -128,17 +128,14 @@ namespace slice {
|
||||
* \return -1 for infinite number otherwise [0..int64_max] for finit step.
|
||||
*/
|
||||
inline int64_t get_sliced_value(const int64_t dim, const int64_t start, const int64_t stop, const int64_t step) {
|
||||
using namespace ov::util;
|
||||
|
||||
const auto is_reverse_step = step < 0;
|
||||
|
||||
constexpr int64_t min_bound = 0;
|
||||
constexpr int64_t inf_bound = -1;
|
||||
|
||||
const auto& norm_dim = dim == inf_bound ? std::numeric_limits<int64_t>::max() : dim;
|
||||
#ifdef OPENVINO_ARCH_64_BIT
|
||||
const auto& norm_dim = dim::is_inf_bound(dim) ? std::numeric_limits<int64_t>::max() : dim;
|
||||
const auto is_norm_dim_max = ov::internal::is_max(norm_dim);
|
||||
#else
|
||||
const auto is_norm_dim_max = ov::internal::is_max(size_t(norm_dim));
|
||||
#endif
|
||||
|
||||
const auto is_start_lt_min_bound = start < min_bound;
|
||||
const auto are_bounds_diff_sign = is_start_lt_min_bound != (stop < 0);
|
||||
@@ -151,24 +148,24 @@ inline int64_t get_sliced_value(const int64_t dim, const int64_t start, const in
|
||||
int64_t lb, ub;
|
||||
if (is_norm_dim_max && (are_bounds_diff_sign || any_bound_max || is_start_limit)) {
|
||||
if (is_reverse_step) {
|
||||
ub = (is_start_lt_min_bound || any_bound_max) ? inf_bound : inf_bound - start;
|
||||
ub = (is_start_lt_min_bound || any_bound_max) ? dim::inf_bound : dim::inf_bound - start;
|
||||
} else if (is_start_lt_min_bound && !is_start_limit) {
|
||||
ub = is_stop_max ? -start : stop;
|
||||
} else {
|
||||
ub = inf_bound;
|
||||
ub = dim::inf_bound;
|
||||
}
|
||||
lb = min_bound;
|
||||
} else {
|
||||
const int64_t lower_max = is_reverse_step ? norm_dim - 1 : norm_dim;
|
||||
const int64_t upper_min = is_reverse_step ? inf_bound : min_bound;
|
||||
const int64_t upper_min = is_reverse_step ? dim::inf_bound : min_bound;
|
||||
|
||||
lb = ov::util::clip(ov::util::normalize(start, norm_dim), min_bound, lower_max);
|
||||
ub = ov::util::clip(ov::util::normalize(stop, norm_dim), upper_min, norm_dim);
|
||||
}
|
||||
|
||||
// Calculate sliced value from bounds and step.
|
||||
if (is_norm_dim_max && lb == min_bound && ub == inf_bound) {
|
||||
return inf_bound;
|
||||
if (is_norm_dim_max && lb == min_bound && dim::is_inf_bound(ub)) {
|
||||
return dim::inf_bound;
|
||||
} else {
|
||||
// Limit sliced value to not-positive for negative step or not-negative for positive step
|
||||
auto sliced_value =
|
||||
@@ -312,6 +309,7 @@ std::unique_ptr<TResult> get_input_bounds(const ov::Node* op,
|
||||
template <class TDim>
|
||||
TDim make_dim(const TDim& dim, const Bounds& start, const Bounds& stop, int64_t step) {
|
||||
using TDimVal = typename TDim::value_type;
|
||||
using namespace ov::util;
|
||||
|
||||
const auto is_start_zero_crossing = is_bounds_zero_crossing(start);
|
||||
const auto start_lb = is_start_zero_crossing && is_lb_within_dim(start.first, dim) ? 0 : start.first;
|
||||
@@ -323,11 +321,11 @@ TDim make_dim(const TDim& dim, const Bounds& start, const Bounds& stop, int64_t
|
||||
|
||||
TDimVal lb, ub;
|
||||
if (step > 0) {
|
||||
lb = static_cast<TDimVal>(get_sliced_value(dim.get_min_length(), start_ub, stop_lb, step));
|
||||
ub = static_cast<TDimVal>(get_sliced_value(dim.get_max_length(), start_lb, stop_ub, step));
|
||||
lb = static_cast<TDimVal>(get_sliced_value(dim::value_convert(dim.get_min_length()), start_ub, stop_lb, step));
|
||||
ub = static_cast<TDimVal>(get_sliced_value(dim::value_convert(dim.get_max_length()), start_lb, stop_ub, step));
|
||||
} else {
|
||||
lb = static_cast<TDimVal>(get_sliced_value(dim.get_min_length(), start_lb, stop_ub, step));
|
||||
ub = static_cast<TDimVal>(get_sliced_value(dim.get_max_length(), start_ub, stop_lb, step));
|
||||
lb = static_cast<TDimVal>(get_sliced_value(dim::value_convert(dim.get_min_length()), start_lb, stop_ub, step));
|
||||
ub = static_cast<TDimVal>(get_sliced_value(dim::value_convert(dim.get_max_length()), start_ub, stop_lb, step));
|
||||
}
|
||||
|
||||
return {lb, ub};
|
||||
|
||||
@@ -92,8 +92,10 @@ std::vector<TShape> shape_infer(const util::TopKBase* op,
|
||||
const auto k_max = k.get_max_length();
|
||||
|
||||
const auto lower = std::min<TDimValue>(in_min, k_min);
|
||||
const auto upper = in_max < 0 ? Dimension::dynamic().get_max_length()
|
||||
: std::min<TDimValue>(in_max, (k_max < 0 ? Interval::s_max : k_max));
|
||||
const auto upper =
|
||||
in_max < 0
|
||||
? Dimension::dynamic().get_max_length()
|
||||
: std::min<TDimValue>(in_max, (k_max < 0 ? std::numeric_limits<TDimValue>::max() : k_max));
|
||||
dim_axis = TDim(lower, upper);
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user