Skip to content

Commit

Permalink
Add int32 bias support for int16x8 convolution (ARM-software#131)
Browse files Browse the repository at this point in the history
Adds new unit test and also adds support for arm_convolve_s16 for the
refactored unit test.
  • Loading branch information
mansnils authored Apr 29, 2024
1 parent ac4a57a commit 15dbe7c
Show file tree
Hide file tree
Showing 167 changed files with 7,457 additions and 2,933 deletions.
12 changes: 10 additions & 2 deletions Include/arm_nn_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@
* Description: Public header file to contain the CMSIS-NN structs for the
* TensorFlowLite micro compliant functions
*
* $Date: 26 March 2024
* $Revision: V.3.1.0
* $Date: 11 April 2024
* $Revision: V.3.2.0
*
* Target : Arm(R) M-Profile Architecture
* -------------------------------------------------------------------- */

#ifndef ARM_NN_TYPES_H
#define ARM_NN_TYPES_H

#include <stdbool.h>
#include <stdint.h>

/**
Expand Down Expand Up @@ -70,6 +71,13 @@ typedef struct
int32_t size; /**< Buffer size */
} cmsis_nn_context;

/** CMSIS-NN object used to hold bias data for int16 variants. */
typedef struct
{
const void *data; /**< Pointer to bias data */
const bool is_int32_bias; /**< Indicate type of bias data. True means int32 else int64 */
} cmsis_nn_bias_data;

/** CMSIS-NN object to contain the dimensions of the tensors */
typedef struct
{
Expand Down
15 changes: 8 additions & 7 deletions Include/arm_nnfunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@
* Title: arm_nnfunctions.h
* Description: Public header file for CMSIS NN Library
*
* $Date: 10 April 2024
* $Revision: V.15.2.0
* $Date: 23 April 2024
* $Revision: V.16.0.0
*
* Target : Arm(R) M-Profile Architecture
* -------------------------------------------------------------------- */
Expand Down Expand Up @@ -250,7 +249,8 @@ int32_t arm_convolve_wrapper_s8_get_buffer_size_dsp(const cmsis_nn_conv_params *
* spatial filter dimensions
* @param[in] filter_data Filter data pointer. Data type: int8
* @param[in] bias_dims Bias tensor dimensions. Format: [C_OUT]
* @param[in] bias_data Bias data pointer. Data type: int64
* @param[in] bias_data Struct with optional bias data pointer. Bias data type can be int64 or int32 depending
* flag in struct.
* @param[in] output_dims Output tensor dimensions. Format: [N, H, W, C_OUT]
* @param[out] output_data Output data pointer. Data type: int16
*
Expand All @@ -267,7 +267,7 @@ arm_cmsis_nn_status arm_convolve_wrapper_s16(const cmsis_nn_context *ctx,
const cmsis_nn_dims *filter_dims,
const int8_t *filter_data,
const cmsis_nn_dims *bias_dims,
const int64_t *bias_data,
const cmsis_nn_bias_data *bias_data,
const cmsis_nn_dims *output_dims,
int16_t *output_data);

Expand Down Expand Up @@ -521,7 +521,8 @@ int32_t arm_transpose_conv_s8_get_buffer_size_mve(const cmsis_nn_dims *input_dim
* spatial filter dimensions
* @param[in] filter_data Filter data pointer. Data type: int8
* @param[in] bias_dims Bias tensor dimensions. Format: [C_OUT]
* @param[in] bias_data Optional bias data pointer. Data type: int64
* @param[in] bias_data Struct with optional bias data pointer. Bias data type can be int64 or int32 depending
* flag in struct.
* @param[in] output_dims Output tensor dimensions. Format: [N, H, W, C_OUT]
* @param[out] output_data Output data pointer. Data type: int16
*
Expand All @@ -542,7 +543,7 @@ arm_cmsis_nn_status arm_convolve_s16(const cmsis_nn_context *ctx,
const cmsis_nn_dims *filter_dims,
const int8_t *filter_data,
const cmsis_nn_dims *bias_dims,
const int64_t *bias_data,
const cmsis_nn_bias_data *bias_data,
const cmsis_nn_dims *output_dims,
int16_t *output_data);

Expand Down
21 changes: 12 additions & 9 deletions Include/arm_nnsupportfunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
* Title: arm_nnsupportfunctions.h
* Description: Public header file of support functions for CMSIS NN Library
*
* $Date: 16 April 2024
* $Revision: V.20.3.0
* $Date: 23 April 2024
* $Revision: V.21.0.0
*
* Target : Arm(R) M-Profile Architecture
* -------------------------------------------------------------------- */
Expand Down Expand Up @@ -264,12 +264,14 @@ int8_t *arm_nn_mat_mult_s8(const int8_t *input_row,
* @param[in] input_a pointer to operand A
* @param[in] input_b pointer to operand B, always consists of 2 vectors.
* @param[in] output_ch number of rows of A
* @param[in] out_shift pointer to per output channel requantization shift parameter.
* @param[in] out_mult pointer to per output channel requantization multiplier parameter.
* @param[in] out_shift pointer to per output channel requantization shift parameter.
* @param[in] out_mult pointer to per output channel requantization multiplier parameter.
* @param[in] activation_min minimum value to clamp the output to. Range : int16
* @param[in] activation_max maximum value to clamp the output to. Range : int16
* @param[in] num_col_a number of columns of A
* @param[in] output_bias per output channel bias. Range : int64
* @param[in] bias_data pointer to struct with bias vector. The length of this vector is equal to the number
* of output columns (or RHS input rows). The vector can be int32 or int64 indicated by a
* flag in the struct.
* @param[in,out] out_0 pointer to output
* @return The function returns one of the two
* 1. The incremented output pointer for a successful operation or
Expand All @@ -288,7 +290,7 @@ int16_t *arm_nn_mat_mult_kernel_s16(const int8_t *input_a,
const int32_t activation_min,
const int32_t activation_max,
const int32_t num_col_a,
const int64_t *const output_bias,
const cmsis_nn_bias_data *const bias_data,
int16_t *out_0);

/**
Expand Down Expand Up @@ -497,8 +499,9 @@ arm_cmsis_nn_status arm_nn_mat_mult_nt_t_s8(const int8_t *lhs,
*
* @param[in] lhs Pointer to the LHS input matrix
* @param[in] rhs Pointer to the RHS input matrix
* @param[in] bias Pointer to the bias vector. The length of this vector is equal to the number of
* output columns (or RHS input rows)
* @param[in] bias_data Pointer to struct with bias vector. The length of this vector is equal to the number
* of output columns (or RHS input rows). The vector can be int32 or int64 indicated by a
* flag in the struct.
* @param[out] dst Pointer to the output matrix with "m" rows and "n" columns
* @param[in] dst_multipliers Pointer to the multipliers vector needed for the per-channel requantization.
* The length of this vector is equal to the number of output columns (or RHS input
Expand All @@ -519,7 +522,7 @@ arm_cmsis_nn_status arm_nn_mat_mult_nt_t_s8(const int8_t *lhs,
*/
arm_cmsis_nn_status arm_nn_mat_mult_nt_t_s16(const int16_t *lhs,
const int8_t *rhs,
const int64_t *bias,
const cmsis_nn_bias_data *bias_data,
int16_t *dst,
const int32_t *dst_multipliers,
const int32_t *dst_shifts,
Expand Down
34 changes: 26 additions & 8 deletions Source/ConvolutionFunctions/arm_convolve_s16.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
* Title: arm_convolve_s16.c
* Description: s16 version of convolution.
*
* $Date: 22 March 2024
* $Revision: V.3.0.0
* $Date: 22 April 2024
* $Revision: V.4.0.0
*
* Target : Arm(R) M-Profile Architecture
*
Expand Down Expand Up @@ -55,7 +55,7 @@ arm_cmsis_nn_status arm_convolve_s16(const cmsis_nn_context *ctx,
const cmsis_nn_dims *filter_dims,
const int8_t *filter_data,
const cmsis_nn_dims *bias_dims,
const int64_t *bias_data,
const cmsis_nn_bias_data *bias_data,
const cmsis_nn_dims *output_dims,
int16_t *output_data)
{
Expand Down Expand Up @@ -200,6 +200,9 @@ arm_cmsis_nn_status arm_convolve_s16(const cmsis_nn_context *ctx,
im2col = buffer_a;
#else // #if defined(ARM_MATH_MVEI)

const int64_t *bias_s64 = (const int64_t *)bias_data->data;
const int32_t *bias_s32 = (const int32_t *)bias_data->data;
const bool is_int32_bias = bias_data->is_int32_bias;
const int8_t *ker_a = filter_data;
int i;

Expand Down Expand Up @@ -235,28 +238,43 @@ arm_cmsis_nn_status arm_convolve_s16(const cmsis_nn_context *ctx,
uint16_t col_count = rhs_cols;

#endif

while (col_count)
{
int8_t ker_a1 = *ker_a++;
int16_t ip_b1 = *ip_as_col++;
sum += ker_a1 * ip_b1;
col_count--;
}
if (bias_data)

if (is_int32_bias)
{
int32_t reduced_multiplier = REDUCE_MULTIPLIER(output_mult[i]);
int64_t acc_64 = sum + bias_data[i];
sum = arm_nn_requantize_s64(acc_64, reduced_multiplier, output_shift[i]);
if (bias_s32)
{
sum += bias_s32[i];
}

sum = arm_nn_requantize(sum, output_mult[i], output_shift[i]);
}
else
{
sum = arm_nn_requantize(sum, output_mult[i], output_shift[i]);
int64_t acc_64 = sum;

if (bias_s64)
{
acc_64 += bias_s64[i];
}

int32_t reduced_multiplier = REDUCE_MULTIPLIER(output_mult[i]);
sum = arm_nn_requantize_s64(acc_64, reduced_multiplier, output_shift[i]);
}

sum = MAX(sum, out_activation_min);
sum = MIN(sum, out_activation_max);
*out++ = (int16_t)sum;
}
lhs_rows = 0;

#endif // #if defined(ARM_MATH_MVEI)
}

Expand Down
6 changes: 3 additions & 3 deletions Source/ConvolutionFunctions/arm_convolve_wrapper_s16.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
* Description: s16 convolution layer wrapper function with the main purpose to call the optimal kernel available in
* cmsis-nn to perform the convolution.
*
* $Date: 12 March 2024
* $Revision: V.2.2.0
* $Date: 23 April 2024
* $Revision: V.3.0.0
*
* Target : Arm(R) M-Profile Architecture
*
Expand Down Expand Up @@ -55,7 +55,7 @@ arm_cmsis_nn_status arm_convolve_wrapper_s16(const cmsis_nn_context *ctx,
const cmsis_nn_dims *filter_dims,
const int8_t *filter_data,
const cmsis_nn_dims *bias_dims,
const int64_t *bias_data,
const cmsis_nn_bias_data *bias_data,
const cmsis_nn_dims *output_dims,
int16_t *output_data)
{
Expand Down
Loading

0 comments on commit 15dbe7c

Please sign in to comment.