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