Use explicit conversion from regexp matched array values Signed-off-by: Jan Vesely <[email protected]> --- tests/cl/program/program-tester.c | 31 +++++++++++++++++++++++++---- tests/util/piglit-util-cl.c | 42 +++++++++++++++++++++++++++++++++++++++ tests/util/piglit-util-cl.h | 25 +++++++++++++++++++++++ 3 files changed, 94 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, float_array) CASE(TYPE_FLOAT, cl_float, get_float_array, float_array) - CASE(TYPE_DOUBLE, cl_double, get_float_array, float_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_type*)test_arg.value)[rb], \ + test_arg.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..d7a7901 100644 --- a/tests/util/piglit-util-cl.c +++ b/tests/util/piglit-util-cl.c @@ -59,6 +59,29 @@ 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 + 0xfff ; // add 0.5 of non-represented value to put + // the final value in the middle + 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 + 1) * 4096); +} /* TODO: Tolerance should be specified in terms of ULP. */ bool @@ -118,6 +141,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. */ -- 2.7.4 _______________________________________________ Piglit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/piglit
