blob: 033245ab8120c35858199fa0e5478e9e1f7ea923 [file] [log] [blame]
/*
* Copyright (c) 2021 Stephanos Ioannidis <root@stephanos.io>
* Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_TESTS_LIB_CMSIS_DSP_COMMON_TEST_COMMON_H_
#define ZEPHYR_TESTS_LIB_CMSIS_DSP_COMMON_TEST_COMMON_H_
#include <zephyr/ztest.h>
#include <zephyr/kernel.h>
#include <stdlib.h>
#include <arm_math.h>
#ifdef CONFIG_CMSIS_DSP_FLOAT16
#include <arm_math_f16.h>
#endif
#include "math_helper.h"
#define ASSERT_MSG_BUFFER_ALLOC_FAILED "buffer allocation failed"
#define ASSERT_MSG_SNR_LIMIT_EXCEED "signal-to-noise ratio " \
"error limit exceeded"
#define ASSERT_MSG_ABS_ERROR_LIMIT_EXCEED "absolute error limit exceeded"
#define ASSERT_MSG_REL_ERROR_LIMIT_EXCEED "relative error limit exceeded"
#define ASSERT_MSG_ERROR_LIMIT_EXCEED "error limit exceeded"
#define ASSERT_MSG_INCORRECT_COMP_RESULT "incorrect computation result"
#if defined(CONFIG_ZTEST_NEW_API)
#define DEFINE_TEST_VARIANT1(suite, name, variant, a1) \
ZTEST(suite, test_##name##_##variant) \
{ \
test_##name(a1); \
}
#define DEFINE_TEST_VARIANT2(suite, name, variant, a1, a2) \
ZTEST(suite, test_##name##_##variant) \
{ \
test_##name(a1, a2); \
}
#define DEFINE_TEST_VARIANT3(suite, name, variant, a1, a2, a3) \
ZTEST(suite, test_##name##_##variant) \
{ \
test_##name(a1, a2, a3); \
}
#define DEFINE_TEST_VARIANT4(suite, name, variant, a1, a2, a3, a4) \
ZTEST(suite, test_##name##_##variant) \
{ \
test_##name(a1, a2, a3, a4); \
}
#define DEFINE_TEST_VARIANT5(suite, name, variant, a1, a2, a3, a4, a5) \
ZTEST(suite, test_##name##_##variant) \
{ \
test_##name(a1, a2, a3, a4, a5); \
}
#define DEFINE_TEST_VARIANT6(suite, name, variant, a1, a2, a3, a4, a5, a6) \
ZTEST(suite, test_##name##_##variant) \
{ \
test_##name(a1, a2, a3, a4, a5, a6); \
}
#define DEFINE_TEST_VARIANT7(suite, name, variant, a1, a2, a3, a4, a5, a6, a7) \
ZTEST(suite, test_##name##_##variant) \
{ \
test_##name(a1, a2, a3, a4, a5, a6, a7); \
}
#else /* !defined(CONFIG_ZTEST_NEW_API) */
#define DEFINE_TEST_VARIANT1(name, variant, a1) \
static void test_##name##_##variant(void) \
{ \
test_##name(a1); \
}
#define DEFINE_TEST_VARIANT2(name, variant, a1, a2) \
static void test_##name##_##variant(void) \
{ \
test_##name(a1, a2); \
}
#define DEFINE_TEST_VARIANT3(name, variant, a1, a2, a3) \
static void test_##name##_##variant(void) \
{ \
test_##name(a1, a2, a3); \
}
#define DEFINE_TEST_VARIANT4(name, variant, a1, a2, a3, a4) \
static void test_##name##_##variant(void) \
{ \
test_##name(a1, a2, a3, a4); \
}
#define DEFINE_TEST_VARIANT5(name, variant, a1, a2, a3, a4, a5) \
static void test_##name##_##variant(void) \
{ \
test_##name(a1, a2, a3, a4, a5); \
}
#define DEFINE_TEST_VARIANT6(name, variant, a1, a2, a3, a4, a5, a6) \
static void test_##name##_##variant(void) \
{ \
test_##name(a1, a2, a3, a4, a5, a6); \
}
#define DEFINE_TEST_VARIANT7(name, variant, a1, a2, a3, a4, a5, a6, a7) \
static void test_##name##_##variant(void) \
{ \
test_##name(a1, a2, a3, a4, a5, a6, a7); \
}
#endif /* !defined(CONFIG_ZTEST_NEW_API) */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
static inline bool test_equal_f64(
size_t length, const float64_t *a, const float64_t *b)
{
size_t index;
for (index = 0; index < length; index++) {
if (a[index] != b[index]) {
return false;
}
}
return true;
}
static inline bool test_equal_f32(
size_t length, const float32_t *a, const float32_t *b)
{
size_t index;
for (index = 0; index < length; index++) {
if (a[index] != b[index]) {
return false;
}
}
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)
{
size_t index;
for (index = 0; index < length; index++) {
if (a[index] != b[index]) {
return false;
}
}
return true;
}
static inline bool test_equal_q31(
size_t length, const q31_t *a, const q31_t *b)
{
size_t index;
for (index = 0; index < length; index++) {
if (a[index] != b[index]) {
return false;
}
}
return true;
}
static inline bool test_equal_q15(
size_t length, const q15_t *a, const q15_t *b)
{
size_t index;
for (index = 0; index < length; index++) {
if (a[index] != b[index]) {
return false;
}
}
return true;
}
static inline bool test_equal_q7(
size_t length, const q7_t *a, const q7_t *b)
{
size_t index;
for (index = 0; index < length; index++) {
if (a[index] != b[index]) {
return false;
}
}
return true;
}
static inline bool test_near_equal_f64(
size_t length, const float64_t *a, const float64_t *b,
float64_t threshold)
{
size_t index;
for (index = 0; index < length; index++) {
if (fabs(a[index] - b[index]) > threshold) {
return false;
}
}
return true;
}
static inline bool test_near_equal_f32(
size_t length, const float32_t *a, const float32_t *b,
float32_t threshold)
{
size_t index;
for (index = 0; index < length; index++) {
if (fabsf(a[index] - b[index]) > threshold) {
return false;
}
}
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 (fabsf((float)a[index] - (float)b[index]) > (float)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)
{
size_t index;
for (index = 0; index < length; index++) {
if (llabs(a[index] - b[index]) > threshold) {
return false;
}
}
return true;
}
static inline bool test_near_equal_q31(
size_t length, const q31_t *a, const q31_t *b, q31_t threshold)
{
size_t index;
for (index = 0; index < length; index++) {
if (abs(a[index] - b[index]) > threshold) {
return false;
}
}
return true;
}
static inline bool test_near_equal_q15(
size_t length, const q15_t *a, const q15_t *b, q15_t threshold)
{
size_t index;
for (index = 0; index < length; index++) {
if (abs(a[index] - b[index]) > threshold) {
return false;
}
}
return true;
}
static inline bool test_near_equal_q7(
size_t length, const q7_t *a, const q7_t *b, q7_t threshold)
{
size_t index;
for (index = 0; index < length; index++) {
if (abs(a[index] - b[index]) > threshold) {
return false;
}
}
return true;
}
static inline bool test_rel_error_f64(
size_t length, const float64_t *a, const float64_t *b,
float64_t threshold)
{
size_t index;
float64_t rel, delta, average;
for (index = 0; index < length; index++) {
delta = fabs(a[index] - b[index]);
average = (fabs(a[index]) + fabs(b[index])) / 2.0;
if (average != 0) {
rel = delta / average;
if (rel > threshold) {
return false;
}
}
}
return true;
}
static inline bool test_rel_error_f32(
size_t length, const float32_t *a, const float32_t *b,
float32_t threshold)
{
size_t index;
float32_t rel, delta, average;
for (index = 0; index < length; index++) {
delta = fabsf(a[index] - b[index]);
average = (fabsf(a[index]) + fabsf(b[index])) / 2.0f;
if (average != 0) {
rel = delta / average;
if (rel > threshold) {
return false;
}
}
}
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 = fabsf((float)a[index] - (float)b[index]);
average = (fabsf((float)a[index]) + fabsf((float)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)
{
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;
}
static inline bool test_close_error_f32(
size_t length, const float32_t *ref, const float32_t *val,
float32_t abs_threshold, float32_t rel_threshold)
{
size_t index;
for (index = 0; index < length; index++) {
if (fabsf(val[index] - ref[index]) >
(abs_threshold + rel_threshold * fabsf(ref[index]))) {
return false;
}
}
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 (fabsf((float)val[index] - (float)ref[index]) >
(abs_threshold + rel_threshold * fabsf((float)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)
{
float64_t snr;
snr = arm_snr_f64(a, b, length);
return (snr >= threshold);
}
static inline bool test_snr_error_f32(
size_t length, const float32_t *a, const float32_t *b,
float32_t threshold)
{
float32_t snr;
snr = arm_snr_f32(a, b, length);
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)
{
float32_t snr;
snr = arm_snr_q63(a, b, length);
return (snr >= threshold);
}
static inline bool test_snr_error_q31(
size_t length, const q31_t *a, const q31_t *b, float32_t threshold)
{
float32_t snr;
snr = arm_snr_q31(a, b, length);
return (snr >= threshold);
}
static inline bool test_snr_error_q15(
size_t length, const q15_t *a, const q15_t *b, float32_t threshold)
{
float32_t snr;
snr = arm_snr_q15(a, b, length);
return (snr >= threshold);
}
static inline bool test_snr_error_q7(
size_t length, const q7_t *a, const q7_t *b, float32_t threshold)
{
float32_t snr;
snr = arm_snr_q7(a, b, length);
return (snr >= threshold);
}
#pragma GCC diagnostic pop
#endif /* ZEPHYR_TESTS_LIB_CMSIS_DSP_COMMON_TEST_COMMON_H_ */