blob: 4df984346569c79f615b645f5819e772d20bdbe6 [file] [edit]
From d9b2ca61b9a5a0afd02b48a90891a9be25f6860d Mon Sep 17 00:00:00 2001
From: TFLite Patcher <tflite@localhost>
Date: Fri, 18 Oct 2024 18:15:55 +0800
Subject: [PATCH] Backport fp16 DTS testing mode from upstream
PATCH_NAME=dts-fp16-mode
---
tensorflow/lite/kernels/BUILD | 2 +
tensorflow/lite/kernels/activations_test.cc | 56 ++++---
tensorflow/lite/kernels/add_n_test.cc | 7 +-
tensorflow/lite/kernels/add_test.cc | 17 +-
tensorflow/lite/kernels/batch_matmul_test.cc | 108 +++++++------
tensorflow/lite/kernels/cast_test.cc | 28 ++--
tensorflow/lite/kernels/ceil_test.cc | 26 ++--
tensorflow/lite/kernels/concatenation_test.cc | 9 +-
tensorflow/lite/kernels/conv_test.cc | 32 ++--
.../lite/kernels/depth_to_space_test.cc | 3 +-
tensorflow/lite/kernels/elementwise_test.cc | 9 +-
tensorflow/lite/kernels/fill_test.cc | 17 +-
tensorflow/lite/kernels/floor_test.cc | 29 ++--
tensorflow/lite/kernels/gather_nd_test.cc | 39 ++---
tensorflow/lite/kernels/l2norm_test.cc | 21 +--
.../lite/kernels/maximum_minimum_test.cc | 6 +-
tensorflow/lite/kernels/mul_test.cc | 4 +-
tensorflow/lite/kernels/neg_test.cc | 5 +-
.../lite/kernels/non_max_suppression_test.cc | 15 +-
tensorflow/lite/kernels/one_hot_test.cc | 4 +-
tensorflow/lite/kernels/pooling3d_test.cc | 15 +-
tensorflow/lite/kernels/pooling_test.cc | 35 +++--
tensorflow/lite/kernels/segment_sum_test.cc | 11 +-
tensorflow/lite/kernels/select_test.cc | 7 +-
.../lite/kernels/space_to_depth_test.cc | 6 +-
.../lite/kernels/stablehlo_min_max_test.cc | 6 +-
tensorflow/lite/kernels/sub_test.cc | 5 +-
.../lite/kernels/test_delegate_providers.cc | 11 ++
.../lite/kernels/test_delegate_providers.h | 4 +
.../kernels/test_delegate_providers_test.cc | 5 +-
tensorflow/lite/kernels/test_util.cc | 113 +++++++++++++-
tensorflow/lite/kernels/test_util.h | 29 +++-
tensorflow/lite/kernels/test_util_test.cc | 146 ++++++++++++++++++
.../lite/kernels/transpose_conv_test.cc | 69 +++++----
tensorflow/lite/kernels/zeros_like_test.cc | 2 +-
35 files changed, 637 insertions(+), 264 deletions(-)
diff --git a/tensorflow/lite/kernels/BUILD b/tensorflow/lite/kernels/BUILD
index e627daf1..e53761a4 100644
--- a/tensorflow/lite/kernels/BUILD
+++ b/tensorflow/lite/kernels/BUILD
@@ -224,6 +224,7 @@ cc_library(
"//tensorflow/lite/tools/optimize:quantization_utils",
"//tensorflow/lite/tools/versioning",
"@com_google_absl//absl/algorithm:container",
+ "@com_google_absl//absl/base",
"@com_google_absl//absl/types:span",
"@com_google_googletest//:gtest",
"@flatbuffers",
@@ -621,6 +622,7 @@ cc_test(
size = "small",
srcs = ["test_util_test.cc"],
deps = [
+ ":test_delegate_providers_lib",
":test_util",
"//tensorflow/lite:array",
"//tensorflow/lite:util",
diff --git a/tensorflow/lite/kernels/activations_test.cc b/tensorflow/lite/kernels/activations_test.cc
index 33237391..226b10e6 100644
--- a/tensorflow/lite/kernels/activations_test.cc
+++ b/tensorflow/lite/kernels/activations_test.cc
@@ -26,6 +26,7 @@ limitations under the License.
#include <utility>
#include <vector>
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "absl/memory/memory.h"
#include "flatbuffers/flatbuffers.h" // from @flatbuffers
@@ -343,10 +344,11 @@ TEST(FloatActivationsOpTest, Relu0To1) {
0.3, -2.0, 1.1, -0.1, //
});
m.Invoke();
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({
- 0.0, 0.0, 0.2, 0.0, //
- 0.3, 0.0, 1.0, 0.0, //
- }));
+ EXPECT_THAT(m.GetOutput(),
+ Pointwise(FloatingPointEq(), {
+ 0.0, 0.0, 0.2, 0.0, //
+ 0.3, 0.0, 1.0, 0.0, //
+ }));
}
TEST(FloatActivationsOpTest, Relu1) {
@@ -357,10 +359,11 @@ TEST(FloatActivationsOpTest, Relu1) {
0.3, -2.0, 1.1, -0.1, //
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({
- 0.0, -0.6, 0.2, -0.4, //
- 0.3, -1.0, 1.0, -0.1, //
- }));
+ EXPECT_THAT(m.GetOutput(),
+ Pointwise(FloatingPointEq(), {
+ 0.0, -0.6, 0.2, -0.4, //
+ 0.3, -1.0, 1.0, -0.1, //
+ }));
}
TEST(FloatActivationsOpTest, Relu6) {
@@ -2476,12 +2479,14 @@ TEST_P(PReluOpTest, PReluFloat32) {
});
m.SetAlpha({0.0f, 1.0f, 2.0f});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({
- 0.0f, 0.0f, 0.0f, // Row 1, Column 1
- 1.0f, 1.0f, 1.0f, // Row 1, Column 2
- 0.0f, -1.0f, -2.0f, // Row 2, Column 1
- 0.0f, -2.0f, -4.0f, // Row 2, Column 2
- }));
+ EXPECT_THAT(
+ m.GetOutput(),
+ Pointwise(FloatingPointEq(), {
+ 0.0f, 0.0f, 0.0f, // Row 1, Column 1
+ 1.0f, 1.0f, 1.0f, // Row 1, Column 2
+ 0.0f, -1.0f, -2.0f, // Row 2, Column 1
+ 0.0f, -2.0f, -4.0f, // Row 2, Column 2
+ }));
}
TEST_P(PReluOpTest, PReluFloat32SameShapes) {
@@ -2501,12 +2506,14 @@ TEST_P(PReluOpTest, PReluFloat32SameShapes) {
0.0f, 1.0f, 2.0f, // Row 2, Column 2
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({
- 0.0f, 0.0f, 0.0f, // Row 1, Column 1
- 1.0f, 1.0f, 1.0f, // Row 1, Column 2
- 0.0f, -1.0f, -2.0f, // Row 2, Column 1
- 0.0f, -2.0f, -4.0f, // Row 2, Column 2
- }));
+ EXPECT_THAT(
+ m.GetOutput(),
+ Pointwise(FloatingPointEq(), {
+ 0.0f, 0.0f, 0.0f, // Row 1, Column 1
+ 1.0f, 1.0f, 1.0f, // Row 1, Column 2
+ 0.0f, -1.0f, -2.0f, // Row 2, Column 1
+ 0.0f, -2.0f, -4.0f, // Row 2, Column 2
+ }));
}
TEST_P(PReluOpTest, PReluUInt8) {
@@ -2661,10 +2668,11 @@ TEST(FloatActivationsOpTest, LeakyRelu) {
1.0f, -1.0f, -2.0f, // Row 2
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({
- 0.0f, 1.0f, 3.0f, // Row 1
- 1.0f, -0.5f, -1.0f, // Row 2
- }));
+ EXPECT_THAT(m.GetOutput(),
+ Pointwise(FloatingPointEq(), {
+ 0.0f, 1.0f, 3.0f, // Row 1
+ 1.0f, -0.5f, -1.0f, // Row 2
+ }));
}
class GeluOpModel : public SingleOpModel {
diff --git a/tensorflow/lite/kernels/add_n_test.cc b/tensorflow/lite/kernels/add_n_test.cc
index 62173427..c77fc448 100644
--- a/tensorflow/lite/kernels/add_n_test.cc
+++ b/tensorflow/lite/kernels/add_n_test.cc
@@ -16,6 +16,7 @@ limitations under the License.
#include <vector>
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "flatbuffers/flatbuffers.h" // from @flatbuffers
#include "tensorflow/lite/kernels/add_n_test_common.h"
@@ -36,7 +37,8 @@ TEST(FloatAddNOpModel, AddMultipleTensors) {
m.PopulateTensor<float>(m.input(1), {0.1, 0.2, 0.3, 0.5});
m.PopulateTensor<float>(m.input(2), {0.5, 0.1, 0.1, 0.2});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({-1.4, 0.5, 1.1, 1.5}));
+ EXPECT_THAT(m.GetOutput(),
+ Pointwise(FloatingPointEq(), {-1.4, 0.5, 1.1, 1.5}));
}
TEST(FloatAddNOpModel, Add2Tensors) {
@@ -46,7 +48,8 @@ TEST(FloatAddNOpModel, Add2Tensors) {
m.PopulateTensor<float>(m.input(0), {-2.0, 0.2, 0.7, 0.8});
m.PopulateTensor<float>(m.input(1), {0.1, 0.2, 0.3, 0.5});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({-1.9, 0.4, 1.0, 1.3}));
+ EXPECT_THAT(m.GetOutput(),
+ Pointwise(FloatingPointEq(), {-1.9, 0.4, 1.0, 1.3}));
}
TEST(IntegerAddNOpModel, AddMultipleTensors) {
diff --git a/tensorflow/lite/kernels/add_test.cc b/tensorflow/lite/kernels/add_test.cc
index ba5f1a1e..ffb21ecf 100644
--- a/tensorflow/lite/kernels/add_test.cc
+++ b/tensorflow/lite/kernels/add_test.cc
@@ -22,6 +22,7 @@ limitations under the License.
#include <utility>
#include <vector>
+#include <gmock/gmock.h>
#include "flatbuffers/flatbuffers.h" // from @flatbuffers
#include "tensorflow/lite/kernels/test_util.h"
#include "tensorflow/lite/schema/schema_generated.h"
@@ -143,7 +144,8 @@ TEST(FloatAddOpModel, NoActivationInplaceInput0) {
TfLiteTensor* output_tensor = m.GetOutputTensor(kInplaceOutputTensorIdx);
output_tensor->data.data = input_tensor->data.data;
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({-1.9, 0.4, 1.0, 1.3}));
+ EXPECT_THAT(m.GetOutput(),
+ Pointwise(FloatingPointEq(), {-1.9, 0.4, 1.0, 1.3}));
EXPECT_EQ(output_tensor->data.data, input_tensor->data.data);
}
@@ -159,7 +161,8 @@ TEST(FloatAddOpModel, NoActivationInplaceInput1) {
TfLiteTensor* output_tensor = m.GetOutputTensor(kInplaceOutputTensorIdx);
output_tensor->data.data = input_tensor->data.data;
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({-1.9, 0.4, 1.0, 1.3}));
+ EXPECT_THAT(m.GetOutput(),
+ Pointwise(FloatingPointEq(), {-1.9, 0.4, 1.0, 1.3}));
EXPECT_EQ(output_tensor->data.data, input_tensor->data.data);
}
@@ -170,7 +173,8 @@ TEST(FloatAddOpModel, NoActivation) {
m.PopulateTensor<float>(m.input1(), {-2.0, 0.2, 0.7, 0.8});
m.PopulateTensor<float>(m.input2(), {0.1, 0.2, 0.3, 0.5});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({-1.9, 0.4, 1.0, 1.3}));
+ EXPECT_THAT(m.GetOutput(),
+ Pointwise(FloatingPointEq(), {-1.9, 0.4, 1.0, 1.3}));
}
TEST(FloatAddOpModel, ActivationRELU_N1_TO_1) {
@@ -180,7 +184,8 @@ TEST(FloatAddOpModel, ActivationRELU_N1_TO_1) {
m.PopulateTensor<float>(m.input1(), {-2.0, 0.2, 0.7, 0.8});
m.PopulateTensor<float>(m.input2(), {0.1, 0.2, 0.3, 0.5});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({-1.0, 0.4, 1.0, 1.0}));
+ EXPECT_THAT(m.GetOutput(),
+ Pointwise(FloatingPointEq(), {-1.0, 0.4, 1.0, 1.0}));
}
TEST(FloatAddOpModel, VariousInputShapes) {
@@ -194,7 +199,7 @@ TEST(FloatAddOpModel, VariousInputShapes) {
m.PopulateTensor<float>(m.input2(), {0.1, 0.2, 0.3, 0.5, 1.1, 0.1});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
EXPECT_THAT(m.GetOutput(),
- ElementsAreArray({-1.9, 0.4, 1.0, 1.3, 2.2, 2.1}))
+ Pointwise(FloatingPointEq(), {-1.9, 0.4, 1.0, 1.3, 2.2, 2.1}))
<< "With shape number " << i;
}
}
@@ -363,7 +368,7 @@ void TestFloatBroadcast(std::vector<int> input1_shape,
m.PopulateTensor<float>(m.input1(), input1);
m.PopulateTensor<float>(m.input2(), input2);
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), testing::ContainerEq(output_ref));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), output_ref));
}
template <typename IntegerType>
diff --git a/tensorflow/lite/kernels/batch_matmul_test.cc b/tensorflow/lite/kernels/batch_matmul_test.cc
index 4b449757..7f5e2848 100644
--- a/tensorflow/lite/kernels/batch_matmul_test.cc
+++ b/tensorflow/lite/kernels/batch_matmul_test.cc
@@ -137,7 +137,8 @@ TEST_P(BatchMatMulOpTest, Float32Test_Simple) {
{7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18});
ASSERT_EQ(model.Invoke(), kTfLiteOk);
EXPECT_THAT(model.GetOutput(),
- ElementsAreArray({74., 80., 86., 92., 173., 188., 203., 218.}));
+ Pointwise(FloatingPointEq(),
+ {74., 80., 86., 92., 173., 188., 203., 218.}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({1, 2, 4}));
}
@@ -174,7 +175,8 @@ TEST_P(BatchMatMulOpTest, Float32Test_SimpleRHSAdjoint) {
{7, 11, 15, 8, 12, 16, 9, 13, 17, 10, 14, 18});
ASSERT_EQ(model.Invoke(), kTfLiteOk);
EXPECT_THAT(model.GetOutput(),
- ElementsAreArray({74., 80., 86., 92., 173., 188., 203., 218.}));
+ Pointwise(FloatingPointEq(),
+ {74., 80., 86., 92., 173., 188., 203., 218.}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({1, 2, 4}));
}
@@ -186,7 +188,8 @@ TEST_P(BatchMatMulOpTest, Float32Test_SimpleLHSAdjoint) {
{7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18});
ASSERT_EQ(model.Invoke(), kTfLiteOk);
EXPECT_THAT(model.GetOutput(),
- ElementsAreArray({74., 80., 86., 92., 173., 188., 203., 218.}));
+ Pointwise(FloatingPointEq(),
+ {74., 80., 86., 92., 173., 188., 203., 218.}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({1, 2, 4}));
}
@@ -199,10 +202,10 @@ TEST_P(BatchMatMulOpTest, Float32Test_BatchSizeTwo) {
{7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30});
ASSERT_EQ(model.Invoke(), kTfLiteOk);
- EXPECT_THAT(
- model.GetOutput(),
- ElementsAreArray({74., 80., 86., 92., 173., 188., 203., 218., 560., 584.,
- 608., 632., 767., 800., 833., 866.}));
+ EXPECT_THAT(model.GetOutput(),
+ Pointwise(FloatingPointEq(),
+ {74., 80., 86., 92., 173., 188., 203., 218., 560., 584.,
+ 608., 632., 767., 800., 833., 866.}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({2, 2, 4}));
}
@@ -215,10 +218,10 @@ TEST_P(BatchMatMulOpTest, Float32Test_Broadcast) {
{7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18});
ASSERT_EQ(model.Invoke(), kTfLiteOk);
- EXPECT_THAT(
- model.GetOutput(),
- ElementsAreArray({74., 80., 86., 92., 173., 188., 203., 218., 272., 296.,
- 320., 344., 371., 404., 437., 470.}));
+ EXPECT_THAT(model.GetOutput(),
+ Pointwise(FloatingPointEq(),
+ {74., 80., 86., 92., 173., 188., 203., 218., 272., 296.,
+ 320., 344., 371., 404., 437., 470.}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({2, 2, 4}));
}
@@ -231,10 +234,10 @@ TEST_P(BatchMatMulOpTest, Float32Test_BroadcastLHSAdjoint) {
{7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18});
ASSERT_EQ(model.Invoke(), kTfLiteOk);
- EXPECT_THAT(
- model.GetOutput(),
- ElementsAreArray({74., 80., 86., 92., 173., 188., 203., 218., 272., 296.,
- 320., 344., 371., 404., 437., 470.}));
+ EXPECT_THAT(model.GetOutput(),
+ Pointwise(FloatingPointEq(),
+ {74., 80., 86., 92., 173., 188., 203., 218., 272., 296.,
+ 320., 344., 371., 404., 437., 470.}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({2, 2, 4}));
}
@@ -250,14 +253,15 @@ TEST_P(BatchMatMulOpTest, Float32Test_Broadcast2) {
ASSERT_EQ(model.Invoke(), kTfLiteOk);
EXPECT_THAT(
model.GetOutput(),
- ElementsAreArray({29., 32., 35., 38., 65., 72., 79., 86., 101.,
- 112., 123., 134., 53., 56., 59., 62., 121., 128.,
- 135., 142., 189., 200., 211., 222., 77., 80., 83.,
- 86., 177., 184., 191., 198., 277., 288., 299., 310.,
- 137., 152., 167., 182., 173., 192., 211., 230., 209.,
- 232., 255., 278., 257., 272., 287., 302., 325., 344.,
- 363., 382., 393., 416., 439., 462., 377., 392., 407.,
- 422., 477., 496., 515., 534., 577., 600., 623., 646.}));
+ Pointwise(
+ FloatingPointEq(),
+ {29., 32., 35., 38., 65., 72., 79., 86., 101., 112., 123.,
+ 134., 53., 56., 59., 62., 121., 128., 135., 142., 189., 200.,
+ 211., 222., 77., 80., 83., 86., 177., 184., 191., 198., 277.,
+ 288., 299., 310., 137., 152., 167., 182., 173., 192., 211., 230.,
+ 209., 232., 255., 278., 257., 272., 287., 302., 325., 344., 363.,
+ 382., 393., 416., 439., 462., 377., 392., 407., 422., 477., 496.,
+ 515., 534., 577., 600., 623., 646.}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({2, 3, 3, 4}));
}
@@ -274,14 +278,15 @@ TEST_P(BatchMatMulOpTest, Float32Test_Broadcast2LHSAdjoint) {
ASSERT_EQ(model.Invoke(), kTfLiteOk);
EXPECT_THAT(
model.GetOutput(),
- ElementsAreArray({29., 32., 35., 38., 65., 72., 79., 86., 101.,
- 112., 123., 134., 53., 56., 59., 62., 121., 128.,
- 135., 142., 189., 200., 211., 222., 77., 80., 83.,
- 86., 177., 184., 191., 198., 277., 288., 299., 310.,
- 137., 152., 167., 182., 173., 192., 211., 230., 209.,
- 232., 255., 278., 257., 272., 287., 302., 325., 344.,
- 363., 382., 393., 416., 439., 462., 377., 392., 407.,
- 422., 477., 496., 515., 534., 577., 600., 623., 646.}));
+ Pointwise(
+ FloatingPointEq(),
+ {29., 32., 35., 38., 65., 72., 79., 86., 101., 112., 123.,
+ 134., 53., 56., 59., 62., 121., 128., 135., 142., 189., 200.,
+ 211., 222., 77., 80., 83., 86., 177., 184., 191., 198., 277.,
+ 288., 299., 310., 137., 152., 167., 182., 173., 192., 211., 230.,
+ 209., 232., 255., 278., 257., 272., 287., 302., 325., 344., 363.,
+ 382., 393., 416., 439., 462., 377., 392., 407., 422., 477., 496.,
+ 515., 534., 577., 600., 623., 646.}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({2, 3, 3, 4}));
}
@@ -297,14 +302,15 @@ TEST_P(BatchMatMulOpTest, Float32Test_Broadcast2RHSAdjoint) {
ASSERT_EQ(model.Invoke(), kTfLiteOk);
EXPECT_THAT(
model.GetOutput(),
- ElementsAreArray({29., 32., 35., 38., 65., 72., 79., 86., 101.,
- 112., 123., 134., 53., 56., 59., 62., 121., 128.,
- 135., 142., 189., 200., 211., 222., 77., 80., 83.,
- 86., 177., 184., 191., 198., 277., 288., 299., 310.,
- 137., 152., 167., 182., 173., 192., 211., 230., 209.,
- 232., 255., 278., 257., 272., 287., 302., 325., 344.,
- 363., 382., 393., 416., 439., 462., 377., 392., 407.,
- 422., 477., 496., 515., 534., 577., 600., 623., 646.}));
+ Pointwise(
+ FloatingPointEq(),
+ {29., 32., 35., 38., 65., 72., 79., 86., 101., 112., 123.,
+ 134., 53., 56., 59., 62., 121., 128., 135., 142., 189., 200.,
+ 211., 222., 77., 80., 83., 86., 177., 184., 191., 198., 277.,
+ 288., 299., 310., 137., 152., 167., 182., 173., 192., 211., 230.,
+ 209., 232., 255., 278., 257., 272., 287., 302., 325., 344., 363.,
+ 382., 393., 416., 439., 462., 377., 392., 407., 422., 477., 496.,
+ 515., 534., 577., 600., 623., 646.}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({2, 3, 3, 4}));
}
@@ -320,14 +326,15 @@ TEST_P(BatchMatMulOpTest, Float32Test_Broadcast2BothAdjoint) {
ASSERT_EQ(model.Invoke(), kTfLiteOk);
EXPECT_THAT(
model.GetOutput(),
- ElementsAreArray({29., 32., 35., 38., 65., 72., 79., 86., 101.,
- 112., 123., 134., 53., 56., 59., 62., 121., 128.,
- 135., 142., 189., 200., 211., 222., 77., 80., 83.,
- 86., 177., 184., 191., 198., 277., 288., 299., 310.,
- 137., 152., 167., 182., 173., 192., 211., 230., 209.,
- 232., 255., 278., 257., 272., 287., 302., 325., 344.,
- 363., 382., 393., 416., 439., 462., 377., 392., 407.,
- 422., 477., 496., 515., 534., 577., 600., 623., 646.}));
+ Pointwise(
+ FloatingPointEq(),
+ {29., 32., 35., 38., 65., 72., 79., 86., 101., 112., 123.,
+ 134., 53., 56., 59., 62., 121., 128., 135., 142., 189., 200.,
+ 211., 222., 77., 80., 83., 86., 177., 184., 191., 198., 277.,
+ 288., 299., 310., 137., 152., 167., 182., 173., 192., 211., 230.,
+ 209., 232., 255., 278., 257., 272., 287., 302., 325., 344., 363.,
+ 382., 393., 416., 439., 462., 377., 392., 407., 422., 477., 496.,
+ 515., 534., 577., 600., 623., 646.}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({2, 3, 3, 4}));
}
@@ -346,9 +353,10 @@ TEST_P(BatchMatMulOpTest, Float32Test_BroadcastFromRHS) {
ASSERT_EQ(model.Invoke(), kTfLiteOk);
EXPECT_THAT(
model.GetOutput(),
- ElementsAreArray({185., 200., 460., 500., 735., 800., 1010., 1100.,
- 335., 350., 860., 900., 1385., 1450., 1910., 2000.,
- 485., 500., 1260., 1300., 2035., 2100., 2810., 2900.}));
+ Pointwise(FloatingPointEq(),
+ {185., 200., 460., 500., 735., 800., 1010., 1100.,
+ 335., 350., 860., 900., 1385., 1450., 1910., 2000.,
+ 485., 500., 1260., 1300., 2035., 2100., 2810., 2900.}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({3, 1, 4, 2}));
}
diff --git a/tensorflow/lite/kernels/cast_test.cc b/tensorflow/lite/kernels/cast_test.cc
index 4e03e956..7cd4e498 100644
--- a/tensorflow/lite/kernels/cast_test.cc
+++ b/tensorflow/lite/kernels/cast_test.cc
@@ -40,7 +40,7 @@ TEST(CastOpModel, CastInt4ToFloat) {
m.Set4BitInput({1, 2, 3, 4, 5, 6});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
EXPECT_THAT(m.ExtractVector<float>(m.output()),
- ElementsAreArray({1.f, 2.f, 3.f, 4.f, 5.f, 6.f}));
+ Pointwise(FloatingPointEq(), {1.f, 2.f, 3.f, 4.f, 5.f, 6.f}));
}
TEST(CastOpModel, CastInt4ToFloatLarge) {
@@ -82,8 +82,9 @@ TEST(CastOpModel, CastInt16ToFloat) {
CastOpModel m({TensorType_INT16, {2, 3}}, {TensorType_FLOAT32, {2, 3}});
m.PopulateTensor<int16_t>(m.input(), {100, 200, 300, 400, 500, 600});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.ExtractVector<float>(m.output()),
- ElementsAreArray({100.f, 200.f, 300.f, 400.f, 500.f, 600.f}));
+ EXPECT_THAT(
+ m.ExtractVector<float>(m.output()),
+ Pointwise(FloatingPointEq(), {100.f, 200.f, 300.f, 400.f, 500.f, 600.f}));
}
TEST(CastOpModel, CastInt16ToInt32) {
@@ -98,8 +99,9 @@ TEST(CastOpModel, CastInt32ToFloat) {
CastOpModel m({TensorType_INT32, {2, 3}}, {TensorType_FLOAT32, {2, 3}});
m.PopulateTensor<int32_t>(m.input(), {100, 200, 300, 400, 500, 600});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.ExtractVector<float>(m.output()),
- ElementsAreArray({100.f, 200.f, 300.f, 400.f, 500.f, 600.f}));
+ EXPECT_THAT(
+ m.ExtractVector<float>(m.output()),
+ Pointwise(FloatingPointEq(), {100.f, 200.f, 300.f, 400.f, 500.f, 600.f}));
}
TEST(CastOpModel, CastFloatToInt32) {
@@ -122,8 +124,9 @@ TEST(CastOpModel, CastInt64ToFloat) {
CastOpModel m({TensorType_INT64, {2, 3}}, {TensorType_FLOAT32, {2, 3}});
m.PopulateTensor<int64_t>(m.input(), {100, 200, 300, 400, 500, 600});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.ExtractVector<float>(m.output()),
- ElementsAreArray({100.f, 200.f, 300.f, 400.f, 500.f, 600.f}));
+ EXPECT_THAT(
+ m.ExtractVector<float>(m.output()),
+ Pointwise(FloatingPointEq(), {100.f, 200.f, 300.f, 400.f, 500.f, 600.f}));
}
TEST(CastOpModel, CastFloatToInt64) {
@@ -147,7 +150,7 @@ TEST(CastOpModel, CastBoolToFloat) {
m.PopulateTensor<bool>(m.input(), {true, true, false, true, false, true});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
EXPECT_THAT(m.ExtractVector<float>(m.output()),
- ElementsAreArray({1.f, 1.0f, 0.f, 1.0f, 0.0f, 1.0f}));
+ Pointwise(FloatingPointEq(), {1.f, 1.0f, 0.f, 1.0f, 0.0f, 1.0f}));
}
TEST(CastOpModel, CastFloatToUInt8) {
@@ -163,7 +166,7 @@ TEST(CastOpModel, CastUInt8ToFloat) {
m.PopulateTensor<uint8_t>(m.input(), {123, 0, 1, 2, 3, 4});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
EXPECT_THAT(m.ExtractVector<float>(m.output()),
- ElementsAreArray({123.f, 0.f, 1.f, 2.f, 3.f, 4.f}));
+ Pointwise(FloatingPointEq(), {123.f, 0.f, 1.f, 2.f, 3.f, 4.f}));
}
TEST(CastOpModel, CastFloatToUInt16) {
@@ -179,7 +182,7 @@ TEST(CastOpModel, CastUInt16ToFloat) {
m.PopulateTensor<uint16_t>(m.input(), {123, 0, 1, 2, 3, 4});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
EXPECT_THAT(m.ExtractVector<float>(m.output()),
- ElementsAreArray({123.f, 0.f, 1.f, 2.f, 3.f, 4.f}));
+ Pointwise(FloatingPointEq(), {123.f, 0.f, 1.f, 2.f, 3.f, 4.f}));
}
TEST(CastOpModel, CastInt32ToUInt8) {
@@ -206,8 +209,9 @@ TEST(CastOpModel, CastComplex64ToFloat) {
std::complex<float>(3.0f, 13.0f), std::complex<float>(4.0f, 14.0f),
std::complex<float>(5.0f, 15.0f), std::complex<float>(6.0f, 16.0f)});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.ExtractVector<float>(m.output()),
- ElementsAreArray({1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}));
+ EXPECT_THAT(
+ m.ExtractVector<float>(m.output()),
+ Pointwise(FloatingPointEq(), {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}));
}
TEST(CastOpModel, CastFloatToComplex64) {
diff --git a/tensorflow/lite/kernels/ceil_test.cc b/tensorflow/lite/kernels/ceil_test.cc
index b1dfa38b..e16012b0 100644
--- a/tensorflow/lite/kernels/ceil_test.cc
+++ b/tensorflow/lite/kernels/ceil_test.cc
@@ -57,21 +57,21 @@ TEST(CeilOpTest, SingleDim) {
TEST(CeilOpTest, MultiDims) {
CeilOpModel model({2, 1, 1, 5}, TensorType_FLOAT32);
- model.PopulateTensor<float>(model.input(), {
- 0.0001,
- 8.0001,
- 0.9999,
- 9.9999,
- 0.5,
- -0.0001,
- -8.0001,
- -0.9999,
- -9.9999,
- -0.5,
- });
+ std::vector<float> input;
+ if (AllowFp16PrecisionForFp32()) {
+ input = {
+ 0.01, 8.01, 0.99, 9.99, 0.5, -0.01, -8.01, -0.99, -9.99, -0.5,
+ };
+ } else {
+ input = {
+ 0.0001, 8.0001, 0.9999, 9.9999, 0.5,
+ -0.0001, -8.0001, -0.9999, -9.9999, -0.5,
+ };
+ }
+ model.PopulateTensor<float>(model.input(), input);
ASSERT_EQ(model.Invoke(), kTfLiteOk);
EXPECT_THAT(model.GetOutput(),
- ElementsAreArray({1, 9, 1, 10, 1, 0, -8, 0, -9, 0}));
+ Pointwise(FloatingPointEq(), {1, 9, 1, 10, 1, 0, -8, 0, -9, 0}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({2, 1, 1, 5}));
}
diff --git a/tensorflow/lite/kernels/concatenation_test.cc b/tensorflow/lite/kernels/concatenation_test.cc
index a5b4a3cf..685abd5d 100644
--- a/tensorflow/lite/kernels/concatenation_test.cc
+++ b/tensorflow/lite/kernels/concatenation_test.cc
@@ -379,10 +379,11 @@ TEST(ConcatenationOpTest, FourInputs) {
m0.SetInput(3, {1.3f, 3.3f, 4.3f, 7.3f});
ASSERT_EQ(m0.Invoke(), kTfLiteOk);
EXPECT_THAT(m0.GetOutput(),
- ElementsAreArray({
- 1.0f, 3.0f, 1.1f, 3.1f, 1.2f, 3.2f, 1.3f, 3.3f, //
- 4.0f, 7.0f, 4.1f, 7.1f, 4.2f, 7.2f, 4.3f, 7.3f, //
- }));
+ Pointwise(FloatingPointEq(),
+ {
+ 1.0f, 3.0f, 1.1f, 3.1f, 1.2f, 3.2f, 1.3f, 3.3f, //
+ 4.0f, 7.0f, 4.1f, 7.1f, 4.2f, 7.2f, 4.3f, 7.3f, //
+ }));
}
TEST(ConcatenationOpTest, FourInputsUInt32) {
diff --git a/tensorflow/lite/kernels/conv_test.cc b/tensorflow/lite/kernels/conv_test.cc
index 634c77d5..6fe08679 100644
--- a/tensorflow/lite/kernels/conv_test.cc
+++ b/tensorflow/lite/kernels/conv_test.cc
@@ -463,14 +463,16 @@ TEST_P(ConvolutionOpTest, PointwiseFloat32) {
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({
- // First batch
- 1.5, 1.5, 1.5, 1.5, // row = 1
- 3., 3., 3., 3., // row = 2
- // Second batch
- 1.5, 3., 4.5, 6., // row = 1
- 1.5, 3., 4.5, 6., // row = 2
- }));
+ EXPECT_THAT(m.GetOutput(),
+ Pointwise(FloatingPointEq(), {
+ // First batch
+ 1.5, 1.5, 1.5, 1.5, // row = 1
+ 3., 3., 3., 3., // row = 2
+
+ // Second batch
+ 1.5, 3., 4.5, 6., // row = 1
+ 1.5, 3., 4.5, 6., // row = 2
+ }));
}
// TODO(alanchiao): this passes locally, but fails on continuous build system.
@@ -497,12 +499,14 @@ TEST_P(ConvolutionOpTest, DISABLED_PointwiseMultifilterFloat32) {
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(),
- ElementsAreArray({
- 1.5, 2.5, 1.5, 2.5, 1.5, 2.5, 1.5, 2.5, 3., 5., 3.,
- 5., 3., 5., 3., 5., 1.5, 2.5, 3., 5., 4.5, 7.5,
- 6., 10., 1.5, 2.5, 3., 5., 4.5, 7.5, 6., 10.,
- }));
+ EXPECT_THAT(
+ m.GetOutput(),
+ Pointwise(FloatingPointEq(),
+ {
+ 1.5, 2.5, 1.5, 2.5, 1.5, 2.5, 1.5, 2.5, 3., 5., 3.,
+ 5., 3., 5., 3., 5., 1.5, 2.5, 3., 5., 4.5, 7.5,
+ 6., 10., 1.5, 2.5, 3., 5., 4.5, 7.5, 6., 10.,
+ }));
}
TEST_P(ConvolutionOpTest, SimpleTestFloat32WithAnisotropicStrides) {
diff --git a/tensorflow/lite/kernels/depth_to_space_test.cc b/tensorflow/lite/kernels/depth_to_space_test.cc
index 33a07561..35897d8b 100644
--- a/tensorflow/lite/kernels/depth_to_space_test.cc
+++ b/tensorflow/lite/kernels/depth_to_space_test.cc
@@ -71,7 +71,8 @@ TEST(DepthToSpaceOpModel, Float32) {
DepthToSpaceOpModel m({TensorType_FLOAT32, {1, 1, 1, 4}}, 2);
m.SetInput<float>({1.4, 2.3, 3.2, 4.1});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput<float>(), ElementsAreArray({1.4, 2.3, 3.2, 4.1}));
+ EXPECT_THAT(m.GetOutput<float>(),
+ Pointwise(FloatingPointEq(), {1.4, 2.3, 3.2, 4.1}));
EXPECT_THAT(m.GetOutputShape(), ElementsAre(1, 2, 2, 1));
}
diff --git a/tensorflow/lite/kernels/elementwise_test.cc b/tensorflow/lite/kernels/elementwise_test.cc
index 520cc9f2..57b39de3 100644
--- a/tensorflow/lite/kernels/elementwise_test.cc
+++ b/tensorflow/lite/kernels/elementwise_test.cc
@@ -231,10 +231,11 @@ TEST(ElementWise, Abs) {
3.f, -2.f, 10.f, 1.f, //
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.ExtractVector<float>(m.output()), ElementsAreArray({
- 0.f, 6.2f, 2.f, 4.f, //
- 3.f, 2.f, 10.f, 1.f, //
- }));
+ EXPECT_THAT(m.ExtractVector<float>(m.output()),
+ Pointwise(FloatingPointEq(), {
+ 0.f, 6.2f, 2.f, 4.f, //
+ 3.f, 2.f, 10.f, 1.f, //
+ }));
}
TEST(ElementWise, AbsInt32) {
diff --git a/tensorflow/lite/kernels/fill_test.cc b/tensorflow/lite/kernels/fill_test.cc
index 90828a52..028623e3 100644
--- a/tensorflow/lite/kernels/fill_test.cc
+++ b/tensorflow/lite/kernels/fill_test.cc
@@ -132,8 +132,9 @@ TEST_P(FillOpTest, FillFloat) {
FillOpModel<int64_t, float> m(TensorType_INT64, {3}, {2, 2, 2}, 4.0,
GetParam());
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(),
- ElementsAreArray({4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0}));
+ EXPECT_THAT(
+ m.GetOutput(),
+ Pointwise(FloatingPointEq(), {4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0}));
EXPECT_THAT(m.GetOutputShape(), ElementsAreArray({2, 2, 2}));
}
@@ -141,8 +142,9 @@ TEST_P(FillOpTest, FillFloat16) {
FillOpModel<int64_t, Eigen::half> m(TensorType_INT64, {3}, {2, 2, 2},
Eigen::half(4.0f), GetParam());
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(),
- ElementsAreArray({4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0}));
+ EXPECT_THAT(
+ m.GetOutput(),
+ Pointwise(FloatingPointEq(), {4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0}));
EXPECT_THAT(m.GetOutputShape(), ElementsAreArray({2, 2, 2}));
}
@@ -150,15 +152,16 @@ TEST_P(FillOpTest, FillFloatInt32Dims) {
FillOpModel<int32_t, float> m(TensorType_INT32, {3}, {2, 2, 2}, 4.0,
GetParam());
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(),
- ElementsAreArray({4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0}));
+ EXPECT_THAT(
+ m.GetOutput(),
+ Pointwise(FloatingPointEq(), {4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0}));
EXPECT_THAT(m.GetOutputShape(), ElementsAreArray({2, 2, 2}));
}
TEST_P(FillOpTest, FillOutputScalar) {
FillOpModel<int64_t, float> m(TensorType_INT64, {0}, {}, 4.0, GetParam());
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({4.0}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {4.0}));
EXPECT_THAT(m.GetOutputShape(), IsEmpty());
}
diff --git a/tensorflow/lite/kernels/floor_test.cc b/tensorflow/lite/kernels/floor_test.cc
index 9a259372..5e51ca12 100644
--- a/tensorflow/lite/kernels/floor_test.cc
+++ b/tensorflow/lite/kernels/floor_test.cc
@@ -57,21 +57,22 @@ TEST(FloorOpTest, SingleDim) {
TEST(FloorOpTest, MultiDims) {
FloorOpModel model({2, 1, 1, 5}, TensorType_FLOAT32);
- model.PopulateTensor<float>(model.input(), {
- 0.0001,
- 8.0001,
- 0.9999,
- 9.9999,
- 0.5,
- -0.0001,
- -8.0001,
- -0.9999,
- -9.9999,
- -0.5,
- });
+ std::vector<float> input;
+ if (AllowFp16PrecisionForFp32()) {
+ input = {
+ 0.01, 8.01, 0.99, 9.99, 0.5, -0.01, -8.01, -0.99, -9.99, -0.5,
+ };
+ } else {
+ input = {
+ 0.0001, 8.0001, 0.9999, 9.9999, 0.5,
+ -0.0001, -8.0001, -0.9999, -9.9999, -0.5,
+ };
+ }
+ model.PopulateTensor<float>(model.input(), input);
ASSERT_EQ(model.Invoke(), kTfLiteOk);
- EXPECT_THAT(model.GetOutput(),
- ElementsAreArray({0, 8, 0, 9, 0, -1, -9, -1, -10, -1}));
+ EXPECT_THAT(
+ model.GetOutput(),
+ Pointwise(FloatingPointEq(), {0, 8, 0, 9, 0, -1, -9, -1, -10, -1}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({2, 1, 1, 5}));
}
diff --git a/tensorflow/lite/kernels/gather_nd_test.cc b/tensorflow/lite/kernels/gather_nd_test.cc
index ee26b14f..f1c5aac8 100644
--- a/tensorflow/lite/kernels/gather_nd_test.cc
+++ b/tensorflow/lite/kernels/gather_nd_test.cc
@@ -70,7 +70,7 @@ TEST(GatherNdOpTest, ElementIndexingIntoMatrix) {
m.SetPositions<int32_t>({0, 0, 1, 1});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput<float>(), ElementsAreArray({1.1, 2.2}));
+ EXPECT_THAT(m.GetOutput<float>(), Pointwise(FloatingPointEq(), {1.1, 2.2}));
}
TEST(GatherNdOpTest, ErrorOnOutOfBoundsTooLarge) {
@@ -95,7 +95,8 @@ TEST(GatherNdOpTest, SliceIndexingIntoMatrix) {
m.SetPositions<int32_t>({1, 0});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput<float>(), ElementsAreArray({2.1, 2.2, 1.1, 1.2}));
+ EXPECT_THAT(m.GetOutput<float>(),
+ Pointwise(FloatingPointEq(), {2.1, 2.2, 1.1, 1.2}));
}
TEST(GatherNdOpTest, BatchedIndexingIntoMatrix1) {
@@ -105,7 +106,8 @@ TEST(GatherNdOpTest, BatchedIndexingIntoMatrix1) {
m.SetPositions<int32_t>({1, 0});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput<float>(), ElementsAreArray({2.1, 2.2, 1.1, 1.2}));
+ EXPECT_THAT(m.GetOutput<float>(),
+ Pointwise(FloatingPointEq(), {2.1, 2.2, 1.1, 1.2}));
}
TEST(GatherNdOpTest, BatchedIndexingIntoMatrix2) {
@@ -115,7 +117,7 @@ TEST(GatherNdOpTest, BatchedIndexingIntoMatrix2) {
m.SetPositions<int32_t>({0, 0, 1, 1});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput<float>(), ElementsAreArray({1.1, 2.2}));
+ EXPECT_THAT(m.GetOutput<float>(), Pointwise(FloatingPointEq(), {1.1, 2.2}));
}
TEST(GatherNdOpTest, DuplicateIndexingIntoMatrix) {
@@ -124,7 +126,7 @@ TEST(GatherNdOpTest, DuplicateIndexingIntoMatrix) {
m.SetPositions<int32_t>({0, 0, 0, 0});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput<float>(), ElementsAreArray({1.1, 1.1}));
+ EXPECT_THAT(m.GetOutput<float>(), Pointwise(FloatingPointEq(), {1.1, 1.1}));
}
TEST(GatherNdOpTest, ElementIndexingIntoRank3Tensor) {
@@ -136,7 +138,7 @@ TEST(GatherNdOpTest, ElementIndexingIntoRank3Tensor) {
m.SetPositions<int32_t>({0, 0, 1, 1, 1, 0});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput<float>(), ElementsAreArray({-1.2, -4.1}));
+ EXPECT_THAT(m.GetOutput<float>(), Pointwise(FloatingPointEq(), {-1.2, -4.1}));
}
TEST(GatherNdOpTest, SliceIndexingIntoRank3Tensor) {
@@ -149,8 +151,8 @@ TEST(GatherNdOpTest, SliceIndexingIntoRank3Tensor) {
ASSERT_EQ(m.Invoke(), kTfLiteOk);
EXPECT_THAT(m.GetOutput<float>(),
- ElementsAreArray({1.1, -1.2, 1.3, -2.1, 2.2, 2.3, 5.1, -5.2, 5.3,
- 6.1, -6.2, 6.3}));
+ Pointwise(FloatingPointEq(), {1.1, -1.2, 1.3, -2.1, 2.2, 2.3, 5.1,
+ -5.2, 5.3, 6.1, -6.2, 6.3}));
}
TEST(GatherNdOpTest, BatchedIndexingIntoRank3Tensor1) {
@@ -162,7 +164,7 @@ TEST(GatherNdOpTest, BatchedIndexingIntoRank3Tensor1) {
m.SetPositions<int32_t>({0, 0, 1, 1, 1, 0});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput<float>(), ElementsAreArray({-1.2, -4.1}));
+ EXPECT_THAT(m.GetOutput<float>(), Pointwise(FloatingPointEq(), {-1.2, -4.1}));
}
TEST(GatherNdOpTest, BatchedIndexingIntoRank3Tensor2) {
@@ -175,8 +177,8 @@ TEST(GatherNdOpTest, BatchedIndexingIntoRank3Tensor2) {
ASSERT_EQ(m.Invoke(), kTfLiteOk);
EXPECT_THAT(m.GetOutput<float>(),
- ElementsAreArray({3.1, 3.2, -3.3, -4.1, -4.2, 4.3, 1.1, -1.2, 1.3,
- -2.1, 2.2, 2.3}));
+ Pointwise(FloatingPointEq(), {3.1, 3.2, -3.3, -4.1, -4.2, 4.3,
+ 1.1, -1.2, 1.3, -2.1, 2.2, 2.3}));
}
TEST(GatherNdOpTest, BatchedIndexingIntoRank3Tensor3) {
@@ -189,8 +191,8 @@ TEST(GatherNdOpTest, BatchedIndexingIntoRank3Tensor3) {
ASSERT_EQ(m.Invoke(), kTfLiteOk);
EXPECT_THAT(m.GetOutput<float>(),
- ElementsAreArray({-2.1, 2.2, 2.3, 3.1, 3.2, -3.3, 1.1, -1.2, 1.3,
- 6.1, -6.2, 6.3}));
+ Pointwise(FloatingPointEq(), {-2.1, 2.2, 2.3, 3.1, 3.2, -3.3, 1.1,
+ -1.2, 1.3, 6.1, -6.2, 6.3}));
}
TEST(GatherNdOpTest, BatchedIndexingIntoRank3Tensor4) {
@@ -202,7 +204,8 @@ TEST(GatherNdOpTest, BatchedIndexingIntoRank3Tensor4) {
m.SetPositions<int32_t>({0, 0, 1, 1, 0, 1, 1, 1, 2, 2, 1, 2});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput<float>(), ElementsAreArray({-1.2, 3.2, 4.3, 6.3}));
+ EXPECT_THAT(m.GetOutput<float>(),
+ Pointwise(FloatingPointEq(), {-1.2, 3.2, 4.3, 6.3}));
}
TEST(GatherNdOpTest, DuplicateIndexingIntoRank3Tensor) {
@@ -215,7 +218,7 @@ TEST(GatherNdOpTest, DuplicateIndexingIntoRank3Tensor) {
ASSERT_EQ(m.Invoke(), kTfLiteOk);
EXPECT_THAT(m.GetOutput<float>(),
- ElementsAreArray({-2.1, 2.2, 2.3, -2.1, 2.2, 2.3}));
+ Pointwise(FloatingPointEq(), {-2.1, 2.2, 2.3, -2.1, 2.2, 2.3}));
}
TEST(GatherNdOpTest, Float32Int32) {
@@ -228,7 +231,7 @@ TEST(GatherNdOpTest, Float32Int32) {
ASSERT_EQ(m.Invoke(), kTfLiteOk);
EXPECT_THAT(m.GetOutput<float>(),
- ElementsAreArray({-2.1, 2.2, 2.3, 3.1, 3.2, -3.3}));
+ Pointwise(FloatingPointEq(), {-2.1, 2.2, 2.3, 3.1, 3.2, -3.3}));
}
TEST(GatherNdOpTest, Float32Int64) {
@@ -241,7 +244,7 @@ TEST(GatherNdOpTest, Float32Int64) {
ASSERT_EQ(m.Invoke(), kTfLiteOk);
EXPECT_THAT(m.GetOutput<float>(),
- ElementsAreArray({-2.1, 2.2, 2.3, 3.1, 3.2, -3.3}));
+ Pointwise(FloatingPointEq(), {-2.1, 2.2, 2.3, 3.1, 3.2, -3.3}));
}
TEST(GatherNdOpTest, Int32Int32) {
@@ -366,7 +369,7 @@ TEST(GatherNdOpTest, Float32Int16) {
ASSERT_EQ(m.Invoke(), kTfLiteOk);
EXPECT_THAT(m.GetOutput<float>(),
- ElementsAreArray({-2.1, 2.2, 2.3, 3.1, 3.2, -3.3}));
+ Pointwise(FloatingPointEq(), {-2.1, 2.2, 2.3, 3.1, 3.2, -3.3}));
}
TEST(GatherNdOpTest, StringInt32) {
diff --git a/tensorflow/lite/kernels/l2norm_test.cc b/tensorflow/lite/kernels/l2norm_test.cc
index c7beb4d0..bddff780 100644
--- a/tensorflow/lite/kernels/l2norm_test.cc
+++ b/tensorflow/lite/kernels/l2norm_test.cc
@@ -78,8 +78,9 @@ TEST(L2NormOpTest, SimpleFloatTest) {
ActivationFunctionType_NONE);
m.SetInput({-1.1, 0.6, 0.7, 1.2, -0.7, 0.1});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput<float>(),
- ElementsAreArray({-0.55, 0.3, 0.35, 0.6, -0.35, 0.05}));
+ EXPECT_THAT(
+ m.GetOutput<float>(),
+ Pointwise(FloatingPointEq(), {-0.55, 0.3, 0.35, 0.6, -0.35, 0.05}));
}
TEST(L2NormOpTest, ZerosVectorFloatTest) {
@@ -95,8 +96,9 @@ TEST(L2NormOpTest, SimpleFloatWithRankLessThanFourTest) {
L2NormOpModel m({1, 6}, TensorType_FLOAT32, ActivationFunctionType_NONE);
m.SetInput({-1.1, 0.6, 0.7, 1.2, -0.7, 0.1});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput<float>(),
- ElementsAreArray({-0.55, 0.3, 0.35, 0.6, -0.35, 0.05}));
+ EXPECT_THAT(
+ m.GetOutput<float>(),
+ Pointwise(FloatingPointEq(), {-0.55, 0.3, 0.35, 0.6, -0.35, 0.05}));
}
TEST(L2NormOpTest, MultipleBatchFloatTest) {
@@ -109,11 +111,12 @@ TEST(L2NormOpTest, MultipleBatchFloatTest) {
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
EXPECT_THAT(m.GetOutput<float>(),
- ElementsAreArray({
- -0.55, 0.3, 0.35, 0.6, -0.35, 0.05, // batch 1
- -0.55, 0.3, 0.35, 0.6, -0.35, 0.05, // batch 2
- -0.55, 0.3, 0.35, 0.6, -0.35, 0.05, // batch 3
- }));
+ Pointwise(FloatingPointEq(),
+ {
+ -0.55, 0.3, 0.35, 0.6, -0.35, 0.05, // batch 1
+ -0.55, 0.3, 0.35, 0.6, -0.35, 0.05, // batch 2
+ -0.55, 0.3, 0.35, 0.6, -0.35, 0.05, // batch 3
+ }));
}
TEST(L2NormOpTest, ZerosVectorUint8Test) {
diff --git a/tensorflow/lite/kernels/maximum_minimum_test.cc b/tensorflow/lite/kernels/maximum_minimum_test.cc
index 72886dce..30b85ae4 100644
--- a/tensorflow/lite/kernels/maximum_minimum_test.cc
+++ b/tensorflow/lite/kernels/maximum_minimum_test.cc
@@ -90,7 +90,11 @@ void TestModel(tflite::BuiltinOperator op, const TensorData& input1,
ASSERT_EQ(m->Invoke(), kTfLiteOk);
EXPECT_THAT(m->GetOutputShape(), ElementsAreArray(output.shape));
- EXPECT_THAT(m->GetOutput(), ElementsAreArray(output_values));
+ if constexpr (std::is_same_v<data_type, float>) {
+ EXPECT_THAT(m->GetOutput(), Pointwise(FloatingPointEq(), output_values));
+ } else {
+ EXPECT_THAT(m->GetOutput(), ElementsAreArray(output_values));
+ }
}
TEST(MaximumOpTest, FloatTest) {
diff --git a/tensorflow/lite/kernels/mul_test.cc b/tensorflow/lite/kernels/mul_test.cc
index f5f0d40d..9c7bbc31 100644
--- a/tensorflow/lite/kernels/mul_test.cc
+++ b/tensorflow/lite/kernels/mul_test.cc
@@ -945,7 +945,7 @@ void TestFloatBroadcast(std::vector<int> input1_shape,
m.PopulateTensor<float>(m.input1(), input1);
m.PopulateTensor<float>(m.input2(), input2);
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), testing::ContainerEq(output_ref));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), output_ref));
}
template <typename IntegerType>
@@ -1029,7 +1029,7 @@ void TestIntegerBroadcast(std::vector<int> input1_shape,
m.template PopulateTensor<IntegerType>(m.input1(), input1);
m.template PopulateTensor<IntegerType>(m.input2(), input2);
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), testing::ContainerEq(output_ref));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), output_ref));
}
// To improve automatic test sharding (via shard_count in the BUILD file),
diff --git a/tensorflow/lite/kernels/neg_test.cc b/tensorflow/lite/kernels/neg_test.cc
index fa0d8bda..5627f326 100644
--- a/tensorflow/lite/kernels/neg_test.cc
+++ b/tensorflow/lite/kernels/neg_test.cc
@@ -57,8 +57,9 @@ TEST(NegOpModel, NegFloat) {
NegOpModel m({TensorType_FLOAT32, {2, 3}}, {TensorType_FLOAT32, {2, 3}});
m.SetInput<float>({-2.0f, -1.0f, 0.f, 1.0f, 2.0f, 3.0f});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput<float>(),
- ElementsAreArray({2.0f, 1.0f, 0.f, -1.0f, -2.0f, -3.0f}));
+ EXPECT_THAT(
+ m.GetOutput<float>(),
+ Pointwise(FloatingPointEq(), {2.0f, 1.0f, 0.f, -1.0f, -2.0f, -3.0f}));
}
TEST(NegOpModel, NegInt32) {
diff --git a/tensorflow/lite/kernels/non_max_suppression_test.cc b/tensorflow/lite/kernels/non_max_suppression_test.cc
index 21680dc1..5bec3f6d 100644
--- a/tensorflow/lite/kernels/non_max_suppression_test.cc
+++ b/tensorflow/lite/kernels/non_max_suppression_test.cc
@@ -210,7 +210,7 @@ TEST(NonMaxSuppressionV5OpModel, TestOutput) {
EXPECT_THAT(nms.GetNumSelectedIndices(), ElementsAreArray({3}));
EXPECT_THAT(nms.GetSelectedIndices(), ElementsAreArray({3, 0, 5, 0, 0, 0}));
EXPECT_THAT(nms.GetSelectedScores(),
- ElementsAreArray({0.95, 0.9, 0.3, 0.0, 0.0, 0.0}));
+ Pointwise(FloatingPointEq(), {0.95, 0.9, 0.3, 0.0, 0.0, 0.0}));
// No candidate gets selected. But the outputs should be zeroed out.
nms.SetScoreThreshold(0.99);
@@ -218,7 +218,7 @@ TEST(NonMaxSuppressionV5OpModel, TestOutput) {
EXPECT_THAT(nms.GetNumSelectedIndices(), ElementsAreArray({0}));
EXPECT_THAT(nms.GetSelectedIndices(), ElementsAreArray({0, 0, 0, 0, 0, 0}));
EXPECT_THAT(nms.GetSelectedScores(),
- ElementsAreArray({0.0, 0.0, 0.0, 0.0, 0.0, 0.0}));
+ Pointwise(FloatingPointEq(), {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}));
}
TEST(NonMaxSuppressionV5OpModel, TestDynamicOutput) {
@@ -233,26 +233,29 @@ TEST(NonMaxSuppressionV5OpModel, TestDynamicOutput) {
ASSERT_EQ(nms.Invoke(), kTfLiteOk);
EXPECT_THAT(nms.GetNumSelectedIndices(), ElementsAreArray({2}));
EXPECT_THAT(nms.GetSelectedIndices(), ElementsAreArray({3, 0}));
- EXPECT_THAT(nms.GetSelectedScores(), ElementsAreArray({0.95, 0.9}));
+ EXPECT_THAT(nms.GetSelectedScores(),
+ Pointwise(FloatingPointEq(), {0.95, 0.9}));
nms.SetMaxOutputSize(1);
ASSERT_EQ(nms.Invoke(), kTfLiteOk);
EXPECT_THAT(nms.GetNumSelectedIndices(), ElementsAreArray({1}));
EXPECT_THAT(nms.GetSelectedIndices(), ElementsAreArray({3}));
- EXPECT_THAT(nms.GetSelectedScores(), ElementsAreArray({0.95}));
+ EXPECT_THAT(nms.GetSelectedScores(), Pointwise(FloatingPointEq(), {0.95}));
nms.SetMaxOutputSize(3);
ASSERT_EQ(nms.Invoke(), kTfLiteOk);
EXPECT_THAT(nms.GetNumSelectedIndices(), ElementsAreArray({3}));
EXPECT_THAT(nms.GetSelectedIndices(), ElementsAreArray({3, 0, 5}));
- EXPECT_THAT(nms.GetSelectedScores(), ElementsAreArray({0.95, 0.9, 0.3}));
+ EXPECT_THAT(nms.GetSelectedScores(),
+ Pointwise(FloatingPointEq(), {0.95, 0.9, 0.3}));
// No candidate gets selected. But the outputs should be zeroed out.
nms.SetScoreThreshold(0.99);
ASSERT_EQ(nms.Invoke(), kTfLiteOk);
EXPECT_THAT(nms.GetNumSelectedIndices(), ElementsAreArray({0}));
EXPECT_THAT(nms.GetSelectedIndices(), ElementsAreArray({0, 0, 0}));
- EXPECT_THAT(nms.GetSelectedScores(), ElementsAreArray({0.0, 0.0, 0.0}));
+ EXPECT_THAT(nms.GetSelectedScores(),
+ Pointwise(FloatingPointEq(), {0.0, 0.0, 0.0}));
}
} // namespace
} // namespace tflite
diff --git a/tensorflow/lite/kernels/one_hot_test.cc b/tensorflow/lite/kernels/one_hot_test.cc
index 7149b204..28539297 100644
--- a/tensorflow/lite/kernels/one_hot_test.cc
+++ b/tensorflow/lite/kernels/one_hot_test.cc
@@ -19,6 +19,7 @@ limitations under the License.
#include <memory>
#include <vector>
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "tensorflow/lite/core/interpreter.h"
#include "tensorflow/lite/kernels/test_util.h"
@@ -73,7 +74,8 @@ TEST(OneHotOpTest, BasicFloat) {
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({3, 3}));
EXPECT_THAT(model.GetOutput(),
- ElementsAreArray({1.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 1.f}));
+ Pointwise(FloatingPointEq(),
+ {1.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 1.f}));
}
TEST(OneHotOpTest, BasicInt) {
diff --git a/tensorflow/lite/kernels/pooling3d_test.cc b/tensorflow/lite/kernels/pooling3d_test.cc
index 815b9447..b7788417 100644
--- a/tensorflow/lite/kernels/pooling3d_test.cc
+++ b/tensorflow/lite/kernels/pooling3d_test.cc
@@ -164,7 +164,7 @@ TYPED_TEST(AveragePoolingOpTest, AveragePool) {
/*output=*/{GetTensorType<TypeParam>(), {}, 0, 15.9375});
m.SetInput({0, 6, 2, 4, 4, 5, 1, 4, 3, 2, 10, 7, 2, 3, 5, 1});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({3.125, 4.25}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {3.125, 4.25}));
}
TYPED_TEST(AveragePoolingOpTest, AveragePoolFilterH1) {
@@ -176,7 +176,7 @@ TYPED_TEST(AveragePoolingOpTest, AveragePoolFilterH1) {
/*output=*/{GetTensorType<TypeParam>(), {}, 0, 15.9375});
m.SetInput({0, 6, 2, 4, 4, 5, 1, 4, 3, 2, 10, 7, 2, 3, 5, 1});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({2.75, 5.75}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {2.75, 5.75}));
}
TYPED_TEST(AveragePoolingOpTest, AveragePoolPaddingSameStride1) {
@@ -192,8 +192,9 @@ TYPED_TEST(AveragePoolingOpTest, AveragePoolPaddingSameStride1) {
m.SetInput({0, 6, 2, 4, 2, 5, 4, 3, 3, 2, 10, 7, 3, 2, 2, 4});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
EXPECT_THAT(m.GetOutput(),
- ElementsAreArray({2.875, 4.125, 4.5, 4.5, 3.0, 3.25, 3.25, 3.5,
- 2.5, 4.0, 5.75, 5.5, 2.5, 2.0, 3.0, 4.0}));
+ Pointwise(FloatingPointEq(),
+ {2.875, 4.125, 4.5, 4.5, 3.0, 3.25, 3.25, 3.5, 2.5, 4.0,
+ 5.75, 5.5, 2.5, 2.0, 3.0, 4.0}));
}
TYPED_TEST(AveragePoolingOpTest, AveragePoolPaddingValidStride1) {
@@ -208,7 +209,7 @@ TYPED_TEST(AveragePoolingOpTest, AveragePoolPaddingValidStride1) {
/*stride_w=*/1);
m.SetInput({0, 6, 2, 4, 2, 5, 4, 3, 3, 2, 10, 7, 3, 2, 2, 4});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({2.875, 4.125, 4.5}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {2.875, 4.125, 4.5}));
}
TYPED_TEST(MaxPoolingOpTest, MaxPool) {
@@ -220,7 +221,7 @@ TYPED_TEST(MaxPoolingOpTest, MaxPool) {
/*output=*/{GetTensorType<TypeParam>(), {}, 0, 15.9375});
m.SetInput({0, 6, 2, 4, 4, 5, 1, 4, 3, 2, 10, 7, 2, 3, 5, 1});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({6.0, 10.0}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {6.0, 10.0}));
}
TYPED_TEST(MaxPoolingOpTest, MaxPoolFilterH1) {
@@ -263,7 +264,7 @@ TYPED_TEST(MaxPoolingOpTest, MaxPoolPaddingValidStride1) {
/*stride_w=*/1);
m.SetInput({0, 6, 2, 4, 2, 5, 4, 3, 3, 2, 10, 7, 3, 2, 2, 4});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({6.0, 10.0, 10.0}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {6.0, 10.0, 10.0}));
}
} // namespace tflite
diff --git a/tensorflow/lite/kernels/pooling_test.cc b/tensorflow/lite/kernels/pooling_test.cc
index b36b0528..240f7818 100644
--- a/tensorflow/lite/kernels/pooling_test.cc
+++ b/tensorflow/lite/kernels/pooling_test.cc
@@ -147,7 +147,7 @@ TEST(FloatPoolingOpTest, AveragePool) {
3, 2, 10, 7, //
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({2.75, 5.75}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {2.75, 5.75}));
}
TEST(FloatPoolingOpTest, AveragePoolActivationRelu) {
@@ -161,7 +161,7 @@ TEST(FloatPoolingOpTest, AveragePoolActivationRelu) {
3, 2, -10, 7, //
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({0.0, 0.75}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {0.0, 0.75}));
}
TEST(FloatPoolingOpTest, AveragePoolActivationRelu1) {
@@ -175,14 +175,14 @@ TEST(FloatPoolingOpTest, AveragePoolActivationRelu1) {
-3, -2, -10, 7, //
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({-1.0, 0.75}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {-1.0, 0.75}));
m.SetInput({
0, -6, -2, -4, //
-3, -2, 10, -7, //
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({-1.0, -0.75}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {-1.0, -0.75}));
}
TEST(FloatPoolingOpTest, AveragePoolActivationRelu6) {
@@ -196,14 +196,14 @@ TEST(FloatPoolingOpTest, AveragePoolActivationRelu6) {
-3, -2, 10, 7, //
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({0.0, 6.0}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {0.0, 6.0}));
m.SetInput({
0, 6, 12, 4, //
3, 2, 10, 7, //
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({2.75, 6.0}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {2.75, 6.0}));
}
TEST(FloatPoolingOpTest, AveragePoolPaddingSameStride1) {
@@ -217,8 +217,9 @@ TEST(FloatPoolingOpTest, AveragePoolPaddingSameStride1) {
3, 2, 10, 7, //
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(),
- ElementsAreArray({2.75, 5.0, 5.75, 5.5, 2.5, 6.0, 8.5, 7.0}));
+ EXPECT_THAT(
+ m.GetOutput(),
+ Pointwise(FloatingPointEq(), {2.75, 5.0, 5.75, 5.5, 2.5, 6.0, 8.5, 7.0}));
}
TEST(FloatPoolingOpTest, AveragePoolPaddingValidStride1) {
@@ -232,7 +233,7 @@ TEST(FloatPoolingOpTest, AveragePoolPaddingValidStride1) {
3, 2, 10, 7, //
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({2.75, 5.0, 5.75}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {2.75, 5.0, 5.75}));
}
TEST(QuantizedPoolingOpTest, AveragePool) {
@@ -642,7 +643,7 @@ TEST(FloatPoolingOpTest, MaxPoolActivationRelu) {
-3, -2, 10.5, 7, //
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({0.0, 10.5}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {0.0, 10.5}));
}
TEST(FloatPoolingOpTest, MaxPoolActivationRelu1) {
@@ -656,14 +657,14 @@ TEST(FloatPoolingOpTest, MaxPoolActivationRelu1) {
-3, -2, -0.3, 0.7, //
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({-1.0, 0.7}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {-1.0, 0.7}));
m.SetInput({
-2.75, -6, -2, -4, //
-3, -2, 10, -7, //
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({-1.0, 1.0}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {-1.0, 1.0}));
}
TEST(FloatPoolingOpTest, MaxPoolActivationRelu6) {
@@ -677,14 +678,14 @@ TEST(FloatPoolingOpTest, MaxPoolActivationRelu6) {
-3, -2, 10, 7, //
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({0.0, 6.0}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {0.0, 6.0}));
m.SetInput({
0, 4.5, 12, 4, //
3, 2, 10, 7, //
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({4.5, 6.0}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {4.5, 6.0}));
}
TEST(FloatPoolingOpTest, MaxPoolPaddingSameStride1) {
@@ -1062,7 +1063,7 @@ TEST(FloatPoolingOpTest, L2Pool) {
3, 2, 10, 7, //
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({3.5, 6.5}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {3.5, 6.5}));
}
TEST(FloatPoolingOpTest, L2PoolActivationRelu) {
@@ -1117,7 +1118,7 @@ TEST(FloatPoolingOpTest, L2PoolPaddingSame) {
3, 2, 10, 7, //
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({3.5, 6.5}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {3.5, 6.5}));
}
TEST(FloatPoolingOpTest, L2PoolPaddingSameSlide1) {
@@ -1148,7 +1149,7 @@ TEST(FloatPoolingOpTest, L2PoolPaddingValidSlide1) {
3, 2, 10, 7, //
});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), ElementsAreArray({3.5, 6.0, 6.5}));
+ EXPECT_THAT(m.GetOutput(), Pointwise(FloatingPointEq(), {3.5, 6.0, 6.5}));
}
#if GTEST_HAS_DEATH_TEST
diff --git a/tensorflow/lite/kernels/segment_sum_test.cc b/tensorflow/lite/kernels/segment_sum_test.cc
index 7fc9b174..c434de30 100644
--- a/tensorflow/lite/kernels/segment_sum_test.cc
+++ b/tensorflow/lite/kernels/segment_sum_test.cc
@@ -16,6 +16,7 @@ limitations under the License.
#include <vector>
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "tensorflow/lite/kernels/test_util.h"
#include "tensorflow/lite/schema/schema_generated.h"
@@ -85,8 +86,9 @@ TEST(SegmentSumOpModelTest, Float32Test_Simple) {
{1, 2, 3, 4, 4, 3, 2, 1, 5, 6, 7, 8});
model.PopulateTensor<int>(model.segment_ids(), {0, 0, 1});
ASSERT_EQ(model.Invoke(), kTfLiteOk);
- EXPECT_THAT(model.GetOutput(), ElementsAreArray({5.0f, 5.0f, 5.0f, 5.0f, 5.0f,
- 6.0f, 7.0f, 8.0f}));
+ EXPECT_THAT(model.GetOutput(),
+ Pointwise(FloatingPointEq(),
+ {5.0f, 5.0f, 5.0f, 5.0f, 5.0f, 6.0f, 7.0f, 8.0f}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({2, 4}));
}
@@ -96,7 +98,7 @@ TEST(SegmentSumOpModelTest, Float32Test_OneDimension) {
model.PopulateTensor<float>(model.data(), {1, 2, 3});
model.PopulateTensor<int32_t>(model.segment_ids(), {0, 0, 1});
ASSERT_EQ(model.Invoke(), kTfLiteOk);
- EXPECT_THAT(model.GetOutput(), ElementsAreArray({3.0f, 3.0f}));
+ EXPECT_THAT(model.GetOutput(), Pointwise(FloatingPointEq(), {3.0f, 3.0f}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({2}));
}
@@ -106,7 +108,8 @@ TEST(SegmentSumOpModelTest, Float32Test_ThreeDimensions) {
model.PopulateTensor<float>(model.data(), {1, 2, 3, 4, 5, 6});
model.PopulateTensor<int32_t>(model.segment_ids(), {0, 0, 1});
ASSERT_EQ(model.Invoke(), kTfLiteOk);
- EXPECT_THAT(model.GetOutput(), ElementsAreArray({4.0f, 6.0f, 5.0f, 6.0f}));
+ EXPECT_THAT(model.GetOutput(),
+ Pointwise(FloatingPointEq(), {4.0f, 6.0f, 5.0f, 6.0f}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({2, 2, 1}));
}
diff --git a/tensorflow/lite/kernels/select_test.cc b/tensorflow/lite/kernels/select_test.cc
index 2805f58e..034cf12c 100644
--- a/tensorflow/lite/kernels/select_test.cc
+++ b/tensorflow/lite/kernels/select_test.cc
@@ -17,6 +17,7 @@ limitations under the License.
#include <initializer_list>
#include <vector>
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "flatbuffers/flatbuffers.h" // from @flatbuffers
#include "tensorflow/lite/kernels/test_util.h"
@@ -107,7 +108,8 @@ TEST(SelectOpTest, SelectFloat) {
model.PopulateTensor<float>(model.input3(), {0.5, 0.6, 0.7, 0.8});
ASSERT_EQ(model.Invoke(), kTfLiteOk);
- EXPECT_THAT(model.GetOutput<float>(), ElementsAreArray({0.1, 0.6, 0.3, 0.8}));
+ EXPECT_THAT(model.GetOutput<float>(),
+ Pointwise(FloatingPointEq(), {0.1, 0.6, 0.3, 0.8}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({1, 1, 1, 4}));
}
@@ -277,7 +279,8 @@ TEST(SelectV2OpTest, SelectFloat) {
model.PopulateTensor<float>(model.input3(), {0.5, 0.6, 0.7, 0.8});
ASSERT_EQ(model.Invoke(), kTfLiteOk);
- EXPECT_THAT(model.GetOutput<float>(), ElementsAreArray({0.1, 0.6, 0.3, 0.8}));
+ EXPECT_THAT(model.GetOutput<float>(),
+ Pointwise(FloatingPointEq(), {0.1, 0.6, 0.3, 0.8}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({1, 1, 1, 4}));
}
diff --git a/tensorflow/lite/kernels/space_to_depth_test.cc b/tensorflow/lite/kernels/space_to_depth_test.cc
index 146c6a1b..3038e305 100644
--- a/tensorflow/lite/kernels/space_to_depth_test.cc
+++ b/tensorflow/lite/kernels/space_to_depth_test.cc
@@ -17,6 +17,7 @@ limitations under the License.
#include <initializer_list>
#include <vector>
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "flatbuffers/flatbuffers.h" // from @flatbuffers
#include "tensorflow/lite/kernels/test_util.h"
@@ -65,8 +66,9 @@ TEST(SpaceToDepthOpModel, Float32) {
SpaceToDepthOpModel m({TensorType_FLOAT32, {1, 2, 2, 2}}, 2);
m.SetInput<float>({1.4, 2.3, 3.2, 4.1, 5.4, 6.3, 7.2, 8.1});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput<float>(),
- ElementsAreArray({1.4, 2.3, 3.2, 4.1, 5.4, 6.3, 7.2, 8.1}));
+ EXPECT_THAT(
+ m.GetOutput<float>(),
+ Pointwise(FloatingPointEq(), {1.4, 2.3, 3.2, 4.1, 5.4, 6.3, 7.2, 8.1}));
EXPECT_THAT(m.GetOutputShape(), ElementsAre(1, 1, 1, 8));
}
diff --git a/tensorflow/lite/kernels/stablehlo_min_max_test.cc b/tensorflow/lite/kernels/stablehlo_min_max_test.cc
index 4903a415..d4dca87e 100644
--- a/tensorflow/lite/kernels/stablehlo_min_max_test.cc
+++ b/tensorflow/lite/kernels/stablehlo_min_max_test.cc
@@ -72,7 +72,8 @@ TEST(StablehloElementwise, MaxWorks) {
model.PopulateTensor<float>(model.input1(), {1.2, 2.5, -1.2, 1});
model.PopulateTensor<float>(model.input2(), {0.1, 3, 2, 0.5});
ASSERT_EQ(model.Invoke(), kTfLiteOk);
- EXPECT_THAT(model.GetOutput(), ElementsAreArray({1.2, 3.0, 2.0, 1.0}));
+ EXPECT_THAT(model.GetOutput(),
+ Pointwise(FloatingPointEq(), {1.2, 3.0, 2.0, 1.0}));
}
TEST(StablehloElementwise, MinWorks) {
@@ -82,7 +83,8 @@ TEST(StablehloElementwise, MinWorks) {
model.PopulateTensor<float>(model.input1(), {1.2, 2.5, -1.2, 1});
model.PopulateTensor<float>(model.input2(), {0.1, 3, 2, 0.5});
ASSERT_EQ(model.Invoke(), kTfLiteOk);
- EXPECT_THAT(model.GetOutput(), ElementsAreArray({0.1, 2.5, -1.2, 0.5}));
+ EXPECT_THAT(model.GetOutput(),
+ Pointwise(FloatingPointEq(), {0.1, 2.5, -1.2, 0.5}));
}
} // namespace
diff --git a/tensorflow/lite/kernels/sub_test.cc b/tensorflow/lite/kernels/sub_test.cc
index 88ede0f9..eca14dc7 100644
--- a/tensorflow/lite/kernels/sub_test.cc
+++ b/tensorflow/lite/kernels/sub_test.cc
@@ -683,7 +683,10 @@ void TestFloatBroadcast(std::vector<int> input1_shape,
m.PopulateTensor<float>(m.input1(), input1);
m.PopulateTensor<float>(m.input2(), input2);
ASSERT_EQ(m.Invoke(), kTfLiteOk);
- EXPECT_THAT(m.GetOutput(), testing::ContainerEq(output_ref));
+ // While there is no error in FP32 mode, 1e-3 error is expected in FP16 mode.
+ EXPECT_THAT(m.GetOutput(),
+ ElementsAreArray(ArrayFloatNear(output_ref, /*max_abs_err=*/0,
+ /*fp16_max_abs_err=*/1e-3)));
}
template <typename IntegerType>
diff --git a/tensorflow/lite/kernels/test_delegate_providers.cc b/tensorflow/lite/kernels/test_delegate_providers.cc
index 1d91ef45..ddf00c0f 100644
--- a/tensorflow/lite/kernels/test_delegate_providers.cc
+++ b/tensorflow/lite/kernels/test_delegate_providers.cc
@@ -24,6 +24,7 @@ limitations under the License.
namespace tflite {
constexpr char KernelTestDelegateProviders::kAccelerationTestConfigPath[];
constexpr char KernelTestDelegateProviders::kUseSimpleAllocator[];
+constexpr char KernelTestDelegateProviders::kAllowFp16PrecisionForFp32[];
/*static*/ KernelTestDelegateProviders* KernelTestDelegateProviders::Get() {
static KernelTestDelegateProviders* const providers =
@@ -37,6 +38,8 @@ KernelTestDelegateProviders::KernelTestDelegateProviders()
params_.AddParam(kAccelerationTestConfigPath,
tools::ToolParam::Create<std::string>(""));
params_.AddParam(kUseSimpleAllocator, tools::ToolParam::Create<bool>(false));
+ params_.AddParam(kAllowFp16PrecisionForFp32,
+ tools::ToolParam::Create<bool>(false));
}
bool KernelTestDelegateProviders::InitFromCmdlineArgs(int* argc,
@@ -56,6 +59,14 @@ bool KernelTestDelegateProviders::InitFromCmdlineArgs(int* argc,
this->params_.Set<bool>(kUseSimpleAllocator, val, argv_position);
},
false, "Use Simple Memory Allocator for SingleOpModel",
+ Flag::kOptional),
+ Flag(
+ kAllowFp16PrecisionForFp32,
+ [this](const bool& val, int argv_position) { // NOLINT
+ this->params_.Set<bool>(kAllowFp16PrecisionForFp32, val,
+ argv_position);
+ },
+ false, "Compare result in fp16 precision for fp32 operations",
Flag::kOptional)};
delegate_list_util_.AppendCmdlineFlags(flags);
diff --git a/tensorflow/lite/kernels/test_delegate_providers.h b/tensorflow/lite/kernels/test_delegate_providers.h
index 58023b55..8995f789 100644
--- a/tensorflow/lite/kernels/test_delegate_providers.h
+++ b/tensorflow/lite/kernels/test_delegate_providers.h
@@ -70,6 +70,10 @@ class KernelTestDelegateProviders {
static constexpr char kAccelerationTestConfigPath[] =
"acceleration_test_config_path";
+ // An option name to allow fp16 precision for fp32 computation.
+ static constexpr char kAllowFp16PrecisionForFp32[] =
+ "allow_fp16_precision_for_fp32";
+
private:
// Contain delegate-related parameters that are initialized from command-line
// flags.
diff --git a/tensorflow/lite/kernels/test_delegate_providers_test.cc b/tensorflow/lite/kernels/test_delegate_providers_test.cc
index c6afae70..bbade2c7 100644
--- a/tensorflow/lite/kernels/test_delegate_providers_test.cc
+++ b/tensorflow/lite/kernels/test_delegate_providers_test.cc
@@ -24,12 +24,15 @@ TEST(KernelTestDelegateProvidersTest, DelegateProvidersParams) {
const auto& params = providers.ConstParams();
EXPECT_TRUE(params.HasParam("use_xnnpack"));
EXPECT_TRUE(params.HasParam("use_nnapi"));
+ EXPECT_TRUE(params.HasParam("allow_fp16_precision_for_fp32"));
- int argc = 3;
+ int argc = 4;
const char* argv[] = {"program_name", "--use_nnapi=true",
+ "--allow_fp16_precision_for_fp32=true",
"--other_undefined_flag=1"};
EXPECT_TRUE(providers.InitFromCmdlineArgs(&argc, argv));
EXPECT_TRUE(params.Get<bool>("use_nnapi"));
+ EXPECT_TRUE(params.Get<bool>("allow_fp16_precision_for_fp32"));
EXPECT_EQ(2, argc);
EXPECT_EQ("--other_undefined_flag=1", argv[1]);
}
diff --git a/tensorflow/lite/kernels/test_util.cc b/tensorflow/lite/kernels/test_util.cc
index 99ab45a1..965a0fda 100644
--- a/tensorflow/lite/kernels/test_util.cc
+++ b/tensorflow/lite/kernels/test_util.cc
@@ -18,6 +18,7 @@ limitations under the License.
#include <stdint.h>
#include <algorithm>
+#include <cmath>
#include <complex>
#include <functional>
#include <map>
@@ -30,6 +31,7 @@ limitations under the License.
#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include "absl/base/casts.h"
#include "flatbuffers/flatbuffers.h" // from @flatbuffers
#include "tensorflow/lite/core/api/op_resolver.h"
#include "tensorflow/lite/core/c/common.h"
@@ -54,15 +56,122 @@ limitations under the License.
namespace tflite {
+using ::testing::Eq;
+using ::testing::FloatEq;
using ::testing::FloatNear;
using ::testing::Matcher;
+namespace {
+
+// Converts an integer from the sign-and-magnitude representation to
+// the biased representation. More precisely, let N be 2 to the
+// power of (kBitCount - 1), an integer x is represented by the
+// unsigned number x + N.
+//
+// For instance,
+//
+// -N + 1 (the most negative number representable using
+// sign-and-magnitude) is represented by 1;
+// 0 is represented by N; and
+// N - 1 (the biggest number representable using
+// sign-and-magnitude) is represented by 2N - 1.
+//
+// Read https://en.wikipedia.org/wiki/Signed_number_representations
+// for more details on signed number representations.
+uint32_t SignAndMagnitudeToBiased(uint32_t sam) {
+ constexpr uint32_t kSignBitMask = 1u << 31;
+ if (kSignBitMask & sam) {
+ // sam represents a negative number.
+ return ~sam + 1;
+ } else {
+ // sam represents a positive number.
+ return kSignBitMask | sam;
+ }
+}
+// Given two numbers in the sign-and-magnitude representation,
+// returns the distance between them as an unsigned number.
+uint32_t DistanceBetweenSignAndMagnitudeNumbers(uint32_t sam1, uint32_t sam2) {
+ uint32_t biased1 = SignAndMagnitudeToBiased(sam1);
+ uint32_t biased2 = SignAndMagnitudeToBiased(sam2);
+ return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
+}
+// Returns true if and only if lhs is at most max_ulps ULP's away from rhs.
+// In particular, this function:
+//
+// - returns true if both numbers are NAN.
+// - returns false if exact one of numbers is NAN.
+// - treats really large numbers as almost equal to infinity.
+// - thinks +0.0 and -0.0 are 0 DLP's apart.
+bool AlmostEquals(float lhs, float rhs, uint32_t max_ulps) {
+ if (std::isnan(lhs) || std::isnan(rhs)) {
+ return std::isnan(lhs) && std::isnan(rhs);
+ }
+
+ return DistanceBetweenSignAndMagnitudeNumbers(
+ absl::bit_cast<uint32_t>(lhs), absl::bit_cast<uint32_t>(rhs)) <=
+ max_ulps;
+}
+
+MATCHER_P3(FloatAbsRelNear, value, max_abs_err, max_rel_err, "") {
+ auto matcher =
+ FloatNear(value, std::max(max_abs_err, std::abs(max_rel_err * value)));
+ return ::testing::ExplainMatchResult(matcher, arg, result_listener);
+}
+
+MATCHER(Fp16Eq, "") {
+ // FP16 only has 10 bits precision while FP32 has 23 bits precision. Thus, to
+ // check if results of FP16 are almost equal, we could check the result is
+ // within 4 * 2^13 ULPs of FP32, which equals to 4 ULPs of FP16.
+ constexpr uint32_t fp16_ulps_in_fp32 = 4 * (1 << 13);
+ float actual = std::get<0>(arg);
+ float expected = std::get<1>(arg);
+ // The minimum exponent of FP16 is 2^-14, which means the minimum ULP of FP16
+ // is 2^-24. Therefore, when expected is less than 2^-14, i.e. a subnormal
+ // FP16 number, the minimum ULP of FP16 should be used instead of ULP of FP32.
+ if (std::abs(expected) < 0x1p-14) {
+ return std::abs(actual - expected) <= 4 * 0x1p-24;
+ }
+ return AlmostEquals(actual, expected, fp16_ulps_in_fp32);
+}
+
+} // namespace
+
+bool AllowFp16PrecisionForFp32() {
+ return tflite::KernelTestDelegateProviders::Get()->ConstParams().Get<bool>(
+ tflite::KernelTestDelegateProviders::kAllowFp16PrecisionForFp32);
+}
+
+Matcher<std::tuple<float, float>> FloatingPointEq() {
+ if (AllowFp16PrecisionForFp32()) {
+ return Fp16Eq();
+ }
+ return Eq();
+}
+
+Matcher<std::tuple<float, float>> FloatingPointAlmostEq() {
+ if (AllowFp16PrecisionForFp32()) {
+ return Fp16Eq();
+ }
+ return FloatEq();
+}
+
std::vector<Matcher<float>> ArrayFloatNear(const std::vector<float>& values,
- float max_abs_error) {
+ float max_abs_err,
+ float fp16_max_abs_err,
+ float max_rel_err,
+ float fp16_max_rel_err) {
+ if (AllowFp16PrecisionForFp32()) {
+ if (fp16_max_abs_err == kFpErrorAuto) {
+ max_abs_err = std::max(max_abs_err, std::sqrt(max_abs_err));
+ } else {
+ max_abs_err = fp16_max_abs_err;
+ }
+ max_rel_err = fp16_max_rel_err;
+ }
std::vector<Matcher<float>> matchers;
matchers.reserve(values.size());
for (const float& v : values) {
- matchers.emplace_back(FloatNear(v, max_abs_error));
+ matchers.emplace_back(FloatAbsRelNear(v, max_abs_err, max_rel_err));
}
return matchers;
}
diff --git a/tensorflow/lite/kernels/test_util.h b/tensorflow/lite/kernels/test_util.h
index 710ab60d..ec7d799e 100644
--- a/tensorflow/lite/kernels/test_util.h
+++ b/tensorflow/lite/kernels/test_util.h
@@ -60,11 +60,36 @@ limitations under the License.
namespace tflite {
+// This constant indicates the error bound is derived automatically in functions
+// like ArrayFloatNear.
+constexpr float kFpErrorAuto = -1;
+
+// Returns whether we allow FP16 precision for FP32 operations, i.e. in FP16
+// mode.
+bool AllowFp16PrecisionForFp32();
+
+// It checks if the actual number almost equals the expected number with the
+// tolerance of 4 FP16 ULPs in FP16 mode; 4 FP32 ULPs in FP32 mode.
+// Given float x, 2^e <= |x| <= 2^(e+1), then ULP(x) = 2^(max(e, e_min)-p+1)
+// where e_min is -24 for FP16, -126 for FP32; p is 10 for FP16, 23 for FP32.
+::testing::Matcher<std::tuple<float, float>> FloatingPointAlmostEq();
+
+// In FP32 mode, it equals to Eq(), which means the error bound is zero (no
+// error allowed); in FP16 mode, it checks if the actual number almost equals
+// the expected number with the tolerance of 4 FP16 ULPs.
+::testing::Matcher<std::tuple<float, float>> FloatingPointEq();
+
// A gmock matcher that check that elements of a float vector match to a given
-// tolerance.
+// tolerance. In FP32 mode, the tolerance is max(max_abs_err, value *
+// max_rel_err). In FP16 mode, the tolerance is max(fp16_max_abs_err, value *
+// fp16_max_rel_err). If fp16_max_abs_err is kFpErrorAuto, it is set to
+// std::max(max_abs_err, sqrt(max_abs_err)) automatically.
std::vector<::testing::Matcher<float>> ArrayFloatNear(
- const std::vector<float>& values, float max_abs_error = 1e-5);
+ const std::vector<float>& values, float max_abs_err = 1e-5,
+ float fp16_max_abs_err = kFpErrorAuto, float max_rel_err = 0,
+ float fp16_max_rel_err = 0.01);
+// TODO(b/280061335): Add FP16 logic as ArrayFloatNear does.
// A gmock matcher that check that elements of a complex vector match to a given
// tolerance.
std::vector<::testing::Matcher<std::complex<float>>> ArrayComplex64Near(
diff --git a/tensorflow/lite/kernels/test_util_test.cc b/tensorflow/lite/kernels/test_util_test.cc
index 7ac0cff1..ed9a679b 100644
--- a/tensorflow/lite/kernels/test_util_test.cc
+++ b/tensorflow/lite/kernels/test_util_test.cc
@@ -16,13 +16,17 @@ limitations under the License.
#include <stdint.h>
+#include <cfloat>
+#include <cmath>
#include <initializer_list>
+#include <tuple>
#include <vector>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "tensorflow/lite/array.h"
#include "tensorflow/lite/core/c/common.h"
+#include "tensorflow/lite/kernels/test_delegate_providers.h"
#include "tensorflow/lite/util.h"
namespace tflite {
@@ -30,6 +34,148 @@ namespace {
using ::testing::ElementsAreArray;
+TEST(TestUtilTest, ArrayFloatNearFp32) {
+ std::vector<float> expected = {0.1, 100.0, 0.0, -1};
+ // 9 * 10^-6 abs error should be tolerated by 1e-5 abs error.
+ std::vector<float> near = {0.100009, 99.999991, 0.000009, -1.000009};
+ // 2 * 10^-5 abs error should not be tolerated by 1e-5 abs error.
+ std::vector<float> not_near = {0.10002, 99.99998, 0.00002, -1.00002};
+ // Manually set the absoulte error and relative error to 1% and 1e-4.
+ std::vector<float> manual_error = {0.1009, 99.1, 0.00009, -1.009};
+
+ EXPECT_THAT(near, ElementsAreArray(ArrayFloatNear(expected)));
+ auto not_near_matchers = ArrayFloatNear(expected);
+ for (auto& matcher : not_near_matchers) {
+ matcher = Not(matcher);
+ }
+ EXPECT_THAT(not_near, ElementsAreArray(not_near_matchers));
+ EXPECT_THAT(manual_error, ElementsAreArray(ArrayFloatNear(
+ expected, /*max_abs_err=*/1e-4, kFpErrorAuto,
+ /*max_rel_err=*/0.01)));
+}
+
+TEST(TestUtilTest, ArrayFloatNearFp16) {
+ std::vector<float> expected = {0.1, 100.0, 0.0, -1};
+ // 0.003 abs error or <1% rel error should be tolerated by ArrayFloatNear.
+ std::vector<float> near = {0.103, 99.1, 0.003, -1.009};
+ // 0.004 abs error or >1% rel error should not be tolerated by ArrayFloatNear.
+ std::vector<float> not_near = {0.104, 98.9, 0.004, -1.011};
+ // Manually set the FP16 absoulte error and FP16 relative error to 10% and
+ // 1.
+ std::vector<float> manual_error = {1, 91, 0.9, -1.9};
+
+ // Setup FP16 mode.
+ tflite::KernelTestDelegateProviders::Get()->MutableParams()->Set<bool>(
+ tflite::KernelTestDelegateProviders::kAllowFp16PrecisionForFp32, true);
+
+ EXPECT_THAT(near, ElementsAreArray(ArrayFloatNear(expected)));
+ auto not_near_matchers = ArrayFloatNear(expected);
+ for (auto& matcher : not_near_matchers) {
+ matcher = Not(matcher);
+ }
+ EXPECT_THAT(not_near, ElementsAreArray(not_near_matchers));
+ EXPECT_THAT(manual_error,
+ ElementsAreArray(ArrayFloatNear(
+ expected, /*max_abs_err=*/0, /*fp16_max_abs_err=*/1,
+ /*max_rel_err=*/0, /*fp16_max_rel_err=*/0.1)));
+
+ // Revoke FP16 mode.
+ tflite::KernelTestDelegateProviders::Get()->MutableParams()->Set<bool>(
+ tflite::KernelTestDelegateProviders::kAllowFp16PrecisionForFp32, false);
+}
+
+TEST(TestUtilTest, FloatingPointEqFp32) {
+ // Minimum number that FP32 could represent. When the expected is a subnormal
+ // FP32 number, i.e. its exponent is the minimum, -126, FLT_TRUE_MIN is the
+ // ULP used.
+ constexpr float fp32_true_min = FLT_TRUE_MIN;
+
+ EXPECT_THAT(std::tuple(0.1, 0.1), FloatingPointEq());
+ EXPECT_THAT(std::tuple(100, 100), FloatingPointEq());
+ EXPECT_THAT(std::tuple(-1, -1), FloatingPointEq());
+ EXPECT_THAT(std::tuple(0, 0), FloatingPointEq());
+
+ EXPECT_THAT(std::tuple(0.1, 0.10000002), Not(FloatingPointEq()));
+ EXPECT_THAT(std::tuple(100, 100.00002), Not(FloatingPointEq()));
+ EXPECT_THAT(std::tuple(-1, -1.0000002), Not(FloatingPointEq()));
+ EXPECT_THAT(std::tuple(0, 4 * fp32_true_min), Not(FloatingPointEq()));
+ EXPECT_THAT(std::tuple(0, -4 * fp32_true_min), Not(FloatingPointEq()));
+
+ // FP32 has 23 bits for the fraction part, so the ULP error is between
+ // 2^-23 / 2 and 2^-23 relative error. With rounding to nearest, up to 4.5
+ // ULPs error should be considered as 4 ULPs. So the tolerated relative error
+ // of 4 ULPs is between 4.5 * 2^-23 / 2 and 4.5 * 2^-23 ~= 2.68 * 10^-7 and
+ // 5.36 * 10^-7.
+ // 2.5 * 10^-7 relative error should be tolerated by 4 ULPs.
+ EXPECT_THAT(std::tuple(0.1, 0.100000025), FloatingPointAlmostEq());
+ EXPECT_THAT(std::tuple(100, 100.000025), FloatingPointAlmostEq());
+ EXPECT_THAT(std::tuple(-1, -1.00000025), FloatingPointAlmostEq());
+ EXPECT_THAT(std::tuple(0, 4 * fp32_true_min), FloatingPointAlmostEq());
+ EXPECT_THAT(std::tuple(0, -4 * fp32_true_min), FloatingPointAlmostEq());
+
+ // 5.5 * 10^-7 relative error should not be tolerated by 4 ULPs.
+ EXPECT_THAT(std::tuple(0.1, 0.100000055), Not(FloatingPointAlmostEq()));
+ EXPECT_THAT(std::tuple(100, 100.000055), Not(FloatingPointAlmostEq()));
+ EXPECT_THAT(std::tuple(-1, -1.00000055), Not(FloatingPointAlmostEq()));
+ EXPECT_THAT(std::tuple(0, 5 * fp32_true_min), Not(FloatingPointAlmostEq()));
+ EXPECT_THAT(std::tuple(0, -5 * fp32_true_min), Not(FloatingPointAlmostEq()));
+}
+
+TEST(TestUtilTest, FloatingPointEqFp16) {
+ // Minimum number that FP16 could represent. When the expected is a subnormal
+ // FP16 number, i.e. its exponent is the minimum, -14, this is the ULP used.
+ // Given minimum exponent is -14 and fraction has 10 bits, the true minimum
+ // of FP16 is 2^(-14-10) = 2^(-24).
+ constexpr float fp16_true_min = 0x1p-24;
+ // Setup FP16 mode.
+ tflite::KernelTestDelegateProviders::Get()->MutableParams()->Set<bool>(
+ tflite::KernelTestDelegateProviders::kAllowFp16PrecisionForFp32, true);
+
+ // FP16 has 10 bits for tha fraction part, so the ULP error is between
+ // 2^-10 / 2 and 2^-10 relative error. Since we emulate a FP16 ULP by 2^13
+ // FP32 ULPs, rounding error is negligible. So the tolerated relative error
+ // of 4 ULPs is roughly between 4 * 2^-10 / 2 and 4 * 2^-10 ~= 0.195% and
+ // 0.39%.
+ // 0.15% relative error should be tolerated by 4 ULPs in FP16.
+ EXPECT_THAT(std::tuple(0.1, 0.10015), FloatingPointEq());
+ EXPECT_THAT(std::tuple(100, 100.15), FloatingPointEq());
+ EXPECT_THAT(std::tuple(-1, -1.0015), FloatingPointEq());
+ EXPECT_THAT(std::tuple(0, 4 * fp16_true_min), FloatingPointEq());
+ EXPECT_THAT(std::tuple(0, -4 * fp16_true_min), FloatingPointEq());
+ // NaN equals to NaN in FP16 mode.
+ EXPECT_THAT(std::tuple(std::nanf(""), std::nanf("")), FloatingPointEq());
+
+ // FloatingPointEq() should behave exactly like FloatingPointAlmostEq() in
+ // FP16 mode.
+ EXPECT_THAT(std::tuple(0.1, 0.10015), FloatingPointAlmostEq());
+ EXPECT_THAT(std::tuple(100, 100.15), FloatingPointAlmostEq());
+ EXPECT_THAT(std::tuple(-1, -1.0015), FloatingPointAlmostEq());
+ EXPECT_THAT(std::tuple(0, 4 * fp16_true_min), FloatingPointAlmostEq());
+ EXPECT_THAT(std::tuple(0, -4 * fp16_true_min), FloatingPointAlmostEq());
+
+ // 0.4% relative error should not be tolerated by 4 ULPs in FP16.
+ EXPECT_THAT(std::tuple(0.1, 0.1004), Not(FloatingPointEq()));
+ EXPECT_THAT(std::tuple(100, 100.4), Not(FloatingPointEq()));
+ EXPECT_THAT(std::tuple(-1, -1.004), Not(FloatingPointEq()));
+ EXPECT_THAT(std::tuple(0, 5 * fp16_true_min), Not(FloatingPointEq()));
+ EXPECT_THAT(std::tuple(0, -5 * fp16_true_min), Not(FloatingPointEq()));
+ // NaN equals to NaN in FP16 mode.
+ EXPECT_THAT(std::tuple(std::nanf(""), std::nanf("")),
+ FloatingPointAlmostEq());
+
+ // FloatingPointEq() should behave exactly like FloatingPointAlmostEq() in
+ // FP16 mode.
+ EXPECT_THAT(std::tuple(0.1, 0.1004), Not(FloatingPointAlmostEq()));
+ EXPECT_THAT(std::tuple(100, 100.4), Not(FloatingPointAlmostEq()));
+ EXPECT_THAT(std::tuple(-1, -1.004), Not(FloatingPointAlmostEq()));
+ EXPECT_THAT(std::tuple(0, 5 * fp16_true_min), Not(FloatingPointAlmostEq()));
+ EXPECT_THAT(std::tuple(0, -5 * fp16_true_min), Not(FloatingPointAlmostEq()));
+
+ // Revoke FP16 mode.
+ tflite::KernelTestDelegateProviders::Get()->MutableParams()->Set<bool>(
+ tflite::KernelTestDelegateProviders::kAllowFp16PrecisionForFp32, false);
+}
+
TEST(TestUtilTest, QuantizeVector) {
std::vector<float> data = {-1.0, -0.5, 0.0, 0.5, 1.0, 1000.0};
auto q_data = Quantize<uint8_t>(data, /*scale=*/1.0, /*zero_point=*/0);
diff --git a/tensorflow/lite/kernels/transpose_conv_test.cc b/tensorflow/lite/kernels/transpose_conv_test.cc
index bbe7d3f0..7b29f348 100644
--- a/tensorflow/lite/kernels/transpose_conv_test.cc
+++ b/tensorflow/lite/kernels/transpose_conv_test.cc
@@ -154,9 +154,10 @@ TEST_P(TransposeConvOpTest, SimpleTest) {
model.SetInput({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16});
ASSERT_EQ(model.Invoke(), kTfLiteOk);
- EXPECT_THAT(model.GetOutput(),
- ElementsAreArray({29, 62, 83, 75, 99, 192, 237, 198, 207, 372,
- 417, 330, 263, 446, 485, 365}));
+ EXPECT_THAT(
+ model.GetOutput(),
+ Pointwise(FloatingPointEq(), {29, 62, 83, 75, 99, 192, 237, 198, 207, 372,
+ 417, 330, 263, 446, 485, 365}));
// GetOutputShape() should always be same as model.SetOutputShape(...);
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({1, 4, 4, 1}));
}
@@ -183,8 +184,8 @@ TEST_P(TransposeConvOpTest, fusedRELUTest) {
ASSERT_EQ(model.Invoke(), kTfLiteOk);
EXPECT_THAT(model.GetOutput(),
- ElementsAreArray({29, 24, 0, 0, 99, 72, 0, 0, 207, 186, 0, 0, 263,
- 292, 141, 0}));
+ Pointwise(FloatingPointEq(), {29, 24, 0, 0, 99, 72, 0, 0, 207,
+ 186, 0, 0, 263, 292, 141, 0}));
// GetOutputShape() should always be same as model.SetOutputShape(...);
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({1, 4, 4, 1}));
}
@@ -213,8 +214,9 @@ TEST_P(TransposeConvOpTest, TwoFiltersTest) {
ASSERT_EQ(model.Invoke(), kTfLiteOk);
EXPECT_THAT(model.GetOutput(),
- ElementsAreArray({184, 412, 568, 528, 678, 1347, 1689, 1434, 1494,
- 2715, 3057, 2442, 1968, 3352, 3652, 2760}));
+ Pointwise(FloatingPointEq(),
+ {184, 412, 568, 528, 678, 1347, 1689, 1434, 1494, 2715,
+ 3057, 2442, 1968, 3352, 3652, 2760}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({1, 4, 4, 1}));
}
@@ -243,10 +245,11 @@ TEST_P(TransposeConvOpTest, PaddingValidTest) {
EXPECT_THAT(
model.GetOutput(),
- ElementsAreArray({5, 22, 59, 101, 114, 83, 52, 184, 412,
- 568, 528, 344, 237, 678, 1347, 1689, 1434, 879,
- 597, 1494, 2715, 3057, 2442, 1431, 856, 1968, 3352,
- 3652, 2760, 1548, 689, 1534, 2543, 2729, 2010, 1103}));
+ Pointwise(FloatingPointEq(),
+ {5, 22, 59, 101, 114, 83, 52, 184, 412,
+ 568, 528, 344, 237, 678, 1347, 1689, 1434, 879,
+ 597, 1494, 2715, 3057, 2442, 1431, 856, 1968, 3352,
+ 3652, 2760, 1548, 689, 1534, 2543, 2729, 2010, 1103}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({1, 6, 6, 1}));
}
@@ -269,10 +272,10 @@ TEST_P(TransposeConvOpTest, StrideValidTest) {
model.SetInput({1, 2, 3, 4});
ASSERT_EQ(model.Invoke(), kTfLiteOk);
- EXPECT_THAT(
- model.GetOutput(),
- ElementsAreArray({1, 2, 5, 4, 6, 4, 5, 14, 10, 12, 10, 14, 36,
- 24, 30, 12, 15, 34, 20, 24, 21, 24, 55, 32, 36}));
+ EXPECT_THAT(model.GetOutput(),
+ Pointwise(FloatingPointEq(),
+ {1, 2, 5, 4, 6, 4, 5, 14, 10, 12, 10, 14, 36,
+ 24, 30, 12, 15, 34, 20, 24, 21, 24, 55, 32, 36}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({1, 5, 5, 1}));
}
@@ -295,12 +298,12 @@ TEST_P(TransposeConvOpTest, MultiChannelTest) {
model.SetInput({1, 2, 3, 4});
ASSERT_EQ(model.Invoke(), kTfLiteOk);
- EXPECT_THAT(
- model.GetOutput(),
- ElementsAreArray({1, 2, 3, 4, 7, 10, 6, 8, 10, 12, 7, 8, 9,
- 10, 25, 28, 18, 20, 22, 24, 16, 20, 24, 28, 62, 72,
- 42, 48, 54, 60, 21, 24, 27, 30, 61, 68, 36, 40, 44,
- 48, 39, 42, 45, 48, 103, 110, 60, 64, 68, 72}));
+ EXPECT_THAT(model.GetOutput(),
+ Pointwise(FloatingPointEq(),
+ {1, 2, 3, 4, 7, 10, 6, 8, 10, 12, 7, 8, 9,
+ 10, 25, 28, 18, 20, 22, 24, 16, 20, 24, 28, 62, 72,
+ 42, 48, 54, 60, 21, 24, 27, 30, 61, 68, 36, 40, 44,
+ 48, 39, 42, 45, 48, 103, 110, 60, 64, 68, 72}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({1, 5, 5, 2}));
}
@@ -947,12 +950,12 @@ TEST_P(TransposeConvOpTest, MultiChannelBiasTest) {
model.SetBias({3, 4});
ASSERT_EQ(model.Invoke(), kTfLiteOk);
- EXPECT_THAT(
- model.GetOutput(),
- ElementsAreArray({4, 6, 6, 8, 10, 14, 9, 12, 13, 16, 10, 12, 12,
- 14, 28, 32, 21, 24, 25, 28, 19, 24, 27, 32, 65, 76,
- 45, 52, 57, 64, 24, 28, 30, 34, 64, 72, 39, 44, 47,
- 52, 42, 46, 48, 52, 106, 114, 63, 68, 71, 76}));
+ EXPECT_THAT(model.GetOutput(),
+ Pointwise(FloatingPointEq(),
+ {4, 6, 6, 8, 10, 14, 9, 12, 13, 16, 10, 12, 12,
+ 14, 28, 32, 21, 24, 25, 28, 19, 24, 27, 32, 65, 76,
+ 45, 52, 57, 64, 24, 28, 30, 34, 64, 72, 39, 44, 47,
+ 52, 42, 46, 48, 52, 106, 114, 63, 68, 71, 76}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({1, 5, 5, 2}));
}
@@ -988,12 +991,12 @@ TEST_P(TransposeConvOpTest, MultiChannelBiasWithFusedActivationTest) {
model.SetBias({3, 4});
ASSERT_EQ(model.Invoke(), kTfLiteOk);
- EXPECT_THAT(
- model.GetOutput(),
- ElementsAreArray({4, 6, 6, 8, 10, 14, 9, 12, 13, 16, 10, 12, 12,
- 14, 28, 32, 21, 24, 25, 28, 13, 12, 9, 8, 35, 40,
- 45, 52, 57, 64, 0, 0, 0, 0, 0, 0, 39, 44, 47,
- 52, 0, 0, 0, 0, 4, 6, 63, 68, 71, 76}));
+ EXPECT_THAT(model.GetOutput(),
+ Pointwise(FloatingPointEq(),
+ {4, 6, 6, 8, 10, 14, 9, 12, 13, 16, 10, 12, 12,
+ 14, 28, 32, 21, 24, 25, 28, 13, 12, 9, 8, 35, 40,
+ 45, 52, 57, 64, 0, 0, 0, 0, 0, 0, 39, 44, 47,
+ 52, 0, 0, 0, 0, 4, 6, 63, 68, 71, 76}));
EXPECT_THAT(model.GetOutputShape(), ElementsAreArray({1, 5, 5, 2}));
}
diff --git a/tensorflow/lite/kernels/zeros_like_test.cc b/tensorflow/lite/kernels/zeros_like_test.cc
index 64157a13..ab937ab8 100644
--- a/tensorflow/lite/kernels/zeros_like_test.cc
+++ b/tensorflow/lite/kernels/zeros_like_test.cc
@@ -51,7 +51,7 @@ TEST(ZerosLikeOpModel, ZerosLikeFloat) {
m.PopulateTensor<float>(m.input(), {-2.0, -1.0, 0.0, 1.0, 2.0, 3.0});
ASSERT_EQ(m.Invoke(), kTfLiteOk);
EXPECT_THAT(m.ExtractVector<float>(m.output()),
- ElementsAreArray({0.0, 0.0, 0.0, 0.0, 0.0, 0.0}));
+ Pointwise(FloatingPointEq(), {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}));
EXPECT_THAT(m.GetTensorShape(m.output()), ElementsAreArray({2, 3}));
}