Project Ne10
An Open Optimized Software Library Project for the ARM Architecture
Loading...
Searching...
No Matches
unit_test_common.c
1/*
2 * Copyright 2012-15 ARM Limited and Contributors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of ARM Limited nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY ARM LIMITED AND CONTRIBUTORS "AS IS" AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL ARM LIMITED AND CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28/*
29 * NE10 Library : test/src/unit_test_common.c
30 */
31
32#include<time.h>
33#include<unistd.h>
34#include "unit_test_common.h"
35
36void FILL_FLOAT_ARRAY (ne10_float32_t *arr, ne10_uint32_t count)
37{
38 ne10_uint32_t i = 0;
39
40 sleep (1);
41
42 NE10_float_rng_init (time (NULL));
43
44 for (i = 0; i < count; i++)
45 {
46 arr[i] = NE10_float_rng_next();
47 }
48}
49
50void FILL_FLOAT_ARRAY_LIMIT (ne10_float32_t *arr, ne10_uint32_t count)
51{
52 ne10_uint32_t i = 0;
53
54 sleep (1);
55
56 NE10_float_rng_limit_init (time (NULL));
57
58 for (i = 0; i < count; i++)
59 {
60 arr[ i ] = NE10_float_rng_limit_next();
61 }
62}
63
64void FILL_FLOAT_ARRAY_LIMIT_GT1 (ne10_float32_t *arr, ne10_uint32_t count)
65{
66 ne10_uint32_t i = 0;
67
68 sleep (1);
69
70 NE10_float_rng_limit_gt1_init (time (NULL));
71
72 for (i = 0; i < count; i++)
73 {
74 arr[ i ] = NE10_float_rng_limit_gt1_next();
75 }
76}
77
78// this function checks whether the difference between two ne10_float32_t values is within the acceptable error range
79ne10_int32_t EQUALS_FLOAT (ne10_float32_t fa, ne10_float32_t fb , ne10_uint32_t err)
80{ ne10_float32_t tolerance = (ne10_float32_t)err / 200000;
81 if (abs(fa-fb) <= tolerance)
82 {
83 return 1;
84 }
85 else
86 {
87 return 0;
88 }
89}
90
91ne10_float32_t ARRAY_GUARD_SIG[ARRAY_GUARD_LEN] = { 10.0f, 20.0f, 30.0f, 40.0f };
92// this function adds a ARRAY_GUARD_LEN signature to the begining and the end of an array, minimum acceptable size for the array is 2*ARRAY_GUARD_LEN.
93ne10_int32_t GUARD_ARRAY (ne10_float32_t* array, ne10_uint32_t array_length)
94{
95 ne10_float32_t* the_array = array - ARRAY_GUARD_LEN;
96 memcpy (the_array, ARRAY_GUARD_SIG, sizeof (ARRAY_GUARD_SIG));
97 the_array = array + array_length;
98 memcpy (the_array, ARRAY_GUARD_SIG, sizeof (ARRAY_GUARD_SIG));
99 return 1;
100}
101
102// this function returns TRUE if the signature matches the ARRAY_GUARD_SIGguard and returns FALSE otherwise
103ne10_int32_t CHECK_ARRAY_GUARD (ne10_float32_t* array, ne10_uint32_t array_length)
104{
105 ne10_float32_t* the_array = array - ARRAY_GUARD_LEN;
106 ne10_int32_t i;
107 for (i = 0; i < ARRAY_GUARD_LEN; i++)
108 {
109 if (! EQUALS_FLOAT (the_array[i], ARRAY_GUARD_SIG[i], ERROR_MARGIN_SMALL))
110 {
111 fprintf (stderr, " ERROR: prefix array guard signature is wrong. \n");
112 return 0; // Match not found, return FALSE
113 }
114 }
115
116 the_array = array + array_length;
117 for (i = 0; i < ARRAY_GUARD_LEN; i++)
118 {
119 if (! EQUALS_FLOAT (the_array[i], ARRAY_GUARD_SIG[i], ERROR_MARGIN_SMALL))
120 {
121 fprintf (stderr, " ERROR: suffix array guard signature is wrong. \n");
122 return 0; // Match not found, return FALSE
123 }
124 }
125
126 return 1;
127}
128
129
130ne10_uint8_t ARRAY_GUARD_SIG_UINT8[ARRAY_GUARD_LEN] = { 0x12, 0x34, 0x56, 0x78 };
131// this function adds a ARRAY_GUARD_LEN signature to the begining and the end of an array, minimum acceptable size for the array is 2*ARRAY_GUARD_LEN.
132ne10_int32_t GUARD_ARRAY_UINT8 (ne10_uint8_t* array, ne10_uint32_t array_length)
133{
134 ne10_uint8_t* the_array = array - ARRAY_GUARD_LEN;
135 memcpy (the_array, ARRAY_GUARD_SIG_UINT8, sizeof (ARRAY_GUARD_SIG_UINT8));
136 the_array = array + array_length;
137 memcpy (the_array, ARRAY_GUARD_SIG_UINT8, sizeof (ARRAY_GUARD_SIG_UINT8));
138 return 1;
139}
140
141// this function returns TRUE if the signature matches the ARRAY_GUARD_SIGguard and returns FALSE otherwise
142ne10_int32_t CHECK_ARRAY_GUARD_UINT8 (ne10_uint8_t* array, ne10_uint32_t array_length)
143{
144 ne10_uint8_t* the_array = array - ARRAY_GUARD_LEN;
145 ne10_int32_t i;
146 for (i = 0; i < ARRAY_GUARD_LEN; i++)
147 {
148 if (the_array[i] != ARRAY_GUARD_SIG_UINT8[i])
149 {
150 fprintf (stderr, " ERROR: prefix array guard signature is wrong. \n");
151 return 0; // Match not found, return FALSE
152 }
153 }
154
155 the_array = array + array_length;
156 for (i = 0; i < ARRAY_GUARD_LEN; i++)
157 {
158 if (the_array[i] != ARRAY_GUARD_SIG_UINT8[i])
159 {
160 fprintf (stderr, " ERROR: suffix array guard signature is wrong. \n");
161 return 0; // Match not found, return FALSE
162 }
163 }
164
165 return 1;
166}
167
178ne10_float32_t CAL_SNR_FLOAT32 (ne10_float32_t *pRef, ne10_float32_t *pTest, ne10_uint32_t buffSize)
179{
180 ne10_float32_t EnergySignal = 0.0, EnergyError = 0.0;
181 ne10_uint32_t i;
182 ne10_float32_t SNR;
183
184 for (i = 0; i < buffSize; i++)
185 {
186 EnergySignal += pRef[i] * pRef[i];
187 EnergyError += (pRef[i] - pTest[i]) * (pRef[i] - pTest[i]);
188 }
189 SNR = 10 * log10 (EnergySignal / EnergyError);
190 return (SNR);
191
192}
193
204ne10_float32_t CAL_PSNR_UINT8 (ne10_uint8_t *pRef, ne10_uint8_t *pTest, ne10_uint32_t buffSize)
205{
206 ne10_float64_t mse = 0.0, max = 255.0;
207 ne10_uint32_t i;
208 ne10_float32_t PSNR;
209
210 for (i = 0; i < buffSize; i++)
211 {
212 mse += (pRef[i] - pTest[i]) * (pRef[i] - pTest[i]);
213 }
214 mse /= buffSize;
215 PSNR = 10 * log10 (max*max / mse);
216 return (PSNR);
217
218}
219char ne10_log_buffer[5000];
220char *ne10_log_buffer_ptr;
221
222void ne10_log(const char *func_name,
223 const char *format_str,
224 ne10_int32_t n,
225 ne10_int32_t time_c,
226 ne10_int32_t time_neon,
227 ne10_float32_t time_savings,
228 ne10_float32_t time_speedup)
229{
230 int byte_count = 0;
231 byte_count = sprintf(ne10_log_buffer_ptr,
232 "{ \"name\" : \"%s %d\", \"time_c\" : %d, "
233 "\"time_neon\" : %d },",
234 func_name, n, time_c, time_neon);
235 ne10_log_buffer_ptr += byte_count;
236
237 /* print the result, which is needed by command line performance test. */
238 fprintf (stdout,
239 "%25d%20d%20d%19.2f%%%18.2f:1\n",
240 n,
241 time_c,
242 time_neon,
243 time_savings,
244 time_speedup);
245}
246
247/* this function should handle all performance result output. ne10_log
248 * should be replaced by this function.
249 * info parameter contains the misc information, which is in below format:
250 * key1:value1\nkey2:value2\nkey3:value3
251 */
252void ne10_performance_print(ne10_print_target_t target,
253 long int neon_ticks,
254 long int c_ticks,
255 char *info)
256{
257 double f = (double)c_ticks / neon_ticks;
258 switch (target) {
259 case UBUNTU_COMMAND_LINE:
260 printf("\n%s\nneon(ms): %.2f c(ms): %.2f(ms) speedup: %.2f",
261 info,
262 neon_ticks / 1000.0,
263 c_ticks / 1000.0,
264 f);
265 break;
266 case ANDROID_DEMO:
267 break;
268 case IOS_DEMO:
269 break;
270 }
271}
272
273void diff(const ne10_uint8_t *mat1,
274 const ne10_uint8_t *mat2,
275 ne10_int32_t *dst,
276 ne10_uint32_t dst_stride,
277 ne10_uint32_t width,
278 ne10_uint32_t height,
279 ne10_uint32_t src_stride,
280 ne10_uint32_t channel)
281{
282 assert(mat1 != 0 && mat2 != 0 && dst != 0);
283
284 int i, j, k;
285
286 for(k = 0; k < channel; k++)
287 {
288 for(j = 0; j < height; j++)
289 {
290 const ne10_uint8_t *row1 = mat1 + j * src_stride;
291 const ne10_uint8_t *row2 = mat2 + j * src_stride;
292 ne10_int32_t *row_dst = dst + j * dst_stride / sizeof(ne10_int32_t);
293 for(i = 0; i < width; i++)
294 {
295 *(row_dst + i * channel + k) =
296 (ne10_int32_t) (*(row1 + i * channel + k)) -
297 *(row2 + i * channel + k);
298 }
299 }
300 }
301}
302
303/* check how many point is not in [-2, 2] */
304int diff_count(const ne10_int32_t *mat,
305 ne10_int32_t width,
306 ne10_int32_t height,
307 ne10_int32_t stride,
308 ne10_int32_t channel)
309{
310 assert(mat != 0);
311
312 int i, j, k;
313 int count = 0;
314 for(j = 0; j < height; j++)
315 {
316 const ne10_int32_t *row = mat + j * stride / sizeof(ne10_int32_t);
317 for(i = 0; i < width; i++)
318 {
319 for(k = 0; k < channel; k++)
320 {
321 const ne10_int32_t val = *(row + i * channel + k);
322 if (val != -1 && val != 0 && val != -2 && val != 1 && val != 2)
323 {
324 ++count;
325 }
326 }
327 }
328 }
329
330 return count;
331}
332
333void progress_bar(float progress)
334{
335 assert(progress <= 1);
336
337 static float progress_prev = 0;
338 if (progress != progress_prev)
339 {
340 int bar_width = 70;
341
342 printf("[");
343 int pos = bar_width * progress;
344 int i;
345 for (i = 0; i < bar_width; ++i) {
346 if (i < pos)
347 printf("=");
348 else if (i == pos)
349 printf(">");
350 else
351 printf(" ");
352 }
353 printf("] %d%%\r", (int)(progress * 100.0));
354 fflush(stdout);
355 progress_prev = progress;
356 }
357}