test(agc): accept any NaN where the f16 fma and fma_mix tests expect one

agc_driver_f16_fma_denormal_modes and
agc_driver_fma_mix_f16_denormal_modes compared NaN results (inf * 0)
bit for bit with the RX 6700 XT's, but the NaN bits of f16 arithmetic
and of v_fma_mix_f32 with f16 sources are left to the driver, so the
tests fail on NVIDIA (0x7fff for 0xfe00). Rows whose expected value is
a NaN now accept any NaN; every other row is still exact.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
thuanquangandClaude Opus 5.5 committed 2026-10-17 18:13:41 +07:00
1 parent 864729dc0d
commit e5b4b326ca
2 files changed
+12 -2

No files matched your search

@@ -205,13 +205,18 @@ void Run(AgcDriver::VulkanDevice& device, const Mode& mode) {
device.WaitIdle();
}
bool Matches(std::uint32_t actual, std::uint32_t expected) {
const auto nan = [](std::uint32_t half) { return (half & 0x7fffu) > 0x7c00u; };
return actual == expected || (nan(expected) && actual <= 0xffffu && nan(actual));
}
void Check(const Mode& mode) {
constexpr const char* Names[Results] = {"v_fma_f16", "v_fmac_f16"};
for (std::uint32_t tid = 0; tid < Threads; ++tid) {
const std::uint32_t expected = Expected[tid][mode.column];
for (std::uint32_t form = 0; form < Results; ++form) {
const std::uint32_t actual = Output[tid * Results + form];
Require(actual == expected, std::string(Names[form]) + " " + mode.name + " of " + Hex(Rows[tid][0]) + ", " + Hex(Rows[tid][1]) + ", " + Hex(Rows[tid][2]) + " is " + Hex(actual) + ", expected " + Hex(expected));
Require(Matches(actual, expected), std::string(Names[form]) + " " + mode.name + " of " + Hex(Rows[tid][0]) + ", " + Hex(Rows[tid][1]) + ", " + Hex(Rows[tid][2]) + " is " + Hex(actual) + ", expected " + Hex(expected));
}
}
}
@@ -166,6 +166,11 @@ void Run(AgcDriver::VulkanDevice& device, const Mode& mode) {
device.WaitIdle();
}
bool Matches(std::uint32_t actual, std::uint32_t expected) {
const auto nan = [](std::uint32_t single) { return (single & 0x7fffffffu) > 0x7f800000u; };
return actual == expected || (nan(expected) && nan(actual));
}
void Check(const Mode& mode) {
constexpr const char* Names[Results] = {"v_fma_mix_f32 of three f16 sources", "v_fma_mix_f32 of an f16, an f32 and an f16 source"};
const std::uint32_t f32Kept = (mode.value.floatMode >> 4u) & 1u;
@@ -174,7 +179,7 @@ void Check(const Mode& mode) {
for (std::uint32_t form = 0; form < Results; ++form) {
const std::uint32_t actual = Output[tid * Results + form];
const std::uint32_t expected = Expected[f32Kept][f16InputsKept][tid][form];
Require(actual == expected, std::string(Names[form]) + " " + mode.name + " of " + Hex(Rows[tid][0]) + ", " + Hex(Rows[tid][1]) + ", " + Hex(Rows[tid][2]) + " is " + Hex(actual) + ", expected " + Hex(expected));
Require(Matches(actual, expected), std::string(Names[form]) + " " + mode.name + " of " + Hex(Rows[tid][0]) + ", " + Hex(Rows[tid][1]) + ", " + Hex(Rows[tid][2]) + " is " + Hex(actual) + ", expected " + Hex(expected));
}
}
}