diff options
author | Jeremy Johnson <jeremy.johnson@arm.com> | 2023-11-07 16:27:35 +0000 |
---|---|---|
committer | Eric Kunze <eric.kunze@arm.com> | 2023-11-16 21:24:23 +0000 |
commit | 9a758384d1066ade713311940f3d15c860f90866 (patch) | |
tree | c25c9624b7c1d589d0648d6b3b4e6333f87a7712 /reference_model/test | |
parent | 2d70ac4c02808609feb357488dcd080bd6fc5ba5 (diff) | |
download | reference_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.cpp | 61 |
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 |