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