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

@@ -23,6 +23,7 @@
#include "../funcs_test_utils.hpp"
#include "half_utils.hpp"
#include <CL/cl_half.h>
// Generates cl_half input
std::vector<cl_half> generate_half_input(size_t count,
@@ -36,7 +37,7 @@ std::vector<cl_half> generate_half_input(size_t count,
std::uniform_real_distribution<cl_float> dis(min, max);
for(auto& i : input)
{
i = float2half_rte(dis(gen));
i = cl_half_from_float(dis(gen), CL_HALF_RTE);
}
input.insert(input.begin(), special_cases.begin(), special_cases.end());

View File

@@ -51,86 +51,4 @@ inline int clz(INT_TYPE x)
} // namespace detail
inline cl_float half2float(cl_half us)
{
uint32_t u = us;
uint32_t sign = (u << 16) & 0x80000000;
int32_t exponent = (u & 0x7c00) >> 10;
uint32_t mantissa = (u & 0x03ff) << 13;
union{ cl_uint u; cl_float f;}uu;
if( exponent == 0 )
{
if( mantissa == 0 )
return sign ? -0.0f : 0.0f;
int shift = detail::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;
}
inline cl_ushort float2half_rte(cl_float f)
{
union{ cl_float f; cl_uint u; } u = {f};
cl_uint sign = (u.u >> 16) & 0x8000;
cl_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;
}
#endif // TEST_CONFORMANCE_CLCPP_HALF_UTILS_HPP

View File

@@ -23,6 +23,8 @@
#include "common.hpp"
#include <CL/cl_half.h>
// -----------------------------------------------------------------------------------
// ------------- ONLY FOR OPENCL 22 CONFORMANCE TEST 22 DEVELOPMENT ------------------
// -----------------------------------------------------------------------------------
@@ -263,7 +265,7 @@ struct vload_half_func : public unary_func<
Iterator temp = x + static_cast<diff_type>(offset * N);
for(size_t i = 0; i < N; i++)
{
r.s[i] = half2float(*temp);
r.s[i] = cl_half_to_float(*temp);
temp++;
}
return r;
@@ -309,7 +311,7 @@ struct vloada_half_func : public unary_func<
Iterator temp = x + static_cast<diff_type>(offset * alignment);
for(size_t i = 0; i < N; i++)
{
r.s[i] = half2float(*temp);
r.s[i] = cl_half_to_float(*temp);
temp++;
}
return r;

View File

@@ -16,9 +16,6 @@
#ifndef TEST_CONFORMANCE_CLCPP_VLOAD_VSTORE_FUNCS_VSTORE_FUNCS_HPP
#define TEST_CONFORMANCE_CLCPP_VLOAD_VSTORE_FUNCS_VSTORE_FUNCS_HPP
#include "../common.hpp"
#include "../funcs_test_utils.hpp"
#include <iterator>
#include "../common.hpp"
@@ -26,6 +23,8 @@
#include "common.hpp"
#include <CL/cl_half.h>
// -----------------------------------------------------------------------------------
// ------------- ONLY FOR OPENCL 22 CONFORMANCE TEST 22 DEVELOPMENT ------------------
// -----------------------------------------------------------------------------------
@@ -240,7 +239,7 @@ struct vstore_half_func : public unary_func<
result_type r;
for(size_t i = 0; i < N; i++)
{
r.s[i] = float2half_rte(in.s[i]);
r.s[i] = cl_half_from_float(in.s[i], CL_HALF_RTE);
}
return r;
}
@@ -287,7 +286,7 @@ struct vstorea_half_func : public unary_func<
result_type r;
for(size_t i = 0; i < N; i++)
{
r.s[i] = float2half_rte(in.s[i]);
r.s[i] = cl_half_from_float(in.s[i], CL_HALF_RTE);
}
return r;
}