@@ -258,6 +258,17 @@ inline void LogErrorFmt(const wchar_t *fmt, ...) {
258258 WEX::Logging::Log::Error (buf.data ());
259259}
260260
261+ inline void LogErrorFmtThrow (const wchar_t *fmt, ...) {
262+ va_list args;
263+ va_start (args, fmt);
264+ std::wstring buf (vFormatToWString (fmt, args));
265+ va_end (args);
266+ WEX::Logging::Log::Error (buf.data ());
267+
268+ // Throws an exception to abort the test.
269+ VERIFY_FAIL (L" Test error" );
270+ }
271+
261272inline std::wstring
262273GetPathToHlslDataFile (const wchar_t *relative,
263274 LPCWSTR paramName = HLSLDATAFILEPARAM,
@@ -459,15 +470,17 @@ inline bool GetTestParamUseWARP(bool defaultVal) {
459470
460471#ifdef FP_SUBNORMAL
461472
462- inline bool isdenorm (float f) { return FP_SUBNORMAL == std::fpclassify (f); }
473+ template <typename T> inline bool isdenorm (T f) {
474+ return FP_SUBNORMAL == std::fpclassify (f);
475+ }
463476
464477#else
465478
466- inline bool isdenorm (float f) {
467- return (std::numeric_limits<float >::denorm_min () <= f &&
468- f < std::numeric_limits<float >::min ()) ||
469- (-std::numeric_limits<float >::min () < f &&
470- f <= -std::numeric_limits<float >::denorm_min ());
479+ template < typename T> inline bool isdenorm (T f) {
480+ return (std::numeric_limits<T >::denorm_min () <= f &&
481+ f < std::numeric_limits<T >::min ()) ||
482+ (-std::numeric_limits<T >::min () < f &&
483+ f <= -std::numeric_limits<T >::denorm_min ());
471484}
472485
473486#endif // FP_SUBNORMAL
@@ -515,6 +528,31 @@ inline bool isnanFloat16(uint16_t val) {
515528uint16_t ConvertFloat32ToFloat16 (float val) throw();
516529float ConvertFloat16ToFloat32 (uint16_t val) throw();
517530
531+ inline bool CompareDoubleULP (
532+ const double &Src, const double &Ref, int64_t ULPTolerance,
533+ hlsl::DXIL::Float32DenormMode Mode = hlsl::DXIL::Float32DenormMode::Any) {
534+ if (Src == Ref) {
535+ return true ;
536+ }
537+ if (std::isnan (Src)) {
538+ return std::isnan (Ref);
539+ }
540+
541+ if (Mode == hlsl::DXIL::Float32DenormMode::Any) {
542+ // If denorm expected, output can be sign preserved zero. Otherwise output
543+ // should pass the regular ulp testing.
544+ if (isdenorm (Ref) && Src == 0 && std::signbit (Src) == std::signbit (Ref))
545+ return true ;
546+ }
547+
548+ // For FTZ or Preserve mode, we should get the expected number within
549+ // ULPTolerance for any operations.
550+ int64_t Diff = *((const uint64_t *)&Src) - *((const uint64_t *)&Ref);
551+
552+ uint64_t AbsoluteDiff = Diff < 0 ? -Diff : Diff;
553+ return AbsoluteDiff <= (uint64_t )ULPTolerance;
554+ }
555+
518556inline bool CompareFloatULP (
519557 const float &fsrc, const float &fref, int ULPTolerance,
520558 hlsl::DXIL::Float32DenormMode mode = hlsl::DXIL::Float32DenormMode::Any) {
0 commit comments