1 //
2 // Copyright (c) 2017 The Khronos Group Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 #include "conversions.h"
17 #include <limits.h>
18 #include <time.h>
19 #include <assert.h>
20 #include "mt19937.h"
21 #include "compat.h"
22
23 #if defined(__SSE__) || defined(_MSC_VER)
24 #include <xmmintrin.h>
25 #endif
26 #if defined(__SSE2__) || defined(_MSC_VER)
27 #include <emmintrin.h>
28 #endif
29
print_type_to_string(ExplicitType type,void * data,char * string)30 void print_type_to_string(ExplicitType type, void *data, char *string)
31 {
32 switch (type)
33 {
34 case kBool:
35 if (*(char *)data)
36 sprintf(string, "true");
37 else
38 sprintf(string, "false");
39 return;
40 case kChar: sprintf(string, "%d", (int)*((cl_char *)data)); return;
41 case kUChar:
42 case kUnsignedChar:
43 sprintf(string, "%u", (int)*((cl_uchar *)data));
44 return;
45 case kShort: sprintf(string, "%d", (int)*((cl_short *)data)); return;
46 case kUShort:
47 case kUnsignedShort:
48 sprintf(string, "%u", (int)*((cl_ushort *)data));
49 return;
50 case kInt: sprintf(string, "%d", *((cl_int *)data)); return;
51 case kUInt:
52 case kUnsignedInt: sprintf(string, "%u", *((cl_uint *)data)); return;
53 case kLong: sprintf(string, "%lld", *((cl_long *)data)); return;
54 case kULong:
55 case kUnsignedLong:
56 sprintf(string, "%llu", *((cl_ulong *)data));
57 return;
58 case kFloat: sprintf(string, "%f", *((cl_float *)data)); return;
59 case kHalf: sprintf(string, "half"); return;
60 case kDouble: sprintf(string, "%g", *((cl_double *)data)); return;
61 default: sprintf(string, "INVALID"); return;
62 }
63 }
64
get_explicit_type_size(ExplicitType type)65 size_t get_explicit_type_size(ExplicitType type)
66 {
67 /* Quick method to avoid branching: make sure the following array matches
68 * the Enum order */
69 static size_t sExplicitTypeSizes[] = {
70 sizeof(cl_bool), sizeof(cl_char), sizeof(cl_uchar),
71 sizeof(cl_uchar), sizeof(cl_short), sizeof(cl_ushort),
72 sizeof(cl_ushort), sizeof(cl_int), sizeof(cl_uint),
73 sizeof(cl_uint), sizeof(cl_long), sizeof(cl_ulong),
74 sizeof(cl_ulong), sizeof(cl_float), sizeof(cl_half),
75 sizeof(cl_double)
76 };
77
78 return sExplicitTypeSizes[type];
79 }
80
get_explicit_type_name(ExplicitType type)81 const char *get_explicit_type_name(ExplicitType type)
82 {
83 /* Quick method to avoid branching: make sure the following array matches
84 * the Enum order */
85 static const char *sExplicitTypeNames[] = {
86 "bool", "char", "uchar", "unsigned char", "short", "ushort",
87 "unsigned short", "int", "uint", "unsigned int", "long", "ulong",
88 "unsigned long", "float", "half", "double"
89 };
90
91 return sExplicitTypeNames[type];
92 }
93
94 static long lrintf_clamped(float f);
lrintf_clamped(float f)95 static long lrintf_clamped(float f)
96 {
97 static const float magic[2] = { MAKE_HEX_FLOAT(0x1.0p23f, 0x1, 23),
98 -MAKE_HEX_FLOAT(0x1.0p23f, 0x1, 23) };
99
100 if (f >= -(float)LONG_MIN) return LONG_MAX;
101
102 if (f <= (float)LONG_MIN) return LONG_MIN;
103
104 // Round fractional values to integer in round towards nearest mode
105 if (fabsf(f) < MAKE_HEX_FLOAT(0x1.0p23f, 0x1, 23))
106 {
107 volatile float x = f;
108 float magicVal = magic[f < 0];
109
110 #if defined(__SSE__) || defined(_WIN32)
111 // Defeat x87 based arithmetic, which cant do FTZ, and will round this
112 // incorrectly
113 __m128 v = _mm_set_ss(x);
114 __m128 m = _mm_set_ss(magicVal);
115 v = _mm_add_ss(v, m);
116 v = _mm_sub_ss(v, m);
117 _mm_store_ss((float *)&x, v);
118 #else
119 x += magicVal;
120 x -= magicVal;
121 #endif
122 f = x;
123 }
124
125 return (long)f;
126 }
127
128 static long lrint_clamped(double f);
lrint_clamped(double f)129 static long lrint_clamped(double f)
130 {
131 static const double magic[2] = { MAKE_HEX_DOUBLE(0x1.0p52, 0x1LL, 52),
132 MAKE_HEX_DOUBLE(-0x1.0p52, -0x1LL, 52) };
133
134 if (sizeof(long) > 4)
135 {
136 if (f >= -(double)LONG_MIN) return LONG_MAX;
137 }
138 else
139 {
140 if (f >= LONG_MAX) return LONG_MAX;
141 }
142
143 if (f <= (double)LONG_MIN) return LONG_MIN;
144
145 // Round fractional values to integer in round towards nearest mode
146 if (fabs(f) < MAKE_HEX_DOUBLE(0x1.0p52, 0x1LL, 52))
147 {
148 volatile double x = f;
149 double magicVal = magic[f < 0];
150 #if defined(__SSE2__) || (defined(_MSC_VER))
151 // Defeat x87 based arithmetic, which cant do FTZ, and will round this
152 // incorrectly
153 __m128d v = _mm_set_sd(x);
154 __m128d m = _mm_set_sd(magicVal);
155 v = _mm_add_sd(v, m);
156 v = _mm_sub_sd(v, m);
157 _mm_store_sd((double *)&x, v);
158 #else
159 x += magicVal;
160 x -= magicVal;
161 #endif
162 f = x;
163 }
164
165 return (long)f;
166 }
167
168
169 typedef cl_long Long;
170 typedef cl_ulong ULong;
171
172 static ULong sUpperLimits[kNumExplicitTypes] = {
173 0,
174 127,
175 255,
176 255,
177 32767,
178 65535,
179 65535,
180 0x7fffffffLL,
181 0xffffffffLL,
182 0xffffffffLL,
183 0x7fffffffffffffffLL,
184 0xffffffffffffffffLL,
185 0xffffffffffffffffLL,
186 0,
187 0
188 }; // Last two values aren't stored here
189
190 static Long sLowerLimits[kNumExplicitTypes] = {
191 -1,
192 -128,
193 0,
194 0,
195 -32768,
196 0,
197 0,
198 (Long)0xffffffff80000000LL,
199 0,
200 0,
201 (Long)0x8000000000000000LL,
202 0,
203 0,
204 0,
205 0
206 }; // Last two values aren't stored here
207
208 #define BOOL_CASE(inType) \
209 case kBool: \
210 boolPtr = (bool *)outRaw; \
211 *boolPtr = (*inType##Ptr) != 0 ? true : false; \
212 break;
213
214 #define SIMPLE_CAST_CASE(inType, outEnum, outType) \
215 case outEnum: \
216 outType##Ptr = (outType *)outRaw; \
217 *outType##Ptr = (outType)(*inType##Ptr); \
218 break;
219
220 // Sadly, the ULong downcasting cases need a separate #define to get rid of
221 // signed/unsigned comparison warnings
222 #define DOWN_CAST_CASE(inType, outEnum, outType, sat) \
223 case outEnum: \
224 outType##Ptr = (outType *)outRaw; \
225 if (sat) \
226 { \
227 if ((sLowerLimits[outEnum] < 0 \
228 && *inType##Ptr > (Long)sUpperLimits[outEnum]) \
229 || (sLowerLimits[outEnum] == 0 \
230 && (ULong)*inType##Ptr > sUpperLimits[outEnum])) \
231 *outType##Ptr = (outType)sUpperLimits[outEnum]; \
232 else if (*inType##Ptr < sLowerLimits[outEnum]) \
233 *outType##Ptr = (outType)sLowerLimits[outEnum]; \
234 else \
235 *outType##Ptr = (outType)*inType##Ptr; \
236 } \
237 else \
238 { \
239 *outType##Ptr = (outType)( \
240 *inType##Ptr \
241 & (0xffffffffffffffffLL >> (64 - (sizeof(outType) * 8)))); \
242 } \
243 break;
244
245 #define U_DOWN_CAST_CASE(inType, outEnum, outType, sat) \
246 case outEnum: \
247 outType##Ptr = (outType *)outRaw; \
248 if (sat) \
249 { \
250 if ((ULong)*inType##Ptr > sUpperLimits[outEnum]) \
251 *outType##Ptr = (outType)sUpperLimits[outEnum]; \
252 else \
253 *outType##Ptr = (outType)*inType##Ptr; \
254 } \
255 else \
256 { \
257 *outType##Ptr = (outType)( \
258 *inType##Ptr \
259 & (0xffffffffffffffffLL >> (64 - (sizeof(outType) * 8)))); \
260 } \
261 break;
262
263 #define TO_FLOAT_CASE(inType) \
264 case kFloat: \
265 floatPtr = (float *)outRaw; \
266 *floatPtr = (float)(*inType##Ptr); \
267 break;
268 #define TO_DOUBLE_CASE(inType) \
269 case kDouble: \
270 doublePtr = (double *)outRaw; \
271 *doublePtr = (double)(*inType##Ptr); \
272 break;
273
274
275 /* Note: we use lrintf here to force the rounding instead of whatever the
276 * processor's current rounding mode is */
277 #define FLOAT_ROUND_TO_NEAREST_CASE(outEnum, outType) \
278 case outEnum: \
279 outType##Ptr = (outType *)outRaw; \
280 *outType##Ptr = (outType)lrintf_clamped(*floatPtr); \
281 break;
282
283 #define FLOAT_ROUND_CASE(outEnum, outType, rounding, sat) \
284 case outEnum: { \
285 outType##Ptr = (outType *)outRaw; \
286 /* Get the tens digit */ \
287 Long wholeValue = (Long)*floatPtr; \
288 float largeRemainder = (*floatPtr - (float)wholeValue) * 10.f; \
289 /* What do we do based on that? */ \
290 if (rounding == kRoundToEven) \
291 { \
292 if (wholeValue & 1LL) /*between 1 and 1.99 */ \
293 wholeValue += 1LL; /* round up to even */ \
294 } \
295 else if (rounding == kRoundToZero) \
296 { \
297 /* Nothing to do, round-to-zero is what C casting does */ \
298 } \
299 else if (rounding == kRoundToPosInf) \
300 { \
301 /* Only positive numbers are wrong */ \
302 if (largeRemainder != 0.f && wholeValue >= 0) wholeValue++; \
303 } \
304 else if (rounding == kRoundToNegInf) \
305 { \
306 /* Only negative numbers are off */ \
307 if (largeRemainder != 0.f && wholeValue < 0) wholeValue--; \
308 } \
309 else \
310 { /* Default is round-to-nearest */ \
311 wholeValue = (Long)lrintf_clamped(*floatPtr); \
312 } \
313 /* Now apply saturation rules */ \
314 if (sat) \
315 { \
316 if ((sLowerLimits[outEnum] < 0 \
317 && wholeValue > (Long)sUpperLimits[outEnum]) \
318 || (sLowerLimits[outEnum] == 0 \
319 && (ULong)wholeValue > sUpperLimits[outEnum])) \
320 *outType##Ptr = (outType)sUpperLimits[outEnum]; \
321 else if (wholeValue < sLowerLimits[outEnum]) \
322 *outType##Ptr = (outType)sLowerLimits[outEnum]; \
323 else \
324 *outType##Ptr = (outType)wholeValue; \
325 } \
326 else \
327 { \
328 *outType##Ptr = (outType)( \
329 wholeValue \
330 & (0xffffffffffffffffLL >> (64 - (sizeof(outType) * 8)))); \
331 } \
332 } \
333 break;
334
335 #define DOUBLE_ROUND_CASE(outEnum, outType, rounding, sat) \
336 case outEnum: { \
337 outType##Ptr = (outType *)outRaw; \
338 /* Get the tens digit */ \
339 Long wholeValue = (Long)*doublePtr; \
340 double largeRemainder = (*doublePtr - (double)wholeValue) * 10.0; \
341 /* What do we do based on that? */ \
342 if (rounding == kRoundToEven) \
343 { \
344 if (wholeValue & 1LL) /*between 1 and 1.99 */ \
345 wholeValue += 1LL; /* round up to even */ \
346 } \
347 else if (rounding == kRoundToZero) \
348 { \
349 /* Nothing to do, round-to-zero is what C casting does */ \
350 } \
351 else if (rounding == kRoundToPosInf) \
352 { \
353 /* Only positive numbers are wrong */ \
354 if (largeRemainder != 0.0 && wholeValue >= 0) wholeValue++; \
355 } \
356 else if (rounding == kRoundToNegInf) \
357 { \
358 /* Only negative numbers are off */ \
359 if (largeRemainder != 0.0 && wholeValue < 0) wholeValue--; \
360 } \
361 else \
362 { /* Default is round-to-nearest */ \
363 wholeValue = (Long)lrint_clamped(*doublePtr); \
364 } \
365 /* Now apply saturation rules */ \
366 if (sat) \
367 { \
368 if ((sLowerLimits[outEnum] < 0 \
369 && wholeValue > (Long)sUpperLimits[outEnum]) \
370 || (sLowerLimits[outEnum] == 0 \
371 && (ULong)wholeValue > sUpperLimits[outEnum])) \
372 *outType##Ptr = (outType)sUpperLimits[outEnum]; \
373 else if (wholeValue < sLowerLimits[outEnum]) \
374 *outType##Ptr = (outType)sLowerLimits[outEnum]; \
375 else \
376 *outType##Ptr = (outType)wholeValue; \
377 } \
378 else \
379 { \
380 *outType##Ptr = (outType)( \
381 wholeValue \
382 & (0xffffffffffffffffLL >> (64 - (sizeof(outType) * 8)))); \
383 } \
384 } \
385 break;
386
387 typedef unsigned char uchar;
388 typedef unsigned short ushort;
389 typedef unsigned int uint;
390 typedef unsigned long ulong;
391
convert_explicit_value(void * inRaw,void * outRaw,ExplicitType inType,bool saturate,RoundingType roundType,ExplicitType outType)392 void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
393 bool saturate, RoundingType roundType,
394 ExplicitType outType)
395 {
396 bool *boolPtr;
397 char *charPtr;
398 uchar *ucharPtr;
399 short *shortPtr;
400 ushort *ushortPtr;
401 int *intPtr;
402 uint *uintPtr;
403 Long *LongPtr;
404 ULong *ULongPtr;
405 float *floatPtr;
406 double *doublePtr;
407
408
409 switch (inType)
410 {
411 case kBool:
412 boolPtr = (bool *)inRaw;
413 switch (outType)
414 {
415 case kBool:
416 memcpy(outRaw, inRaw, get_explicit_type_size(inType));
417 break;
418
419 case kChar:
420 case kUChar:
421 case kUnsignedChar:
422 case kShort:
423 case kUShort:
424 case kUnsignedShort:
425 case kInt:
426 case kUInt:
427 case kUnsignedInt:
428 case kLong:
429 case kULong:
430 case kUnsignedLong:
431 memset(outRaw, *boolPtr ? 0xff : 0,
432 get_explicit_type_size(outType));
433 break;
434
435 case kFloat:
436 floatPtr = (float *)outRaw;
437 *floatPtr = (*boolPtr) ? -1.f : 0.f;
438 break;
439 case kDouble:
440 doublePtr = (double *)outRaw;
441 *doublePtr = (*boolPtr) ? -1.0 : 0.0;
442 break;
443 default:
444 log_error("ERROR: Invalid type given to "
445 "convert_explicit_value!!\n");
446 break;
447 }
448 break;
449
450 case kChar:
451 charPtr = (char *)inRaw;
452 switch (outType)
453 {
454 BOOL_CASE(char)
455
456 case kChar:
457 memcpy(outRaw, inRaw, get_explicit_type_size(inType));
458 break;
459
460 DOWN_CAST_CASE(char, kUChar, uchar, saturate)
461 SIMPLE_CAST_CASE(char, kUnsignedChar, uchar)
462 SIMPLE_CAST_CASE(char, kShort, short)
463 SIMPLE_CAST_CASE(char, kUShort, ushort)
464 SIMPLE_CAST_CASE(char, kUnsignedShort, ushort)
465 SIMPLE_CAST_CASE(char, kInt, int)
466 SIMPLE_CAST_CASE(char, kUInt, uint)
467 SIMPLE_CAST_CASE(char, kUnsignedInt, uint)
468 SIMPLE_CAST_CASE(char, kLong, Long)
469 SIMPLE_CAST_CASE(char, kULong, ULong)
470 SIMPLE_CAST_CASE(char, kUnsignedLong, ULong)
471
472 TO_FLOAT_CASE(char)
473 TO_DOUBLE_CASE(char)
474
475 default:
476 log_error("ERROR: Invalid type given to "
477 "convert_explicit_value!!\n");
478 break;
479 }
480 break;
481
482 case kUChar:
483 ucharPtr = (uchar *)inRaw;
484 switch (outType)
485 {
486 BOOL_CASE(uchar)
487
488 case kUChar:
489 case kUnsignedChar:
490 memcpy(outRaw, inRaw, get_explicit_type_size(inType));
491 break;
492
493 DOWN_CAST_CASE(uchar, kChar, char, saturate)
494 SIMPLE_CAST_CASE(uchar, kShort, short)
495 SIMPLE_CAST_CASE(uchar, kUShort, ushort)
496 SIMPLE_CAST_CASE(uchar, kUnsignedShort, ushort)
497 SIMPLE_CAST_CASE(uchar, kInt, int)
498 SIMPLE_CAST_CASE(uchar, kUInt, uint)
499 SIMPLE_CAST_CASE(uchar, kUnsignedInt, uint)
500 SIMPLE_CAST_CASE(uchar, kLong, Long)
501 SIMPLE_CAST_CASE(uchar, kULong, ULong)
502 SIMPLE_CAST_CASE(uchar, kUnsignedLong, ULong)
503
504 TO_FLOAT_CASE(uchar)
505 TO_DOUBLE_CASE(uchar)
506
507 default:
508 log_error("ERROR: Invalid type given to "
509 "convert_explicit_value!!\n");
510 break;
511 }
512 break;
513
514 case kUnsignedChar:
515 ucharPtr = (uchar *)inRaw;
516 switch (outType)
517 {
518 BOOL_CASE(uchar)
519
520 case kUChar:
521 case kUnsignedChar:
522 memcpy(outRaw, inRaw, get_explicit_type_size(inType));
523 break;
524
525 DOWN_CAST_CASE(uchar, kChar, char, saturate)
526 SIMPLE_CAST_CASE(uchar, kShort, short)
527 SIMPLE_CAST_CASE(uchar, kUShort, ushort)
528 SIMPLE_CAST_CASE(uchar, kUnsignedShort, ushort)
529 SIMPLE_CAST_CASE(uchar, kInt, int)
530 SIMPLE_CAST_CASE(uchar, kUInt, uint)
531 SIMPLE_CAST_CASE(uchar, kUnsignedInt, uint)
532 SIMPLE_CAST_CASE(uchar, kLong, Long)
533 SIMPLE_CAST_CASE(uchar, kULong, ULong)
534 SIMPLE_CAST_CASE(uchar, kUnsignedLong, ULong)
535
536 TO_FLOAT_CASE(uchar)
537 TO_DOUBLE_CASE(uchar)
538
539 default:
540 log_error("ERROR: Invalid type given to "
541 "convert_explicit_value!!\n");
542 break;
543 }
544 break;
545
546 case kShort:
547 shortPtr = (short *)inRaw;
548 switch (outType)
549 {
550 BOOL_CASE(short)
551
552 case kShort:
553 memcpy(outRaw, inRaw, get_explicit_type_size(inType));
554 break;
555
556 DOWN_CAST_CASE(short, kChar, char, saturate)
557 DOWN_CAST_CASE(short, kUChar, uchar, saturate)
558 DOWN_CAST_CASE(short, kUnsignedChar, uchar, saturate)
559 DOWN_CAST_CASE(short, kUShort, ushort, saturate)
560 DOWN_CAST_CASE(short, kUnsignedShort, ushort, saturate)
561 SIMPLE_CAST_CASE(short, kInt, int)
562 SIMPLE_CAST_CASE(short, kUInt, uint)
563 SIMPLE_CAST_CASE(short, kUnsignedInt, uint)
564 SIMPLE_CAST_CASE(short, kLong, Long)
565 SIMPLE_CAST_CASE(short, kULong, ULong)
566 SIMPLE_CAST_CASE(short, kUnsignedLong, ULong)
567
568 TO_FLOAT_CASE(short)
569 TO_DOUBLE_CASE(short)
570
571 default:
572 log_error("ERROR: Invalid type given to "
573 "convert_explicit_value!!\n");
574 break;
575 }
576 break;
577
578 case kUShort:
579 ushortPtr = (ushort *)inRaw;
580 switch (outType)
581 {
582 BOOL_CASE(ushort)
583
584 case kUShort:
585 case kUnsignedShort:
586 memcpy(outRaw, inRaw, get_explicit_type_size(inType));
587 break;
588
589 DOWN_CAST_CASE(ushort, kChar, char, saturate)
590 DOWN_CAST_CASE(ushort, kUChar, uchar, saturate)
591 DOWN_CAST_CASE(ushort, kUnsignedChar, uchar, saturate)
592 DOWN_CAST_CASE(ushort, kShort, short, saturate)
593 SIMPLE_CAST_CASE(ushort, kInt, int)
594 SIMPLE_CAST_CASE(ushort, kUInt, uint)
595 SIMPLE_CAST_CASE(ushort, kUnsignedInt, uint)
596 SIMPLE_CAST_CASE(ushort, kLong, Long)
597 SIMPLE_CAST_CASE(ushort, kULong, ULong)
598 SIMPLE_CAST_CASE(ushort, kUnsignedLong, ULong)
599
600 TO_FLOAT_CASE(ushort)
601 TO_DOUBLE_CASE(ushort)
602
603 default:
604 log_error("ERROR: Invalid type given to "
605 "convert_explicit_value!!\n");
606 break;
607 }
608 break;
609
610 case kUnsignedShort:
611 ushortPtr = (ushort *)inRaw;
612 switch (outType)
613 {
614 BOOL_CASE(ushort)
615
616 case kUShort:
617 case kUnsignedShort:
618 memcpy(outRaw, inRaw, get_explicit_type_size(inType));
619 break;
620
621 DOWN_CAST_CASE(ushort, kChar, char, saturate)
622 DOWN_CAST_CASE(ushort, kUChar, uchar, saturate)
623 DOWN_CAST_CASE(ushort, kUnsignedChar, uchar, saturate)
624 DOWN_CAST_CASE(ushort, kShort, short, saturate)
625 SIMPLE_CAST_CASE(ushort, kInt, int)
626 SIMPLE_CAST_CASE(ushort, kUInt, uint)
627 SIMPLE_CAST_CASE(ushort, kUnsignedInt, uint)
628 SIMPLE_CAST_CASE(ushort, kLong, Long)
629 SIMPLE_CAST_CASE(ushort, kULong, ULong)
630 SIMPLE_CAST_CASE(ushort, kUnsignedLong, ULong)
631
632 TO_FLOAT_CASE(ushort)
633 TO_DOUBLE_CASE(ushort)
634
635 default:
636 log_error("ERROR: Invalid type given to "
637 "convert_explicit_value!!\n");
638 break;
639 }
640 break;
641
642 case kInt:
643 intPtr = (int *)inRaw;
644 switch (outType)
645 {
646 BOOL_CASE(int)
647
648 case kInt:
649 memcpy(outRaw, inRaw, get_explicit_type_size(inType));
650 break;
651
652 DOWN_CAST_CASE(int, kChar, char, saturate)
653 DOWN_CAST_CASE(int, kUChar, uchar, saturate)
654 DOWN_CAST_CASE(int, kUnsignedChar, uchar, saturate)
655 DOWN_CAST_CASE(int, kShort, short, saturate)
656 DOWN_CAST_CASE(int, kUShort, ushort, saturate)
657 DOWN_CAST_CASE(int, kUnsignedShort, ushort, saturate)
658 DOWN_CAST_CASE(int, kUInt, uint, saturate)
659 DOWN_CAST_CASE(int, kUnsignedInt, uint, saturate)
660 SIMPLE_CAST_CASE(int, kLong, Long)
661 SIMPLE_CAST_CASE(int, kULong, ULong)
662 SIMPLE_CAST_CASE(int, kUnsignedLong, ULong)
663
664 TO_FLOAT_CASE(int)
665 TO_DOUBLE_CASE(int)
666
667 default:
668 log_error("ERROR: Invalid type given to "
669 "convert_explicit_value!!\n");
670 break;
671 }
672 break;
673
674 case kUInt:
675 uintPtr = (uint *)inRaw;
676 switch (outType)
677 {
678 BOOL_CASE(uint)
679
680 case kUInt:
681 case kUnsignedInt:
682 memcpy(outRaw, inRaw, get_explicit_type_size(inType));
683 break;
684
685 DOWN_CAST_CASE(uint, kChar, char, saturate)
686 DOWN_CAST_CASE(uint, kUChar, uchar, saturate)
687 DOWN_CAST_CASE(uint, kUnsignedChar, uchar, saturate)
688 DOWN_CAST_CASE(uint, kShort, short, saturate)
689 DOWN_CAST_CASE(uint, kUShort, ushort, saturate)
690 DOWN_CAST_CASE(uint, kUnsignedShort, ushort, saturate)
691 DOWN_CAST_CASE(uint, kInt, int, saturate)
692 SIMPLE_CAST_CASE(uint, kLong, Long)
693 SIMPLE_CAST_CASE(uint, kULong, ULong)
694 SIMPLE_CAST_CASE(uint, kUnsignedLong, ULong)
695
696 TO_FLOAT_CASE(uint)
697 TO_DOUBLE_CASE(uint)
698
699 default:
700 log_error("ERROR: Invalid type given to "
701 "convert_explicit_value!!\n");
702 break;
703 }
704 break;
705
706 case kUnsignedInt:
707 uintPtr = (uint *)inRaw;
708 switch (outType)
709 {
710 BOOL_CASE(uint)
711
712 case kUInt:
713 case kUnsignedInt:
714 memcpy(outRaw, inRaw, get_explicit_type_size(inType));
715 break;
716
717 DOWN_CAST_CASE(uint, kChar, char, saturate)
718 DOWN_CAST_CASE(uint, kUChar, uchar, saturate)
719 DOWN_CAST_CASE(uint, kUnsignedChar, uchar, saturate)
720 DOWN_CAST_CASE(uint, kShort, short, saturate)
721 DOWN_CAST_CASE(uint, kUShort, ushort, saturate)
722 DOWN_CAST_CASE(uint, kUnsignedShort, ushort, saturate)
723 DOWN_CAST_CASE(uint, kInt, int, saturate)
724 SIMPLE_CAST_CASE(uint, kLong, Long)
725 SIMPLE_CAST_CASE(uint, kULong, ULong)
726 SIMPLE_CAST_CASE(uint, kUnsignedLong, ULong)
727
728 TO_FLOAT_CASE(uint)
729 TO_DOUBLE_CASE(uint)
730
731 default:
732 log_error("ERROR: Invalid type given to "
733 "convert_explicit_value!!\n");
734 break;
735 }
736 break;
737
738 case kLong:
739 LongPtr = (Long *)inRaw;
740 switch (outType)
741 {
742 BOOL_CASE(Long)
743
744 case kLong:
745 memcpy(outRaw, inRaw, get_explicit_type_size(inType));
746 break;
747
748 DOWN_CAST_CASE(Long, kChar, char, saturate)
749 DOWN_CAST_CASE(Long, kUChar, uchar, saturate)
750 DOWN_CAST_CASE(Long, kUnsignedChar, uchar, saturate)
751 DOWN_CAST_CASE(Long, kShort, short, saturate)
752 DOWN_CAST_CASE(Long, kUShort, ushort, saturate)
753 DOWN_CAST_CASE(Long, kUnsignedShort, ushort, saturate)
754 DOWN_CAST_CASE(Long, kInt, int, saturate)
755 DOWN_CAST_CASE(Long, kUInt, uint, saturate)
756 DOWN_CAST_CASE(Long, kUnsignedInt, uint, saturate)
757 DOWN_CAST_CASE(Long, kULong, ULong, saturate)
758 DOWN_CAST_CASE(Long, kUnsignedLong, ULong, saturate)
759
760 TO_FLOAT_CASE(Long)
761 TO_DOUBLE_CASE(Long)
762
763 default:
764 log_error("ERROR: Invalid type given to "
765 "convert_explicit_value!!\n");
766 break;
767 }
768 break;
769
770 case kULong:
771 ULongPtr = (ULong *)inRaw;
772 switch (outType)
773 {
774 BOOL_CASE(ULong)
775
776 case kUnsignedLong:
777 case kULong:
778 memcpy(outRaw, inRaw, get_explicit_type_size(inType));
779 break;
780
781 U_DOWN_CAST_CASE(ULong, kChar, char, saturate)
782 U_DOWN_CAST_CASE(ULong, kUChar, uchar, saturate)
783 U_DOWN_CAST_CASE(ULong, kUnsignedChar, uchar, saturate)
784 U_DOWN_CAST_CASE(ULong, kShort, short, saturate)
785 U_DOWN_CAST_CASE(ULong, kUShort, ushort, saturate)
786 U_DOWN_CAST_CASE(ULong, kUnsignedShort, ushort, saturate)
787 U_DOWN_CAST_CASE(ULong, kInt, int, saturate)
788 U_DOWN_CAST_CASE(ULong, kUInt, uint, saturate)
789 U_DOWN_CAST_CASE(ULong, kUnsignedInt, uint, saturate)
790 U_DOWN_CAST_CASE(ULong, kLong, Long, saturate)
791
792 TO_FLOAT_CASE(ULong)
793 TO_DOUBLE_CASE(ULong)
794
795 default:
796 log_error("ERROR: Invalid type given to "
797 "convert_explicit_value!!\n");
798 break;
799 }
800 break;
801
802 case kUnsignedLong:
803 ULongPtr = (ULong *)inRaw;
804 switch (outType)
805 {
806 BOOL_CASE(ULong)
807
808 case kULong:
809 case kUnsignedLong:
810 memcpy(outRaw, inRaw, get_explicit_type_size(inType));
811 break;
812
813 U_DOWN_CAST_CASE(ULong, kChar, char, saturate)
814 U_DOWN_CAST_CASE(ULong, kUChar, uchar, saturate)
815 U_DOWN_CAST_CASE(ULong, kUnsignedChar, uchar, saturate)
816 U_DOWN_CAST_CASE(ULong, kShort, short, saturate)
817 U_DOWN_CAST_CASE(ULong, kUShort, ushort, saturate)
818 U_DOWN_CAST_CASE(ULong, kUnsignedShort, ushort, saturate)
819 U_DOWN_CAST_CASE(ULong, kInt, int, saturate)
820 U_DOWN_CAST_CASE(ULong, kUInt, uint, saturate)
821 U_DOWN_CAST_CASE(ULong, kUnsignedInt, uint, saturate)
822 U_DOWN_CAST_CASE(ULong, kLong, Long, saturate)
823
824 TO_FLOAT_CASE(ULong)
825 TO_DOUBLE_CASE(ULong)
826
827 default:
828 log_error("ERROR: Invalid type given to "
829 "convert_explicit_value!!\n");
830 break;
831 }
832 break;
833
834 case kFloat:
835 floatPtr = (float *)inRaw;
836 switch (outType)
837 {
838 BOOL_CASE(float)
839
840 FLOAT_ROUND_CASE(kChar, char, roundType, saturate)
841 FLOAT_ROUND_CASE(kUChar, uchar, roundType, saturate)
842 FLOAT_ROUND_CASE(kUnsignedChar, uchar, roundType, saturate)
843 FLOAT_ROUND_CASE(kShort, short, roundType, saturate)
844 FLOAT_ROUND_CASE(kUShort, ushort, roundType, saturate)
845 FLOAT_ROUND_CASE(kUnsignedShort, ushort, roundType, saturate)
846 FLOAT_ROUND_CASE(kInt, int, roundType, saturate)
847 FLOAT_ROUND_CASE(kUInt, uint, roundType, saturate)
848 FLOAT_ROUND_CASE(kUnsignedInt, uint, roundType, saturate)
849 FLOAT_ROUND_CASE(kLong, Long, roundType, saturate)
850 FLOAT_ROUND_CASE(kULong, ULong, roundType, saturate)
851 FLOAT_ROUND_CASE(kUnsignedLong, ULong, roundType, saturate)
852
853 case kFloat:
854 memcpy(outRaw, inRaw, get_explicit_type_size(inType));
855 break;
856
857 TO_DOUBLE_CASE(float);
858
859 default:
860 log_error("ERROR: Invalid type given to "
861 "convert_explicit_value!!\n");
862 break;
863 }
864 break;
865
866 case kDouble:
867 doublePtr = (double *)inRaw;
868 switch (outType)
869 {
870 BOOL_CASE(double)
871
872 DOUBLE_ROUND_CASE(kChar, char, roundType, saturate)
873 DOUBLE_ROUND_CASE(kUChar, uchar, roundType, saturate)
874 DOUBLE_ROUND_CASE(kUnsignedChar, uchar, roundType, saturate)
875 DOUBLE_ROUND_CASE(kShort, short, roundType, saturate)
876 DOUBLE_ROUND_CASE(kUShort, ushort, roundType, saturate)
877 DOUBLE_ROUND_CASE(kUnsignedShort, ushort, roundType, saturate)
878 DOUBLE_ROUND_CASE(kInt, int, roundType, saturate)
879 DOUBLE_ROUND_CASE(kUInt, uint, roundType, saturate)
880 DOUBLE_ROUND_CASE(kUnsignedInt, uint, roundType, saturate)
881 DOUBLE_ROUND_CASE(kLong, Long, roundType, saturate)
882 DOUBLE_ROUND_CASE(kULong, ULong, roundType, saturate)
883 DOUBLE_ROUND_CASE(kUnsignedLong, ULong, roundType, saturate)
884
885 TO_FLOAT_CASE(double);
886
887 case kDouble:
888 memcpy(outRaw, inRaw, get_explicit_type_size(inType));
889 break;
890
891 default:
892 log_error("ERROR: Invalid type given to "
893 "convert_explicit_value!!\n");
894 break;
895 }
896 break;
897
898 default:
899 log_error(
900 "ERROR: Invalid type given to convert_explicit_value!!\n");
901 break;
902 }
903 }
904
generate_random_data(ExplicitType type,size_t count,MTdata d,void * outData)905 void generate_random_data(ExplicitType type, size_t count, MTdata d,
906 void *outData)
907 {
908 bool *boolPtr;
909 cl_char *charPtr;
910 cl_uchar *ucharPtr;
911 cl_short *shortPtr;
912 cl_ushort *ushortPtr;
913 cl_int *intPtr;
914 cl_uint *uintPtr;
915 cl_long *longPtr;
916 cl_ulong *ulongPtr;
917 cl_float *floatPtr;
918 cl_double *doublePtr;
919 cl_half *halfPtr;
920 size_t i;
921 cl_uint bits = genrand_int32(d);
922 cl_uint bitsLeft = 32;
923
924 switch (type)
925 {
926 case kBool:
927 boolPtr = (bool *)outData;
928 for (i = 0; i < count; i++)
929 {
930 if (0 == bitsLeft)
931 {
932 bits = genrand_int32(d);
933 bitsLeft = 32;
934 }
935 boolPtr[i] = (bits & 1) ? true : false;
936 bits >>= 1;
937 bitsLeft -= 1;
938 }
939 break;
940
941 case kChar:
942 charPtr = (cl_char *)outData;
943 for (i = 0; i < count; i++)
944 {
945 if (0 == bitsLeft)
946 {
947 bits = genrand_int32(d);
948 bitsLeft = 32;
949 }
950 charPtr[i] = (cl_char)((cl_int)(bits & 255) - 127);
951 bits >>= 8;
952 bitsLeft -= 8;
953 }
954 break;
955
956 case kUChar:
957 case kUnsignedChar:
958 ucharPtr = (cl_uchar *)outData;
959 for (i = 0; i < count; i++)
960 {
961 if (0 == bitsLeft)
962 {
963 bits = genrand_int32(d);
964 bitsLeft = 32;
965 }
966 ucharPtr[i] = (cl_uchar)(bits & 255);
967 bits >>= 8;
968 bitsLeft -= 8;
969 }
970 break;
971
972 case kShort:
973 shortPtr = (cl_short *)outData;
974 for (i = 0; i < count; i++)
975 {
976 if (0 == bitsLeft)
977 {
978 bits = genrand_int32(d);
979 bitsLeft = 32;
980 }
981 shortPtr[i] = (cl_short)((cl_int)(bits & 65535) - 32767);
982 bits >>= 16;
983 bitsLeft -= 16;
984 }
985 break;
986
987 case kUShort:
988 case kUnsignedShort:
989 ushortPtr = (cl_ushort *)outData;
990 for (i = 0; i < count; i++)
991 {
992 if (0 == bitsLeft)
993 {
994 bits = genrand_int32(d);
995 bitsLeft = 32;
996 }
997 ushortPtr[i] = (cl_ushort)((cl_int)(bits & 65535));
998 bits >>= 16;
999 bitsLeft -= 16;
1000 }
1001 break;
1002
1003 case kInt:
1004 intPtr = (cl_int *)outData;
1005 for (i = 0; i < count; i++)
1006 {
1007 intPtr[i] = (cl_int)genrand_int32(d);
1008 }
1009 break;
1010
1011 case kUInt:
1012 case kUnsignedInt:
1013 uintPtr = (cl_uint *)outData;
1014 for (i = 0; i < count; i++)
1015 {
1016 uintPtr[i] = (unsigned int)genrand_int32(d);
1017 }
1018 break;
1019
1020 case kLong:
1021 longPtr = (cl_long *)outData;
1022 for (i = 0; i < count; i++)
1023 {
1024 longPtr[i] = (cl_long)genrand_int32(d)
1025 | ((cl_long)genrand_int32(d) << 32);
1026 }
1027 break;
1028
1029 case kULong:
1030 case kUnsignedLong:
1031 ulongPtr = (cl_ulong *)outData;
1032 for (i = 0; i < count; i++)
1033 {
1034 ulongPtr[i] = (cl_ulong)genrand_int32(d)
1035 | ((cl_ulong)genrand_int32(d) << 32);
1036 }
1037 break;
1038
1039 case kFloat:
1040 floatPtr = (cl_float *)outData;
1041 for (i = 0; i < count; i++)
1042 {
1043 // [ -(double) 0x7fffffff, (double) 0x7fffffff ]
1044 double t = genrand_real1(d);
1045 floatPtr[i] = (float)((1.0 - t) * -(double)0x7fffffff
1046 + t * (double)0x7fffffff);
1047 }
1048 break;
1049
1050 case kDouble:
1051 doublePtr = (cl_double *)outData;
1052 for (i = 0; i < count; i++)
1053 {
1054 cl_long u = (cl_long)genrand_int32(d)
1055 | ((cl_long)genrand_int32(d) << 32);
1056 double t = (double)u;
1057 // scale [-2**63, 2**63] to [-2**31, 2**31]
1058 t *= MAKE_HEX_DOUBLE(0x1.0p-32, 0x1, -32);
1059 doublePtr[i] = t;
1060 }
1061 break;
1062
1063 case kHalf:
1064 halfPtr = (ushort *)outData;
1065 for (i = 0; i < count; i++)
1066 {
1067 if (0 == bitsLeft)
1068 {
1069 bits = genrand_int32(d);
1070 bitsLeft = 32;
1071 }
1072 halfPtr[i] =
1073 bits & 65535; /* Kindly generates random bits for us */
1074 bits >>= 16;
1075 bitsLeft -= 16;
1076 }
1077 break;
1078
1079 default:
1080 log_error(
1081 "ERROR: Invalid type passed in to generate_random_data!\n");
1082 break;
1083 }
1084 }
1085
create_random_data(ExplicitType type,MTdata d,size_t count)1086 void *create_random_data(ExplicitType type, MTdata d, size_t count)
1087 {
1088 void *data = malloc(get_explicit_type_size(type) * count);
1089 generate_random_data(type, count, d, data);
1090 return data;
1091 }
1092
read_upscale_signed(void * inRaw,ExplicitType inType)1093 cl_long read_upscale_signed(void *inRaw, ExplicitType inType)
1094 {
1095 switch (inType)
1096 {
1097 case kChar: return (cl_long)(*((cl_char *)inRaw));
1098 case kUChar:
1099 case kUnsignedChar: return (cl_long)(*((cl_uchar *)inRaw));
1100 case kShort: return (cl_long)(*((cl_short *)inRaw));
1101 case kUShort:
1102 case kUnsignedShort: return (cl_long)(*((cl_ushort *)inRaw));
1103 case kInt: return (cl_long)(*((cl_int *)inRaw));
1104 case kUInt:
1105 case kUnsignedInt: return (cl_long)(*((cl_uint *)inRaw));
1106 case kLong: return (cl_long)(*((cl_long *)inRaw));
1107 case kULong:
1108 case kUnsignedLong: return (cl_long)(*((cl_ulong *)inRaw));
1109 default: return 0;
1110 }
1111 }
1112
read_upscale_unsigned(void * inRaw,ExplicitType inType)1113 cl_ulong read_upscale_unsigned(void *inRaw, ExplicitType inType)
1114 {
1115 switch (inType)
1116 {
1117 case kChar: return (cl_ulong)(*((cl_char *)inRaw));
1118 case kUChar:
1119 case kUnsignedChar: return (cl_ulong)(*((cl_uchar *)inRaw));
1120 case kShort: return (cl_ulong)(*((cl_short *)inRaw));
1121 case kUShort:
1122 case kUnsignedShort: return (cl_ulong)(*((cl_ushort *)inRaw));
1123 case kInt: return (cl_ulong)(*((cl_int *)inRaw));
1124 case kUInt:
1125 case kUnsignedInt: return (cl_ulong)(*((cl_uint *)inRaw));
1126 case kLong: return (cl_ulong)(*((cl_long *)inRaw));
1127 case kULong:
1128 case kUnsignedLong: return (cl_ulong)(*((cl_ulong *)inRaw));
1129 default: return 0;
1130 }
1131 }
1132
read_as_float(void * inRaw,ExplicitType inType)1133 float read_as_float(void *inRaw, ExplicitType inType)
1134 {
1135 switch (inType)
1136 {
1137 case kChar: return (float)(*((cl_char *)inRaw));
1138 case kUChar:
1139 case kUnsignedChar: return (float)(*((cl_char *)inRaw));
1140 case kShort: return (float)(*((cl_short *)inRaw));
1141 case kUShort:
1142 case kUnsignedShort: return (float)(*((cl_ushort *)inRaw));
1143 case kInt: return (float)(*((cl_int *)inRaw));
1144 case kUInt:
1145 case kUnsignedInt: return (float)(*((cl_uint *)inRaw));
1146 case kLong: return (float)(*((cl_long *)inRaw));
1147 case kULong:
1148 case kUnsignedLong: return (float)(*((cl_ulong *)inRaw));
1149 case kFloat: return *((float *)inRaw);
1150 case kDouble: return (float)*((double *)inRaw);
1151 default: return 0;
1152 }
1153 }
1154
get_random_float(float low,float high,MTdata d)1155 float get_random_float(float low, float high, MTdata d)
1156 {
1157 float t = (float)((double)genrand_int32(d) / (double)0xFFFFFFFF);
1158 return (1.0f - t) * low + t * high;
1159 }
1160
get_random_double(double low,double high,MTdata d)1161 double get_random_double(double low, double high, MTdata d)
1162 {
1163 cl_ulong u =
1164 (cl_ulong)genrand_int32(d) | ((cl_ulong)genrand_int32(d) << 32);
1165 double t = (double)u * MAKE_HEX_DOUBLE(0x1.0p-64, 0x1, -64);
1166 return (1.0f - t) * low + t * high;
1167 }
1168
any_float(MTdata d)1169 float any_float(MTdata d)
1170 {
1171 union {
1172 float f;
1173 cl_uint u;
1174 } u;
1175
1176 u.u = genrand_int32(d);
1177 return u.f;
1178 }
1179
1180
any_double(MTdata d)1181 double any_double(MTdata d)
1182 {
1183 union {
1184 double f;
1185 cl_ulong u;
1186 } u;
1187
1188 u.u = (cl_ulong)genrand_int32(d) | ((cl_ulong)genrand_int32(d) << 32);
1189 return u.f;
1190 }
1191
random_in_range(int minV,int maxV,MTdata d)1192 int random_in_range(int minV, int maxV, MTdata d)
1193 {
1194 cl_ulong r = ((cl_ulong)genrand_int32(d)) * (maxV - minV + 1);
1195 return (cl_uint)(r >> 32) + minV;
1196 }
1197
get_random_size_t(size_t low,size_t high,MTdata d)1198 size_t get_random_size_t(size_t low, size_t high, MTdata d)
1199 {
1200 enum
1201 {
1202 N = sizeof(size_t) / sizeof(int)
1203 };
1204
1205 union {
1206 int word[N];
1207 size_t size;
1208 } u;
1209
1210 for (unsigned i = 0; i != N; ++i)
1211 {
1212 u.word[i] = genrand_int32(d);
1213 }
1214
1215 assert(low <= high && "Invalid random number range specified");
1216 size_t range = high - low;
1217
1218 return (range) ? low + ((u.size - low) % range) : low;
1219 }
1220