blob: 14ff00469b054842acd2c96b6f2df3e9592359b5 [file] [log] [blame]
José Fonsecae6ebebc2009-08-07 01:20:01 +01001/**************************************************************************
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
José Fonsecaa07437f2009-10-22 18:10:19 +010037#include "util/u_cpu_detect.h"
38
Zack Rusinc61bf362010-02-08 18:05:22 -050039#include "gallivm/lp_bld_const.h"
40#include "gallivm/lp_bld_misc.h"
José Fonsecae6ebebc2009-08-07 01:20:01 +010041#include "lp_test.h"
42
43
José Fonseca095e66f2009-10-27 20:09:53 +000044#ifdef PIPE_CC_MSVC
45static INLINE double
46round(double x)
47{
48 if (x >= 0.0)
49 return floor(x + 0.5);
50 else
51 return ceil(x - 0.5);
52}
53#endif
54
55
José Fonsecae6ebebc2009-08-07 01:20:01 +010056void
57dump_type(FILE *fp,
José Fonsecab4835ea2009-09-14 11:05:06 +010058 struct lp_type type)
José Fonsecae6ebebc2009-08-07 01:20:01 +010059{
José Fonseca60584af2009-08-08 23:10:59 +010060 fprintf(fp, "%s%s%u%sx%u",
61 type.sign ? (type.floating || type.fixed ? "" : "s") : "u",
62 type.floating ? "f" : (type.fixed ? "h" : "i"),
José Fonsecae6ebebc2009-08-07 01:20:01 +010063 type.width,
64 type.norm ? "n" : "",
65 type.length);
66}
67
68
69double
José Fonsecab4835ea2009-09-14 11:05:06 +010070read_elem(struct lp_type type, const void *src, unsigned index)
José Fonsecae6ebebc2009-08-07 01:20:01 +010071{
72 double scale = lp_const_scale(type);
73 double value;
74 assert(index < type.length);
75 if (type.floating) {
76 switch(type.width) {
77 case 32:
78 value = *((const float *)src + index);
79 break;
80 case 64:
81 value = *((const double *)src + index);
82 break;
83 default:
84 assert(0);
85 return 0.0;
86 }
87 }
88 else {
89 if(type.sign) {
90 switch(type.width) {
91 case 8:
92 value = *((const int8_t *)src + index);
93 break;
94 case 16:
95 value = *((const int16_t *)src + index);
96 break;
97 case 32:
98 value = *((const int32_t *)src + index);
99 break;
100 case 64:
101 value = *((const int64_t *)src + index);
102 break;
103 default:
104 assert(0);
105 return 0.0;
106 }
107 }
108 else {
109 switch(type.width) {
110 case 8:
111 value = *((const uint8_t *)src + index);
112 break;
113 case 16:
114 value = *((const uint16_t *)src + index);
115 break;
116 case 32:
117 value = *((const uint32_t *)src + index);
118 break;
119 case 64:
120 value = *((const uint64_t *)src + index);
121 break;
122 default:
123 assert(0);
124 return 0.0;
125 }
126 }
127 }
128 return value/scale;
129}
130
131
132void
José Fonsecab4835ea2009-09-14 11:05:06 +0100133write_elem(struct lp_type type, void *dst, unsigned index, double value)
José Fonsecae6ebebc2009-08-07 01:20:01 +0100134{
José Fonsecae6ebebc2009-08-07 01:20:01 +0100135 assert(index < type.length);
José Fonseca60584af2009-08-08 23:10:59 +0100136 if(!type.sign && value < 0.0)
137 value = 0.0;
José Fonseca33ce51b2009-08-21 07:34:15 +0100138 if(type.norm && value < -1.0)
139 value = -1.0;
José Fonseca60584af2009-08-08 23:10:59 +0100140 if(type.norm && value > 1.0)
141 value = 1.0;
José Fonsecae6ebebc2009-08-07 01:20:01 +0100142 if (type.floating) {
143 switch(type.width) {
144 case 32:
145 *((float *)dst + index) = (float)(value);
146 break;
147 case 64:
148 *((double *)dst + index) = value;
149 break;
150 default:
151 assert(0);
152 }
153 }
154 else {
José Fonseca60584af2009-08-08 23:10:59 +0100155 double scale = lp_const_scale(type);
José Fonseca33ce51b2009-08-21 07:34:15 +0100156 value = round(value*scale);
José Fonsecae6ebebc2009-08-07 01:20:01 +0100157 if(type.sign) {
José Fonseca33ce51b2009-08-21 07:34:15 +0100158 long long lvalue = (long long)value;
159 lvalue = MIN2(lvalue, ((long long)1 << (type.width - 1)) - 1);
José Fonsecae6ebebc2009-08-07 01:20:01 +0100160 switch(type.width) {
161 case 8:
José Fonsecac67570b2009-08-14 12:02:06 +0100162 *((int8_t *)dst + index) = (int8_t)lvalue;
José Fonsecae6ebebc2009-08-07 01:20:01 +0100163 break;
164 case 16:
José Fonsecac67570b2009-08-14 12:02:06 +0100165 *((int16_t *)dst + index) = (int16_t)lvalue;
José Fonsecae6ebebc2009-08-07 01:20:01 +0100166 break;
167 case 32:
José Fonsecac67570b2009-08-14 12:02:06 +0100168 *((int32_t *)dst + index) = (int32_t)lvalue;
José Fonsecae6ebebc2009-08-07 01:20:01 +0100169 break;
170 case 64:
José Fonseca33ce51b2009-08-21 07:34:15 +0100171 *((int64_t *)dst + index) = (int64_t)lvalue;
José Fonsecae6ebebc2009-08-07 01:20:01 +0100172 break;
173 default:
174 assert(0);
175 }
176 }
177 else {
José Fonseca33ce51b2009-08-21 07:34:15 +0100178 unsigned long long lvalue = (long long)value;
179 lvalue = MIN2(lvalue, ((unsigned long long)1 << type.width) - 1);
José Fonsecae6ebebc2009-08-07 01:20:01 +0100180 switch(type.width) {
181 case 8:
José Fonsecac67570b2009-08-14 12:02:06 +0100182 *((uint8_t *)dst + index) = (uint8_t)lvalue;
José Fonsecae6ebebc2009-08-07 01:20:01 +0100183 break;
184 case 16:
José Fonsecac67570b2009-08-14 12:02:06 +0100185 *((uint16_t *)dst + index) = (uint16_t)lvalue;
José Fonsecae6ebebc2009-08-07 01:20:01 +0100186 break;
187 case 32:
José Fonsecac67570b2009-08-14 12:02:06 +0100188 *((uint32_t *)dst + index) = (uint32_t)lvalue;
José Fonsecae6ebebc2009-08-07 01:20:01 +0100189 break;
190 case 64:
José Fonsecac67570b2009-08-14 12:02:06 +0100191 *((uint64_t *)dst + index) = (uint64_t)lvalue;
José Fonsecae6ebebc2009-08-07 01:20:01 +0100192 break;
193 default:
194 assert(0);
195 }
196 }
197 }
198}
199
200
201void
José Fonsecab4835ea2009-09-14 11:05:06 +0100202random_elem(struct lp_type type, void *dst, unsigned index)
José Fonsecae6ebebc2009-08-07 01:20:01 +0100203{
José Fonseca60584af2009-08-08 23:10:59 +0100204 double value;
José Fonsecae6ebebc2009-08-07 01:20:01 +0100205 assert(index < type.length);
José Fonseca459ea002009-09-16 10:39:06 +0100206 value = (double)rand()/(double)RAND_MAX;
José Fonseca60584af2009-08-08 23:10:59 +0100207 if(!type.norm) {
208 unsigned long long mask;
209 if (type.floating)
210 mask = ~(unsigned long long)0;
211 else if (type.fixed)
212 mask = ((unsigned long long)1 << (type.width / 2)) - 1;
213 else if (type.sign)
214 mask = ((unsigned long long)1 << (type.width - 1)) - 1;
215 else
216 mask = ((unsigned long long)1 << type.width) - 1;
José Fonseca459ea002009-09-16 10:39:06 +0100217 value += (double)(mask & rand());
José Fonsecae6ebebc2009-08-07 01:20:01 +0100218 }
José Fonseca60584af2009-08-08 23:10:59 +0100219 if(!type.sign)
José Fonseca459ea002009-09-16 10:39:06 +0100220 if(rand() & 1)
José Fonseca60584af2009-08-08 23:10:59 +0100221 value = -value;
222 write_elem(type, dst, index, value);
José Fonsecae6ebebc2009-08-07 01:20:01 +0100223}
224
225
226void
José Fonsecab4835ea2009-09-14 11:05:06 +0100227read_vec(struct lp_type type, const void *src, double *dst)
José Fonsecae6ebebc2009-08-07 01:20:01 +0100228{
229 unsigned i;
230 for (i = 0; i < type.length; ++i)
231 dst[i] = read_elem(type, src, i);
232}
233
234
235void
José Fonsecab4835ea2009-09-14 11:05:06 +0100236write_vec(struct lp_type type, void *dst, const double *src)
José Fonsecae6ebebc2009-08-07 01:20:01 +0100237{
238 unsigned i;
239 for (i = 0; i < type.length; ++i)
240 write_elem(type, dst, i, src[i]);
241}
242
243
244float
245random_float(void)
246{
José Fonseca459ea002009-09-16 10:39:06 +0100247 return (float)((double)rand()/(double)RAND_MAX);
José Fonsecae6ebebc2009-08-07 01:20:01 +0100248}
249
250
251void
José Fonsecab4835ea2009-09-14 11:05:06 +0100252random_vec(struct lp_type type, void *dst)
José Fonsecae6ebebc2009-08-07 01:20:01 +0100253{
254 unsigned i;
255 for (i = 0; i < type.length; ++i)
256 random_elem(type, dst, i);
257}
258
259
260boolean
José Fonsecab4835ea2009-09-14 11:05:06 +0100261compare_vec_with_eps(struct lp_type type, const void *res, const void *ref, double eps)
José Fonsecae6ebebc2009-08-07 01:20:01 +0100262{
José Fonsecae6ebebc2009-08-07 01:20:01 +0100263 unsigned i;
José Fonsecae6ebebc2009-08-07 01:20:01 +0100264 for (i = 0; i < type.length; ++i) {
265 double res_elem = read_elem(type, res, i);
José Fonsecab19cb002009-08-07 09:51:04 +0100266 double ref_elem = read_elem(type, ref, i);
José Fonsecae6ebebc2009-08-07 01:20:01 +0100267 double delta = fabs(res_elem - ref_elem);
268 if(delta >= 2.0*eps)
269 return FALSE;
270 }
271
272 return TRUE;
273}
274
275
José Fonseca33ce51b2009-08-21 07:34:15 +0100276boolean
José Fonsecab4835ea2009-09-14 11:05:06 +0100277compare_vec(struct lp_type type, const void *res, const void *ref)
José Fonseca33ce51b2009-08-21 07:34:15 +0100278{
279 double eps = lp_const_eps(type);
280 return compare_vec_with_eps(type, res, ref, eps);
281}
282
283
José Fonsecae6ebebc2009-08-07 01:20:01 +0100284void
José Fonsecab4835ea2009-09-14 11:05:06 +0100285dump_vec(FILE *fp, struct lp_type type, const void *src)
José Fonsecae6ebebc2009-08-07 01:20:01 +0100286{
287 unsigned i;
288 for (i = 0; i < type.length; ++i) {
289 if(i)
290 fprintf(fp, " ");
291 if (type.floating) {
292 double value;
293 switch(type.width) {
294 case 32:
295 value = *((const float *)src + i);
296 break;
297 case 64:
298 value = *((const double *)src + i);
299 break;
300 default:
301 assert(0);
302 value = 0.0;
303 }
304 fprintf(fp, "%f", value);
305 }
306 else {
José Fonseca33ce51b2009-08-21 07:34:15 +0100307 if(type.sign && !type.norm) {
José Fonsecae6ebebc2009-08-07 01:20:01 +0100308 long long value;
309 const char *format;
310 switch(type.width) {
311 case 8:
312 value = *((const int8_t *)src + i);
313 format = "%3lli";
314 break;
315 case 16:
316 value = *((const int16_t *)src + i);
317 format = "%5lli";
318 break;
319 case 32:
320 value = *((const int32_t *)src + i);
321 format = "%10lli";
322 break;
323 case 64:
324 value = *((const int64_t *)src + i);
325 format = "%20lli";
326 break;
327 default:
328 assert(0);
329 value = 0.0;
330 format = "?";
331 }
332 fprintf(fp, format, value);
333 }
334 else {
335 unsigned long long value;
336 const char *format;
337 switch(type.width) {
338 case 8:
339 value = *((const uint8_t *)src + i);
José Fonseca33ce51b2009-08-21 07:34:15 +0100340 format = type.norm ? "%2x" : "%4llu";
José Fonsecae6ebebc2009-08-07 01:20:01 +0100341 break;
342 case 16:
343 value = *((const uint16_t *)src + i);
José Fonseca33ce51b2009-08-21 07:34:15 +0100344 format = type.norm ? "%4x" : "%6llx";
José Fonsecae6ebebc2009-08-07 01:20:01 +0100345 break;
346 case 32:
347 value = *((const uint32_t *)src + i);
José Fonseca33ce51b2009-08-21 07:34:15 +0100348 format = type.norm ? "%8x" : "%11llx";
José Fonsecae6ebebc2009-08-07 01:20:01 +0100349 break;
350 case 64:
351 value = *((const uint64_t *)src + i);
José Fonseca33ce51b2009-08-21 07:34:15 +0100352 format = type.norm ? "%16x" : "%21llx";
José Fonsecae6ebebc2009-08-07 01:20:01 +0100353 break;
354 default:
355 assert(0);
356 value = 0.0;
357 format = "?";
358 }
359 fprintf(fp, format, value);
360 }
361 }
362 }
363}
364
365
366int main(int argc, char **argv)
367{
368 unsigned verbose = 0;
369 FILE *fp = NULL;
370 unsigned long n = 1000;
371 unsigned i;
372 boolean success;
373
374 for(i = 1; i < argc; ++i) {
375 if(strcmp(argv[i], "-v") == 0)
376 ++verbose;
377 else if(strcmp(argv[i], "-o") == 0)
378 fp = fopen(argv[++i], "wt");
379 else
380 n = atoi(argv[i]);
381 }
382
José Fonseca1df539c2009-09-26 09:33:32 +0100383 LLVMLinkInJIT();
384 LLVMInitializeNativeTarget();
José Fonseca1df539c2009-09-26 09:33:32 +0100385
José Fonsecaa07437f2009-10-22 18:10:19 +0100386 util_cpu_detect();
387
José Fonsecae6ebebc2009-08-07 01:20:01 +0100388 if(fp) {
389 /* Warm up the caches */
390 test_some(0, NULL, 100);
391
392 write_tsv_header(fp);
393 }
394
395 if(n)
396 success = test_some(verbose, fp, n);
397 else
398 success = test_all(verbose, fp);
399
400 if(fp)
401 fclose(fp);
402
403 return success ? 0 : 1;
404}