From 4019a26a5b79ad9d18899c6cd06d5e323b51fdc3 Mon Sep 17 00:00:00 2001 From: Sreelakshmi Haridas Maruthur Date: Tue, 9 Apr 2024 09:58:33 -0600 Subject: [PATCH] conversions: Fix verification of half subnormal cases with FTZ (#1914) --- .../conversions/basic_test_conversions.cpp | 18 +++------- .../conversions/conversions_data_info.h | 36 +++++++++++++++++++ 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/test_conformance/conversions/basic_test_conversions.cpp b/test_conformance/conversions/basic_test_conversions.cpp index b5f59dea..155c272b 100644 --- a/test_conformance/conversions/basic_test_conversions.cpp +++ b/test_conformance/conversions/basic_test_conversions.cpp @@ -1005,14 +1005,6 @@ double SubtractTime(uint64_t endTime, uint64_t startTime) } #endif -static void setAllowZ(uint8_t *allow, uint32_t *x, cl_uint count) -{ - cl_uint i; - for (i = 0; i < count; ++i) - allow[i] |= (uint8_t)((x[i] & 0x7f800000U) == 0); -} - - void MapResultValuesComplete(const std::unique_ptr &ptr); void CL_CALLBACK CalcReferenceValuesComplete(cl_event e, cl_int status, @@ -1337,15 +1329,13 @@ cl_int PrepareReference(cl_uint job_id, cl_uint thread_id, void *p) // Decide if we allow a zero result in addition to the correctly rounded // one memset(a, 0, count); - if (gForceFTZ) + if (gForceFTZ && (inType == kfloat || outType == kfloat)) { - if (inType == kfloat || outType == kfloat) - setAllowZ((uint8_t *)a, (uint32_t *)s, count); + info->set_allow_zero_array((uint8_t *)a, d, s, count); } - if (gForceHalfFTZ) + if (gForceHalfFTZ && (inType == khalf || outType == khalf)) { - if (inType == khalf || outType == khalf) - setAllowZ((uint8_t *)a, (uint32_t *)s, count); + info->set_allow_zero_array((uint8_t *)a, d, s, count); } } else diff --git a/test_conformance/conversions/conversions_data_info.h b/test_conformance/conversions/conversions_data_info.h index bf887ede..807d8ee9 100644 --- a/test_conformance/conversions/conversions_data_info.h +++ b/test_conformance/conversions/conversions_data_info.h @@ -30,6 +30,7 @@ extern roundingMode qcom_rm; #include +#include "harness/conversions.h" #include "harness/mt19937.h" #include "harness/rounding_mode.h" #include "harness/typeWrappers.h" @@ -82,6 +83,7 @@ struct DataInitBase : public DataInitInfo virtual void conv_array(void *out, void *in, size_t n) {} virtual void conv_array_sat(void *out, void *in, size_t n) {} virtual void init(const cl_uint &, const cl_uint &) {} + virtual void set_allow_zero_array(uint8_t *allow, void *out, void *in, size_t n) {} }; template @@ -99,6 +101,9 @@ struct DataInfoSpec : public DataInitBase void conv(OutType *out, InType *in); void conv_sat(OutType *out, InType *in); + // Decide if we allow a zero result in addition to the correctly rounded one + void set_allow_zero(uint8_t *allow, OutType *out, InType *in); + // min/max ranges for output type of data std::pair ranges; @@ -130,6 +135,10 @@ struct DataInfoSpec : public DataInitBase } void init(const cl_uint &, const cl_uint &) override; + void set_allow_zero_array(uint8_t *allow, void *out, void *in, size_t n) override { + for (size_t i = 0; i < n; i++) + set_allow_zero(&allow[i], &((OutType *)out)[i], &((InType *)in)[i]); + } InType clamp(const InType &); inline float fclamp(float lo, float v, float hi) { @@ -717,6 +726,33 @@ void DataInfoSpec::conv_sat(OutType *out, } } +template +void DataInfoSpec::set_allow_zero(uint8_t *allow, + OutType *out, + InType *in) +{ + // from double + if (std::is_same::value) + *allow |= IsDoubleSubnormal(*in); + // from float + if (std::is_same::value) + *allow |= IsFloatSubnormal(*in); + // from half + if (is_in_half()) + *allow |= IsHalfSubnormal(*in); + + // handle the cases that the converted result is subnormal + // from double + if (std::is_same::value) + *allow |= IsDoubleSubnormal(*out); + // from float + if (std::is_same::value) + *allow |= IsFloatSubnormal(*out); + // from half + if (is_out_half()) + *allow |= IsHalfSubnormal(*out); +} + template void DataInfoSpec::init(const cl_uint &job_id, const cl_uint &thread_id)