1 /*
2 * SPDX-FileCopyrightText: Copyright 2010-2024 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_OUTPUT_C * AVGPOOLING_INT16_OUTPUT_W * AVGPOOLING_INT16_OUTPUT_H *
32 AVGPOOLING_INT16_BATCH_SIZE] = {0};
33
34 cmsis_nn_context ctx;
35 cmsis_nn_pool_params pool_params;
36 cmsis_nn_dims input_dims;
37 cmsis_nn_dims filter_dims;
38 cmsis_nn_dims output_dims;
39
40 const int16_t *input_data = avgpooling_int16_input_tensor;
41
42 input_dims.n = AVGPOOLING_INT16_BATCH_SIZE;
43 input_dims.w = AVGPOOLING_INT16_INPUT_W;
44 input_dims.h = AVGPOOLING_INT16_INPUT_H;
45 input_dims.c = AVGPOOLING_INT16_INPUT_C;
46 filter_dims.w = AVGPOOLING_INT16_FILTER_W;
47 filter_dims.h = AVGPOOLING_INT16_FILTER_H;
48 output_dims.w = AVGPOOLING_INT16_OUTPUT_W;
49 output_dims.h = AVGPOOLING_INT16_OUTPUT_H;
50 output_dims.c = AVGPOOLING_INT16_INPUT_C;
51
52 pool_params.padding.w = AVGPOOLING_INT16_PADDING_W;
53 pool_params.padding.h = AVGPOOLING_INT16_PADDING_H;
54 pool_params.stride.w = AVGPOOLING_INT16_STRIDE_W;
55 pool_params.stride.h = AVGPOOLING_INT16_STRIDE_H;
56
57 pool_params.activation.min = AVGPOOLING_INT16_ACTIVATION_MIN;
58 pool_params.activation.max = AVGPOOLING_INT16_ACTIVATION_MAX;
59
60 ctx.size = arm_avgpool_s16_get_buffer_size(AVGPOOLING_INT16_OUTPUT_W, AVGPOOLING_INT16_INPUT_C);
61 ctx.buf = malloc(ctx.size);
62
63 arm_cmsis_nn_status result =
64 arm_avgpool_s16(&ctx, &pool_params, &input_dims, input_data, &filter_dims, &output_dims, output);
65
66 if (ctx.buf)
67 {
68 // The caller is responsible to clear the scratch buffers for security reasons if applicable.
69 memset(ctx.buf, 0, ctx.size);
70 free(ctx.buf);
71 }
72 TEST_ASSERT_EQUAL(expected, result);
73 TEST_ASSERT_TRUE(validate_s16(output,
74 avgpooling_int16_output,
75 AVGPOOLING_INT16_OUTPUT_C * AVGPOOLING_INT16_OUTPUT_W * AVGPOOLING_INT16_OUTPUT_H *
76 AVGPOOLING_INT16_BATCH_SIZE));
77 }
78
avgpooling_int16_1_arm_avgpool_s16(void)79 void avgpooling_int16_1_arm_avgpool_s16(void)
80 {
81 const arm_cmsis_nn_status expected = ARM_CMSIS_NN_SUCCESS;
82 int16_t output[AVGPOOLING_INT16_1_OUTPUT_C * AVGPOOLING_INT16_1_OUTPUT_W * AVGPOOLING_INT16_1_OUTPUT_H *
83 AVGPOOLING_INT16_1_BATCH_SIZE] = {0};
84
85 cmsis_nn_context ctx;
86 cmsis_nn_pool_params pool_params;
87 cmsis_nn_dims input_dims;
88 cmsis_nn_dims filter_dims;
89 cmsis_nn_dims output_dims;
90
91 const int16_t *input_data = avgpooling_int16_1_input_tensor;
92
93 input_dims.n = AVGPOOLING_INT16_1_BATCH_SIZE;
94 input_dims.w = AVGPOOLING_INT16_1_INPUT_W;
95 input_dims.h = AVGPOOLING_INT16_1_INPUT_H;
96 input_dims.c = AVGPOOLING_INT16_1_INPUT_C;
97 filter_dims.w = AVGPOOLING_INT16_1_FILTER_W;
98 filter_dims.h = AVGPOOLING_INT16_1_FILTER_H;
99 output_dims.w = AVGPOOLING_INT16_1_OUTPUT_W;
100 output_dims.h = AVGPOOLING_INT16_1_OUTPUT_H;
101 output_dims.c = AVGPOOLING_INT16_1_INPUT_C;
102
103 pool_params.padding.w = AVGPOOLING_INT16_1_PADDING_W;
104 pool_params.padding.h = AVGPOOLING_INT16_1_PADDING_H;
105 pool_params.stride.w = AVGPOOLING_INT16_1_STRIDE_W;
106 pool_params.stride.h = AVGPOOLING_INT16_1_STRIDE_H;
107
108 pool_params.activation.min = AVGPOOLING_INT16_1_ACTIVATION_MIN;
109 pool_params.activation.max = AVGPOOLING_INT16_1_ACTIVATION_MAX;
110
111 ctx.size = arm_avgpool_s16_get_buffer_size(AVGPOOLING_INT16_1_OUTPUT_W, AVGPOOLING_INT16_1_INPUT_C);
112 ctx.buf = malloc(ctx.size);
113
114 arm_cmsis_nn_status result =
115 arm_avgpool_s16(&ctx, &pool_params, &input_dims, input_data, &filter_dims, &output_dims, output);
116
117 if (ctx.buf)
118 {
119 memset(ctx.buf, 0, ctx.size);
120 free(ctx.buf);
121 }
122 TEST_ASSERT_EQUAL(expected, result);
123 TEST_ASSERT_TRUE(validate_s16(output,
124 avgpooling_int16_1_output,
125 AVGPOOLING_INT16_1_OUTPUT_C * AVGPOOLING_INT16_1_OUTPUT_W *
126 AVGPOOLING_INT16_1_OUTPUT_H * AVGPOOLING_INT16_1_BATCH_SIZE));
127 }
128
avgpooling_int16_2_arm_avgpool_s16(void)129 void avgpooling_int16_2_arm_avgpool_s16(void)
130 {
131 const arm_cmsis_nn_status expected = ARM_CMSIS_NN_SUCCESS;
132 int16_t output[AVGPOOLING_INT16_2_OUTPUT_C * AVGPOOLING_INT16_2_OUTPUT_W * AVGPOOLING_INT16_2_OUTPUT_H *
133 AVGPOOLING_INT16_2_BATCH_SIZE] = {0};
134
135 cmsis_nn_context ctx;
136 cmsis_nn_pool_params pool_params;
137 cmsis_nn_dims input_dims;
138 cmsis_nn_dims filter_dims;
139 cmsis_nn_dims output_dims;
140
141 const int16_t *input_data = avgpooling_int16_2_input_tensor;
142
143 input_dims.n = AVGPOOLING_INT16_2_BATCH_SIZE;
144 input_dims.w = AVGPOOLING_INT16_2_INPUT_W;
145 input_dims.h = AVGPOOLING_INT16_2_INPUT_H;
146 input_dims.c = AVGPOOLING_INT16_2_INPUT_C;
147 filter_dims.w = AVGPOOLING_INT16_2_FILTER_W;
148 filter_dims.h = AVGPOOLING_INT16_2_FILTER_H;
149 output_dims.w = AVGPOOLING_INT16_2_OUTPUT_W;
150 output_dims.h = AVGPOOLING_INT16_2_OUTPUT_H;
151 output_dims.c = AVGPOOLING_INT16_2_INPUT_C;
152
153 pool_params.padding.w = AVGPOOLING_INT16_2_PADDING_W;
154 pool_params.padding.h = AVGPOOLING_INT16_2_PADDING_H;
155 pool_params.stride.w = AVGPOOLING_INT16_2_STRIDE_W;
156 pool_params.stride.h = AVGPOOLING_INT16_2_STRIDE_H;
157
158 pool_params.activation.min = AVGPOOLING_INT16_2_ACTIVATION_MIN;
159 pool_params.activation.max = AVGPOOLING_INT16_2_ACTIVATION_MAX;
160
161 ctx.size = arm_avgpool_s16_get_buffer_size(AVGPOOLING_INT16_2_OUTPUT_W, AVGPOOLING_INT16_2_INPUT_C);
162 ctx.buf = malloc(ctx.size);
163
164 arm_cmsis_nn_status result =
165 arm_avgpool_s16(&ctx, &pool_params, &input_dims, input_data, &filter_dims, &output_dims, output);
166
167 if (ctx.buf)
168 {
169 memset(ctx.buf, 0, ctx.size);
170 free(ctx.buf);
171 }
172 TEST_ASSERT_EQUAL(expected, result);
173 TEST_ASSERT_TRUE(validate_s16(output,
174 avgpooling_int16_2_output,
175 AVGPOOLING_INT16_2_OUTPUT_C * AVGPOOLING_INT16_2_OUTPUT_W *
176 AVGPOOLING_INT16_2_OUTPUT_H * AVGPOOLING_INT16_2_BATCH_SIZE));
177 }
178
avgpooling_int16_3_arm_avgpool_s16(void)179 void avgpooling_int16_3_arm_avgpool_s16(void)
180 {
181 const arm_cmsis_nn_status expected = ARM_CMSIS_NN_SUCCESS;
182 int16_t output[AVGPOOLING_INT16_3_OUTPUT_C * AVGPOOLING_INT16_3_OUTPUT_W * AVGPOOLING_INT16_3_OUTPUT_H *
183 AVGPOOLING_INT16_3_BATCH_SIZE] = {0};
184
185 cmsis_nn_context ctx;
186 cmsis_nn_pool_params pool_params;
187 cmsis_nn_dims input_dims;
188 cmsis_nn_dims filter_dims;
189 cmsis_nn_dims output_dims;
190
191 const int16_t *input_data = avgpooling_int16_3_input_tensor;
192
193 input_dims.n = AVGPOOLING_INT16_3_BATCH_SIZE;
194 input_dims.w = AVGPOOLING_INT16_3_INPUT_W;
195 input_dims.h = AVGPOOLING_INT16_3_INPUT_H;
196 input_dims.c = AVGPOOLING_INT16_3_INPUT_C;
197 filter_dims.w = AVGPOOLING_INT16_3_FILTER_W;
198 filter_dims.h = AVGPOOLING_INT16_3_FILTER_H;
199 output_dims.w = AVGPOOLING_INT16_3_OUTPUT_W;
200 output_dims.h = AVGPOOLING_INT16_3_OUTPUT_H;
201 output_dims.c = AVGPOOLING_INT16_3_INPUT_C;
202
203 pool_params.padding.w = AVGPOOLING_INT16_3_PADDING_W;
204 pool_params.padding.h = AVGPOOLING_INT16_3_PADDING_H;
205 pool_params.stride.w = AVGPOOLING_INT16_3_STRIDE_W;
206 pool_params.stride.h = AVGPOOLING_INT16_3_STRIDE_H;
207
208 pool_params.activation.min = AVGPOOLING_INT16_3_ACTIVATION_MIN;
209 pool_params.activation.max = AVGPOOLING_INT16_3_ACTIVATION_MAX;
210
211 ctx.size = arm_avgpool_s16_get_buffer_size(AVGPOOLING_INT16_3_OUTPUT_W, AVGPOOLING_INT16_3_INPUT_C);
212 ctx.buf = malloc(ctx.size);
213
214 arm_cmsis_nn_status result =
215 arm_avgpool_s16(&ctx, &pool_params, &input_dims, input_data, &filter_dims, &output_dims, output);
216
217 if (ctx.buf)
218 {
219 memset(ctx.buf, 0, ctx.size);
220 free(ctx.buf);
221 }
222 TEST_ASSERT_EQUAL(expected, result);
223 TEST_ASSERT_TRUE(validate_s16(output,
224 avgpooling_int16_3_output,
225 AVGPOOLING_INT16_3_OUTPUT_C * AVGPOOLING_INT16_3_OUTPUT_W *
226 AVGPOOLING_INT16_3_OUTPUT_H * AVGPOOLING_INT16_3_BATCH_SIZE));
227 }
228
buffer_size_mve_arm_avgpool_s16(void)229 void buffer_size_mve_arm_avgpool_s16(void)
230 {
231 #if defined(ARM_MATH_MVEI)
232 const int32_t buf_size = arm_avgpool_s16_get_buffer_size(AVGPOOLING_INT16_3_OUTPUT_W, AVGPOOLING_INT16_3_INPUT_C);
233 const int32_t mve_buf_size =
234 arm_avgpool_s16_get_buffer_size_mve(AVGPOOLING_INT16_3_OUTPUT_W, AVGPOOLING_INT16_3_INPUT_C);
235
236 TEST_ASSERT_EQUAL(buf_size, mve_buf_size);
237 #endif
238 }
239
buffer_size_dsp_arm_avgpool_s16(void)240 void buffer_size_dsp_arm_avgpool_s16(void)
241 {
242 #if defined(ARM_MATH_DSP) && !defined(ARM_MATH_MVEI)
243 const int32_t buf_size = arm_avgpool_s16_get_buffer_size(AVGPOOLING_INT16_3_OUTPUT_W, AVGPOOLING_INT16_3_INPUT_C);
244 const int32_t dsp_buf_size =
245 arm_avgpool_s16_get_buffer_size_dsp(AVGPOOLING_INT16_3_OUTPUT_W, AVGPOOLING_INT16_3_INPUT_C);
246
247 TEST_ASSERT_EQUAL(buf_size, dsp_buf_size);
248 #endif
249 }
250
avgpooling_int16_param_fail_arm_avgpool_s16(void)251 void avgpooling_int16_param_fail_arm_avgpool_s16(void)
252 {
253 const arm_cmsis_nn_status expected = ARM_CMSIS_NN_ARG_ERROR;
254 int16_t output[AVGPOOLING_INT16_3_OUTPUT_C * AVGPOOLING_INT16_3_OUTPUT_W * AVGPOOLING_INT16_3_OUTPUT_H *
255 AVGPOOLING_INT16_3_BATCH_SIZE] = {0};
256
257 cmsis_nn_context ctx;
258 cmsis_nn_pool_params pool_params;
259 cmsis_nn_dims input_dims;
260 cmsis_nn_dims filter_dims;
261 cmsis_nn_dims output_dims;
262
263 const int16_t *input_data = avgpooling_int16_3_input_tensor;
264
265 input_dims.n = 0;
266 input_dims.w = AVGPOOLING_INT16_3_INPUT_W;
267 input_dims.h = AVGPOOLING_INT16_3_INPUT_H;
268 input_dims.c = AVGPOOLING_INT16_3_INPUT_C;
269 filter_dims.w = AVGPOOLING_INT16_3_FILTER_W;
270 filter_dims.h = AVGPOOLING_INT16_3_FILTER_H;
271 output_dims.w = AVGPOOLING_INT16_3_OUTPUT_W;
272 output_dims.h = AVGPOOLING_INT16_3_OUTPUT_H;
273 output_dims.c = AVGPOOLING_INT16_3_INPUT_C;
274
275 pool_params.padding.w = AVGPOOLING_INT16_3_PADDING_W;
276 pool_params.padding.h = AVGPOOLING_INT16_3_PADDING_H;
277 pool_params.stride.w = AVGPOOLING_INT16_3_STRIDE_W;
278 pool_params.stride.h = AVGPOOLING_INT16_3_STRIDE_H;
279
280 pool_params.activation.min = AVGPOOLING_INT16_3_ACTIVATION_MIN;
281 pool_params.activation.max = AVGPOOLING_INT16_3_ACTIVATION_MAX;
282
283 ctx.size = arm_avgpool_s16_get_buffer_size(AVGPOOLING_INT16_3_OUTPUT_W, AVGPOOLING_INT16_3_INPUT_C);
284 ctx.buf = malloc(ctx.size);
285
286 arm_cmsis_nn_status result =
287 arm_avgpool_s16(&ctx, &pool_params, &input_dims, input_data, &filter_dims, &output_dims, output);
288
289 if (ctx.buf)
290 {
291 memset(ctx.buf, 0, ctx.size);
292 free(ctx.buf);
293 }
294 TEST_ASSERT_EQUAL(expected, result);
295 }
296