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.
This commit is contained in:
Chuang-Yu Cheng
2025-02-12 01:46:23 +09:00
committed by GitHub
parent ecd012737f
commit 54afc2e7a5
2 changed files with 38 additions and 2 deletions

View File

@@ -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

View File

@@ -1336,6 +1336,33 @@ std::vector<std::string> correctBufferVector = {
"00512,01024,262144,1048576"
};
std::vector<std::string> 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);