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
diff --git a/reference_model/src/verify/verify_abs_error.cc b/reference_model/src/verify/verify_abs_error.cc
new file mode 100644
index 0000000..1afa7fd
--- /dev/null
+++ b/reference_model/src/verify/verify_abs_error.cc
@@ -0,0 +1,74 @@
+// Copyright (c) 2023, ARM Limited.
+//
+//    Licensed under the Apache License, Version 2.0 (the "License");
+//    you may not use this file except in compliance with the License.
+//    You may obtain a copy of the License at
+//
+//         http://www.apache.org/licenses/LICENSE-2.0
+//
+//    Unless required by applicable law or agreed to in writing, software
+//    distributed under the License is distributed on an "AS IS" BASIS,
+//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//    See the License for the specific language governing permissions and
+//    limitations under the License.
+
+#include <cmath>
+#include <limits>
+#include <memory>
+#include <type_traits>
+#include <utility>
+
+#include "verifiers.h"
+
+namespace TosaReference
+{
+
+namespace
+{
+bool validateData(const double* ref, const double* bnd, const float* imp, const std::vector<int32_t>& shape)
+{
+    const size_t T = static_cast<size_t>(numElements(shape));
+    TOSA_REF_REQUIRE(T > 0, "[AE] Invalid shape for reference tensor");
+
+    for (size_t i = 0; i < T; ++i)
+    {
+        double errBound = ref[i] * exp2(-AccPrecision<float>::normal_frac) * bnd[i];
+        bool valid      = tosaCheckFloatBound(imp[i], ref[i], errBound);
+        if (!valid)
+        {
+            auto pos = indexToPosition(T, shape);
+            WARNING("[Verifier][AE] Location %s", positionToString(pos).c_str());
+            return false;
+        }
+    }
+    return true;
+}
+}    // namespace
+bool verifyAbsError(const CTensor* ref, const CTensor* refBnd, const CTensor* imp)
+{
+    // Validate that tensors are provided
+    TOSA_REF_REQUIRE(ref != nullptr, "[AE] Reference tensor is missing");
+    TOSA_REF_REQUIRE(refBnd != nullptr, "[AE] Reference bounds tensor is missing");
+    TOSA_REF_REQUIRE(imp != nullptr, "[AE] Implementation tensor is missing");
+
+    const std::vector<int32_t> refShape(ref->shape, ref->shape + ref->num_dims);
+
+    const double* refData    = reinterpret_cast<const double*>(ref->data);
+    const double* refBndData = reinterpret_cast<const double*>(refBnd->data);
+    TOSA_REF_REQUIRE(refData != nullptr && refBndData != nullptr, "[AE] Missing data for reference or bounds tensors");
+
+    switch (imp->data_type)
+    {
+        case tosa_datatype_fp32_t: {
+            const float* impData = reinterpret_cast<const float*>(imp->data);
+            TOSA_REF_REQUIRE(impData != nullptr, "[AE] Missing data for implementation");
+            return validateData(refData, refBndData, impData, refShape);
+        }
+        default:
+            WARNING("[Verifier][AE] Data-type not supported.");
+            break;
+    }
+
+    return false;
+}
+}    // namespace TosaReference