genericopenlibs/liboil/src/liboiltest.c
changeset 18 47c74d1534e1
equal deleted inserted replaced
0:e4d67989cc36 18:47c74d1534e1
       
     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 }