1 /**************************************************************************
3 * Copyright 2009 VMware, Inc.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
31 * Shared testing code.
33 * @author Jose Fonseca <jfonseca@vmware.com>
37 #include "util/u_cpu_detect.h"
38 #include "util/u_math.h"
40 #include "gallivm/lp_bld_const.h"
41 #include "gallivm/lp_bld_init.h"
49 fprintf(fp, "%s%s%u%sx%u",
50 type.sign ? (type.floating || type.fixed ? "" : "s") : "u",
51 type.floating ? "f" : (type.fixed ? "h" : "i"),
59 read_elem(struct lp_type type, const void *src, unsigned index)
61 double scale = lp_const_scale(type);
63 assert(index < type.length);
67 value = *((const float *)src + index);
70 value = *((const double *)src + index);
81 value = *((const int8_t *)src + index);
84 value = *((const int16_t *)src + index);
87 value = *((const int32_t *)src + index);
90 value = *((const int64_t *)src + index);
100 value = *((const uint8_t *)src + index);
103 value = *((const uint16_t *)src + index);
106 value = *((const uint32_t *)src + index);
109 value = *((const uint64_t *)src + index);
122 write_elem(struct lp_type type, void *dst, unsigned index, double value)
124 assert(index < type.length);
125 if(!type.sign && value < 0.0)
127 if(type.norm && value < -1.0)
129 if(type.norm && value > 1.0)
134 *((float *)dst + index) = (float)(value);
137 *((double *)dst + index) = value;
144 double scale = lp_const_scale(type);
145 value = round(value*scale);
147 long long lvalue = (long long)value;
148 lvalue = MIN2(lvalue, ((long long)1 << (type.width - 1)) - 1);
151 *((int8_t *)dst + index) = (int8_t)lvalue;
154 *((int16_t *)dst + index) = (int16_t)lvalue;
157 *((int32_t *)dst + index) = (int32_t)lvalue;
160 *((int64_t *)dst + index) = (int64_t)lvalue;
167 unsigned long long lvalue = (long long)value;
168 lvalue = MIN2(lvalue, ((unsigned long long)1 << type.width) - 1);
171 *((uint8_t *)dst + index) = (uint8_t)lvalue;
174 *((uint16_t *)dst + index) = (uint16_t)lvalue;
177 *((uint32_t *)dst + index) = (uint32_t)lvalue;
180 *((uint64_t *)dst + index) = (uint64_t)lvalue;
191 random_elem(struct lp_type type, void *dst, unsigned index)
194 assert(index < type.length);
195 value = (double)rand()/(double)RAND_MAX;
201 unsigned long long mask;
203 mask = ((unsigned long long)1 << (type.width / 2)) - 1;
205 mask = ((unsigned long long)1 << (type.width - 1)) - 1;
207 mask = ((unsigned long long)1 << type.width) - 1;
208 value += (double)(mask & rand());
214 write_elem(type, dst, index, value);
219 read_vec(struct lp_type type, const void *src, double *dst)
222 for (i = 0; i < type.length; ++i)
223 dst[i] = read_elem(type, src, i);
228 write_vec(struct lp_type type, void *dst, const double *src)
231 for (i = 0; i < type.length; ++i)
232 write_elem(type, dst, i, src[i]);
239 return (float)((double)rand()/(double)RAND_MAX);
244 random_vec(struct lp_type type, void *dst)
247 for (i = 0; i < type.length; ++i)
248 random_elem(type, dst, i);
253 compare_vec_with_eps(struct lp_type type, const void *res, const void *ref, double eps)
256 eps *= type.floating ? 8.0 : 2.0;
257 for (i = 0; i < type.length; ++i) {
258 double res_elem = read_elem(type, res, i);
259 double ref_elem = read_elem(type, ref, i);
260 double delta = res_elem - ref_elem;
261 if (ref_elem < -1.0 || ref_elem > 1.0) {
275 compare_vec(struct lp_type type, const void *res, const void *ref)
277 double eps = lp_const_eps(type);
278 return compare_vec_with_eps(type, res, ref, eps);
283 dump_vec(FILE *fp, struct lp_type type, const void *src)
286 for (i = 0; i < type.length; ++i) {
293 value = *((const float *)src + i);
296 value = *((const double *)src + i);
302 fprintf(fp, "%f", value);
305 if(type.sign && !type.norm) {
310 value = *((const int8_t *)src + i);
314 value = *((const int16_t *)src + i);
318 value = *((const int32_t *)src + i);
322 value = *((const int64_t *)src + i);
330 fprintf(fp, format, value);
333 unsigned long long value;
337 value = *((const uint8_t *)src + i);
338 format = type.norm ? "%2x" : "%4llu";
341 value = *((const uint16_t *)src + i);
342 format = type.norm ? "%4x" : "%6llx";
345 value = *((const uint32_t *)src + i);
346 format = type.norm ? "%8x" : "%11llx";
349 value = *((const uint64_t *)src + i);
350 format = type.norm ? "%16x" : "%21llx";
357 fprintf(fp, format, value);
364 int main(int argc, char **argv)
366 unsigned verbose = 0;
368 unsigned long n = 1000;
371 boolean single = FALSE;
372 struct gallivm_state *gallivm;
374 for(i = 1; i < argc; ++i) {
375 if(strcmp(argv[i], "-v") == 0)
377 else if(strcmp(argv[i], "-s") == 0)
379 else if(strcmp(argv[i], "-o") == 0)
380 fp = fopen(argv[++i], "wt");
387 gallivm = gallivm_create();
392 /* Warm up the caches */
393 test_some(gallivm, 0, NULL, 100);
395 write_tsv_header(fp);
399 success = test_single(gallivm, verbose, fp);
401 success = test_some(gallivm, verbose, fp, n);
403 success = test_all(gallivm, verbose, fp);
408 return success ? 0 : 1;