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