blob: 8842d4fe9080bdfe526de1d7d8e9d38c668daca7 [file] [edit]
From 0bbbca95e69cce8793c93ab00efa96b1f82f3a78 Mon Sep 17 00:00:00 2001
From: Tommy Chiang <ototot@google.com>
Date: Wed, 9 Oct 2024 00:49:13 -0700
Subject: [PATCH] Fix inaccurate RsqrtInt16 test
ElementWise.RsqrtInt16 expects rsqrt(0.1) to be ~3.19407 from the
reference kernel, while the correct answer is ~= 3.16228. This breaks
some correctly-implemented delegates.
Fix the accuracy issue by using the right error range and the output
produced from CPU.
Note that this CL also renames some variable names for clarity.
PiperOrigin-RevId: 683924801
PATCH_NAME=dts-rsqrtint16
---
tensorflow/lite/kernels/elementwise_test.cc | 109 +++++++++++---------
1 file changed, 61 insertions(+), 48 deletions(-)
diff --git a/tensorflow/lite/kernels/elementwise_test.cc b/tensorflow/lite/kernels/elementwise_test.cc
index 57b39de3..97e42fb9 100644
--- a/tensorflow/lite/kernels/elementwise_test.cc
+++ b/tensorflow/lite/kernels/elementwise_test.cc
@@ -252,12 +252,13 @@ TEST(ElementWise, AbsInt32) {
}
TEST(ElementWise, AbsInt8) {
- std::vector<float> data = {15., 46., 78., -142., -1., -17., -49., 113.};
- std::vector<float> abs_data(data.size());
- for (int i = 0; i < abs_data.size(); i++) {
- abs_data[i] = std::abs(data[i]);
+ const std::vector<float> input_data = {15., 46., 78., -142.,
+ -1., -17., -49., 113.};
+ std::vector<float> expected_output(input_data.size());
+ for (int i = 0; i < expected_output.size(); i++) {
+ expected_output[i] = std::abs(input_data[i]);
}
- const auto minmax = std::minmax_element(data.begin(), data.end());
+ const auto minmax = std::minmax_element(input_data.begin(), input_data.end());
const float abs_max = std::max(std::abs(*minmax.first), *minmax.second);
const float kInputScale = (*minmax.second - *minmax.first) / 255.0;
const float kOutputScale = abs_max / 255.0;
@@ -275,19 +276,20 @@ TEST(ElementWise, AbsInt8) {
{kInputScale},
{input_zero_point}},
{TensorType_INT8, {1, 8}, 0, abs_max, kOutputScale, output_zero_point});
- m.AsymmetricQuantizeAndPopulate<int8_t>(m.input(), data);
+ m.AsymmetricQuantizeAndPopulate<int8_t>(m.input(), input_data);
ASSERT_EQ(m.Invoke(), kTfLiteOk);
EXPECT_THAT(m.ExtractDequantVector<int8_t>(m.output()),
- ElementsAreArray(ArrayFloatNear(abs_data, kInputScale)));
+ ElementsAreArray(ArrayFloatNear(expected_output, kInputScale)));
}
TEST(ElementWise, AbsSameScaleInt8) {
- std::vector<float> data = {15., 46., 78., -142., -1., -17., -49., 113.};
- std::vector<float> abs_data(data.size());
- for (int i = 0; i < abs_data.size(); i++) {
- abs_data[i] = std::abs(data[i]);
+ const std::vector<float> input_data = {15., 46., 78., -142.,
+ -1., -17., -49., 113.};
+ std::vector<float> expected_output(input_data.size());
+ for (int i = 0; i < expected_output.size(); i++) {
+ expected_output[i] = std::abs(input_data[i]);
}
- const auto minmax = std::minmax_element(data.begin(), data.end());
+ const auto minmax = std::minmax_element(input_data.begin(), input_data.end());
const float abs_max = std::max(std::abs(*minmax.first), *minmax.second);
const float kInputScale = (*minmax.second - *minmax.first) / 255.0;
const int input_zero_point = 127 - *minmax.second;
@@ -303,26 +305,28 @@ TEST(ElementWise, AbsSameScaleInt8) {
{kInputScale},
{input_zero_point}},
{TensorType_INT8, {1, 8}, 0, abs_max, kInputScale, input_zero_point});
- m.AsymmetricQuantizeAndPopulate<int8_t>(m.input(), data);
+ m.AsymmetricQuantizeAndPopulate<int8_t>(m.input(), input_data);
ASSERT_EQ(m.Invoke(), kTfLiteOk);
EXPECT_THAT(m.ExtractDequantVector<int8_t>(m.output()),
- ElementsAreArray(ArrayFloatNear(abs_data, kInputScale)));
+ ElementsAreArray(ArrayFloatNear(expected_output, kInputScale)));
}
TEST(ElementWise, AbsInt16) {
const float kQuantizedTolerance = GetQuantizationStep<int16_t>(-150, 150);
- std::vector<float> data = {15., 46., 78., -142., -1., -17., -49., 113.};
- std::vector<float> abs_data(data.size());
- for (int i = 0; i < abs_data.size(); i++) {
- abs_data[i] = std::abs(data[i]);
+ const std::vector<float> input_data = {15., 46., 78., -142.,
+ -1., -17., -49., 113.};
+ std::vector<float> expected_output(input_data.size());
+ for (int i = 0; i < expected_output.size(); i++) {
+ expected_output[i] = std::abs(input_data[i]);
}
ElementWiseOpQuantizedModel m(BuiltinOperator_ABS,
{TensorType_INT16, {1, 8}, -142, 142},
{TensorType_INT16, {1, 8}, -150, 150});
- m.QuantizeAndPopulate<int16_t>(m.input(), data);
+ m.QuantizeAndPopulate<int16_t>(m.input(), input_data);
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.ExtractDequantVector<int16_t>(m.output()),
- ElementsAreArray(ArrayFloatNear(abs_data, kQuantizedTolerance)));
+ EXPECT_THAT(
+ m.ExtractDequantVector<int16_t>(m.output()),
+ ElementsAreArray(ArrayFloatNear(expected_output, kQuantizedTolerance)));
}
TEST(ElementWise, Sqrt) {
@@ -344,10 +348,11 @@ TEST(ElementWise, Rsqrt) {
}
TEST(ElementWise, RsqrtInt8) {
- std::vector<float> data = {15., 46., 78., 142., 1., 17., 49., 113.};
- std::vector<float> rsqrt_data(data.size());
- for (int i = 0; i < rsqrt_data.size(); i++) {
- rsqrt_data[i] = 1.f / std::sqrt(data[i]);
+ const std::vector<float> input_data = {15., 46., 78., 142.,
+ 1., 17., 49., 113.};
+ std::vector<float> expected_output(input_data.size());
+ for (int i = 0; i < expected_output.size(); i++) {
+ expected_output[i] = 1.f / std::sqrt(input_data[i]);
}
float kInputScale = 142.0 / 255.0;
float kOutputScale = 1.0 / 255.0;
@@ -371,17 +376,18 @@ TEST(ElementWise, RsqrtInt8) {
true,
{kOutputScale},
{zero_point}});
- m.QuantizeAndPopulate<int8_t>(m.input(), data);
+ m.QuantizeAndPopulate<int8_t>(m.input(), input_data);
ASSERT_EQ(m.Invoke(), kTfLiteOk);
EXPECT_THAT(m.ExtractDequantVector<int8_t>(m.output()),
- ElementsAreArray(ArrayFloatNear(rsqrt_data, kInputScale)));
+ ElementsAreArray(ArrayFloatNear(expected_output, kInputScale)));
}
TEST(ElementWise, RsqrtCloseTo0Int8) {
- std::vector<float> data = {15., 46., 78., 142., 0.1, 1., 49., 113.};
- std::vector<float> rsqrt_data(data.size());
- for (int i = 0; i < rsqrt_data.size(); i++) {
- rsqrt_data[i] = 1.f / std::sqrt(data[i]);
+ const std::vector<float> input_data = {15., 46., 78., 142.,
+ 0.1, 1., 49., 113.};
+ std::vector<float> expected_output(input_data.size());
+ for (int i = 0; i < expected_output.size(); i++) {
+ expected_output[i] = 1.f / std::sqrt(input_data[i]);
}
float kInputScale = 142.0 / 255.0;
float kOutputScale = 3.16 / 255.0;
@@ -405,17 +411,18 @@ TEST(ElementWise, RsqrtCloseTo0Int8) {
true,
{kOutputScale},
{zero_point}});
- m.QuantizeAndPopulate<int8_t>(m.input(), data);
+ m.QuantizeAndPopulate<int8_t>(m.input(), input_data);
ASSERT_EQ(m.Invoke(), kTfLiteOk);
EXPECT_THAT(m.ExtractDequantVector<int8_t>(m.output()),
- ElementsAreArray(ArrayFloatNear(rsqrt_data, kInputScale)));
+ ElementsAreArray(ArrayFloatNear(expected_output, kInputScale)));
}
TEST(ElementWise, RsqrtNanInt8) {
- std::vector<float> data = {15., 46., 78., 142., 1., 17., -49., 113.};
- std::vector<float> rsqrt_data(data.size());
- for (int i = 0; i < rsqrt_data.size(); i++) {
- rsqrt_data[i] = 1.f / std::sqrt(data[i]);
+ const std::vector<float> input_data = {15., 46., 78., 142.,
+ 1., 17., -49., 113.};
+ std::vector<float> expected_output(input_data.size());
+ for (int i = 0; i < expected_output.size(); i++) {
+ expected_output[i] = 1.f / std::sqrt(input_data[i]);
}
float kInputScale = 142.0 / 127.0;
float kOutputScale = 1.0 / 255.0;
@@ -440,29 +447,35 @@ TEST(ElementWise, RsqrtNanInt8) {
true,
{kOutputScale},
{output_zero_point}});
- m.QuantizeAndPopulate<int8_t>(m.input(), data);
+ m.QuantizeAndPopulate<int8_t>(m.input(), input_data);
EXPECT_THAT(m.Invoke(), kTfLiteError);
}
TEST(ElementWise, RsqrtInt16) {
- const float input_min = -0.8f;
- const float input_max = 0.8f;
+ const std::vector<float> input_data = {1., 0.1, 4., 9.};
+ std::vector<float> expected_output(input_data.size());
+ for (int i = 0; i < expected_output.size(); i++) {
+ expected_output[i] = 1.f / std::sqrt(input_data[i]);
+ }
- const float output_min = -2.4f;
- const float output_max = 2.4f;
+ const float input_min = -10.;
+ const float input_max = 10.;
+
+ const float output_min = -4.;
+ const float output_max = 4.;
const float kQuantizedTolerance =
GetLUTTolerance<int16_t>(input_min, input_max, output_min, output_max);
- ElementWiseOpQuantizedModel m(BuiltinOperator_RSQRT,
- {TensorType_INT16, {1, 1, 4, 1}, -10, 10},
- {TensorType_INT16, {1, 1, 4, 1}, -10, 10});
- m.QuantizeAndPopulate<int16_t>(m.input(), {1, 0.1, 4, 9});
+ ElementWiseOpQuantizedModel m(
+ BuiltinOperator_RSQRT,
+ {TensorType_INT16, {1, 1, 4, 1}, input_min, input_max},
+ {TensorType_INT16, {1, 1, 4, 1}, output_min, output_max});
+ m.QuantizeAndPopulate<int16_t>(m.input(), input_data);
ASSERT_EQ(m.Invoke(), kTfLiteOk);
EXPECT_THAT(
m.ExtractDequantVector<int16_t>(m.output()),
- ElementsAreArray(ArrayFloatNear({1.00009, 3.19407, 0.500198, 0.333262},
- kQuantizedTolerance)));
+ ElementsAreArray(ArrayFloatNear(expected_output, kQuantizedTolerance)));
}
TEST(ElementWise, RsqrtNanInt16) {