diff options
Diffstat (limited to 'tests/validation/Validation.h')
-rw-r--r-- | tests/validation/Validation.h | 86 |
1 files changed, 84 insertions, 2 deletions
diff --git a/tests/validation/Validation.h b/tests/validation/Validation.h index f220224991..8ed98fbc82 100644 --- a/tests/validation/Validation.h +++ b/tests/validation/Validation.h @@ -235,14 +235,15 @@ void validate_keypoints(T target_first, T target_last, U reference_first, U refe template <typename T> struct compare_base { - compare_base(typename T::value_type target, typename T::value_type reference, T tolerance = T(0)) - : _target{ target }, _reference{ reference }, _tolerance{ tolerance } + compare_base(typename T::value_type target, typename T::value_type reference, T tolerance = T(0), bool wrap_range = false) + : _target{ target }, _reference{ reference }, _tolerance{ tolerance }, _wrap_range{ wrap_range } { } typename T::value_type _target{}; typename T::value_type _reference{}; T _tolerance{}; + bool _wrap_range{}; }; template <typename T> @@ -266,6 +267,12 @@ struct compare<AbsoluteTolerance<U>> : public compare_base<AbsoluteTolerance<U>> using comparison_type = typename std::conditional<std::is_integral<U>::value, int64_t, U>::type; + if(this->_wrap_range) + { + const comparison_type abs_difference(std::abs(static_cast<comparison_type>(this->_target)) - std::abs(static_cast<comparison_type>(this->_reference))); + return abs_difference <= static_cast<comparison_type>(this->_tolerance); + } + const comparison_type abs_difference(std::abs(static_cast<comparison_type>(this->_target) - static_cast<comparison_type>(this->_reference))); return abs_difference <= static_cast<comparison_type>(this->_tolerance); @@ -316,6 +323,13 @@ void validate(const IAccessor &tensor, const SimpleTensor<T> &reference, U toler } template <typename T, typename U> +void validate_wrap(const IAccessor &tensor, const SimpleTensor<T> &reference, U tolerance_value, float tolerance_number) +{ + // Validate with valid region covering the entire shape + validate_wrap(tensor, reference, shape_to_valid_region(tensor.shape()), tolerance_value, tolerance_number); +} + +template <typename T, typename U> void validate(const IAccessor &tensor, const SimpleTensor<T> &reference, const ValidRegion &valid_region, U tolerance_value, float tolerance_number) { int64_t num_mismatches = 0; @@ -376,6 +390,74 @@ void validate(const IAccessor &tensor, const SimpleTensor<T> &reference, const V } } +template <typename T, typename U> +void validate_wrap(const IAccessor &tensor, const SimpleTensor<T> &reference, const ValidRegion &valid_region, U tolerance_value, float tolerance_number) +{ + int64_t num_mismatches = 0; + int64_t num_elements = 0; + + ARM_COMPUTE_EXPECT_EQUAL(tensor.element_size(), reference.element_size(), framework::LogLevel::ERRORS); + ARM_COMPUTE_EXPECT_EQUAL(tensor.data_type(), reference.data_type(), framework::LogLevel::ERRORS); + + if(reference.format() != Format::UNKNOWN) + { + ARM_COMPUTE_EXPECT_EQUAL(tensor.format(), reference.format(), framework::LogLevel::ERRORS); + } + + ARM_COMPUTE_EXPECT_EQUAL(tensor.num_channels(), reference.num_channels(), framework::LogLevel::ERRORS); + ARM_COMPUTE_EXPECT(compare_dimensions(tensor.shape(), reference.shape()), framework::LogLevel::ERRORS); + + const int min_elements = std::min(tensor.num_elements(), reference.num_elements()); + const int min_channels = std::min(tensor.num_channels(), reference.num_channels()); + + // Iterate over all elements within valid region, e.g. U8, S16, RGB888, ... + for(int element_idx = 0; element_idx < min_elements; ++element_idx) + { + const Coordinates id = index2coord(reference.shape(), element_idx); + + if(is_in_valid_region(valid_region, id)) + { + // Iterate over all channels within one element + for(int c = 0; c < min_channels; ++c) + { + const T &target_value = reinterpret_cast<const T *>(tensor(id))[c]; + const T &reference_value = reinterpret_cast<const T *>(reference(id))[c]; + + bool equal = compare<U>(target_value, reference_value, tolerance_value); + + if(!equal) + { + equal = compare<U>(target_value, reference_value, tolerance_value, true); + } + + if(!equal) + { + 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)); + ARM_COMPUTE_TEST_INFO("reference = " << std::setprecision(5) << framework::make_printable(reference_value)); + ARM_COMPUTE_TEST_INFO("tolerance = " << std::setprecision(5) << framework::make_printable(static_cast<typename U::value_type>(tolerance_value))); + framework::ARM_COMPUTE_PRINT_INFO(); + + ++num_mismatches; + } + + ++num_elements; + } + } + } + + if(num_elements > 0) + { + const int64_t absolute_tolerance_number = tolerance_number * num_elements; + const float percent_mismatches = static_cast<float>(num_mismatches) / num_elements * 100.f; + + ARM_COMPUTE_TEST_INFO(num_mismatches << " values (" << std::fixed << std::setprecision(2) << percent_mismatches + << "%) mismatched (maximum tolerated " << std::setprecision(2) << tolerance_number << "%)"); + ARM_COMPUTE_EXPECT(num_mismatches <= absolute_tolerance_number, framework::LogLevel::ERRORS); + } +} + /** Check which keypoints from [first1, last1) are missing in [first2, last2) */ template <typename T, typename U, typename V> std::pair<int64_t, int64_t> compare_keypoints(T first1, T last1, U first2, U last2, V tolerance) |