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 <stdlib.h>
20 
21 #include <arm_nnfunctions.h>
22 #include <unity.h>
23 
24 #include "../TestData/basic/test_data.h"
25 #include "../TestData/conv_2/test_data.h"
26 #include "../TestData/conv_2x2_dilation/test_data.h"
27 #include "../TestData/conv_2x2_dilation_5x5_input/test_data.h"
28 #include "../TestData/conv_2x3_dilation/test_data.h"
29 #include "../TestData/conv_3/test_data.h"
30 #include "../TestData/conv_3x2_dilation/test_data.h"
31 #include "../TestData/conv_3x3_dilation_5x5_input/test_data.h"
32 #include "../TestData/conv_4/test_data.h"
33 #include "../TestData/conv_5/test_data.h"
34 #include "../TestData/conv_dilation_golden/test_data.h"
35 #include "../TestData/conv_out_activation/test_data.h"
36 #include "../TestData/stride2pad1/test_data.h"
37 #include "../Utils/validate.h"
38 
basic_arm_convolve_s8(void)39 void basic_arm_convolve_s8(void)
40 {
41     const arm_cmsis_nn_status expected = ARM_CMSIS_NN_SUCCESS;
42     int8_t output[BASIC_DST_SIZE] = {0};
43 
44     cmsis_nn_context ctx;
45     cmsis_nn_conv_params conv_params;
46     cmsis_nn_per_channel_quant_params quant_params;
47     cmsis_nn_dims input_dims;
48     cmsis_nn_dims filter_dims;
49     cmsis_nn_dims bias_dims;
50     cmsis_nn_dims output_dims;
51 
52     const int32_t *bias_data = basic_biases;
53     const int8_t *kernel_data = basic_weights;
54     const int8_t *input_data = basic_input;
55     const int8_t *output_ref = basic_output_ref;
56     const int32_t output_ref_size = BASIC_DST_SIZE;
57 
58     input_dims.n = BASIC_INPUT_BATCHES;
59     input_dims.w = BASIC_INPUT_W;
60     input_dims.h = BASIC_INPUT_H;
61     input_dims.c = BASIC_IN_CH;
62     filter_dims.w = BASIC_FILTER_X;
63     filter_dims.h = BASIC_FILTER_Y;
64     filter_dims.c = BASIC_IN_CH;
65     output_dims.w = BASIC_OUTPUT_W;
66     output_dims.h = BASIC_OUTPUT_H;
67     output_dims.c = BASIC_OUT_CH;
68 
69     conv_params.padding.w = BASIC_PAD_X;
70     conv_params.padding.h = BASIC_PAD_Y;
71     conv_params.stride.w = BASIC_STRIDE_X;
72     conv_params.stride.h = BASIC_STRIDE_Y;
73     conv_params.dilation.w = BASIC_DILATION_X;
74     conv_params.dilation.h = BASIC_DILATION_Y;
75 
76     conv_params.input_offset = BASIC_INPUT_OFFSET;
77     conv_params.output_offset = BASIC_OUTPUT_OFFSET;
78     conv_params.activation.min = BASIC_OUT_ACTIVATION_MIN;
79     conv_params.activation.max = BASIC_OUT_ACTIVATION_MAX;
80     quant_params.multiplier = (int32_t *)basic_output_mult;
81     quant_params.shift = (int32_t *)basic_output_shift;
82 
83     int32_t buf_size = arm_convolve_s8_get_buffer_size(&input_dims, &filter_dims);
84     ctx.buf = malloc(buf_size);
85     ctx.size = 0;
86 
87     arm_cmsis_nn_status result = arm_convolve_s8(&ctx,
88                                                  &conv_params,
89                                                  &quant_params,
90                                                  &input_dims,
91                                                  input_data,
92                                                  &filter_dims,
93                                                  kernel_data,
94                                                  &bias_dims,
95                                                  bias_data,
96                                                  &output_dims,
97                                                  output);
98 
99     if (ctx.buf)
100     {
101         // The caller is responsible to clear the scratch buffers for security reasons if applicable.
102         memset(ctx.buf, 0, buf_size);
103         free(ctx.buf);
104     }
105     TEST_ASSERT_EQUAL(expected, result);
106     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
107     memset(output, 0, sizeof(output));
108 
109     buf_size = arm_convolve_wrapper_s8_get_buffer_size(&conv_params, &input_dims, &filter_dims, &output_dims);
110     ctx.buf = malloc(buf_size);
111     ctx.size = 0;
112 
113     result = arm_convolve_wrapper_s8(&ctx,
114                                      &conv_params,
115                                      &quant_params,
116                                      &input_dims,
117                                      input_data,
118                                      &filter_dims,
119                                      kernel_data,
120                                      &bias_dims,
121                                      bias_data,
122                                      &output_dims,
123                                      output);
124 
125     if (ctx.buf)
126     {
127         memset(ctx.buf, 0, buf_size);
128         free(ctx.buf);
129     }
130     TEST_ASSERT_EQUAL(expected, result);
131     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
132 }
133 
stride2pad1_arm_convolve_s8(void)134 void stride2pad1_arm_convolve_s8(void)
135 {
136     const arm_cmsis_nn_status expected = ARM_CMSIS_NN_SUCCESS;
137     int8_t output[STRIDE2PAD1_DST_SIZE] = {0};
138 
139     cmsis_nn_context ctx;
140     cmsis_nn_conv_params conv_params;
141     cmsis_nn_per_channel_quant_params quant_params;
142     cmsis_nn_dims input_dims;
143     cmsis_nn_dims filter_dims;
144     cmsis_nn_dims bias_dims;
145     cmsis_nn_dims output_dims;
146 
147     const int32_t *bias_data = stride2pad1_biases;
148     const int8_t *kernel_data = stride2pad1_weights;
149     const int8_t *input_data = stride2pad1_input;
150     const int8_t *output_ref = stride2pad1_output_ref;
151     const int32_t output_ref_size = STRIDE2PAD1_DST_SIZE;
152 
153     input_dims.n = STRIDE2PAD1_INPUT_BATCHES;
154     input_dims.w = STRIDE2PAD1_INPUT_W;
155     input_dims.h = STRIDE2PAD1_INPUT_H;
156     input_dims.c = STRIDE2PAD1_IN_CH;
157     filter_dims.w = STRIDE2PAD1_FILTER_X;
158     filter_dims.h = STRIDE2PAD1_FILTER_Y;
159     filter_dims.c = STRIDE2PAD1_IN_CH;
160     output_dims.w = STRIDE2PAD1_OUTPUT_W;
161     output_dims.h = STRIDE2PAD1_OUTPUT_H;
162     output_dims.c = STRIDE2PAD1_OUT_CH;
163 
164     conv_params.padding.w = STRIDE2PAD1_PAD_X;
165     conv_params.padding.h = STRIDE2PAD1_PAD_Y;
166     conv_params.stride.w = STRIDE2PAD1_STRIDE_X;
167     conv_params.stride.h = STRIDE2PAD1_STRIDE_Y;
168     conv_params.dilation.w = STRIDE2PAD1_DILATION_X;
169     conv_params.dilation.h = STRIDE2PAD1_DILATION_Y;
170 
171     conv_params.input_offset = STRIDE2PAD1_INPUT_OFFSET;
172     conv_params.output_offset = STRIDE2PAD1_OUTPUT_OFFSET;
173     conv_params.activation.min = STRIDE2PAD1_OUT_ACTIVATION_MIN;
174     conv_params.activation.max = STRIDE2PAD1_OUT_ACTIVATION_MAX;
175     quant_params.multiplier = (int32_t *)stride2pad1_output_mult;
176     quant_params.shift = (int32_t *)stride2pad1_output_shift;
177 
178     int32_t buf_size = arm_convolve_s8_get_buffer_size(&input_dims, &filter_dims);
179     ctx.buf = malloc(buf_size);
180     ctx.size = 0;
181 
182     arm_cmsis_nn_status result = arm_convolve_s8(&ctx,
183                                                  &conv_params,
184                                                  &quant_params,
185                                                  &input_dims,
186                                                  input_data,
187                                                  &filter_dims,
188                                                  kernel_data,
189                                                  &bias_dims,
190                                                  bias_data,
191                                                  &output_dims,
192                                                  output);
193 
194     if (ctx.buf)
195     {
196         memset(ctx.buf, 0, buf_size);
197         free(ctx.buf);
198     }
199     TEST_ASSERT_EQUAL(expected, result);
200     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
201     memset(output, 0, sizeof(output));
202 
203     buf_size = arm_convolve_wrapper_s8_get_buffer_size(&conv_params, &input_dims, &filter_dims, &output_dims);
204     ctx.buf = malloc(buf_size);
205     ctx.size = 0;
206 
207     result = arm_convolve_wrapper_s8(&ctx,
208                                      &conv_params,
209                                      &quant_params,
210                                      &input_dims,
211                                      input_data,
212                                      &filter_dims,
213                                      kernel_data,
214                                      &bias_dims,
215                                      bias_data,
216                                      &output_dims,
217                                      output);
218 
219     if (ctx.buf)
220     {
221         memset(ctx.buf, 0, buf_size);
222         free(ctx.buf);
223     }
224     TEST_ASSERT_EQUAL(expected, result);
225     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
226 }
227 
conv_2_arm_convolve_s8(void)228 void conv_2_arm_convolve_s8(void)
229 {
230     const arm_cmsis_nn_status expected = ARM_CMSIS_NN_SUCCESS;
231     int8_t output[CONV_2_DST_SIZE] = {0};
232 
233     cmsis_nn_context ctx;
234     cmsis_nn_conv_params conv_params;
235     cmsis_nn_per_channel_quant_params quant_params;
236     cmsis_nn_dims input_dims;
237     cmsis_nn_dims filter_dims;
238     cmsis_nn_dims bias_dims;
239     cmsis_nn_dims output_dims;
240 
241     const int32_t *bias_data = conv_2_biases;
242     const int8_t *kernel_data = conv_2_weights;
243     const int8_t *input_data = conv_2_input;
244     const int8_t *output_ref = conv_2_output_ref;
245     const int32_t output_ref_size = CONV_2_DST_SIZE;
246 
247     input_dims.n = CONV_2_INPUT_BATCHES;
248     input_dims.w = CONV_2_INPUT_W;
249     input_dims.h = CONV_2_INPUT_H;
250     input_dims.c = CONV_2_IN_CH;
251     filter_dims.w = CONV_2_FILTER_X;
252     filter_dims.h = CONV_2_FILTER_Y;
253     filter_dims.c = CONV_2_IN_CH;
254     output_dims.w = CONV_2_OUTPUT_W;
255     output_dims.h = CONV_2_OUTPUT_H;
256     output_dims.c = CONV_2_OUT_CH;
257 
258     conv_params.padding.w = CONV_2_PAD_X;
259     conv_params.padding.h = CONV_2_PAD_Y;
260     conv_params.stride.w = CONV_2_STRIDE_X;
261     conv_params.stride.h = CONV_2_STRIDE_Y;
262     conv_params.dilation.w = CONV_2_DILATION_X;
263     conv_params.dilation.h = CONV_2_DILATION_Y;
264 
265     conv_params.input_offset = CONV_2_INPUT_OFFSET;
266     conv_params.output_offset = CONV_2_OUTPUT_OFFSET;
267     conv_params.activation.min = CONV_2_OUT_ACTIVATION_MIN;
268     conv_params.activation.max = CONV_2_OUT_ACTIVATION_MAX;
269     quant_params.multiplier = (int32_t *)conv_2_output_mult;
270     quant_params.shift = (int32_t *)conv_2_output_shift;
271 
272     int32_t buf_size = arm_convolve_s8_get_buffer_size(&input_dims, &filter_dims);
273     ctx.buf = malloc(buf_size);
274     ctx.size = 0;
275 
276     arm_cmsis_nn_status result = arm_convolve_s8(&ctx,
277                                                  &conv_params,
278                                                  &quant_params,
279                                                  &input_dims,
280                                                  input_data,
281                                                  &filter_dims,
282                                                  conv_2_weights,
283                                                  &bias_dims,
284                                                  bias_data,
285                                                  &output_dims,
286                                                  output);
287 
288     if (ctx.buf)
289     {
290         memset(ctx.buf, 0, buf_size);
291         free(ctx.buf);
292     }
293     TEST_ASSERT_EQUAL(expected, result);
294     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
295     memset(output, 0, sizeof(output));
296 
297     buf_size = arm_convolve_wrapper_s8_get_buffer_size(&conv_params, &input_dims, &filter_dims, &output_dims);
298     ctx.buf = malloc(buf_size);
299     ctx.size = 0;
300 
301     result = arm_convolve_wrapper_s8(&ctx,
302                                      &conv_params,
303                                      &quant_params,
304                                      &input_dims,
305                                      input_data,
306                                      &filter_dims,
307                                      kernel_data,
308                                      &bias_dims,
309                                      bias_data,
310                                      &output_dims,
311                                      output);
312 
313     if (ctx.buf)
314     {
315         memset(ctx.buf, 0, buf_size);
316         free(ctx.buf);
317     }
318     TEST_ASSERT_EQUAL(expected, result);
319     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
320 }
321 
conv_3_arm_convolve_s8(void)322 void conv_3_arm_convolve_s8(void)
323 {
324     const arm_cmsis_nn_status expected = ARM_CMSIS_NN_SUCCESS;
325     int8_t output[CONV_3_DST_SIZE] = {0};
326 
327     cmsis_nn_context ctx;
328     cmsis_nn_conv_params conv_params;
329     cmsis_nn_per_channel_quant_params quant_params;
330     cmsis_nn_dims input_dims;
331     cmsis_nn_dims filter_dims;
332     cmsis_nn_dims bias_dims;
333     cmsis_nn_dims output_dims;
334 
335     const int32_t *bias_data = conv_3_biases;
336     const int8_t *kernel_data = conv_3_weights;
337     const int8_t *input_data = conv_3_input;
338     const int8_t *output_ref = conv_3_output_ref;
339     const int32_t output_ref_size = CONV_3_DST_SIZE;
340 
341     input_dims.n = CONV_3_INPUT_BATCHES;
342     input_dims.w = CONV_3_INPUT_W;
343     input_dims.h = CONV_3_INPUT_H;
344     input_dims.c = CONV_3_IN_CH;
345     filter_dims.w = CONV_3_FILTER_X;
346     filter_dims.h = CONV_3_FILTER_Y;
347     filter_dims.c = CONV_3_IN_CH;
348     output_dims.w = CONV_3_OUTPUT_W;
349     output_dims.h = CONV_3_OUTPUT_H;
350     output_dims.c = CONV_3_OUT_CH;
351 
352     conv_params.padding.w = CONV_3_PAD_X;
353     conv_params.padding.h = CONV_3_PAD_Y;
354     conv_params.stride.w = CONV_3_STRIDE_X;
355     conv_params.stride.h = CONV_3_STRIDE_Y;
356     conv_params.dilation.w = CONV_3_DILATION_X;
357     conv_params.dilation.h = CONV_3_DILATION_Y;
358 
359     conv_params.input_offset = CONV_3_INPUT_OFFSET;
360     conv_params.output_offset = CONV_3_OUTPUT_OFFSET;
361     conv_params.activation.min = CONV_3_OUT_ACTIVATION_MIN;
362     conv_params.activation.max = CONV_3_OUT_ACTIVATION_MAX;
363     quant_params.multiplier = (int32_t *)conv_3_output_mult;
364     quant_params.shift = (int32_t *)conv_3_output_shift;
365 
366     int32_t buf_size = arm_convolve_s8_get_buffer_size(&input_dims, &filter_dims);
367     ctx.buf = malloc(buf_size);
368     ctx.size = 0;
369 
370     arm_cmsis_nn_status result = arm_convolve_s8(&ctx,
371                                                  &conv_params,
372                                                  &quant_params,
373                                                  &input_dims,
374                                                  input_data,
375                                                  &filter_dims,
376                                                  conv_3_weights,
377                                                  &bias_dims,
378                                                  bias_data,
379                                                  &output_dims,
380                                                  output);
381 
382     if (ctx.buf)
383     {
384         memset(ctx.buf, 0, buf_size);
385         free(ctx.buf);
386     }
387     TEST_ASSERT_EQUAL(expected, result);
388     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
389     memset(output, 0, sizeof(output));
390 
391     buf_size = arm_convolve_wrapper_s8_get_buffer_size(&conv_params, &input_dims, &filter_dims, &output_dims);
392     ctx.buf = malloc(buf_size);
393     ctx.size = 0;
394 
395     result = arm_convolve_wrapper_s8(&ctx,
396                                      &conv_params,
397                                      &quant_params,
398                                      &input_dims,
399                                      input_data,
400                                      &filter_dims,
401                                      kernel_data,
402                                      &bias_dims,
403                                      bias_data,
404                                      &output_dims,
405                                      output);
406 
407     if (ctx.buf)
408     {
409         memset(ctx.buf, 0, buf_size);
410         free(ctx.buf);
411     }
412     TEST_ASSERT_EQUAL(expected, result);
413     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
414 }
415 
conv_4_arm_convolve_s8(void)416 void conv_4_arm_convolve_s8(void)
417 {
418     const arm_cmsis_nn_status expected = ARM_CMSIS_NN_SUCCESS;
419     int8_t output[CONV_4_DST_SIZE] = {0};
420 
421     cmsis_nn_context ctx;
422     cmsis_nn_conv_params conv_params;
423     cmsis_nn_per_channel_quant_params quant_params;
424     cmsis_nn_dims input_dims;
425     cmsis_nn_dims filter_dims;
426     cmsis_nn_dims bias_dims;
427     cmsis_nn_dims output_dims;
428 
429     const int32_t *bias_data = conv_4_biases;
430     const int8_t *kernel_data = conv_4_weights;
431     const int8_t *input_data = conv_4_input;
432     const int8_t *output_ref = conv_4_output_ref;
433     const int32_t output_ref_size = CONV_4_DST_SIZE;
434 
435     input_dims.n = CONV_4_INPUT_BATCHES;
436     input_dims.w = CONV_4_INPUT_W;
437     input_dims.h = CONV_4_INPUT_H;
438     input_dims.c = CONV_4_IN_CH;
439     filter_dims.w = CONV_4_FILTER_X;
440     filter_dims.h = CONV_4_FILTER_Y;
441     filter_dims.c = CONV_4_IN_CH;
442     output_dims.w = CONV_4_OUTPUT_W;
443     output_dims.h = CONV_4_OUTPUT_H;
444     output_dims.c = CONV_4_OUT_CH;
445 
446     conv_params.padding.w = CONV_4_PAD_X;
447     conv_params.padding.h = CONV_4_PAD_Y;
448     conv_params.stride.w = CONV_4_STRIDE_X;
449     conv_params.stride.h = CONV_4_STRIDE_Y;
450     conv_params.dilation.w = CONV_4_DILATION_X;
451     conv_params.dilation.h = CONV_4_DILATION_Y;
452 
453     conv_params.input_offset = CONV_4_INPUT_OFFSET;
454     conv_params.output_offset = CONV_4_OUTPUT_OFFSET;
455     conv_params.activation.min = CONV_4_OUT_ACTIVATION_MIN;
456     conv_params.activation.max = CONV_4_OUT_ACTIVATION_MAX;
457     quant_params.multiplier = (int32_t *)conv_4_output_mult;
458     quant_params.shift = (int32_t *)conv_4_output_shift;
459 
460     int32_t buf_size = arm_convolve_s8_get_buffer_size(&input_dims, &filter_dims);
461     ctx.buf = malloc(buf_size);
462     ctx.size = 0;
463 
464     arm_cmsis_nn_status result = arm_convolve_s8(&ctx,
465                                                  &conv_params,
466                                                  &quant_params,
467                                                  &input_dims,
468                                                  input_data,
469                                                  &filter_dims,
470                                                  conv_4_weights,
471                                                  &bias_dims,
472                                                  bias_data,
473                                                  &output_dims,
474                                                  output);
475 
476     if (ctx.buf)
477     {
478         memset(ctx.buf, 0, buf_size);
479         free(ctx.buf);
480     }
481     TEST_ASSERT_EQUAL(expected, result);
482     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
483     memset(output, 0, sizeof(output));
484 
485     buf_size = arm_convolve_wrapper_s8_get_buffer_size(&conv_params, &input_dims, &filter_dims, &output_dims);
486     ctx.buf = malloc(buf_size);
487     ctx.size = 0;
488 
489     result = arm_convolve_wrapper_s8(&ctx,
490                                      &conv_params,
491                                      &quant_params,
492                                      &input_dims,
493                                      input_data,
494                                      &filter_dims,
495                                      kernel_data,
496                                      &bias_dims,
497                                      bias_data,
498                                      &output_dims,
499                                      output);
500 
501     if (ctx.buf)
502     {
503         memset(ctx.buf, 0, buf_size);
504         free(ctx.buf);
505     }
506     TEST_ASSERT_EQUAL(expected, result);
507     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
508 }
509 
conv_out_activation_arm_convolve_s8(void)510 void conv_out_activation_arm_convolve_s8(void)
511 {
512     int8_t output[CONV_OUT_ACTIVATION_DST_SIZE] = {0};
513 
514     cmsis_nn_context ctx;
515     cmsis_nn_conv_params conv_params;
516     cmsis_nn_per_channel_quant_params quant_params;
517     cmsis_nn_dims input_dims;
518     cmsis_nn_dims filter_dims;
519     cmsis_nn_dims bias_dims;
520     cmsis_nn_dims output_dims;
521 
522     const int32_t *bias_data = conv_out_activation_biases;
523     const int8_t *kernel_data = conv_out_activation_weights;
524     const int8_t *input_data = conv_out_activation_input;
525     const int8_t *output_ref = conv_out_activation_output_ref;
526     const int32_t output_ref_size = CONV_OUT_ACTIVATION_DST_SIZE;
527 
528     input_dims.n = CONV_OUT_ACTIVATION_INPUT_BATCHES;
529     input_dims.w = CONV_OUT_ACTIVATION_INPUT_W;
530     input_dims.h = CONV_OUT_ACTIVATION_INPUT_H;
531     input_dims.c = CONV_OUT_ACTIVATION_IN_CH;
532     filter_dims.w = CONV_OUT_ACTIVATION_FILTER_X;
533     filter_dims.h = CONV_OUT_ACTIVATION_FILTER_Y;
534     filter_dims.c = CONV_OUT_ACTIVATION_IN_CH;
535     output_dims.w = CONV_OUT_ACTIVATION_OUTPUT_W;
536     output_dims.h = CONV_OUT_ACTIVATION_OUTPUT_H;
537     output_dims.c = CONV_OUT_ACTIVATION_OUT_CH;
538 
539     conv_params.padding.w = CONV_OUT_ACTIVATION_PAD_X;
540     conv_params.padding.h = CONV_OUT_ACTIVATION_PAD_Y;
541     conv_params.stride.w = CONV_OUT_ACTIVATION_STRIDE_X;
542     conv_params.stride.h = CONV_OUT_ACTIVATION_STRIDE_Y;
543     conv_params.dilation.w = CONV_OUT_ACTIVATION_DILATION_X;
544     conv_params.dilation.h = CONV_OUT_ACTIVATION_DILATION_Y;
545 
546     conv_params.input_offset = CONV_OUT_ACTIVATION_INPUT_OFFSET;
547     conv_params.output_offset = CONV_OUT_ACTIVATION_OUTPUT_OFFSET;
548     conv_params.activation.min = CONV_OUT_ACTIVATION_OUT_ACTIVATION_MIN;
549     conv_params.activation.max = CONV_OUT_ACTIVATION_OUT_ACTIVATION_MAX;
550     quant_params.multiplier = (int32_t *)conv_out_activation_output_mult;
551     quant_params.shift = (int32_t *)conv_out_activation_output_shift;
552 
553     int32_t buf_size = arm_convolve_wrapper_s8_get_buffer_size(&conv_params, &input_dims, &filter_dims, &output_dims);
554     ctx.buf = malloc(buf_size);
555 
556     arm_cmsis_nn_status result = arm_convolve_wrapper_s8(&ctx,
557                                                          &conv_params,
558                                                          &quant_params,
559                                                          &input_dims,
560                                                          input_data,
561                                                          &filter_dims,
562                                                          kernel_data,
563                                                          &bias_dims,
564                                                          bias_data,
565                                                          &output_dims,
566                                                          output);
567     if (ctx.buf)
568     {
569         memset(ctx.buf, 0, buf_size);
570         free(ctx.buf);
571     }
572     TEST_ASSERT_EQUAL(ARM_CMSIS_NN_SUCCESS, result);
573     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
574 }
575 
conv_2x2_dilation_arm_convolve_s8(void)576 void conv_2x2_dilation_arm_convolve_s8(void)
577 {
578     int8_t output[CONV_2X2_DILATION_DST_SIZE] = {0};
579 
580     cmsis_nn_context ctx;
581     cmsis_nn_conv_params conv_params;
582     cmsis_nn_per_channel_quant_params quant_params;
583     cmsis_nn_dims input_dims;
584     cmsis_nn_dims filter_dims;
585     cmsis_nn_dims bias_dims;
586     cmsis_nn_dims output_dims;
587 
588     const arm_cmsis_nn_status expected = ARM_CMSIS_NN_SUCCESS;
589     const int32_t *bias_data = conv_2x2_dilation_biases;
590     const int8_t *kernel_data = conv_2x2_dilation_weights;
591     const int8_t *input_data = conv_2x2_dilation_input;
592     const int8_t *output_ref = conv_2x2_dilation_output_ref;
593     const int32_t output_ref_size = CONV_2X2_DILATION_DST_SIZE;
594 
595     input_dims.n = CONV_2X2_DILATION_INPUT_BATCHES;
596     input_dims.w = CONV_2X2_DILATION_INPUT_W;
597     input_dims.h = CONV_2X2_DILATION_INPUT_H;
598     input_dims.c = CONV_2X2_DILATION_IN_CH;
599     filter_dims.w = CONV_2X2_DILATION_FILTER_X;
600     filter_dims.h = CONV_2X2_DILATION_FILTER_Y;
601     filter_dims.c = CONV_2X2_DILATION_IN_CH;
602     output_dims.w = CONV_2X2_DILATION_OUTPUT_W;
603     output_dims.h = CONV_2X2_DILATION_OUTPUT_H;
604     output_dims.c = CONV_2X2_DILATION_OUT_CH;
605 
606     conv_params.padding.w = CONV_2X2_DILATION_PAD_X;
607     conv_params.padding.h = CONV_2X2_DILATION_PAD_Y;
608     conv_params.stride.w = CONV_2X2_DILATION_STRIDE_X;
609     conv_params.stride.h = CONV_2X2_DILATION_STRIDE_Y;
610     conv_params.dilation.w = CONV_2X2_DILATION_DILATION_X;
611     conv_params.dilation.h = CONV_2X2_DILATION_DILATION_Y;
612 
613     conv_params.input_offset = CONV_2X2_DILATION_INPUT_OFFSET;
614     conv_params.output_offset = CONV_2X2_DILATION_OUTPUT_OFFSET;
615     conv_params.activation.min = CONV_2X2_DILATION_OUT_ACTIVATION_MIN;
616     conv_params.activation.max = CONV_2X2_DILATION_OUT_ACTIVATION_MAX;
617     quant_params.multiplier = (int32_t *)conv_2x2_dilation_output_mult;
618     quant_params.shift = (int32_t *)conv_2x2_dilation_output_shift;
619 
620     int32_t buf_size = arm_convolve_s8_get_buffer_size(&input_dims, &filter_dims);
621     ctx.buf = malloc(buf_size);
622     ctx.size = 0;
623 
624     arm_cmsis_nn_status result = arm_convolve_s8(&ctx,
625                                                  &conv_params,
626                                                  &quant_params,
627                                                  &input_dims,
628                                                  input_data,
629                                                  &filter_dims,
630                                                  kernel_data,
631                                                  &bias_dims,
632                                                  bias_data,
633                                                  &output_dims,
634                                                  output);
635 
636     if (ctx.buf)
637     {
638         memset(ctx.buf, 0, buf_size);
639         free(ctx.buf);
640     }
641     TEST_ASSERT_EQUAL(expected, result);
642     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
643     memset(output, 0, sizeof(output));
644 
645     buf_size = arm_convolve_wrapper_s8_get_buffer_size(&conv_params, &input_dims, &filter_dims, &output_dims);
646     ctx.buf = malloc(buf_size);
647     ctx.size = 0;
648 
649     result = arm_convolve_wrapper_s8(&ctx,
650                                      &conv_params,
651                                      &quant_params,
652                                      &input_dims,
653                                      input_data,
654                                      &filter_dims,
655                                      kernel_data,
656                                      &bias_dims,
657                                      bias_data,
658                                      &output_dims,
659                                      output);
660 
661     if (ctx.buf)
662     {
663         memset(ctx.buf, 0, buf_size);
664         free(ctx.buf);
665     }
666     TEST_ASSERT_EQUAL(expected, result);
667     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
668 }
669 
conv_2x2_dilation_5x5_input_arm_convolve_s8(void)670 void conv_2x2_dilation_5x5_input_arm_convolve_s8(void)
671 {
672     int8_t output[CONV_2X2_DILATION_5X5_INPUT_DST_SIZE] = {0};
673 
674     cmsis_nn_context ctx;
675     cmsis_nn_conv_params conv_params;
676     cmsis_nn_per_channel_quant_params quant_params;
677     cmsis_nn_dims input_dims;
678     cmsis_nn_dims filter_dims;
679     cmsis_nn_dims bias_dims;
680     cmsis_nn_dims output_dims;
681 
682     const int32_t *bias_data = conv_2x2_dilation_5x5_input_biases;
683     const int8_t *kernel_data = conv_2x2_dilation_5x5_input_weights;
684     const int8_t *input_data = conv_2x2_dilation_5x5_input_input;
685     const int8_t *output_ref = conv_2x2_dilation_5x5_input_output_ref;
686     const int32_t output_ref_size = CONV_2X2_DILATION_5X5_INPUT_DST_SIZE;
687     const arm_cmsis_nn_status expected = ARM_CMSIS_NN_SUCCESS;
688 
689     input_dims.n = CONV_2X2_DILATION_5X5_INPUT_INPUT_BATCHES;
690     input_dims.w = CONV_2X2_DILATION_5X5_INPUT_INPUT_W;
691     input_dims.h = CONV_2X2_DILATION_5X5_INPUT_INPUT_H;
692     input_dims.c = CONV_2X2_DILATION_5X5_INPUT_IN_CH;
693     filter_dims.w = CONV_2X2_DILATION_5X5_INPUT_FILTER_X;
694     filter_dims.h = CONV_2X2_DILATION_5X5_INPUT_FILTER_Y;
695     filter_dims.c = CONV_2X2_DILATION_5X5_INPUT_IN_CH;
696     output_dims.w = CONV_2X2_DILATION_5X5_INPUT_OUTPUT_W;
697     output_dims.h = CONV_2X2_DILATION_5X5_INPUT_OUTPUT_H;
698     output_dims.c = CONV_2X2_DILATION_5X5_INPUT_OUT_CH;
699 
700     conv_params.padding.w = CONV_2X2_DILATION_5X5_INPUT_PAD_X;
701     conv_params.padding.h = CONV_2X2_DILATION_5X5_INPUT_PAD_Y;
702     conv_params.stride.w = CONV_2X2_DILATION_5X5_INPUT_STRIDE_X;
703     conv_params.stride.h = CONV_2X2_DILATION_5X5_INPUT_STRIDE_Y;
704     conv_params.dilation.w = CONV_2X2_DILATION_5X5_INPUT_DILATION_X;
705     conv_params.dilation.h = CONV_2X2_DILATION_5X5_INPUT_DILATION_Y;
706 
707     conv_params.input_offset = CONV_2X2_DILATION_5X5_INPUT_INPUT_OFFSET;
708     conv_params.output_offset = CONV_2X2_DILATION_5X5_INPUT_OUTPUT_OFFSET;
709     conv_params.activation.min = CONV_2X2_DILATION_5X5_INPUT_OUT_ACTIVATION_MIN;
710     conv_params.activation.max = CONV_2X2_DILATION_5X5_INPUT_OUT_ACTIVATION_MAX;
711     quant_params.multiplier = (int32_t *)conv_2x2_dilation_5x5_input_output_mult;
712     quant_params.shift = (int32_t *)conv_2x2_dilation_5x5_input_output_shift;
713 
714     int32_t buf_size = arm_convolve_s8_get_buffer_size(&input_dims, &filter_dims);
715     ctx.buf = malloc(buf_size);
716 
717     arm_cmsis_nn_status result = arm_convolve_s8(&ctx,
718                                                  &conv_params,
719                                                  &quant_params,
720                                                  &input_dims,
721                                                  input_data,
722                                                  &filter_dims,
723                                                  kernel_data,
724                                                  &bias_dims,
725                                                  bias_data,
726                                                  &output_dims,
727                                                  output);
728     if (ctx.buf)
729     {
730         memset(ctx.buf, 0, buf_size);
731         free(ctx.buf);
732     }
733     TEST_ASSERT_EQUAL(expected, result);
734     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
735     memset(output, 0, sizeof(output));
736 
737     buf_size = arm_convolve_wrapper_s8_get_buffer_size(&conv_params, &input_dims, &filter_dims, &output_dims);
738     ctx.buf = malloc(buf_size);
739     ctx.size = 0;
740 
741     result = arm_convolve_wrapper_s8(&ctx,
742                                      &conv_params,
743                                      &quant_params,
744                                      &input_dims,
745                                      input_data,
746                                      &filter_dims,
747                                      kernel_data,
748                                      &bias_dims,
749                                      bias_data,
750                                      &output_dims,
751                                      output);
752 
753     if (ctx.buf)
754     {
755         memset(ctx.buf, 0, buf_size);
756         free(ctx.buf);
757     }
758     TEST_ASSERT_EQUAL(expected, result);
759     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
760 }
761 
conv_3x3_dilation_5x5_input_arm_convolve_s8(void)762 void conv_3x3_dilation_5x5_input_arm_convolve_s8(void)
763 {
764     int8_t output[CONV_3X3_DILATION_5X5_INPUT_DST_SIZE] = {0};
765 
766     cmsis_nn_context ctx;
767     cmsis_nn_conv_params conv_params;
768     cmsis_nn_per_channel_quant_params quant_params;
769     cmsis_nn_dims input_dims;
770     cmsis_nn_dims filter_dims;
771     cmsis_nn_dims bias_dims;
772     cmsis_nn_dims output_dims;
773 
774     const int32_t *bias_data = conv_3x3_dilation_5x5_input_biases;
775     const int8_t *kernel_data = conv_3x3_dilation_5x5_input_weights;
776     const int8_t *input_data = conv_3x3_dilation_5x5_input_input;
777     const int8_t *output_ref = conv_3x3_dilation_5x5_input_output_ref;
778     const int32_t output_ref_size = CONV_3X3_DILATION_5X5_INPUT_DST_SIZE;
779     const arm_cmsis_nn_status expected = ARM_CMSIS_NN_SUCCESS;
780 
781     input_dims.n = CONV_3X3_DILATION_5X5_INPUT_INPUT_BATCHES;
782     input_dims.w = CONV_3X3_DILATION_5X5_INPUT_INPUT_W;
783     input_dims.h = CONV_3X3_DILATION_5X5_INPUT_INPUT_H;
784     input_dims.c = CONV_3X3_DILATION_5X5_INPUT_IN_CH;
785     filter_dims.w = CONV_3X3_DILATION_5X5_INPUT_FILTER_X;
786     filter_dims.h = CONV_3X3_DILATION_5X5_INPUT_FILTER_Y;
787     filter_dims.c = CONV_3X3_DILATION_5X5_INPUT_IN_CH;
788     output_dims.w = CONV_3X3_DILATION_5X5_INPUT_OUTPUT_W;
789     output_dims.h = CONV_3X3_DILATION_5X5_INPUT_OUTPUT_H;
790     output_dims.c = CONV_3X3_DILATION_5X5_INPUT_OUT_CH;
791 
792     conv_params.padding.w = CONV_3X3_DILATION_5X5_INPUT_PAD_X;
793     conv_params.padding.h = CONV_3X3_DILATION_5X5_INPUT_PAD_Y;
794     conv_params.stride.w = CONV_3X3_DILATION_5X5_INPUT_STRIDE_X;
795     conv_params.stride.h = CONV_3X3_DILATION_5X5_INPUT_STRIDE_Y;
796     conv_params.dilation.w = CONV_3X3_DILATION_5X5_INPUT_DILATION_X;
797     conv_params.dilation.h = CONV_3X3_DILATION_5X5_INPUT_DILATION_Y;
798 
799     conv_params.input_offset = CONV_3X3_DILATION_5X5_INPUT_INPUT_OFFSET;
800     conv_params.output_offset = CONV_3X3_DILATION_5X5_INPUT_OUTPUT_OFFSET;
801     conv_params.activation.min = CONV_3X3_DILATION_5X5_INPUT_OUT_ACTIVATION_MIN;
802     conv_params.activation.max = CONV_3X3_DILATION_5X5_INPUT_OUT_ACTIVATION_MAX;
803     quant_params.multiplier = (int32_t *)conv_3x3_dilation_5x5_input_output_mult;
804     quant_params.shift = (int32_t *)conv_3x3_dilation_5x5_input_output_shift;
805 
806     int32_t buf_size = arm_convolve_s8_get_buffer_size(&input_dims, &filter_dims);
807     ctx.buf = malloc(buf_size);
808 
809     arm_cmsis_nn_status result = arm_convolve_s8(&ctx,
810                                                  &conv_params,
811                                                  &quant_params,
812                                                  &input_dims,
813                                                  input_data,
814                                                  &filter_dims,
815                                                  kernel_data,
816                                                  &bias_dims,
817                                                  bias_data,
818                                                  &output_dims,
819                                                  output);
820     if (ctx.buf)
821     {
822         memset(ctx.buf, 0, buf_size);
823         free(ctx.buf);
824     }
825     TEST_ASSERT_EQUAL(expected, result);
826     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
827     memset(output, 0, sizeof(output));
828 
829     buf_size = arm_convolve_wrapper_s8_get_buffer_size(&conv_params, &input_dims, &filter_dims, &output_dims);
830     ctx.buf = malloc(buf_size);
831     ctx.size = 0;
832 
833     result = arm_convolve_wrapper_s8(&ctx,
834                                      &conv_params,
835                                      &quant_params,
836                                      &input_dims,
837                                      input_data,
838                                      &filter_dims,
839                                      kernel_data,
840                                      &bias_dims,
841                                      bias_data,
842                                      &output_dims,
843                                      output);
844 
845     if (ctx.buf)
846     {
847         memset(ctx.buf, 0, buf_size);
848         free(ctx.buf);
849     }
850     TEST_ASSERT_EQUAL(expected, result);
851     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
852 }
853 
conv_2x3_dilation_arm_convolve_s8(void)854 void conv_2x3_dilation_arm_convolve_s8(void)
855 {
856     int8_t output[CONV_2X3_DILATION_DST_SIZE] = {0};
857 
858     cmsis_nn_context ctx;
859     cmsis_nn_conv_params conv_params;
860     cmsis_nn_per_channel_quant_params quant_params;
861     cmsis_nn_dims input_dims;
862     cmsis_nn_dims filter_dims;
863     cmsis_nn_dims bias_dims;
864     cmsis_nn_dims output_dims;
865 
866     const int32_t *bias_data = conv_2x3_dilation_biases;
867     const int8_t *kernel_data = conv_2x3_dilation_weights;
868     const int8_t *input_data = conv_2x3_dilation_input;
869     const int8_t *output_ref = conv_2x3_dilation_output_ref;
870     const int32_t output_ref_size = CONV_2X3_DILATION_DST_SIZE;
871     const arm_cmsis_nn_status expected = ARM_CMSIS_NN_SUCCESS;
872 
873     input_dims.n = CONV_2X3_DILATION_INPUT_BATCHES;
874     input_dims.w = CONV_2X3_DILATION_INPUT_W;
875     input_dims.h = CONV_2X3_DILATION_INPUT_H;
876     input_dims.c = CONV_2X3_DILATION_IN_CH;
877     filter_dims.w = CONV_2X3_DILATION_FILTER_X;
878     filter_dims.h = CONV_2X3_DILATION_FILTER_Y;
879     filter_dims.c = CONV_2X3_DILATION_IN_CH;
880     output_dims.w = CONV_2X3_DILATION_OUTPUT_W;
881     output_dims.h = CONV_2X3_DILATION_OUTPUT_H;
882     output_dims.c = CONV_2X3_DILATION_OUT_CH;
883 
884     conv_params.padding.w = CONV_2X3_DILATION_PAD_X;
885     conv_params.padding.h = CONV_2X3_DILATION_PAD_Y;
886     conv_params.stride.w = CONV_2X3_DILATION_STRIDE_X;
887     conv_params.stride.h = CONV_2X3_DILATION_STRIDE_Y;
888     conv_params.dilation.w = CONV_2X3_DILATION_DILATION_X;
889     conv_params.dilation.h = CONV_2X3_DILATION_DILATION_Y;
890 
891     conv_params.input_offset = CONV_2X3_DILATION_INPUT_OFFSET;
892     conv_params.output_offset = CONV_2X3_DILATION_OUTPUT_OFFSET;
893     conv_params.activation.min = CONV_2X3_DILATION_OUT_ACTIVATION_MIN;
894     conv_params.activation.max = CONV_2X3_DILATION_OUT_ACTIVATION_MAX;
895     quant_params.multiplier = (int32_t *)conv_2x3_dilation_output_mult;
896     quant_params.shift = (int32_t *)conv_2x3_dilation_output_shift;
897 
898     int32_t buf_size = arm_convolve_s8_get_buffer_size(&input_dims, &filter_dims);
899     ctx.buf = malloc(buf_size);
900 
901     arm_cmsis_nn_status result = arm_convolve_s8(&ctx,
902                                                  &conv_params,
903                                                  &quant_params,
904                                                  &input_dims,
905                                                  input_data,
906                                                  &filter_dims,
907                                                  kernel_data,
908                                                  &bias_dims,
909                                                  bias_data,
910                                                  &output_dims,
911                                                  output);
912     if (ctx.buf)
913     {
914         memset(ctx.buf, 0, buf_size);
915         free(ctx.buf);
916     }
917     TEST_ASSERT_EQUAL(expected, result);
918     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
919     memset(output, 0, sizeof(output));
920 
921     buf_size = arm_convolve_wrapper_s8_get_buffer_size(&conv_params, &input_dims, &filter_dims, &output_dims);
922     ctx.buf = malloc(buf_size);
923     ctx.size = 0;
924 
925     result = arm_convolve_wrapper_s8(&ctx,
926                                      &conv_params,
927                                      &quant_params,
928                                      &input_dims,
929                                      input_data,
930                                      &filter_dims,
931                                      kernel_data,
932                                      &bias_dims,
933                                      bias_data,
934                                      &output_dims,
935                                      output);
936 
937     if (ctx.buf)
938     {
939         memset(ctx.buf, 0, buf_size);
940         free(ctx.buf);
941     }
942     TEST_ASSERT_EQUAL(expected, result);
943     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
944 }
945 
conv_3x2_dilation_arm_convolve_s8(void)946 void conv_3x2_dilation_arm_convolve_s8(void)
947 {
948     int8_t output[CONV_3X2_DILATION_DST_SIZE] = {0};
949 
950     cmsis_nn_context ctx;
951     cmsis_nn_conv_params conv_params;
952     cmsis_nn_per_channel_quant_params quant_params;
953     cmsis_nn_dims input_dims;
954     cmsis_nn_dims filter_dims;
955     cmsis_nn_dims bias_dims;
956     cmsis_nn_dims output_dims;
957 
958     const int32_t *bias_data = conv_3x2_dilation_biases;
959     const int8_t *kernel_data = conv_3x2_dilation_weights;
960     const int8_t *input_data = conv_3x2_dilation_input;
961     const int8_t *output_ref = conv_3x2_dilation_output_ref;
962     const int32_t output_ref_size = CONV_3X2_DILATION_DST_SIZE;
963     const arm_cmsis_nn_status expected = ARM_CMSIS_NN_SUCCESS;
964 
965     input_dims.n = CONV_3X2_DILATION_INPUT_BATCHES;
966     input_dims.w = CONV_3X2_DILATION_INPUT_W;
967     input_dims.h = CONV_3X2_DILATION_INPUT_H;
968     input_dims.c = CONV_3X2_DILATION_IN_CH;
969     filter_dims.w = CONV_3X2_DILATION_FILTER_X;
970     filter_dims.h = CONV_3X2_DILATION_FILTER_Y;
971     filter_dims.c = CONV_3X2_DILATION_IN_CH;
972     output_dims.w = CONV_3X2_DILATION_OUTPUT_W;
973     output_dims.h = CONV_3X2_DILATION_OUTPUT_H;
974     output_dims.c = CONV_3X2_DILATION_OUT_CH;
975 
976     conv_params.padding.w = CONV_3X2_DILATION_PAD_X;
977     conv_params.padding.h = CONV_3X2_DILATION_PAD_Y;
978     conv_params.stride.w = CONV_3X2_DILATION_STRIDE_X;
979     conv_params.stride.h = CONV_3X2_DILATION_STRIDE_Y;
980     conv_params.dilation.w = CONV_3X2_DILATION_DILATION_X;
981     conv_params.dilation.h = CONV_3X2_DILATION_DILATION_Y;
982 
983     conv_params.input_offset = CONV_3X2_DILATION_INPUT_OFFSET;
984     conv_params.output_offset = CONV_3X2_DILATION_OUTPUT_OFFSET;
985     conv_params.activation.min = CONV_3X2_DILATION_OUT_ACTIVATION_MIN;
986     conv_params.activation.max = CONV_3X2_DILATION_OUT_ACTIVATION_MAX;
987     quant_params.multiplier = (int32_t *)conv_3x2_dilation_output_mult;
988     quant_params.shift = (int32_t *)conv_3x2_dilation_output_shift;
989 
990     int32_t buf_size = arm_convolve_s8_get_buffer_size(&input_dims, &filter_dims);
991     ctx.buf = malloc(buf_size);
992 
993     arm_cmsis_nn_status result = arm_convolve_s8(&ctx,
994                                                  &conv_params,
995                                                  &quant_params,
996                                                  &input_dims,
997                                                  input_data,
998                                                  &filter_dims,
999                                                  kernel_data,
1000                                                  &bias_dims,
1001                                                  bias_data,
1002                                                  &output_dims,
1003                                                  output);
1004     if (ctx.buf)
1005     {
1006         memset(ctx.buf, 0, buf_size);
1007         free(ctx.buf);
1008     }
1009     TEST_ASSERT_EQUAL(expected, result);
1010     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
1011     memset(output, 0, sizeof(output));
1012 
1013     buf_size = arm_convolve_wrapper_s8_get_buffer_size(&conv_params, &input_dims, &filter_dims, &output_dims);
1014     ctx.buf = malloc(buf_size);
1015     ctx.size = 0;
1016 
1017     result = arm_convolve_wrapper_s8(&ctx,
1018                                      &conv_params,
1019                                      &quant_params,
1020                                      &input_dims,
1021                                      input_data,
1022                                      &filter_dims,
1023                                      kernel_data,
1024                                      &bias_dims,
1025                                      bias_data,
1026                                      &output_dims,
1027                                      output);
1028 
1029     if (ctx.buf)
1030     {
1031         memset(ctx.buf, 0, buf_size);
1032         free(ctx.buf);
1033     }
1034     TEST_ASSERT_EQUAL(expected, result);
1035     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
1036 }
1037 
conv_dilation_golden_arm_convolve_s8(void)1038 void conv_dilation_golden_arm_convolve_s8(void)
1039 {
1040     int8_t output[CONV_DILATION_GOLDEN_DST_SIZE] = {0};
1041 
1042     cmsis_nn_context ctx;
1043     cmsis_nn_conv_params conv_params;
1044     cmsis_nn_per_channel_quant_params quant_params;
1045     cmsis_nn_dims input_dims;
1046     cmsis_nn_dims filter_dims;
1047     cmsis_nn_dims bias_dims;
1048     cmsis_nn_dims output_dims;
1049 
1050     const int32_t *bias_data = conv_dilation_golden_biases;
1051     const int8_t *kernel_data = conv_dilation_golden_weights;
1052     const int8_t *input_data = conv_dilation_golden_input;
1053     const int8_t *output_ref = conv_dilation_golden_output_ref;
1054     const int32_t output_ref_size = CONV_DILATION_GOLDEN_DST_SIZE;
1055     const arm_cmsis_nn_status expected = ARM_CMSIS_NN_SUCCESS;
1056 
1057     input_dims.n = CONV_DILATION_GOLDEN_INPUT_BATCHES;
1058     input_dims.w = CONV_DILATION_GOLDEN_INPUT_W;
1059     input_dims.h = CONV_DILATION_GOLDEN_INPUT_H;
1060     input_dims.c = CONV_DILATION_GOLDEN_IN_CH;
1061     filter_dims.w = CONV_DILATION_GOLDEN_FILTER_X;
1062     filter_dims.h = CONV_DILATION_GOLDEN_FILTER_Y;
1063     filter_dims.c = CONV_DILATION_GOLDEN_IN_CH;
1064     output_dims.w = CONV_DILATION_GOLDEN_OUTPUT_W;
1065     output_dims.h = CONV_DILATION_GOLDEN_OUTPUT_H;
1066     output_dims.c = CONV_DILATION_GOLDEN_OUT_CH;
1067 
1068     conv_params.padding.w = CONV_DILATION_GOLDEN_PAD_X;
1069     conv_params.padding.h = CONV_DILATION_GOLDEN_PAD_Y;
1070     conv_params.stride.w = CONV_DILATION_GOLDEN_STRIDE_X;
1071     conv_params.stride.h = CONV_DILATION_GOLDEN_STRIDE_Y;
1072     conv_params.dilation.w = CONV_DILATION_GOLDEN_DILATION_X;
1073     conv_params.dilation.h = CONV_DILATION_GOLDEN_DILATION_Y;
1074 
1075     conv_params.input_offset = CONV_DILATION_GOLDEN_INPUT_OFFSET;
1076     conv_params.output_offset = CONV_DILATION_GOLDEN_OUTPUT_OFFSET;
1077     conv_params.activation.min = CONV_DILATION_GOLDEN_OUT_ACTIVATION_MIN;
1078     conv_params.activation.max = CONV_DILATION_GOLDEN_OUT_ACTIVATION_MAX;
1079     quant_params.multiplier = (int32_t *)conv_dilation_golden_output_mult;
1080     quant_params.shift = (int32_t *)conv_dilation_golden_output_shift;
1081 
1082     int32_t buf_size = arm_convolve_s8_get_buffer_size(&input_dims, &filter_dims);
1083     ctx.buf = malloc(buf_size);
1084 
1085     arm_cmsis_nn_status result = arm_convolve_s8(&ctx,
1086                                                  &conv_params,
1087                                                  &quant_params,
1088                                                  &input_dims,
1089                                                  input_data,
1090                                                  &filter_dims,
1091                                                  kernel_data,
1092                                                  &bias_dims,
1093                                                  bias_data,
1094                                                  &output_dims,
1095                                                  output);
1096     if (ctx.buf)
1097     {
1098         memset(ctx.buf, 0, buf_size);
1099         free(ctx.buf);
1100     }
1101     TEST_ASSERT_EQUAL(expected, result);
1102     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
1103     memset(output, 0, sizeof(output));
1104 
1105     buf_size = arm_convolve_wrapper_s8_get_buffer_size(&conv_params, &input_dims, &filter_dims, &output_dims);
1106     ctx.buf = malloc(buf_size);
1107     ctx.size = 0;
1108 
1109     result = arm_convolve_wrapper_s8(&ctx,
1110                                      &conv_params,
1111                                      &quant_params,
1112                                      &input_dims,
1113                                      input_data,
1114                                      &filter_dims,
1115                                      kernel_data,
1116                                      &bias_dims,
1117                                      bias_data,
1118                                      &output_dims,
1119                                      output);
1120 
1121     if (ctx.buf)
1122     {
1123         memset(ctx.buf, 0, buf_size);
1124         free(ctx.buf);
1125     }
1126     TEST_ASSERT_EQUAL(expected, result);
1127     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
1128 }
1129 
conv_5_arm_convolve_s8(void)1130 void conv_5_arm_convolve_s8(void)
1131 {
1132     const arm_cmsis_nn_status expected = ARM_CMSIS_NN_SUCCESS;
1133     int8_t output[CONV_5_DST_SIZE] = {0};
1134 
1135     cmsis_nn_context ctx;
1136     cmsis_nn_conv_params conv_params;
1137     cmsis_nn_per_channel_quant_params quant_params;
1138     cmsis_nn_dims input_dims;
1139     cmsis_nn_dims filter_dims;
1140     cmsis_nn_dims bias_dims;
1141     cmsis_nn_dims output_dims;
1142 
1143     const int32_t *bias_data = conv_5_biases;
1144     const int8_t *kernel_data = conv_5_weights;
1145     const int8_t *input_data = conv_5_input;
1146     const int8_t *output_ref = conv_5_output_ref;
1147     const int32_t output_ref_size = CONV_5_DST_SIZE;
1148 
1149     input_dims.n = CONV_5_INPUT_BATCHES;
1150     input_dims.w = CONV_5_INPUT_W;
1151     input_dims.h = CONV_5_INPUT_H;
1152     input_dims.c = CONV_5_IN_CH;
1153     filter_dims.w = CONV_5_FILTER_X;
1154     filter_dims.h = CONV_5_FILTER_Y;
1155     filter_dims.c = CONV_5_IN_CH;
1156     output_dims.w = CONV_5_OUTPUT_W;
1157     output_dims.h = CONV_5_OUTPUT_H;
1158     output_dims.c = CONV_5_OUT_CH;
1159 
1160     conv_params.padding.w = CONV_5_PAD_X;
1161     conv_params.padding.h = CONV_5_PAD_Y;
1162     conv_params.stride.w = CONV_5_STRIDE_X;
1163     conv_params.stride.h = CONV_5_STRIDE_Y;
1164     conv_params.dilation.w = CONV_5_DILATION_X;
1165     conv_params.dilation.h = CONV_5_DILATION_Y;
1166 
1167     conv_params.input_offset = CONV_5_INPUT_OFFSET;
1168     conv_params.output_offset = CONV_5_OUTPUT_OFFSET;
1169     conv_params.activation.min = CONV_5_OUT_ACTIVATION_MIN;
1170     conv_params.activation.max = CONV_5_OUT_ACTIVATION_MAX;
1171     quant_params.multiplier = (int32_t *)conv_5_output_mult;
1172     quant_params.shift = (int32_t *)conv_5_output_shift;
1173 
1174     int32_t buf_size = arm_convolve_s8_get_buffer_size(&input_dims, &filter_dims);
1175     ctx.buf = malloc(buf_size);
1176     ctx.size = 0;
1177 
1178     arm_cmsis_nn_status result = arm_convolve_s8(&ctx,
1179                                                  &conv_params,
1180                                                  &quant_params,
1181                                                  &input_dims,
1182                                                  input_data,
1183                                                  &filter_dims,
1184                                                  conv_5_weights,
1185                                                  &bias_dims,
1186                                                  bias_data,
1187                                                  &output_dims,
1188                                                  output);
1189 
1190     if (ctx.buf)
1191     {
1192         memset(ctx.buf, 0, buf_size);
1193         free(ctx.buf);
1194     }
1195     TEST_ASSERT_EQUAL(expected, result);
1196     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
1197     memset(output, 0, sizeof(output));
1198 
1199     buf_size = arm_convolve_wrapper_s8_get_buffer_size(&conv_params, &input_dims, &filter_dims, &output_dims);
1200     ctx.buf = malloc(buf_size);
1201     ctx.size = 0;
1202 
1203     result = arm_convolve_wrapper_s8(&ctx,
1204                                      &conv_params,
1205                                      &quant_params,
1206                                      &input_dims,
1207                                      input_data,
1208                                      &filter_dims,
1209                                      kernel_data,
1210                                      &bias_dims,
1211                                      bias_data,
1212                                      &output_dims,
1213                                      output);
1214 
1215     if (ctx.buf)
1216     {
1217         memset(ctx.buf, 0, buf_size);
1218         free(ctx.buf);
1219     }
1220     TEST_ASSERT_EQUAL(expected, result);
1221     TEST_ASSERT_TRUE(validate(output, output_ref, output_ref_size));
1222 }
1223 
buffer_size_arm_convolve_s8(void)1224 void buffer_size_arm_convolve_s8(void)
1225 {
1226     cmsis_nn_conv_params conv_params;
1227     cmsis_nn_dims input_dims;
1228     cmsis_nn_dims filter_dims;
1229     cmsis_nn_dims output_dims;
1230 
1231     input_dims.n = CONV_5_INPUT_BATCHES;
1232     input_dims.w = CONV_5_INPUT_W;
1233     input_dims.h = CONV_5_INPUT_H;
1234     input_dims.c = CONV_5_IN_CH;
1235     filter_dims.w = CONV_5_FILTER_X;
1236     filter_dims.h = CONV_5_FILTER_Y;
1237     filter_dims.c = CONV_5_IN_CH;
1238     output_dims.w = CONV_5_OUTPUT_W;
1239     output_dims.h = CONV_5_OUTPUT_H;
1240     output_dims.c = CONV_5_OUT_CH;
1241 
1242     conv_params.padding.w = CONV_5_PAD_X;
1243     conv_params.padding.h = CONV_5_PAD_Y;
1244     conv_params.stride.w = CONV_5_STRIDE_X;
1245     conv_params.stride.h = CONV_5_STRIDE_Y;
1246     conv_params.dilation.w = CONV_5_DILATION_X;
1247     conv_params.dilation.h = CONV_5_DILATION_Y;
1248 
1249     conv_params.input_offset = CONV_5_INPUT_OFFSET;
1250     conv_params.output_offset = CONV_5_OUTPUT_OFFSET;
1251     conv_params.activation.min = CONV_5_OUT_ACTIVATION_MIN;
1252     conv_params.activation.max = CONV_5_OUT_ACTIVATION_MAX;
1253 
1254     const int32_t buf_size = arm_convolve_s8_get_buffer_size(&input_dims, &filter_dims);
1255     const int32_t wrapper_buf_size =
1256         arm_convolve_wrapper_s8_get_buffer_size(&conv_params, &input_dims, &filter_dims, &output_dims);
1257 
1258     TEST_ASSERT_EQUAL(wrapper_buf_size, buf_size);
1259 }
1260 
buffer_size_mve_arm_convolve_s8(void)1261 void buffer_size_mve_arm_convolve_s8(void)
1262 {
1263 #if defined(ARM_MATH_MVEI)
1264     cmsis_nn_conv_params conv_params;
1265     cmsis_nn_dims input_dims;
1266     cmsis_nn_dims filter_dims;
1267     cmsis_nn_dims output_dims;
1268 
1269     input_dims.n = CONV_5_INPUT_BATCHES;
1270     input_dims.w = CONV_5_INPUT_W;
1271     input_dims.h = CONV_5_INPUT_H;
1272     input_dims.c = CONV_5_IN_CH;
1273     filter_dims.w = CONV_5_FILTER_X;
1274     filter_dims.h = CONV_5_FILTER_Y;
1275     filter_dims.c = CONV_5_IN_CH;
1276     output_dims.w = CONV_5_OUTPUT_W;
1277     output_dims.h = CONV_5_OUTPUT_H;
1278     output_dims.c = CONV_5_OUT_CH;
1279 
1280     conv_params.padding.w = CONV_5_PAD_X;
1281     conv_params.padding.h = CONV_5_PAD_Y;
1282     conv_params.stride.w = CONV_5_STRIDE_X;
1283     conv_params.stride.h = CONV_5_STRIDE_Y;
1284     conv_params.dilation.w = CONV_5_DILATION_X;
1285     conv_params.dilation.h = CONV_5_DILATION_Y;
1286 
1287     conv_params.input_offset = CONV_5_INPUT_OFFSET;
1288     conv_params.output_offset = CONV_5_OUTPUT_OFFSET;
1289     conv_params.activation.min = CONV_5_OUT_ACTIVATION_MIN;
1290     conv_params.activation.max = CONV_5_OUT_ACTIVATION_MAX;
1291 
1292     const int32_t wrapper_buf_size =
1293         arm_convolve_wrapper_s8_get_buffer_size(&conv_params, &input_dims, &filter_dims, &output_dims);
1294     const int32_t mve_wrapper_buf_size =
1295         arm_convolve_wrapper_s8_get_buffer_size_mve(&conv_params, &input_dims, &filter_dims, &output_dims);
1296 
1297     TEST_ASSERT_EQUAL(wrapper_buf_size, mve_wrapper_buf_size);
1298 #endif
1299 }
1300 
buffer_size_dsp_arm_convolve_s8(void)1301 void buffer_size_dsp_arm_convolve_s8(void)
1302 {
1303 #if defined(ARM_MATH_DSP) && !defined(ARM_MATH_MVEI)
1304     cmsis_nn_conv_params conv_params;
1305     cmsis_nn_dims input_dims;
1306     cmsis_nn_dims filter_dims;
1307     cmsis_nn_dims output_dims;
1308 
1309     input_dims.n = CONV_5_INPUT_BATCHES;
1310     input_dims.w = CONV_5_INPUT_W;
1311     input_dims.h = CONV_5_INPUT_H;
1312     input_dims.c = CONV_5_IN_CH;
1313     filter_dims.w = CONV_5_FILTER_X;
1314     filter_dims.h = CONV_5_FILTER_Y;
1315     filter_dims.c = CONV_5_IN_CH;
1316     output_dims.w = CONV_5_OUTPUT_W;
1317     output_dims.h = CONV_5_OUTPUT_H;
1318     output_dims.c = CONV_5_OUT_CH;
1319 
1320     conv_params.padding.w = CONV_5_PAD_X;
1321     conv_params.padding.h = CONV_5_PAD_Y;
1322     conv_params.stride.w = CONV_5_STRIDE_X;
1323     conv_params.stride.h = CONV_5_STRIDE_Y;
1324     conv_params.dilation.w = CONV_5_DILATION_X;
1325     conv_params.dilation.h = CONV_5_DILATION_Y;
1326 
1327     conv_params.input_offset = CONV_5_INPUT_OFFSET;
1328     conv_params.output_offset = CONV_5_OUTPUT_OFFSET;
1329     conv_params.activation.min = CONV_5_OUT_ACTIVATION_MIN;
1330     conv_params.activation.max = CONV_5_OUT_ACTIVATION_MAX;
1331 
1332     const int32_t wrapper_buf_size =
1333         arm_convolve_wrapper_s8_get_buffer_size(&conv_params, &input_dims, &filter_dims, &output_dims);
1334     const int32_t dsp_wrapper_buf_size =
1335         arm_convolve_wrapper_s8_get_buffer_size_dsp(&conv_params, &input_dims, &filter_dims, &output_dims);
1336 
1337     TEST_ASSERT_EQUAL(wrapper_buf_size, dsp_wrapper_buf_size);
1338 #endif
1339 }
1340