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