Skip to content

Commit b428ba5

Browse files
authored
Relax NaN comparison in compression tests (#2388)
* Relax NaN comparison in compression tests `compareExact(float)` currently requires bitwise equality, even for NaN, but C vs C++ EXR can generate NaNs that are not bit-wise identical, leading to reports of failures on various architectures. This fixes the failures noted in #1281, #1460, #1628 in the `test*Compression` tests, of the form: F float at 59, 0 not equal: C++ loaded C 0x7fc4e364 (nan) vs C loaded C 7f84e364 (nan) and in `testOptimizedInterleavePatterns`: error reading back channel B pixel 21,-76 got -nan expected -nan This change takes the conservative approach and relaxes the bitwise comparison only for the architectures that are known to have NaN differences. This also changes the method of bitwise comparison of float values. The C++ standard does not guarantee that writing one field of a union and reading another is well-defined, and we've seen cases of it failing with Intel's oneAPI. This changes the comparison to use `memcpy` to a `uint32_t` instead of a union. Made with Cursor Signed-off-by: Cary Phillips <cary@ilm.com> * remove extraneous bothNan Signed-off-by: Cary Phillips <cary@ilm.com> * Use test on all architectures Signed-off-by: Cary Phillips <cary@ilm.com> --------- Signed-off-by: Cary Phillips <cary@ilm.com>
1 parent f21cb81 commit b428ba5

1 file changed

Lines changed: 13 additions & 11 deletions

File tree

src/test/OpenEXRCoreTest/compression.cpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -519,22 +519,24 @@ struct pixels
519519
const char* tagb,
520520
const char* chan)
521521
{
522-
union
523-
{
524-
uint32_t iv;
525-
float fv;
526-
} a, b;
527-
a.fv = af;
528-
b.fv = bf;
529-
if (a.iv != b.iv)
522+
// On some architectures (Windows 32‑bit x86, i686 with x87 extended
523+
// precision, aarch64, ppc64le, arm7), the C and C++ codepaths may
524+
// generate NaN values that are not bitwise identical. Accept these
525+
// special cases as equal.
526+
const bool bothNaN = std::isnan(af) && std::isnan(bf);
527+
if (bothNaN)
528+
return;
529+
530+
uint32_t a,b; memcpy(&a,&af,sizeof a); memcpy(&b,&bf,sizeof b);
531+
if (a != b)
530532
{
531533
std::cout << chan << " float at " << x << ", " << y
532-
<< " not equal: " << taga << " 0x" << std::hex << a.iv
534+
<< " not equal: " << taga << " 0x" << std::hex << a
533535
<< std::dec << " (" << af << ") vs " << tagb << " "
534-
<< std::hex << b.iv << std::dec << " (" << bf << ")"
536+
<< std::hex << b << std::dec << " (" << bf << ")"
535537
<< std::endl;
536538
}
537-
EXRCORE_TEST (a.iv == b.iv);
539+
EXRCORE_TEST (a == b);
538540
}
539541
void
540542
compareExact (const pixels& o, const char* otag, const char* selftag) const

0 commit comments

Comments
 (0)