|
1 /* |
|
2 * LIBOIL - Library of Optimized Inner Loops |
|
3 * Copyright (c) 2003,2004 David A. Schleef <ds@schleef.org> |
|
4 * All rights reserved. |
|
5 * |
|
6 * Redistribution and use in source and binary forms, with or without |
|
7 * modification, are permitted provided that the following conditions |
|
8 * are met: |
|
9 * 1. Redistributions of source code must retain the above copyright |
|
10 * notice, this list of conditions and the following disclaimer. |
|
11 * 2. Redistributions in binary form must reproduce the above copyright |
|
12 * notice, this list of conditions and the following disclaimer in the |
|
13 * documentation and/or other materials provided with the distribution. |
|
14 * |
|
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, |
|
19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
|
20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
|
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
|
23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
|
24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
25 * POSSIBILITY OF SUCH DAMAGE. |
|
26 */ |
|
27 //Portions Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. |
|
28 |
|
29 #ifdef HAVE_CONFIG_H |
|
30 #include <config.h> |
|
31 #endif |
|
32 |
|
33 #include <liboil/liboiltest.h> |
|
34 #include <liboil/liboildebug.h> |
|
35 #include <liboil/liboilrandom.h> |
|
36 #include <liboil/liboilprofile.h> |
|
37 #include <liboil/liboilfault.h> |
|
38 #include <stdlib.h> |
|
39 #include <string.h> |
|
40 #include <stdio.h> |
|
41 #include <math.h> |
|
42 |
|
43 #ifdef __SYMBIAN32__ |
|
44 #ifdef __WINSCW__ |
|
45 #pragma warn_unusedarg off |
|
46 #endif//__WINSCW__ |
|
47 #endif//__SYMBIAN32__ |
|
48 |
|
49 #define MAX_PARAMS 20 |
|
50 |
|
51 /** |
|
52 * SECTION:liboiltest |
|
53 * @title:OilTest |
|
54 * @short_description: Test and profile function implementations. |
|
55 * |
|
56 */ |
|
57 static void oil_test_init_params (OilTest *test); |
|
58 static void fill_array (void *ptr, OilType type, int pre_n, int stride, |
|
59 int post_n); |
|
60 static double check_array (void *data, void *ref, OilType type, int pre_n, |
|
61 int stride, int post_n); |
|
62 static int check_holes (void *data, OilType type, int pre_n, |
|
63 int stride, int post_n, int guard); |
|
64 |
|
65 /** |
|
66 * oil_test_new: |
|
67 * @klass: an OilFunctionClass |
|
68 * |
|
69 * Creates a new OilTest for the OilFunctionClass represented by @klass. |
|
70 * |
|
71 * Returns: the new OilTest |
|
72 */ |
|
73 #ifdef __SYMBIAN32__ |
|
74 EXPORT_C |
|
75 #endif |
|
76 OilTest * |
|
77 oil_test_new (OilFunctionClass *klass) |
|
78 { |
|
79 OilTest *test; |
|
80 OilPrototype *proto; |
|
81 int i; |
|
82 |
|
83 if (klass == NULL) return NULL; |
|
84 |
|
85 proto = oil_prototype_from_string (klass->prototype); |
|
86 if (proto == NULL) return NULL; |
|
87 |
|
88 test = malloc (sizeof (OilTest)); |
|
89 memset (test, 0, sizeof (OilTest)); |
|
90 |
|
91 test->klass = klass; |
|
92 test->proto = proto; |
|
93 test->impl = klass->reference_impl; |
|
94 test->tolerance = 0.0; |
|
95 |
|
96 for (i=0;i<proto->n_params;i++){ |
|
97 if (proto->params[i].parameter_type == OIL_ARG_UNKNOWN) { |
|
98 return NULL; |
|
99 } |
|
100 if (oil_type_is_floating_point(proto->params[i].type)) { |
|
101 test->tolerance = 0.001; |
|
102 } |
|
103 memcpy (&test->params[proto->params[i].parameter_type], &proto->params[i], |
|
104 sizeof(OilParameter)); |
|
105 } |
|
106 for (i=0;i<OIL_ARG_LAST;i++){ |
|
107 test->params[i].src_data = NULL; |
|
108 test->params[i].ref_data = NULL; |
|
109 test->params[i].test_data = NULL; |
|
110 test->params[i].test_header = OIL_TEST_HEADER; |
|
111 test->params[i].test_footer = OIL_TEST_FOOTER; |
|
112 } |
|
113 |
|
114 test->iterations = 10; |
|
115 test->n = 100; |
|
116 test->m = 100; |
|
117 |
|
118 return test; |
|
119 } |
|
120 |
|
121 /** |
|
122 * oil_test_free: |
|
123 * @test: the OilTest |
|
124 * |
|
125 * Frees memory associated with @test. |
|
126 */ |
|
127 #ifdef __SYMBIAN32__ |
|
128 EXPORT_C |
|
129 #endif |
|
130 void |
|
131 oil_test_free (OilTest *test) |
|
132 { |
|
133 int i; |
|
134 |
|
135 if (test->proto) { |
|
136 oil_prototype_free (test->proto); |
|
137 } |
|
138 |
|
139 for(i=0;i<OIL_ARG_LAST;i++){ |
|
140 if (test->params[i].src_data) { |
|
141 free (test->params[i].src_data); |
|
142 } |
|
143 if (test->params[i].ref_data) { |
|
144 free (test->params[i].ref_data); |
|
145 } |
|
146 if (test->params[i].test_data) { |
|
147 free (test->params[i].test_data); |
|
148 } |
|
149 } |
|
150 |
|
151 free(test); |
|
152 } |
|
153 |
|
154 /** |
|
155 * oil_test_set_impl: |
|
156 * @test: the OilTest |
|
157 * @impl: an OilFunctionImpl to set |
|
158 * |
|
159 * Sets the current implementation of @test to @impl. |
|
160 */ |
|
161 #ifdef __SYMBIAN32__ |
|
162 EXPORT_C |
|
163 #endif |
|
164 void |
|
165 oil_test_set_impl (OilTest *test, OilFunctionImpl *impl) |
|
166 { |
|
167 test->impl = impl; |
|
168 } |
|
169 |
|
170 /** |
|
171 * oil_test_set_iterations: |
|
172 * @test: the OilTest |
|
173 * @iterations: the number of iterations |
|
174 * |
|
175 * Sets the number of iterations of @test to @iterations. |
|
176 */ |
|
177 #ifdef __SYMBIAN32__ |
|
178 EXPORT_C |
|
179 #endif |
|
180 void |
|
181 oil_test_set_iterations (OilTest *test, int iterations) |
|
182 { |
|
183 test->iterations = iterations; |
|
184 } |
|
185 |
|
186 /** |
|
187 * oil_test_set_test_header: |
|
188 * @test: the OilTest |
|
189 * @p: the OilParameter to change the header for |
|
190 * @test_header: the number of bytes of guard header |
|
191 * |
|
192 * Sets the number of bytes of guard header for @p to @test_header. |
|
193 */ |
|
194 #ifdef __SYMBIAN32__ |
|
195 EXPORT_C |
|
196 #endif |
|
197 void |
|
198 oil_test_set_test_header (OilTest *test, OilParameter *p, int test_header) |
|
199 { |
|
200 p->test_header = test_header; |
|
201 } |
|
202 |
|
203 /** |
|
204 * oil_test_set_test_footer: |
|
205 * @test: the OilTest |
|
206 * @p: the OilParameter to change the footer for |
|
207 * @test_footer: the number of bytes of guard footer |
|
208 * |
|
209 * Sets the number of bytes of guard footer for @p to @test_footer. |
|
210 */ |
|
211 #ifdef __SYMBIAN32__ |
|
212 EXPORT_C |
|
213 #endif |
|
214 void |
|
215 oil_test_set_test_footer (OilTest *test, OilParameter *p, int test_footer) |
|
216 { |
|
217 p->test_footer = test_footer; |
|
218 } |
|
219 |
|
220 /** |
|
221 * oil_test_init: |
|
222 * @test: the OilTest |
|
223 * |
|
224 * Intializes @test. |
|
225 * |
|
226 * FIXME: needs work |
|
227 */ |
|
228 #ifdef __SYMBIAN32__ |
|
229 EXPORT_C |
|
230 #endif |
|
231 void |
|
232 oil_test_init (OilTest *test) |
|
233 { |
|
234 if (test->inited) { |
|
235 return; |
|
236 } |
|
237 |
|
238 oil_test_init_params(test); |
|
239 |
|
240 test->params[OIL_ARG_N].value = test->n; |
|
241 |
|
242 test->inited = 1; |
|
243 |
|
244 if (test->klass->test_func) { |
|
245 test->klass->test_func (test); |
|
246 } |
|
247 } |
|
248 |
|
249 #ifdef __WINSCW__ |
|
250 #pragma suppress_warnings on |
|
251 #endif//__WINSCW__ |
|
252 #ifdef __ARMCC__ |
|
253 #pragma diag_remark 188 |
|
254 #endif//__ARMCC__ |
|
255 |
|
256 static void |
|
257 oil_test_check_function (void * priv) |
|
258 { |
|
259 OilTest *test = priv; |
|
260 int i; |
|
261 int j; |
|
262 unsigned long args[MAX_PARAMS]; |
|
263 unsigned int pointer_mask; |
|
264 |
|
265 oil_test_init (test); |
|
266 |
|
267 OIL_LOG("calling function %s", test->impl->name); |
|
268 |
|
269 pointer_mask = 1; |
|
270 for(i=0;i<test->proto->n_params;i++){ |
|
271 OilParameter *p; |
|
272 j = test->proto->params[i].parameter_type; |
|
273 p = &test->params[j]; |
|
274 |
|
275 pointer_mask <<= 1; |
|
276 OIL_LOG(" %s: 0x%08lx (%ld)", oil_arg_type_name (j), p->value, p->value); |
|
277 if (p->is_pointer) { |
|
278 pointer_mask |= 1; |
|
279 if (p->direction == 's') { |
|
280 args[i] = (unsigned long)p->src_data + p->test_header; |
|
281 } else if (p->direction == 'i') { |
|
282 memcpy (p->test_data, p->src_data, p->size); |
|
283 args[i] = (unsigned long)p->test_data + p->test_header; |
|
284 } else if (p->direction == 'd') { |
|
285 memset (p->test_data, p->guard, p->size); |
|
286 args[i] = (unsigned long)p->test_data + p->test_header; |
|
287 } else { |
|
288 OIL_ERROR ("not reached"); |
|
289 } |
|
290 } else { |
|
291 args[i] = p->value; |
|
292 } |
|
293 } |
|
294 #ifdef __WINSCW__ |
|
295 #pragma suppress_warnings off |
|
296 #endif//__WINSCW__ |
|
297 |
|
298 oil_profile_init (&test->prof); |
|
299 for(i=0;i<test->iterations;i++){ |
|
300 int k; |
|
301 |
|
302 for(k=0;k<test->proto->n_params;k++){ |
|
303 OilParameter *p; |
|
304 j = test->proto->params[k].parameter_type; |
|
305 p = &test->params[j]; |
|
306 if (p->direction == 'i') { |
|
307 memcpy (p->test_data, p->src_data, p->size); |
|
308 } |
|
309 } |
|
310 _oil_test_marshal_function (test->impl->func, args, test->proto->n_params, |
|
311 pointer_mask, &test->prof); |
|
312 } |
|
313 |
|
314 oil_profile_get_ave_std (&test->prof, &test->profile_ave, |
|
315 &test->profile_std); |
|
316 } |
|
317 |
|
318 /** |
|
319 * oil_test_check_ref: |
|
320 * @test: the OilTest |
|
321 * |
|
322 * Runs the test specified by @test on the reference function of the |
|
323 * class being tested. |
|
324 */ |
|
325 #ifdef __SYMBIAN32__ |
|
326 EXPORT_C |
|
327 #endif |
|
328 void |
|
329 oil_test_check_ref (OilTest *test) |
|
330 { |
|
331 int i; |
|
332 |
|
333 if (test->proto->n_params > MAX_PARAMS) { |
|
334 OIL_ERROR ("function class %s has too many parameters", |
|
335 test->klass->name); |
|
336 return; |
|
337 } |
|
338 if (test->klass->reference_impl == NULL) { |
|
339 OIL_ERROR ("function class %s has no reference implementation", |
|
340 test->klass->name); |
|
341 return; |
|
342 } |
|
343 |
|
344 test->impl = test->klass->reference_impl; |
|
345 |
|
346 oil_test_check_function (test); |
|
347 |
|
348 for(i=0;i<OIL_ARG_LAST;i++){ |
|
349 OilParameter *p = &test->params[i]; |
|
350 |
|
351 if (p->is_pointer) { |
|
352 if (p->direction == 'i' || p->direction == 'd') { |
|
353 memcpy (p->ref_data, p->test_data, p->size); |
|
354 } |
|
355 } |
|
356 } |
|
357 |
|
358 test->tested_ref = 1; |
|
359 } |
|
360 |
|
361 static int |
|
362 check_guard (uint8_t *data, int n, int guard) |
|
363 { |
|
364 int i; |
|
365 for(i=0;i<n;i++) { |
|
366 if (data[i] != guard) return 0; |
|
367 } |
|
368 return 1; |
|
369 } |
|
370 |
|
371 /** |
|
372 * oil_test_check_impl: |
|
373 * @test: the OilTest |
|
374 * @impl: an OilFunctionImpl |
|
375 * |
|
376 * Runs the testing procedure described by @test on the implementation |
|
377 * @impl. |
|
378 * |
|
379 * Returns: 1 if @impl passes the test, 0 if it fails |
|
380 */ |
|
381 #ifdef __SYMBIAN32__ |
|
382 EXPORT_C |
|
383 #endif |
|
384 int |
|
385 oil_test_check_impl (OilTest *test, OilFunctionImpl *impl) |
|
386 { |
|
387 double x; |
|
388 int i; |
|
389 int n; |
|
390 int fail = 0; |
|
391 int ret; |
|
392 |
|
393 if (test->proto->n_params > MAX_PARAMS) { |
|
394 OIL_ERROR ("function has too many parameters"); |
|
395 return 0; |
|
396 } |
|
397 |
|
398 if (!test->inited || !test->tested_ref) { |
|
399 oil_test_check_ref(test); |
|
400 } |
|
401 |
|
402 test->impl = impl; |
|
403 ret = oil_fault_check_try (oil_test_check_function, test); |
|
404 if (!ret) { |
|
405 OIL_ERROR ("illegal instruction in %s", test->impl->name); |
|
406 test->profile_ave = 0; |
|
407 test->profile_std = 0; |
|
408 |
|
409 return 0; |
|
410 } |
|
411 |
|
412 x = 0; |
|
413 n = 0; |
|
414 for(i=0;i<OIL_ARG_LAST;i++){ |
|
415 OilParameter *p = &test->params[i]; |
|
416 |
|
417 if (p->is_pointer) { |
|
418 if (p->direction == 'i' || p->direction == 'd') { |
|
419 x += check_array (p->test_data + p->test_header, |
|
420 p->ref_data + p->test_header, p->type, p->pre_n, p->stride, |
|
421 p->post_n); |
|
422 n += p->pre_n * p->post_n; |
|
423 if (!check_guard (p->test_data, p->test_header, p->guard)) { |
|
424 fail = 1; |
|
425 OIL_ERROR("function %s wrote before area for parameter %s", |
|
426 test->impl->name, p->parameter_name); |
|
427 } |
|
428 if (!check_guard ((uint8_t *)p->test_data + p->size - p->test_footer, |
|
429 p->test_footer, p->guard)) { |
|
430 fail = 1; |
|
431 OIL_ERROR("function %s wrote after area for parameter %s", |
|
432 test->impl->name, p->parameter_name); |
|
433 } |
|
434 if (!check_holes (p->test_data, p->type, p->pre_n, p->stride, |
|
435 p->post_n, p->guard)) { |
|
436 fail = 1; |
|
437 OIL_ERROR("function %s wrote in interstitial area for parameter %s", |
|
438 test->impl->name, p->parameter_name); |
|
439 } |
|
440 } |
|
441 } |
|
442 } |
|
443 OIL_DEBUG("sum of absolute differences %g for %d values", x, n); |
|
444 test->sum_abs_diff = x; |
|
445 test->n_points = n; |
|
446 |
|
447 if (x > test->tolerance * n || fail) { |
|
448 OIL_ERROR ("function %s in class %s failed check (%g > %g) || (outside=%d)", |
|
449 test->impl->name, test->klass->name, x, test->tolerance * n, fail); |
|
450 return 0; |
|
451 } |
|
452 |
|
453 return 1; |
|
454 } |
|
455 |
|
456 /** |
|
457 * oil_test_cleanup |
|
458 * @test: the OilTest |
|
459 * |
|
460 * Cleans up @test. |
|
461 * |
|
462 * FIXME: needs work |
|
463 */ |
|
464 #ifdef __SYMBIAN32__ |
|
465 EXPORT_C |
|
466 #endif |
|
467 void |
|
468 oil_test_cleanup (OilTest *test) |
|
469 { |
|
470 OilParameter *params = test->params; |
|
471 |
|
472 /* src1 */ |
|
473 if(params[OIL_ARG_SRC1].type) { |
|
474 if (!params[OIL_ARG_SSTR1].type) { |
|
475 params[OIL_ARG_SSTR1].value = oil_type_sizeof (params[OIL_ARG_SRC1].type); |
|
476 } |
|
477 } |
|
478 |
|
479 /* src2 */ |
|
480 if(params[OIL_ARG_SRC2].type) { |
|
481 if (!params[OIL_ARG_SSTR2].type) { |
|
482 params[OIL_ARG_SSTR2].value = oil_type_sizeof (params[OIL_ARG_SRC2].type); |
|
483 } |
|
484 } |
|
485 |
|
486 /* src3 */ |
|
487 if(params[OIL_ARG_SRC3].type) { |
|
488 if (!params[OIL_ARG_SSTR3].type) { |
|
489 params[OIL_ARG_SSTR3].value = oil_type_sizeof (params[OIL_ARG_SRC3].type); |
|
490 } |
|
491 } |
|
492 |
|
493 /* dest1 */ |
|
494 if(params[OIL_ARG_DEST1].type) { |
|
495 if (!params[OIL_ARG_DSTR1].type) { |
|
496 params[OIL_ARG_DSTR1].value = oil_type_sizeof (params[OIL_ARG_DEST1].type); |
|
497 } |
|
498 } |
|
499 |
|
500 /* dest2 */ |
|
501 if(params[OIL_ARG_DEST2].type) { |
|
502 if (!params[OIL_ARG_DSTR2].type) { |
|
503 params[OIL_ARG_DSTR2].value = oil_type_sizeof (params[OIL_ARG_DEST2].type); |
|
504 } |
|
505 } |
|
506 |
|
507 /* dest3 */ |
|
508 if(params[OIL_ARG_DEST3].type) { |
|
509 if (!params[OIL_ARG_DSTR3].type) { |
|
510 params[OIL_ARG_DSTR3].value = oil_type_sizeof (params[OIL_ARG_DEST3].type); |
|
511 } |
|
512 } |
|
513 |
|
514 } |
|
515 |
|
516 |
|
517 static void |
|
518 init_parameter (OilTest *test, OilParameter *p, OilParameter *ps) |
|
519 { |
|
520 if (!p->type) return; |
|
521 |
|
522 p->pre_n = p->prestride_length; |
|
523 if (p->prestride_var == 1) { |
|
524 p->pre_n += test->n; |
|
525 } |
|
526 if (p->prestride_var == 2) { |
|
527 p->pre_n += test->m; |
|
528 } |
|
529 |
|
530 if (ps->value) { |
|
531 p->stride = ps->value; |
|
532 } else { |
|
533 p->stride = oil_type_sizeof (p->type) * p->pre_n; |
|
534 ps->value = p->stride; |
|
535 } |
|
536 |
|
537 p->post_n = p->poststride_length; |
|
538 if (p->poststride_var == 1) { |
|
539 p->post_n += test->n; |
|
540 } |
|
541 if (p->poststride_var == 2) { |
|
542 p->post_n += test->m; |
|
543 } |
|
544 |
|
545 p->size = p->stride * p->post_n + p->test_header + p->test_footer; |
|
546 p->guard = oil_rand_u8(); |
|
547 |
|
548 if (p->direction == 'i' || p->direction == 's') { |
|
549 if (p->src_data) free (p->src_data); |
|
550 |
|
551 OIL_DEBUG("allocating %d bytes for src_data for %s", p->size, p->parameter_name); |
|
552 p->src_data = malloc (p->size); |
|
553 memset (p->src_data, p->guard, p->size); |
|
554 fill_array (p->src_data + p->test_header, p->type, p->pre_n, p->stride, p->post_n); |
|
555 } |
|
556 |
|
557 if (p->direction == 'i' || p->direction == 'd') { |
|
558 if (p->ref_data) free (p->ref_data); |
|
559 p->ref_data = malloc (p->size); |
|
560 memset (p->ref_data, p->guard, p->size); |
|
561 OIL_DEBUG("allocating %d bytes for ref_data and test_data for %s", p->size, p->parameter_name); |
|
562 |
|
563 if (p->test_data) free (p->test_data); |
|
564 p->test_data = malloc (p->size); |
|
565 memset (p->test_data, p->guard, p->size); |
|
566 } |
|
567 } |
|
568 |
|
569 static void |
|
570 oil_test_init_params (OilTest *test) |
|
571 { |
|
572 init_parameter (test, &test->params[OIL_ARG_DEST1], |
|
573 &test->params[OIL_ARG_DSTR1]); |
|
574 init_parameter (test, &test->params[OIL_ARG_DEST2], |
|
575 &test->params[OIL_ARG_DSTR2]); |
|
576 init_parameter (test, &test->params[OIL_ARG_DEST3], |
|
577 &test->params[OIL_ARG_DSTR3]); |
|
578 |
|
579 init_parameter (test, &test->params[OIL_ARG_SRC1], |
|
580 &test->params[OIL_ARG_SSTR1]); |
|
581 init_parameter (test, &test->params[OIL_ARG_SRC2], |
|
582 &test->params[OIL_ARG_SSTR2]); |
|
583 init_parameter (test, &test->params[OIL_ARG_SRC3], |
|
584 &test->params[OIL_ARG_SSTR3]); |
|
585 init_parameter (test, &test->params[OIL_ARG_SRC4], |
|
586 &test->params[OIL_ARG_SSTR4]); |
|
587 init_parameter (test, &test->params[OIL_ARG_SRC5], |
|
588 &test->params[OIL_ARG_SSTR5]); |
|
589 |
|
590 init_parameter (test, &test->params[OIL_ARG_INPLACE1], |
|
591 &test->params[OIL_ARG_ISTR1]); |
|
592 init_parameter (test, &test->params[OIL_ARG_INPLACE2], |
|
593 &test->params[OIL_ARG_ISTR2]); |
|
594 } |
|
595 |
|
596 static void |
|
597 fill_array (void *data, OilType type, int pre_n, int stride, int post_n) |
|
598 { |
|
599 int i; |
|
600 |
|
601 #define FILL(type,func) do {\ |
|
602 for(i=0;i<post_n;i++){ \ |
|
603 func (OIL_OFFSET(data, i*stride), pre_n); \ |
|
604 } \ |
|
605 }while(0) |
|
606 |
|
607 switch (type) { |
|
608 case OIL_TYPE_s8p: |
|
609 FILL(int8_t,oil_random_s8); |
|
610 break; |
|
611 case OIL_TYPE_u8p: |
|
612 FILL(uint8_t,oil_random_u8); |
|
613 break; |
|
614 case OIL_TYPE_s16p: |
|
615 FILL(int16_t,oil_random_s16); |
|
616 break; |
|
617 case OIL_TYPE_u16p: |
|
618 FILL(uint16_t,oil_random_u16); |
|
619 break; |
|
620 case OIL_TYPE_s32p: |
|
621 FILL(int32_t,oil_random_s32); |
|
622 break; |
|
623 case OIL_TYPE_u32p: |
|
624 FILL(uint32_t,oil_random_u32); |
|
625 break; |
|
626 case OIL_TYPE_s64p: |
|
627 FILL(int64_t,oil_random_s64); |
|
628 break; |
|
629 case OIL_TYPE_u64p: |
|
630 FILL(uint64_t,oil_random_u64); |
|
631 break; |
|
632 case OIL_TYPE_f32p: |
|
633 FILL(float,oil_random_f32); |
|
634 break; |
|
635 case OIL_TYPE_f64p: |
|
636 FILL(double,oil_random_f64); |
|
637 break; |
|
638 default: |
|
639 OIL_ERROR ("should not be reached (type == %d)", type); |
|
640 return; |
|
641 break; |
|
642 } |
|
643 } |
|
644 |
|
645 static double |
|
646 check_array (void *data, void *ref, OilType type, int pre_n, int stride, int post_n) |
|
647 { |
|
648 int i; |
|
649 int j; |
|
650 int s2 = oil_type_sizeof (type); |
|
651 double x = 0; |
|
652 |
|
653 #if 0 |
|
654 OIL_ERROR ("check array pre_n=%d stride=%d post_n=%d", |
|
655 pre_n, stride, post_n); |
|
656 #endif |
|
657 |
|
658 #define CHECK(type) do {\ |
|
659 for(i=0;i<post_n;i++){ \ |
|
660 for(j=0;j<pre_n;j++){ \ |
|
661 x += fabs((double)OIL_GET(data, i*stride + j*s2, type) - \ |
|
662 (double)OIL_GET(ref, i*stride + j*s2, type)); \ |
|
663 } \ |
|
664 } \ |
|
665 }while(0) |
|
666 |
|
667 switch (type) { |
|
668 case OIL_TYPE_s8p: |
|
669 CHECK(int8_t); |
|
670 break; |
|
671 case OIL_TYPE_u8p: |
|
672 CHECK(uint8_t); |
|
673 break; |
|
674 case OIL_TYPE_s16p: |
|
675 CHECK(int16_t); |
|
676 break; |
|
677 case OIL_TYPE_u16p: |
|
678 CHECK(uint16_t); |
|
679 break; |
|
680 case OIL_TYPE_s32p: |
|
681 CHECK(int32_t); |
|
682 break; |
|
683 case OIL_TYPE_u32p: |
|
684 CHECK(uint32_t); |
|
685 break; |
|
686 case OIL_TYPE_s64p: |
|
687 CHECK(int64_t); |
|
688 break; |
|
689 case OIL_TYPE_u64p: |
|
690 CHECK(uint64_t); |
|
691 break; |
|
692 case OIL_TYPE_f32p: |
|
693 CHECK(float); |
|
694 break; |
|
695 case OIL_TYPE_f64p: |
|
696 CHECK(double); |
|
697 break; |
|
698 default: |
|
699 OIL_ERROR ("should not be reached (type == %d)", type); |
|
700 return 1e9; |
|
701 break; |
|
702 } |
|
703 return x; |
|
704 } |
|
705 |
|
706 static int |
|
707 check_holes (void *data, OilType type, int pre_n, int stride, int post_n, |
|
708 int guard) |
|
709 { |
|
710 int i; |
|
711 int chunk_size; |
|
712 int hole_size; |
|
713 |
|
714 chunk_size = pre_n * oil_type_sizeof (type); |
|
715 hole_size = stride - chunk_size; |
|
716 if (hole_size == 0) { |
|
717 return 1; |
|
718 } |
|
719 |
|
720 for(i=0;i<post_n;i++){ |
|
721 if (!check_guard (OIL_OFFSET(data, stride * i + chunk_size), |
|
722 hole_size, guard)) { |
|
723 return 0; |
|
724 } |
|
725 } |
|
726 |
|
727 return 1; |
|
728 } |
|
729 |
|
730 #ifdef __SYMBIAN32__ |
|
731 EXPORT_C |
|
732 #endif |
|
733 void * |
|
734 oil_test_get_source_data (OilTest *test, OilArgType arg_type) |
|
735 { |
|
736 uint8_t *ptr; |
|
737 |
|
738 ptr = test->params[arg_type].src_data; |
|
739 ptr += test->params[arg_type].test_header; |
|
740 |
|
741 return ptr; |
|
742 } |
|
743 |
|
744 #ifdef __SYMBIAN32__ |
|
745 EXPORT_C |
|
746 #endif |
|
747 int |
|
748 oil_test_get_arg_pre_n (OilTest *test, OilArgType arg_type) |
|
749 { |
|
750 return test->params[arg_type].pre_n; |
|
751 } |
|
752 |
|
753 #ifdef __SYMBIAN32__ |
|
754 EXPORT_C |
|
755 #endif |
|
756 int |
|
757 oil_test_get_arg_post_n (OilTest *test, OilArgType arg_type) |
|
758 { |
|
759 return test->params[arg_type].post_n; |
|
760 } |
|
761 |
|
762 #ifdef __SYMBIAN32__ |
|
763 EXPORT_C |
|
764 #endif |
|
765 int |
|
766 oil_test_get_arg_stride (OilTest *test, OilArgType arg_type) |
|
767 { |
|
768 return test->params[arg_type].stride; |
|
769 } |
|
770 |
|
771 #ifdef __SYMBIAN32__ |
|
772 EXPORT_C |
|
773 #endif |
|
774 int |
|
775 oil_test_get_value (OilTest *test, OilArgType arg_type) |
|
776 { |
|
777 return test->params[arg_type].value; |
|
778 } |