Skip to content

Commit

Permalink
Add support for nan inputs of Sign Op to align with Pytorch/numpy imp…
Browse files Browse the repository at this point in the history
…lement
  • Loading branch information
liubo-intel committed Jan 9, 2024
1 parent 2d7e35c commit af3be4d
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Sign

**Outputs**

* **1**: The result of element-wise *Sign* operation. A tensor of type *T* with mapped elements of the input tensor to -1 (if it is negative), 0 (if it is zero), or 1 (if it is positive).
* **1**: The result of element-wise *Sign* operation. A tensor of type *T* with mapped elements of the input tensor to -1 (if it is negative), 0 (if it is zero), or 1 (if it is positive), nan is returned for nan inputs.

**Types**

Expand Down
16 changes: 14 additions & 2 deletions src/core/reference/include/openvino/reference/sign.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,21 @@ constexpr T sign(const T v) {
return static_cast<T>(static_cast<bool>(v));
}

template <class T, typename std::enable_if<ov::is_floating_point<T>() || std::is_signed<T>::value>::type* = nullptr>
template <class T,
typename std::enable_if<std::is_floating_point<typename std::decay<T>::type>::value ||
std::is_signed<T>::value>::type* = nullptr>
constexpr T sign(const T v) {
return static_cast<T>((T{0} < v) - (v < T{0}));
return static_cast<T>(std::isnan(static_cast<float>(v)) ? v : ((T{0} < v) - (v < T{0})));
}

template <class T,
typename std::enable_if<std::is_same<float16, typename std::decay<T>::type>::value ||
std::is_same<bfloat16, typename std::decay<T>::type>::value>::type* = nullptr>
T sign(const T v) {
if (std::isnan(static_cast<float>(v)))
return static_cast<T>(v);
else
return static_cast<T>((T{0} < v) - (v < T{0}));
}
} // namespace func

Expand Down
15 changes: 15 additions & 0 deletions src/core/tests/eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,21 @@ TEST(eval, evaluate_sign) {
ASSERT_EQ(result_val, expec);
}

TEST(eval, evaluate_sign_2) {
auto p = make_shared<ov::op::v0::Parameter>(element::f16, Shape{2, 3});
auto sign = make_shared<op::v0::Sign>(p);
auto model = make_shared<Model>(OutputVector{sign}, ParameterVector{p});
auto result = ov::Tensor();
auto out_vector = ov::TensorVector{result};
auto in_vector = ov::TensorVector{make_tensor<element::Type_t::f16>(Shape{2, 3}, {NAN, -2, 0, -4.8f, 4.8f, -0.0f})};
ASSERT_TRUE(model->evaluate(out_vector, in_vector));
result = out_vector.at(0);

EXPECT_EQ(result.get_element_type(), element::f16);
EXPECT_THAT(read_vector<float16>(result),
Pointwise(NanSensitiveFloatEq(), std::vector<float16>{NAN, -1, 0, -1, 1, 0}));
}

TEST(eval, evaluate_sin) {
auto p = make_shared<ov::op::v0::Parameter>(element::f32, Shape{11});
auto sin = make_shared<op::v0::Sin>(p);
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/intel_cpu/src/nodes/mathematics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ void Math::execute(dnnl::stream strm) {
dst_data[i] = 1.0f;
else if (src_data[i] < 0.0f)
dst_data[i] = -1.0f;
else if (std::isnan(src_data[i]))
dst_data[i] = src_data[i];
else
dst_data[i] = 0.0f;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ void ActivationLayerCPUTest::generate_inputs(const std::vector<ov::Shape>& targe
in_data.range = range;
in_data.resolution = resolution;
tensor = ov::test::utils::create_and_fill_tensor(funcInput.get_element_type(), targetInputStaticShapes[i], in_data);
// cover Sign NAN test case
if ((activationType == utils::ActivationTypes::Sign) && targetInputStaticShapes[i].size() == 8 &&
funcInput.get_element_type() == ov::element::f32) {
static_cast<float*>(tensor.data())[0] = NAN;
}
} else {
tensor = ov::test::utils::create_and_fill_tensor(funcInput.get_element_type(), targetInputStaticShapes[i]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,14 +352,16 @@ void compare(const ov::Tensor& expected,
for (size_t i = 0; i < shape_size_cnt; ++i) {
double expected_value = expected_data[i];
double actual_value = actual_data[i];
if (std::isnan(expected_value) && std::isnan(actual_value))
continue;
if (std::isnan(expected_value)) {
std::ostringstream out_stream;
out_stream << "Expected value is NAN on coordinate: " << i;
out_stream << "Expected value is NAN but Actual value is not on coordinate: " << i;
throw std::runtime_error(out_stream.str());
}
if (std::isnan(actual_value)) {
std::ostringstream out_stream;
out_stream << "Actual value is NAN on coordinate: " << i;
out_stream << "Actual value is NAN but Expected value is not on coordinate: " << i;
throw std::runtime_error(out_stream.str());
}
double abs = std::fabs(expected_value - actual_value);
Expand Down

0 comments on commit af3be4d

Please sign in to comment.