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:
Kévin Petit
2020-08-14 13:50:14 +01:00
committed by GitHub
parent 655d83db80
commit ed50fcad2d
15 changed files with 64 additions and 941 deletions

View File

@@ -16,10 +16,13 @@
#include "utils.h"
#include "harness/errorHelpers.h"
#include "harness/imageHelpers.h"
#include "harness/rounding_mode.h"
#include <math.h>
#include <CL/cl_half.h>
static RoundingMode gFloatToHalfRoundingMode = kDefaultRoundingMode;
@@ -772,14 +775,18 @@ bool DataCompare( TSurfaceFormat surfaceFormat, cl_channel_type type, const std:
{
for(unsigned planeIdx = 0; planeIdx < channelNum; ++planeIdx)
{
float test = convert_half_to_float(dataTest.at(offset + j * channelNum + planeIdx));
float ref = convert_half_to_float(dataExp.at(offset + j * channelNum + planeIdx));
if (abs(test - ref) > epsilon)
{
log_error("Tested image is different than reference (x,y,plane) = (%i,%i,%i), test value = %f, expected value = %f\n",
j, i, planeIdx, test, ref);
return false;
}
float test = cl_half_to_float(
dataTest.at(offset + j * channelNum + planeIdx));
float ref = cl_half_to_float(
dataExp.at(offset + j * channelNum + planeIdx));
if (abs(test - ref) > epsilon)
{
log_error(
"Tested image is different than reference (x,y,plane) = "
"(%i,%i,%i), test value = %f, expected value = %f\n",
j, i, planeIdx, test, ref);
return false;
}
}
}
}
@@ -1554,90 +1561,6 @@ bool MediaSurfaceCreate(cl_dx9_media_adapter_type_khr adapterType, unsigned int
return true;
}
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;
}
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;
}
cl_int deviceExistForCLTest(cl_platform_id platform,
cl_dx9_media_adapter_type_khr media_adapters_type,
void *media_adapters,