CMSIS-NN: add kernel and unittest for int16 pooling (#1408)
Co-authored-by: Måns Nilsson <mans.nilsson@arm.com>
Change-Id: Iafcfd0c2509d23566fdbb2709796e2c210fa1083
Co-authored-by: Annie Tallund <annie.tallund@arm.com>
diff --git a/ARM.CMSIS.pdsc b/ARM.CMSIS.pdsc
index 0938273..1fba1b3 100644
--- a/ARM.CMSIS.pdsc
+++ b/ARM.CMSIS.pdsc
@@ -17,6 +17,7 @@
- Support dilation for int8 convolution
- Support dilation for int8 depthwise convolution
- Support for int16 depthwise conv for reference implementation including dilation
+ - Support for int16 average and max pooling for reference implementation
CMSIS-RTOS2:
- RTX 5.5.4 (see revision history for details)
</release>
@@ -2844,7 +2845,9 @@
<file category="source" name="CMSIS/NN/Source/ConcatenationFunctions/arm_concatenation_s8_z.c"/>
<file category="source" name="CMSIS/NN/Source/SVDFunctions/arm_svdf_s8.c"/>
<file category="source" name="CMSIS/NN/Source/PoolingFunctions/arm_max_pool_s8.c"/>
+ <file category="source" name="CMSIS/NN/Source/PoolingFunctions/arm_max_pool_s16.c"/>
<file category="source" name="CMSIS/NN/Source/PoolingFunctions/arm_avgpool_s8.c"/>
+ <file category="source" name="CMSIS/NN/Source/PoolingFunctions/arm_avgpool_s16.c"/>
<file category="source" name="CMSIS/NN/Source/PoolingFunctions/arm_pool_q7_HWC.c"/>
<file category="source" name="CMSIS/NN/Source/BasicMathFunctions/arm_elementwise_mul_s8.c"/>
<file category="source" name="CMSIS/NN/Source/BasicMathFunctions/arm_elementwise_add_s8.c"/>
diff --git a/CMSIS/NN/Include/arm_nnfunctions.h b/CMSIS/NN/Include/arm_nnfunctions.h
index 8c10637..685e8cc 100644
--- a/CMSIS/NN/Include/arm_nnfunctions.h
+++ b/CMSIS/NN/Include/arm_nnfunctions.h
@@ -21,7 +21,7 @@
* Title: arm_nnfunctions.h
* Description: Public header file for CMSIS NN Library
*
- * $Date: 20 January 2022
+ * $Date: 24 January 2022
* $Revision: V.7.4.0
*
* Target Processor: Cortex-M CPUs
@@ -1916,6 +1916,47 @@
int32_t arm_avgpool_s8_get_buffer_size(const int dim_dst_width, const int ch_src);
/**
+ * @brief s16 average pooling function.
+ *
+ * @param[in, out] ctx Function context (e.g. temporary buffer). Check the function
+ * definition file to see if an additional buffer is required.
+ * Optional function {API}_get_buffer_size() provides the buffer
+ * size if an additional buffer is required.
+ * @param[in] pool_params Pooling parameters
+ * @param[in] input_dims Input (activation) tensor dimensions. Format: [H, W, C_IN]
+ * Argument 'N' is not used.
+ * @param[in] input_data Input (activation) data pointer. Data type: int16
+ * @param[in] filter_dims Filter tensor dimensions. Format: [H, W]
+ * Argument N and C are not used.
+ * @param[in] output_dims Output tensor dimensions. Format: [H, W, C_OUT]
+ * Argument N is not used.
+ * C_OUT equals C_IN.
+ * @param[in, out] output_data Output data pointer. Data type: int16
+ * @return The function returns
+ * <code>ARM_MATH_SUCCESS</code> - Successful operation
+ *
+ * @details
+ * - Supported Framework: TensorFlow Lite
+ *
+ */
+arm_status arm_avgpool_s16(const cmsis_nn_context *ctx,
+ const cmsis_nn_pool_params *pool_params,
+ const cmsis_nn_dims *input_dims,
+ const int16_t *input_data,
+ const cmsis_nn_dims *filter_dims,
+ const cmsis_nn_dims *output_dims,
+ int16_t *output_data);
+
+/**
+ * @brief Get the required buffer size for S16 average pooling function
+ * @param[in] dim_dst_width output tensor dimension
+ * @param[in] ch_src number of input tensor channels
+ * @return The function returns required buffer size in bytes
+ *
+ */
+int32_t arm_avgpool_s16_get_buffer_size(const int dim_dst_width, const int ch_src);
+
+/**
* @brief s8 max pooling function.
*
* @param[in, out] ctx Function context (e.g. temporary buffer). Check the function
@@ -1947,6 +1988,40 @@
const cmsis_nn_dims *filter_dims,
const cmsis_nn_dims *output_dims,
q7_t *output_data);
+
+/**
+ * @brief s16 max pooling function.
+ *
+ * @param[in, out] ctx Function context (e.g. temporary buffer). Check the function
+ * definition file to see if an additional buffer is required.
+ * Optional function {API}_get_buffer_size() provides the buffer
+ * size if an additional buffer is required.
+ * @param[in] pool_params Pooling parameters
+ * @param[in] input_dims Input (activation) tensor dimensions. Format: [H, W, C_IN]
+ * Argument 'N' is not used.
+ * @param[in] input_data Input (activation) data pointer. The input tensor must not
+ * overlap with the output tensor. Data type: int16
+ * @param[in] filter_dims Filter tensor dimensions. Format: [H, W]
+ * Argument N and C are not used.
+ * @param[in] output_dims Output tensor dimensions. Format: [H, W, C_OUT]
+ * Argument N is not used.
+ * C_OUT equals C_IN.
+ * @param[in, out] output_data Output data pointer. Data type: int16
+ * @return The function returns
+ * <code>ARM_MATH_SUCCESS</code> - Successful operation
+ *
+ * @details
+ * - Supported Framework: TensorFlow Lite
+ *
+ */
+arm_status arm_max_pool_s16(const cmsis_nn_context *ctx,
+ const cmsis_nn_pool_params *pool_params,
+ const cmsis_nn_dims *input_dims,
+ const int16_t *src,
+ const cmsis_nn_dims *filter_dims,
+ const cmsis_nn_dims *output_dims,
+ int16_t *dst);
+
/**
* @defgroup Softmax Softmax Functions
*
diff --git a/CMSIS/NN/README.md b/CMSIS/NN/README.md
index 942d22d..9ac6593 100644
--- a/CMSIS/NN/README.md
+++ b/CMSIS/NN/README.md
@@ -39,8 +39,10 @@
|| arm_fully_connected_s8() |FULLY CONNECTED & <br/> MAT MUL | None | No | Yes | Yes | |
|| arm_fully_connected_s16() |FULLY CONNECTED & <br/> MAT MUL | None | No | Yes | No | |
|[Pooling](https://arm-software.github.io/CMSIS_5/NN/html/group__Pooling.html)||||| | ||
-|| arm_avgpool_s8() | AVERAGE POOL | None | input_ch * 2<br/>(DSP only) | Yes| Yes| Best case case is when channels are multiple of 4 or <br/> at the least >= 4 |
+|| arm_avgpool_s8() | AVERAGE POOL | None | input_ch * 2<br/>(DSP only) | Yes| Yes| Best case is when channels are multiple of 4 or <br/> at the least >= 4 |
+|| arm_avgpool_s16() | AVERAGE POOL | None | None | No| No| Best case is when channels are multiple of 4 or <br/> at the least >= 4 |
|| arm_maxpool_s8() | MAX POOL | None | None | Yes| Yes| |
+|| arm_maxpool_s16() | MAX POOL | None | None | No| No| |
|[Softmax](https://arm-software.github.io/CMSIS_5/NN/html/group__Softmax.html)||||| | ||
||arm_softmax_q7()| SOFTMAX | None | None | Yes | No | Not bit exact to TFLu but can be up to 70x faster |
||arm_softmax_s8()| SOFTMAX | None | None | No | Yes | Bit exact to TFLu |
diff --git a/CMSIS/NN/Source/PoolingFunctions/CMakeLists.txt b/CMSIS/NN/Source/PoolingFunctions/CMakeLists.txt
index d157234..a37503b 100644
--- a/CMSIS/NN/Source/PoolingFunctions/CMakeLists.txt
+++ b/CMSIS/NN/Source/PoolingFunctions/CMakeLists.txt
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2019-2021 Arm Limited.
+# Copyright (c) 2019-2022 Arm Limited.
#
# SPDX-License-Identifier: Apache-2.0
#
@@ -17,6 +17,8 @@
#
file(GLOB SRC "./*_s8.c")
-target_sources(cmsis-nn PRIVATE ${SRC})
+file(GLOB SRC_S16 "./*_s16.c")
+target_sources(cmsis-nn PRIVATE ${SRC} ${SRC_S16})
+
diff --git a/CMSIS/NN/Source/PoolingFunctions/arm_avgpool_s16.c b/CMSIS/NN/Source/PoolingFunctions/arm_avgpool_s16.c
new file mode 100644
index 0000000..e9c7213
--- /dev/null
+++ b/CMSIS/NN/Source/PoolingFunctions/arm_avgpool_s16.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2022 Arm Limited or its affiliates.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* ----------------------------------------------------------------------
+ * Project: CMSIS NN Library
+ * Title: arm_avgpool_s16.c
+ * Description: Pooling function implementations
+ *
+ * $Date: 26. January 2022
+ * $Revision: V.1.0.0
+ *
+ * Target Processor: Cortex-M CPUs
+ *
+ * -------------------------------------------------------------------- */
+
+#include "arm_nnfunctions.h"
+#include "arm_nnsupportfunctions.h"
+
+/**
+ * @ingroup groupNN
+ */
+
+/**
+ * @addtogroup Pooling
+ * @{
+ */
+
+/*
+ * s16 average pooling function
+ *
+ * Refer to header file for details.
+ *
+ */
+arm_status arm_avgpool_s16(const cmsis_nn_context *ctx,
+ const cmsis_nn_pool_params *pool_params,
+ const cmsis_nn_dims *input_dims,
+ const q15_t *src,
+ const cmsis_nn_dims *filter_dims,
+ const cmsis_nn_dims *output_dims,
+ q15_t *dst)
+{
+ const int32_t input_y = input_dims->h;
+ const int32_t input_x = input_dims->w;
+ const int32_t output_y = output_dims->h;
+ const int32_t output_x = output_dims->w;
+ const int32_t stride_y = pool_params->stride.h;
+ const int32_t stride_x = pool_params->stride.w;
+ const int32_t kernel_y = filter_dims->h;
+ const int32_t kernel_x = filter_dims->w;
+ const int32_t pad_y = pool_params->padding.h;
+ const int32_t pad_x = pool_params->padding.w;
+ const int32_t act_min = pool_params->activation.min;
+ const int32_t act_max = pool_params->activation.max;
+ const int32_t ch_src = input_dims->c;
+
+ /* Reference C code adapted from CMSIS-NN arm_avgpool_s8.c.
+ */
+
+ for (int i_y = 0, base_idx_y = -pad_y; i_y < output_y; base_idx_y += stride_y, i_y++)
+ {
+ for (int i_x = 0, base_idx_x = -pad_x; i_x < output_x; base_idx_x += stride_x, i_x++)
+ {
+ /* Condition for kernel start dimension: (base_idx_<x,y> + kernel_<x,y>_start) >= 0 */
+ const int32_t ker_y_start = MAX(0, -base_idx_y);
+ const int32_t ker_x_start = MAX(0, -base_idx_x);
+
+ /* Condition for kernel end dimension: (base_idx_<x,y> + kernel_<x,y>_end) < dim_src_<width,height> */
+ const int32_t kernel_y_end = MIN(kernel_y, input_y - base_idx_y);
+ const int32_t kernel_x_end = MIN(kernel_x, input_x - base_idx_x);
+
+ for (int i_ch_in = 0; i_ch_in < ch_src; i_ch_in++)
+ {
+ int sum = 0;
+ int count = 0;
+
+ for (int k_y = ker_y_start; k_y < kernel_y_end; k_y++)
+ {
+ for (int k_x = ker_x_start; k_x < kernel_x_end; k_x++)
+ {
+ sum += src[i_ch_in + ch_src * (k_x + base_idx_x + (k_y + base_idx_y) * input_x)];
+ count++;
+ }
+ }
+
+ // Prevent static code issue DIVIDE_BY_ZERO.
+ if (count == 0)
+ {
+ return ARM_MATH_ARGUMENT_ERROR;
+ }
+
+ sum = sum > 0 ? (sum + count / 2) / count : (sum - count / 2) / count;
+ sum = MAX(sum, act_min);
+ sum = MIN(sum, act_max);
+
+ dst[i_ch_in + ch_src * (i_x + i_y * output_x)] = sum;
+ }
+ }
+ }
+
+ return ARM_MATH_SUCCESS;
+}
+
+int32_t arm_avgpool_s16_get_buffer_size(const int output_x, const int ch_src)
+{
+ (void)output_x;
+ (void)ch_src;
+ return 0;
+}
+
+/**
+ * @} end of Pooling group
+ */
diff --git a/CMSIS/NN/Source/PoolingFunctions/arm_max_pool_s16.c b/CMSIS/NN/Source/PoolingFunctions/arm_max_pool_s16.c
new file mode 100644
index 0000000..483f874
--- /dev/null
+++ b/CMSIS/NN/Source/PoolingFunctions/arm_max_pool_s16.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2022 Arm Limited or its affiliates.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* ----------------------------------------------------------------------
+ * Project: CMSIS NN Library
+ * Title: arm_max_pool_s16.c
+ * Description: Pooling function implementations
+ *
+ * $Date: 24. January 2022
+ * $Revision: V.1.0.0
+ *
+ * Target Processor: Cortex-M CPUs
+ *
+ * -------------------------------------------------------------------- */
+
+#include "arm_nnfunctions.h"
+#include "arm_nnsupportfunctions.h"
+
+static void compare_and_replace_if_larger(int16_t *base, const int16_t *target, int32_t length)
+{
+ q15_t *dst = base;
+ const q15_t *src = target;
+ union arm_nnword ref_max;
+ union arm_nnword comp_max;
+ int32_t cnt = length >> 1;
+
+ while (cnt > 0l)
+ {
+ ref_max.word = arm_nn_read_q15x2(dst);
+ comp_max.word = arm_nn_read_q15x2_ia(&src);
+
+ if (comp_max.half_words[0] > ref_max.half_words[0])
+ {
+ ref_max.half_words[0] = comp_max.half_words[0];
+ }
+ if (comp_max.half_words[1] > ref_max.half_words[1])
+ {
+ ref_max.half_words[1] = comp_max.half_words[1];
+ }
+
+ arm_nn_write_q15x2_ia(&dst, ref_max.word);
+
+ cnt--;
+ }
+
+ if (length & 0x1)
+ {
+ if (*src > *dst)
+ {
+ *dst = *src;
+ }
+ }
+}
+
+static void clamp_output(int16_t *source, int32_t length, const int16_t act_min, const int16_t act_max)
+{
+ union arm_nnword in;
+ int32_t cnt = length >> 1;
+
+ while (cnt > 0l)
+ {
+ in.word = arm_nn_read_q15x2(source);
+
+ in.half_words[0] = MAX(in.half_words[0], act_min);
+ in.half_words[0] = MIN(in.half_words[0], act_max);
+ in.half_words[1] = MAX(in.half_words[1], act_min);
+ in.half_words[1] = MIN(in.half_words[1], act_max);
+
+ arm_nn_write_q15x2_ia(&source, in.word);
+ cnt--;
+ }
+
+ if (length & 0x1)
+ {
+ int16_t comp = *source;
+ comp = MAX(comp, act_min);
+ comp = MIN(comp, act_max);
+ *source = comp;
+ }
+}
+
+/**
+ * @ingroup groupNN
+ */
+
+/**
+ * @addtogroup Pooling
+ * @{
+ */
+
+/*
+ * Optimized s16 max pooling function
+ *
+ * Refer to header file for details.
+ *
+ */
+
+arm_status arm_max_pool_s16(const cmsis_nn_context *ctx,
+ const cmsis_nn_pool_params *pool_params,
+ const cmsis_nn_dims *input_dims,
+ const int16_t *src,
+ const cmsis_nn_dims *filter_dims,
+ const cmsis_nn_dims *output_dims,
+ int16_t *dst)
+{
+ const int32_t input_y = input_dims->h;
+ const int32_t input_x = input_dims->w;
+ const int32_t output_y = output_dims->h;
+ const int32_t output_x = output_dims->w;
+ const int32_t stride_y = pool_params->stride.h;
+ const int32_t stride_x = pool_params->stride.w;
+ const int32_t kernel_y = filter_dims->h;
+ const int32_t kernel_x = filter_dims->w;
+ const int32_t pad_y = pool_params->padding.h;
+ const int32_t pad_x = pool_params->padding.w;
+ const int16_t act_min = pool_params->activation.min;
+ const int16_t act_max = pool_params->activation.max;
+ const int32_t channel_in = input_dims->c;
+ (void)ctx;
+ int16_t *dst_base = dst;
+
+ for (int i_y = 0, base_idx_y = -pad_y; i_y < output_y; base_idx_y += stride_y, i_y++)
+ {
+ for (int i_x = 0, base_idx_x = -pad_x; i_x < output_x; base_idx_x += stride_x, i_x++)
+ {
+ /* Condition for kernel start dimension: (base_idx_<x,y> + kernel_<x,y>_start) >= 0 */
+ const int32_t ker_y_start = MAX(0, -base_idx_y);
+ const int32_t ker_x_start = MAX(0, -base_idx_x);
+
+ /* Condition for kernel end dimension: (base_idx_<x,y> + kernel_<x,y>_end) < dim_src_<width,height> */
+ const int32_t kernel_y_end = MIN(kernel_y, input_y - base_idx_y);
+ const int32_t kernel_x_end = MIN(kernel_x, input_x - base_idx_x);
+
+ int count = 0;
+
+ for (int k_y = ker_y_start; k_y < kernel_y_end; k_y++)
+ {
+ for (int k_x = ker_x_start; k_x < kernel_x_end; k_x++)
+ {
+ const int16_t *start = src + channel_in * (k_x + base_idx_x + (k_y + base_idx_y) * input_x);
+
+ if (count == 0)
+ {
+ memcpy(dst, start, channel_in * sizeof(int16_t));
+ count++;
+ }
+ else
+ {
+ compare_and_replace_if_larger(dst, start, channel_in);
+ }
+ }
+ }
+ /* 'count' is expected to be non-zero here. */
+ dst += channel_in;
+ }
+ }
+
+ clamp_output(dst_base, output_x * output_y * channel_in, act_min, act_max);
+
+ return ARM_MATH_SUCCESS;
+}
+
+/**
+ * @} end of Pooling group
+ */
diff --git a/CMSIS/NN/Tests/UnitTest/CMakeLists.txt b/CMSIS/NN/Tests/UnitTest/CMakeLists.txt
index 5ebc907..707f46e 100644
--- a/CMSIS/NN/Tests/UnitTest/CMakeLists.txt
+++ b/CMSIS/NN/Tests/UnitTest/CMakeLists.txt
@@ -67,6 +67,7 @@
endfunction(add_cmsis_nn_unit_test_executable)
add_subdirectory(TestCases/test_arm_avgpool_s8)
+add_subdirectory(TestCases/test_arm_avgpool_s16)
add_subdirectory(TestCases/test_arm_convolve_1x1_s8_fast)
add_subdirectory(TestCases/test_arm_convolve_s8)
add_subdirectory(TestCases/test_arm_convolve_s16)
@@ -78,6 +79,7 @@
add_subdirectory(TestCases/test_arm_fully_connected_s8)
add_subdirectory(TestCases/test_arm_fully_connected_s16)
add_subdirectory(TestCases/test_arm_max_pool_s8)
+add_subdirectory(TestCases/test_arm_max_pool_s16)
add_subdirectory(TestCases/test_arm_softmax_s8)
add_subdirectory(TestCases/test_arm_svdf_s8)
diff --git a/CMSIS/NN/Tests/UnitTest/PregeneratedData/avgpooling_int16/input.txt b/CMSIS/NN/Tests/UnitTest/PregeneratedData/avgpooling_int16/input.txt
new file mode 100644
index 0000000..df7dba7
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/PregeneratedData/avgpooling_int16/input.txt
@@ -0,0 +1,25 @@
+# 1,4,6,2
+1.107700000000000000e+04,-9.242000000000000000e+03
+-9.812000000000000000e+03,3.245400000000000000e+04
+1.037300000000000000e+04,-3.269400000000000000e+04
+1.289300000000000000e+04,8.403000000000000000e+03
+1.754200000000000000e+04,-1.513400000000000000e+04
+9.160000000000000000e+02,-2.036100000000000000e+04
+1.495000000000000000e+03,-4.616000000000000000e+03
+-4.699000000000000000e+03,1.241200000000000000e+04
+8.355000000000000000e+03,2.939200000000000000e+04
+-1.515000000000000000e+03,-2.910100000000000000e+04
+-3.187600000000000000e+04,1.499800000000000000e+04
+6.195000000000000000e+03,-2.471800000000000000e+04
+2.229000000000000000e+03,2.087200000000000000e+04
+1.325900000000000000e+04,1.343000000000000000e+04
+2.457700000000000000e+04,2.859000000000000000e+03
+1.112300000000000000e+04,-2.391300000000000000e+04
+-1.954600000000000000e+04,1.228300000000000000e+04
+-2.812200000000000000e+04,7.332000000000000000e+03
+2.030900000000000000e+04,-3.305000000000000000e+03
+-2.232000000000000000e+03,1.689200000000000000e+04
+-2.994500000000000000e+04,2.991100000000000000e+04
+-2.000300000000000000e+04,1.710400000000000000e+04
+1.597700000000000000e+04,-1.161600000000000000e+04
+1.207300000000000000e+04,-9.683000000000000000e+03
diff --git a/CMSIS/NN/Tests/UnitTest/PregeneratedData/maxpool_int16/input.txt b/CMSIS/NN/Tests/UnitTest/PregeneratedData/maxpool_int16/input.txt
new file mode 100644
index 0000000..41cb187
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/PregeneratedData/maxpool_int16/input.txt
@@ -0,0 +1,13 @@
+# 1,3,4,2
+2.018300000000000000e+04,-2.304800000000000000e+04
+-1.523100000000000000e+04,1.078900000000000000e+04
+-6.367000000000000000e+03,2.796300000000000000e+04
+-2.610600000000000000e+04,-1.231000000000000000e+03
+2.446000000000000000e+03,2.542300000000000000e+04
+2.669700000000000000e+04,-2.364000000000000000e+03
+2.570400000000000000e+04,1.845200000000000000e+04
+-2.104000000000000000e+04,-3.148300000000000000e+04
+4.698000000000000000e+03,-2.768700000000000000e+04
+5.280000000000000000e+02,-3.126300000000000000e+04
+3.259600000000000000e+04,1.478100000000000000e+04
+2.534900000000000000e+04,-1.707700000000000000e+04
diff --git a/CMSIS/NN/Tests/UnitTest/PregeneratedData/maxpool_int16_1/input.txt b/CMSIS/NN/Tests/UnitTest/PregeneratedData/maxpool_int16_1/input.txt
new file mode 100644
index 0000000..c321100
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/PregeneratedData/maxpool_int16_1/input.txt
@@ -0,0 +1,21 @@
+# 1,5,4,2
+-2.616600000000000000e+04,3.027700000000000000e+04
+1.143800000000000000e+04,2.071300000000000000e+04
+1.520300000000000000e+04,6.590000000000000000e+02
+-1.312000000000000000e+04,1.431000000000000000e+04
+-6.746000000000000000e+03,-1.105000000000000000e+04
+-2.747700000000000000e+04,-1.107800000000000000e+04
+-1.542000000000000000e+03,-8.760000000000000000e+02
+1.321000000000000000e+03,2.995300000000000000e+04
+-6.256000000000000000e+03,-1.950000000000000000e+04
+1.348000000000000000e+04,-1.640700000000000000e+04
+2.222100000000000000e+04,2.037000000000000000e+04
+-1.214400000000000000e+04,-1.889900000000000000e+04
+-9.740000000000000000e+02,-2.731000000000000000e+04
+1.260000000000000000e+02,-1.063400000000000000e+04
+2.343200000000000000e+04,-4.660000000000000000e+02
+-2.424100000000000000e+04,-5.013000000000000000e+03
+-5.155000000000000000e+03,-1.014000000000000000e+03
+2.402000000000000000e+04,2.602300000000000000e+04
+4.895000000000000000e+03,3.205900000000000000e+04
+-3.012000000000000000e+03,5.604000000000000000e+03
diff --git a/CMSIS/NN/Tests/UnitTest/PregeneratedData/maxpool_int16_2/input.txt b/CMSIS/NN/Tests/UnitTest/PregeneratedData/maxpool_int16_2/input.txt
new file mode 100644
index 0000000..bb7a9c9
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/PregeneratedData/maxpool_int16_2/input.txt
@@ -0,0 +1,50 @@
+# 1,7,7,3
+1.023100000000000000e+04,-1.881000000000000000e+03,-5.938000000000000000e+03
+-3.223600000000000000e+04,3.431000000000000000e+03,1.854400000000000000e+04
+-2.218800000000000000e+04,1.610300000000000000e+04,2.597800000000000000e+04
+-5.177000000000000000e+03,1.680100000000000000e+04,2.602200000000000000e+04
+-1.511100000000000000e+04,1.161000000000000000e+03,-2.412700000000000000e+04
+-2.157700000000000000e+04,1.855400000000000000e+04,2.082100000000000000e+04
+2.317800000000000000e+04,-2.762900000000000000e+04,-3.210700000000000000e+04
+8.173000000000000000e+03,-1.063900000000000000e+04,-2.292200000000000000e+04
+-2.460400000000000000e+04,2.973100000000000000e+04,2.118100000000000000e+04
+-2.300800000000000000e+04,6.314000000000000000e+03,1.575400000000000000e+04
+1.670600000000000000e+04,-2.390800000000000000e+04,1.895200000000000000e+04
+-3.035600000000000000e+04,2.743200000000000000e+04,-2.114800000000000000e+04
+-3.165000000000000000e+04,6.980000000000000000e+03,-1.735100000000000000e+04
+-1.736200000000000000e+04,-1.203500000000000000e+04,-1.517800000000000000e+04
+2.674400000000000000e+04,8.455000000000000000e+03,7.985000000000000000e+03
+7.971000000000000000e+03,3.127200000000000000e+04,1.108500000000000000e+04
+1.891800000000000000e+04,-3.046900000000000000e+04,2.336500000000000000e+04
+-1.069500000000000000e+04,2.969500000000000000e+04,-1.405700000000000000e+04
+-8.956000000000000000e+03,1.117400000000000000e+04,3.119700000000000000e+04
+-2.690700000000000000e+04,-2.829900000000000000e+04,2.950000000000000000e+03
+1.652500000000000000e+04,-2.737000000000000000e+03,3.207100000000000000e+04
+-3.186200000000000000e+04,1.131000000000000000e+03,-2.199300000000000000e+04
+-2.372000000000000000e+04,2.415700000000000000e+04,-6.964000000000000000e+03
+9.970000000000000000e+03,-3.066500000000000000e+04,8.036000000000000000e+03
+7.891000000000000000e+03,-2.038800000000000000e+04,2.079300000000000000e+04
+1.014900000000000000e+04,1.924300000000000000e+04,-3.171000000000000000e+03
+-4.007000000000000000e+03,3.169000000000000000e+03,-4.756000000000000000e+03
+6.291000000000000000e+03,9.056000000000000000e+03,-1.601900000000000000e+04
+1.505000000000000000e+04,1.138300000000000000e+04,-3.037700000000000000e+04
+1.192900000000000000e+04,-1.192200000000000000e+04,8.188000000000000000e+03
+-8.621000000000000000e+03,-1.859600000000000000e+04,1.067100000000000000e+04
+-1.301200000000000000e+04,-2.677800000000000000e+04,-1.077200000000000000e+04
+-9.167000000000000000e+03,1.423100000000000000e+04,7.896000000000000000e+03
+-1.615200000000000000e+04,-2.237100000000000000e+04,7.830000000000000000e+03
+2.686400000000000000e+04,-2.647900000000000000e+04,1.264000000000000000e+03
+2.504000000000000000e+04,-1.564700000000000000e+04,2.480000000000000000e+04
+7.652000000000000000e+03,-9.300000000000000000e+02,9.660000000000000000e+03
+-8.777000000000000000e+03,-2.061300000000000000e+04,1.583400000000000000e+04
+-2.633000000000000000e+04,3.750000000000000000e+03,2.553400000000000000e+04
+2.423300000000000000e+04,3.128800000000000000e+04,-1.385400000000000000e+04
+4.670000000000000000e+03,-1.967700000000000000e+04,-2.366000000000000000e+03
+1.696000000000000000e+04,-5.193000000000000000e+03,2.121400000000000000e+04
+-2.447500000000000000e+04,-2.206000000000000000e+04,-2.931000000000000000e+04
+-3.193700000000000000e+04,2.822600000000000000e+04,2.386400000000000000e+04
+-1.397000000000000000e+03,-1.441700000000000000e+04,-1.575100000000000000e+04
+-9.613000000000000000e+03,-2.177500000000000000e+04,-6.951000000000000000e+03
+2.301400000000000000e+04,2.595100000000000000e+04,4.013000000000000000e+03
+-3.274300000000000000e+04,3.266000000000000000e+04,-1.848900000000000000e+04
+2.353200000000000000e+04,1.019600000000000000e+04,3.240900000000000000e+04
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/TestData/avgpooling_int16/config_data.h b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/avgpooling_int16/config_data.h
new file mode 100644
index 0000000..b9e0d86
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/avgpooling_int16/config_data.h
@@ -0,0 +1,19 @@
+// Generated by generate_test_data.py using TFL version 2.6.0 as reference.
+#pragma once
+#define AVGPOOLING_INT16_OUT_CH 2
+#define AVGPOOLING_INT16_IN_CH 2
+#define AVGPOOLING_INT16_INPUT_W 6
+#define AVGPOOLING_INT16_INPUT_H 4
+#define AVGPOOLING_INT16_DST_SIZE 24
+#define AVGPOOLING_INT16_INPUT_SIZE 48
+#define AVGPOOLING_INT16_OUT_ACTIVATION_MIN -32768
+#define AVGPOOLING_INT16_OUT_ACTIVATION_MAX 32767
+#define AVGPOOLING_INT16_INPUT_BATCHES 1
+#define AVGPOOLING_INT16_FILTER_X 2
+#define AVGPOOLING_INT16_FILTER_Y 3
+#define AVGPOOLING_INT16_STRIDE_X 2
+#define AVGPOOLING_INT16_STRIDE_Y 1
+#define AVGPOOLING_INT16_PAD_X 0
+#define AVGPOOLING_INT16_PAD_Y 1
+#define AVGPOOLING_INT16_OUTPUT_W 3
+#define AVGPOOLING_INT16_OUTPUT_H 4
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/TestData/avgpooling_int16/input_data.h b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/avgpooling_int16/input_data.h
new file mode 100644
index 0000000..f468c28
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/avgpooling_int16/input_data.h
@@ -0,0 +1,9 @@
+// Generated by generate_test_data.py using TFL version 2.6.0 as reference.
+#pragma once
+#include <stdint.h>
+
+const int16_t avgpooling_int16_input[48] = {11077, -9242, -9812, 32454, 10373, -32694, 12893, 8403, 17542, -15134,
+ 916, -20361, 1495, -4616, -4699, 12412, 8355, 29392, -1515, -29101,
+ -31876, 14998, 6195, -24718, 2229, 20872, 13259, 13430, 24577, 2859,
+ 11123, -23913, -19546, 12283, -28122, 7332, 20309, -3305, -2232, 16892,
+ -29945, 29911, -20003, 17104, 15977, -11616, 12073, -9683};
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/TestData/avgpooling_int16/output_ref_data.h b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/avgpooling_int16/output_ref_data.h
new file mode 100644
index 0000000..fbbca4f
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/avgpooling_int16/output_ref_data.h
@@ -0,0 +1,7 @@
+// Generated by generate_test_data.py using TFL version 2.6.0 as reference.
+#pragma once
+#include <stdint.h>
+
+const int16_t avgpooling_int16_output_ref[24] = {-485, 7752, 7527, -6000, -1806, -11304, 2258, 10885,
+ 10968, -7509, -9149, -4267, 5060, 9281, -1235, 4375,
+ -7550, -1901, 8391, 11972, -3562, 6490, -4905, -421};
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/TestData/avgpooling_int16/test_data.h b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/avgpooling_int16/test_data.h
new file mode 100644
index 0000000..31add6d
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/avgpooling_int16/test_data.h
@@ -0,0 +1,4 @@
+// Generated by generate_test_data.py using TFL version 2.6.0 as reference.
+#include "config_data.h"
+#include "input_data.h"
+#include "output_ref_data.h"
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16/config_data.h b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16/config_data.h
new file mode 100644
index 0000000..0e894af
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16/config_data.h
@@ -0,0 +1,19 @@
+// Generated by generate_test_data.py using TFL version 2.6.0 as reference.
+#pragma once
+#define MAXPOOL_INT16_OUT_CH 2
+#define MAXPOOL_INT16_IN_CH 2
+#define MAXPOOL_INT16_INPUT_W 4
+#define MAXPOOL_INT16_INPUT_H 3
+#define MAXPOOL_INT16_DST_SIZE 4
+#define MAXPOOL_INT16_INPUT_SIZE 24
+#define MAXPOOL_INT16_OUT_ACTIVATION_MIN -32768
+#define MAXPOOL_INT16_OUT_ACTIVATION_MAX 32767
+#define MAXPOOL_INT16_INPUT_BATCHES 1
+#define MAXPOOL_INT16_FILTER_X 2
+#define MAXPOOL_INT16_FILTER_Y 2
+#define MAXPOOL_INT16_STRIDE_X 2
+#define MAXPOOL_INT16_STRIDE_Y 2
+#define MAXPOOL_INT16_PAD_X 0
+#define MAXPOOL_INT16_PAD_Y 0
+#define MAXPOOL_INT16_OUTPUT_W 2
+#define MAXPOOL_INT16_OUTPUT_H 1
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16/input_data.h b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16/input_data.h
new file mode 100644
index 0000000..ff089ef
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16/input_data.h
@@ -0,0 +1,7 @@
+// Generated by generate_test_data.py using TFL version 2.6.0 as reference.
+#pragma once
+#include <stdint.h>
+
+const int16_t maxpool_int16_input[24] = {20183, -23048, -15231, 10789, -6367, 27963, -26106, -1231,
+ 2446, 25423, 26697, -2364, 25704, 18452, -21040, -31483,
+ 4698, -27687, 528, -31263, 32596, 14781, 25349, -17077};
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16/output_ref_data.h b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16/output_ref_data.h
new file mode 100644
index 0000000..e63f120
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16/output_ref_data.h
@@ -0,0 +1,5 @@
+// Generated by generate_test_data.py using TFL version 2.6.0 as reference.
+#pragma once
+#include <stdint.h>
+
+const int16_t maxpool_int16_output_ref[4] = {26697, 25423, 25704, 27963};
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16/test_data.h b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16/test_data.h
new file mode 100644
index 0000000..31add6d
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16/test_data.h
@@ -0,0 +1,4 @@
+// Generated by generate_test_data.py using TFL version 2.6.0 as reference.
+#include "config_data.h"
+#include "input_data.h"
+#include "output_ref_data.h"
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_1/config_data.h b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_1/config_data.h
new file mode 100644
index 0000000..fbd2982
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_1/config_data.h
@@ -0,0 +1,19 @@
+// Generated by generate_test_data.py using TFL version 2.6.0 as reference.
+#pragma once
+#define MAXPOOL_INT16_1_OUT_CH 2
+#define MAXPOOL_INT16_1_IN_CH 2
+#define MAXPOOL_INT16_1_INPUT_W 4
+#define MAXPOOL_INT16_1_INPUT_H 5
+#define MAXPOOL_INT16_1_DST_SIZE 20
+#define MAXPOOL_INT16_1_INPUT_SIZE 40
+#define MAXPOOL_INT16_1_OUT_ACTIVATION_MIN -30000
+#define MAXPOOL_INT16_1_OUT_ACTIVATION_MAX 30000
+#define MAXPOOL_INT16_1_INPUT_BATCHES 1
+#define MAXPOOL_INT16_1_FILTER_X 3
+#define MAXPOOL_INT16_1_FILTER_Y 3
+#define MAXPOOL_INT16_1_STRIDE_X 2
+#define MAXPOOL_INT16_1_STRIDE_Y 1
+#define MAXPOOL_INT16_1_PAD_X 0
+#define MAXPOOL_INT16_1_PAD_Y 1
+#define MAXPOOL_INT16_1_OUTPUT_W 2
+#define MAXPOOL_INT16_1_OUTPUT_H 5
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_1/input_data.h b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_1/input_data.h
new file mode 100644
index 0000000..09c5f6a
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_1/input_data.h
@@ -0,0 +1,8 @@
+// Generated by generate_test_data.py using TFL version 2.6.0 as reference.
+#pragma once
+#include <stdint.h>
+
+const int16_t maxpool_int16_1_input[40] = {-26166, 30277, 11438, 20713, 15203, 659, -13120, 14310, -6746, -11050,
+ -27477, -11078, -1542, -876, 1321, 29953, -6256, -19500, 13480, -16407,
+ 22221, 20370, -12144, -18899, -974, -27310, 126, -10634, 23432, -466,
+ -24241, -5013, -5155, -1014, 24020, 26023, 4895, 32059, -3012, 5604};
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_1/output_ref_data.h b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_1/output_ref_data.h
new file mode 100644
index 0000000..4b22942
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_1/output_ref_data.h
@@ -0,0 +1,6 @@
+// Generated by generate_test_data.py using TFL version 2.6.0 as reference.
+#pragma once
+#include <stdint.h>
+
+const int16_t maxpool_int16_1_output_ref[20] = {15203, 30000, 15203, 29953, 22221, 30000, 22221, 29953, 23432, 20370,
+ 23432, 29953, 24020, 30000, 23432, 30000, 24020, 30000, 23432, 30000};
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_1/test_data.h b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_1/test_data.h
new file mode 100644
index 0000000..31add6d
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_1/test_data.h
@@ -0,0 +1,4 @@
+// Generated by generate_test_data.py using TFL version 2.6.0 as reference.
+#include "config_data.h"
+#include "input_data.h"
+#include "output_ref_data.h"
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_2/config_data.h b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_2/config_data.h
new file mode 100644
index 0000000..bb46471
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_2/config_data.h
@@ -0,0 +1,19 @@
+// Generated by generate_test_data.py using TFL version 2.6.0 as reference.
+#pragma once
+#define MAXPOOL_INT16_2_OUT_CH 3
+#define MAXPOOL_INT16_2_IN_CH 3
+#define MAXPOOL_INT16_2_INPUT_W 7
+#define MAXPOOL_INT16_2_INPUT_H 7
+#define MAXPOOL_INT16_2_DST_SIZE 75
+#define MAXPOOL_INT16_2_INPUT_SIZE 147
+#define MAXPOOL_INT16_2_OUT_ACTIVATION_MIN -30000
+#define MAXPOOL_INT16_2_OUT_ACTIVATION_MAX 30000
+#define MAXPOOL_INT16_2_INPUT_BATCHES 1
+#define MAXPOOL_INT16_2_FILTER_X 3
+#define MAXPOOL_INT16_2_FILTER_Y 3
+#define MAXPOOL_INT16_2_STRIDE_X 1
+#define MAXPOOL_INT16_2_STRIDE_Y 1
+#define MAXPOOL_INT16_2_PAD_X 0
+#define MAXPOOL_INT16_2_PAD_Y 0
+#define MAXPOOL_INT16_2_OUTPUT_W 5
+#define MAXPOOL_INT16_2_OUTPUT_H 5
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_2/input_data.h b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_2/input_data.h
new file mode 100644
index 0000000..41c3203
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_2/input_data.h
@@ -0,0 +1,16 @@
+// Generated by generate_test_data.py using TFL version 2.6.0 as reference.
+#pragma once
+#include <stdint.h>
+
+const int16_t maxpool_int16_2_input[147] = {
+ 10231, -1881, -5938, -32236, 3431, 18544, -22188, 16103, 25978, -5177, 16801, 26022, -15111, 1161,
+ -24127, -21577, 18554, 20821, 23178, -27629, -32107, 8173, -10639, -22922, -24604, 29731, 21181, -23008,
+ 6314, 15754, 16706, -23908, 18952, -30356, 27432, -21148, -31650, 6980, -17351, -17362, -12035, -15178,
+ 26744, 8455, 7985, 7971, 31272, 11085, 18918, -30469, 23365, -10695, 29695, -14057, -8956, 11174,
+ 31197, -26907, -28299, 2950, 16525, -2737, 32071, -31862, 1131, -21993, -23720, 24157, -6964, 9970,
+ -30665, 8036, 7891, -20388, 20793, 10149, 19243, -3171, -4007, 3169, -4756, 6291, 9056, -16019,
+ 15050, 11383, -30377, 11929, -11922, 8188, -8621, -18596, 10671, -13012, -26778, -10772, -9167, 14231,
+ 7896, -16152, -22371, 7830, 26864, -26479, 1264, 25040, -15647, 24800, 7652, -930, 9660, -8777,
+ -20613, 15834, -26330, 3750, 25534, 24233, 31288, -13854, 4670, -19677, -2366, 16960, -5193, 21214,
+ -24475, -22060, -29310, -31937, 28226, 23864, -1397, -14417, -15751, -9613, -21775, -6951, 23014, 25951,
+ 4013, -32743, 32660, -18489, 23532, 10196, 32409};
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_2/output_ref_data.h b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_2/output_ref_data.h
new file mode 100644
index 0000000..7444b48
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_2/output_ref_data.h
@@ -0,0 +1,10 @@
+// Generated by generate_test_data.py using TFL version 2.6.0 as reference.
+#pragma once
+#include <stdint.h>
+
+const int16_t maxpool_int16_2_output_ref[75] = {
+ 26744, 30000, 25978, 18918, 30000, 26022, 18918, 29695, 30000, 16706, 29695, 30000, 23178, 27432, 30000,
+ 26744, 30000, 23365, 18918, 30000, 23365, 18918, 29695, 30000, 16706, 29695, 30000, 16525, 27432, 30000,
+ 26744, 30000, 23365, 18918, 30000, 23365, 18918, 29695, 30000, 10149, 29695, 30000, 26864, 19243, 30000,
+ 25040, 24157, 24800, 11929, 24157, 25534, 24233, 30000, 25534, 24233, 30000, 25534, 26864, 30000, 21214,
+ 25040, 28226, 24800, 11929, 28226, 25534, 24233, 30000, 25534, 24233, 30000, 25534, 26864, 30000, 30000};
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_2/test_data.h b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_2/test_data.h
new file mode 100644
index 0000000..31add6d
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/TestData/maxpool_int16_2/test_data.h
@@ -0,0 +1,4 @@
+// Generated by generate_test_data.py using TFL version 2.6.0 as reference.
+#include "config_data.h"
+#include "input_data.h"
+#include "output_ref_data.h"
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/test_arm_avgpool_s16/CMakeLists.txt b/CMSIS/NN/Tests/UnitTest/TestCases/test_arm_avgpool_s16/CMakeLists.txt
new file mode 100644
index 0000000..08ebf9a
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/test_arm_avgpool_s16/CMakeLists.txt
@@ -0,0 +1,23 @@
+#
+# Copyright (C) 2010-2022 Arm Limited or its affiliates.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the License); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an AS IS BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+add_cmsis_nn_unit_test_executable(test_arm_avgpool_s16)
+
+target_sources(test_arm_avgpool_s16 PRIVATE
+ Unity/unity_test_arm_avgpool_s16.c
+ Unity/TestRunner/unity_test_arm_avgpool_s16_runner.c)
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/test_arm_avgpool_s16/Unity/unity_test_arm_avgpool_s16.c b/CMSIS/NN/Tests/UnitTest/TestCases/test_arm_avgpool_s16/Unity/unity_test_arm_avgpool_s16.c
new file mode 100644
index 0000000..c26af31
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/test_arm_avgpool_s16/Unity/unity_test_arm_avgpool_s16.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010-2022 Arm Limited or its affiliates.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../test_arm_avgpool_s16.c"
+#include "unity.h"
+
+#ifdef USING_FVP_CORSTONE_300
+extern void uart_init(void);
+#endif
+
+/* This function is called from the autogenerated file.
+ * The name must be exactly like this
+ */
+void setUp(void)
+{ /* This is run before EACH TEST */
+#ifdef USING_FVP_CORSTONE_300
+ uart_init();
+#endif
+}
+
+/* This function is called from the autogenerated file.
+ * The name must be exactly like this
+ */
+void tearDown(void) {}
+
+void test_avgpooling_int16_arm_avgpool_s16(void) { avgpooling_int16_arm_avgpool_s16(); }
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/test_arm_avgpool_s16/test_arm_avgpool_s16.c b/CMSIS/NN/Tests/UnitTest/TestCases/test_arm_avgpool_s16/test_arm_avgpool_s16.c
new file mode 100644
index 0000000..937cbc2
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/test_arm_avgpool_s16/test_arm_avgpool_s16.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010-2022 Arm Limited or its affiliates.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "arm_nnfunctions.h"
+#include "unity.h"
+
+#include "../TestData/avgpooling_int16/test_data.h"
+#include "../Utils/validate.h"
+
+void avgpooling_int16_arm_avgpool_s16(void)
+{
+ const arm_status expected = ARM_MATH_SUCCESS;
+ q15_t output[AVGPOOLING_INT16_DST_SIZE] = {0};
+
+ cmsis_nn_context ctx;
+ cmsis_nn_pool_params pool_params;
+ cmsis_nn_dims input_dims;
+ cmsis_nn_dims filter_dims;
+ cmsis_nn_dims output_dims;
+
+ const q15_t *input_data = avgpooling_int16_input;
+
+ input_dims.n = AVGPOOLING_INT16_INPUT_BATCHES;
+ input_dims.w = AVGPOOLING_INT16_INPUT_W;
+ input_dims.h = AVGPOOLING_INT16_INPUT_H;
+ input_dims.c = AVGPOOLING_INT16_IN_CH;
+ filter_dims.w = AVGPOOLING_INT16_FILTER_X;
+ filter_dims.h = AVGPOOLING_INT16_FILTER_Y;
+ output_dims.w = AVGPOOLING_INT16_OUTPUT_W;
+ output_dims.h = AVGPOOLING_INT16_OUTPUT_H;
+ output_dims.c = AVGPOOLING_INT16_OUT_CH;
+
+ pool_params.padding.w = AVGPOOLING_INT16_PAD_X;
+ pool_params.padding.h = AVGPOOLING_INT16_PAD_Y;
+ pool_params.stride.w = AVGPOOLING_INT16_STRIDE_X;
+ pool_params.stride.h = AVGPOOLING_INT16_STRIDE_Y;
+
+ pool_params.activation.min = AVGPOOLING_INT16_OUT_ACTIVATION_MIN;
+ pool_params.activation.max = AVGPOOLING_INT16_OUT_ACTIVATION_MAX;
+
+ ctx.size = arm_avgpool_s16_get_buffer_size(AVGPOOLING_INT16_OUTPUT_W, AVGPOOLING_INT16_IN_CH);
+ ctx.buf = malloc(ctx.size);
+
+ arm_status result =
+ arm_avgpool_s16(&ctx, &pool_params, &input_dims, input_data, &filter_dims, &output_dims, output);
+
+ free(ctx.buf);
+ TEST_ASSERT_EQUAL(expected, result);
+ TEST_ASSERT_TRUE(validate_s16(output, avgpooling_int16_output_ref, AVGPOOLING_INT16_DST_SIZE));
+}
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/test_arm_max_pool_s16/CMakeLists.txt b/CMSIS/NN/Tests/UnitTest/TestCases/test_arm_max_pool_s16/CMakeLists.txt
new file mode 100644
index 0000000..b8ed83d
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/test_arm_max_pool_s16/CMakeLists.txt
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2022 Arm Limited or its affiliates.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the License); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an AS IS BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+add_cmsis_nn_unit_test_executable(test_arm_max_pool_s16)
+
+target_sources(test_arm_max_pool_s16 PRIVATE
+ Unity/unity_test_arm_max_pool_s16.c
+ Unity/TestRunner/unity_test_arm_max_pool_s16_runner.c)
+
+
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/test_arm_max_pool_s16/Unity/unity_test_arm_max_pool_s16.c b/CMSIS/NN/Tests/UnitTest/TestCases/test_arm_max_pool_s16/Unity/unity_test_arm_max_pool_s16.c
new file mode 100644
index 0000000..cea79c7
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/test_arm_max_pool_s16/Unity/unity_test_arm_max_pool_s16.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 Arm Limited or its affiliates.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../test_arm_max_pool_s16.c"
+#include "unity.h"
+
+#ifdef USING_FVP_CORSTONE_300
+extern void uart_init(void);
+#endif
+
+/* This function is called from the autogenerated file.
+ * The name must be exactly like this
+ */
+void setUp(void)
+{ /* This is run before EACH TEST */
+#ifdef USING_FVP_CORSTONE_300
+ uart_init();
+#endif
+}
+
+/* This function is called from the autogenerated file.
+ * The name must be exactly like this
+ */
+void tearDown(void) {}
+
+void test_maxpool_int16_arm_max_pool_s16(void) { maxpool_int16_arm_max_pool_s16(); }
+
+void test_maxpool_int16_1_arm_max_pool_s16(void) { maxpool_int16_1_arm_max_pool_s16(); }
+
+void test_maxpool_int16_2_arm_max_pool_s16(void) { maxpool_int16_2_arm_max_pool_s16(); }
diff --git a/CMSIS/NN/Tests/UnitTest/TestCases/test_arm_max_pool_s16/test_arm_max_pool_s16.c b/CMSIS/NN/Tests/UnitTest/TestCases/test_arm_max_pool_s16/test_arm_max_pool_s16.c
new file mode 100644
index 0000000..1f500ec
--- /dev/null
+++ b/CMSIS/NN/Tests/UnitTest/TestCases/test_arm_max_pool_s16/test_arm_max_pool_s16.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2022 Arm Limited or its affiliates.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "unity.h"
+#include <arm_nnfunctions.h>
+
+#include "../TestData/maxpool_int16/test_data.h"
+#include "../TestData/maxpool_int16_1/test_data.h"
+#include "../TestData/maxpool_int16_2/test_data.h"
+#include "../Utils/validate.h"
+
+#define REPEAT_NUM (2)
+
+void maxpool_int16_arm_max_pool_s16(void)
+{
+ const arm_status expected = ARM_MATH_SUCCESS;
+ int16_t output[MAXPOOL_INT16_DST_SIZE] = {0};
+
+ cmsis_nn_context ctx;
+ cmsis_nn_pool_params pool_params;
+ cmsis_nn_dims input_dims;
+ cmsis_nn_dims filter_dims;
+ cmsis_nn_dims output_dims;
+
+ const int16_t *input_data = maxpool_int16_input;
+
+ input_dims.n = MAXPOOL_INT16_INPUT_BATCHES;
+ input_dims.w = MAXPOOL_INT16_INPUT_W;
+ input_dims.h = MAXPOOL_INT16_INPUT_H;
+ input_dims.c = MAXPOOL_INT16_IN_CH;
+ filter_dims.w = MAXPOOL_INT16_FILTER_X;
+ filter_dims.h = MAXPOOL_INT16_FILTER_Y;
+ output_dims.w = MAXPOOL_INT16_OUTPUT_W;
+ output_dims.h = MAXPOOL_INT16_OUTPUT_H;
+ output_dims.c = MAXPOOL_INT16_OUT_CH;
+
+ pool_params.padding.w = MAXPOOL_INT16_PAD_X;
+ pool_params.padding.h = MAXPOOL_INT16_PAD_Y;
+ pool_params.stride.w = MAXPOOL_INT16_STRIDE_X;
+ pool_params.stride.h = MAXPOOL_INT16_STRIDE_Y;
+
+ pool_params.activation.min = MAXPOOL_INT16_OUT_ACTIVATION_MIN;
+ pool_params.activation.max = MAXPOOL_INT16_OUT_ACTIVATION_MAX;
+
+ for (int i = 0; i < REPEAT_NUM; i++)
+ {
+ arm_status result =
+ arm_max_pool_s16(&ctx, &pool_params, &input_dims, input_data, &filter_dims, &output_dims, output);
+
+ TEST_ASSERT_EQUAL(expected, result);
+ TEST_ASSERT_TRUE(validate_s16(output, maxpool_int16_output_ref, MAXPOOL_INT16_DST_SIZE));
+ }
+}
+
+void maxpool_int16_1_arm_max_pool_s16(void)
+{
+ const arm_status expected = ARM_MATH_SUCCESS;
+ int16_t output[MAXPOOL_INT16_1_DST_SIZE] = {0};
+
+ cmsis_nn_context ctx;
+ cmsis_nn_pool_params pool_params;
+ cmsis_nn_dims input_dims;
+ cmsis_nn_dims filter_dims;
+ cmsis_nn_dims output_dims;
+
+ const int16_t *input_data = maxpool_int16_1_input;
+
+ input_dims.n = MAXPOOL_INT16_1_INPUT_BATCHES;
+ input_dims.w = MAXPOOL_INT16_1_INPUT_W;
+ input_dims.h = MAXPOOL_INT16_1_INPUT_H;
+ input_dims.c = MAXPOOL_INT16_1_IN_CH;
+ filter_dims.w = MAXPOOL_INT16_1_FILTER_X;
+ filter_dims.h = MAXPOOL_INT16_1_FILTER_Y;
+ output_dims.w = MAXPOOL_INT16_1_OUTPUT_W;
+ output_dims.h = MAXPOOL_INT16_1_OUTPUT_H;
+ output_dims.c = MAXPOOL_INT16_1_OUT_CH;
+
+ pool_params.padding.w = MAXPOOL_INT16_1_PAD_X;
+ pool_params.padding.h = MAXPOOL_INT16_1_PAD_Y;
+ pool_params.stride.w = MAXPOOL_INT16_1_STRIDE_X;
+ pool_params.stride.h = MAXPOOL_INT16_1_STRIDE_Y;
+
+ pool_params.activation.min = MAXPOOL_INT16_1_OUT_ACTIVATION_MIN;
+ pool_params.activation.max = MAXPOOL_INT16_1_OUT_ACTIVATION_MAX;
+
+ for (int i = 0; i < REPEAT_NUM; i++)
+ {
+ arm_status result =
+ arm_max_pool_s16(&ctx, &pool_params, &input_dims, input_data, &filter_dims, &output_dims, output);
+
+ TEST_ASSERT_EQUAL(expected, result);
+ TEST_ASSERT_TRUE(validate_s16(output, maxpool_int16_1_output_ref, MAXPOOL_INT16_1_DST_SIZE));
+ }
+}
+
+void maxpool_int16_2_arm_max_pool_s16(void)
+{
+ const arm_status expected = ARM_MATH_SUCCESS;
+ int16_t output[MAXPOOL_INT16_2_DST_SIZE] = {0};
+
+ cmsis_nn_context ctx;
+ cmsis_nn_pool_params pool_params;
+ cmsis_nn_dims input_dims;
+ cmsis_nn_dims filter_dims;
+ cmsis_nn_dims output_dims;
+
+ const int16_t *input_data = maxpool_int16_2_input;
+
+ input_dims.n = MAXPOOL_INT16_2_INPUT_BATCHES;
+ input_dims.w = MAXPOOL_INT16_2_INPUT_W;
+ input_dims.h = MAXPOOL_INT16_2_INPUT_H;
+ input_dims.c = MAXPOOL_INT16_2_IN_CH;
+ filter_dims.w = MAXPOOL_INT16_2_FILTER_X;
+ filter_dims.h = MAXPOOL_INT16_2_FILTER_Y;
+ output_dims.w = MAXPOOL_INT16_2_OUTPUT_W;
+ output_dims.h = MAXPOOL_INT16_2_OUTPUT_H;
+ output_dims.c = MAXPOOL_INT16_2_OUT_CH;
+
+ pool_params.padding.w = MAXPOOL_INT16_2_PAD_X;
+ pool_params.padding.h = MAXPOOL_INT16_2_PAD_Y;
+ pool_params.stride.w = MAXPOOL_INT16_2_STRIDE_X;
+ pool_params.stride.h = MAXPOOL_INT16_2_STRIDE_Y;
+
+ pool_params.activation.min = MAXPOOL_INT16_2_OUT_ACTIVATION_MIN;
+ pool_params.activation.max = MAXPOOL_INT16_2_OUT_ACTIVATION_MAX;
+
+ for (int i = 0; i < REPEAT_NUM; i++)
+ {
+ arm_status result =
+ arm_max_pool_s16(&ctx, &pool_params, &input_dims, input_data, &filter_dims, &output_dims, output);
+
+ TEST_ASSERT_EQUAL(expected, result);
+ TEST_ASSERT_TRUE(validate_s16(output, maxpool_int16_2_output_ref, MAXPOOL_INT16_2_DST_SIZE));
+ }
+}
diff --git a/CMSIS/NN/Tests/UnitTest/generate_test_data.py b/CMSIS/NN/Tests/UnitTest/generate_test_data.py
index db992ed..e018c47 100755
--- a/CMSIS/NN/Tests/UnitTest/generate_test_data.py
+++ b/CMSIS/NN/Tests/UnitTest/generate_test_data.py
@@ -545,13 +545,22 @@
class PoolingSettings(TestSettings):
def __init__(self, dataset, testtype, args, channels=8, x_in=4, y_in=4, w_x=4, w_y=4, stride_x=1, stride_y=1,
- batches=1, pad=False, relu6=False):
+ randmin=INT8_MIN, randmax=INT8_MAX, batches=1, pad=False, relu6=False, out_activation_min=None,
+ out_activation_max=None, int16xint8=False):
super().__init__(dataset, testtype, args, channels, channels, x_in, y_in, w_x, w_y, stride_x, stride_y, pad,
- relu6=relu6)
+ randmin=randmin, randmax=randmax, relu6=relu6, out_activation_min=out_activation_min,
+ out_activation_max=out_activation_max, int16xint8=int16xint8)
def generate_data(self, input_data=None):
+ if self.is_int16xint8:
+ datatype = "int16_t"
+ inttype = tf.int16
+ else:
+ datatype = "int8_t"
+ inttype = tf.int8
+
input_data = self.get_randomized_input_data(input_data)
- self.generate_c_array("input", input_data, datatype="int8_t")
+ self.generate_c_array("input", input_data, datatype=datatype)
input_data = tf.cast(input_data, tf.float32)
@@ -571,7 +580,7 @@
else:
raise RuntimeError("Wrong test type")
- interpreter = self.convert_and_interpret(model, input_data, tf.int8)
+ interpreter = self.convert_and_interpret(model, input_data, inttype)
output_details = interpreter.get_output_details()
self.set_output_dims_and_padding(output_details[0]['shape'][2], output_details[0]['shape'][1])
@@ -580,7 +589,7 @@
interpreter.invoke()
output_data = interpreter.get_tensor(output_details[0]["index"])
self.generate_c_array("output_ref", np.clip(output_data, self.out_activation_min, self.out_activation_max),
- datatype="int8_t")
+ datatype=datatype)
self.write_c_config_header()
self.write_c_header_wrapper()
@@ -1173,6 +1182,10 @@
dataset = 'avgpooling_5'
ALL_TESTDATA_SETS[dataset] = PoolingSettings(dataset, type_of_test, args, channels=1, x_in=3, y_in=3,
stride_x=1, stride_y=1, w_x=1, w_y=3, pad=True, relu6=True)
+ dataset = 'avgpooling_int16'
+ ALL_TESTDATA_SETS[dataset] = PoolingSettings(dataset, type_of_test, args, channels=2, x_in=6, y_in=4,
+ stride_x=2, stride_y=1, w_x=2, w_y=3, pad=True,
+ randmin=INT16_MIN, randmax=INT16_MAX, int16xint8=True)
type_of_test = 'maxpool'
dataset = 'maxpooling'
@@ -1199,6 +1212,21 @@
dataset = 'maxpooling_7'
ALL_TESTDATA_SETS[dataset] = PoolingSettings(dataset, type_of_test, args, channels=1, x_in=4, y_in=2, stride_x=2,
stride_y=2, w_x=2, w_y=2, pad=False, relu6=True)
+ dataset = 'maxpool_int16'
+ ALL_TESTDATA_SETS[dataset] = PoolingSettings(dataset, type_of_test, args, channels=2, x_in=4, y_in=3, stride_x=2,
+ stride_y=2, w_x=2, w_y=2, pad=False, randmin=INT16_MIN,
+ randmax=INT16_MAX, int16xint8=True)
+ dataset = 'maxpool_int16_1'
+ ALL_TESTDATA_SETS[dataset] = PoolingSettings(dataset, type_of_test, args, channels=2, x_in=4, y_in=5, stride_x=2,
+ stride_y=1, w_x=3, w_y=3, pad=True, randmin=INT16_MIN,
+ randmax=INT16_MAX, out_activation_min=-30000, out_activation_max=30000,
+ int16xint8=True)
+ dataset = 'maxpool_int16_2'
+ ALL_TESTDATA_SETS[dataset] = PoolingSettings(dataset, type_of_test, args, channels=3, x_in=7, y_in=7, stride_x=1,
+ stride_y=1, w_x=3, w_y=3, pad=False, randmin=INT16_MIN,
+ randmax=INT16_MAX, out_activation_min=-30000, out_activation_max=30000,
+ int16xint8=True)
+
type_of_test = 'softmax'
dataset = 'softmax'
ALL_TESTDATA_SETS[dataset] = SoftmaxSettings(dataset, type_of_test, args, x_in=5, y_in=1)
@@ -1263,4 +1291,10 @@
generator = FullyConnectedSettings(testdataset, test_type, args)
elif args.testtype == 'avgpool' or args.testtype == 'maxpool':
generator = PoolingSettings(testdataset, test_type, args)
+ elif args.testtype == 'softmax':
+ generator = SoftmaxSettings(testdataset, test_type, args)
+ elif args.testtype == 'svdf':
+ generator = SVDFSettings(testdataset, test_type, args)
+ else:
+ raise RuntimeError("Please specify type of test with -t")
generator.generate_data()