diff --git a/.gitignore b/.gitignore index d53754d..d1129b5 100644 --- a/.gitignore +++ b/.gitignore @@ -82,6 +82,7 @@ Makefile.in /tests/*.log /tests/*.sum /tests/*/check_p_* +!/tests/*/check_p_*.h !/tests/*/check_p_*.c /tests/*/*.log diff --git a/README.md b/README.md index e728a03..7f783ff 100644 --- a/README.md +++ b/README.md @@ -226,7 +226,8 @@ FUNCTION | NOTES [p_log10()](src/math/p_log10.c) | denary log [p_max()](src/math/p_max.c) | finds max val [p_min()](src/math/p_min.c) | finds min val -[p_mean()](src/math/p_mean.c) | mean operation +[p_minmax()](src/math/p_minmax.c) | finds min and max val +[p_mean()](src/math/p_mean.c) | mean operation [p_median()](src/math/p_median.c) | finds middle value [p_mode()](src/math/p_mode.c) | finds most common value [p_mul()](src/math/p_mul.c) | multiplication diff --git a/benchmark/math/Makemodule.am b/benchmark/math/Makemodule.am index c20a839..22374f8 100644 --- a/benchmark/math/Makemodule.am +++ b/benchmark/math/Makemodule.am @@ -30,6 +30,7 @@ benchmark/math/bench_p_max_f32 \ benchmark/math/bench_p_mean_f32 \ benchmark/math/bench_p_median_f32 \ benchmark/math/bench_p_min_f32 \ +benchmark/math/bench_p_minmax_f32 \ benchmark/math/bench_p_mul_f32 \ benchmark/math/bench_p_popcount_u32 \ benchmark/math/bench_p_popcount_u64 \ @@ -81,6 +82,7 @@ benchmark_math_bench_p_max_f32_SOURCES = benchmark/math/p_max_f32.c benchmark_math_bench_p_mean_f32_SOURCES = benchmark/math/one.c benchmark_math_bench_p_median_f32_SOURCES = benchmark/math/one.c benchmark_math_bench_p_min_f32_SOURCES = benchmark/math/p_min_f32.c +benchmark_math_bench_p_minmax_f32_SOURCES = benchmark/math/p_minmax_f32.c benchmark_math_bench_p_mode_f32_SOURCES = benchmark/math/one.c benchmark_math_bench_p_mul_f32_SOURCES = benchmark/math/one.c benchmark_math_bench_p_popcount_u32_SOURCES = benchmark/math/p_popcount_u32.c @@ -126,6 +128,7 @@ benchmark_math_bench_p_max_f32_CFLAGS = -DFUNCTION=p_max_f32 -DIS_ benchmark_math_bench_p_mean_f32_CFLAGS = -DFUNCTION=p_mean_f32 -DIS_UNARY benchmark_math_bench_p_median_f32_CFLAGS = -DFUNCTION=p_median_f32 -DIS_UNARY benchmark_math_bench_p_min_f32_CFLAGS = -DFUNCTION=p_min_f32 -DIS_UNARY +benchmark_math_bench_p_minmax_f32_CFLAGS = -DFUNCTION=p_minmax_f32 -DIS_UNARY benchmark_math_bench_p_mode_f32_CFLAGS = -DFUNCTION=p_mode_f32 -DIS_UNARY benchmark_math_bench_p_mul_f32_CFLAGS = -DFUNCTION=p_mul_f32 -DIS_BINARY benchmark_math_bench_p_popcount_u32_CFLAGS = -DFUNCTION=p_popcount_u32 -DIS_UNARY @@ -171,6 +174,7 @@ benchmark_math_bench_p_max_f32_LDADD = $(benchmark_math_LDADD) benchmark_math_bench_p_mean_f32_LDADD = $(benchmark_math_LDADD) benchmark_math_bench_p_median_f32_LDADD = $(benchmark_math_LDADD) benchmark_math_bench_p_min_f32_LDADD = $(benchmark_math_LDADD) +benchmark_math_bench_p_minmax_f32_LDADD = $(benchmark_math_LDADD) benchmark_math_bench_p_mode_f32_LDADD = $(benchmark_math_LDADD) benchmark_math_bench_p_mul_f32_LDADD = $(benchmark_math_LDADD) benchmark_math_bench_p_popcount_u32_LDADD = $(benchmark_math_LDADD) diff --git a/benchmark/math/all.c b/benchmark/math/all.c index edef460..742b8e6 100644 --- a/benchmark/math/all.c +++ b/benchmark/math/all.c @@ -42,6 +42,12 @@ void bench_p_min_f32(const struct p_bench_specification *spec) p_min_f32(spec->mem.i1.p_float, spec->mem.i2.p_float, spec->mem.o1.p_int, spec->current_size); } +void bench_p_minmax_f32(const struct p_bench_specification *spec) +{ + p_minmax_f32(spec->mem.i1.p_float, spec->mem.i2.p_float, + spec->mem.i3.p_float, spec->mem.o1.p_int, spec->mem.o2.p_int, + spec->current_size); +} declare_unary(p_mode_f32) declare_binary(p_mul_f32) void bench_p_popcount_u32(const struct p_bench_specification *spec) @@ -104,6 +110,7 @@ const struct p_bench_item benchmark_items[] = { item(p_mean_f32), item(p_median_f32), item(p_min_f32), + item(p_minmax_f32), item(p_mode_f32), item(p_mul_f32), item(p_popcount_u32), diff --git a/benchmark/math/p_minmax_f32.c b/benchmark/math/p_minmax_f32.c new file mode 100644 index 0000000..cb3d0d9 --- /dev/null +++ b/benchmark/math/p_minmax_f32.c @@ -0,0 +1,14 @@ +#include "../bench_tmpl.h" + +void bench_p_minmax_f32(const struct p_bench_specification *spec) +{ + p_minmax_f32(spec->mem.i1.p_float, spec->mem.i2.p_float, + spec->mem.i3.p_float, spec->mem.o1.p_int, spec->mem.o2.p_int, + spec->current_size); +} + +const struct p_bench_item benchmark_items[] = { + item(p_minmax_f32), + + { NULL, NULL } +}; diff --git a/include/pal_math.h b/include/pal_math.h index 832013f..5ea23f0 100644 --- a/include/pal_math.h +++ b/include/pal_math.h @@ -270,6 +270,10 @@ void p_max_f64(const double *a, double *c, int *index, int n); void p_min_f32(const float *a, float *c, int *index, int n); void p_min_f64(const double *a, double *c, int *index, int n); +/*find min and max values and their indices from input vector */ +void p_minmax_f32(const float *a, float *c1, float *c2, int *index1, int *index2, int n); +void p_minmax_f64(const double *a, double *c1, double *c2, int *index1, int *index2, int n); + /* **************************************************************** * Miscellaneous Operations diff --git a/src/math/Makemodule.am b/src/math/Makemodule.am index 750284e..922f9e5 100644 --- a/src/math/Makemodule.am +++ b/src/math/Makemodule.am @@ -32,6 +32,7 @@ src/math/p_max.c \ src/math/p_mean.c \ src/math/p_median.c \ src/math/p_min.c \ +src/math/p_minmax.c \ src/math/p_mode.c \ src/math/p_mul.c \ src/math/p_sin.c \ diff --git a/src/math/p_minmax.c b/src/math/p_minmax.c new file mode 100644 index 0000000..8561796 --- /dev/null +++ b/src/math/p_minmax.c @@ -0,0 +1,45 @@ +#include + +/** + * + * Finds the minimum and maximum values in vector 'a'. Returns the min and max + * values and the indices of the minimum and maximum values. + * + * @param a Pointer to input vector + * + * @param c1 Pointer to output scalar (minimum) + * + * @param c2 Pointer to output scalar (maximum) + * + * @param[out] index1 Pointer to return index of min + * + * @param[out] index2 Pointer to return index of max + * + * @param n Size of 'a' vector. + * + * @return None + * + */ +void PSYM(p_minmax)(const PTYPE *a, PTYPE *c1, PTYPE *c2, int *index1, int *index2, int n) +{ + int pos_min = 0; + int pos_max = 0; + PTYPE min = *a; + PTYPE max = *a; + int i; + + for (i = 1; i < n; i++) { + if (*(a + i) < min) { + pos_min = i; + min = *(a + i); + } + else if (*(a + i) > max) { + pos_max = i; + max = *(a + i); + } + } + *c1 = min; + *c2 = max; + *index1 = pos_min; + *index2 = pos_max; +} diff --git a/tests/math/Makemodule.am b/tests/math/Makemodule.am index 869bc8a..5b42be4 100644 --- a/tests/math/Makemodule.am +++ b/tests/math/Makemodule.am @@ -50,6 +50,7 @@ tests/math/gold/p_max_f32.gold.h \ tests/math/gold/p_mean_f32.gold.h \ tests/math/gold/p_median_f32.gold.h \ tests/math/gold/p_min_f32.gold.h \ +tests/math/gold/p_minmax_f32.gold.h \ tests/math/gold/p_mode_f32.gold.h \ tests/math/gold/p_mul_f32.gold.h \ tests/math/gold/p_pow_f32.gold.h \ @@ -91,6 +92,7 @@ tests/math/gold/p_max_f64.gold.h \ tests/math/gold/p_mean_f64.gold.h \ tests/math/gold/p_median_f64.gold.h \ tests/math/gold/p_min_f64.gold.h \ +tests/math/gold/p_minmax_f64.gold.h \ tests/math/gold/p_mode_f64.gold.h \ tests/math/gold/p_mul_f64.gold.h \ tests/math/gold/p_pow_f64.gold.h \ @@ -154,6 +156,7 @@ tests/math/check_p_max_f32 \ tests/math/check_p_mean_f32 \ tests/math/check_p_median_f32 \ tests/math/check_p_min_f32 \ +tests/math/check_p_minmax_f32 \ tests/math/check_p_mode_f32 \ tests/math/check_p_mul_f32 \ tests/math/check_p_popcount \ @@ -200,6 +203,7 @@ tests/math/check_p_max_f64 \ tests/math/check_p_mean_f64 \ tests/math/check_p_median_f64 \ tests/math/check_p_min_f64 \ +tests/math/check_p_minmax_f64 \ tests/math/check_p_mode_f64 \ tests/math/check_p_mul_f64 \ tests/math/check_p_pow_f64 \ @@ -244,6 +248,7 @@ tests_math_check_p_max_f32_SOURCES = $(CHECK_SCALAR_AND_INDEX) tests/mat tests_math_check_p_mean_f32_SOURCES = $(SIMPLETEST) tests_math_check_p_median_f32_SOURCES = $(SIMPLETEST) tests_math_check_p_min_f32_SOURCES = $(CHECK_SCALAR_AND_INDEX) tests/math/p_min.c +tests_math_check_p_minmax_f32_SOURCES = tests/math/check_p_minmax.c tests/math/check_p_minmax.h tests/math/p_minmax.c tests_math_check_p_mode_f32_SOURCES = $(SIMPLETEST) tests_math_check_p_mul_f32_SOURCES = $(SIMPLETEST) tests_math_check_p_popcount_SOURCES = $(NOTEST) @@ -289,6 +294,7 @@ tests_math_check_p_max_f64_SOURCES = $(tests_math_check_p_max_f32_SOURCE tests_math_check_p_mean_f64_SOURCES = $(tests_math_check_p_mean_f32_SOURCES) tests_math_check_p_median_f64_SOURCES = $(tests_math_check_p_median_f32_SOURCES) tests_math_check_p_min_f64_SOURCES = $(tests_math_check_p_min_f32_SOURCES) +tests_math_check_p_minmax_f64_SOURCES = $(tests_math_check_p_minmax_f32_SOURCES) tests_math_check_p_mode_f64_SOURCES = $(tests_math_check_p_mode_f32_SOURCES) tests_math_check_p_mul_f64_SOURCES = $(tests_math_check_p_mul_f32_SOURCES) tests_math_check_p_pow_f64_SOURCES = $(NOTEST) @@ -331,6 +337,7 @@ tests_math_check_p_max_f32_SOURCES += tests/math/gold/p_max_f32.gold.h tests_math_check_p_mean_f32_SOURCES += tests/math/gold/p_mean_f32.gold.h tests_math_check_p_median_f32_SOURCES += tests/math/gold/p_median_f32.gold.h tests_math_check_p_min_f32_SOURCES += tests/math/gold/p_min_f32.gold.h +tests_math_check_p_minmax_f32_SOURCES += tests/math/gold/p_minmax_f32.gold.h tests_math_check_p_mode_f32_SOURCES += tests/math/gold/p_mode_f32.gold.h tests_math_check_p_mul_f32_SOURCES += tests/math/gold/p_mul_f32.gold.h tests_math_check_p_pow_f32_SOURCES += tests/math/gold/p_pow_f32.gold.h @@ -373,6 +380,7 @@ tests_math_check_p_max_f64_SOURCES += tests/math/gold/p_max_f64.gold.h tests_math_check_p_mean_f64_SOURCES += tests/math/gold/p_mean_f64.gold.h tests_math_check_p_median_f64_SOURCES += tests/math/gold/p_median_f64.gold.h tests_math_check_p_min_f64_SOURCES += tests/math/gold/p_min_f64.gold.h +tests_math_check_p_minmax_f64_SOURCES += tests/math/gold/p_minmax_f64.gold.h tests_math_check_p_mode_f64_SOURCES += tests/math/gold/p_mode_f64.gold.h tests_math_check_p_mul_f64_SOURCES += tests/math/gold/p_mul_f64.gold.h #tests_math_check_p_pow_f64_SOURCES += tests/math/gold/p_pow_f64.gold.h @@ -416,6 +424,7 @@ tests_math_check_p_max_f32_CFLAGS = -DP_FLOAT_TYPE=P_FLOAT_SINGLE -DFUN tests_math_check_p_mean_f32_CFLAGS = -DP_FLOAT_TYPE=P_FLOAT_SINGLE -DFUNCTION=p_mean_f32 -DIS_UNARY -DSCALAR_OUTPUT tests_math_check_p_median_f32_CFLAGS = -DP_FLOAT_TYPE=P_FLOAT_SINGLE -DFUNCTION=p_median_f32 -DIS_UNARY -DSCALAR_OUTPUT tests_math_check_p_min_f32_CFLAGS = -DP_FLOAT_TYPE=P_FLOAT_SINGLE -DFUNCTION=p_min_f32 -DSCALAR_OUTPUT +tests_math_check_p_minmax_f32_CFLAGS = -DP_FLOAT_TYPE=P_FLOAT_SINGLE -DFUNCTION=p_minmax_f32 tests_math_check_p_mode_f32_CFLAGS = -DP_FLOAT_TYPE=P_FLOAT_SINGLE -DFUNCTION=p_mode_f32 -DIS_UNARY -DSCALAR_OUTPUT tests_math_check_p_mul_f32_CFLAGS = -DP_FLOAT_TYPE=P_FLOAT_SINGLE -DFUNCTION=p_mul_f32 -DIS_BINARY tests_math_check_p_popcount_CFLAGS = -DP_FLOAT_TYPE=P_FLOAT_SINGLE -DFUNCTION=p_popcount @@ -462,6 +471,7 @@ tests_math_check_p_max_f64_CFLAGS = -DP_FLOAT_TYPE=P_FLOAT_DOUBLE -DFUN tests_math_check_p_mean_f64_CFLAGS = -DP_FLOAT_TYPE=P_FLOAT_DOUBLE -DFUNCTION=p_mean_f64 -DIS_UNARY -DSCALAR_OUTPUT tests_math_check_p_median_f64_CFLAGS = -DP_FLOAT_TYPE=P_FLOAT_DOUBLE -DFUNCTION=p_median_f64 -DIS_UNARY -DSCALAR_OUTPUT tests_math_check_p_min_f64_CFLAGS = -DP_FLOAT_TYPE=P_FLOAT_DOUBLE -DFUNCTION=p_min_f64 -DSCALAR_OUTPUT +tests_math_check_p_minmax_f64_CFLAGS = -DP_FLOAT_TYPE=P_FLOAT_DOUBLE -DFUNCTION=p_minmax_f64 tests_math_check_p_mode_f64_CFLAGS = -DP_FLOAT_TYPE=P_FLOAT_DOUBLE -DFUNCTION=p_mode_f64 -DIS_UNARY -DSCALAR_OUTPUT tests_math_check_p_mul_f64_CFLAGS = -DP_FLOAT_TYPE=P_FLOAT_DOUBLE -DFUNCTION=p_mul_f64 -DIS_BINARY # Override fault tolerance for p_pow_f64 @@ -506,6 +516,7 @@ tests_math_check_p_max_f32_CPPFLAGS = $(CPPFLAGS_tests_math) tests_math_check_p_mean_f32_CPPFLAGS = $(CPPFLAGS_tests_math) tests_math_check_p_median_f32_CPPFLAGS = $(CPPFLAGS_tests_math) tests_math_check_p_min_f32_CPPFLAGS = $(CPPFLAGS_tests_math) +tests_math_check_p_minmax_f32_CPPFLAGS = $(CPPFLAGS_tests_math) tests_math_check_p_mode_f32_CPPFLAGS = $(CPPFLAGS_tests_math) tests_math_check_p_mul_f32_CPPFLAGS = $(CPPFLAGS_tests_math) tests_math_check_p_popcount_CPPFLAGS = $(CPPFLAGS_tests_math) @@ -551,6 +562,7 @@ tests_math_check_p_max_f64_CPPFLAGS = $(CPPFLAGS_tests_math) tests_math_check_p_mean_f64_CPPFLAGS = $(CPPFLAGS_tests_math) tests_math_check_p_median_f64_CPPFLAGS = $(CPPFLAGS_tests_math) tests_math_check_p_min_f64_CPPFLAGS = $(CPPFLAGS_tests_math) +tests_math_check_p_minmax_f64_CPPFLAGS = $(CPPFLAGS_tests_math) tests_math_check_p_mode_f64_CPPFLAGS = $(CPPFLAGS_tests_math) tests_math_check_p_mul_f64_CPPFLAGS = $(CPPFLAGS_tests_math) tests_math_check_p_pow_f64_CPPFLAGS = $(CPPFLAGS_tests_math) @@ -594,6 +606,7 @@ tests_math_check_p_max_f32_LDFLAGS = $(LDFLAGS_tests) tests_math_check_p_mean_f32_LDFLAGS = $(LDFLAGS_tests) tests_math_check_p_median_f32_LDFLAGS = $(LDFLAGS_tests) tests_math_check_p_min_f32_LDFLAGS = $(LDFLAGS_tests) +tests_math_check_p_minmax_f32_LDFLAGS = $(LDFLAGS_tests) tests_math_check_p_mode_f32_LDFLAGS = $(LDFLAGS_tests_large) tests_math_check_p_mul_f32_LDFLAGS = $(LDFLAGS_tests) tests_math_check_p_popcount_LDFLAGS = $(LDFLAGS_tests) @@ -639,6 +652,7 @@ tests_math_check_p_max_f64_LDFLAGS = $(LDFLAGS_tests) tests_math_check_p_mean_f64_LDFLAGS = $(LDFLAGS_tests) tests_math_check_p_median_f64_LDFLAGS = $(LDFLAGS_tests) tests_math_check_p_min_f64_LDFLAGS = $(LDFLAGS_tests) +tests_math_check_p_minmax_f64_LDFLAGS = $(LDFLAGS_tests) tests_math_check_p_mode_f64_LDFLAGS = $(LDFLAGS_tests_large) tests_math_check_p_mul_f64_LDFLAGS = $(LDFLAGS_tests) tests_math_check_p_pow_f64_LDFLAGS = $(LDFLAGS_tests) @@ -682,6 +696,7 @@ tests_math_check_p_max_f32_LDADD = $(LDADD_tests) tests_math_check_p_mean_f32_LDADD = $(LDADD_tests) tests_math_check_p_median_f32_LDADD = $(LDADD_tests) tests_math_check_p_min_f32_LDADD = $(LDADD_tests) +tests_math_check_p_minmax_f32_LDADD = $(LDADD_tests) tests_math_check_p_mode_f32_LDADD = $(LDADD_tests) tests_math_check_p_mul_f32_LDADD = $(LDADD_tests) tests_math_check_p_popcount_LDADD = $(LDADD_tests) @@ -727,6 +742,7 @@ tests_math_check_p_max_f64_LDADD = $(LDADD_tests) tests_math_check_p_mean_f64_LDADD = $(LDADD_tests) tests_math_check_p_median_f64_LDADD = $(LDADD_tests) tests_math_check_p_min_f64_LDADD = $(LDADD_tests) +tests_math_check_p_minmax_f64_LDADD = $(LDADD_tests) tests_math_check_p_mode_f64_LDADD = $(LDADD_tests) tests_math_check_p_mul_f64_LDADD = $(LDADD_tests) tests_math_check_p_pow_f64_LDADD = $(LDADD_tests) diff --git a/tests/math/check_p_minmax.c b/tests/math/check_p_minmax.c new file mode 100644 index 0000000..fc83296 --- /dev/null +++ b/tests/math/check_p_minmax.c @@ -0,0 +1,169 @@ +/* p_minmax has a different signature from all other math functions in the + PAL. It has 1 input vector and 2 output scalars and 2 output indices. As a + result, it needs a distinct test infrastructure. */ + +#include +#include +#include +#include +#include +#include + +#include +/* TODO: This relative path include is fragile */ +#include "../src/base/pal_base_private.h" +#include + +#include "check_p_minmax.h" + +#ifndef FUNCTION +#error FUNCTION must be defined +#endif + +#define GOLD_PATH XSTRING(gold/FUNCTION.gold.h) +#include GOLD_PATH + +PTYPE *ai, *result1, *result2; +int *resultIndex1, *resultIndex2; + +struct gold *gold = builtin_gold; +size_t gold_size = ARRAY_SIZE(builtin_gold); + +/* For detecting erroneous overwrites */ +#define OUTPUT_END_MARKER ((PTYPE)60189537703610376.0) + +bool equals(PTYPE x, PTYPE y) +{ + PTYPE err; + + if (fabs(x - y) <= EPSILON_MAX) + return true; + + if (fabs(x) > fabs(y)) + err = fabs((x - y) / x); + else + err = fabs((x - y) / y); + + return err <= EPSILON_RELMAX; +} + +int setup(struct ut_suite *suite) +{ + size_t i; + + (void) suite; + + ai = calloc(gold_size, sizeof(PTYPE)); + + /* Allocate one extra element for res and add end marker so overwrites can + * be detected */ + result1 = calloc(2, sizeof(PTYPE)); + result1[1] = OUTPUT_END_MARKER; + resultIndex1 = calloc(1, sizeof(int)); + + result2 = calloc(2, sizeof(PTYPE)); + result2[1] = OUTPUT_END_MARKER; + resultIndex2 = calloc(1, sizeof(int)); + + for (i = 0; i < gold_size; i++) { + ai[i] = gold[i].ai; + } + + return 0; +} + +int teardown(struct ut_suite *suite) +{ + free(ai); + free(result1); + free(result2); + free(resultIndex1); + free(resultIndex2); + + return 0; +} + +int tc_against_gold_e(struct ut_suite *suite, struct ut_tcase *tcase) +{ + /* Run FUNCTION against gold input here so results are available + * for all test cases. */ + FUNCTION(ai, result1, result2, resultIndex1, resultIndex2, gold_size); + + return 0; +} + +int tc_against_gold_v(struct ut_suite *suite, struct ut_tcase *tcase) +{ + ut_assert_msg(equals(result1[0], gold[0].gold1), + "%s: result 1: %f != %f", + XSTRING(FUNCTION), result1[0], gold[0].gold1); + + ut_assert_msg(equals(result2[0], gold[0].gold2), + "%s: result 2: %f != %f", + XSTRING(FUNCTION), result2[0], gold[0].gold2); + + ut_assert_msg(result1[1] == OUTPUT_END_MARKER, + "Output end marker was overwritten"); + + ut_assert_msg(result2[1] == OUTPUT_END_MARKER, + "Output end marker was overwritten"); + + // Skip checking the index + + return 0; +} + +int tc_against_ref_v(struct ut_suite *suite, struct ut_tcase *tcase) +{ + if (gold_size == 0) + return 0; + + PTYPE reference1, reference2; + int indexOfReference1, indexOfReference2; + generate_ref(&reference1, &reference2, + &indexOfReference1, &indexOfReference2, gold_size); + + ut_assert_msg(equals(reference1, gold[0].gold1), + "%s: result 1: %f != %f", + XSTRING(FUNCTION), result1[0], reference1); + + ut_assert_msg(equals(reference2, gold[0].gold2), + "%s: result 2: %f != %f", + XSTRING(FUNCTION), result2[0], reference2); + + ut_assert_msg(resultIndex1[0] == indexOfReference1, + "%s: index 1: %d != %d", + XSTRING(FUNCTION), resultIndex1[0], indexOfReference1); + + ut_assert_msg(resultIndex2[0] == indexOfReference2, + "%s: index 2: %d != %d", + XSTRING(FUNCTION), resultIndex2[0], indexOfReference2); + + return 0; +} + +DECLARE_UT_TCASE(tc_against_gold, tc_against_gold_e, tc_against_gold_v, NULL); +DECLARE_UT_TCASE(tc_against_ref, NULL, tc_against_ref_v, NULL); + +DECLARE_UT_TCASE_LIST(tcases, &tc_against_gold, &tc_against_ref); + +#define FUNCTION_SUITE XCONCAT2(FUNCTION,_suite) +DECLARE_UT_SUITE(FUNCTION_SUITE, setup, teardown, false, tcases, NULL); + +int main(int argc, char *argv[]) +{ + int ret; + char buf[1024] = { 0 }; + + struct ut_suite *suite; + + suite = &FUNCTION_SUITE; + + ret = ut_run(suite); + + ut_report(buf, ARRAY_SIZE(buf), suite, true); + + printf("%s", buf); + + return ret; +} diff --git a/tests/math/check_p_minmax.h b/tests/math/check_p_minmax.h new file mode 100644 index 0000000..c0fe149 --- /dev/null +++ b/tests/math/check_p_minmax.h @@ -0,0 +1,31 @@ +#pragma once +#include +#include +#include + +/* Max allowed diff against expected value */ +#ifndef EPSILON_MAX +#define EPSILON_MAX ((PTYPE)0.001) +#endif +#ifndef EPSILON_RELMAX +#define EPSILON_RELMAX ((PTYPE)0.00001) +#endif + +struct gold { + PTYPE ai; + PTYPE bi; + PTYPE res; + PTYPE gold1; + PTYPE gold2; +}; + +extern PTYPE *ai, *result1, *result2; +extern int *resultIndex1, *resultIndex2; + +/* Functions that can be overridden by individual tests */ + +/* Compare two values */ +bool compare(PTYPE x, PTYPE y); + +/* Needs to be implemented by tests that define FUNCTION */ +void generate_ref(PTYPE *outValue1, PTYPE *outValue2, int *outIndex1, int *outIndex2, size_t n); diff --git a/tests/math/check_scalar_and_index.c b/tests/math/check_scalar_and_index.c index d7f8ecf..3cbd675 100644 --- a/tests/math/check_scalar_and_index.c +++ b/tests/math/check_scalar_and_index.c @@ -88,11 +88,9 @@ int tc_against_gold_e(struct ut_suite *suite, struct ut_tcase *tcase) int tc_against_gold_v(struct ut_suite *suite, struct ut_tcase *tcase) { - size_t i; - ut_assert_msg(equals(result[0], gold[0].gold), - "p_max: max: %f != %f", - result[0], gold[0].gold); + "%s: result: %f != %f", + XSTRING(FUNCTION), result[0], gold[0].gold); ut_assert_msg(result[1] == OUTPUT_END_MARKER, "Output end marker was overwritten"); @@ -104,7 +102,6 @@ int tc_against_gold_v(struct ut_suite *suite, struct ut_tcase *tcase) int tc_against_ref_v(struct ut_suite *suite, struct ut_tcase *tcase) { - int i; if (gold_size == 0) return 0; diff --git a/tests/math/gold/p_minmax_f32.dat b/tests/math/gold/p_minmax_f32.dat new file mode 100644 index 0000000..e80730c --- /dev/null +++ b/tests/math/gold/p_minmax_f32.dat @@ -0,0 +1,100 @@ +0.96471,0.00000,0.00000,0.01058,0.99850 +0.40522,0.00000,0.00000,0.00000,0.00000 +0.81190,0.00000,0.00000,0.00000,0.00000 +0.21345,0.00000,0.00000,0.00000,0.00000 +0.64648,0.00000,0.00000,0.00000,0.00000 +0.74434,0.00000,0.00000,0.00000,0.00000 +0.08103,0.00000,0.00000,0.00000,0.00000 +0.71016,0.00000,0.00000,0.00000,0.00000 +0.73774,0.00000,0.00000,0.00000,0.00000 +0.48865,0.00000,0.00000,0.00000,0.00000 +0.11629,0.00000,0.00000,0.00000,0.00000 +0.29966,0.00000,0.00000,0.00000,0.00000 +0.73373,0.00000,0.00000,0.00000,0.00000 +0.32525,0.00000,0.00000,0.00000,0.00000 +0.80294,0.00000,0.00000,0.00000,0.00000 +0.34027,0.00000,0.00000,0.00000,0.00000 +0.29447,0.00000,0.00000,0.00000,0.00000 +0.18887,0.00000,0.00000,0.00000,0.00000 +0.75922,0.00000,0.00000,0.00000,0.00000 +0.43127,0.00000,0.00000,0.00000,0.00000 +0.14393,0.00000,0.00000,0.00000,0.00000 +0.45588,0.00000,0.00000,0.00000,0.00000 +0.35222,0.00000,0.00000,0.00000,0.00000 +0.45009,0.00000,0.00000,0.00000,0.00000 +0.57549,0.00000,0.00000,0.00000,0.00000 +0.88188,0.00000,0.00000,0.00000,0.00000 +0.24708,0.00000,0.00000,0.00000,0.00000 +0.68722,0.00000,0.00000,0.00000,0.00000 +0.26866,0.00000,0.00000,0.00000,0.00000 +0.45450,0.00000,0.00000,0.00000,0.00000 +0.52732,0.00000,0.00000,0.00000,0.00000 +0.87144,0.00000,0.00000,0.00000,0.00000 +0.64022,0.00000,0.00000,0.00000,0.00000 +0.24929,0.00000,0.00000,0.00000,0.00000 +0.32390,0.00000,0.00000,0.00000,0.00000 +0.93879,0.00000,0.00000,0.00000,0.00000 +0.95617,0.00000,0.00000,0.00000,0.00000 +0.35153,0.00000,0.00000,0.00000,0.00000 +0.63724,0.00000,0.00000,0.00000,0.00000 +0.41246,0.00000,0.00000,0.00000,0.00000 +0.79963,0.00000,0.00000,0.00000,0.00000 +0.39507,0.00000,0.00000,0.00000,0.00000 +0.08591,0.00000,0.00000,0.00000,0.00000 +0.45585,0.00000,0.00000,0.00000,0.00000 +0.56320,0.00000,0.00000,0.00000,0.00000 +0.92693,0.00000,0.00000,0.00000,0.00000 +0.85905,0.00000,0.00000,0.00000,0.00000 +0.62786,0.00000,0.00000,0.00000,0.00000 +0.68030,0.00000,0.00000,0.00000,0.00000 +0.19151,0.00000,0.00000,0.00000,0.00000 +0.80966,0.00000,0.00000,0.00000,0.00000 +0.84018,0.00000,0.00000,0.00000,0.00000 +0.51889,0.00000,0.00000,0.00000,0.00000 +0.99850,0.00000,0.00000,0.00000,0.00000 +0.72458,0.00000,0.00000,0.00000,0.00000 +0.93294,0.00000,0.00000,0.00000,0.00000 +0.47115,0.00000,0.00000,0.00000,0.00000 +0.93411,0.00000,0.00000,0.00000,0.00000 +0.15654,0.00000,0.00000,0.00000,0.00000 +0.57602,0.00000,0.00000,0.00000,0.00000 +0.01058,0.00000,0.00000,0.00000,0.00000 +0.71613,0.00000,0.00000,0.00000,0.00000 +0.82687,0.00000,0.00000,0.00000,0.00000 +0.71104,0.00000,0.00000,0.00000,0.00000 +0.21758,0.00000,0.00000,0.00000,0.00000 +0.47417,0.00000,0.00000,0.00000,0.00000 +0.74419,0.00000,0.00000,0.00000,0.00000 +0.12838,0.00000,0.00000,0.00000,0.00000 +0.76381,0.00000,0.00000,0.00000,0.00000 +0.62480,0.00000,0.00000,0.00000,0.00000 +0.52175,0.00000,0.00000,0.00000,0.00000 +0.70593,0.00000,0.00000,0.00000,0.00000 +0.74609,0.00000,0.00000,0.00000,0.00000 +0.89665,0.00000,0.00000,0.00000,0.00000 +0.04927,0.00000,0.00000,0.00000,0.00000 +0.64255,0.00000,0.00000,0.00000,0.00000 +0.57977,0.00000,0.00000,0.00000,0.00000 +0.76592,0.00000,0.00000,0.00000,0.00000 +0.17153,0.00000,0.00000,0.00000,0.00000 +0.16770,0.00000,0.00000,0.00000,0.00000 +0.77164,0.00000,0.00000,0.00000,0.00000 +0.88195,0.00000,0.00000,0.00000,0.00000 +0.20855,0.00000,0.00000,0.00000,0.00000 +0.78977,0.00000,0.00000,0.00000,0.00000 +0.59706,0.00000,0.00000,0.00000,0.00000 +0.38240,0.00000,0.00000,0.00000,0.00000 +0.95845,0.00000,0.00000,0.00000,0.00000 +0.47646,0.00000,0.00000,0.00000,0.00000 +0.88036,0.00000,0.00000,0.00000,0.00000 +0.15826,0.00000,0.00000,0.00000,0.00000 +0.90522,0.00000,0.00000,0.00000,0.00000 +0.90496,0.00000,0.00000,0.00000,0.00000 +0.41028,0.00000,0.00000,0.00000,0.00000 +0.55725,0.00000,0.00000,0.00000,0.00000 +0.65521,0.00000,0.00000,0.00000,0.00000 +0.59359,0.00000,0.00000,0.00000,0.00000 +0.21998,0.00000,0.00000,0.00000,0.00000 +0.09618,0.00000,0.00000,0.00000,0.00000 +0.27289,0.00000,0.00000,0.00000,0.00000 +0.75328,0.00000,0.00000,0.00000,0.00000 diff --git a/tests/math/gold/p_minmax_f64.dat b/tests/math/gold/p_minmax_f64.dat new file mode 100644 index 0000000..e80730c --- /dev/null +++ b/tests/math/gold/p_minmax_f64.dat @@ -0,0 +1,100 @@ +0.96471,0.00000,0.00000,0.01058,0.99850 +0.40522,0.00000,0.00000,0.00000,0.00000 +0.81190,0.00000,0.00000,0.00000,0.00000 +0.21345,0.00000,0.00000,0.00000,0.00000 +0.64648,0.00000,0.00000,0.00000,0.00000 +0.74434,0.00000,0.00000,0.00000,0.00000 +0.08103,0.00000,0.00000,0.00000,0.00000 +0.71016,0.00000,0.00000,0.00000,0.00000 +0.73774,0.00000,0.00000,0.00000,0.00000 +0.48865,0.00000,0.00000,0.00000,0.00000 +0.11629,0.00000,0.00000,0.00000,0.00000 +0.29966,0.00000,0.00000,0.00000,0.00000 +0.73373,0.00000,0.00000,0.00000,0.00000 +0.32525,0.00000,0.00000,0.00000,0.00000 +0.80294,0.00000,0.00000,0.00000,0.00000 +0.34027,0.00000,0.00000,0.00000,0.00000 +0.29447,0.00000,0.00000,0.00000,0.00000 +0.18887,0.00000,0.00000,0.00000,0.00000 +0.75922,0.00000,0.00000,0.00000,0.00000 +0.43127,0.00000,0.00000,0.00000,0.00000 +0.14393,0.00000,0.00000,0.00000,0.00000 +0.45588,0.00000,0.00000,0.00000,0.00000 +0.35222,0.00000,0.00000,0.00000,0.00000 +0.45009,0.00000,0.00000,0.00000,0.00000 +0.57549,0.00000,0.00000,0.00000,0.00000 +0.88188,0.00000,0.00000,0.00000,0.00000 +0.24708,0.00000,0.00000,0.00000,0.00000 +0.68722,0.00000,0.00000,0.00000,0.00000 +0.26866,0.00000,0.00000,0.00000,0.00000 +0.45450,0.00000,0.00000,0.00000,0.00000 +0.52732,0.00000,0.00000,0.00000,0.00000 +0.87144,0.00000,0.00000,0.00000,0.00000 +0.64022,0.00000,0.00000,0.00000,0.00000 +0.24929,0.00000,0.00000,0.00000,0.00000 +0.32390,0.00000,0.00000,0.00000,0.00000 +0.93879,0.00000,0.00000,0.00000,0.00000 +0.95617,0.00000,0.00000,0.00000,0.00000 +0.35153,0.00000,0.00000,0.00000,0.00000 +0.63724,0.00000,0.00000,0.00000,0.00000 +0.41246,0.00000,0.00000,0.00000,0.00000 +0.79963,0.00000,0.00000,0.00000,0.00000 +0.39507,0.00000,0.00000,0.00000,0.00000 +0.08591,0.00000,0.00000,0.00000,0.00000 +0.45585,0.00000,0.00000,0.00000,0.00000 +0.56320,0.00000,0.00000,0.00000,0.00000 +0.92693,0.00000,0.00000,0.00000,0.00000 +0.85905,0.00000,0.00000,0.00000,0.00000 +0.62786,0.00000,0.00000,0.00000,0.00000 +0.68030,0.00000,0.00000,0.00000,0.00000 +0.19151,0.00000,0.00000,0.00000,0.00000 +0.80966,0.00000,0.00000,0.00000,0.00000 +0.84018,0.00000,0.00000,0.00000,0.00000 +0.51889,0.00000,0.00000,0.00000,0.00000 +0.99850,0.00000,0.00000,0.00000,0.00000 +0.72458,0.00000,0.00000,0.00000,0.00000 +0.93294,0.00000,0.00000,0.00000,0.00000 +0.47115,0.00000,0.00000,0.00000,0.00000 +0.93411,0.00000,0.00000,0.00000,0.00000 +0.15654,0.00000,0.00000,0.00000,0.00000 +0.57602,0.00000,0.00000,0.00000,0.00000 +0.01058,0.00000,0.00000,0.00000,0.00000 +0.71613,0.00000,0.00000,0.00000,0.00000 +0.82687,0.00000,0.00000,0.00000,0.00000 +0.71104,0.00000,0.00000,0.00000,0.00000 +0.21758,0.00000,0.00000,0.00000,0.00000 +0.47417,0.00000,0.00000,0.00000,0.00000 +0.74419,0.00000,0.00000,0.00000,0.00000 +0.12838,0.00000,0.00000,0.00000,0.00000 +0.76381,0.00000,0.00000,0.00000,0.00000 +0.62480,0.00000,0.00000,0.00000,0.00000 +0.52175,0.00000,0.00000,0.00000,0.00000 +0.70593,0.00000,0.00000,0.00000,0.00000 +0.74609,0.00000,0.00000,0.00000,0.00000 +0.89665,0.00000,0.00000,0.00000,0.00000 +0.04927,0.00000,0.00000,0.00000,0.00000 +0.64255,0.00000,0.00000,0.00000,0.00000 +0.57977,0.00000,0.00000,0.00000,0.00000 +0.76592,0.00000,0.00000,0.00000,0.00000 +0.17153,0.00000,0.00000,0.00000,0.00000 +0.16770,0.00000,0.00000,0.00000,0.00000 +0.77164,0.00000,0.00000,0.00000,0.00000 +0.88195,0.00000,0.00000,0.00000,0.00000 +0.20855,0.00000,0.00000,0.00000,0.00000 +0.78977,0.00000,0.00000,0.00000,0.00000 +0.59706,0.00000,0.00000,0.00000,0.00000 +0.38240,0.00000,0.00000,0.00000,0.00000 +0.95845,0.00000,0.00000,0.00000,0.00000 +0.47646,0.00000,0.00000,0.00000,0.00000 +0.88036,0.00000,0.00000,0.00000,0.00000 +0.15826,0.00000,0.00000,0.00000,0.00000 +0.90522,0.00000,0.00000,0.00000,0.00000 +0.90496,0.00000,0.00000,0.00000,0.00000 +0.41028,0.00000,0.00000,0.00000,0.00000 +0.55725,0.00000,0.00000,0.00000,0.00000 +0.65521,0.00000,0.00000,0.00000,0.00000 +0.59359,0.00000,0.00000,0.00000,0.00000 +0.21998,0.00000,0.00000,0.00000,0.00000 +0.09618,0.00000,0.00000,0.00000,0.00000 +0.27289,0.00000,0.00000,0.00000,0.00000 +0.75328,0.00000,0.00000,0.00000,0.00000 diff --git a/tests/math/p_minmax.c b/tests/math/p_minmax.c new file mode 100644 index 0000000..cbee5be --- /dev/null +++ b/tests/math/p_minmax.c @@ -0,0 +1,25 @@ +#include +#include "check_p_minmax.h" + +void generate_ref(PTYPE *outValue1, PTYPE *outValue2, int *outIndex1, int *outIndex2, size_t n) +{ + int i; + + *outIndex1 = 0; + *outIndex2 = 0; + *outValue1 = ai[0]; + *outValue2 = ai[0]; + + for (i = 1; i < n; i++) { + if (ai[i] < *outValue1) + { + *outIndex1 = i; + *outValue1 = ai[i]; + } + if (ai[i] > *outValue2) + { + *outIndex2 = i; + *outValue2 = ai[i]; + } + } +}