aboutsummaryrefslogtreecommitdiff
path: root/reference_model/test
diff options
context:
space:
mode:
authorJeremy Johnson <jeremy.johnson@arm.com>2023-11-07 16:27:35 +0000
committerEric Kunze <eric.kunze@arm.com>2023-11-16 21:24:23 +0000
commit9a758384d1066ade713311940f3d15c860f90866 (patch)
treec25c9624b7c1d589d0648d6b3b4e6333f87a7712 /reference_model/test
parent2d70ac4c02808609feb357488dcd080bd6fc5ba5 (diff)
downloadreference_model-9a758384d1066ade713311940f3d15c860f90866.tar.gz
Main Compliance testing support for EXP & POW
Added new ABS_ERROR mode to verify lib and ref model. Signed-off-by: Jeremy Johnson <jeremy.johnson@arm.com> Change-Id: Ifb78290675833d3df7df91a4d6cef336b02b64a4
Diffstat (limited to 'reference_model/test')
-rw-r--r--reference_model/test/verify_tests.cpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/reference_model/test/verify_tests.cpp b/reference_model/test/verify_tests.cpp
index 31e27c0..f92792a 100644
--- a/reference_model/test/verify_tests.cpp
+++ b/reference_model/test/verify_tests.cpp
@@ -428,4 +428,65 @@ TEST_CASE("positive - ulp")
}
}
+TEST_CASE("positive - abs error")
+{
+ std::string jsonCfg = R"({
+ "tensors" : {
+ "out1" : {
+ "mode": "ABS_ERROR",
+ "data_type": "FP32"
+ }
+ }
+ })";
+
+ const auto shape = std::vector<int32_t>{ 4, 4, 4 };
+ 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_fp32 = generateRandomTensorData<float>(elementCount, true);
+ std::vector<double> data_fp64(data_fp32.begin(), data_fp32.end());
+
+ // Set up simple bounds of the input to 2.0
+ std::vector<double> bounds_fp64(elementCount);
+ std::for_each(std::begin(bounds_fp64), std::end(bounds_fp64), [](auto& value) { value = 2.0; });
+ constexpr float insideErrBound = 1.0e-7 * 2; // v.approx exp2(-23) * bounds[]
+ constexpr float outsideErrBound = 1.0e-7 * 3;
+
+ SUBCASE("inside")
+ {
+ // Generate some data that meets the ABS_ERROR requirements of the result.
+ auto otherData_fp32 = data_fp32;
+ std::for_each(std::begin(otherData_fp32), std::end(otherData_fp32), [insideErrBound](auto& value) {
+ if (std::abs(value) != 0.0 && !std::isinf(value) && !std::isnan(value))
+ value += value * insideErrBound;
+ });
+ const auto referenceTensor =
+ TosaTensor("out1", tosa_datatype_fp64_t, shape, reinterpret_cast<uint8_t*>(data_fp64.data()));
+ const auto boundsTensor =
+ TosaTensor("out1", tosa_datatype_fp64_t, shape, reinterpret_cast<uint8_t*>(bounds_fp64.data()));
+ const auto implementationTensor =
+ TosaTensor("out1", tosa_datatype_fp32_t, shape, reinterpret_cast<uint8_t*>(otherData_fp32.data()));
+ REQUIRE(tvf_verify_data(referenceTensor.cTensor(), boundsTensor.cTensor(), implementationTensor.cTensor(),
+ jsonCfg.c_str()));
+ }
+
+ SUBCASE("outside")
+ {
+ // Generate some data that exceeds a specified number of ULP for each value in the tensor.
+ auto otherData_fp32 = data_fp32;
+ std::for_each(std::begin(otherData_fp32), std::end(otherData_fp32), [outsideErrBound](auto& value) {
+ if (std::abs(value) != 0.0 && !std::isinf(value) && !std::isnan(value))
+ value += value * outsideErrBound;
+ });
+
+ const auto referenceTensor =
+ TosaTensor("out1", tosa_datatype_fp64_t, shape, reinterpret_cast<uint8_t*>(data_fp64.data()));
+ const auto boundsTensor =
+ TosaTensor("out1", tosa_datatype_fp64_t, shape, reinterpret_cast<uint8_t*>(bounds_fp64.data()));
+ const auto implementationTensor =
+ TosaTensor("out1", tosa_datatype_fp32_t, shape, reinterpret_cast<uint8_t*>(otherData_fp32.data()));
+ REQUIRE_FALSE(tvf_verify_data(referenceTensor.cTensor(), boundsTensor.cTensor(), implementationTensor.cTensor(),
+ jsonCfg.c_str()));
+ }
+}
TEST_SUITE_END(); // verify