@@ -176,37 +176,37 @@ enum class ValidationType {
176176};
177177
178178template <typename T>
179- bool doValuesMatch (T A, T B, float Tolerance, ValidationType) {
180- if (Tolerance == 0 .0f )
179+ bool doValuesMatch (T A, T B, double Tolerance, ValidationType) {
180+ if (Tolerance == 0.0 )
181181 return A == B;
182182
183183 T Diff = A > B ? A - B : B - A;
184184 return Diff <= Tolerance;
185185}
186186
187- bool doValuesMatch (HLSLBool_t A, HLSLBool_t B, float , ValidationType) {
187+ bool doValuesMatch (HLSLBool_t A, HLSLBool_t B, double , ValidationType) {
188188 return A == B;
189189}
190190
191- bool doValuesMatch (HLSLHalf_t A, HLSLHalf_t B, float Tolerance,
191+ bool doValuesMatch (HLSLHalf_t A, HLSLHalf_t B, double Tolerance,
192192 ValidationType ValidationType) {
193193 switch (ValidationType) {
194194 case ValidationType::Epsilon:
195- return CompareHalfEpsilon (A.Val , B.Val , Tolerance);
195+ return CompareHalfEpsilon (A.Val , B.Val , static_cast < float >( Tolerance) );
196196 case ValidationType::Ulp:
197- return CompareHalfULP (A.Val , B.Val , Tolerance);
197+ return CompareHalfULP (A.Val , B.Val , static_cast < float >( Tolerance) );
198198 default :
199199 hlsl_test::LogErrorFmt (
200200 L" Invalid ValidationType. Expecting Epsilon or ULP." );
201201 return false ;
202202 }
203203}
204204
205- bool doValuesMatch (float A, float B, float Tolerance,
205+ bool doValuesMatch (float A, float B, double Tolerance,
206206 ValidationType ValidationType) {
207207 switch (ValidationType) {
208208 case ValidationType::Epsilon:
209- return CompareFloatEpsilon (A, B, Tolerance);
209+ return CompareFloatEpsilon (A, B, static_cast < float >( Tolerance) );
210210 case ValidationType::Ulp: {
211211 // Tolerance is in ULPs. Convert to int for the comparison.
212212 const int IntTolerance = static_cast <int >(Tolerance);
@@ -219,7 +219,7 @@ bool doValuesMatch(float A, float B, float Tolerance,
219219 }
220220}
221221
222- bool doValuesMatch (double A, double B, float Tolerance,
222+ bool doValuesMatch (double A, double B, double Tolerance,
223223 ValidationType ValidationType) {
224224 switch (ValidationType) {
225225 case ValidationType::Epsilon:
@@ -238,7 +238,7 @@ bool doValuesMatch(double A, double B, float Tolerance,
238238
239239template <typename T>
240240bool doVectorsMatch (const std::vector<T> &ActualValues,
241- const std::vector<T> &ExpectedValues, float Tolerance,
241+ const std::vector<T> &ExpectedValues, double Tolerance,
242242 ValidationType ValidationType, bool VerboseLogging) {
243243
244244 DXASSERT (
@@ -540,14 +540,14 @@ InputSets<T> buildTestInputs(size_t VectorSize, const InputSet OpInputSets[3],
540540}
541541
542542struct ValidationConfig {
543- float Tolerance = 0 .0f ;
543+ double Tolerance = 0.0 ;
544544 ValidationType Type = ValidationType::Epsilon;
545545
546- static ValidationConfig Epsilon (float Tolerance) {
546+ static ValidationConfig Epsilon (double Tolerance) {
547547 return ValidationConfig{Tolerance, ValidationType::Epsilon};
548548 }
549549
550- static ValidationConfig Ulp (float Tolerance) {
550+ static ValidationConfig Ulp (double Tolerance) {
551551 return ValidationConfig{Tolerance, ValidationType::Ulp};
552552 }
553553};
@@ -943,8 +943,7 @@ struct Op<OpType::AsUint_SplitDouble, double, 1> : StrictValidation {};
943943template <> struct ExpectedBuilder <OpType::AsUint_SplitDouble, double > {
944944 static std::vector<uint32_t >
945945 buildExpected (Op<OpType::AsUint_SplitDouble, double , 1 > &,
946- const InputSets<double > &Inputs, uint16_t ScalarInputFlags) {
947- DXASSERT_NOMSG (ScalarInputFlags == 0 );
946+ const InputSets<double > &Inputs) {
948947 DXASSERT_NOMSG (Inputs.size () == 1 );
949948
950949 size_t VectorSize = Inputs[0 ].size ();
@@ -1018,8 +1017,7 @@ template <> struct Op<OpType::Frexp, float, 1> : DefaultValidation<float> {};
10181017
10191018template <> struct ExpectedBuilder <OpType::Frexp, float > {
10201019 static std::vector<float > buildExpected (Op<OpType::Frexp, float , 1 > &,
1021- const InputSets<float > &Inputs,
1022- uint32_t ) {
1020+ const InputSets<float > &Inputs) {
10231021 DXASSERT_NOMSG (Inputs.size () == 1 );
10241022
10251023 // Expected values size is doubled. In the first half we store the
@@ -1089,7 +1087,7 @@ OP_3(OpType::Select, StrictValidation, (static_cast<bool>(A) ? B : C));
10891087 template <typename T> struct Op <OP, T, 1 > : StrictValidation {}; \
10901088 template <typename T> struct ExpectedBuilder <OP, T> { \
10911089 static std::vector<HLSLBool_t> \
1092- buildExpected (Op<OP, T, 1 > &, const InputSets<T> &Inputs, uint16_t ) { \
1090+ buildExpected (Op<OP, T, 1 > &, const InputSets<T> &Inputs) { \
10931091 const bool Res = STDFUNC (Inputs[0 ].begin (), Inputs[0 ].end (), \
10941092 [](T A) { return A != static_cast <T>(0 ); }); \
10951093 return std::vector<HLSLBool_t>{Res}; \
@@ -1115,9 +1113,7 @@ template <typename T> struct ExpectedBuilder<OpType::Dot, T> {
11151113 // worst-case sequence, then summing the per-step epsilons to produce a
11161114 // conservative error tolerance for the entire Dot operation.
11171115 static std::vector<T> buildExpected (Op<OpType::Dot, T, 2 > &Op,
1118- const InputSets<T> &Inputs,
1119- uint16_t ScalarInputFlags) {
1120- UNREFERENCED_PARAMETER (ScalarInputFlags);
1116+ const InputSets<T> &Inputs) {
11211117
11221118 std::vector<double > PositiveProducts;
11231119 std::vector<double > NegativeProducts;
@@ -1126,7 +1122,7 @@ template <typename T> struct ExpectedBuilder<OpType::Dot, T> {
11261122
11271123 // Floating point ops have a tolerance of 0.5 ULPs per operation as per the
11281124 // DX spec.
1129- const float ULPTolerance = 0 .5f ;
1125+ const double ULPTolerance = 0.5 ;
11301126
11311127 // Accumulate in fp64 to improve precision.
11321128 double DotProduct = 0.0 ; // computed reference result
@@ -1179,7 +1175,7 @@ template <typename T> struct ExpectedBuilder<OpType::Dot, T> {
11791175};
11801176
11811177template <typename T>
1182- static double computeAbsoluteEpsilon (double A, float ULPTolerance) {
1178+ static double computeAbsoluteEpsilon (double A, double ULPTolerance) {
11831179 DXASSERT ((!isinf (A) && !isnan (A)),
11841180 " Input values should not produce inf or nan results" );
11851181
@@ -1226,30 +1222,6 @@ STRICT_OP_1(OpType::LoadAndStore_DT_SB_SRV, (A));
12261222STRICT_OP_1 (OpType::LoadAndStore_RD_SB_UAV, (A));
12271223STRICT_OP_1 (OpType::LoadAndStore_RD_SB_SRV, (A));
12281224
1229- static double computeAbsoluteEpsilon (double A, float ULPTolerance)
1230- {
1231- if (isinf (A) || isnan (A))
1232- static double computeAbsoluteEpsilon (double A, float ULPTolerance) {
1233- if (isinf (A) || isnan (A))
1234- // None of the existing input values should produce inf or nan results.
1235- DXASSERT_NOMSG (false );
1236-
1237- // ULP is a positive value by definition. So, working with abs(A) simplifies
1238- // our logic for computing ULP in the first place.
1239- A = std::abs (A);
1240-
1241- double ULP = 0.0 ;
1242-
1243- if constexpr (std::is_same_v<T, HLSLHalf_t>)
1244- ULP = HLSLHalf_t::GetULP (A);
1245- else
1246- ULP =
1247- std::nextafter (static_cast <T>(A), std::numeric_limits<T>::infinity ()) -
1248- static_cast <T>(A);
1249-
1250- return ULP * ULPTolerance;
1251- }
1252-
12531225//
12541226// dispatchTest
12551227//
0 commit comments