diff options
author | Jack Frankland <jack.frankland@arm.com> | 2023-09-13 15:47:48 +0100 |
---|---|---|
committer | Jeremy Johnson <jeremy.johnson@arm.com> | 2023-10-02 11:30:47 +0100 |
commit | 62737b15a30e431dcefaaf28001f304e46598fc6 (patch) | |
tree | c22f4e3cb416eda3105f9bff903d698dace2f35f /reference_model/test | |
parent | fbf76784f8ec9650f25d4debfd599bd095cf41c2 (diff) | |
download | reference_model-62737b15a30e431dcefaaf28001f304e46598fc6.tar.gz |
Add ULP verification for fp32
Add a verifier to check two results are correct within a certain ULP
tolerance for IEEE-754 32-bit floating point values.
Add a test to check the ULP verifier is correct.
Signed-off-by: Jack Frankland <jack.frankland@arm.com>
Change-Id: Iaf43069f300999479d998e7837746b247ca5177e
Diffstat (limited to 'reference_model/test')
-rw-r--r-- | reference_model/test/verify_tests.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/reference_model/test/verify_tests.cpp b/reference_model/test/verify_tests.cpp index 731a808..7482847 100644 --- a/reference_model/test/verify_tests.cpp +++ b/reference_model/test/verify_tests.cpp @@ -14,6 +14,8 @@ #include "verify.h" #include <algorithm> +#include <cmath> +#include <cstdint> #include <doctest.h> #include <array> @@ -55,6 +57,14 @@ private: tosa_tensor_t _tensor; }; +template <typename FP> +std::enable_if_t<std::is_floating_point_v<FP>, FP> increment(FP input, uint64_t steps) +{ + for (uint64_t step = 0; step < steps; ++step) + input = std::nextafter(input, std::numeric_limits<FP>::infinity()); + return input; +} + auto& getRandomGenerator() { static std::mt19937 gen(0); @@ -227,4 +237,49 @@ TEST_CASE("positive - exact") } } +TEST_CASE("positive - ulp") +{ + std::string json_cfg = R"({ + "tensors" : { + "out1" : { + "mode": "ULP", + "ulp_info": { + "ulp": 5 + } + } + } + })"; + + const auto shape = std::vector<int32_t>{ 8, 8, 8 }; + const auto elementCount = std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<>()); + + // Generate some random floats using the full range of fp32. + auto data = generateRandomTensorData<float>(elementCount, false); + SUBCASE("same") + { + // Generate some data that meets the ULP requirements of the result. + auto otherData = data; + std::for_each(std::begin(otherData), std::end(otherData), [](auto& value) { value = increment(value, 5); }); + const auto referenceTensor = + TosaTensor("out1", tosa_datatype_fp64_t, shape, reinterpret_cast<uint8_t*>(data.data())); + const auto implementationTensor = + TosaTensor("out1", tosa_datatype_fp32_t, shape, reinterpret_cast<uint8_t*>(otherData.data())); + REQUIRE(tvf_verify_data(referenceTensor.cTensor(), nullptr, implementationTensor.cTensor(), json_cfg.c_str())); + } + + SUBCASE("different") + { + // Generate some data that exceeds a specified number of ULP for each value in the tensor. + auto otherData = std::vector<float>(elementCount); + std::for_each(std::begin(otherData), std::end(otherData), [](auto& value) { value = increment(value, 6); }); + + const auto referenceTensor = + TosaTensor("out1", tosa_datatype_fp64_t, shape, reinterpret_cast<uint8_t*>(data.data())); + const auto implementationTensor = + TosaTensor("out1", tosa_datatype_fp32_t, shape, reinterpret_cast<uint8_t*>(otherData.data())); + REQUIRE_FALSE( + tvf_verify_data(referenceTensor.cTensor(), nullptr, implementationTensor.cTensor(), json_cfg.c_str())); + } +} + TEST_SUITE_END(); // verify |