From 54afc2e7a5b75504a86bd5ec7f14a2dd48eefe3b Mon Sep 17 00:00:00 2001 From: Chuang-Yu Cheng Date: Wed, 12 Feb 2025 01:46:23 +0900 Subject: [PATCH] printf: Fix floating-point rounding consistency for RTZ devices (#2202) 1. In vector test, prepare RTZ answer for RTZ rounding. 2. In mixed_format_random test, for a given float 'arg', the test previously used 'arg' directly to generate ref_str: ``` ref_str << str_sprintf(format, arg); ``` This approach incorrectly assumes: ``` (float) arg == to_fp(to_str(arg)); ``` However, this assumption fails under RTZ rounding. For example: ``` arg = 0xC642549C to_str(arg) = -12437.152343f to_fp_rtz(-12437.152343f) = 0xC642549B (-0X1.84A936P+13) to_fp_rte(-12437.152343f) = 0xC642549C (-0X1.84A938P+13) ``` To address this, the reference result is now computed based on the literal float string rather than the original 'arg' value. --- test_conformance/printf/test_printf.cpp | 6 +++-- test_conformance/printf/util_printf.cpp | 34 +++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/test_conformance/printf/test_printf.cpp b/test_conformance/printf/test_printf.cpp index ef52f044..380878cb 100644 --- a/test_conformance/printf/test_printf.cpp +++ b/test_conformance/printf/test_printf.cpp @@ -317,8 +317,10 @@ cl_program makeMixedFormatPrintfProgram(cl_kernel* kernel_ptr, { const float max_range = 100000.f; float arg = get_random_float(-max_range, max_range, gMTdata); - args_str << str_sprintf("%f", arg) << "f, "; - ref_str << str_sprintf(format, arg) << ", "; + std::string arg_str = str_sprintf("%f", arg); + args_str << arg_str << "f, "; + float arg_deviceRound = std::stof(arg_str); + ref_str << str_sprintf(format, arg_deviceRound) << ", "; } } // Restore the original CPU rounding mode diff --git a/test_conformance/printf/util_printf.cpp b/test_conformance/printf/util_printf.cpp index cd84c01a..803f13ab 100644 --- a/test_conformance/printf/util_printf.cpp +++ b/test_conformance/printf/util_printf.cpp @@ -1336,6 +1336,33 @@ std::vector correctBufferVector = { "00512,01024,262144,1048576" }; +std::vector correctBufferVectorRTZ = { + + "1.00,2.00,3.00,4.00", + + "0xfa,0xfb", + + "0x1234,0x8765", + + "0x12345678,0x87654321", + + "12345678,98765432", + + "1.00,2.00,3.00,4.00", + + "1.23e+03,9.87e+05,4.99e-04", + + "0x1p-2,0x1p-1,0x1p+0,0x1.8p+0", + + "1,2,3,4,1.5,3.13999,2.5,3.5", + + "1,2,3,4,5,6,7,10,11,0,40,100,200,400,1000,2000", + + "+1,-2,+3,-4,+5,-6,+7,-8", + + "00512,01024,262144,1048576" +}; + //----------------------------------------------------------- //Test case for vector | @@ -1822,7 +1849,14 @@ void generateRef(const cl_device_id device) as they're constant and hard-coded */ if (caseToTest->printFN == NULL) + { + if (caseToTest->_type == TYPE_VECTOR + && fpConfigSingle == CL_FP_ROUND_TO_ZERO) + { + caseToTest->_correctBuffer = correctBufferVectorRTZ; + } continue; + } // Make sure the reference result is empty assert(caseToTest->_correctBuffer.size() == 0);