mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Merge pull request #499 from openmv/nn_nonsquare
Use nonsquare NN functions.
This commit is contained in:
commit
42efbac090
@ -180,7 +180,7 @@ extern "C"
|
|||||||
* @param[in] dim_im_out_y output tensor dimension y
|
* @param[in] dim_im_out_y output tensor dimension y
|
||||||
* @param[in,out] bufferA pointer to buffer space for input
|
* @param[in,out] bufferA pointer to buffer space for input
|
||||||
* @param[in,out] bufferB pointer to buffer space for output
|
* @param[in,out] bufferB pointer to buffer space for output
|
||||||
* @return The function returns <code>ARM_MATH_SUCCESS</code>
|
* @return The function returns <code>ARM_MATH_SUCCESS</code>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
arm_status arm_convolve_HWC_q7_basic_nonsquare(const q7_t * Im_in,
|
arm_status arm_convolve_HWC_q7_basic_nonsquare(const q7_t * Im_in,
|
||||||
@ -219,9 +219,9 @@ extern "C"
|
|||||||
* @param[in] out_shift amount of right-shift for output
|
* @param[in] out_shift amount of right-shift for output
|
||||||
* @param[in,out] Im_out pointer to output tensor
|
* @param[in,out] Im_out pointer to output tensor
|
||||||
* @param[in] dim_im_out output tensor dimension
|
* @param[in] dim_im_out output tensor dimension
|
||||||
* @param[in,out] bufferA pointer to buffer space for input
|
* @param[in,out] bufferA pointer to buffer space for input
|
||||||
* @param[in,out] bufferB pointer to buffer space for output
|
* @param[in,out] bufferB pointer to buffer space for output
|
||||||
* @return The function returns <code>ARM_MATH_SUCCESS</code>
|
* @return The function returns <code>ARM_MATH_SUCCESS</code>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -236,9 +236,9 @@ extern "C"
|
|||||||
const q15_t * bias,
|
const q15_t * bias,
|
||||||
const uint16_t bias_shift,
|
const uint16_t bias_shift,
|
||||||
const uint16_t out_shift,
|
const uint16_t out_shift,
|
||||||
q15_t * Im_out,
|
q15_t * Im_out,
|
||||||
const uint16_t dim_im_out,
|
const uint16_t dim_im_out,
|
||||||
q15_t * bufferA,
|
q15_t * bufferA,
|
||||||
q7_t * bufferB);
|
q7_t * bufferB);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -256,7 +256,7 @@ extern "C"
|
|||||||
* @param[in] out_shift amount of right-shift for output
|
* @param[in] out_shift amount of right-shift for output
|
||||||
* @param[in,out] Im_out pointer to output tensor
|
* @param[in,out] Im_out pointer to output tensor
|
||||||
* @param[in] dim_im_out output tensor dimension
|
* @param[in] dim_im_out output tensor dimension
|
||||||
* @param[in,out] bufferA pointer to buffer space for input
|
* @param[in,out] bufferA pointer to buffer space for input
|
||||||
* @param[in,out] bufferB pointer to buffer space for output
|
* @param[in,out] bufferB pointer to buffer space for output
|
||||||
* @return The function returns either
|
* @return The function returns either
|
||||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||||
@ -278,9 +278,9 @@ extern "C"
|
|||||||
const q7_t * bias,
|
const q7_t * bias,
|
||||||
const uint16_t bias_shift,
|
const uint16_t bias_shift,
|
||||||
const uint16_t out_shift,
|
const uint16_t out_shift,
|
||||||
q7_t * Im_out,
|
q7_t * Im_out,
|
||||||
const uint16_t dim_im_out,
|
const uint16_t dim_im_out,
|
||||||
q15_t * bufferA,
|
q15_t * bufferA,
|
||||||
q7_t * bufferB);
|
q7_t * bufferB);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -303,7 +303,7 @@ extern "C"
|
|||||||
* @param[in,out] Im_out pointer to output tensor
|
* @param[in,out] Im_out pointer to output tensor
|
||||||
* @param[in] dim_im_out_x output tensor dimension x
|
* @param[in] dim_im_out_x output tensor dimension x
|
||||||
* @param[in] dim_im_out_y output tensor dimension y
|
* @param[in] dim_im_out_y output tensor dimension y
|
||||||
* @param[in,out] bufferA pointer to buffer space for input
|
* @param[in,out] bufferA pointer to buffer space for input
|
||||||
* @param[in,out] bufferB pointer to buffer space for output
|
* @param[in,out] bufferB pointer to buffer space for output
|
||||||
* @return The function returns either
|
* @return The function returns either
|
||||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||||
@ -355,7 +355,7 @@ extern "C"
|
|||||||
* @param[in,out] Im_out pointer to output tensor
|
* @param[in,out] Im_out pointer to output tensor
|
||||||
* @param[in] dim_im_out_x output tensor dimension x
|
* @param[in] dim_im_out_x output tensor dimension x
|
||||||
* @param[in] dim_im_out_y output tensor dimension y
|
* @param[in] dim_im_out_y output tensor dimension y
|
||||||
* @param[in,out] bufferA pointer to buffer space for input
|
* @param[in,out] bufferA pointer to buffer space for input
|
||||||
* @param[in,out] bufferB pointer to buffer space for output
|
* @param[in,out] bufferB pointer to buffer space for output
|
||||||
* @return The function returns either
|
* @return The function returns either
|
||||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||||
@ -949,6 +949,35 @@ extern "C"
|
|||||||
q7_t * bufferA,
|
q7_t * bufferA,
|
||||||
q7_t * Im_out);
|
q7_t * Im_out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Q7 max pooling nonsquare function
|
||||||
|
* @param[in] Im_in pointer to input tensor
|
||||||
|
* @param[in] dim_im_in_x input tensor dimention x
|
||||||
|
* @param[in] dim_im_in_x input tensor dimention y
|
||||||
|
* @param[in] ch_im_in number of input tensor channels
|
||||||
|
* @param[in] dim_kernel filter kernel size
|
||||||
|
* @param[in] padding padding sizes
|
||||||
|
* @param[in] stride convolution stride
|
||||||
|
* @param[in] dim_im_out_x output tensor dimension x
|
||||||
|
* @param[in] dim_im_out_y output tensor dimension y
|
||||||
|
* @param[in,out] bufferA pointer to buffer space for input
|
||||||
|
* @param[in,out] Im_out pointer to output tensor
|
||||||
|
* @return none.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void arm_maxpool_q7_HWC_nonsquare(q7_t * Im_in,
|
||||||
|
const uint16_t dim_im_in_x,
|
||||||
|
const uint16_t dim_im_in_y,
|
||||||
|
const uint16_t ch_im_in,
|
||||||
|
const uint16_t dim_kernel,
|
||||||
|
const uint16_t padding,
|
||||||
|
const uint16_t stride,
|
||||||
|
const uint16_t dim_im_out_x,
|
||||||
|
const uint16_t dim_im_out_y,
|
||||||
|
q7_t * bufferA,
|
||||||
|
q7_t * Im_out);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Q7 average pooling function
|
* @brief Q7 average pooling function
|
||||||
* @param[in] Im_in pointer to input tensor
|
* @param[in] Im_in pointer to input tensor
|
||||||
@ -974,6 +1003,34 @@ extern "C"
|
|||||||
q7_t * bufferA,
|
q7_t * bufferA,
|
||||||
q7_t * Im_out);
|
q7_t * Im_out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Q7 average pooling nonsquare function
|
||||||
|
* @param[in] Im_in pointer to input tensor
|
||||||
|
* @param[in] dim_im_in input tensor dimention
|
||||||
|
* @param[in] ch_im_in number of input tensor channels
|
||||||
|
* @param[in] dim_kernel filter kernel size
|
||||||
|
* @param[in] padding padding sizes
|
||||||
|
* @param[in] stride convolution stride
|
||||||
|
* @param[in] dim_im_out output tensor dimension
|
||||||
|
* @param[in,out] bufferA pointer to buffer space for input
|
||||||
|
* @param[in,out] Im_out pointer to output tensor
|
||||||
|
* @return none.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void arm_avepool_q7_HWC_nonsquare(q7_t * Im_in,
|
||||||
|
const uint16_t dim_im_in_x,
|
||||||
|
const uint16_t dim_im_in_y,
|
||||||
|
const uint16_t ch_im_in,
|
||||||
|
const uint16_t dim_kernel,
|
||||||
|
const uint16_t padding,
|
||||||
|
const uint16_t stride,
|
||||||
|
const uint16_t dim_im_out_x,
|
||||||
|
const uint16_t dim_im_out_y,
|
||||||
|
q7_t * bufferA,
|
||||||
|
q7_t * Im_out);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup Softmax Softmax Functions
|
* @defgroup Softmax Softmax Functions
|
||||||
*
|
*
|
||||||
|
|||||||
180
src/cmsis/src/nn/PoolingFunctions/arm_pool_q7_HWC_nonsquare.c
Normal file
180
src/cmsis/src/nn/PoolingFunctions/arm_pool_q7_HWC_nonsquare.c
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||||
|
*
|
||||||
|
* 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_pool_q7_HWC.c
|
||||||
|
* Description: Pooling function implementations
|
||||||
|
*
|
||||||
|
* $Date: 17. January 2018
|
||||||
|
* $Revision: V.1.0.0
|
||||||
|
*
|
||||||
|
* Target Processor: Cortex-M cores
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include "arm_math.h"
|
||||||
|
#include "arm_nnfunctions.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup groupNN
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup Pooling
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Q7 max pooling function
|
||||||
|
* @param[in, out] Im_in pointer to input tensor
|
||||||
|
* @param[in] dim_im_in input tensor dimention
|
||||||
|
* @param[in] ch_im_in number of input tensor channels
|
||||||
|
* @param[in] dim_kernel filter kernel size
|
||||||
|
* @param[in] padding padding sizes
|
||||||
|
* @param[in] stride convolution stride
|
||||||
|
* @param[in] dim_im_out output tensor dimension
|
||||||
|
* @param[in,out] bufferA pointer to buffer space for input
|
||||||
|
* @param[in,out] Im_out pointer to output tensor
|
||||||
|
* @return none.
|
||||||
|
*
|
||||||
|
* @details
|
||||||
|
*
|
||||||
|
* <b>Buffer size:</b>
|
||||||
|
*
|
||||||
|
* bufferA size: 0
|
||||||
|
*
|
||||||
|
* The pooling function is implemented as split x-pooling then
|
||||||
|
* y-pooling.
|
||||||
|
*
|
||||||
|
* This pooling function is input-destructive. Input data is undefined
|
||||||
|
* after calling this function.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
arm_maxpool_q7_HWC_nonsquare(q7_t * Im_in,
|
||||||
|
const uint16_t dim_im_in_x,
|
||||||
|
const uint16_t dim_im_in_y,
|
||||||
|
const uint16_t ch_im_in,
|
||||||
|
const uint16_t dim_kernel,
|
||||||
|
const uint16_t padding,
|
||||||
|
const uint16_t stride,
|
||||||
|
const uint16_t dim_im_out_x,
|
||||||
|
const uint16_t dim_im_out_y,
|
||||||
|
q7_t * bufferA, q7_t * Im_out)
|
||||||
|
{
|
||||||
|
/* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */
|
||||||
|
|
||||||
|
int16_t i_ch_in, i_x, i_y;
|
||||||
|
int16_t k_x, k_y;
|
||||||
|
|
||||||
|
for (i_ch_in = 0; i_ch_in < ch_im_in; i_ch_in++)
|
||||||
|
{
|
||||||
|
for (i_y = 0; i_y < dim_im_out_y; i_y++)
|
||||||
|
{
|
||||||
|
for (i_x = 0; i_x < dim_im_out_x; i_x++)
|
||||||
|
{
|
||||||
|
int max = -129;
|
||||||
|
for (k_y = i_y * stride - padding; k_y < i_y * stride - padding + dim_kernel; k_y++)
|
||||||
|
{
|
||||||
|
for (k_x = i_x * stride - padding; k_x < i_x * stride - padding + dim_kernel; k_x++)
|
||||||
|
{
|
||||||
|
if (k_y >= 0 && k_x >= 0 && k_y < dim_im_in_y && k_x < dim_im_in_x)
|
||||||
|
{
|
||||||
|
if (Im_in[i_ch_in + ch_im_in * (k_x + k_y * dim_im_in_x)] > max)
|
||||||
|
{
|
||||||
|
max = Im_in[i_ch_in + ch_im_in * (k_x + k_y * dim_im_in_x)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Im_out[i_ch_in + ch_im_in * (i_x + i_y * dim_im_out_x)] = max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Q7 average pooling function
|
||||||
|
* @param[in,out] Im_in pointer to input tensor
|
||||||
|
* @param[in] dim_im_in input tensor dimention
|
||||||
|
* @param[in] ch_im_in number of input tensor channels
|
||||||
|
* @param[in] dim_kernel filter kernel size
|
||||||
|
* @param[in] padding padding sizes
|
||||||
|
* @param[in] stride convolution stride
|
||||||
|
* @param[in] dim_im_out output tensor dimension
|
||||||
|
* @param[in,out] bufferA pointer to buffer space for input
|
||||||
|
* @param[in,out] Im_out pointer to output tensor
|
||||||
|
* @return none.
|
||||||
|
*
|
||||||
|
* @details
|
||||||
|
*
|
||||||
|
* <b>Buffer size:</b>
|
||||||
|
*
|
||||||
|
* bufferA size: 2*dim_im_out*ch_im_in
|
||||||
|
*
|
||||||
|
* The pooling function is implemented as split x-pooling then
|
||||||
|
* y-pooling.
|
||||||
|
*
|
||||||
|
* This pooling function is input-destructive. Input data is undefined
|
||||||
|
* after calling this function.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
arm_avepool_q7_HWC_nonsquare(q7_t * Im_in,
|
||||||
|
const uint16_t dim_im_in_x,
|
||||||
|
const uint16_t dim_im_in_y,
|
||||||
|
const uint16_t ch_im_in,
|
||||||
|
const uint16_t dim_kernel,
|
||||||
|
const uint16_t padding,
|
||||||
|
const uint16_t stride,
|
||||||
|
const uint16_t dim_im_out_x,
|
||||||
|
const uint16_t dim_im_out_y,
|
||||||
|
q7_t * bufferA, q7_t * Im_out)
|
||||||
|
{
|
||||||
|
/* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */
|
||||||
|
|
||||||
|
int16_t i_ch_in, i_x, i_y;
|
||||||
|
int16_t k_x, k_y;
|
||||||
|
|
||||||
|
for (i_ch_in = 0; i_ch_in < ch_im_in; i_ch_in++)
|
||||||
|
{
|
||||||
|
for (i_y = 0; i_y < dim_im_out_y; i_y++)
|
||||||
|
{
|
||||||
|
for (i_x = 0; i_x < dim_im_out_x; i_x++)
|
||||||
|
{
|
||||||
|
int sum = 0;
|
||||||
|
int count = 0;
|
||||||
|
for (k_y = i_y * stride - padding; k_y < i_y * stride - padding + dim_kernel; k_y++)
|
||||||
|
{
|
||||||
|
for (k_x = i_x * stride - padding; k_x < i_x * stride - padding + dim_kernel; k_x++)
|
||||||
|
{
|
||||||
|
if (k_y >= 0 && k_x >= 0 && k_y < dim_im_in_y && k_x < dim_im_in_x)
|
||||||
|
{
|
||||||
|
sum += Im_in[i_ch_in + ch_im_in * (k_x + k_y * dim_im_in_x)];
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Im_out[i_ch_in + ch_im_in * (i_x + i_y * dim_im_out_x)] = sum / count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
117
src/omv/nn/nn.c
117
src/omv/nn/nn.c
@ -381,19 +381,34 @@ int nn_run_network(nn_t *net, image_t *img, rectangle_t *roi, bool softmax)
|
|||||||
|
|
||||||
case LAYER_TYPE_CONV: {
|
case LAYER_TYPE_CONV: {
|
||||||
conv_func_t conv_func = NULL;
|
conv_func_t conv_func = NULL;
|
||||||
|
conv_func_nonsquare_t conv_func_nonsquare = NULL;
|
||||||
conv_layer_t *conv_layer = (conv_layer_t *) layer;
|
conv_layer_t *conv_layer = (conv_layer_t *) layer;
|
||||||
if (prev_layer->c % 4 != 0 ||
|
if (prev_layer->c % 4 != 0 ||
|
||||||
conv_layer->n % 2 != 0 || prev_layer->h % 2 != 0) {
|
conv_layer->n % 2 != 0 || prev_layer->h % 2 != 0) {
|
||||||
conv_func = arm_convolve_HWC_q7_basic;
|
|
||||||
if (prev_layer->c == 3) {
|
if (prev_layer->c == 3) {
|
||||||
conv_func = arm_convolve_HWC_q7_RGB;
|
conv_func = arm_convolve_HWC_q7_RGB;
|
||||||
|
} else if (prev_layer->w == prev_layer->h) {
|
||||||
|
conv_func = arm_convolve_HWC_q7_basic;
|
||||||
|
} else {
|
||||||
|
conv_func_nonsquare = arm_convolve_HWC_q7_basic_nonsquare;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
conv_func = arm_convolve_HWC_q7_fast;
|
if (prev_layer->w == prev_layer->h) {
|
||||||
|
conv_func = arm_convolve_HWC_q7_fast;
|
||||||
|
} else {
|
||||||
|
conv_func_nonsquare = arm_convolve_HWC_q7_fast_nonsquare;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (conv_func) {
|
||||||
|
conv_func(input_buffer, prev_layer->h, prev_layer->c, conv_layer->wt, conv_layer->c,
|
||||||
|
conv_layer->krn_dim, conv_layer->krn_pad, conv_layer->krn_str, conv_layer->bias,
|
||||||
|
conv_layer->l_shift, conv_layer->r_shift, output_buffer, conv_layer->h, (q15_t*)col_buffer, NULL);
|
||||||
|
} else {
|
||||||
|
conv_func_nonsquare(input_buffer, prev_layer->w, prev_layer->h, prev_layer->c, conv_layer->wt, conv_layer->c,
|
||||||
|
conv_layer->krn_dim, conv_layer->krn_dim, conv_layer->krn_pad, conv_layer->krn_pad, conv_layer->krn_str,
|
||||||
|
conv_layer->krn_str, conv_layer->bias, conv_layer->l_shift, conv_layer->r_shift, output_buffer,
|
||||||
|
conv_layer->w, conv_layer->h, (q15_t*)col_buffer, NULL);
|
||||||
}
|
}
|
||||||
conv_func(input_buffer, prev_layer->h, prev_layer->c, conv_layer->wt, conv_layer->c,
|
|
||||||
conv_layer->krn_dim, conv_layer->krn_pad, conv_layer->krn_str, conv_layer->bias,
|
|
||||||
conv_layer->l_shift, conv_layer->r_shift, output_buffer, conv_layer->h, (q15_t*)col_buffer, NULL);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,14 +420,28 @@ int nn_run_network(nn_t *net, image_t *img, rectangle_t *roi, bool softmax)
|
|||||||
|
|
||||||
case LAYER_TYPE_POOL: {
|
case LAYER_TYPE_POOL: {
|
||||||
pool_func_t pool_func = NULL;
|
pool_func_t pool_func = NULL;
|
||||||
|
pool_func_nonsquare_t pool_func_nonsquare = NULL;
|
||||||
pool_layer_t *pool_layer = (pool_layer_t *) layer;
|
pool_layer_t *pool_layer = (pool_layer_t *) layer;
|
||||||
if (pool_layer->ptype == POOL_TYPE_MAX) {
|
if (pool_layer->ptype == POOL_TYPE_MAX) {
|
||||||
pool_func = arm_maxpool_q7_HWC;
|
if (prev_layer->w == prev_layer->h) {
|
||||||
|
pool_func = arm_maxpool_q7_HWC;
|
||||||
|
} else {
|
||||||
|
pool_func_nonsquare = arm_maxpool_q7_HWC_nonsquare;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
pool_func = arm_avepool_q7_HWC;
|
if (prev_layer->w == prev_layer->h) {
|
||||||
|
pool_func = arm_avepool_q7_HWC;
|
||||||
|
} else {
|
||||||
|
pool_func_nonsquare = arm_avepool_q7_HWC_nonsquare;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pool_func) {
|
||||||
|
pool_func(input_buffer, prev_layer->h, prev_layer->c, pool_layer->krn_dim,
|
||||||
|
pool_layer->krn_pad, pool_layer->krn_str, layer->w, col_buffer, output_buffer);
|
||||||
|
} else {
|
||||||
|
pool_func_nonsquare(input_buffer, prev_layer->w, prev_layer->h, prev_layer->c, pool_layer->krn_dim,
|
||||||
|
pool_layer->krn_pad, pool_layer->krn_str, layer->w, layer->h, col_buffer, output_buffer);
|
||||||
}
|
}
|
||||||
pool_func(input_buffer, prev_layer->h, prev_layer->c, pool_layer->krn_dim,
|
|
||||||
pool_layer->krn_pad, pool_layer->krn_str, layer->w, col_buffer, output_buffer);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,6 +497,13 @@ int nn_run_network(nn_t *net, image_t *img, rectangle_t *roi, bool softmax)
|
|||||||
#define POOL_FUNC_2STR(pool_func)\
|
#define POOL_FUNC_2STR(pool_func)\
|
||||||
(pool_func == arm_maxpool_q7_HWC) ? "arm_maxpool_q7_HWC" : "arm_avepool_q7_HWC"
|
(pool_func == arm_maxpool_q7_HWC) ? "arm_maxpool_q7_HWC" : "arm_avepool_q7_HWC"
|
||||||
|
|
||||||
|
#define CONV_FUNC_NONSQ_2STR(conv_func)\
|
||||||
|
(conv_func == arm_convolve_HWC_q7_basic_nonsquare) ? "arm_convolve_HWC_q7_basic_nonsquare":\
|
||||||
|
"arm_convolve_HWC_q7_fast_nonsquare"
|
||||||
|
|
||||||
|
#define POOL_FUNC_NONSQ_2STR(pool_func)\
|
||||||
|
(pool_func == arm_maxpool_q7_HWC_nonsquare) ? "arm_maxpool_q7_HWC_nonsquare" : "arm_avepool_q7_HWC_nonsquare"
|
||||||
|
|
||||||
int nn_dry_run_network(nn_t *net, image_t *img, bool softmax)
|
int nn_dry_run_network(nn_t *net, image_t *img, bool softmax)
|
||||||
{
|
{
|
||||||
uint32_t layer_idx = 0;
|
uint32_t layer_idx = 0;
|
||||||
@ -505,22 +541,41 @@ int nn_dry_run_network(nn_t *net, image_t *img, bool softmax)
|
|||||||
|
|
||||||
case LAYER_TYPE_CONV: {
|
case LAYER_TYPE_CONV: {
|
||||||
conv_func_t conv_func = NULL;
|
conv_func_t conv_func = NULL;
|
||||||
|
conv_func_nonsquare_t conv_func_nonsquare = NULL;
|
||||||
conv_layer_t *conv_layer = (conv_layer_t *) layer;
|
conv_layer_t *conv_layer = (conv_layer_t *) layer;
|
||||||
if (prev_layer->c % 4 != 0 ||
|
if (prev_layer->c % 4 != 0 ||
|
||||||
conv_layer->n % 2 != 0 || prev_layer->h % 2 != 0) {
|
conv_layer->n % 2 != 0 || prev_layer->h % 2 != 0) {
|
||||||
conv_func = arm_convolve_HWC_q7_basic;
|
|
||||||
if (prev_layer->c == 3) {
|
if (prev_layer->c == 3) {
|
||||||
conv_func = arm_convolve_HWC_q7_RGB;
|
conv_func = arm_convolve_HWC_q7_RGB;
|
||||||
|
} else if (prev_layer->w == prev_layer->h) {
|
||||||
|
conv_func = arm_convolve_HWC_q7_basic;
|
||||||
|
} else {
|
||||||
|
conv_func_nonsquare = arm_convolve_HWC_q7_basic_nonsquare;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
conv_func = arm_convolve_HWC_q7_fast;
|
if (prev_layer->w == prev_layer->h) {
|
||||||
|
conv_func = arm_convolve_HWC_q7_fast;
|
||||||
|
} else {
|
||||||
|
conv_func_nonsquare = arm_convolve_HWC_q7_fast_nonsquare;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conv_func) {
|
||||||
|
printf("forward: %s(%s, %lu, %lu, %s, %lu, %lu, %lu, %lu, %s, %lu, %lu, %s, %lu, %s, %p);\n",
|
||||||
|
CONV_FUNC_2STR(conv_func), BUFFER_2STR(input_buffer),
|
||||||
|
prev_layer->h, prev_layer->c, "conv_wt", conv_layer->c,
|
||||||
|
conv_layer->krn_dim, conv_layer->krn_pad, conv_layer->krn_str,
|
||||||
|
"conv_bias", conv_layer->l_shift, conv_layer->r_shift,
|
||||||
|
BUFFER_2STR(output_buffer), conv_layer->h, "col_buffer", NULL);
|
||||||
|
} else {
|
||||||
|
printf("forward: %s(%s, %lu, %lu, %lu, %s, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %s, %lu, %lu, \
|
||||||
|
%s, %lu, %lu, %s, %p);\n",
|
||||||
|
CONV_FUNC_NONSQ_2STR(conv_func_nonsquare), BUFFER_2STR(input_buffer),
|
||||||
|
prev_layer->w, prev_layer->h, prev_layer->c, "conv_wt", conv_layer->c,
|
||||||
|
conv_layer->krn_dim, conv_layer->krn_dim, conv_layer->krn_pad, conv_layer->krn_pad,
|
||||||
|
conv_layer->krn_str, conv_layer->krn_str, "conv_bias", conv_layer->l_shift, conv_layer->r_shift,
|
||||||
|
BUFFER_2STR(output_buffer), conv_layer->w, conv_layer->h, "col_buffer", NULL);
|
||||||
}
|
}
|
||||||
printf("forward: %s(%s, %lu, %lu, %s, %lu, %lu, %lu, %lu, %s, %lu, %lu, %s, %lu, %s, %p);\n",
|
|
||||||
CONV_FUNC_2STR(conv_func), BUFFER_2STR(input_buffer),
|
|
||||||
prev_layer->h, prev_layer->c, "conv_wt", conv_layer->c,
|
|
||||||
conv_layer->krn_dim, conv_layer->krn_pad, conv_layer->krn_str,
|
|
||||||
"conv_bias", conv_layer->l_shift, conv_layer->r_shift,
|
|
||||||
BUFFER_2STR(output_buffer), conv_layer->h, "col_buffer", NULL);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -533,16 +588,32 @@ int nn_dry_run_network(nn_t *net, image_t *img, bool softmax)
|
|||||||
|
|
||||||
case LAYER_TYPE_POOL: {
|
case LAYER_TYPE_POOL: {
|
||||||
pool_func_t pool_func = NULL;
|
pool_func_t pool_func = NULL;
|
||||||
|
pool_func_nonsquare_t pool_func_nonsquare = NULL;
|
||||||
pool_layer_t *pool_layer = (pool_layer_t *) layer;
|
pool_layer_t *pool_layer = (pool_layer_t *) layer;
|
||||||
if (pool_layer->ptype == POOL_TYPE_MAX) {
|
if (pool_layer->ptype == POOL_TYPE_MAX) {
|
||||||
pool_func = arm_maxpool_q7_HWC;
|
if (prev_layer->w == prev_layer->h) {
|
||||||
|
pool_func = arm_maxpool_q7_HWC;
|
||||||
|
} else {
|
||||||
|
pool_func_nonsquare = arm_maxpool_q7_HWC_nonsquare;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
pool_func = arm_avepool_q7_HWC;
|
if (prev_layer->w == prev_layer->h) {
|
||||||
|
pool_func = arm_avepool_q7_HWC;
|
||||||
|
} else {
|
||||||
|
pool_func_nonsquare = arm_avepool_q7_HWC_nonsquare;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pool_func) {
|
||||||
|
printf("forward: %s(%s, %lu, %lu, %lu, %lu, %lu, %lu, %s, %s);\n",
|
||||||
|
POOL_FUNC_2STR(pool_func), BUFFER_2STR(input_buffer),
|
||||||
|
prev_layer->h, prev_layer->c, pool_layer->krn_dim,
|
||||||
|
pool_layer->krn_pad, pool_layer->krn_str, layer->w, "col_buffer", BUFFER_2STR(output_buffer));
|
||||||
|
} else {
|
||||||
|
printf("forward: %s(%s, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %s, %s);\n",
|
||||||
|
POOL_FUNC_NONSQ_2STR(pool_func_nonsquare), BUFFER_2STR(input_buffer),
|
||||||
|
prev_layer->w, prev_layer->h, prev_layer->c, pool_layer->krn_dim,
|
||||||
|
pool_layer->krn_pad, pool_layer->krn_str, layer->w, layer->h, "col_buffer", BUFFER_2STR(output_buffer));
|
||||||
}
|
}
|
||||||
printf("forward: %s(%s, %lu, %lu, %lu, %lu, %lu, %lu, %s, %s);\n",
|
|
||||||
POOL_FUNC_2STR(pool_func), BUFFER_2STR(input_buffer),
|
|
||||||
prev_layer->h, prev_layer->c, pool_layer->krn_dim,
|
|
||||||
pool_layer->krn_pad, pool_layer->krn_str, layer->w, "col_buffer", BUFFER_2STR(output_buffer));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -93,10 +93,20 @@ typedef arm_status (*conv_func_t) (const q7_t * Im_in, const uint16_t dim_im_in,
|
|||||||
const uint16_t stride, const q7_t * bias, const uint16_t bias_shift, const uint16_t out_shift,
|
const uint16_t stride, const q7_t * bias, const uint16_t bias_shift, const uint16_t out_shift,
|
||||||
q7_t * Im_out, const uint16_t dim_im_out, q15_t * bufferA, q7_t * bufferB);
|
q7_t * Im_out, const uint16_t dim_im_out, q15_t * bufferA, q7_t * bufferB);
|
||||||
|
|
||||||
|
typedef arm_status (*conv_func_nonsquare_t) (const q7_t * Im_in, const uint16_t dim_im_in_x, const uint16_t dim_im_in_y,
|
||||||
|
const uint16_t ch_im_in, const q7_t * wt, const uint16_t ch_im_out, const uint16_t dim_kernel_x, const uint16_t dim_kernel_y,
|
||||||
|
const uint16_t padding_x, const uint16_t padding_y, const uint16_t stride_x, const uint16_t stride_y, const q7_t * bias,
|
||||||
|
const uint16_t bias_shift, const uint16_t out_shift, q7_t * Im_out, const uint16_t dim_im_out_x, const uint16_t dim_im_out_y,
|
||||||
|
q15_t * bufferA, q7_t * bufferB);
|
||||||
|
|
||||||
typedef void (*pool_func_t)(q7_t * Im_in, const uint16_t dim_im_in, const uint16_t ch_im_in,
|
typedef void (*pool_func_t)(q7_t * Im_in, const uint16_t dim_im_in, const uint16_t ch_im_in,
|
||||||
const uint16_t dim_kernel, const uint16_t padding, const uint16_t stride,
|
const uint16_t dim_kernel, const uint16_t padding, const uint16_t stride,
|
||||||
const uint16_t dim_im_out, q7_t * bufferA, q7_t * Im_out);
|
const uint16_t dim_im_out, q7_t * bufferA, q7_t * Im_out);
|
||||||
|
|
||||||
|
typedef void (*pool_func_nonsquare_t)(q7_t * Im_in, const uint16_t dim_im_in_x, const uint16_t dim_im_in_y, const uint16_t ch_im_in,
|
||||||
|
const uint16_t dim_kernel, const uint16_t padding, const uint16_t stride,
|
||||||
|
const uint16_t dim_im_out_x, const uint16_t dim_im_out_y, q7_t * bufferA, q7_t * Im_out);
|
||||||
|
|
||||||
|
|
||||||
int nn_dump_network(nn_t *net);
|
int nn_dump_network(nn_t *net);
|
||||||
int nn_load_network(nn_t *net, const char *path);
|
int nn_load_network(nn_t *net, const char *path);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user