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