Skip to content

Commit

Permalink
Test: Cmocka: Add unit test for sofm_exp_fixed() function
Browse files Browse the repository at this point in the history
There was no unit test for the function, so it is added. The
pass criteria is tuned for current implementation to just
pass. It is useful to verify the next changes to optimize
the function.

Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
  • Loading branch information
singalsu committed Oct 31, 2024
1 parent 2f4efa5 commit cf62b65
Showing 1 changed file with 88 additions and 7 deletions.
95 changes: 88 additions & 7 deletions test/cmocka/src/math/arithmetic/exponential.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Author: Shriram Shastry <malladi.sastry@linux.intel.com>
*/

#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
Expand All @@ -23,9 +24,14 @@

#define ULP_TOLERANCE 5.60032793
#define ULP_SCALE 0.0000999999999749
#define NUMTESTSAMPLES 256
#define REL_DELTA_TOLERANCE 0.06
#define ABS_DELTA_TOLERANCE 0.16

static void gen_exp_testvector(double a, double b, double *r, int32_t *b_i);
#define NUMTESTSAMPLES_TEST1 256
#define NUMTESTSAMPLES_TEST2 256

static void gen_exp_testvector_q28(double a, double b, double *r, int32_t *b_i);
static void gen_exp_testvector_q27(double a, double b, double *r, int32_t *b_i);

/* testvector in Q4.28, -5 to +5 */
/*
Expand All @@ -35,7 +41,7 @@ static void gen_exp_testvector(double a, double b, double *r, int32_t *b_i);
* int32_t *b_i
* Return Type :void
*/
static void gen_exp_testvector(double a, double b, double *r, int32_t *b_i)
static void gen_exp_testvector_q28(double a, double b, double *r, int32_t *b_i)
{
double a2;
double b2;
Expand All @@ -52,7 +58,7 @@ static void gen_exp_testvector(double a, double b, double *r, int32_t *b_i)
*b_i = INT32_MAX;
}

static void test_math_arithmetic_exponential_fixed(void **state)
static void test_function_sofm_exp_int32(void **state)
{
(void)state;

Expand All @@ -66,8 +72,8 @@ static void test_math_arithmetic_exponential_fixed(void **state)
int32_t b_i;

srand((unsigned int)time(NULL));
for (i = 0; i < NUMTESTSAMPLES; i++) {
gen_exp_testvector(a_tmp, b_tmp, &r, &b_i);
for (i = 0; i < NUMTESTSAMPLES_TEST1; i++) {
gen_exp_testvector_q28(a_tmp, b_tmp, &r, &b_i);
a_i = (double)b_i / (1 << 28);

accum = sofm_exp_int32(b_i);
Expand All @@ -81,10 +87,85 @@ static void test_math_arithmetic_exponential_fixed(void **state)
}
}

/* testvector in Q5.27 */
/*
* Arguments :double a
* double b
* double *r
* int32_t *b_i
* Return Type :void
*/
static void gen_exp_testvector_q27(double a, double b, double *r, int32_t *value)
{
double rs;
int64_t irs;

*r = (double)rand() / (double)(RAND_MAX / (b - a)) + a;
rs = *r * 134217728.0;
irs = (int64_t)round(rs);
if (irs > INT32_MAX)
*value = INT32_MAX;
else if (irs < INT32_MIN)
*value = INT32_MIN;
else
*value = (int32_t)irs;
}

static void test_function_sofm_exp_fixed(void **state)
{
(void)state;

double fvalue, fexp_value, ref_exp_value;
double rel_delta, abs_delta;
double arg_min = -11.5;
double arg_max = 7.6245;
double rel_delta_max = 0;
double abs_delta_max = 0;
double r;
int32_t ivalue, iexp_value;
int i;

srand((unsigned int)time(NULL));
for (i = 0; i < NUMTESTSAMPLES_TEST2; i++) {
gen_exp_testvector_q27(arg_min, arg_max, &r, &ivalue);
iexp_value = sofm_exp_fixed(ivalue);
fvalue = (double)ivalue / (1 << 27); /* Q5.27 */
fexp_value = (double)iexp_value / (1 << 20); /* Q12.20 */
/* printf("val = %10.6f, exp = %12.6f\n", fvalue, fexp_value); */
ref_exp_value = exp(fvalue);
rel_delta = fabs((ref_exp_value - fexp_value) / ref_exp_value);
if (rel_delta > rel_delta_max)
rel_delta_max = rel_delta;

if (rel_delta > REL_DELTA_TOLERANCE) {
printf("%s: Relative error %g exceeds limit %g, input %g output %g.\n",
__func__, rel_delta, REL_DELTA_TOLERANCE, fvalue, fexp_value);
assert_true(false);
}

abs_delta = fabs(ref_exp_value - fexp_value);
if (abs_delta > ABS_DELTA_TOLERANCE) {
printf("%s: Absolute error %g exceeds limit %g, input %g output %g.\n",
__func__, abs_delta, ABS_DELTA_TOLERANCE, fvalue, fexp_value);
assert_true(false);
}

if (rel_delta > rel_delta_max)
rel_delta_max = rel_delta;

if (abs_delta > abs_delta_max)
abs_delta_max = abs_delta;
}

printf("%s: Relative max error was %.6f.\n", __func__, rel_delta_max);
printf("%s: Absolute max error was %.6f.\n", __func__, abs_delta_max);
}

int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_math_arithmetic_exponential_fixed)
cmocka_unit_test(test_function_sofm_exp_int32),
cmocka_unit_test(test_function_sofm_exp_fixed),
};

cmocka_set_message_output(CM_OUTPUT_TAP);
Expand Down

0 comments on commit cf62b65

Please sign in to comment.