Fixed ngraph reference impl for Range operation (#20631)

* Fixed ngraph reference impl for Range operation

* Truncate range for integer output type

* explicit static cast
This commit is contained in:
Vladimir Paramuzov
2023-10-24 10:18:04 +04:00
committed by GitHub
parent 7ceff55b71
commit 5853509b3c
2 changed files with 42 additions and 12 deletions
+21 -12
View File
@@ -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,
@@ -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 {
+21
View File
@@ -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);