os/ossrv/genericopenlibs/liboil/tsrc/testsuite/align/src/align.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /*
     2  * Copyright (c) 2004 David A. Schleef <ds@schleef.org>
     3  * Copyright (c) 2005 Eric Anholt <anholt@FreeBSD.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 
    28 /* Tests math functions against the reference, failing if they differ by more
    29  * than some epsilon, and printing the difference.
    30  */
    31 #ifdef HAVE_CONFIG_H
    32 #include "config.h"
    33 #endif
    34 
    35 #include <stdio.h>
    36 #include <liboil/liboil.h>
    37 #include <ctype.h>
    38 #include <stdlib.h>
    39 #include <string.h>
    40 #include <math.h>
    41 #ifdef HAVE_INTTYPES_H
    42 #include <inttypes.h>
    43 #endif
    44 
    45 #include <liboil/liboilprototype.h>
    46 #include <liboil/liboiltest.h>
    47 #include <liboil/liboilcpu.h>
    48 #include <liboil/liboilparameter.h>
    49 
    50 #define LOG_FILE "c:\\logs\\testsuite_align_log.txt"
    51 #include "std_log_result.h"
    52 #define LOG_FILENAME_LINE __FILE__, __LINE__
    53 
    54 void create_xml(int result)
    55 {
    56     if(result)
    57         assert_failed = 1;
    58     
    59     testResultXml("testsuite_align");
    60     close_log_file();
    61 }
    62 
    63 #ifndef PRIx8
    64 #define PRIx8  "x"
    65 #define PRIx16 "x"
    66 #define PRIx32 "x"
    67 #define PRIx64 "llx"
    68 #define PRId8  "d"
    69 #define PRId16 "d"
    70 #define PRId32 "d"
    71 #define PRId64 "lld"
    72 #define PRIu8  "u"
    73 #define PRIu16 "u"
    74 #define PRIu32 "u"
    75 #define PRIu64 "llu"
    76 #endif
    77 
    78 
    79 /* Amount by which results of different types are allowed to deviate from the
    80  * reference.
    81  */
    82 #define INT_EPSILON 1
    83 #define FLOAT_EPSILON 0.0001
    84 
    85 void
    86 dump_array (void *data, void *ref_data, OilType type, int pre_n, int stride,
    87     int post_n)
    88 {
    89   int i, j;
    90   int s2 = oil_type_sizeof (type);
    91   double x;
    92 
    93 #define DUMP(type, format, int) do { \
    94   for(i=0;i<post_n;i++){ \
    95     float epsilon = (int) ? INT_EPSILON : FLOAT_EPSILON; \
    96     std_log(LOG_FILENAME_LINE,"    "); \
    97     for(j=0;j<pre_n;j++){ \
    98       x = fabs(OIL_GET(data, i*stride + j*s2, type) - \
    99           OIL_GET(ref_data, i*stride + j*s2, type)); \
   100       if (x > epsilon) { \
   101         std_log(LOG_FILENAME_LINE,"*" format "* (" format ") ", \
   102         OIL_GET(data, i*stride + j*s2, type), \
   103         OIL_GET(ref_data, i*stride + j*s2, type)); \
   104       } else { \
   105         std_log(LOG_FILENAME_LINE," " format " ", OIL_GET(data, i*stride + j*s2, type)); \
   106       } \
   107     } \
   108     std_log(LOG_FILENAME_LINE,"\n"); \
   109   } \
   110 } while(0)
   111 
   112   switch(type) {
   113     case OIL_TYPE_s8p:
   114     case OIL_TYPE_u8p:
   115       DUMP(int8_t, "0x%02" PRIx8, 1);
   116       break;
   117     case OIL_TYPE_s16p:
   118     case OIL_TYPE_u16p:
   119       DUMP(uint16_t, "0x%04" PRIx16, 1);
   120       break;
   121     case OIL_TYPE_s32p:
   122     case OIL_TYPE_u32p:
   123       DUMP(uint32_t, "0x%08" PRIx32, 1);
   124       break;
   125     case OIL_TYPE_f32p:
   126       DUMP(float, "%g", 0);
   127       break;
   128     case OIL_TYPE_s64p:
   129     case OIL_TYPE_u64p:
   130       DUMP(uint64_t, "0x%016" PRIx64, 1);
   131       break;
   132     case OIL_TYPE_f64p:
   133       DUMP(double, "%g", 0);
   134       break;
   135     default:
   136       break;
   137   }
   138 }
   139 
   140 void
   141 dump_source (OilTest *test)
   142 {
   143   int i;
   144   for(i=0;i<OIL_ARG_LAST;i++){
   145     OilParameter *p = &test->params[i];
   146     if (p->is_pointer) {
   147       if (p->direction == 'i' || p->direction == 's') {
   148         printf ("  %s:\n", p->parameter_name);
   149         dump_array (p->src_data + p->test_header,
   150             p->src_data + p->test_header,
   151             p->type, p->pre_n, p->stride, p->post_n);
   152       }
   153     }
   154   }
   155 }
   156 
   157 void
   158 dump_dest_ref (OilTest *test)
   159 {
   160   int i;
   161   for(i=0;i<OIL_ARG_LAST;i++){
   162     OilParameter *p = &test->params[i];
   163     if (p->is_pointer) {
   164       if (p->direction == 'd') {
   165         printf ("  %s:\n", p->parameter_name);
   166         dump_array (p->ref_data + p->test_header,
   167             p->ref_data + p->test_header,
   168             p->type, p->pre_n, p->stride, p->post_n);
   169       }
   170     }
   171   }
   172 }
   173 
   174 int
   175 test_difference (void *data, void *ref_data, OilType type, int pre_n, int stride,
   176     int post_n)
   177 {
   178   int i, j;
   179   int s2 = oil_type_sizeof (type);
   180   double x;
   181 
   182 #define CHECK(type, is_int) do { \
   183   float epsilon = (is_int) ? INT_EPSILON : FLOAT_EPSILON; \
   184   for(i=0;i<post_n;i++){ \
   185     for(j=0;j<pre_n;j++){ \
   186       x = fabs(OIL_GET(data, i*stride + j*s2, type) - \
   187           OIL_GET(ref_data, i*stride + j*s2, type)); \
   188       if (x > epsilon) { \
   189         return 1; \
   190       } \
   191     } \
   192   } \
   193   return 0; \
   194 } while(0)
   195 
   196   switch(type) {
   197     case OIL_TYPE_s8p:
   198       CHECK(int8_t, 1);
   199       break;
   200     case OIL_TYPE_u8p:
   201       CHECK(uint8_t, 1);
   202       break;
   203     case OIL_TYPE_s16p:
   204       CHECK(int16_t, 1);
   205       break;
   206     case OIL_TYPE_u16p:
   207       CHECK(uint16_t, 1);
   208       break;
   209     case OIL_TYPE_s32p:
   210       CHECK(int32_t, 1);
   211       break;
   212     case OIL_TYPE_u32p:
   213       CHECK(uint32_t, 1);
   214       break;
   215     case OIL_TYPE_s64p:
   216       CHECK(int64_t, 1);
   217       break;
   218     case OIL_TYPE_u64p:
   219       CHECK(uint64_t, 1);
   220       break;
   221     case OIL_TYPE_f32p:
   222       CHECK(float, 0);
   223       break;
   224     case OIL_TYPE_f64p:
   225       CHECK(double, 0);
   226       break;
   227     default:
   228       return 1;
   229   }
   230 }
   231 
   232 int
   233 check_test (OilTest *test)
   234 {
   235   int i, failed = 0;
   236   for(i=0;i<OIL_ARG_LAST;i++){
   237     OilParameter *p = &test->params[i];
   238     if (p->is_pointer) {
   239       if (p->direction == 'i' || p->direction == 'd') {
   240 	if (!test_difference(p->test_data + p->test_header,
   241             p->ref_data + p->test_header,
   242             p->type, p->pre_n, p->stride, p->post_n))
   243 	  continue;
   244         printf (" Failure in %s (marked by *, ref in ()):\n",
   245 	    p->parameter_name);
   246         dump_array (p->test_data + p->test_header,
   247             p->ref_data + p->test_header,
   248             p->type, p->pre_n, p->stride, p->post_n);
   249 	failed = 1;
   250       }
   251     }
   252   }
   253   return failed;
   254 }
   255 
   256 int check_class_with_alignment (OilFunctionClass *klass,
   257     OilArgType arg, int n, int align)
   258 {
   259   OilParameter *p;
   260   int align_offset;
   261   int test_failed = 0;
   262   OilTest *test;
   263   OilFunctionImpl *impl;
   264 
   265   test = oil_test_new(klass);
   266 
   267   p = &test->params[arg];
   268   align_offset = align * oil_type_sizeof(p->type);
   269   oil_test_set_test_header(test, p, OIL_TEST_HEADER + align_offset);
   270 
   271   oil_test_set_iterations(test, 1);
   272   test->n = n;
   273   test->m = n;
   274 
   275   impl = klass->reference_impl;
   276   oil_test_check_impl (test, impl);
   277 
   278   for (impl = klass->first_impl; impl; impl = impl->next) {
   279     if (impl == klass->reference_impl)
   280       continue;
   281     if (oil_impl_is_runnable (impl)) {
   282       if (!oil_test_check_impl (test, impl)) {
   283         printf ("impl %s with arg %d offset %d, n=%d\n", impl->name, arg,
   284             align_offset, n);
   285         std_log(LOG_FILENAME_LINE,"dests for %s:\n", klass->name);
   286         dump_dest_ref(test);
   287         std_log(LOG_FILENAME_LINE,"sources for %s:\n", klass->name);
   288         dump_source(test);
   289       }
   290     }
   291   }
   292   oil_test_free(test);
   293 
   294   if (test_failed)
   295       std_log(LOG_FILENAME_LINE,"Failed in class %s", klass->name);
   296   return test_failed;
   297 }
   298 
   299 /* Check a function class for all implementations matching the reference when
   300  * each parameter is varied in its offset from malloc's alignment by 0 - 3 units
   301  * times size of the type, and with the number of elements varying between 8 and
   302  * 11.
   303  */
   304 int check_class(OilFunctionClass *klass)
   305 {
   306   OilTest *test;
   307   int failed = 0;
   308   int i, n;
   309 
   310   oil_class_optimize (klass);
   311 
   312   std_log(LOG_FILENAME_LINE,"checking class %s\n", klass->name);
   313   
   314   test = oil_test_new(klass);
   315   for (i=0; i < OIL_ARG_LAST; i++) {
   316     OilParameter *p;
   317     int align;
   318 
   319     p = &test->params[i];
   320     if (!p->is_pointer) {
   321       continue;
   322     }
   323 
   324     for (n = 8; n <= 11; n++) {
   325       for (align = 0; align <= 3; align++) {
   326         failed |= check_class_with_alignment (klass, i, n, align);
   327       }
   328     }
   329   }
   330   oil_test_free (test);
   331 
   332   return failed;
   333 }
   334 
   335 int main (int argc, char *argv[])
   336 {
   337   int failed = 0;
   338   int i, n;
   339 
   340   std_log(LOG_FILENAME_LINE,"Test started testsuite_align");
   341   oil_init ();
   342 
   343   n = oil_class_get_n_classes ();
   344   for (i = 0; i < n; i++) {
   345     OilFunctionClass *klass = oil_class_get_by_index(i);
   346     failed |= check_class(klass);
   347   }
   348 
   349   if(failed)
   350       assert_failed = failed;
   351   if(assert_failed)
   352             std_log(LOG_FILENAME_LINE,"Test Fail");
   353   else
   354             std_log(LOG_FILENAME_LINE,"Test Successful");
   355   create_xml(0);
   356   return 0;
   357 }