From ff6c260a65a1341e96e5cbf60dc492172530002f Mon Sep 17 00:00:00 2001 From: Michele Di Giorgio Date: Mon, 26 Feb 2018 15:22:16 +0000 Subject: COMPMID-945: Fix GEMM CL FP32 mismatch - V2 The approach used in e415fc13 was not correct. Switch to allowing to use an absolute tolerance if the relative tolerance comparison fails. Change-Id: I8d94d2f8edd3e0eb7388d3d8ac3ebfc37790e267 Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/122269 Reviewed-by: Anthony Barbier Tested-by: Jenkins --- tests/validation/CL/GEMM.cpp | 6 ++++-- tests/validation/Validation.h | 31 ++++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/tests/validation/CL/GEMM.cpp b/tests/validation/CL/GEMM.cpp index 6539090fcf..217edf4438 100644 --- a/tests/validation/CL/GEMM.cpp +++ b/tests/validation/CL/GEMM.cpp @@ -49,7 +49,9 @@ namespace validation { namespace { -RelativeTolerance tolerance_f32(0.001f); /**< Tolerance value for comparing reference's output against implementation's output for floating point data types */ +RelativeTolerance tolerance_f32(0.001f); /**< Tolerance value for comparing reference's output against implementation's output for floating point data types */ +constexpr float abs_tolerance_f32( + 0.0001f); /**< Absolute tolerance value for comparing reference's output against implementation's output for floating point data types in case using relative tolerance fails because of small values */ RelativeTolerance tolerance_f16(half(0.2)); /**< Tolerance value for comparing reference's output against implementation's output for floating point data types */ constexpr AbsoluteTolerance tolerance_q(1.0f); /**< Tolerance value for comparing reference's output against implementation's output for fixed point data types */ constexpr float tolerance_num = 0.02f; /**< Tolerance number */ @@ -200,7 +202,7 @@ FIXTURE_DATA_TEST_CASE(RunSmall, CLGEMMFixture, framework::DatasetMode::P FIXTURE_DATA_TEST_CASE(RunLarge, CLGEMMFixture, framework::DatasetMode::NIGHTLY, combine(datasets::LargeGEMMDataset(), framework::dataset::make("DataType", DataType::F32))) { // Validate output - validate(CLAccessor(_target), _reference, tolerance_f32); + validate(CLAccessor(_target), _reference, tolerance_f32, 0.f, abs_tolerance_f32); } TEST_SUITE_END() TEST_SUITE_END() diff --git a/tests/validation/Validation.h b/tests/validation/Validation.h index 651b7e5b3c..506318018d 100644 --- a/tests/validation/Validation.h +++ b/tests/validation/Validation.h @@ -180,7 +180,7 @@ void validate(const arm_compute::PaddingSize &padding, const arm_compute::Paddin * other test cases. */ template > -void validate(const IAccessor &tensor, const SimpleTensor &reference, U tolerance_value = U(), float tolerance_number = 0.f); +void validate(const IAccessor &tensor, const SimpleTensor &reference, U tolerance_value = U(), float tolerance_number = 0.f, float absolute_tolerance_value = 0.f); /** Validate tensors with valid region. * @@ -193,7 +193,7 @@ void validate(const IAccessor &tensor, const SimpleTensor &reference, U toler * other test cases. */ template > -void validate(const IAccessor &tensor, const SimpleTensor &reference, const ValidRegion &valid_region, U tolerance_value = U(), float tolerance_number = 0.f); +void validate(const IAccessor &tensor, const SimpleTensor &reference, const ValidRegion &valid_region, U tolerance_value = U(), float tolerance_number = 0.f, float absolute_tolerance_value = 0.f); /** Validate tensors with valid mask. * @@ -206,7 +206,8 @@ void validate(const IAccessor &tensor, const SimpleTensor &reference, const V * other test cases. */ template > -void validate(const IAccessor &tensor, const SimpleTensor &reference, const SimpleTensor &valid_mask, U tolerance_value = U(), float tolerance_number = 0.f); +void validate(const IAccessor &tensor, const SimpleTensor &reference, const SimpleTensor &valid_mask, U tolerance_value = U(), float tolerance_number = 0.f, + float absolute_tolerance_value = 0.f); /** Validate tensors against constant value. * @@ -317,10 +318,10 @@ struct compare> : public compare_base> }; template -void validate(const IAccessor &tensor, const SimpleTensor &reference, U tolerance_value, float tolerance_number) +void validate(const IAccessor &tensor, const SimpleTensor &reference, U tolerance_value, float tolerance_number, float absolute_tolerance_value) { // Validate with valid region covering the entire shape - validate(tensor, reference, shape_to_valid_region(tensor.shape()), tolerance_value, tolerance_number); + validate(tensor, reference, shape_to_valid_region(tensor.shape()), tolerance_value, tolerance_number, absolute_tolerance_value); } template ::value>::type> @@ -331,7 +332,7 @@ void validate_wrap(const IAccessor &tensor, const SimpleTensor &reference, U } template -void validate(const IAccessor &tensor, const SimpleTensor &reference, const ValidRegion &valid_region, U tolerance_value, float tolerance_number) +void validate(const IAccessor &tensor, const SimpleTensor &reference, const ValidRegion &valid_region, U tolerance_value, float tolerance_number, float absolute_tolerance_value) { int64_t num_mismatches = 0; int64_t num_elements = 0; @@ -365,6 +366,14 @@ void validate(const IAccessor &tensor, const SimpleTensor &reference, const V if(!compare(target_value, reference_value, tolerance_value)) { + if(absolute_tolerance_value != 0.f) + { + const AbsoluteTolerance abs_tolerance(absolute_tolerance_value); + if(compare>(target_value, reference_value, abs_tolerance)) + { + continue; + } + } ARM_COMPUTE_TEST_INFO("id = " << id); ARM_COMPUTE_TEST_INFO("channel = " << c); ARM_COMPUTE_TEST_INFO("target = " << std::setprecision(5) << framework::make_printable(target_value)); @@ -474,7 +483,7 @@ void validate_wrap(const IAccessor &tensor, const SimpleTensor &reference, co } template -void validate(const IAccessor &tensor, const SimpleTensor &reference, const SimpleTensor &valid_mask, U tolerance_value, float tolerance_number) +void validate(const IAccessor &tensor, const SimpleTensor &reference, const SimpleTensor &valid_mask, U tolerance_value, float tolerance_number, float absolute_tolerance_value) { int64_t num_mismatches = 0; int64_t num_elements = 0; @@ -508,6 +517,14 @@ void validate(const IAccessor &tensor, const SimpleTensor &reference, const S if(!compare(target_value, reference_value, tolerance_value)) { + if(absolute_tolerance_value != 0.f) + { + const AbsoluteTolerance abs_tolerance(absolute_tolerance_value); + if(compare>(target_value, reference_value, abs_tolerance)) + { + continue; + } + } ARM_COMPUTE_TEST_INFO("id = " << id); ARM_COMPUTE_TEST_INFO("channel = " << c); ARM_COMPUTE_TEST_INFO("target = " << std::setprecision(5) << framework::make_printable(target_value)); -- cgit v1.2.1