blob: 33491e0dc9ce74d6621ae05cd091bb177c896d6d [file] [log] [blame]
Georgios Pinitas7021ef02023-08-22 08:25:57 +01001
Jeremy Johnsond80ea5e2024-01-03 10:54:12 +00002// Copyright (c) 2023-2024, ARM Limited.
Georgios Pinitas7021ef02023-08-22 08:25:57 +01003//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16#ifndef VERIFY_UTILS_H_
17#define VERIFY_UTILS_H_
18
19#include "dtype.h"
Jeremy Johnson718f3472023-11-30 14:18:19 +000020#include "half.hpp"
Georgios Pinitas7021ef02023-08-22 08:25:57 +010021#include "types.h"
22
23#include <cstdint>
24#include <optional>
Jeremy Johnson08965d32024-02-19 13:57:21 +000025#include <string>
Georgios Pinitas7021ef02023-08-22 08:25:57 +010026#include <vector>
27
Jeremy Johnsond1a08ce2023-10-18 17:22:21 +010028#define TOSA_REF_REQUIRE(COND, MESSAGE, ...) \
Jack Franklandaafc8502023-09-13 11:03:50 +010029 if (!(COND)) \
30 { \
Jeremy Johnsond1a08ce2023-10-18 17:22:21 +010031 WARNING("[Verifier]" MESSAGE ".", ##__VA_ARGS__); \
Jack Franklandaafc8502023-09-13 11:03:50 +010032 return false; \
33 }
34
Georgios Pinitas7021ef02023-08-22 08:25:57 +010035namespace TosaReference
36{
37
38// Name alias
39using CTensor = tosa_tensor_t;
40
41/// \brief Supported verification modes
42enum class VerifyMode
43{
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +010044 Unknown,
Georgios Pinitas7021ef02023-08-22 08:25:57 +010045 Exact,
46 Ulp,
47 DotProduct,
Jeremy Johnson9a758382023-11-07 16:27:35 +000048 FpSpecial,
Georgios Pinitas7021ef02023-08-22 08:25:57 +010049 ReduceProduct,
Jeremy Johnson32d0b5a2024-02-01 15:54:07 +000050 AbsError,
51 Relative
Georgios Pinitas7021ef02023-08-22 08:25:57 +010052};
53
54/// \brief ULP verification meta-data
Jeremy Johnsond80ea5e2024-01-03 10:54:12 +000055struct UlpVerifyInfo
Georgios Pinitas7021ef02023-08-22 08:25:57 +010056{
Jeremy Johnsond80ea5e2024-01-03 10:54:12 +000057 UlpVerifyInfo() = default;
Georgios Pinitas7021ef02023-08-22 08:25:57 +010058
Jeremy Johnsona4d907e2023-10-26 13:53:14 +010059 double ulp;
Georgios Pinitas7021ef02023-08-22 08:25:57 +010060};
61
62/// \brief Dot-product verification meta-data
63struct DotProductVerifyInfo
64{
65 DotProductVerifyInfo() = default;
66
Jeremy Johnsonb2d3bff2024-02-26 16:08:07 +000067 int32_t setNumber;
68 int32_t kernelSize;
Georgios Pinitas7021ef02023-08-22 08:25:57 +010069};
70
Jack Frankland12ee1a72023-09-20 09:08:34 +010071/// \brief reduce-product verification meta-data
72struct ReduceProductVerifyInfo
73{
74 ReduceProductVerifyInfo() = default;
75
Jeremy Johnsonb2d3bff2024-02-26 16:08:07 +000076 int64_t numberOfProducts;
Jack Frankland12ee1a72023-09-20 09:08:34 +010077};
78
Jeremy Johnsond80ea5e2024-01-03 10:54:12 +000079/// \brief abs-error verification meta-data
80struct AbsErrorVerifyInfo
81{
82 AbsErrorVerifyInfo() = default;
83
84 double lowerBound;
Jerry Ge51bd4f52024-02-20 11:21:19 -080085 double normalDivisor;
Jeremy Johnson1eb14552024-04-11 16:21:54 +010086 bool boundAsMagnitude;
87 double boundAddition;
Jeremy Johnsond80ea5e2024-01-03 10:54:12 +000088};
89
Jeremy Johnson32d0b5a2024-02-01 15:54:07 +000090/// \brief relative verification meta-data
91struct RelativeVerifyInfo
92{
93 RelativeVerifyInfo() = default;
94
95 double max;
96 double scale;
97};
98
Georgios Pinitas7021ef02023-08-22 08:25:57 +010099/// \brief Verification meta-data
100struct VerifyConfig
101{
102 VerifyConfig() = default;
103
104 VerifyMode mode;
Jeremy Johnsonbb0935f2023-09-14 16:43:48 +0100105 DType dataType;
Jeremy Johnsond80ea5e2024-01-03 10:54:12 +0000106 UlpVerifyInfo ulpInfo;
Georgios Pinitas7021ef02023-08-22 08:25:57 +0100107 DotProductVerifyInfo dotProductInfo;
Jack Frankland12ee1a72023-09-20 09:08:34 +0100108 ReduceProductVerifyInfo reduceProductInfo;
Jeremy Johnsond80ea5e2024-01-03 10:54:12 +0000109 AbsErrorVerifyInfo absErrorInfo;
Jeremy Johnson32d0b5a2024-02-01 15:54:07 +0000110 RelativeVerifyInfo relativeInfo;
Georgios Pinitas7021ef02023-08-22 08:25:57 +0100111};
112
113/// \brief Parse the verification config for a tensor when given in JSON form
114std::optional<VerifyConfig> parseVerifyConfig(const char* tensorName, const char* configJson);
115
116/// \brief Extract number of total elements
117int64_t numElements(const std::vector<int32_t>& shape);
118
Jeremy Johnson2d70ac42023-11-06 17:46:02 +0000119/// \brief Convert a flat index to a shape position
120std::vector<int32_t> indexToPosition(int64_t index, const std::vector<int32_t>& shape);
121
122/// \brief A string representing the shape or position
123std::string positionToString(const std::vector<int32_t>& pos);
124
Georgios Pinitas7021ef02023-08-22 08:25:57 +0100125/// \brief Map API data-type to DType
126DType mapToDType(tosa_datatype_t dataType);
127
Jeremy Johnsona4d907e2023-10-26 13:53:14 +0100128/// \brief Return 2 to the power of N or -N
Jeremy Johnsond1a08ce2023-10-18 17:22:21 +0100129// For use during compile time - as no range check
130constexpr double const_exp2(int32_t n)
131{
132 double v = 1.0;
133 while (n > 0)
134 {
135 v = v * 2.0;
136 n--;
137 }
138 while (n < 0)
139 {
140 v = v / 2.0;
141 n++;
142 }
143 return v;
144}
145
146/// \brief Same as const_exp2 but with runtime range check of N
147double exp2(int32_t n);
148
Jeremy Johnsona4d907e2023-10-26 13:53:14 +0100149/// \brief Return the base-2 exponent of V
150int32_t ilog2(double v);
151
Jeremy Johnsond1a08ce2023-10-18 17:22:21 +0100152/// \brief Accuracy precision information
153template <typename T>
154struct AccPrecision;
155template <>
156struct AccPrecision<float>
157{
158 static constexpr double normal_min = const_exp2(-126);
159 static constexpr double normal_max = const_exp2(128) - const_exp2(127 - 23);
160 static constexpr int32_t normal_frac = 23;
161};
Jeremy Johnson718f3472023-11-30 14:18:19 +0000162template <>
163struct AccPrecision<half_float::half>
164{
165 static constexpr double normal_min = const_exp2(-14);
166 static constexpr double normal_max = const_exp2(16) - const_exp2(15 - 10);
167 static constexpr int32_t normal_frac = 7;
168};
Jeremy Johnsond1a08ce2023-10-18 17:22:21 +0100169
Jeremy Johnson08965d32024-02-19 13:57:21 +0000170/// \brief Single value error bounds check for ULP, ABS_ERROR and other compliance modes
171///
172/// \param testValue Implementation value
173/// \param referenceValue Reference value
174/// \param errorBound Positive error bound value
175/// \param resultDifference Return: Difference between reference value and implementation value
176/// \param resultWarning Return: Warning message if implementation is outside error bounds
177///
178/// \return True if compliant else false
Jeremy Johnson718f3472023-11-30 14:18:19 +0000179template <typename OutType>
Jeremy Johnson08965d32024-02-19 13:57:21 +0000180bool tosaCheckFloatBound(
181 OutType testValue, double referenceValue, double errorBound, double& resultDifference, std::string& resultWarning);
182
183/// \brief Whole tensor checker for values inside error bounds
184///
185/// \param referenceData Reference output tensor data
186/// \param boundsData Optional reference bounds tensor data
187/// \param implementationData Implementation output tensor data
188/// \param shape Tensor shape - all tensors must be this shape
189/// \param modeStr Short string indicating which compliance mode we are testing
190/// \param cfgPtr Pointer to this mode's configuration data, passed to the calcErrorBound()
191/// \param calcErrorBound Pointer to a function that can calculate the error bound per ref value
192///
193/// \return True if compliant else false
194template <typename OutType>
195bool validateData(const double* referenceData,
196 const double* boundsData,
197 const OutType* implementationData,
198 const std::vector<int32_t>& shape,
199 const std::string& modeStr,
200 const void* cfgPtr,
201 double (*calcErrorBound)(double referenceValue, double boundsValue, const void* cfgPtr));
202
203// Unused arguments helper function
204template <typename... Args>
205inline void unused(Args&&...)
206{}
Georgios Pinitas7021ef02023-08-22 08:25:57 +0100207}; // namespace TosaReference
208
209#endif // VERIFY_UTILS_H_