mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 06:09:01 +00:00
The maintenance of the conformance tests is moving to Github. This commit contains all the changes that have been done in Gitlab since the first public release of the conformance tests. Signed-off-by: Kevin Petit <kevin.petit@arm.com>
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,
|
|
0xffffffff80000000LL, 0, 0,
|
|
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_ushort *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;
|
|
}
|
|
|
|
|