From 5853509b3c69e72f3ca80c3939090ea5b8c18fcf Mon Sep 17 00:00:00 2001 From: Vladimir Paramuzov Date: Tue, 24 Oct 2023 10:18:04 +0400 Subject: [PATCH] Fixed ngraph reference impl for Range operation (#20631) * Fixed ngraph reference impl for Range operation * Truncate range for integer output type * explicit static cast --- src/core/src/op/range.cpp | 33 +++++++++++++++++++++------------ src/core/tests/eval.cpp | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/core/src/op/range.cpp b/src/core/src/op/range.cpp index 6285391ae56e06..204161ce10ac7b 100644 --- a/src/core/src/op/range.cpp +++ b/src/core/src/op/range.cpp @@ -144,37 +144,46 @@ bool evaluate(const HostTensorPtr& out, const HostTensorPtr& step, int version) { using T = typename element_type_traits::value_type; - T start_val; - T stop_val; - T step_val; + double start_val; + double stop_val; + double step_val; if (version < 4) { - start_val = *start->get_data_ptr(); - stop_val = *stop->get_data_ptr(); - step_val = *step->get_data_ptr(); + start_val = static_cast(*start->get_data_ptr()); + stop_val = static_cast(*stop->get_data_ptr()); + step_val = static_cast(*step->get_data_ptr()); if (!(check_value(start_val) && check_value(stop_val) && check_value(step_val) && (step_val != static_cast(0)))) { return false; } } else { - if (!(get_casted_value(start, &start_val) && get_casted_value(stop, &stop_val) && - get_casted_value(step, &step_val))) { + if (!(get_casted_value(start, &start_val) && get_casted_value(stop, &stop_val) && + get_casted_value(step, &step_val))) { return false; } } int64_t out_size = 0; + if (ov::element::Type(ET).is_integral_number()) { + start_val = std::trunc(start_val); + stop_val = std::trunc(stop_val); + step_val = std::trunc(step_val); + } + int64_t steps = static_cast(std::ceil(double(stop_val - start_val) / step_val)); if (steps > 0) { out_size = steps; } ov::Shape out_shape = ov::Shape({static_cast(out_size)}); out->set_shape(out_shape); - ov::reference::range(&start_val, &step_val, shape_size(out_shape), out->get_data_ptr()); + + T start_val_casted = static_cast(start_val); + T step_val_casted = static_cast(step_val); + ov::reference::range(&start_val_casted, &step_val_casted, shape_size(out_shape), out->get_data_ptr()); return true; } -bool evaluate_power(const HostTensorPtr& out, +bool evaluate_range(const HostTensorPtr& out, const HostTensorPtr& start, const HostTensorPtr& stop, const HostTensorPtr& step, @@ -209,7 +218,7 @@ bool op::v4::Range::evaluate(const HostTensorVector& outputs, const HostTensorVe HostTensorPtr start = inputs[0]; HostTensorPtr stop = inputs[1]; HostTensorPtr step = inputs[2]; - return rangeop::evaluate_power(out, start, stop, step, m_output_type, 4); + return rangeop::evaluate_range(out, start, stop, step, m_output_type, 4); } bool op::v4::Range::has_evaluate() const { @@ -381,7 +390,7 @@ bool op::v0::Range::evaluate(const HostTensorVector& outputs, const HostTensorVe HostTensorPtr start = inputs[0]; HostTensorPtr stop = inputs[1]; HostTensorPtr step = inputs[2]; - return rangeop::evaluate_power(out, start, stop, step, start->get_element_type(), 0); + return rangeop::evaluate_range(out, start, stop, step, start->get_element_type(), 0); } bool op::v0::Range::has_evaluate() const { diff --git a/src/core/tests/eval.cpp b/src/core/tests/eval.cpp index 86b3cc2ecf82ce..fabf47f0f2f248 100644 --- a/src/core/tests/eval.cpp +++ b/src/core/tests/eval.cpp @@ -178,6 +178,27 @@ TEST(eval, evaluate_dynamic_range_sum) { ASSERT_EQ(cval, seq); } +TEST(eval, evaluate_dynamic_range_fp16_out) { + auto p_start = make_shared(element::i32, PartialShape{}); + auto p_stop = make_shared(element::i32, PartialShape{}); + auto p_step = make_shared(element::i32, PartialShape{}); + auto range = make_shared(p_start, p_stop, p_step, ov::element::f16); + auto model = make_shared(OutputVector{range}, ParameterVector{p_start, p_stop, p_step}); + auto result_tensor = ov::Tensor(); + auto out_vector = ov::TensorVector{result_tensor}; + auto in_vector = ov::TensorVector{make_tensor({}, {0}), + make_tensor({}, {3087}), + make_tensor({}, {1})}; + ASSERT_TRUE(model->evaluate(out_vector, in_vector)); + result_tensor = out_vector.at(0); + EXPECT_EQ(result_tensor.get_element_type(), element::f16); + EXPECT_EQ(result_tensor.get_shape(), (Shape{3087})); + auto cval = read_vector(result_tensor); + for (size_t i = 0; i < 3087; i++) { + ASSERT_EQ(cval[i], ov::float16(i)); + } +} + TEST(eval, evaluate_broadcast_v3_bidirectional) { Shape shape_a{4, 1}; auto A = make_shared(element::f32, shape_a);