mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 06:09:01 +00:00
1199 lines
42 KiB
C++
1199 lines
42 KiB
C++
//
|
|
// Copyright (c) 2017 The Khronos Group Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
#include "conversions.h"
|
|
#include <limits.h>
|
|
#include <time.h>
|
|
#include <assert.h>
|
|
#include "mt19937.h"
|
|
#include "compat.h"
|
|
|
|
#if defined( __SSE__ ) || defined (_MSC_VER)
|
|
#include <xmmintrin.h>
|
|
#endif
|
|
#if defined( __SSE2__ ) || defined (_MSC_VER)
|
|
#include <emmintrin.h>
|
|
#endif
|
|
|
|
void print_type_to_string(ExplicitType type, void *data, char* string) {
|
|
switch (type) {
|
|
case kBool:
|
|
if (*(char*)data)
|
|
sprintf(string, "true");
|
|
else
|
|
sprintf(string, "false");
|
|
return;
|
|
case kChar:
|
|
sprintf(string, "%d", (int)*((cl_char*)data));
|
|
return;
|
|
case kUChar:
|
|
case kUnsignedChar:
|
|
sprintf(string, "%u", (int)*((cl_uchar*)data));
|
|
return;
|
|
case kShort:
|
|
sprintf(string, "%d", (int)*((cl_short*)data));
|
|
return;
|
|
case kUShort:
|
|
case kUnsignedShort:
|
|
sprintf(string, "%u", (int)*((cl_ushort*)data));
|
|
return;
|
|
case kInt:
|
|
sprintf(string, "%d", *((cl_int*)data));
|
|
return;
|
|
case kUInt:
|
|
case kUnsignedInt:
|
|
sprintf(string, "%u", *((cl_uint*)data));
|
|
return;
|
|
case kLong:
|
|
sprintf(string, "%lld", *((cl_long*)data));
|
|
return;
|
|
case kULong:
|
|
case kUnsignedLong:
|
|
sprintf(string, "%llu", *((cl_ulong*)data));
|
|
return;
|
|
case kFloat:
|
|
sprintf(string, "%f", *((cl_float*)data));
|
|
return;
|
|
case kHalf:
|
|
sprintf(string, "half");
|
|
return;
|
|
case kDouble:
|
|
sprintf(string, "%g", *((cl_double*)data));
|
|
return;
|
|
default:
|
|
sprintf(string, "INVALID");
|
|
return;
|
|
}
|
|
|
|
}
|
|
|
|
size_t get_explicit_type_size( ExplicitType type )
|
|
{
|
|
/* Quick method to avoid branching: make sure the following array matches the Enum order */
|
|
static size_t sExplicitTypeSizes[] = {
|
|
sizeof( cl_bool ),
|
|
sizeof( cl_char ),
|
|
sizeof( cl_uchar ),
|
|
sizeof( cl_uchar ),
|
|
sizeof( cl_short ),
|
|
sizeof( cl_ushort ),
|
|
sizeof( cl_ushort ),
|
|
sizeof( cl_int ),
|
|
sizeof( cl_uint ),
|
|
sizeof( cl_uint ),
|
|
sizeof( cl_long ),
|
|
sizeof( cl_ulong ),
|
|
sizeof( cl_ulong ),
|
|
sizeof( cl_float ),
|
|
sizeof( cl_half ),
|
|
sizeof( cl_double )
|
|
};
|
|
|
|
return sExplicitTypeSizes[ type ];
|
|
}
|
|
|
|
const char * get_explicit_type_name( ExplicitType type )
|
|
{
|
|
/* Quick method to avoid branching: make sure the following array matches the Enum order */
|
|
static const char *sExplicitTypeNames[] = { "bool", "char", "uchar", "unsigned char", "short", "ushort", "unsigned short", "int",
|
|
"uint", "unsigned int", "long", "ulong", "unsigned long", "float", "half", "double" };
|
|
|
|
return sExplicitTypeNames[ type ];
|
|
}
|
|
|
|
static long lrintf_clamped( float f );
|
|
static long lrintf_clamped( float f )
|
|
{
|
|
static const float magic[2] = { MAKE_HEX_FLOAT( 0x1.0p23f, 0x1, 23), - MAKE_HEX_FLOAT( 0x1.0p23f, 0x1, 23) };
|
|
|
|
if( f >= -(float) LONG_MIN )
|
|
return LONG_MAX;
|
|
|
|
if( f <= (float) LONG_MIN )
|
|
return LONG_MIN;
|
|
|
|
// Round fractional values to integer in round towards nearest mode
|
|
if( fabsf(f) < MAKE_HEX_FLOAT( 0x1.0p23f, 0x1, 23 ) )
|
|
{
|
|
volatile float x = f;
|
|
float magicVal = magic[ f < 0 ];
|
|
|
|
#if defined( __SSE__ ) || defined (_WIN32)
|
|
// Defeat x87 based arithmetic, which cant do FTZ, and will round this incorrectly
|
|
__m128 v = _mm_set_ss( x );
|
|
__m128 m = _mm_set_ss( magicVal );
|
|
v = _mm_add_ss( v, m );
|
|
v = _mm_sub_ss( v, m );
|
|
_mm_store_ss( (float*) &x, v );
|
|
#else
|
|
x += magicVal;
|
|
x -= magicVal;
|
|
#endif
|
|
f = x;
|
|
}
|
|
|
|
return (long) f;
|
|
}
|
|
|
|
static long lrint_clamped( double f );
|
|
static long lrint_clamped( double f )
|
|
{
|
|
static const double magic[2] = { MAKE_HEX_DOUBLE(0x1.0p52, 0x1LL, 52), MAKE_HEX_DOUBLE(-0x1.0p52, -0x1LL, 52) };
|
|
|
|
if( sizeof( long ) > 4 )
|
|
{
|
|
if( f >= -(double) LONG_MIN )
|
|
return LONG_MAX;
|
|
}
|
|
else
|
|
{
|
|
if( f >= LONG_MAX )
|
|
return LONG_MAX;
|
|
}
|
|
|
|
if( f <= (double) LONG_MIN )
|
|
return LONG_MIN;
|
|
|
|
// Round fractional values to integer in round towards nearest mode
|
|
if( fabs(f) < MAKE_HEX_DOUBLE(0x1.0p52, 0x1LL, 52) )
|
|
{
|
|
volatile double x = f;
|
|
double magicVal = magic[ f < 0 ];
|
|
#if defined( __SSE2__ ) || (defined (_MSC_VER))
|
|
// Defeat x87 based arithmetic, which cant do FTZ, and will round this incorrectly
|
|
__m128d v = _mm_set_sd( x );
|
|
__m128d m = _mm_set_sd( magicVal );
|
|
v = _mm_add_sd( v, m );
|
|
v = _mm_sub_sd( v, m );
|
|
_mm_store_sd( (double*) &x, v );
|
|
#else
|
|
x += magicVal;
|
|
x -= magicVal;
|
|
#endif
|
|
f = x;
|
|
}
|
|
|
|
return (long) f;
|
|
}
|
|
|
|
|
|
typedef cl_long Long;
|
|
typedef cl_ulong ULong;
|
|
|
|
static ULong sUpperLimits[ kNumExplicitTypes ] =
|
|
{
|
|
0,
|
|
127, 255, 255,
|
|
32767, 65535, 65535,
|
|
0x7fffffffLL, 0xffffffffLL, 0xffffffffLL,
|
|
0x7fffffffffffffffLL, 0xffffffffffffffffLL, 0xffffffffffffffffLL,
|
|
0, 0 }; // Last two values aren't stored here
|
|
|
|
static Long sLowerLimits[ kNumExplicitTypes ] =
|
|
{
|
|
-1,
|
|
-128, 0, 0,
|
|
-32768, 0, 0,
|
|
(Long)0xffffffff80000000LL, 0, 0,
|
|
(Long)0x8000000000000000LL, 0, 0,
|
|
0, 0 }; // Last two values aren't stored here
|
|
|
|
#define BOOL_CASE(inType) \
|
|
case kBool: \
|
|
boolPtr = (bool *)outRaw; \
|
|
*boolPtr = ( *inType##Ptr ) != 0 ? true : false; \
|
|
break;
|
|
|
|
#define SIMPLE_CAST_CASE(inType,outEnum,outType) \
|
|
case outEnum: \
|
|
outType##Ptr = (outType *)outRaw; \
|
|
*outType##Ptr = (outType)(*inType##Ptr); \
|
|
break;
|
|
|
|
// Sadly, the ULong downcasting cases need a separate #define to get rid of signed/unsigned comparison warnings
|
|
#define DOWN_CAST_CASE(inType,outEnum,outType,sat) \
|
|
case outEnum: \
|
|
outType##Ptr = (outType *)outRaw; \
|
|
if( sat ) \
|
|
{ \
|
|
if( ( sLowerLimits[outEnum] < 0 && *inType##Ptr > (Long)sUpperLimits[outEnum] ) || ( sLowerLimits[outEnum] == 0 && (ULong)*inType##Ptr > sUpperLimits[outEnum] ) )\
|
|
*outType##Ptr = (outType)sUpperLimits[outEnum];\
|
|
else if( *inType##Ptr < sLowerLimits[outEnum] )\
|
|
*outType##Ptr = (outType)sLowerLimits[outEnum]; \
|
|
else \
|
|
*outType##Ptr = (outType)*inType##Ptr; \
|
|
} else { \
|
|
*outType##Ptr = (outType)( *inType##Ptr & ( 0xffffffffffffffffLL >> ( 64 - ( sizeof( outType ) * 8 ) ) ) ); \
|
|
} \
|
|
break;
|
|
|
|
#define U_DOWN_CAST_CASE(inType,outEnum,outType,sat) \
|
|
case outEnum: \
|
|
outType##Ptr = (outType *)outRaw; \
|
|
if( sat ) \
|
|
{ \
|
|
if( (ULong)*inType##Ptr > sUpperLimits[outEnum] )\
|
|
*outType##Ptr = (outType)sUpperLimits[outEnum];\
|
|
else \
|
|
*outType##Ptr = (outType)*inType##Ptr; \
|
|
} else { \
|
|
*outType##Ptr = (outType)( *inType##Ptr & ( 0xffffffffffffffffLL >> ( 64 - ( sizeof( outType ) * 8 ) ) ) ); \
|
|
} \
|
|
break;
|
|
|
|
#define TO_FLOAT_CASE(inType) \
|
|
case kFloat: \
|
|
floatPtr = (float *)outRaw; \
|
|
*floatPtr = (float)(*inType##Ptr); \
|
|
break;
|
|
#define TO_DOUBLE_CASE(inType) \
|
|
case kDouble: \
|
|
doublePtr = (double *)outRaw; \
|
|
*doublePtr = (double)(*inType##Ptr); \
|
|
break;
|
|
|
|
|
|
/* Note: we use lrintf here to force the rounding instead of whatever the processor's current rounding mode is */
|
|
#define FLOAT_ROUND_TO_NEAREST_CASE(outEnum,outType) \
|
|
case outEnum: \
|
|
outType##Ptr = (outType *)outRaw; \
|
|
*outType##Ptr = (outType)lrintf_clamped( *floatPtr ); \
|
|
break;
|
|
|
|
#define FLOAT_ROUND_CASE(outEnum,outType,rounding,sat) \
|
|
case outEnum: \
|
|
{ \
|
|
outType##Ptr = (outType *)outRaw; \
|
|
/* Get the tens digit */ \
|
|
Long wholeValue = (Long)*floatPtr;\
|
|
float largeRemainder = ( *floatPtr - (float)wholeValue ) * 10.f; \
|
|
/* What do we do based on that? */ \
|
|
if( rounding == kRoundToEven ) \
|
|
{ \
|
|
if( wholeValue & 1LL ) /*between 1 and 1.99 */ \
|
|
wholeValue += 1LL; /* round up to even */ \
|
|
} \
|
|
else if( rounding == kRoundToZero ) \
|
|
{ \
|
|
/* Nothing to do, round-to-zero is what C casting does */ \
|
|
} \
|
|
else if( rounding == kRoundToPosInf ) \
|
|
{ \
|
|
/* Only positive numbers are wrong */ \
|
|
if( largeRemainder != 0.f && wholeValue >= 0 ) \
|
|
wholeValue++; \
|
|
} \
|
|
else if( rounding == kRoundToNegInf ) \
|
|
{ \
|
|
/* Only negative numbers are off */ \
|
|
if( largeRemainder != 0.f && wholeValue < 0 ) \
|
|
wholeValue--; \
|
|
} \
|
|
else \
|
|
{ /* Default is round-to-nearest */ \
|
|
wholeValue = (Long)lrintf_clamped( *floatPtr ); \
|
|
} \
|
|
/* Now apply saturation rules */ \
|
|
if( sat ) \
|
|
{ \
|
|
if( ( sLowerLimits[outEnum] < 0 && wholeValue > (Long)sUpperLimits[outEnum] ) || ( sLowerLimits[outEnum] == 0 && (ULong)wholeValue > sUpperLimits[outEnum] ) )\
|
|
*outType##Ptr = (outType)sUpperLimits[outEnum];\
|
|
else if( wholeValue < sLowerLimits[outEnum] )\
|
|
*outType##Ptr = (outType)sLowerLimits[outEnum]; \
|
|
else \
|
|
*outType##Ptr = (outType)wholeValue; \
|
|
} else { \
|
|
*outType##Ptr = (outType)( wholeValue & ( 0xffffffffffffffffLL >> ( 64 - ( sizeof( outType ) * 8 ) ) ) ); \
|
|
} \
|
|
} \
|
|
break;
|
|
|
|
#define DOUBLE_ROUND_CASE(outEnum,outType,rounding,sat) \
|
|
case outEnum: \
|
|
{ \
|
|
outType##Ptr = (outType *)outRaw; \
|
|
/* Get the tens digit */ \
|
|
Long wholeValue = (Long)*doublePtr;\
|
|
double largeRemainder = ( *doublePtr - (double)wholeValue ) * 10.0; \
|
|
/* What do we do based on that? */ \
|
|
if( rounding == kRoundToEven ) \
|
|
{ \
|
|
if( wholeValue & 1LL ) /*between 1 and 1.99 */ \
|
|
wholeValue += 1LL; /* round up to even */ \
|
|
} \
|
|
else if( rounding == kRoundToZero ) \
|
|
{ \
|
|
/* Nothing to do, round-to-zero is what C casting does */ \
|
|
} \
|
|
else if( rounding == kRoundToPosInf ) \
|
|
{ \
|
|
/* Only positive numbers are wrong */ \
|
|
if( largeRemainder != 0.0 && wholeValue >= 0 ) \
|
|
wholeValue++; \
|
|
} \
|
|
else if( rounding == kRoundToNegInf ) \
|
|
{ \
|
|
/* Only negative numbers are off */ \
|
|
if( largeRemainder != 0.0 && wholeValue < 0 ) \
|
|
wholeValue--; \
|
|
} \
|
|
else \
|
|
{ /* Default is round-to-nearest */ \
|
|
wholeValue = (Long)lrint_clamped( *doublePtr ); \
|
|
} \
|
|
/* Now apply saturation rules */ \
|
|
if( sat ) \
|
|
{ \
|
|
if( ( sLowerLimits[outEnum] < 0 && wholeValue > (Long)sUpperLimits[outEnum] ) || ( sLowerLimits[outEnum] == 0 && (ULong)wholeValue > sUpperLimits[outEnum] ) )\
|
|
*outType##Ptr = (outType)sUpperLimits[outEnum];\
|
|
else if( wholeValue < sLowerLimits[outEnum] )\
|
|
*outType##Ptr = (outType)sLowerLimits[outEnum]; \
|
|
else \
|
|
*outType##Ptr = (outType)wholeValue; \
|
|
} else { \
|
|
*outType##Ptr = (outType)( wholeValue & ( 0xffffffffffffffffLL >> ( 64 - ( sizeof( outType ) * 8 ) ) ) ); \
|
|
} \
|
|
} \
|
|
break;
|
|
|
|
typedef unsigned char uchar;
|
|
typedef unsigned short ushort;
|
|
typedef unsigned int uint;
|
|
typedef unsigned long ulong;
|
|
|
|
void convert_explicit_value( void *inRaw, void *outRaw, ExplicitType inType, bool saturate, RoundingType roundType, ExplicitType outType )
|
|
{
|
|
bool *boolPtr;
|
|
char *charPtr;
|
|
uchar *ucharPtr;
|
|
short *shortPtr;
|
|
ushort *ushortPtr;
|
|
int *intPtr;
|
|
uint *uintPtr;
|
|
Long *LongPtr;
|
|
ULong *ULongPtr;
|
|
float *floatPtr;
|
|
double *doublePtr;
|
|
|
|
|
|
switch( inType )
|
|
{
|
|
case kBool:
|
|
boolPtr = (bool *)inRaw;
|
|
switch( outType )
|
|
{
|
|
case kBool:
|
|
memcpy( outRaw, inRaw, get_explicit_type_size( inType ) );
|
|
break;
|
|
|
|
case kChar:
|
|
case kUChar:
|
|
case kUnsignedChar:
|
|
case kShort:
|
|
case kUShort:
|
|
case kUnsignedShort:
|
|
case kInt:
|
|
case kUInt:
|
|
case kUnsignedInt:
|
|
case kLong:
|
|
case kULong:
|
|
case kUnsignedLong:
|
|
memset( outRaw, *boolPtr ? 0xff : 0, get_explicit_type_size( outType ) );
|
|
break;
|
|
|
|
case kFloat:
|
|
floatPtr = (float *)outRaw;
|
|
*floatPtr = ( *boolPtr ) ? -1.f : 0.f;
|
|
break;
|
|
case kDouble:
|
|
doublePtr = (double *)outRaw;
|
|
*doublePtr = ( *boolPtr ) ? -1.0 : 0.0;
|
|
break;
|
|
default:
|
|
log_error( "ERROR: Invalid type given to convert_explicit_value!!\n" );
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case kChar:
|
|
charPtr = (char *)inRaw;
|
|
switch( outType )
|
|
{
|
|
BOOL_CASE(char)
|
|
|
|
case kChar:
|
|
memcpy( outRaw, inRaw, get_explicit_type_size( inType ) );
|
|
break;
|
|
|
|
DOWN_CAST_CASE(char,kUChar,uchar,saturate)
|
|
SIMPLE_CAST_CASE(char,kUnsignedChar,uchar)
|
|
SIMPLE_CAST_CASE(char,kShort,short)
|
|
SIMPLE_CAST_CASE(char,kUShort,ushort)
|
|
SIMPLE_CAST_CASE(char,kUnsignedShort,ushort)
|
|
SIMPLE_CAST_CASE(char,kInt,int)
|
|
SIMPLE_CAST_CASE(char,kUInt,uint)
|
|
SIMPLE_CAST_CASE(char,kUnsignedInt,uint)
|
|
SIMPLE_CAST_CASE(char,kLong,Long)
|
|
SIMPLE_CAST_CASE(char,kULong,ULong)
|
|
SIMPLE_CAST_CASE(char,kUnsignedLong,ULong)
|
|
|
|
TO_FLOAT_CASE(char)
|
|
TO_DOUBLE_CASE(char)
|
|
|
|
default:
|
|
log_error( "ERROR: Invalid type given to convert_explicit_value!!\n" );
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case kUChar:
|
|
ucharPtr = (uchar *)inRaw;
|
|
switch( outType )
|
|
{
|
|
BOOL_CASE(uchar)
|
|
|
|
case kUChar:
|
|
case kUnsignedChar:
|
|
memcpy( outRaw, inRaw, get_explicit_type_size( inType ) );
|
|
break;
|
|
|
|
DOWN_CAST_CASE(uchar,kChar,char,saturate)
|
|
SIMPLE_CAST_CASE(uchar,kShort,short)
|
|
SIMPLE_CAST_CASE(uchar,kUShort,ushort)
|
|
SIMPLE_CAST_CASE(uchar,kUnsignedShort,ushort)
|
|
SIMPLE_CAST_CASE(uchar,kInt,int)
|
|
SIMPLE_CAST_CASE(uchar,kUInt,uint)
|
|
SIMPLE_CAST_CASE(uchar,kUnsignedInt,uint)
|
|
SIMPLE_CAST_CASE(uchar,kLong,Long)
|
|
SIMPLE_CAST_CASE(uchar,kULong,ULong)
|
|
SIMPLE_CAST_CASE(uchar,kUnsignedLong,ULong)
|
|
|
|
TO_FLOAT_CASE(uchar)
|
|
TO_DOUBLE_CASE(uchar)
|
|
|
|
default:
|
|
log_error( "ERROR: Invalid type given to convert_explicit_value!!\n" );
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case kUnsignedChar:
|
|
ucharPtr = (uchar *)inRaw;
|
|
switch( outType )
|
|
{
|
|
BOOL_CASE(uchar)
|
|
|
|
case kUChar:
|
|
case kUnsignedChar:
|
|
memcpy( outRaw, inRaw, get_explicit_type_size( inType ) );
|
|
break;
|
|
|
|
DOWN_CAST_CASE(uchar,kChar,char,saturate)
|
|
SIMPLE_CAST_CASE(uchar,kShort,short)
|
|
SIMPLE_CAST_CASE(uchar,kUShort,ushort)
|
|
SIMPLE_CAST_CASE(uchar,kUnsignedShort,ushort)
|
|
SIMPLE_CAST_CASE(uchar,kInt,int)
|
|
SIMPLE_CAST_CASE(uchar,kUInt,uint)
|
|
SIMPLE_CAST_CASE(uchar,kUnsignedInt,uint)
|
|
SIMPLE_CAST_CASE(uchar,kLong,Long)
|
|
SIMPLE_CAST_CASE(uchar,kULong,ULong)
|
|
SIMPLE_CAST_CASE(uchar,kUnsignedLong,ULong)
|
|
|
|
TO_FLOAT_CASE(uchar)
|
|
TO_DOUBLE_CASE(uchar)
|
|
|
|
default:
|
|
log_error( "ERROR: Invalid type given to convert_explicit_value!!\n" );
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case kShort:
|
|
shortPtr = (short *)inRaw;
|
|
switch( outType )
|
|
{
|
|
BOOL_CASE(short)
|
|
|
|
case kShort:
|
|
memcpy( outRaw, inRaw, get_explicit_type_size( inType ) );
|
|
break;
|
|
|
|
DOWN_CAST_CASE(short,kChar,char,saturate)
|
|
DOWN_CAST_CASE(short,kUChar,uchar,saturate)
|
|
DOWN_CAST_CASE(short,kUnsignedChar,uchar,saturate)
|
|
DOWN_CAST_CASE(short,kUShort,ushort,saturate)
|
|
DOWN_CAST_CASE(short,kUnsignedShort,ushort,saturate)
|
|
SIMPLE_CAST_CASE(short,kInt,int)
|
|
SIMPLE_CAST_CASE(short,kUInt,uint)
|
|
SIMPLE_CAST_CASE(short,kUnsignedInt,uint)
|
|
SIMPLE_CAST_CASE(short,kLong,Long)
|
|
SIMPLE_CAST_CASE(short,kULong,ULong)
|
|
SIMPLE_CAST_CASE(short,kUnsignedLong,ULong)
|
|
|
|
TO_FLOAT_CASE(short)
|
|
TO_DOUBLE_CASE(short)
|
|
|
|
default:
|
|
log_error( "ERROR: Invalid type given to convert_explicit_value!!\n" );
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case kUShort:
|
|
ushortPtr = (ushort *)inRaw;
|
|
switch( outType )
|
|
{
|
|
BOOL_CASE(ushort)
|
|
|
|
case kUShort:
|
|
case kUnsignedShort:
|
|
memcpy( outRaw, inRaw, get_explicit_type_size( inType ) );
|
|
break;
|
|
|
|
DOWN_CAST_CASE(ushort,kChar,char,saturate)
|
|
DOWN_CAST_CASE(ushort,kUChar,uchar,saturate)
|
|
DOWN_CAST_CASE(ushort,kUnsignedChar,uchar,saturate)
|
|
DOWN_CAST_CASE(ushort,kShort,short,saturate)
|
|
SIMPLE_CAST_CASE(ushort,kInt,int)
|
|
SIMPLE_CAST_CASE(ushort,kUInt,uint)
|
|
SIMPLE_CAST_CASE(ushort,kUnsignedInt,uint)
|
|
SIMPLE_CAST_CASE(ushort,kLong,Long)
|
|
SIMPLE_CAST_CASE(ushort,kULong,ULong)
|
|
SIMPLE_CAST_CASE(ushort,kUnsignedLong,ULong)
|
|
|
|
TO_FLOAT_CASE(ushort)
|
|
TO_DOUBLE_CASE(ushort)
|
|
|
|
default:
|
|
log_error( "ERROR: Invalid type given to convert_explicit_value!!\n" );
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case kUnsignedShort:
|
|
ushortPtr = (ushort *)inRaw;
|
|
switch( outType )
|
|
{
|
|
BOOL_CASE(ushort)
|
|
|
|
case kUShort:
|
|
case kUnsignedShort:
|
|
memcpy( outRaw, inRaw, get_explicit_type_size( inType ) );
|
|
break;
|
|
|
|
DOWN_CAST_CASE(ushort,kChar,char,saturate)
|
|
DOWN_CAST_CASE(ushort,kUChar,uchar,saturate)
|
|
DOWN_CAST_CASE(ushort,kUnsignedChar,uchar,saturate)
|
|
DOWN_CAST_CASE(ushort,kShort,short,saturate)
|
|
SIMPLE_CAST_CASE(ushort,kInt,int)
|
|
SIMPLE_CAST_CASE(ushort,kUInt,uint)
|
|
SIMPLE_CAST_CASE(ushort,kUnsignedInt,uint)
|
|
SIMPLE_CAST_CASE(ushort,kLong,Long)
|
|
SIMPLE_CAST_CASE(ushort,kULong,ULong)
|
|
SIMPLE_CAST_CASE(ushort,kUnsignedLong,ULong)
|
|
|
|
TO_FLOAT_CASE(ushort)
|
|
TO_DOUBLE_CASE(ushort)
|
|
|
|
default:
|
|
log_error( "ERROR: Invalid type given to convert_explicit_value!!\n" );
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case kInt:
|
|
intPtr = (int *)inRaw;
|
|
switch( outType )
|
|
{
|
|
BOOL_CASE(int)
|
|
|
|
case kInt:
|
|
memcpy( outRaw, inRaw, get_explicit_type_size( inType ) );
|
|
break;
|
|
|
|
DOWN_CAST_CASE(int,kChar,char,saturate)
|
|
DOWN_CAST_CASE(int,kUChar,uchar,saturate)
|
|
DOWN_CAST_CASE(int,kUnsignedChar,uchar,saturate)
|
|
DOWN_CAST_CASE(int,kShort,short,saturate)
|
|
DOWN_CAST_CASE(int,kUShort,ushort,saturate)
|
|
DOWN_CAST_CASE(int,kUnsignedShort,ushort,saturate)
|
|
DOWN_CAST_CASE(int,kUInt,uint,saturate)
|
|
DOWN_CAST_CASE(int,kUnsignedInt,uint,saturate)
|
|
SIMPLE_CAST_CASE(int,kLong,Long)
|
|
SIMPLE_CAST_CASE(int,kULong,ULong)
|
|
SIMPLE_CAST_CASE(int,kUnsignedLong,ULong)
|
|
|
|
TO_FLOAT_CASE(int)
|
|
TO_DOUBLE_CASE(int)
|
|
|
|
default:
|
|
log_error( "ERROR: Invalid type given to convert_explicit_value!!\n" );
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case kUInt:
|
|
uintPtr = (uint *)inRaw;
|
|
switch( outType )
|
|
{
|
|
BOOL_CASE(uint)
|
|
|
|
case kUInt:
|
|
case kUnsignedInt:
|
|
memcpy( outRaw, inRaw, get_explicit_type_size( inType ) );
|
|
break;
|
|
|
|
DOWN_CAST_CASE(uint,kChar,char,saturate)
|
|
DOWN_CAST_CASE(uint,kUChar,uchar,saturate)
|
|
DOWN_CAST_CASE(uint,kUnsignedChar,uchar,saturate)
|
|
DOWN_CAST_CASE(uint,kShort,short,saturate)
|
|
DOWN_CAST_CASE(uint,kUShort,ushort,saturate)
|
|
DOWN_CAST_CASE(uint,kUnsignedShort,ushort,saturate)
|
|
DOWN_CAST_CASE(uint,kInt,int,saturate)
|
|
SIMPLE_CAST_CASE(uint,kLong,Long)
|
|
SIMPLE_CAST_CASE(uint,kULong,ULong)
|
|
SIMPLE_CAST_CASE(uint,kUnsignedLong,ULong)
|
|
|
|
TO_FLOAT_CASE(uint)
|
|
TO_DOUBLE_CASE(uint)
|
|
|
|
default:
|
|
log_error( "ERROR: Invalid type given to convert_explicit_value!!\n" );
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case kUnsignedInt:
|
|
uintPtr = (uint *)inRaw;
|
|
switch( outType )
|
|
{
|
|
BOOL_CASE(uint)
|
|
|
|
case kUInt:
|
|
case kUnsignedInt:
|
|
memcpy( outRaw, inRaw, get_explicit_type_size( inType ) );
|
|
break;
|
|
|
|
DOWN_CAST_CASE(uint,kChar,char,saturate)
|
|
DOWN_CAST_CASE(uint,kUChar,uchar,saturate)
|
|
DOWN_CAST_CASE(uint,kUnsignedChar,uchar,saturate)
|
|
DOWN_CAST_CASE(uint,kShort,short,saturate)
|
|
DOWN_CAST_CASE(uint,kUShort,ushort,saturate)
|
|
DOWN_CAST_CASE(uint,kUnsignedShort,ushort,saturate)
|
|
DOWN_CAST_CASE(uint,kInt,int,saturate)
|
|
SIMPLE_CAST_CASE(uint,kLong,Long)
|
|
SIMPLE_CAST_CASE(uint,kULong,ULong)
|
|
SIMPLE_CAST_CASE(uint,kUnsignedLong,ULong)
|
|
|
|
TO_FLOAT_CASE(uint)
|
|
TO_DOUBLE_CASE(uint)
|
|
|
|
default:
|
|
log_error( "ERROR: Invalid type given to convert_explicit_value!!\n" );
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case kLong:
|
|
LongPtr = (Long *)inRaw;
|
|
switch( outType )
|
|
{
|
|
BOOL_CASE(Long)
|
|
|
|
case kLong:
|
|
memcpy( outRaw, inRaw, get_explicit_type_size( inType ) );
|
|
break;
|
|
|
|
DOWN_CAST_CASE(Long,kChar,char,saturate)
|
|
DOWN_CAST_CASE(Long,kUChar,uchar,saturate)
|
|
DOWN_CAST_CASE(Long,kUnsignedChar,uchar,saturate)
|
|
DOWN_CAST_CASE(Long,kShort,short,saturate)
|
|
DOWN_CAST_CASE(Long,kUShort,ushort,saturate)
|
|
DOWN_CAST_CASE(Long,kUnsignedShort,ushort,saturate)
|
|
DOWN_CAST_CASE(Long,kInt,int,saturate)
|
|
DOWN_CAST_CASE(Long,kUInt,uint,saturate)
|
|
DOWN_CAST_CASE(Long,kUnsignedInt,uint,saturate)
|
|
DOWN_CAST_CASE(Long,kULong,ULong,saturate)
|
|
DOWN_CAST_CASE(Long,kUnsignedLong,ULong,saturate)
|
|
|
|
TO_FLOAT_CASE(Long)
|
|
TO_DOUBLE_CASE(Long)
|
|
|
|
default:
|
|
log_error( "ERROR: Invalid type given to convert_explicit_value!!\n" );
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case kULong:
|
|
ULongPtr = (ULong *)inRaw;
|
|
switch( outType )
|
|
{
|
|
BOOL_CASE(ULong)
|
|
|
|
case kUnsignedLong:
|
|
case kULong:
|
|
memcpy( outRaw, inRaw, get_explicit_type_size( inType ) );
|
|
break;
|
|
|
|
U_DOWN_CAST_CASE(ULong,kChar,char,saturate)
|
|
U_DOWN_CAST_CASE(ULong,kUChar,uchar,saturate)
|
|
U_DOWN_CAST_CASE(ULong,kUnsignedChar,uchar,saturate)
|
|
U_DOWN_CAST_CASE(ULong,kShort,short,saturate)
|
|
U_DOWN_CAST_CASE(ULong,kUShort,ushort,saturate)
|
|
U_DOWN_CAST_CASE(ULong,kUnsignedShort,ushort,saturate)
|
|
U_DOWN_CAST_CASE(ULong,kInt,int,saturate)
|
|
U_DOWN_CAST_CASE(ULong,kUInt,uint,saturate)
|
|
U_DOWN_CAST_CASE(ULong,kUnsignedInt,uint,saturate)
|
|
U_DOWN_CAST_CASE(ULong,kLong,Long,saturate)
|
|
|
|
TO_FLOAT_CASE(ULong)
|
|
TO_DOUBLE_CASE(ULong)
|
|
|
|
default:
|
|
log_error( "ERROR: Invalid type given to convert_explicit_value!!\n" );
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case kUnsignedLong:
|
|
ULongPtr = (ULong *)inRaw;
|
|
switch( outType )
|
|
{
|
|
BOOL_CASE(ULong)
|
|
|
|
case kULong:
|
|
case kUnsignedLong:
|
|
memcpy( outRaw, inRaw, get_explicit_type_size( inType ) );
|
|
break;
|
|
|
|
U_DOWN_CAST_CASE(ULong,kChar,char,saturate)
|
|
U_DOWN_CAST_CASE(ULong,kUChar,uchar,saturate)
|
|
U_DOWN_CAST_CASE(ULong,kUnsignedChar,uchar,saturate)
|
|
U_DOWN_CAST_CASE(ULong,kShort,short,saturate)
|
|
U_DOWN_CAST_CASE(ULong,kUShort,ushort,saturate)
|
|
U_DOWN_CAST_CASE(ULong,kUnsignedShort,ushort,saturate)
|
|
U_DOWN_CAST_CASE(ULong,kInt,int,saturate)
|
|
U_DOWN_CAST_CASE(ULong,kUInt,uint,saturate)
|
|
U_DOWN_CAST_CASE(ULong,kUnsignedInt,uint,saturate)
|
|
U_DOWN_CAST_CASE(ULong,kLong,Long,saturate)
|
|
|
|
TO_FLOAT_CASE(ULong)
|
|
TO_DOUBLE_CASE(ULong)
|
|
|
|
default:
|
|
log_error( "ERROR: Invalid type given to convert_explicit_value!!\n" );
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case kFloat:
|
|
floatPtr = (float *)inRaw;
|
|
switch( outType )
|
|
{
|
|
BOOL_CASE(float)
|
|
|
|
FLOAT_ROUND_CASE(kChar,char,roundType,saturate)
|
|
FLOAT_ROUND_CASE(kUChar,uchar,roundType,saturate)
|
|
FLOAT_ROUND_CASE(kUnsignedChar,uchar,roundType,saturate)
|
|
FLOAT_ROUND_CASE(kShort,short,roundType,saturate)
|
|
FLOAT_ROUND_CASE(kUShort,ushort,roundType,saturate)
|
|
FLOAT_ROUND_CASE(kUnsignedShort,ushort,roundType,saturate)
|
|
FLOAT_ROUND_CASE(kInt,int,roundType,saturate)
|
|
FLOAT_ROUND_CASE(kUInt,uint,roundType,saturate)
|
|
FLOAT_ROUND_CASE(kUnsignedInt,uint,roundType,saturate)
|
|
FLOAT_ROUND_CASE(kLong,Long,roundType,saturate)
|
|
FLOAT_ROUND_CASE(kULong,ULong,roundType,saturate)
|
|
FLOAT_ROUND_CASE(kUnsignedLong,ULong,roundType,saturate)
|
|
|
|
case kFloat:
|
|
memcpy( outRaw, inRaw, get_explicit_type_size( inType ) );
|
|
break;
|
|
|
|
TO_DOUBLE_CASE(float);
|
|
|
|
default:
|
|
log_error( "ERROR: Invalid type given to convert_explicit_value!!\n" );
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case kDouble:
|
|
doublePtr = (double *)inRaw;
|
|
switch( outType )
|
|
{
|
|
BOOL_CASE(double)
|
|
|
|
DOUBLE_ROUND_CASE(kChar,char,roundType,saturate)
|
|
DOUBLE_ROUND_CASE(kUChar,uchar,roundType,saturate)
|
|
DOUBLE_ROUND_CASE(kUnsignedChar,uchar,roundType,saturate)
|
|
DOUBLE_ROUND_CASE(kShort,short,roundType,saturate)
|
|
DOUBLE_ROUND_CASE(kUShort,ushort,roundType,saturate)
|
|
DOUBLE_ROUND_CASE(kUnsignedShort,ushort,roundType,saturate)
|
|
DOUBLE_ROUND_CASE(kInt,int,roundType,saturate)
|
|
DOUBLE_ROUND_CASE(kUInt,uint,roundType,saturate)
|
|
DOUBLE_ROUND_CASE(kUnsignedInt,uint,roundType,saturate)
|
|
DOUBLE_ROUND_CASE(kLong,Long,roundType,saturate)
|
|
DOUBLE_ROUND_CASE(kULong,ULong,roundType,saturate)
|
|
DOUBLE_ROUND_CASE(kUnsignedLong,ULong,roundType,saturate)
|
|
|
|
TO_FLOAT_CASE(double);
|
|
|
|
case kDouble:
|
|
memcpy( outRaw, inRaw, get_explicit_type_size( inType ) );
|
|
break;
|
|
|
|
default:
|
|
log_error( "ERROR: Invalid type given to convert_explicit_value!!\n" );
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
log_error( "ERROR: Invalid type given to convert_explicit_value!!\n" );
|
|
break;
|
|
}
|
|
}
|
|
|
|
void generate_random_data( ExplicitType type, size_t count, MTdata d, void *outData )
|
|
{
|
|
bool *boolPtr;
|
|
cl_char *charPtr;
|
|
cl_uchar *ucharPtr;
|
|
cl_short *shortPtr;
|
|
cl_ushort *ushortPtr;
|
|
cl_int *intPtr;
|
|
cl_uint *uintPtr;
|
|
cl_long *longPtr;
|
|
cl_ulong *ulongPtr;
|
|
cl_float *floatPtr;
|
|
cl_double *doublePtr;
|
|
cl_half *halfPtr;
|
|
size_t i;
|
|
cl_uint bits = genrand_int32(d);
|
|
cl_uint bitsLeft = 32;
|
|
|
|
switch( type )
|
|
{
|
|
case kBool:
|
|
boolPtr = (bool *)outData;
|
|
for( i = 0; i < count; i++ )
|
|
{
|
|
if( 0 == bitsLeft)
|
|
{
|
|
bits = genrand_int32(d);
|
|
bitsLeft = 32;
|
|
}
|
|
boolPtr[i] = ( bits & 1 ) ? true : false;
|
|
bits >>= 1; bitsLeft -= 1;
|
|
}
|
|
break;
|
|
|
|
case kChar:
|
|
charPtr = (cl_char *)outData;
|
|
for( i = 0; i < count; i++ )
|
|
{
|
|
if( 0 == bitsLeft)
|
|
{
|
|
bits = genrand_int32(d);
|
|
bitsLeft = 32;
|
|
}
|
|
charPtr[i] = (cl_char)( (cl_int)(bits & 255 ) - 127 );
|
|
bits >>= 8; bitsLeft -= 8;
|
|
}
|
|
break;
|
|
|
|
case kUChar:
|
|
case kUnsignedChar:
|
|
ucharPtr = (cl_uchar *)outData;
|
|
for( i = 0; i < count; i++ )
|
|
{
|
|
if( 0 == bitsLeft)
|
|
{
|
|
bits = genrand_int32(d);
|
|
bitsLeft = 32;
|
|
}
|
|
ucharPtr[i] = (cl_uchar)( bits & 255 );
|
|
bits >>= 8; bitsLeft -= 8;
|
|
}
|
|
break;
|
|
|
|
case kShort:
|
|
shortPtr = (cl_short *)outData;
|
|
for( i = 0; i < count; i++ )
|
|
{
|
|
if( 0 == bitsLeft)
|
|
{
|
|
bits = genrand_int32(d);
|
|
bitsLeft = 32;
|
|
}
|
|
shortPtr[i] = (cl_short)( (cl_int)( bits & 65535 ) - 32767 );
|
|
bits >>= 16; bitsLeft -= 16;
|
|
}
|
|
break;
|
|
|
|
case kUShort:
|
|
case kUnsignedShort:
|
|
ushortPtr = (cl_ushort *)outData;
|
|
for( i = 0; i < count; i++ )
|
|
{
|
|
if( 0 == bitsLeft)
|
|
{
|
|
bits = genrand_int32(d);
|
|
bitsLeft = 32;
|
|
}
|
|
ushortPtr[i] = (cl_ushort)( (cl_int)( bits & 65535 ) );
|
|
bits >>= 16; bitsLeft -= 16;
|
|
}
|
|
break;
|
|
|
|
case kInt:
|
|
intPtr = (cl_int *)outData;
|
|
for( i = 0; i < count; i++ )
|
|
{
|
|
intPtr[i] = (cl_int)genrand_int32(d);
|
|
}
|
|
break;
|
|
|
|
case kUInt:
|
|
case kUnsignedInt:
|
|
uintPtr = (cl_uint *)outData;
|
|
for( i = 0; i < count; i++ )
|
|
{
|
|
uintPtr[i] = (unsigned int)genrand_int32(d);
|
|
}
|
|
break;
|
|
|
|
case kLong:
|
|
longPtr = (cl_long *)outData;
|
|
for( i = 0; i < count; i++ )
|
|
{
|
|
longPtr[i] = (cl_long)genrand_int32(d) | ( (cl_long)genrand_int32(d) << 32 );
|
|
}
|
|
break;
|
|
|
|
case kULong:
|
|
case kUnsignedLong:
|
|
ulongPtr = (cl_ulong *)outData;
|
|
for( i = 0; i < count; i++ )
|
|
{
|
|
ulongPtr[i] = (cl_ulong)genrand_int32(d) | ( (cl_ulong)genrand_int32(d) << 32 );
|
|
}
|
|
break;
|
|
|
|
case kFloat:
|
|
floatPtr = (cl_float *)outData;
|
|
for( i = 0; i < count; i++ )
|
|
{
|
|
// [ -(double) 0x7fffffff, (double) 0x7fffffff ]
|
|
double t = genrand_real1(d);
|
|
floatPtr[i] = (float) ((1.0 - t) * -(double) 0x7fffffff + t * (double) 0x7fffffff);
|
|
}
|
|
break;
|
|
|
|
case kDouble:
|
|
doublePtr = (cl_double *)outData;
|
|
for( i = 0; i < count; i++ )
|
|
{
|
|
cl_long u = (cl_long)genrand_int32(d) | ( (cl_long)genrand_int32(d) << 32 );
|
|
double t = (double) u;
|
|
t *= MAKE_HEX_DOUBLE( 0x1.0p-32, 0x1, -32 ); // scale [-2**63, 2**63] to [-2**31, 2**31]
|
|
doublePtr[i] = t;
|
|
}
|
|
break;
|
|
|
|
case kHalf:
|
|
halfPtr = (ushort *)outData;
|
|
for( i = 0; i < count; i++ )
|
|
{
|
|
if( 0 == bitsLeft)
|
|
{
|
|
bits = genrand_int32(d);
|
|
bitsLeft = 32;
|
|
}
|
|
halfPtr[i] = bits & 65535; /* Kindly generates random bits for us */
|
|
bits >>= 16; bitsLeft -= 16;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
log_error( "ERROR: Invalid type passed in to generate_random_data!\n" );
|
|
break;
|
|
}
|
|
}
|
|
|
|
void * create_random_data( ExplicitType type, MTdata d, size_t count )
|
|
{
|
|
void *data = malloc( get_explicit_type_size( type ) * count );
|
|
generate_random_data( type, count, d, data );
|
|
return data;
|
|
}
|
|
|
|
cl_long read_upscale_signed( void *inRaw, ExplicitType inType )
|
|
{
|
|
switch( inType )
|
|
{
|
|
case kChar:
|
|
return (cl_long)( *( (cl_char *)inRaw ) );
|
|
case kUChar:
|
|
case kUnsignedChar:
|
|
return (cl_long)( *( (cl_uchar *)inRaw ) );
|
|
case kShort:
|
|
return (cl_long)( *( (cl_short *)inRaw ) );
|
|
case kUShort:
|
|
case kUnsignedShort:
|
|
return (cl_long)( *( (cl_ushort *)inRaw ) );
|
|
case kInt:
|
|
return (cl_long)( *( (cl_int *)inRaw ) );
|
|
case kUInt:
|
|
case kUnsignedInt:
|
|
return (cl_long)( *( (cl_uint *)inRaw ) );
|
|
case kLong:
|
|
return (cl_long)( *( (cl_long *)inRaw ) );
|
|
case kULong:
|
|
case kUnsignedLong:
|
|
return (cl_long)( *( (cl_ulong *)inRaw ) );
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
cl_ulong read_upscale_unsigned( void *inRaw, ExplicitType inType )
|
|
{
|
|
switch( inType )
|
|
{
|
|
case kChar:
|
|
return (cl_ulong)( *( (cl_char *)inRaw ) );
|
|
case kUChar:
|
|
case kUnsignedChar:
|
|
return (cl_ulong)( *( (cl_uchar *)inRaw ) );
|
|
case kShort:
|
|
return (cl_ulong)( *( (cl_short *)inRaw ) );
|
|
case kUShort:
|
|
case kUnsignedShort:
|
|
return (cl_ulong)( *( (cl_ushort *)inRaw ) );
|
|
case kInt:
|
|
return (cl_ulong)( *( (cl_int *)inRaw ) );
|
|
case kUInt:
|
|
case kUnsignedInt:
|
|
return (cl_ulong)( *( (cl_uint *)inRaw ) );
|
|
case kLong:
|
|
return (cl_ulong)( *( (cl_long *)inRaw ) );
|
|
case kULong:
|
|
case kUnsignedLong:
|
|
return (cl_ulong)( *( (cl_ulong *)inRaw ) );
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
float read_as_float( void *inRaw, ExplicitType inType )
|
|
{
|
|
switch( inType )
|
|
{
|
|
case kChar:
|
|
return (float)( *( (cl_char *)inRaw ) );
|
|
case kUChar:
|
|
case kUnsignedChar:
|
|
return (float)( *( (cl_char *)inRaw ) );
|
|
case kShort:
|
|
return (float)( *( (cl_short *)inRaw ) );
|
|
case kUShort:
|
|
case kUnsignedShort:
|
|
return (float)( *( (cl_ushort *)inRaw ) );
|
|
case kInt:
|
|
return (float)( *( (cl_int *)inRaw ) );
|
|
case kUInt:
|
|
case kUnsignedInt:
|
|
return (float)( *( (cl_uint *)inRaw ) );
|
|
case kLong:
|
|
return (float)( *( (cl_long *)inRaw ) );
|
|
case kULong:
|
|
case kUnsignedLong:
|
|
return (float)( *( (cl_ulong *)inRaw ) );
|
|
case kFloat:
|
|
return *( (float *)inRaw );
|
|
case kDouble:
|
|
return (float) *( (double*)inRaw );
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
float get_random_float(float low, float high, MTdata d)
|
|
{
|
|
float t = (float)((double)genrand_int32(d) / (double)0xFFFFFFFF);
|
|
return (1.0f - t) * low + t * high;
|
|
}
|
|
|
|
double get_random_double(double low, double high, MTdata d)
|
|
{
|
|
cl_ulong u = (cl_ulong) genrand_int32(d) | ((cl_ulong) genrand_int32(d) << 32 );
|
|
double t = (double) u * MAKE_HEX_DOUBLE( 0x1.0p-64, 0x1, -64);
|
|
return (1.0f - t) * low + t * high;
|
|
}
|
|
|
|
float any_float( MTdata d )
|
|
{
|
|
union
|
|
{
|
|
float f;
|
|
cl_uint u;
|
|
}u;
|
|
|
|
u.u = genrand_int32(d);
|
|
return u.f;
|
|
}
|
|
|
|
|
|
double any_double( MTdata d )
|
|
{
|
|
union
|
|
{
|
|
double f;
|
|
cl_ulong u;
|
|
}u;
|
|
|
|
u.u = (cl_ulong) genrand_int32(d) | ((cl_ulong) genrand_int32(d) << 32);
|
|
return u.f;
|
|
}
|
|
|
|
int random_in_range( int minV, int maxV, MTdata d )
|
|
{
|
|
cl_ulong r = ((cl_ulong) genrand_int32(d) ) * (maxV - minV + 1);
|
|
return (cl_uint)(r >> 32) + minV;
|
|
}
|
|
|
|
size_t get_random_size_t(size_t low, size_t high, MTdata d)
|
|
{
|
|
enum { N = sizeof(size_t)/sizeof(int) };
|
|
|
|
union {
|
|
int word[N];
|
|
size_t size;
|
|
} u;
|
|
|
|
for (unsigned i=0; i != N; ++i) {
|
|
u.word[i] = genrand_int32(d);
|
|
}
|
|
|
|
assert(low <= high && "Invalid random number range specified");
|
|
size_t range = high - low;
|
|
|
|
return (range) ? low + ((u.size - low) % range) : low;
|
|
}
|
|
|
|
|