blob: 0916415bcb79133d0cb4e0bf6f9c74e9ffbeaa3a [file] [edit]
/*
* Copyright 2025 The ChromiumOS Authors
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <gtest/gtest.h>
#include "common/test_util/fp16_compare.h"
// Adapted from
// https://github.com/tensorflow/tensorflow/blob/b0b4ec040b9b8f4b7fefdb5d7c3695349dae1d9d/tensorflow/lite/kernels/test_util_test.cc#L124-L177
TEST(Fp16CompareTest, Eq) {
// 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;
// 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(0.1f, Fp16Eq(0.10015));
EXPECT_THAT(100.f, Fp16Eq(100.15));
EXPECT_THAT(-1.f, Fp16Eq(-1.0015));
EXPECT_THAT(0.f, Fp16Eq(4 * fp16_true_min));
EXPECT_THAT(0.f, Fp16Eq(-4 * fp16_true_min));
// NaN equals to NaN.
EXPECT_THAT(std::nanf(""), Fp16Eq(std::nanf("")));
// 0.4% relative error should not be tolerated by 4 ULPs in FP16.
EXPECT_THAT(0.1f, Not(Fp16Eq(0.1004)));
EXPECT_THAT(100.f, Not(Fp16Eq(100.4)));
EXPECT_THAT(-1.f, Not(Fp16Eq(-1.004)));
EXPECT_THAT(0.f, Not(Fp16Eq(5 * fp16_true_min)));
EXPECT_THAT(0.f, Not(Fp16Eq(-5 * fp16_true_min)));
}
int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}