diff --git a/src/core/src/op/slice.cpp b/src/core/src/op/slice.cpp index e4a7f2c54e4..860e9db0ea4 100644 --- a/src/core/src/op/slice.cpp +++ b/src/core/src/op/slice.cpp @@ -60,6 +60,20 @@ int64_t get_sliced_dim_size(int64_t start, int64_t stop, int64_t step, int64_t d return sliced_dim_size; } +bool is_max_int(element::Type_t ind_type, int64_t value) { + int64_t max_type_value = 0; + switch (ind_type) { + case element::i32: + max_type_value = std::numeric_limits::value_type>::max(); + break; + case element::i64: + max_type_value = std::numeric_limits::value_type>::max(); + break; + default: + return false; + } + return max_type_value == value; +} } // namespace bool op::v8::Slice::visit_attributes(AttributeVisitor& visitor) { @@ -288,16 +302,17 @@ PartialShape op::v8::Slice::calculate_output_shape(const std::vector& s // Avoid negative index normalization without upper bounds if (!axis_dim.get_interval().has_upper_bound()) { - if ((step < 0 && start < 0 && stop > 0) || (step > 0 && stop < 0 && start > 0)) { + if (is_max_int(get_input_element_type(2), stop) || is_max_int(get_input_element_type(1), start)) { + output_shape[norm_axis] = Dimension(-1); + continue; + } else if ((step < 0 && start < 0 && stop > 0) || (step > 0 && stop < 0 && start > 0)) { output_shape[norm_axis] = Dimension(-1); continue; } else if (step < 0 && start > 0 && stop < 0) { - int64_t max_out_dim = start >= INT32_MAX ? INT64_MAX : start + 1; - output_shape[norm_axis] = Dimension(0, max_out_dim); + output_shape[norm_axis] = Dimension(0, start + 1); continue; } else if (step > 0 && stop > 0 && start < 0) { - int64_t max_out_dim = stop >= INT32_MAX ? INT64_MAX : stop; - output_shape[norm_axis] = Dimension(0, max_out_dim); + output_shape[norm_axis] = Dimension(0, stop); continue; } } diff --git a/src/core/tests/type_prop/slice.cpp b/src/core/tests/type_prop/slice.cpp index 40733aec8e2..462e2e839b4 100644 --- a/src/core/tests/type_prop/slice.cpp +++ b/src/core/tests/type_prop/slice.cpp @@ -386,7 +386,7 @@ TEST(type_prop, slice_v8_basic_const_inputs_MAX_MIN_INT_dynamic_dimensions) { Dimension(10, 20), Dimension(30, 40), Dimension(0, 50), - Dimension(0, INT32_MAX)}; + Dimension(-1)}; std::vector start_val{2, 2, INT32_MIN, INT32_MIN, INT32_MIN, INT32_MIN, INT32_MIN, 0, 0}; std::vector stop_val{10, INT32_MAX, 5, 10, 15, 25, INT32_MAX, 50, INT32_MAX}; @@ -536,11 +536,7 @@ TEST(type_prop, slice_v8_basic_const_inputs_data_full_dynamic_dims_neg_step_neg_ TEST(type_prop, slice_v8_basic_const_inputs_data_full_dynamic_dims_neg_step_mix_ind) { PartialShape data_shape{Dimension(-1), Dimension(-1), Dimension(-1), Dimension(-1), Dimension(-1)}; - PartialShape expected_out_shape{Dimension(0, 6), - Dimension(0, 6), - Dimension(-1), - Dimension(0, INT32_MAX - 5), - Dimension(-1)}; + PartialShape expected_out_shape{Dimension(0, 6), Dimension(0, 6), Dimension(-1), Dimension(0, -1), Dimension(-1)}; std::vector start_val{5, 5, -10, INT32_MAX, INT32_MAX}; std::vector stop_val{-10, INT32_MIN, 5, 5, INT32_MIN}; @@ -557,6 +553,80 @@ TEST(type_prop, slice_v8_basic_const_inputs_data_full_dynamic_dims_neg_step_mix_ EXPECT_EQ(op->get_output_partial_shape(0), expected_out_shape); } +TEST(type_prop, slice_v8_basic_const_inputs_dynamic_dims_maxint32) { + PartialShape data_shape{Dimension(0, 2000), Dimension(-1), 4}; + PartialShape expected_out_shape{Dimension(0, 2000), Dimension(-1), Dimension(4)}; + + std::vector start_val{0, 0, 0}; + std::vector stop_val{INT32_MAX, INT32_MAX, INT32_MAX}; + std::vector step_val{1, 1, 1}; + + std::vector axes_val(start_val.size()); + std::iota(axes_val.begin(), axes_val.end(), 0); + + element::Type_t et = element::i32; + std::vector> input_vals{start_val, stop_val, step_val, axes_val}; + const auto op = make_slice_op_const_inputs(input_vals, data_shape, et); + + EXPECT_EQ(op->get_element_type(), et); + EXPECT_EQ(op->get_output_partial_shape(0), expected_out_shape); +} + +TEST(type_prop, slice_v8_basic_const_inputs_dynamic_dims_maxint64) { + PartialShape data_shape{Dimension(0, 2000), Dimension(-1), 4}; + PartialShape expected_out_shape{Dimension(0, 2000), Dimension(-1), Dimension(4)}; + + std::vector start_val{0, 0, 0}; + std::vector stop_val{INT64_MAX, INT64_MAX, INT64_MAX}; + std::vector step_val{1, 1, 1}; + + std::vector axes_val(start_val.size()); + std::iota(axes_val.begin(), axes_val.end(), 0); + + element::Type_t et = element::i64; + std::vector> input_vals{start_val, stop_val, step_val, axes_val}; + const auto op = make_slice_op_const_inputs(input_vals, data_shape, et); + + EXPECT_EQ(op->get_element_type(), et); + EXPECT_EQ(op->get_output_partial_shape(0), expected_out_shape); +} + +TEST(type_prop, slice_v8_basic_const_inputs_dynamic_dims_maxint32_start1) { + PartialShape data_shape{Dimension(0, 2000), Dimension(-1), 4}; + PartialShape expected_out_shape{Dimension(0, 2000), Dimension(-1), Dimension(4)}; + + std::vector start_val{1}; + std::vector stop_val{INT32_MAX}; + std::vector step_val{1}; + + std::vector axes_val{1}; + + element::Type_t et = element::i32; + std::vector> input_vals{start_val, stop_val, step_val, axes_val}; + const auto op = make_slice_op_const_inputs(input_vals, data_shape, et); + + EXPECT_EQ(op->get_element_type(), et); + EXPECT_EQ(op->get_output_partial_shape(0), expected_out_shape); +} + +TEST(type_prop, slice_v8_basic_const_inputs_dynamic_dims_maxint64_start1) { + PartialShape data_shape{Dimension(0, 2000), Dimension(-1), 4}; + PartialShape expected_out_shape{Dimension(0, 2000), Dimension(-1), Dimension(4)}; + + std::vector start_val{1}; + std::vector stop_val{INT64_MAX}; + std::vector step_val{1}; + + std::vector axes_val{1}; + + element::Type_t et = element::i64; + std::vector> input_vals{start_val, stop_val, step_val, axes_val}; + const auto op = make_slice_op_const_inputs(input_vals, data_shape, et); + + EXPECT_EQ(op->get_element_type(), et); + EXPECT_EQ(op->get_output_partial_shape(0), expected_out_shape); +} + TEST(type_prop, slice_v8_basic_const_inputs_MAX_MIN_INT_64_dynamic_dimensions_neg_step) { PartialShape data_shape{10, Dimension(10, 20),