Build native Windows packages for both RDNA4 targets
Add explicit gfx1200/gfx1201 builds, runtime selection and per-target code objects. Guard staging, packaging and installation against mixed architectures; retain gfx1201 compatibility and strict K/M arithmetic. Adapt realdody's target configuration and MSVC binary16/BOOL portability fixes from ae530b0. Do not import its forced gfx12 layout on RDNA3. Add exhaustive binary16 and C++/PowerShell target contract regressions. Validation: 20 CTest gates on RX 9070 XT; four software-only gfx1200 gates; MSVC portability compile checks; exact 4K K async and M control outputs; isolated package install/restore and mixed-target rejection tests. No physical gfx1200 validation is claimed. Co-authored-by: realdody <[email protected]>
This commit is contained in:
1 parent
8f7058d2ba
commit
98de8e3a3e
51 files changed
+636
-127
No files matched your search
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
// Adapted from realdody/d4r ae530b0 (MIT), realdody <[email protected]>.
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
namespace d4r::diag::binary16 {
|
||||
// MSVC has no _Float16 extension. Convert double<->IEEE binary16 explicitly with
|
||||
// round-to-nearest-even, matching a native _Float16 cast. This probe compares the
|
||||
// f16-accumulator MMA against a double sum rounded once to half, so the rounding
|
||||
// must match IEEE 754 binary16 exactly.
|
||||
inline uint16_t half_bits(double value) {
|
||||
uint64_t bits;
|
||||
std::memcpy(&bits, &value, sizeof(bits));
|
||||
const uint16_t sign = static_cast<uint16_t>((bits >> 63) << 15);
|
||||
int32_t exponent = static_cast<int32_t>((bits >> 52) & 0x7ff);
|
||||
uint64_t mantissa = bits & 0x000fffffffffffffULL;
|
||||
if (exponent == 0x7ff) return static_cast<uint16_t>(sign | (mantissa ? 0x7e00 : 0x7c00));
|
||||
if (exponent == 0) return sign; // double subnormal rounds to half zero
|
||||
int32_t unbiased = exponent - 1023;
|
||||
if (unbiased > 15) return static_cast<uint16_t>(sign | 0x7c00);
|
||||
mantissa |= 0x0010000000000000ULL; // implicit leading one (53-bit significand)
|
||||
const int shift = unbiased >= -14 ? 42 : 28 - unbiased;
|
||||
uint64_t rounded = shift >= 64 ? 0 : (mantissa >> shift);
|
||||
if (shift < 64) {
|
||||
const uint64_t remainder = mantissa & ((1ULL << shift) - 1);
|
||||
const uint64_t halfway = 1ULL << (shift - 1);
|
||||
if (remainder > halfway || (remainder == halfway && (rounded & 1))) ++rounded;
|
||||
}
|
||||
if (unbiased >= -14) {
|
||||
if (rounded >= 0x800) { // rounding overflowed into the exponent
|
||||
rounded = 0x400;
|
||||
if (++unbiased > 15) return static_cast<uint16_t>(sign | 0x7c00);
|
||||
}
|
||||
return static_cast<uint16_t>(sign | ((unbiased + 15) << 10) | static_cast<uint16_t>(rounded & 0x3ff));
|
||||
}
|
||||
if (rounded >= 0x400) return static_cast<uint16_t>(sign | 0x0400); // smallest normal half
|
||||
return static_cast<uint16_t>(sign | static_cast<uint16_t>(rounded));
|
||||
}
|
||||
inline double half_value(uint16_t bits) {
|
||||
const bool negative = (bits & 0x8000u) != 0;
|
||||
const uint32_t exponent = (bits >> 10) & 0x1fu;
|
||||
const uint32_t mantissa = bits & 0x3ffu;
|
||||
double magnitude;
|
||||
if (exponent == 0) magnitude = std::ldexp(static_cast<double>(mantissa), -24);
|
||||
else if (exponent == 0x1fu) magnitude = mantissa ? std::numeric_limits<double>::quiet_NaN() : std::numeric_limits<double>::infinity();
|
||||
else magnitude = std::ldexp(static_cast<double>(mantissa) / 1024.0 + 1.0, static_cast<int>(exponent) - 15);
|
||||
return negative ? -magnitude : magnitude;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user