From 0456de7beada3507830700b7a7ab2833e36285e6 Mon Sep 17 00:00:00 2001 From: Stephanos Ioannidis Date: Wed, 18 Aug 2021 21:50:52 +0900 Subject: [PATCH] tests: lib: cmsis_dsp: common: Add f16 test routines This commit adds the common test and validation routines for the half- precision floating point data. Signed-off-by: Stephanos Ioannidis --- tests/lib/cmsis_dsp/common/math_helper.h | 38 +++++++++- tests/lib/cmsis_dsp/common/test_common.h | 95 +++++++++++++++++++++++- 2 files changed, 130 insertions(+), 3 deletions(-) diff --git a/tests/lib/cmsis_dsp/common/math_helper.h b/tests/lib/cmsis_dsp/common/math_helper.h index 9b259e17b78..356fbd50940 100644 --- a/tests/lib/cmsis_dsp/common/math_helper.h +++ b/tests/lib/cmsis_dsp/common/math_helper.h @@ -39,7 +39,10 @@ #ifndef MATH_HELPER_H #define MATH_HELPER_H -#include "arm_math.h" +#include +#ifdef CONFIG_CMSIS_DSP_FLOAT16 +#include +#endif /** * @brief Calculation of SNR @@ -131,6 +134,39 @@ static inline float arm_snr_f32(const float *pRef, const float *pTest, return SNR; } +#ifdef CONFIG_CMSIS_DSP_FLOAT16 +static inline float arm_snr_f16(const float16_t *pRef, const float16_t *pTest, + uint32_t buffSize) +{ + float EnergySignal = 0.0, EnergyError = 0.0; + uint32_t i; + float SNR; + + for (i = 0; i < buffSize; i++) { + /* Checking for a NAN value in pRef array */ + IFNANRETURNZERO((float)pRef[i]); + + /* Checking for a NAN value in pTest array */ + IFNANRETURNZERO((float)pTest[i]); + + EnergySignal += pRef[i] * pRef[i]; + EnergyError += (pRef[i] - pTest[i]) * (pRef[i] - pTest[i]); + } + + /* Checking for a NAN value in EnergyError */ + IFNANRETURNZERO(EnergyError); + + + SNR = 10 * log10f(EnergySignal / EnergyError); + + /* Checking for a NAN value in SNR */ + IFNANRETURNZERO(SNR); + IFINFINITERETURN(SNR, 100000.0); + + return SNR; +} +#endif /* CONFIG_CMSIS_DSP_FLOAT16 */ + static inline float arm_snr_q63(const q63_t *pRef, const q63_t *pTest, uint32_t buffSize) { diff --git a/tests/lib/cmsis_dsp/common/test_common.h b/tests/lib/cmsis_dsp/common/test_common.h index 36a88088e2c..b5649f8ad5d 100644 --- a/tests/lib/cmsis_dsp/common/test_common.h +++ b/tests/lib/cmsis_dsp/common/test_common.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2020 Stephanos Ioannidis - * Copyright (C) 2010-2020 ARM Limited or its affiliates. All rights reserved. + * Copyright (c) 2021 Stephanos Ioannidis + * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,9 @@ #include #include #include +#ifdef CONFIG_CMSIS_DSP_FLOAT16 +#include +#endif #include "math_helper.h" @@ -96,6 +99,22 @@ static inline bool test_equal_f32( return true; } +#ifdef CONFIG_CMSIS_DSP_FLOAT16 +static inline bool test_equal_f16( + size_t length, const float16_t *a, const float16_t *b) +{ + size_t index; + + for (index = 0; index < length; index++) { + if (a[index] != b[index]) { + return false; + } + } + + return true; +} +#endif /* CONFIG_CMSIS_DSP_FLOAT16 */ + static inline bool test_equal_q63( size_t length, const q63_t *a, const q63_t *b) { @@ -182,6 +201,23 @@ static inline bool test_near_equal_f32( return true; } +#ifdef CONFIG_CMSIS_DSP_FLOAT16 +static inline bool test_near_equal_f16( + size_t length, const float16_t *a, const float16_t *b, + float16_t threshold) +{ + size_t index; + + for (index = 0; index < length; index++) { + if (fabs(a[index] - b[index]) > threshold) { + return false; + } + } + + return true; +} +#endif /* CONFIG_CMSIS_DSP_FLOAT16 */ + static inline bool test_near_equal_q63( size_t length, const q63_t *a, const q63_t *b, q63_t threshold) { @@ -284,6 +320,31 @@ static inline bool test_rel_error_f32( return true; } +#ifdef CONFIG_CMSIS_DSP_FLOAT16 +static inline bool test_rel_error_f16( + size_t length, const float16_t *a, const float16_t *b, + float16_t threshold) +{ + size_t index; + float32_t rel, delta, average; + + for (index = 0; index < length; index++) { + delta = fabs(a[index] - b[index]); + average = (fabs(a[index]) + fabs(b[index])) / 2.0f; + + if (average != 0) { + rel = delta / average; + + if (rel > threshold) { + return false; + } + } + } + + return true; +} +#endif /* CONFIG_CMSIS_DSP_FLOAT16 */ + static inline bool test_close_error_f64( size_t length, const float64_t *ref, const float64_t *val, float64_t abs_threshold, float64_t rel_threshold) @@ -316,6 +377,24 @@ static inline bool test_close_error_f32( return true; } +#ifdef CONFIG_CMSIS_DSP_FLOAT16 +static inline bool test_close_error_f16( + size_t length, const float16_t *ref, const float16_t *val, + float32_t abs_threshold, float32_t rel_threshold) +{ + size_t index; + + for (index = 0; index < length; index++) { + if (fabs(val[index] - ref[index]) > + (abs_threshold + rel_threshold * fabs(ref[index]))) { + return false; + } + } + + return true; +} +#endif /* CONFIG_CMSIS_DSP_FLOAT16 */ + static inline bool test_snr_error_f64( size_t length, const float64_t *a, const float64_t *b, float64_t threshold) @@ -336,6 +415,18 @@ static inline bool test_snr_error_f32( return (snr >= threshold); } +#ifdef CONFIG_CMSIS_DSP_FLOAT16 +static inline bool test_snr_error_f16( + size_t length, const float16_t *a, const float16_t *b, + float32_t threshold) +{ + float32_t snr; + + snr = arm_snr_f16(a, b, length); + return (snr >= threshold); +} +#endif /* CONFIG_CMSIS_DSP_FLOAT16 */ + static inline bool test_snr_error_q63( size_t length, const q63_t *a, const q63_t *b, float32_t threshold) {