1 /* ----------------------------------------------------------------------
2 * Project: CMSIS DSP Library
3 * Title: Error.h
4 * Description: Error Header
5 *
6 * $Date: 20. June 2019
7 * $Revision: V1.0.0
8 *
9 * Target Processor: Cortex-M cores
10 * -------------------------------------------------------------------- */
11 /*
12 * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
13 *
14 * SPDX-License-Identifier: Apache-2.0
15 *
16 * Licensed under the Apache License, Version 2.0 (the License); you may
17 * not use this file except in compliance with the License.
18 * You may obtain a copy of the License at
19 *
20 * www.apache.org/licenses/LICENSE-2.0
21 *
22 * Unless required by applicable law or agreed to in writing, software
23 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
24 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25 * See the License for the specific language governing permissions and
26 * limitations under the License.
27 */
28 #ifndef _ASSERT_H_
29 #define _ASSERT_H_
30 #include "arm_math_types.h"
31 #include "arm_math_types_f16.h"
32 #include <exception>
33 #include "Test.h"
34 #include "Pattern.h"
35
36
37 #define UNKNOWN_ERROR 1
38 #define EQUAL_ERROR 2
39 #define NEAR_EQUAL_ERROR 3
40 #define RELATIVE_ERROR 4
41 #define SNR_ERROR 5
42 #define DIFFERENT_LENGTH_ERROR 6
43 #define BOOL_ERROR 7
44 #define MEMORY_ALLOCATION_ERROR 8
45 #define EMPTY_PATTERN_ERROR 9
46 #define TAIL_NOT_EMPTY_ERROR 10
47 #define CLOSE_ERROR 11
48
49 namespace Client {
50
51 // Exception used by tests and runner
52 // to report errors
53 class Error: public std::exception
54 {
55 public:
Error(Testing::errorID_t id,unsigned long nb)56 Error(Testing::errorID_t id,unsigned long nb)
57 {
58 this->errorID = id;
59 this->lineNumber = nb;
60 this->details[0]='\0';
61 };
62
Error(Testing::errorID_t id,unsigned long nb,const char * details)63 Error(Testing::errorID_t id,unsigned long nb, const char *details)
64 {
65 this->errorID = id;
66 this->lineNumber = nb;
67 strcpy(this->details,details);
68 };
69
70 Testing::errorID_t errorID;
71 unsigned long lineNumber;
72 char details[200];
73 };
74
75 /*
76
77 Several test functions to implement tests in the client.
78 They should not be called directly but through macro
79 to get the line number.
80
81 (SNR functions to finish implementing)
82
83 */
84 #if !defined( __CC_ARM ) && defined(ARM_FLOAT16_SUPPORTED)
85 extern void assert_relative_error(unsigned long nb,float16_t &a, float16_t &b, double threshold);
86 extern void assert_relative_error(unsigned long nb,AnyPattern<float16_t> &pa, AnyPattern<float16_t> &pb, double threshold);
87 #endif
88
89 extern void assert_relative_error(unsigned long nb,float32_t &a, float32_t &b, double threshold);
90 extern void assert_relative_error(unsigned long nb,AnyPattern<float32_t> &pa, AnyPattern<float32_t> &pb, double threshold);
91
92 extern void assert_relative_error(unsigned long nb,float64_t &a, float64_t &b, double threshold);
93 extern void assert_relative_error(unsigned long nb,AnyPattern<float64_t> &pa, AnyPattern<float64_t> &pb, double threshold);
94
95 /* Similar to numpy isclose */
96 extern void assert_close_error(unsigned long nb,float64_t &ref, float64_t &val, double absthreshold, double relthreshold);
97 extern void assert_close_error(unsigned long nb,AnyPattern<float64_t> &pref, AnyPattern<float64_t> &pval, double absthreshold, double relthreshold);
98
99 extern void assert_close_error(unsigned long nb,float32_t &ref, float32_t &val, double absthreshold, double relthreshold);
100 extern void assert_close_error(unsigned long nb,AnyPattern<float32_t> &pref, AnyPattern<float32_t> &pval, double absthreshold, double relthreshold);
101
102 #if !defined( __CC_ARM ) && defined(ARM_FLOAT16_SUPPORTED)
103 extern void assert_close_error(unsigned long nb,float16_t &ref, float16_t &val, double absthreshold, double relthreshold);
104 extern void assert_close_error(unsigned long nb,AnyPattern<float16_t> &pref, AnyPattern<float16_t> &pval, double absthreshold, double relthreshold);
105 #endif
106
107 extern void assert_snr_error(unsigned long nb,AnyPattern<float64_t> &pa,AnyPattern<float64_t> &pb, float64_t threshold);
108 extern void assert_snr_error(unsigned long nb,AnyPattern<float32_t> &pa,AnyPattern<float32_t> &pb, float32_t threshold);
109
110 #if !defined( __CC_ARM ) && defined(ARM_FLOAT16_SUPPORTED)
111 extern void assert_snr_error(unsigned long nb,AnyPattern<float16_t> &pa,AnyPattern<float16_t> &pb, float32_t threshold);
112 #endif
113
114 extern void assert_snr_error(unsigned long nb,AnyPattern<q63_t> &pa,AnyPattern<q63_t> &pb, float32_t threshold);
115 extern void assert_snr_error(unsigned long nb,AnyPattern<q31_t> &pa,AnyPattern<q31_t> &pb, float32_t threshold);
116 extern void assert_snr_error(unsigned long nb,AnyPattern<q15_t> &pa,AnyPattern<q15_t> &pb, float32_t threshold);
117 extern void assert_snr_error(unsigned long nb,AnyPattern<q7_t> &pa,AnyPattern<q7_t> &pb, float32_t threshold);
118
119 extern void assert_snr_error(unsigned long nb,float64_t pa,float64_t pb, float64_t threshold);
120 extern void assert_snr_error(unsigned long nb,float32_t pa,float32_t pb, float32_t threshold);
121
122 #if !defined (__CC_ARM) && defined(ARM_FLOAT16_SUPPORTED)
123 extern void assert_snr_error(unsigned long nb,float16_t pa,float16_t pb, float32_t threshold);
124 #endif
125
126 extern void assert_snr_error(unsigned long nb,q63_t pa,q63_t pb, float32_t threshold);
127 extern void assert_snr_error(unsigned long nb,q31_t pa,q31_t pb, float32_t threshold);
128 extern void assert_snr_error(unsigned long nb,q15_t pa,q15_t pb, float32_t threshold);
129 extern void assert_snr_error(unsigned long nb,q7_t pa,q7_t pb, float32_t threshold);
130
131 extern void assert_true(unsigned long nb,bool cond);
132 extern void assert_false(unsigned long nb,bool cond);
133
134 extern void assert_not_empty(unsigned long nb, AnyPattern<float64_t> &p);
135 extern void assert_not_empty(unsigned long nb, AnyPattern<float32_t> &p);
136
137 #if !defined( __CC_ARM ) && defined(ARM_FLOAT16_SUPPORTED)
138 extern void assert_not_empty(unsigned long nb, AnyPattern<float16_t> &p);
139 #endif
140
141 extern void assert_not_empty(unsigned long nb, AnyPattern<q63_t> &p);
142 extern void assert_not_empty(unsigned long nb, AnyPattern<q31_t> &p);
143 extern void assert_not_empty(unsigned long nb, AnyPattern<q15_t> &p);
144 extern void assert_not_empty(unsigned long nb, AnyPattern<q7_t> &p);
145 extern void assert_not_empty(unsigned long nb, AnyPattern<uint32_t> &p);
146 extern void assert_not_empty(unsigned long nb, AnyPattern<uint16_t> &p);
147 extern void assert_not_empty(unsigned long nb, AnyPattern<uint8_t> &p);
148
149 }
150
151 /*
152
153 Macros to use to implement tests.
154
155 */
156 #define ASSERT_EQ(A,B) Client::assert_equal(__LINE__,A,B)
157 #define ASSERT_EQ_PARTIAL(NB,A,B) Client::assert_equal_partial(__LINE__,NB,A,B)
158
159 #define ASSERT_NEAR_EQ(A,B,THRESH) Client::assert_near_equal(__LINE__,A,B,THRESH)
160 #define ASSERT_REL_ERROR(A,B,THRESH) Client::assert_relative_error(__LINE__,A,B,THRESH)
161 #define ASSERT_CLOSE_ERROR(A,B,ABSTHRESH,RELTHRESH) Client::assert_close_error(__LINE__,A,B,ABSTHRESH,RELTHRESH)
162 #define ASSERT_SNR(A,B,SNR) Client::assert_snr_error(__LINE__,A,B,SNR)
163 #define ASSERT_TRUE(A) Client::assert_true(__LINE__,A)
164 #define ASSERT_FALSE(A) Client::assert_false(__LINE__,A)
165 #define ASSERT_NOT_EMPTY(A) Client::assert_not_empty(__LINE__,A)
166 #define ASSERT_EMPTY_TAIL(A) if (!A.isTailEmpty()) throw (Client::Error(TAIL_NOT_EMPTY_ERROR,__LINE__))
167
168 namespace Client {
169
170 using namespace std;
171
172 template <typename T>
assert_equal(unsigned long nb,T pa,T pb)173 void assert_equal(unsigned long nb,T pa, T pb)
174 {
175 if (pa != pb)
176 {
177 throw (Error(EQUAL_ERROR,nb));
178 }
179
180 };
181
182 template <typename T>
assert_equal_partial(unsigned long nb,unsigned long nbSamples,AnyPattern<T> & pa,AnyPattern<T> & pb)183 void assert_equal_partial(unsigned long nb,unsigned long nbSamples,AnyPattern<T> &pa, AnyPattern<T> &pb)
184 {
185 ASSERT_NOT_EMPTY(pa);
186 ASSERT_NOT_EMPTY(pb);
187
188 if (pa.nbSamples() < nbSamples)
189 {
190 throw (Error(EQUAL_ERROR,nb));
191 }
192
193 if (pb.nbSamples() < nbSamples)
194 {
195 throw (Error(EQUAL_ERROR,nb));
196 }
197
198 unsigned long i=0;
199 char id[40];
200
201 T *ptrA = pa.ptr();
202 T *ptrB = pb.ptr();
203
204 for(i=0; i < nbSamples; i++)
205 {
206 try
207 {
208 assert_equal(nb,ptrA[i],ptrB[i]);
209 }
210 catch(Error &err)
211 {
212 sprintf(id," (nb=%lu)",i);
213 strcat(err.details,id);
214 throw(err);
215 }
216 }
217 };
218
219 template <typename T>
assert_equal(unsigned long nb,AnyPattern<T> & pa,AnyPattern<T> & pb)220 void assert_equal(unsigned long nb,AnyPattern<T> &pa, AnyPattern<T> &pb)
221 {
222 ASSERT_NOT_EMPTY(pa);
223 ASSERT_NOT_EMPTY(pb);
224
225 if (pa.nbSamples() != pb.nbSamples())
226 {
227 throw (Error(EQUAL_ERROR,nb));
228 }
229
230 unsigned long i=0;
231 char id[40];
232
233 T *ptrA = pa.ptr();
234 T *ptrB = pb.ptr();
235
236 for(i=0; i < pa.nbSamples(); i++)
237 {
238 try
239 {
240 assert_equal(nb,ptrA[i],ptrB[i]);
241 }
242 catch(Error &err)
243 {
244 sprintf(id," (nb=%lu)",i);
245 strcat(err.details,id);
246 throw(err);
247 }
248 }
249 };
250
251 template <typename T>
assert_near_equal(unsigned long nb,T pa,T pb,T threshold)252 void assert_near_equal(unsigned long nb,T pa, T pb, T threshold)
253 {
254 if (abs(pa - pb) > threshold)
255 {
256 throw (Error(NEAR_EQUAL_ERROR,nb));
257 }
258 };
259
260 template <>
261 void assert_near_equal(unsigned long nb,double pa, double pb, double threshold);
262 template <>
263 void assert_near_equal(unsigned long nb,float32_t pa, float32_t pb, float32_t threshold);
264 template <>
265 void assert_near_equal(unsigned long nb,q63_t pa, q63_t pb, q63_t threshold);
266 template <>
267 void assert_near_equal(unsigned long nb,q31_t pa, q31_t pb, q31_t threshold);
268 template <>
269 void assert_near_equal(unsigned long nb,q15_t pa, q15_t pb, q15_t threshold);
270 template <>
271 void assert_near_equal(unsigned long nb,q7_t pa, q7_t pb, q7_t threshold);
272
273 template <typename T>
assert_near_equal(unsigned long nb,AnyPattern<T> & pa,AnyPattern<T> & pb,T threshold)274 void assert_near_equal(unsigned long nb,AnyPattern<T> &pa, AnyPattern<T> &pb, T threshold)
275 {
276
277 ASSERT_NOT_EMPTY(pa);
278 ASSERT_NOT_EMPTY(pb);
279
280 if (pa.nbSamples() != pb.nbSamples())
281 {
282 throw (Error(NEAR_EQUAL_ERROR,nb));
283 }
284
285 unsigned long i=0;
286 char id[40];
287
288 T *ptrA = pa.ptr();
289 T *ptrB = pb.ptr();
290
291 for(i=0; i < pa.nbSamples(); i++)
292 {
293
294 try
295 {
296 assert_near_equal(nb,ptrA[i],ptrB[i],threshold);
297 }
298 catch(Error &err)
299 {
300 sprintf(id," (nb=%lu)",i);
301 strcat(err.details,id);
302 throw(err);
303 }
304 }
305 };
306
307
308 }
309 #endif
310