1 /*
2  * Copyright (c) 2021 Stephanos Ioannidis <root@stephanos.io>
3  * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <zephyr/ztest.h>
9 #include <zephyr/kernel.h>
10 #include <stdlib.h>
11 #include <arm_math_f16.h>
12 #include "../../common/test_common.h"
13 
14 #include "f16.pat"
15 
16 #define REL_ERROR_THRESH	(3.0e-3)
17 
18 /* Note: this source file is only built when CONFIG_CMSIS_DSP_FLOAT16 is enabled */
19 
20 ZTEST_SUITE(bayes_f16, NULL, NULL, NULL, NULL, NULL);
21 
ZTEST(bayes_f16,test_gaussian_naive_bayes_predict_f16)22 ZTEST(bayes_f16, test_gaussian_naive_bayes_predict_f16)
23 {
24 	arm_gaussian_naive_bayes_instance_f16 inst;
25 
26 	size_t index;
27 	const uint16_t pattern_count = in_dims[0];
28 	const uint16_t class_count = in_dims[1];
29 	const uint16_t vec_dims = in_dims[2];
30 
31 	const float16_t *params = (const float16_t *)in_param;
32 	const float16_t *input = (const float16_t *)in_val;
33 	float16_t *output_probs_buf, *output_probs;
34 	uint16_t *output_preds_buf, *output_preds;
35 	float16_t *temp;
36 
37 	/* Initialise instance */
38 	inst.vectorDimension = vec_dims;
39 	inst.numberOfClasses = class_count;
40 	inst.theta = params;
41 	inst.sigma = params + (class_count * vec_dims);
42 	inst.classPriors = params + (2 * class_count * vec_dims);
43 	inst.epsilon = params[class_count + (2 * class_count * vec_dims)];
44 
45 	/* Allocate output buffers */
46 	output_probs_buf =
47 		malloc(pattern_count * class_count * sizeof(float16_t));
48 	zassert_not_null(output_probs_buf, ASSERT_MSG_BUFFER_ALLOC_FAILED);
49 
50 	output_preds_buf =
51 		malloc(pattern_count * sizeof(uint16_t));
52 	zassert_not_null(output_preds_buf, ASSERT_MSG_BUFFER_ALLOC_FAILED);
53 
54 	output_probs = output_probs_buf;
55 	output_preds = output_preds_buf;
56 
57 	temp = malloc(pattern_count * class_count * sizeof(float16_t));
58 	zassert_not_null(temp, ASSERT_MSG_BUFFER_ALLOC_FAILED);
59 
60 	/* Enumerate patterns */
61 	for (index = 0; index < pattern_count; index++) {
62 		/* Run test function */
63 		*output_preds =
64 			arm_gaussian_naive_bayes_predict_f16(
65 				&inst, input, output_probs, temp);
66 
67 		/* Increment pointers */
68 		input += vec_dims;
69 		output_probs += class_count;
70 		output_preds++;
71 	}
72 
73 	/* Validate output */
74 	zassert_true(
75 		test_rel_error_f16(pattern_count, output_probs_buf,
76 			(float16_t *)ref_prob, REL_ERROR_THRESH),
77 		ASSERT_MSG_REL_ERROR_LIMIT_EXCEED);
78 
79 	zassert_true(
80 		test_equal_q15(pattern_count, output_preds_buf, ref_pred),
81 		ASSERT_MSG_INCORRECT_COMP_RESULT);
82 
83 	/* Free output buffers */
84 	free(output_probs_buf);
85 	free(output_preds_buf);
86 }
87