• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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