mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 06:09:01 +00:00
Use float<->half conversion routines from the OpenCL headers (#884)
* Use float<->half conversion routines from the OpenCL headers Fixes #870 Signed-off-by: Kevin Petit <kevin.petit@arm.com> * Use cl_half_from_double * Fix windows build errors * Fix more build errors * Code formatting * Remove TEST class
This commit is contained in:
@@ -20,44 +20,7 @@
|
||||
#include "cl_utils.h"
|
||||
#include "tests.h"
|
||||
|
||||
static inline float half2float( cl_ushort us )
|
||||
{
|
||||
uint32_t u = us;
|
||||
uint32_t sign = (u << 16) & 0x80000000;
|
||||
int32_t exponent = (u & 0x7c00) >> 10;
|
||||
uint32_t mantissa = (u & 0x03ff) << 13;
|
||||
union{ unsigned int u; float f;}uu;
|
||||
|
||||
if( exponent == 0 )
|
||||
{
|
||||
if( mantissa == 0 )
|
||||
return sign ? -0.0f : 0.0f;
|
||||
|
||||
int shift = __builtin_clz( mantissa ) - 8;
|
||||
exponent -= shift-1;
|
||||
mantissa <<= shift;
|
||||
mantissa &= 0x007fffff;
|
||||
}
|
||||
else
|
||||
if( exponent == 31)
|
||||
{
|
||||
uu.u = mantissa | sign;
|
||||
if( mantissa )
|
||||
uu.u |= 0x7fc00000;
|
||||
else
|
||||
uu.u |= 0x7f800000;
|
||||
|
||||
return uu.f;
|
||||
}
|
||||
|
||||
exponent += 127 - 15;
|
||||
exponent <<= 23;
|
||||
|
||||
exponent |= mantissa;
|
||||
uu.u = exponent | sign;
|
||||
|
||||
return uu.f;
|
||||
}
|
||||
#include <CL/cl_half.h>
|
||||
|
||||
int Test_vLoadHalf_private( cl_device_id device, bool aligned )
|
||||
{
|
||||
@@ -482,8 +445,7 @@ int Test_vLoadHalf_private( cl_device_id device, bool aligned )
|
||||
//create the reference result
|
||||
const unsigned short *s = (const unsigned short *)gIn_half;
|
||||
float *d = (float *)gOut_single_reference;
|
||||
for( j = 0; j < count; j++ )
|
||||
d[j] = half2float( s[j] );
|
||||
for (j = 0; j < count; j++) d[j] = cl_half_to_float(s[j]);
|
||||
|
||||
//Check the vector lengths
|
||||
for( vectorSize = minVectorSize; vectorSize < kLastVectorSizeToTest; vectorSize++)
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "cl_utils.h"
|
||||
#include "tests.h"
|
||||
|
||||
#include <CL/cl_half.h>
|
||||
|
||||
typedef struct ComputeReferenceInfoF_
|
||||
{
|
||||
float *x;
|
||||
@@ -208,406 +210,44 @@ CheckD(cl_uint jid, cl_uint tid, void *userInfo)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static cl_ushort float2half_rte( float f );
|
||||
static cl_ushort float2half_rtz( float f );
|
||||
static cl_ushort float2half_rtp( float f );
|
||||
static cl_ushort float2half_rtn( float f );
|
||||
static cl_ushort double2half_rte( double f );
|
||||
static cl_ushort double2half_rtz( double f );
|
||||
static cl_ushort double2half_rtp( double f );
|
||||
static cl_ushort double2half_rtn( double f );
|
||||
|
||||
static cl_ushort
|
||||
float2half_rte( float f )
|
||||
static cl_ushort float2half_rte(float f)
|
||||
{
|
||||
union{ float f; cl_uint u; } u = {f};
|
||||
cl_uint sign = (u.u >> 16) & 0x8000;
|
||||
float x = fabsf(f);
|
||||
|
||||
//Nan
|
||||
if( x != x )
|
||||
{
|
||||
u.u >>= (24-11);
|
||||
u.u &= 0x7fff;
|
||||
u.u |= 0x0200; //silence the NaN
|
||||
return u.u | sign;
|
||||
}
|
||||
|
||||
// overflow
|
||||
if( x >= MAKE_HEX_FLOAT(0x1.ffep15f, 0x1ffeL, 3) )
|
||||
return 0x7c00 | sign;
|
||||
|
||||
// underflow
|
||||
if( x <= MAKE_HEX_FLOAT(0x1.0p-25f, 0x1L, -25) )
|
||||
return sign; // The halfway case can return 0x0001 or 0. 0 is even.
|
||||
|
||||
// very small
|
||||
if( x < MAKE_HEX_FLOAT(0x1.8p-24f, 0x18L, -28) )
|
||||
return sign | 1;
|
||||
|
||||
// half denormal
|
||||
if( x < MAKE_HEX_FLOAT(0x1.0p-14f, 0x1L, -14) )
|
||||
{
|
||||
u.f = x * MAKE_HEX_FLOAT(0x1.0p-125f, 0x1L, -125);
|
||||
return sign | u.u;
|
||||
}
|
||||
|
||||
u.f *= MAKE_HEX_FLOAT(0x1.0p13f, 0x1L, 13);
|
||||
u.u &= 0x7f800000;
|
||||
x += u.f;
|
||||
u.f = x - u.f;
|
||||
u.f *= MAKE_HEX_FLOAT(0x1.0p-112f, 0x1L, -112);
|
||||
|
||||
return (u.u >> (24-11)) | sign;
|
||||
return cl_half_from_float(f, CL_HALF_RTE);
|
||||
}
|
||||
|
||||
static cl_ushort
|
||||
float2half_rtz( float f )
|
||||
static cl_ushort float2half_rtz(float f)
|
||||
{
|
||||
union{ float f; cl_uint u; } u = {f};
|
||||
cl_uint sign = (u.u >> 16) & 0x8000;
|
||||
float x = fabsf(f);
|
||||
|
||||
//Nan
|
||||
if( x != x )
|
||||
{
|
||||
u.u >>= (24-11);
|
||||
u.u &= 0x7fff;
|
||||
u.u |= 0x0200; //silence the NaN
|
||||
return u.u | sign;
|
||||
}
|
||||
|
||||
// overflow
|
||||
if( x >= MAKE_HEX_FLOAT(0x1.0p16f, 0x1L, 16) )
|
||||
{
|
||||
if( x == INFINITY )
|
||||
return 0x7c00 | sign;
|
||||
|
||||
return 0x7bff | sign;
|
||||
}
|
||||
|
||||
// underflow
|
||||
if( x < MAKE_HEX_FLOAT(0x1.0p-24f, 0x1L, -24) )
|
||||
return sign; // The halfway case can return 0x0001 or 0. 0 is even.
|
||||
|
||||
// half denormal
|
||||
if( x < MAKE_HEX_FLOAT(0x1.0p-14f, 0x1L, -14) )
|
||||
{
|
||||
x *= MAKE_HEX_FLOAT(0x1.0p24f, 0x1L, 24);
|
||||
return (cl_ushort)((int) x | sign);
|
||||
}
|
||||
|
||||
u.u &= 0xFFFFE000U;
|
||||
u.u -= 0x38000000U;
|
||||
|
||||
return (u.u >> (24-11)) | sign;
|
||||
return cl_half_from_float(f, CL_HALF_RTZ);
|
||||
}
|
||||
|
||||
static cl_ushort
|
||||
float2half_rtp( float f )
|
||||
static cl_ushort float2half_rtp(float f)
|
||||
{
|
||||
union{ float f; cl_uint u; } u = {f};
|
||||
cl_uint sign = (u.u >> 16) & 0x8000;
|
||||
float x = fabsf(f);
|
||||
|
||||
//Nan
|
||||
if( x != x )
|
||||
{
|
||||
u.u >>= (24-11);
|
||||
u.u &= 0x7fff;
|
||||
u.u |= 0x0200; //silence the NaN
|
||||
return u.u | sign;
|
||||
}
|
||||
|
||||
// overflow
|
||||
if( f > MAKE_HEX_FLOAT(0x1.ffcp15f, 0x1ffcL, 3) )
|
||||
return 0x7c00;
|
||||
|
||||
if( f <= MAKE_HEX_FLOAT(-0x1.0p16f, -0x1L, 16) )
|
||||
{
|
||||
if( f == -INFINITY )
|
||||
return 0xfc00;
|
||||
|
||||
return 0xfbff;
|
||||
}
|
||||
|
||||
// underflow
|
||||
if( x < MAKE_HEX_FLOAT(0x1.0p-24f, 0x1L, -24) )
|
||||
{
|
||||
if( f > 0 )
|
||||
return 1;
|
||||
return sign;
|
||||
}
|
||||
|
||||
// half denormal
|
||||
if( x < MAKE_HEX_FLOAT(0x1.0p-14f, 0x1L, -14) )
|
||||
{
|
||||
x *= MAKE_HEX_FLOAT(0x1.0p24f, 0x1L, 24);
|
||||
int r = (int) x;
|
||||
r += (float) r != x && f > 0.0f;
|
||||
|
||||
return (cl_ushort)( r | sign);
|
||||
}
|
||||
|
||||
float g = u.f;
|
||||
u.u &= 0xFFFFE000U;
|
||||
if( g > u.f )
|
||||
u.u += 0x00002000U;
|
||||
u.u -= 0x38000000U;
|
||||
|
||||
return (u.u >> (24-11)) | sign;
|
||||
return cl_half_from_float(f, CL_HALF_RTP);
|
||||
}
|
||||
|
||||
|
||||
static cl_ushort
|
||||
float2half_rtn( float f )
|
||||
static cl_ushort float2half_rtn(float f)
|
||||
{
|
||||
union{ float f; cl_uint u; } u = {f};
|
||||
cl_uint sign = (u.u >> 16) & 0x8000;
|
||||
float x = fabsf(f);
|
||||
|
||||
//Nan
|
||||
if( x != x )
|
||||
{
|
||||
u.u >>= (24-11);
|
||||
u.u &= 0x7fff;
|
||||
u.u |= 0x0200; //silence the NaN
|
||||
return u.u | sign;
|
||||
}
|
||||
|
||||
// overflow
|
||||
if( f >= MAKE_HEX_FLOAT(0x1.0p16f, 0x1L, 16) )
|
||||
{
|
||||
if( f == INFINITY )
|
||||
return 0x7c00;
|
||||
|
||||
return 0x7bff;
|
||||
}
|
||||
|
||||
if( f < MAKE_HEX_FLOAT(-0x1.ffcp15f, -0x1ffcL, 3) )
|
||||
return 0xfc00;
|
||||
|
||||
// underflow
|
||||
if( x < MAKE_HEX_FLOAT(0x1.0p-24f, 0x1L, -24) )
|
||||
{
|
||||
if( f < 0 )
|
||||
return 0x8001;
|
||||
return sign;
|
||||
}
|
||||
|
||||
// half denormal
|
||||
if( x < MAKE_HEX_FLOAT(0x1.0p-14f, 0x1L, -14) )
|
||||
{
|
||||
x *= MAKE_HEX_FLOAT(0x1.0p24f, 0x1L, 24);
|
||||
int r = (int) x;
|
||||
r += (float) r != x && f < 0.0f;
|
||||
|
||||
return (cl_ushort)( r | sign);
|
||||
}
|
||||
|
||||
u.u &= 0xFFFFE000U;
|
||||
if( u.f > f )
|
||||
u.u += 0x00002000U;
|
||||
u.u -= 0x38000000U;
|
||||
|
||||
return (u.u >> (24-11)) | sign;
|
||||
return cl_half_from_float(f, CL_HALF_RTN);
|
||||
}
|
||||
|
||||
static cl_ushort
|
||||
double2half_rte( double f )
|
||||
static cl_ushort double2half_rte(double f)
|
||||
{
|
||||
union{ double f; cl_ulong u; } u = {f};
|
||||
cl_ulong sign = (u.u >> 48) & 0x8000;
|
||||
double x = fabs(f);
|
||||
|
||||
//Nan
|
||||
if( x != x )
|
||||
{
|
||||
u.u >>= (53-11);
|
||||
u.u &= 0x7fff;
|
||||
u.u |= 0x0200; //silence the NaN
|
||||
return u.u | sign;
|
||||
}
|
||||
|
||||
// overflow
|
||||
if( x >= MAKE_HEX_DOUBLE(0x1.ffep15, 0x1ffeLL, 3) )
|
||||
return 0x7c00 | sign;
|
||||
|
||||
// underflow
|
||||
if( x <= MAKE_HEX_DOUBLE(0x1.0p-25, 0x1LL, -25) )
|
||||
return sign; // The halfway case can return 0x0001 or 0. 0 is even.
|
||||
|
||||
// very small
|
||||
if( x < MAKE_HEX_DOUBLE(0x1.8p-24, 0x18LL, -28) )
|
||||
return sign | 1;
|
||||
|
||||
// half denormal
|
||||
if( x < MAKE_HEX_DOUBLE(0x1.0p-14, 0x1LL, -14) )
|
||||
{
|
||||
u.f = x * MAKE_HEX_DOUBLE(0x1.0p-1050, 0x1LL, -1050);
|
||||
return sign | u.u;
|
||||
}
|
||||
|
||||
u.f *= MAKE_HEX_DOUBLE(0x1.0p42, 0x1LL, 42);
|
||||
u.u &= 0x7ff0000000000000ULL;
|
||||
x += u.f;
|
||||
u.f = x - u.f;
|
||||
u.f *= MAKE_HEX_DOUBLE(0x1.0p-1008, 0x1LL, -1008);
|
||||
|
||||
return (u.u >> (53-11)) | sign;
|
||||
return cl_half_from_double(f, CL_HALF_RTE);
|
||||
}
|
||||
|
||||
static cl_ushort
|
||||
double2half_rtz( double f )
|
||||
static cl_ushort double2half_rtz(double f)
|
||||
{
|
||||
union{ double f; cl_ulong u; } u = {f};
|
||||
cl_ulong sign = (u.u >> 48) & 0x8000;
|
||||
double x = fabs(f);
|
||||
|
||||
//Nan
|
||||
if( x != x )
|
||||
{
|
||||
u.u >>= (53-11);
|
||||
u.u &= 0x7fff;
|
||||
u.u |= 0x0200; //silence the NaN
|
||||
return u.u | sign;
|
||||
}
|
||||
|
||||
if( x == INFINITY )
|
||||
return 0x7c00 | sign;
|
||||
|
||||
// overflow
|
||||
if( x >= MAKE_HEX_DOUBLE(0x1.0p16, 0x1LL, 16) )
|
||||
return 0x7bff | sign;
|
||||
|
||||
// underflow
|
||||
if( x < MAKE_HEX_DOUBLE(0x1.0p-24, 0x1LL, -24) )
|
||||
return sign; // The halfway case can return 0x0001 or 0. 0 is even.
|
||||
|
||||
// half denormal
|
||||
if( x < MAKE_HEX_DOUBLE(0x1.0p-14, 0x1LL, -14) )
|
||||
{
|
||||
x *= MAKE_HEX_FLOAT(0x1.0p24f, 0x1L, 24);
|
||||
return (cl_ushort)((int) x | sign);
|
||||
}
|
||||
|
||||
u.u &= 0xFFFFFC0000000000ULL;
|
||||
u.u -= 0x3F00000000000000ULL;
|
||||
|
||||
return (u.u >> (53-11)) | sign;
|
||||
return cl_half_from_double(f, CL_HALF_RTZ);
|
||||
}
|
||||
|
||||
static cl_ushort
|
||||
double2half_rtp( double f )
|
||||
static cl_ushort double2half_rtp(double f)
|
||||
{
|
||||
union{ double f; cl_ulong u; } u = {f};
|
||||
cl_ulong sign = (u.u >> 48) & 0x8000;
|
||||
double x = fabs(f);
|
||||
|
||||
//Nan
|
||||
if( x != x )
|
||||
{
|
||||
u.u >>= (53-11);
|
||||
u.u &= 0x7fff;
|
||||
u.u |= 0x0200; //silence the NaN
|
||||
return u.u | sign;
|
||||
}
|
||||
|
||||
// overflow
|
||||
if( f > MAKE_HEX_DOUBLE(0x1.ffcp15, 0x1ffcLL, 3) )
|
||||
return 0x7c00;
|
||||
|
||||
if( f <= MAKE_HEX_DOUBLE(-0x1.0p16, -0x1LL, 16) )
|
||||
{
|
||||
if( f == -INFINITY )
|
||||
return 0xfc00;
|
||||
|
||||
return 0xfbff;
|
||||
}
|
||||
|
||||
// underflow
|
||||
if( x < MAKE_HEX_DOUBLE(0x1.0p-24, 0x1LL, -24) )
|
||||
{
|
||||
if( f > 0 )
|
||||
return 1;
|
||||
return sign;
|
||||
}
|
||||
|
||||
// half denormal
|
||||
if( x < MAKE_HEX_DOUBLE(0x1.0p-14, 0x1LL, -14) )
|
||||
{
|
||||
x *= MAKE_HEX_FLOAT(0x1.0p24f, 0x1L, 24);
|
||||
int r = (int) x;
|
||||
if( 0 == sign )
|
||||
r += (double) r != x;
|
||||
|
||||
return (cl_ushort)( r | sign);
|
||||
}
|
||||
|
||||
double g = u.f;
|
||||
u.u &= 0xFFFFFC0000000000ULL;
|
||||
if( g != u.f && 0 == sign)
|
||||
u.u += 0x0000040000000000ULL;
|
||||
u.u -= 0x3F00000000000000ULL;
|
||||
|
||||
return (u.u >> (53-11)) | sign;
|
||||
return cl_half_from_double(f, CL_HALF_RTP);
|
||||
}
|
||||
|
||||
|
||||
static cl_ushort
|
||||
double2half_rtn( double f )
|
||||
static cl_ushort double2half_rtn(double f)
|
||||
{
|
||||
union{ double f; cl_ulong u; } u = {f};
|
||||
cl_ulong sign = (u.u >> 48) & 0x8000;
|
||||
double x = fabs(f);
|
||||
|
||||
//Nan
|
||||
if( x != x )
|
||||
{
|
||||
u.u >>= (53-11);
|
||||
u.u &= 0x7fff;
|
||||
u.u |= 0x0200; //silence the NaN
|
||||
return u.u | sign;
|
||||
}
|
||||
|
||||
// overflow
|
||||
if( f >= MAKE_HEX_DOUBLE(0x1.0p16, 0x1LL, 16) )
|
||||
{
|
||||
if( f == INFINITY )
|
||||
return 0x7c00;
|
||||
|
||||
return 0x7bff;
|
||||
}
|
||||
|
||||
if( f < MAKE_HEX_DOUBLE(-0x1.ffcp15, -0x1ffcLL, 3) )
|
||||
return 0xfc00;
|
||||
|
||||
// underflow
|
||||
if( x < MAKE_HEX_DOUBLE(0x1.0p-24, 0x1LL, -24) )
|
||||
{
|
||||
if( f < 0 )
|
||||
return 0x8001;
|
||||
return sign;
|
||||
}
|
||||
|
||||
// half denormal
|
||||
if( x < MAKE_HEX_DOUBLE(0x1.0p-14, 0x1LL, -14) )
|
||||
{
|
||||
x *= MAKE_HEX_DOUBLE(0x1.0p24, 0x1LL, 24);
|
||||
int r = (int) x;
|
||||
if( sign )
|
||||
r += (double) r != x;
|
||||
|
||||
return (cl_ushort)( r | sign);
|
||||
}
|
||||
|
||||
double g = u.f;
|
||||
u.u &= 0xFFFFFC0000000000ULL;
|
||||
if( g < u.f && sign)
|
||||
u.u += 0x0000040000000000ULL;
|
||||
u.u -= 0x3F00000000000000ULL;
|
||||
|
||||
return (u.u >> (53-11)) | sign;
|
||||
return cl_half_from_double(f, CL_HALF_RTN);
|
||||
}
|
||||
|
||||
int test_vstore_half( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements )
|
||||
|
||||
Reference in New Issue
Block a user