1 #pragma once
2
3
4 extern "C" {
5 #include "bench.h"
6 #include "test.h"
7 }
8
9
10 #include <type_traits>
11 #include "allocator.h"
12
13 using namespace arm_cmsis_dsp;
14
15 #define REL_ERROR (1.0e-6)
16 #define ABS_ERROR (1.0e-6)
17 #define ERROR(A,B,AE,RE) ((fabs((A) - (B)) > (AE + RE * fabs((B)))))
18 #define ERRVAL(VAL,REF,AE,RE) \
19 std::cout << "Error = " << fabs(VAL-REF) << "\r\n"; \
20 std::cout << "compared to " << (AE + RE * abs((REF))) << "\r\n";
21
22 /************
23 *
24 * Data types
25 *
26 */
27
28 #if defined(TESTMODE)
29 template<typename P,int L=arm_cmsis_dsp::DYNAMIC>
30 using PVector = Vector<P,L,malloc_allocator>;
31
32 template<typename P,int R=arm_cmsis_dsp::DYNAMIC,int C=arm_cmsis_dsp::DYNAMIC>
33 using PMat = Matrix<P,R,C,malloc_allocator>;
34
35 #else
36 #if defined(POOL_ALLOCATOR)
37
38 template<typename P,int L=arm_cmsis_dsp::DYNAMIC>
39 using PVector = Vector<P,L,pool_allocator>;
40
41 template<typename P,int R=arm_cmsis_dsp::DYNAMIC,int C=arm_cmsis_dsp::DYNAMIC>
42 using PMat = Matrix<P,R,C,pool_allocator>;
43
44 #else
45
46 template<typename P,int L=arm_cmsis_dsp::DYNAMIC>
47 using PVector = Vector<P,L,stat_allocator>;
48
49 template<typename P,int R=arm_cmsis_dsp::DYNAMIC,int C=arm_cmsis_dsp::DYNAMIC>
50 using PMat = Matrix<P,R,C,stat_allocator>;
51
52 #endif
53 #endif
54
55 template<typename P,int stride=1>
56 using PView = VectorView<P,stride>;
57
58 template<typename T,
59 int L,
60 template<int> typename A>
init_array(Vector<T,L,A> & pDst,std::size_t nb)61 void init_array(Vector<T,L,A> &pDst,std::size_t nb)
62 {
63 for(std::size_t i=0;i<nb;i++)
64 {
65 pDst[i] = T(i);
66 }
67 }
68
69 #if !defined(DISABLEFLOAT16)
70 template<int L,
71 template<int> typename A>
init_array(Vector<float16_t,L,A> & pDst,std::size_t nb)72 void init_array(Vector<float16_t,L,A> &pDst,std::size_t nb)
73 {
74 for(std::size_t i=0;i<nb;i++)
75 {
76 // Scaled down to prevent saturations in the tests
77 pDst[i] = (float16_t)i*0.001;
78 }
79 }
80 #endif
81
82 template<typename T>
init_array(Vector_Base<T> & pDst,std::size_t nb)83 void init_array(Vector_Base<T> &pDst,std::size_t nb)
84 {
85 for(std::size_t i=0;i<nb;i++)
86 {
87 pDst[i] = T(i);
88 }
89 }
90
91
92 //template<int L,
93 // template<int> typename A>
94 //void init_array(Vector<float16_t,L,A> &pDst,std::size_t nb);
95
96
97 //extern template void init_array<>(Vector_Base<float16_t> &pDst,std::size_t nb);
98
99
100 template<typename T,
101 typename std::enable_if<std::is_pointer<T>::value,bool>::type = true>
102 bool validate(const T a, const T b, std::size_t nb,float abser = ABS_ERROR, float reler = REL_ERROR)
103 {
104 for(std::size_t i=0;i<nb;i++)
105 {
106 if constexpr (number_traits<std::remove_cv_t<std::remove_reference_t<decltype(a[0])>>>::is_float)
107 {
108 if (ERROR(a[i],b[i],abser,reler) )
109 {
110 std::cout << "Error at:" << i << " ; res=" << a[i] << " ; ref=" << b[i] << "\r\n";
111 ERRVAL(a[i],b[i],abser,reler);
112 return(false);
113 }
114 }
115 else
116 {
117 if (a[i]!=b[i])
118 {
119 std::cout << "Error at:" << i << " ; res=" << a[i] << " ; ref=" << b[i] << "\r\n";
120 return(false);
121 }
122 }
123 }
124 return(true);
125 }
126
127 template<typename TA,typename TB,
128 typename std::enable_if<IsVector<TA>::value &&
129 !HasMatrixIndexing<TA>::value &&
130 IsVector<TB>::value &&
131 !HasMatrixIndexing<TB>::value,bool>::type = true>
132 bool validate(const TA &a, const TB &b,float abser = ABS_ERROR, float reler = REL_ERROR)
133 {
134 for(index_t i=0;i<a.length();i++)
135 {
136 if constexpr (number_traits<typename ElementType<TA>::type>::is_float)
137 {
138 if (ERROR(a[i],b[i],abser,reler) )
139 {
140 std::cout << "Error at:" << i << " ; res=" << a[i] << " ; ref=" << b[i] << "\r\n";
141 ERRVAL(a[i],b[i],abser,reler);
142 return(false);
143 }
144 }
145 else
146 {
147 if (a[i]!=b[i])
148 {
149 std::cout << "Error at:" << i << " ; res=" << a[i] << " ; ref=" << b[i] << "\r\n";
150 return(false);
151 }
152 }
153 }
154 return(true);
155 }
156
157
158 template<typename T,
159 typename std::enable_if<!std::is_pointer<T>::value
160 && !IsVector<T>::value && !HasMatrixIndexing<T>::value,bool>::type = true>
161 bool validate(const T a, const T b,float abser = ABS_ERROR, float reler = REL_ERROR)
162 {
163
164 if constexpr (number_traits<std::remove_cv_t<T>>::is_float)
165 {
166 if (ERROR(a,b,abser,reler))
167 {
168 std::cout << "Error: res=" << a << " ; ref=" << b << "\r\n";
169 ERRVAL(a,b,abser,reler);
170 return(false);
171 }
172 }
173 else
174 {
175 if (a != b )
176 {
177 std::cout << "Error : res=" << a << " ; ref=" << b << "\r\n";
178 return(false);
179 }
180 }
181
182 return(true);
183 }
184
185 template<typename MA,typename MB,
186 typename std::enable_if<
187 HasMatrixIndexing<MA>::value &&
188 HasMatrixIndexing<MB>::value &&
189 number_traits<typename ElementType<MA>::type>::is_float,bool>::type = true>
190 bool validate(const MA& a, const MB& b,float abser = ABS_ERROR, float reler = REL_ERROR)
191 {
192 for(index_t row=0;row < a.rows() ; row++)
193 {
194 for(index_t col=0;col < a.columns() ; col++)
195 {
196 if (ERROR(a(row,col),b(row,col),abser,reler) )
197 {
198 //std::cout << fabs(a(row,col)-b(row,col)) << "\r\n";
199 //std::cout << REL_ERROR*fabsf(a(row,col)) << "\r\n";
200 //std::cout << a(row,col) << "\r\n";
201 //std::cout << b(row,col) << "\r\n";
202
203 std::cout << "Error at : (" << row << "," << col << ") ; res=" << a(row,col) << " ; ref=" << b(row,col) << "\r\n";
204 ERRVAL(a(row,col),b(row,col),abser,reler);
205 return(false);
206 }
207 }
208 }
209 return(true);
210 }
211
212 template<typename MA,typename MB,
213 typename std::enable_if<
214 HasMatrixIndexing<MA>::value &&
215 HasMatrixIndexing<MB>::value &&
216 number_traits<typename ElementType<MA>::type>::is_float,bool>::type = true>
217 bool validateLT(const MA& a, const MB& b,float abser = ABS_ERROR, float reler = REL_ERROR)
218 {
219 for(index_t row=0;row < a.rows() ; row++)
220 {
221 for(index_t col=0;col <= row ; col++)
222 {
223 if (ERROR(a(row,col),b(row,col),abser,reler) )
224 {
225 //std::cout << fabs(a(row,col)-b(row,col)) << "\r\n";
226 //std::cout << REL_ERROR*fabsf(a(row,col)) << "\r\n";
227 //std::cout << a(row,col) << "\r\n";
228 //std::cout << b(row,col) << "\r\n";
229
230 std::cout << "Error at : (" << row << "," << col << ") ; res=" << a(row,col) << " ; ref=" << b(row,col) << "\r\n";
231 ERRVAL(a(row,col),b(row,col),abser,reler);
232 return(false);
233 }
234 }
235 }
236 return(true);
237 }
238
239 template<typename MA,typename MB,
240 typename std::enable_if<
241 HasMatrixIndexing<MA>::value &&
242 HasMatrixIndexing<MB>::value &&
243 number_traits<typename ElementType<MA>::type>::is_fixed,bool>::type = true>
244 bool validate(const MA& a, const MB& b,float abser = ABS_ERROR, float reler = REL_ERROR)
245 {
246 (void)abser;
247 (void)reler;
248 for(index_t row=0;row < a.rows() ; row++)
249 {
250 for(index_t col=0;col < a.columns() ; col++)
251 {
252 if (a(row,col).v != b(row,col).v)
253 {
254 std::cout << "Error at : (" << row << "," << col << ") ; res=" << a(row,col) << " ; ref=" << b(row,col) << "\r\n";
255 std::cout << "Error = " << abs(a(row,col).v - b(row,col).v) << "\r\n";
256 return(false);
257 }
258 }
259 }
260 return(true);
261 }
262
263 template<>
264 bool validate(const float32_t* a, const float32_t* b, std::size_t nb,float abser , float reler );
265
266
267 extern template
268 bool validate<>(const float32_t* a, const float32_t* b, std::size_t nb,float abser , float reler );
269
270
271
272
273
274 template<typename T>
title(const std::string & s)275 void title(const std::string &s)
276 {
277 #if !defined(SERIAL_DUMP)
278 #if defined(STATIC_TEST)
279 std::cout<<"\r\n\033[31;1;4m" << s << " " << NameOfType<T>::xls << "\033[0m\r\n";
280 #else
281 std::cout<<"\r\n\033[31;1;4m" << s << " dynamic " << NameOfType<T>::xls << "\033[0m\r\n";
282 #endif
283 #else
284 #if defined(STATIC_TEST)
285 std::cout << "\r\n" << s << " " << NameOfType<T>::xls << "\r\n";
286 #else
287 std::cout << "\r\n" << s << " dynamic " << NameOfType<T>::xls << "\r\n";
288 #endif
289 #endif
290 };