blob: 25ecae4b11f51697f2b1b2f1d2df35f9d0418d51 [file] [log] [blame]
Jeremy Johnsond80ea5e2024-01-03 10:54:12 +00001// Copyright (c) 2023-2024, ARM Limited.
Jeremy Johnson9a758382023-11-07 16:27:35 +00002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include <cmath>
16#include <limits>
17#include <memory>
18#include <type_traits>
19#include <utility>
20
Jeremy Johnson718f3472023-11-30 14:18:19 +000021#include "half.hpp"
Jeremy Johnson9a758382023-11-07 16:27:35 +000022#include "verifiers.h"
23
24namespace TosaReference
25{
26
27namespace
28{
Jeremy Johnson718f3472023-11-30 14:18:19 +000029template <typename OutDtype>
Jeremy Johnsond80ea5e2024-01-03 10:54:12 +000030bool validateData(const double* ref,
31 const double* bnd,
32 const OutDtype* imp,
33 const std::vector<int32_t>& shape,
34 const AbsErrorVerifyInfo& cfg)
Jeremy Johnson9a758382023-11-07 16:27:35 +000035{
36 const size_t T = static_cast<size_t>(numElements(shape));
37 TOSA_REF_REQUIRE(T > 0, "[AE] Invalid shape for reference tensor");
38
39 for (size_t i = 0; i < T; ++i)
40 {
Jeremy Johnsond80ea5e2024-01-03 10:54:12 +000041 double valBound = std::abs(ref[i]) * bnd[i];
42 if (cfg.lowerBound > 0)
43 {
44 valBound = std::max(cfg.lowerBound, valBound);
45 }
46 double errBound = exp2(-AccPrecision<OutDtype>::normal_frac) * valBound;
Jeremy Johnson9a758382023-11-07 16:27:35 +000047 bool valid = tosaCheckFloatBound(imp[i], ref[i], errBound);
48 if (!valid)
49 {
50 auto pos = indexToPosition(T, shape);
51 WARNING("[Verifier][AE] Location %s", positionToString(pos).c_str());
52 return false;
53 }
54 }
55 return true;
56}
57} // namespace
Jeremy Johnsond80ea5e2024-01-03 10:54:12 +000058bool verifyAbsError(const CTensor* ref, const CTensor* refBnd, const CTensor* imp, const AbsErrorVerifyInfo& aeInfo)
Jeremy Johnson9a758382023-11-07 16:27:35 +000059{
60 // Validate that tensors are provided
61 TOSA_REF_REQUIRE(ref != nullptr, "[AE] Reference tensor is missing");
62 TOSA_REF_REQUIRE(refBnd != nullptr, "[AE] Reference bounds tensor is missing");
63 TOSA_REF_REQUIRE(imp != nullptr, "[AE] Implementation tensor is missing");
64
65 const std::vector<int32_t> refShape(ref->shape, ref->shape + ref->num_dims);
66
67 const double* refData = reinterpret_cast<const double*>(ref->data);
68 const double* refBndData = reinterpret_cast<const double*>(refBnd->data);
69 TOSA_REF_REQUIRE(refData != nullptr && refBndData != nullptr, "[AE] Missing data for reference or bounds tensors");
70
71 switch (imp->data_type)
72 {
73 case tosa_datatype_fp32_t: {
Jeremy Johnson718f3472023-11-30 14:18:19 +000074 const auto* impData = reinterpret_cast<const float*>(imp->data);
75 TOSA_REF_REQUIRE(impData != nullptr, "[AE] Missing data for implementation");
Jeremy Johnsond80ea5e2024-01-03 10:54:12 +000076 return validateData(refData, refBndData, impData, refShape, aeInfo);
Jeremy Johnson718f3472023-11-30 14:18:19 +000077 }
78 case tosa_datatype_fp16_t: {
79 const auto* impData = reinterpret_cast<const half_float::half*>(imp->data);
Jeremy Johnson9a758382023-11-07 16:27:35 +000080 TOSA_REF_REQUIRE(impData != nullptr, "[AE] Missing data for implementation");
Jeremy Johnsond80ea5e2024-01-03 10:54:12 +000081 return validateData(refData, refBndData, impData, refShape, aeInfo);
Jeremy Johnson9a758382023-11-07 16:27:35 +000082 }
83 default:
84 WARNING("[Verifier][AE] Data-type not supported.");
85 break;
86 }
87
88 return false;
89}
90} // namespace TosaReference