Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2009 VMware, Inc.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28.  
  29. /**
  30.  * @file
  31.  * Shared testing code.
  32.  *
  33.  * @author Jose Fonseca <jfonseca@vmware.com>
  34.  */
  35.  
  36.  
  37. #include "util/u_cpu_detect.h"
  38. #include "util/u_math.h"
  39.  
  40. #include "gallivm/lp_bld_const.h"
  41. #include "gallivm/lp_bld_init.h"
  42. #include "gallivm/lp_bld_debug.h"
  43. #include "lp_test.h"
  44.  
  45.  
  46. void
  47. dump_type(FILE *fp,
  48.           struct lp_type type)
  49. {
  50.    fprintf(fp, "%s%s%u%sx%u",
  51.            type.sign ? (type.floating || type.fixed ? "" : "s") : "u",
  52.            type.floating ? "f" : (type.fixed ? "h" : "i"),
  53.            type.width,
  54.            type.norm ? "n" : "",
  55.            type.length);
  56. }
  57.  
  58.  
  59. double
  60. read_elem(struct lp_type type, const void *src, unsigned index)
  61. {
  62.    double scale = lp_const_scale(type);
  63.    double value;
  64.    assert(index < type.length);
  65.    if (type.floating) {
  66.       switch(type.width) {
  67.       case 32:
  68.          value = *((const float *)src + index);
  69.          break;
  70.       case 64:
  71.          value =  *((const double *)src + index);
  72.          break;
  73.       default:
  74.          assert(0);
  75.          return 0.0;
  76.       }
  77.    }
  78.    else {
  79.       if(type.sign) {
  80.          switch(type.width) {
  81.          case 8:
  82.             value = *((const int8_t *)src + index);
  83.             break;
  84.          case 16:
  85.             value = *((const int16_t *)src + index);
  86.             break;
  87.          case 32:
  88.             value = *((const int32_t *)src + index);
  89.             break;
  90.          case 64:
  91.             value = *((const int64_t *)src + index);
  92.             break;
  93.          default:
  94.             assert(0);
  95.             return 0.0;
  96.          }
  97.       }
  98.       else {
  99.          switch(type.width) {
  100.          case 8:
  101.             value = *((const uint8_t *)src + index);
  102.             break;
  103.          case 16:
  104.             value = *((const uint16_t *)src + index);
  105.             break;
  106.          case 32:
  107.             value = *((const uint32_t *)src + index);
  108.             break;
  109.          case 64:
  110.             value = *((const uint64_t *)src + index);
  111.             break;
  112.          default:
  113.             assert(0);
  114.             return 0.0;
  115.          }
  116.       }
  117.    }
  118.    return value/scale;
  119. }
  120.  
  121.  
  122. void
  123. write_elem(struct lp_type type, void *dst, unsigned index, double value)
  124. {
  125.    assert(index < type.length);
  126.    if(!type.sign && value < 0.0)
  127.       value = 0.0;
  128.    if(type.norm && value < -1.0)
  129.       value = -1.0;
  130.    if(type.norm && value > 1.0)
  131.       value = 1.0;
  132.    if (type.floating) {
  133.       switch(type.width) {
  134.       case 32:
  135.          *((float *)dst + index) = (float)(value);
  136.          break;
  137.       case 64:
  138.           *((double *)dst + index) = value;
  139.          break;
  140.       default:
  141.          assert(0);
  142.       }
  143.    }
  144.    else {
  145.       double scale = lp_const_scale(type);
  146.       value = round(value*scale);
  147.       if(type.sign) {
  148.          long long lvalue = (long long)value;
  149.          lvalue = MIN2(lvalue, ((long long)1 << (type.width - 1)) - 1);
  150.          switch(type.width) {
  151.          case 8:
  152.             *((int8_t *)dst + index) = (int8_t)lvalue;
  153.             break;
  154.          case 16:
  155.             *((int16_t *)dst + index) = (int16_t)lvalue;
  156.             break;
  157.          case 32:
  158.             *((int32_t *)dst + index) = (int32_t)lvalue;
  159.             break;
  160.          case 64:
  161.             *((int64_t *)dst + index) = (int64_t)lvalue;
  162.             break;
  163.          default:
  164.             assert(0);
  165.          }
  166.       }
  167.       else {
  168.          unsigned long long lvalue = (long long)value;
  169.          lvalue = MIN2(lvalue, ((unsigned long long)1 << type.width) - 1);
  170.          switch(type.width) {
  171.          case 8:
  172.             *((uint8_t *)dst + index) = (uint8_t)lvalue;
  173.             break;
  174.          case 16:
  175.             *((uint16_t *)dst + index) = (uint16_t)lvalue;
  176.             break;
  177.          case 32:
  178.             *((uint32_t *)dst + index) = (uint32_t)lvalue;
  179.             break;
  180.          case 64:
  181.             *((uint64_t *)dst + index) = (uint64_t)lvalue;
  182.             break;
  183.          default:
  184.             assert(0);
  185.          }
  186.       }
  187.    }
  188. }
  189.  
  190.  
  191. void
  192. random_elem(struct lp_type type, void *dst, unsigned index)
  193. {
  194.    double value;
  195.    assert(index < type.length);
  196.    value = (double)rand()/(double)RAND_MAX;
  197.    if(!type.norm) {
  198.       if (type.floating) {
  199.          value *= 2.0;
  200.       }
  201.       else {
  202.          unsigned long long mask;
  203.          if (type.fixed)
  204.             mask = ((unsigned long long)1 << (type.width / 2)) - 1;
  205.          else if (type.sign)
  206.             mask = ((unsigned long long)1 << (type.width - 1)) - 1;
  207.          else
  208.             mask = ((unsigned long long)1 << type.width) - 1;
  209.          value += (double)(mask & rand());
  210.       }
  211.    }
  212.    if(!type.sign)
  213.       if(rand() & 1)
  214.          value = -value;
  215.    write_elem(type, dst, index, value);
  216. }
  217.  
  218.  
  219. void
  220. read_vec(struct lp_type type, const void *src, double *dst)
  221. {
  222.    unsigned i;
  223.    for (i = 0; i < type.length; ++i)
  224.       dst[i] = read_elem(type, src, i);
  225. }
  226.  
  227.  
  228. void
  229. write_vec(struct lp_type type, void *dst, const double *src)
  230. {
  231.    unsigned i;
  232.    for (i = 0; i < type.length; ++i)
  233.       write_elem(type, dst, i, src[i]);
  234. }
  235.  
  236.  
  237. float
  238. random_float(void)
  239. {
  240.     return (float)((double)rand()/(double)RAND_MAX);
  241. }
  242.  
  243.  
  244. void
  245. random_vec(struct lp_type type, void *dst)
  246. {
  247.    unsigned i;
  248.    for (i = 0; i < type.length; ++i)
  249.       random_elem(type, dst, i);
  250. }
  251.  
  252.  
  253. boolean
  254. compare_vec_with_eps(struct lp_type type, const void *res, const void *ref, double eps)
  255. {
  256.    unsigned i;
  257.    eps *= type.floating ? 8.0 : 2.0;
  258.    for (i = 0; i < type.length; ++i) {
  259.       double res_elem = read_elem(type, res, i);
  260.       double ref_elem = read_elem(type, ref, i);
  261.       double delta = res_elem - ref_elem;
  262.       if (ref_elem < -1.0 || ref_elem > 1.0) {
  263.          delta /= ref_elem;
  264.       }
  265.       delta = fabs(delta);
  266.       if (delta >= eps) {
  267.          return FALSE;
  268.       }
  269.    }
  270.  
  271.    return TRUE;
  272. }
  273.  
  274.  
  275. boolean
  276. compare_vec(struct lp_type type, const void *res, const void *ref)
  277. {
  278.    double eps = lp_const_eps(type);
  279.    return compare_vec_with_eps(type, res, ref, eps);
  280. }
  281.  
  282.  
  283. void
  284. dump_vec(FILE *fp, struct lp_type type, const void *src)
  285. {
  286.    unsigned i;
  287.    for (i = 0; i < type.length; ++i) {
  288.       if(i)
  289.          fprintf(fp, " ");
  290.       if (type.floating) {
  291.          double value;
  292.          switch(type.width) {
  293.          case 32:
  294.             value = *((const float *)src + i);
  295.             break;
  296.          case 64:
  297.             value = *((const double *)src + i);
  298.             break;
  299.          default:
  300.             assert(0);
  301.             value = 0.0;
  302.          }
  303.          fprintf(fp, "%f", value);
  304.       }
  305.       else {
  306.          if(type.sign && !type.norm) {
  307.             long long value;
  308.             const char *format;
  309.             switch(type.width) {
  310.             case 8:
  311.                value = *((const int8_t *)src + i);
  312.                format = "%3lli";
  313.                break;
  314.             case 16:
  315.                value = *((const int16_t *)src + i);
  316.                format = "%5lli";
  317.                break;
  318.             case 32:
  319.                value = *((const int32_t *)src + i);
  320.                format = "%10lli";
  321.                break;
  322.             case 64:
  323.                value = *((const int64_t *)src + i);
  324.                format = "%20lli";
  325.                break;
  326.             default:
  327.                assert(0);
  328.                value = 0.0;
  329.                format = "?";
  330.             }
  331.             fprintf(fp, format, value);
  332.          }
  333.          else {
  334.             unsigned long long value;
  335.             const char *format;
  336.             switch(type.width) {
  337.             case 8:
  338.                value = *((const uint8_t *)src + i);
  339.                format = type.norm ? "%2x" : "%4llu";
  340.                break;
  341.             case 16:
  342.                value = *((const uint16_t *)src + i);
  343.                format = type.norm ? "%4x" : "%6llx";
  344.                break;
  345.             case 32:
  346.                value = *((const uint32_t *)src + i);
  347.                format = type.norm ? "%8x" : "%11llx";
  348.                break;
  349.             case 64:
  350.                value = *((const uint64_t *)src + i);
  351.                format = type.norm ? "%16x" : "%21llx";
  352.                break;
  353.             default:
  354.                assert(0);
  355.                value = 0.0;
  356.                format = "?";
  357.             }
  358.             fprintf(fp, format, value);
  359.          }
  360.       }
  361.    }
  362. }
  363.  
  364.  
  365. int main(int argc, char **argv)
  366. {
  367.    unsigned verbose = 0;
  368.    FILE *fp = NULL;
  369.    unsigned long n = 1000;
  370.    unsigned i;
  371.    boolean success;
  372.    boolean single = FALSE;
  373.    unsigned fpstate;
  374.  
  375.    util_cpu_detect();
  376.    fpstate = util_fpstate_get();
  377.    util_fpstate_set_denorms_to_zero(fpstate);
  378.  
  379.    for(i = 1; i < argc; ++i) {
  380.       if(strcmp(argv[i], "-v") == 0)
  381.          ++verbose;
  382.       else if(strcmp(argv[i], "-s") == 0)
  383.          single = TRUE;
  384.       else if(strcmp(argv[i], "-o") == 0)
  385.          fp = fopen(argv[++i], "wt");
  386.       else
  387.          n = atoi(argv[i]);
  388.    }
  389.  
  390.    lp_build_init();
  391.  
  392. #ifdef DEBUG
  393.    if (verbose >= 2) {
  394.       gallivm_debug |= GALLIVM_DEBUG_IR;
  395.       gallivm_debug |= GALLIVM_DEBUG_ASM;
  396.    }
  397. #endif
  398.  
  399.    util_cpu_detect();
  400.  
  401.    if(fp) {
  402.       /* Warm up the caches */
  403.       test_some(0, NULL, 100);
  404.  
  405.       write_tsv_header(fp);
  406.    }
  407.      
  408.    if (single)
  409.       success = test_single(verbose, fp);
  410.    else if (n)
  411.       success = test_some(verbose, fp, n);
  412.    else
  413.       success = test_all(verbose, fp);
  414.  
  415.    if(fp)
  416.       fclose(fp);
  417.  
  418.    return success ? 0 : 1;
  419. }
  420.