On Sat, 2016-08-06 at 14:47 -0400, Jan Vesely wrote: > Use explicit conversion from regexp matched array values > > v2: distance between two half numbers is 8192 single float ulps > no need to place converted float in the middle of single > precision range > > Signed-off-by: Jan Vesely <jan.ves...@rutgers.edu> > --- > tests/cl/program/program-tester.c | 31 ++++++++++++++++++++++++++--- > - > tests/util/piglit-util-cl.c | 40 > +++++++++++++++++++++++++++++++++++++++ > tests/util/piglit-util-cl.h | 25 ++++++++++++++++++++++++ > 3 files changed, 92 insertions(+), 4 deletions(-) > > diff --git a/tests/cl/program/program-tester.c > b/tests/cl/program/program-tester.c > index 8e3cb4d..25b677f 100644 > --- a/tests/cl/program/program-tester.c > +++ b/tests/cl/program/program-tester.c > @@ -111,12 +111,14 @@ > // TODO: probably we could use libmpdec to handle this > // http://www.bytereef.org/mpdecimal/index.html > //#define REGEX_TYPE_HALF "buffer half[1]" > +#define REGEX_TYPE_HALF REGEX_DEFINE_TYPE("half") > #define REGEX_TYPE_FLOAT REGEX_DEFINE_TYPE("float") > #define REGEX_TYPE_DOUBLE REGEX_DEFINE_TYPE("double") > #define REGEX_TYPE REGEX_TYPE_CHAR "|" REGEX_TYPE_UCHAR "|" \ > REGEX_TYPE_SHORT "|" REGEX_TYPE_USHORT "|" \ > - REGEX_TYPE_INT "|" REGEX_TYPE_UINT "|" > REGEX_TYPE_LONG "|" \ > - REGEX_TYPE_ULONG "|" REGEX_TYPE_FLOAT "|" > REGEX_TYPE_DOUBLE > + REGEX_TYPE_INT "|" REGEX_TYPE_UINT "|" \ > + REGEX_TYPE_LONG "|" REGEX_TYPE_ULONG "|" \ > + REGEX_TYPE_HALF "|" REGEX_TYPE_FLOAT "|" > REGEX_TYPE_DOUBLE > > /* Image types */ > /* TODO: add OpenCL 1.2+ types */ > @@ -324,6 +326,7 @@ enum cl_type { > TYPE_UINT, > TYPE_LONG, > TYPE_ULONG, > + TYPE_HALF, > TYPE_FLOAT, > TYPE_DOUBLE, > }; > @@ -1002,7 +1005,7 @@ get_test_arg_value(struct test_arg* test_arg, > const char* value, size_t length) > for(c = 0; c < test_arg->cl_size; c++) > { \ > ra = i*test_arg->cl_size + > c; \ > rb = i*test_arg->cl_mem_size + > c; \ > - ((cl_type*)test_arg->value)[rb] = > array[ra%length]; \ > + ((cl_type*)test_arg->value)[rb] = > convert_##cl_type(array[ra%length]); \ > } > \ > } > \ > break; > @@ -1016,8 +1019,9 @@ get_test_arg_value(struct test_arg* test_arg, > const char* value, size_t length) > CASE(TYPE_UINT, cl_uint, get_uint_array, uint > _array) > CASE(TYPE_LONG, cl_long, get_int_array, int_ > array) > CASE(TYPE_ULONG, cl_ulong, get_uint_array, uint > _array) > + CASE(TYPE_HALF, cl_half, get_float_array, floa > t_array) > CASE(TYPE_FLOAT, cl_float, get_float_array, floa > t_array) > - CASE(TYPE_DOUBLE, cl_double, get_float_array, fl > oat_array) > + CASE(TYPE_DOUBLE, > cl_double, get_float_array, float_array) > } > > #undef CASE > @@ -1040,6 +1044,7 @@ get_test_arg_tolerance(struct test_arg* > test_arg, const char* tolerance_str) > REG_NEWLINE)) { > regex_get_match_str(&value_str, tolerance_str, > pmatch, 1); > switch(test_arg->cl_type) { > + case TYPE_HALF: > case TYPE_FLOAT: > case TYPE_DOUBLE: > test_arg->ulp = get_uint(value_str); > @@ -1070,6 +1075,7 @@ get_test_arg_tolerance(struct test_arg* > test_arg, const char* tolerance_str) > case TYPE_ULONG: > test_arg->tolu = get_uint(value_str); > break; > + case TYPE_HALF: > case TYPE_FLOAT: > case TYPE_DOUBLE: { > float value = get_float(value_str); > @@ -1152,6 +1158,7 @@ get_test_arg(const char* src, struct test* > test, bool arg_in) > ELSEIF(REGEX_TYPE_UINT, TYPE_UINT, cl_uint) > ELSEIF(REGEX_TYPE_LONG, TYPE_LONG, cl_long) > ELSEIF(REGEX_TYPE_ULONG, TYPE_ULONG, cl_ulong) > + ELSEIF(REGEX_TYPE_HALF, TYPE_HALF, cl_half) > ELSEIF(REGEX_TYPE_FLOAT, TYPE_FLOAT, cl_float) > ELSEIF(REGEX_TYPE_DOUBLE, TYPE_DOUBLE, cl_double) > > @@ -2093,6 +2100,21 @@ check_test_arg_value(struct test_arg test_arg, > } > \ > } > \ > return true; > +#define CASEH(enum_type, type, > cl_type) \ > + case > enum_type: \ > + for(i = 0; i < test_arg.length; i++) > { \ > + for(c = 0; c < test_arg.cl_size; c++) > { \ > + rb = i*test_arg.cl_mem_size + > c; \ > + if(!piglit_cl_probe_half(((cl_type*) > value)[rb], \ > + ((cl_ty > pe*)test_arg.value)[rb], \ > + test_ar > g.ulp)) { \ > + ra = i*test_arg.cl_size + > c; \ > + printf("Error at %s[%zu]\n", > type, ra); \ > + return > false; \ > + } > \ > + } > \ > + } > \ > + return true; > #define CASEF(enum_type, type, > cl_type) \ > case > enum_type: \ > for(i = 0; i < test_arg.length; i++) > { \ > @@ -2118,6 +2140,7 @@ check_test_arg_value(struct test_arg test_arg, > CASEU(TYPE_UINT, "uint", cl_uint) > CASEI(TYPE_LONG, "long", cl_long) > CASEU(TYPE_ULONG, "ulong", cl_ulong) > + CASEH(TYPE_HALF, "half", cl_half) > CASEF(TYPE_FLOAT, "float", cl_float) > CASEF(TYPE_DOUBLE, "double", cl_double) > } > diff --git a/tests/util/piglit-util-cl.c b/tests/util/piglit-util- > cl.c > index 7e7d985..fb32fee 100644 > --- a/tests/util/piglit-util-cl.c > +++ b/tests/util/piglit-util-cl.c > @@ -59,6 +59,27 @@ piglit_cl_probe_uinteger(uint64_t value, uint64_t > expect, uint64_t tolerance) > ((isnan(value) && isnan(expect)) || \ > (isinf(value) && isinf(expect) && ((value > 0) == (expect > > 0)))) > > +static float float_from_cl_half(uint32_t in) > +{ > + union { > + uint32_t bits; > + float val; > + } convert; > + uint32_t exponent = ((in >> 10) & 0x1f); > + convert.bits = (((in >> 15) & 0x1) << 31) | //sign > + ((exponent ? (exponent != 0x1f ? exponent + > 112 : 0xff) > + : 0) << 23) | //exponent (0 and 1f are > special cases) > + (((in >> 0) & 0x3ff) << 13); // mantissa > + return convert.val; > +} > + > +bool piglit_cl_probe_half(cl_half value, cl_half expect, uint32_t > ulp) > +{ > + // after conversion to float the last 13 digits are 0, > adjust ulp > + return piglit_cl_probe_floating(float_from_cl_half(value), > + float_from_cl_half(expect), > + ulp * 8192); > +} > > /* TODO: Tolerance should be specified in terms of ULP. */ > bool > @@ -118,6 +139,25 @@ piglit_cl_probe_double(double value, double > expect, uint64_t ulp) > > } > > +cl_half convert_cl_half(double in) > +{ > + union { > + uint64_t bits; > + double val; > + } convert = { .val = in }; > + /* Bit 63 is sign bit */ > + cl_half sign = (cl_half)((convert.bits >> 63) << 15); > + /* Get only the top 10 bits of mantissa */ > + cl_half mantissa = (cl_half)((convert.bits >> 42) & 0x3ff); > + /* 11 bits of exponent */ > + uint64_t exp = (convert.bits >> 52) & 0x7ff; > + /* 0 and ~0 are special cases that are not adjusted, > + * half bias is 15, double bias is 1023 */ > + cl_half exponent = ((exp == 0 || exp == 0x7ff) ? (exp & > 0x3ff) : > + (exp - 1008)) << 10; > + return (sign | exponent | mantissa); > +} > + > bool > piglit_cl_check_error(cl_int error, cl_int expected_error) > { > diff --git a/tests/util/piglit-util-cl.h b/tests/util/piglit-util- > cl.h > index 9fb4f9f..bd9f5a8 100644 > --- a/tests/util/piglit-util-cl.h > +++ b/tests/util/piglit-util-cl.h > @@ -44,6 +44,25 @@ > extern "C" { > #endif > > +#define DIRECT_CONVERT(to, from) \ > +static inline from convert_##to(from in) \ > +{ \ > + return (to)in; \ > +} > + > +DIRECT_CONVERT(cl_char, int64_t); > +DIRECT_CONVERT(cl_uchar, uint64_t); > +DIRECT_CONVERT(cl_short, int64_t); > +DIRECT_CONVERT(cl_ushort, uint64_t); > +DIRECT_CONVERT(cl_int, int64_t); > +DIRECT_CONVERT(cl_uint, uint64_t); > +DIRECT_CONVERT(cl_long, int64_t); > +DIRECT_CONVERT(cl_ulong, uint64_t); > +DIRECT_CONVERT(cl_float, double); > +DIRECT_CONVERT(cl_double, double); > + > +cl_half convert_cl_half(double in); > + > > /* Runtime independent */ > > @@ -62,6 +81,12 @@ bool piglit_cl_probe_uinteger(uint64_t value, > uint64_t tolerance); > > /** > + * \brief Probe half-floating-point \c value if it compares equal to > \c expect with > + * tolerance \c ulp. > + */ > +bool piglit_cl_probe_half(cl_half value, cl_half expect, uint32_t > ulp); > + > +/** > * \brief Probe floating-point \c value if it compares equal to \c > expect with > * tolerance \c ulp. > */
ping -- Jan Vesely <jan.ves...@rutgers.edu>
signature.asc
Description: This is a digitally signed message part
_______________________________________________ Piglit mailing list Piglit@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/piglit