Skip to content

Commit

Permalink
Fixed ngraph reference impl for Range operation (openvinotoolkit#20631)
Browse files Browse the repository at this point in the history
* Fixed ngraph reference impl for Range operation

* Truncate range for integer output type

* explicit static cast
  • Loading branch information
vladimir-paramuzov authored Oct 24, 2023
1 parent 7ceff55 commit 5853509
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 12 deletions.
33 changes: 21 additions & 12 deletions src/core/src/op/range.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,37 +144,46 @@ bool evaluate(const HostTensorPtr& out,
const HostTensorPtr& step,
int version) {
using T = typename element_type_traits<ET>::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<ET>();
stop_val = *stop->get_data_ptr<ET>();
step_val = *step->get_data_ptr<ET>();
start_val = static_cast<double>(*start->get_data_ptr<ET>());
stop_val = static_cast<double>(*stop->get_data_ptr<ET>());
step_val = static_cast<double>(*step->get_data_ptr<ET>());
if (!(check_value(start_val) && check_value(stop_val) && check_value(step_val) &&
(step_val != static_cast<T>(0)))) {
return false;
}
} else {
if (!(get_casted_value<T>(start, &start_val) && get_casted_value<T>(stop, &stop_val) &&
get_casted_value<T>(step, &step_val))) {
if (!(get_casted_value<double>(start, &start_val) && get_casted_value<double>(stop, &stop_val) &&
get_casted_value<double>(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<int64_t>(std::ceil(double(stop_val - start_val) / step_val));
if (steps > 0) {
out_size = steps;
}
ov::Shape out_shape = ov::Shape({static_cast<size_t>(out_size)});
out->set_shape(out_shape);
ov::reference::range(&start_val, &step_val, shape_size(out_shape), out->get_data_ptr<ET>());

T start_val_casted = static_cast<T>(start_val);
T step_val_casted = static_cast<T>(step_val);
ov::reference::range(&start_val_casted, &step_val_casted, shape_size(out_shape), out->get_data_ptr<ET>());
return true;
}

bool evaluate_power(const HostTensorPtr& out,
bool evaluate_range(const HostTensorPtr& out,
const HostTensorPtr& start,
const HostTensorPtr& stop,
const HostTensorPtr& step,
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
21 changes: 21 additions & 0 deletions src/core/tests/eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<ov::op::v0::Parameter>(element::i32, PartialShape{});
auto p_stop = make_shared<ov::op::v0::Parameter>(element::i32, PartialShape{});
auto p_step = make_shared<ov::op::v0::Parameter>(element::i32, PartialShape{});
auto range = make_shared<op::v4::Range>(p_start, p_stop, p_step, ov::element::f16);
auto model = make_shared<Model>(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<element::Type_t::i32>({}, {0}),
make_tensor<element::Type_t::i32>({}, {3087}),
make_tensor<element::Type_t::i32>({}, {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<ov::float16>(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<ov::op::v0::Parameter>(element::f32, shape_a);
Expand Down

0 comments on commit 5853509

Please sign in to comment.