Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 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 
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
}