1 /*
2 * SPDX-FileCopyrightText: Copyright 2010-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include "arm_nnfunctions.h"
20 #include "unity.h"
21
22 #include "../TestData/avgpooling_int16/test_data.h"
23 #include "../TestData/avgpooling_int16_1/test_data.h"
24 #include "../TestData/avgpooling_int16_2/test_data.h"
25 #include "../TestData/avgpooling_int16_3/test_data.h"
26 #include "../Utils/validate.h"
27
avgpooling_int16_arm_avgpool_s16(void)28 void avgpooling_int16_arm_avgpool_s16(void)
29 {
30 const arm_cmsis_nn_status expected = ARM_CMSIS_NN_SUCCESS;
31 int16_t output[AVGPOOLING_INT16_DST_SIZE] = {0};
32
33 cmsis_nn_context ctx;
34 cmsis_nn_pool_params pool_params;
35 cmsis_nn_dims input_dims;
36 cmsis_nn_dims filter_dims;
37 cmsis_nn_dims output_dims;
38
39 const int16_t *input_data = avgpooling_int16_input;
40
41 input_dims.n = AVGPOOLING_INT16_INPUT_BATCHES;
42 input_dims.w = AVGPOOLING_INT16_INPUT_W;
43 input_dims.h = AVGPOOLING_INT16_INPUT_H;
44 input_dims.c = AVGPOOLING_INT16_IN_CH;
45 filter_dims.w = AVGPOOLING_INT16_FILTER_X;
46 filter_dims.h = AVGPOOLING_INT16_FILTER_Y;
47 output_dims.w = AVGPOOLING_INT16_OUTPUT_W;
48 output_dims.h = AVGPOOLING_INT16_OUTPUT_H;
49 output_dims.c = AVGPOOLING_INT16_OUT_CH;
50
51 pool_params.padding.w = AVGPOOLING_INT16_PAD_X;
52 pool_params.padding.h = AVGPOOLING_INT16_PAD_Y;
53 pool_params.stride.w = AVGPOOLING_INT16_STRIDE_X;
54 pool_params.stride.h = AVGPOOLING_INT16_STRIDE_Y;
55
56 pool_params.activation.min = AVGPOOLING_INT16_OUT_ACTIVATION_MIN;
57 pool_params.activation.max = AVGPOOLING_INT16_OUT_ACTIVATION_MAX;
58
59 ctx.size = arm_avgpool_s16_get_buffer_size(AVGPOOLING_INT16_OUTPUT_W, AVGPOOLING_INT16_IN_CH);
60 ctx.buf = malloc(ctx.size);
61
62 arm_cmsis_nn_status result =
63 arm_avgpool_s16(&ctx, &pool_params, &input_dims, input_data, &filter_dims, &output_dims, output);
64
65 if (ctx.buf)
66 {
67 // The caller is responsible to clear the scratch buffers for security reasons if applicable.
68 memset(ctx.buf, 0, ctx.size);
69 free(ctx.buf);
70 }
71 TEST_ASSERT_EQUAL(expected, result);
72 TEST_ASSERT_TRUE(validate_s16(output, avgpooling_int16_output_ref, AVGPOOLING_INT16_DST_SIZE));
73 }
74
avgpooling_int16_1_arm_avgpool_s16(void)75 void avgpooling_int16_1_arm_avgpool_s16(void)
76 {
77 const arm_cmsis_nn_status expected = ARM_CMSIS_NN_SUCCESS;
78 int16_t output[AVGPOOLING_INT16_1_DST_SIZE] = {0};
79
80 cmsis_nn_context ctx;
81 cmsis_nn_pool_params pool_params;
82 cmsis_nn_dims input_dims;
83 cmsis_nn_dims filter_dims;
84 cmsis_nn_dims output_dims;
85
86 const int16_t *input_data = avgpooling_int16_1_input;
87
88 input_dims.n = AVGPOOLING_INT16_1_INPUT_BATCHES;
89 input_dims.w = AVGPOOLING_INT16_1_INPUT_W;
90 input_dims.h = AVGPOOLING_INT16_1_INPUT_H;
91 input_dims.c = AVGPOOLING_INT16_1_IN_CH;
92 filter_dims.w = AVGPOOLING_INT16_1_FILTER_X;
93 filter_dims.h = AVGPOOLING_INT16_1_FILTER_Y;
94 output_dims.w = AVGPOOLING_INT16_1_OUTPUT_W;
95 output_dims.h = AVGPOOLING_INT16_1_OUTPUT_H;
96 output_dims.c = AVGPOOLING_INT16_1_OUT_CH;
97
98 pool_params.padding.w = AVGPOOLING_INT16_1_PAD_X;
99 pool_params.padding.h = AVGPOOLING_INT16_1_PAD_Y;
100 pool_params.stride.w = AVGPOOLING_INT16_1_STRIDE_X;
101 pool_params.stride.h = AVGPOOLING_INT16_1_STRIDE_Y;
102
103 pool_params.activation.min = AVGPOOLING_INT16_1_OUT_ACTIVATION_MIN;
104 pool_params.activation.max = AVGPOOLING_INT16_1_OUT_ACTIVATION_MAX;
105
106 ctx.size = arm_avgpool_s16_get_buffer_size(AVGPOOLING_INT16_1_OUTPUT_W, AVGPOOLING_INT16_1_IN_CH);
107 ctx.buf = malloc(ctx.size);
108
109 arm_cmsis_nn_status result =
110 arm_avgpool_s16(&ctx, &pool_params, &input_dims, input_data, &filter_dims, &output_dims, output);
111
112 if (ctx.buf)
113 {
114 memset(ctx.buf, 0, ctx.size);
115 free(ctx.buf);
116 }
117 TEST_ASSERT_EQUAL(expected, result);
118 TEST_ASSERT_TRUE(validate_s16(output, avgpooling_int16_1_output_ref, AVGPOOLING_INT16_1_DST_SIZE));
119 }
120
avgpooling_int16_2_arm_avgpool_s16(void)121 void avgpooling_int16_2_arm_avgpool_s16(void)
122 {
123 const arm_cmsis_nn_status expected = ARM_CMSIS_NN_SUCCESS;
124 int16_t output[AVGPOOLING_INT16_2_DST_SIZE] = {0};
125
126 cmsis_nn_context ctx;
127 cmsis_nn_pool_params pool_params;
128 cmsis_nn_dims input_dims;
129 cmsis_nn_dims filter_dims;
130 cmsis_nn_dims output_dims;
131
132 const int16_t *input_data = avgpooling_int16_2_input;
133
134 input_dims.n = AVGPOOLING_INT16_2_INPUT_BATCHES;
135 input_dims.w = AVGPOOLING_INT16_2_INPUT_W;
136 input_dims.h = AVGPOOLING_INT16_2_INPUT_H;
137 input_dims.c = AVGPOOLING_INT16_2_IN_CH;
138 filter_dims.w = AVGPOOLING_INT16_2_FILTER_X;
139 filter_dims.h = AVGPOOLING_INT16_2_FILTER_Y;
140 output_dims.w = AVGPOOLING_INT16_2_OUTPUT_W;
141 output_dims.h = AVGPOOLING_INT16_2_OUTPUT_H;
142 output_dims.c = AVGPOOLING_INT16_2_OUT_CH;
143
144 pool_params.padding.w = AVGPOOLING_INT16_2_PAD_X;
145 pool_params.padding.h = AVGPOOLING_INT16_2_PAD_Y;
146 pool_params.stride.w = AVGPOOLING_INT16_2_STRIDE_X;
147 pool_params.stride.h = AVGPOOLING_INT16_2_STRIDE_Y;
148
149 pool_params.activation.min = AVGPOOLING_INT16_2_OUT_ACTIVATION_MIN;
150 pool_params.activation.max = AVGPOOLING_INT16_2_OUT_ACTIVATION_MAX;
151
152 ctx.size = arm_avgpool_s16_get_buffer_size(AVGPOOLING_INT16_2_OUTPUT_W, AVGPOOLING_INT16_2_IN_CH);
153 ctx.buf = malloc(ctx.size);
154
155 arm_cmsis_nn_status result =
156 arm_avgpool_s16(&ctx, &pool_params, &input_dims, input_data, &filter_dims, &output_dims, output);
157
158 if (ctx.buf)
159 {
160 memset(ctx.buf, 0, ctx.size);
161 free(ctx.buf);
162 }
163 TEST_ASSERT_EQUAL(expected, result);
164 TEST_ASSERT_TRUE(validate_s16(output, avgpooling_int16_2_output_ref, AVGPOOLING_INT16_2_DST_SIZE));
165 }
166
avgpooling_int16_3_arm_avgpool_s16(void)167 void avgpooling_int16_3_arm_avgpool_s16(void)
168 {
169 const arm_cmsis_nn_status expected = ARM_CMSIS_NN_SUCCESS;
170 int16_t output[AVGPOOLING_INT16_3_DST_SIZE] = {0};
171
172 cmsis_nn_context ctx;
173 cmsis_nn_pool_params pool_params;
174 cmsis_nn_dims input_dims;
175 cmsis_nn_dims filter_dims;
176 cmsis_nn_dims output_dims;
177
178 const int16_t *input_data = avgpooling_int16_3_input;
179
180 input_dims.n = AVGPOOLING_INT16_3_INPUT_BATCHES;
181 input_dims.w = AVGPOOLING_INT16_3_INPUT_W;
182 input_dims.h = AVGPOOLING_INT16_3_INPUT_H;
183 input_dims.c = AVGPOOLING_INT16_3_IN_CH;
184 filter_dims.w = AVGPOOLING_INT16_3_FILTER_X;
185 filter_dims.h = AVGPOOLING_INT16_3_FILTER_Y;
186 output_dims.w = AVGPOOLING_INT16_3_OUTPUT_W;
187 output_dims.h = AVGPOOLING_INT16_3_OUTPUT_H;
188 output_dims.c = AVGPOOLING_INT16_3_OUT_CH;
189
190 pool_params.padding.w = AVGPOOLING_INT16_3_PAD_X;
191 pool_params.padding.h = AVGPOOLING_INT16_3_PAD_Y;
192 pool_params.stride.w = AVGPOOLING_INT16_3_STRIDE_X;
193 pool_params.stride.h = AVGPOOLING_INT16_3_STRIDE_Y;
194
195 pool_params.activation.min = AVGPOOLING_INT16_3_OUT_ACTIVATION_MIN;
196 pool_params.activation.max = AVGPOOLING_INT16_3_OUT_ACTIVATION_MAX;
197
198 ctx.size = arm_avgpool_s16_get_buffer_size(AVGPOOLING_INT16_3_OUTPUT_W, AVGPOOLING_INT16_3_IN_CH);
199 ctx.buf = malloc(ctx.size);
200
201 arm_cmsis_nn_status result =
202 arm_avgpool_s16(&ctx, &pool_params, &input_dims, input_data, &filter_dims, &output_dims, output);
203
204 if (ctx.buf)
205 {
206 memset(ctx.buf, 0, ctx.size);
207 free(ctx.buf);
208 }
209 TEST_ASSERT_EQUAL(expected, result);
210 TEST_ASSERT_TRUE(validate_s16(output, avgpooling_int16_3_output_ref, AVGPOOLING_INT16_3_DST_SIZE));
211 }
212
buffer_size_mve_arm_avgpool_s16(void)213 void buffer_size_mve_arm_avgpool_s16(void)
214 {
215 #if defined(ARM_MATH_MVEI)
216 const int32_t buf_size = arm_avgpool_s16_get_buffer_size(AVGPOOLING_INT16_3_OUTPUT_W, AVGPOOLING_INT16_3_IN_CH);
217 const int32_t mve_buf_size =
218 arm_avgpool_s16_get_buffer_size_mve(AVGPOOLING_INT16_3_OUTPUT_W, AVGPOOLING_INT16_3_IN_CH);
219
220 TEST_ASSERT_EQUAL(buf_size, mve_buf_size);
221 #endif
222 }
223
buffer_size_dsp_arm_avgpool_s16(void)224 void buffer_size_dsp_arm_avgpool_s16(void)
225 {
226 #if defined(ARM_MATH_DSP) && !defined(ARM_MATH_MVEI)
227 const int32_t buf_size = arm_avgpool_s16_get_buffer_size(AVGPOOLING_INT16_3_OUTPUT_W, AVGPOOLING_INT16_3_IN_CH);
228 const int32_t dsp_buf_size =
229 arm_avgpool_s16_get_buffer_size_dsp(AVGPOOLING_INT16_3_OUTPUT_W, AVGPOOLING_INT16_3_IN_CH);
230
231 TEST_ASSERT_EQUAL(buf_size, dsp_buf_size);
232 #endif
233 }
234
avgpooling_int16_param_fail_arm_avgpool_s16(void)235 void avgpooling_int16_param_fail_arm_avgpool_s16(void)
236 {
237 const arm_cmsis_nn_status expected = ARM_CMSIS_NN_ARG_ERROR;
238 int16_t output[AVGPOOLING_INT16_3_DST_SIZE] = {0};
239
240 cmsis_nn_context ctx;
241 cmsis_nn_pool_params pool_params;
242 cmsis_nn_dims input_dims;
243 cmsis_nn_dims filter_dims;
244 cmsis_nn_dims output_dims;
245
246 const int16_t *input_data = avgpooling_int16_3_input;
247
248 input_dims.n = 0;
249 input_dims.w = AVGPOOLING_INT16_3_INPUT_W;
250 input_dims.h = AVGPOOLING_INT16_3_INPUT_H;
251 input_dims.c = AVGPOOLING_INT16_3_IN_CH;
252 filter_dims.w = AVGPOOLING_INT16_3_FILTER_X;
253 filter_dims.h = AVGPOOLING_INT16_3_FILTER_Y;
254 output_dims.w = AVGPOOLING_INT16_3_OUTPUT_W;
255 output_dims.h = AVGPOOLING_INT16_3_OUTPUT_H;
256 output_dims.c = AVGPOOLING_INT16_3_OUT_CH;
257
258 pool_params.padding.w = AVGPOOLING_INT16_3_PAD_X;
259 pool_params.padding.h = AVGPOOLING_INT16_3_PAD_Y;
260 pool_params.stride.w = AVGPOOLING_INT16_3_STRIDE_X;
261 pool_params.stride.h = AVGPOOLING_INT16_3_STRIDE_Y;
262
263 pool_params.activation.min = AVGPOOLING_INT16_3_OUT_ACTIVATION_MIN;
264 pool_params.activation.max = AVGPOOLING_INT16_3_OUT_ACTIVATION_MAX;
265
266 ctx.size = arm_avgpool_s16_get_buffer_size(AVGPOOLING_INT16_3_OUTPUT_W, AVGPOOLING_INT16_3_IN_CH);
267 ctx.buf = malloc(ctx.size);
268
269 arm_cmsis_nn_status result =
270 arm_avgpool_s16(&ctx, &pool_params, &input_dims, input_data, &filter_dims, &output_dims, output);
271
272 if (ctx.buf)
273 {
274 memset(ctx.buf, 0, ctx.size);
275 free(ctx.buf);
276 }
277 TEST_ASSERT_EQUAL(expected, result);
278 }
279