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:
+21
-12
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user