diff --git a/test_conformance/workgroups/test_wg_scan_reduce.cpp b/test_conformance/workgroups/test_wg_scan_reduce.cpp index d7dd291499..9943ce03d8 100644 --- a/test_conformance/workgroups/test_wg_scan_reduce.cpp +++ b/test_conformance/workgroups/test_wg_scan_reduce.cpp @@ -22,8 +22,8 @@ #include "testBase.h" cl_half_rounding_mode gHalfRoundingMode = CL_HALF_RTE; -constexpr cl_half g_half_min = 0xfbff; -constexpr cl_half g_half_max = 0x7bff; +constexpr cl_half g_half_min = 0xFC00; +constexpr cl_half g_half_max = 0x7C00; static std::string make_kernel_string(const std::string &type, const std::string &kernelName, @@ -113,7 +113,7 @@ template struct Max static constexpr const char *opName = "max"; static constexpr T identityValue = std::is_integral_v ? std::numeric_limits::min() - : -std::numeric_limits::max(); + : -std::numeric_limits::infinity(); static T combine(T a, T b) { return std::max(a, b); } }; @@ -134,7 +134,9 @@ template struct Min { using Type = T; static constexpr const char *opName = "min"; - static constexpr T identityValue = std::numeric_limits::max(); + static constexpr T identityValue = std::is_integral_v + ? std::numeric_limits::max() + : std::numeric_limits::infinity(); static T combine(T a, T b) { return std::min(a, b); } }; @@ -434,6 +436,28 @@ template struct ScanExclusive static constexpr const char *deviceTypeName = TestTypeInfo::deviceName; static constexpr const char *kernelName = "test_wg_scan_exclusive"; + + static int check_result(const Type &test_value, const Type &reference, + const Type &max_err = 0) + { + if constexpr (std::is_floating_point_v) + { + if (std::abs(reference - test_value) > max_err) return -1; + } + else if constexpr (std::is_same_v) + { + if (std::abs(cl_half_to_float(reference) + - cl_half_to_float(test_value)) + > cl_half_to_float(max_err)) + return -1; + } + else + { + if (reference != test_value) return -1; + } + return CL_SUCCESS; + } + static int verify(Type *inptr, Type *outptr, size_t n_elems, size_t max_wg_size, const Type *const max_err = nullptr) { @@ -444,7 +468,8 @@ template struct ScanExclusive Type result = C::identityValue; for (size_t j = 0; j < wg_size; ++j) { - if (result != outptr[i + j]) + if (check_result(outptr[i + j], result, max_err[j]) + != CL_SUCCESS) { log_info("%s_%s: Error at %zu\n", testName, testOpName, i + j); @@ -458,10 +483,79 @@ template struct ScanExclusive static void generate_input_values(Type *inptr, size_t n_elems, size_t max_wg_size, - const Type *max_err = nullptr) + Type *const max_err = nullptr) { MTdataHolder d(gRandomSeed); - for (size_t i = 0; i < n_elems; i++) inptr[i] = (Type)genrand_int64(d); + if constexpr (std::is_floating_point_v< + Type> || std::is_same_v) + { + std::vector ref_vals(max_wg_size, 0); + if constexpr (std::is_same_v) + { + // to prevent overflow limit range of randomization + float max_range = 99.0; + float min_range = -99.0; + // generate reference values for one work group + for (size_t j = 0; j < max_wg_size; j++) + ref_vals[j] = cl_half_from_float( + get_random_float(min_range, max_range, d), + gHalfRoundingMode); + + // populate reference data across all work groups + for (size_t i = 0; i < (size_t)n_elems; i += max_wg_size) + { + size_t wg_size = std::min(max_wg_size, n_elems - i); + memcpy(&inptr[i], ref_vals.data(), sizeof(Type) * wg_size); + } + + if constexpr (std::is_same_v>) + { + // compute maximal summation error + float s = std::abs(cl_half_to_float(ref_vals[0])); + for (size_t i = 1; i < (size_t)n_elems; i++) + { + max_err[i] = cl_half_from_float( + std::abs((max_wg_size - 1) * CL_HALF_EPSILON * s), + gHalfRoundingMode); + s += std::abs(cl_half_to_float(ref_vals[i])); + } + } + } + else + { + double max_range = 999.0; + double min_range = -999.0; + for (size_t j = 0; j < max_wg_size; j++) + ref_vals[j] = get_random_float(min_range, max_range, d); + + for (size_t i = 0; i < (size_t)n_elems; i += max_wg_size) + { + size_t work_group_size = std::min(max_wg_size, n_elems - i); + memcpy(&inptr[i], ref_vals.data(), + sizeof(Type) * work_group_size); + } + + if constexpr (std::is_same_v>) + { + // compute maximal summation error + Type s = std::abs(ref_vals[0]); + for (size_t i = 1; i < (size_t)n_elems; i++) + { + max_err[i] = std::abs((max_wg_size - 1) + * (std::is_same_v + ? CL_FLT_EPSILON + : CL_DBL_EPSILON) + * s); + s += std::abs(ref_vals[i]); + } + } + } + } + else + { + for (size_t i = 0; i < n_elems; i++) + inptr[i] = (Type)genrand_int64(d); + } } }; @@ -546,24 +640,23 @@ static int run_test(cl_device_id device, cl_context context, return TEST_PASS; } -template