aboutsummaryrefslogtreecommitdiff
path: root/reference_model/test
diff options
context:
space:
mode:
authorJack Frankland <jack.frankland@arm.com>2023-09-13 15:47:48 +0100
committerJeremy Johnson <jeremy.johnson@arm.com>2023-10-02 11:30:47 +0100
commit62737b15a30e431dcefaaf28001f304e46598fc6 (patch)
treec22f4e3cb416eda3105f9bff903d698dace2f35f /reference_model/test
parentfbf76784f8ec9650f25d4debfd599bd095cf41c2 (diff)
downloadreference_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.cpp55
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