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