lp_test_main.c revision b19cb0080cbc9877993e76f6cbd6bc170d3d2851
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 "lp_bld_const.h"
38#include "lp_test.h"
39
40
41void
42dump_type(FILE *fp,
43          union lp_type type)
44{
45   fprintf(fp, "%s%u%sx%u",
46           type.floating ? "f" : (type.fixed ? "h" : (type.sign ? "s" : "u")),
47           type.width,
48           type.norm ? "n" : "",
49           type.length);
50}
51
52
53double
54read_elem(union lp_type type, const void *src, unsigned index)
55{
56   double scale = lp_const_scale(type);
57   double value;
58   assert(index < type.length);
59   if (type.floating) {
60      switch(type.width) {
61      case 32:
62         value = *((const float *)src + index);
63         break;
64      case 64:
65         value =  *((const double *)src + index);
66         break;
67      default:
68         assert(0);
69         return 0.0;
70      }
71   }
72   else {
73      if(type.sign) {
74         switch(type.width) {
75         case 8:
76            value = *((const int8_t *)src + index);
77            break;
78         case 16:
79            value = *((const int16_t *)src + index);
80            break;
81         case 32:
82            value = *((const int32_t *)src + index);
83            break;
84         case 64:
85            value = *((const int64_t *)src + index);
86            break;
87         default:
88            assert(0);
89            return 0.0;
90         }
91      }
92      else {
93         switch(type.width) {
94         case 8:
95            value = *((const uint8_t *)src + index);
96            break;
97         case 16:
98            value = *((const uint16_t *)src + index);
99            break;
100         case 32:
101            value = *((const uint32_t *)src + index);
102            break;
103         case 64:
104            value = *((const uint64_t *)src + index);
105            break;
106         default:
107            assert(0);
108            return 0.0;
109         }
110      }
111   }
112   return value/scale;
113}
114
115
116void
117write_elem(union lp_type type, void *dst, unsigned index, double src)
118{
119   double scale = lp_const_scale(type);
120   double value = scale*src;
121   assert(index < type.length);
122   if (type.floating) {
123      switch(type.width) {
124      case 32:
125         *((float *)dst + index) = (float)(value);
126         break;
127      case 64:
128          *((double *)dst + index) = value;
129         break;
130      default:
131         assert(0);
132      }
133   }
134   else {
135      if(type.sign) {
136         switch(type.width) {
137         case 8:
138            *((int8_t *)dst + index) = (int8_t)round(value);
139            break;
140         case 16:
141            *((int16_t *)dst + index) = (int16_t)round(value);
142            break;
143         case 32:
144            *((int32_t *)dst + index) = (int32_t)round(value);
145            break;
146         case 64:
147            *((int64_t *)dst + index) = (int32_t)round(value);
148            break;
149         default:
150            assert(0);
151         }
152      }
153      else {
154         switch(type.width) {
155         case 8:
156            *((uint8_t *)dst + index) = (uint8_t)round(value);
157            break;
158         case 16:
159            *((uint16_t *)dst + index) = (uint16_t)round(value);
160            break;
161         case 32:
162            *((uint32_t *)dst + index) = (uint32_t)round(value);
163            break;
164         case 64:
165            *((uint64_t *)dst + index) = (uint64_t)round(value);
166            break;
167         default:
168            assert(0);
169         }
170      }
171   }
172}
173
174
175void
176random_elem(union lp_type type, void *dst, unsigned index)
177{
178   assert(index < type.length);
179   if (type.floating) {
180      double value = (double)random()/(double)RAND_MAX;
181      if(!type.norm) {
182         value += (double)random();
183         if(random() & 1)
184            value = -value;
185      }
186      switch(type.width) {
187      case 32:
188         *((float *)dst + index) = (float)value;
189         break;
190      case 64:
191          *((double *)dst + index) = value;
192         break;
193      default:
194         assert(0);
195      }
196   }
197   else {
198      switch(type.width) {
199      case 8:
200         *((uint8_t *)dst + index) = (uint8_t)random();
201         break;
202      case 16:
203         *((uint16_t *)dst + index) = (uint16_t)random();
204         break;
205      case 32:
206         *((uint32_t *)dst + index) = (uint32_t)random();
207         break;
208      case 64:
209         *((uint64_t *)dst + index) = (uint64_t)random();
210         break;
211      default:
212         assert(0);
213      }
214   }
215}
216
217
218void
219read_vec(union lp_type type, const void *src, double *dst)
220{
221   unsigned i;
222   for (i = 0; i < type.length; ++i)
223      dst[i] = read_elem(type, src, i);
224}
225
226
227void
228write_vec(union lp_type type, void *dst, const double *src)
229{
230   unsigned i;
231   for (i = 0; i < type.length; ++i)
232      write_elem(type, dst, i, src[i]);
233}
234
235
236float
237random_float(void)
238{
239    return (float)((double)random()/(double)RAND_MAX);
240}
241
242
243void
244random_vec(union lp_type type, void *dst)
245{
246   unsigned i;
247   for (i = 0; i < type.length; ++i)
248      random_elem(type, dst, i);
249}
250
251
252boolean
253compare_vec(union lp_type type, const void *res, const void *ref)
254{
255   double eps;
256   unsigned i;
257
258   if (type.floating) {
259      switch(type.width) {
260      case 32:
261         eps = FLT_EPSILON;
262         break;
263      case 64:
264         eps = DBL_EPSILON;
265         break;
266      default:
267         assert(0);
268         eps = 0.0;
269         break;
270      }
271   }
272   else {
273      double scale = lp_const_scale(type);
274      eps = 1.0/scale;
275   }
276
277   for (i = 0; i < type.length; ++i) {
278      double res_elem = read_elem(type, res, i);
279      double ref_elem = read_elem(type, ref, i);
280      double delta = fabs(res_elem - ref_elem);
281      if(delta >= 2.0*eps)
282         return FALSE;
283   }
284
285   return TRUE;
286}
287
288
289void
290dump_vec(FILE *fp, union lp_type type, const void *src)
291{
292   unsigned i;
293   for (i = 0; i < type.length; ++i) {
294      if(i)
295         fprintf(fp, " ");
296      if (type.floating) {
297         double value;
298         switch(type.width) {
299         case 32:
300            value = *((const float *)src + i);
301            break;
302         case 64:
303            value = *((const double *)src + i);
304            break;
305         default:
306            assert(0);
307            value = 0.0;
308         }
309         fprintf(fp, "%f", value);
310      }
311      else {
312         if(type.sign) {
313            long long value;
314            const char *format;
315            switch(type.width) {
316            case 8:
317               value = *((const int8_t *)src + i);
318               format = "%3lli";
319               break;
320            case 16:
321               value = *((const int16_t *)src + i);
322               format = "%5lli";
323               break;
324            case 32:
325               value = *((const int32_t *)src + i);
326               format = "%10lli";
327               break;
328            case 64:
329               value = *((const int64_t *)src + i);
330               format = "%20lli";
331               break;
332            default:
333               assert(0);
334               value = 0.0;
335               format = "?";
336            }
337            fprintf(fp, format, value);
338         }
339         else {
340            unsigned long long value;
341            const char *format;
342            switch(type.width) {
343            case 8:
344               value = *((const uint8_t *)src + i);
345               format = "%4llu";
346               break;
347            case 16:
348               value = *((const uint16_t *)src + i);
349               format = "%6llu";
350               break;
351            case 32:
352               value = *((const uint32_t *)src + i);
353               format = "%11llu";
354               break;
355            case 64:
356               value = *((const uint64_t *)src + i);
357               format = "%21llu";
358               break;
359            default:
360               assert(0);
361               value = 0.0;
362               format = "?";
363            }
364            fprintf(fp, format, value);
365         }
366      }
367   }
368}
369
370
371int main(int argc, char **argv)
372{
373   unsigned verbose = 0;
374   FILE *fp = NULL;
375   unsigned long n = 1000;
376   unsigned i;
377   boolean success;
378
379   for(i = 1; i < argc; ++i) {
380      if(strcmp(argv[i], "-v") == 0)
381         ++verbose;
382      else if(strcmp(argv[i], "-o") == 0)
383         fp = fopen(argv[++i], "wt");
384      else
385         n = atoi(argv[i]);
386   }
387
388   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}
405