Initial commit
This commit is contained in:
		| @@ -0,0 +1,44 @@ | ||||
| /*------------------------------------------------------------------------------ | ||||
|  * MDK - Component ::Event Recorder | ||||
|  * Copyright (c) 2016 ARM Germany GmbH. All rights reserved. | ||||
|  *------------------------------------------------------------------------------ | ||||
|  * Name:    EventRecorderConf.h | ||||
|  * Purpose: Event Recorder Configuration | ||||
|  * Rev.:    V1.0.0 | ||||
|  *----------------------------------------------------------------------------*/ | ||||
|  | ||||
| //-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- | ||||
|  | ||||
| // <h>Event Recorder | ||||
|  | ||||
| //   <o>Number of Records | ||||
| //     <8=>8 <16=>16 <32=>32 <64=>64 <128=>128 <256=>256 <512=>512 <1024=>1024 | ||||
| //     <2048=>2048 <4096=>4096 <8192=>8192 <16384=>16384 <32768=>32768 | ||||
| //     <65536=>65536 <131072=>131072 <262144=>262144 <524288=>524288 | ||||
| //     <1048576=>1048576 | ||||
| //   <i>Configure size of Event Record Buffer (each record is 16 bytes) | ||||
| //   <i>Must be 2^n (min=8, max=1048576) | ||||
| #define EVENT_RECORD_COUNT      64U | ||||
|  | ||||
| //   <o>Time Stamp Source | ||||
| //      <0=> DWT Cycle Counter  <1=> SysTick | ||||
| //      <3=> User Timer (Normal Reset)  <4=> User Timer (Power-On Reset) | ||||
| //   <i>Selects source for 32-bit time stamp | ||||
| #define EVENT_TIMESTAMP_SOURCE  1 | ||||
|  | ||||
| //   <h>SysTick Configuration | ||||
| //   <i>Configure values when Time Stamp Source is set to SysTick | ||||
|  | ||||
| //     <o>SysTick Input Clock Frequency [Hz] <1-1000000000> | ||||
| //     <i>Defines SysTick input clock (typical identical with processor clock) | ||||
| #define SYSTICK_CLOCK           100000000U | ||||
|  | ||||
| //     <o>SysTick Interrupt Period [us] <1-1000000000> | ||||
| //     <i>Defines time period of the SysTick timer interrupt | ||||
| #define SYSTICK_PERIOD_US       1000U | ||||
|  | ||||
| //   </h> | ||||
|  | ||||
| // </h> | ||||
|  | ||||
| //------------- <<< end of configuration section >>> --------------------------- | ||||
| @@ -0,0 +1,24 @@ | ||||
|  | ||||
| /* | ||||
|  * Auto generated Run-Time-Environment Component Configuration File | ||||
|  *      *** Do not modify ! *** | ||||
|  * | ||||
|  * Project: 'arm_nnexamples_cifar10'  | ||||
|  * Target:  'ARMCM0'  | ||||
|  */ | ||||
|  | ||||
| #ifndef RTE_COMPONENTS_H | ||||
| #define RTE_COMPONENTS_H | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Define the Device Header File:  | ||||
|  */ | ||||
| #define CMSIS_device_header "ARMCM0.h" | ||||
|  | ||||
| #define RTE_Compiler_EventRecorder | ||||
|           #define RTE_Compiler_EventRecorder_DAP | ||||
| #define RTE_Compiler_IO_STDOUT          /* Compiler I/O: STDOUT */ | ||||
|           #define RTE_Compiler_IO_STDOUT_EVR      /* Compiler I/O: STDOUT EVR */ | ||||
|  | ||||
| #endif /* RTE_COMPONENTS_H */ | ||||
| @@ -0,0 +1,22 @@ | ||||
|  | ||||
| /* | ||||
|  * Auto generated Run-Time-Environment Component Configuration File | ||||
|  *      *** Do not modify ! *** | ||||
|  * | ||||
|  * Project: 'arm_nnexamples_cifar10'  | ||||
|  * Target:  'ARMCM3'  | ||||
|  */ | ||||
|  | ||||
| #ifndef RTE_COMPONENTS_H | ||||
| #define RTE_COMPONENTS_H | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Define the Device Header File:  | ||||
|  */ | ||||
| #define CMSIS_device_header "ARMCM3.h" | ||||
|  | ||||
| #define RTE_Compiler_IO_STDOUT          /* Compiler I/O: STDOUT */ | ||||
|           #define RTE_Compiler_IO_STDOUT_ITM      /* Compiler I/O: STDOUT ITM */ | ||||
|  | ||||
| #endif /* RTE_COMPONENTS_H */ | ||||
| @@ -0,0 +1,22 @@ | ||||
|  | ||||
| /* | ||||
|  * Auto generated Run-Time-Environment Component Configuration File | ||||
|  *      *** Do not modify ! *** | ||||
|  * | ||||
|  * Project: 'arm_nnexamples_cifar10'  | ||||
|  * Target:  'ARMCM4_FP'  | ||||
|  */ | ||||
|  | ||||
| #ifndef RTE_COMPONENTS_H | ||||
| #define RTE_COMPONENTS_H | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Define the Device Header File:  | ||||
|  */ | ||||
| #define CMSIS_device_header "ARMCM4_FP.h" | ||||
|  | ||||
| #define RTE_Compiler_IO_STDOUT          /* Compiler I/O: STDOUT */ | ||||
|           #define RTE_Compiler_IO_STDOUT_ITM      /* Compiler I/O: STDOUT ITM */ | ||||
|  | ||||
| #endif /* RTE_COMPONENTS_H */ | ||||
| @@ -0,0 +1,22 @@ | ||||
|  | ||||
| /* | ||||
|  * Auto generated Run-Time-Environment Component Configuration File | ||||
|  *      *** Do not modify ! *** | ||||
|  * | ||||
|  * Project: 'arm_nnexamples_cifar10'  | ||||
|  * Target:  'ARMCM7_SP'  | ||||
|  */ | ||||
|  | ||||
| #ifndef RTE_COMPONENTS_H | ||||
| #define RTE_COMPONENTS_H | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Define the Device Header File:  | ||||
|  */ | ||||
| #define CMSIS_device_header "ARMCM7_SP.h" | ||||
|  | ||||
| #define RTE_Compiler_IO_STDOUT          /* Compiler I/O: STDOUT */ | ||||
|           #define RTE_Compiler_IO_STDOUT_ITM      /* Compiler I/O: STDOUT ITM */ | ||||
|  | ||||
| #endif /* RTE_COMPONENTS_H */ | ||||
| @@ -0,0 +1,196 @@ | ||||
| /* ---------------------------------------------------------------------- | ||||
| * Copyright (C) 2010-2018 Arm Limited. All rights reserved. | ||||
| * | ||||
| * | ||||
| * Project:       CMSIS NN Library | ||||
| * Title:         arm_nnexamples_cifar10.cpp | ||||
| * | ||||
| * Description:   Convolutional Neural Network Example | ||||
| * | ||||
| * Target Processor: Cortex-M4/Cortex-M7 | ||||
| * | ||||
| * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | ||||
| * are met: | ||||
| *   - Redistributions of source code must retain the above copyright | ||||
| *     notice, this list of conditions and the following disclaimer. | ||||
| *   - Redistributions in binary form must reproduce the above copyright | ||||
| *     notice, this list of conditions and the following disclaimer in | ||||
| *     the documentation and/or other materials provided with the | ||||
| *     distribution. | ||||
| *   - Neither the name of Arm LIMITED nor the names of its contributors | ||||
| *     may be used to endorse or promote products derived from this | ||||
| *     software without specific prior written permission. | ||||
| * | ||||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||||
| * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||||
| * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||||
| * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||||
| * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||||
| * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||
| * POSSIBILITY OF SUCH DAMAGE. | ||||
| * -------------------------------------------------------------------- */ | ||||
|  | ||||
| /** | ||||
|  * @ingroup groupExamples | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * @defgroup CNNExample Convolutional Neural Network Example | ||||
|  * | ||||
|  * \par Description: | ||||
|  * \par | ||||
|  * Demonstrates a convolutional neural network (CNN) example with the use of convolution, | ||||
|  * ReLU activation, pooling and fully-connected functions. | ||||
|  * | ||||
|  * \par Model definition: | ||||
|  * \par | ||||
|  * The CNN used in this example is based on CIFAR-10 example from Caffe [1].  | ||||
|  * The neural network consists | ||||
|  * of 3 convolution layers interspersed by ReLU activation and max pooling layers, followed by a  | ||||
|  * fully-connected layer at the end. The input to the network is a 32x32 pixel color image, which will  | ||||
|  * be classified into one of the 10 output classes.  | ||||
|  * This example model implementation needs 32.3 KB to store weights, 40 KB for activations and  | ||||
|  * 3.1 KB for storing the \c im2col data. | ||||
|  * | ||||
|  * \image html CIFAR10_CNN.gif "Neural Network model definition" | ||||
|  * | ||||
|  * \par Variables Description: | ||||
|  * \par | ||||
|  * \li \c conv1_wt, \c conv2_wt, \c conv3_wt are convolution layer weight matrices | ||||
|  * \li \c conv1_bias, \c conv2_bias, \c conv3_bias are convolution layer bias arrays | ||||
|  * \li \c ip1_wt, ip1_bias point to fully-connected layer weights and biases | ||||
|  * \li \c input_data points to the input image data | ||||
|  * \li \c output_data points to the classification output | ||||
|  * \li \c col_buffer is a buffer to store the \c im2col output | ||||
|  * \li \c scratch_buffer is used to store the activation data (intermediate layer outputs) | ||||
|  * | ||||
|  * \par CMSIS DSP Software Library Functions Used: | ||||
|  * \par | ||||
|  * - arm_convolve_HWC_q7_RGB() | ||||
|  * - arm_convolve_HWC_q7_fast() | ||||
|  * - arm_relu_q7() | ||||
|  * - arm_maxpool_q7_HWC() | ||||
|  * - arm_avepool_q7_HWC() | ||||
|  * - arm_fully_connected_q7_opt() | ||||
|  * - arm_fully_connected_q7() | ||||
|  * | ||||
|  * <b> Refer  </b> | ||||
|  * \link arm_nnexamples_cifar10.cpp \endlink | ||||
|  * | ||||
|  * \par [1] https://github.com/BVLC/caffe | ||||
|  */ | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <stdio.h> | ||||
| #include "arm_math.h" | ||||
| #include "arm_nnexamples_cifar10_parameter.h" | ||||
| #include "arm_nnexamples_cifar10_weights.h" | ||||
|  | ||||
| #include "arm_nnfunctions.h" | ||||
| #include "arm_nnexamples_cifar10_inputs.h" | ||||
|  | ||||
| #ifdef _RTE_ | ||||
| #include "RTE_Components.h" | ||||
| #ifdef RTE_Compiler_EventRecorder | ||||
| #include "EventRecorder.h" | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| // include the input and weights | ||||
|  | ||||
| static q7_t conv1_wt[CONV1_IM_CH * CONV1_KER_DIM * CONV1_KER_DIM * CONV1_OUT_CH] = CONV1_WT; | ||||
| static q7_t conv1_bias[CONV1_OUT_CH] = CONV1_BIAS; | ||||
|  | ||||
| static q7_t conv2_wt[CONV2_IM_CH * CONV2_KER_DIM * CONV2_KER_DIM * CONV2_OUT_CH] = CONV2_WT; | ||||
| static q7_t conv2_bias[CONV2_OUT_CH] = CONV2_BIAS; | ||||
|  | ||||
| static q7_t conv3_wt[CONV3_IM_CH * CONV3_KER_DIM * CONV3_KER_DIM * CONV3_OUT_CH] = CONV3_WT; | ||||
| static q7_t conv3_bias[CONV3_OUT_CH] = CONV3_BIAS; | ||||
|  | ||||
| static q7_t ip1_wt[IP1_DIM * IP1_OUT] = IP1_WT; | ||||
| static q7_t ip1_bias[IP1_OUT] = IP1_BIAS; | ||||
|  | ||||
| /* Here the image_data should be the raw uint8 type RGB image in [RGB, RGB, RGB ... RGB] format */ | ||||
| uint8_t   image_data[CONV1_IM_CH * CONV1_IM_DIM * CONV1_IM_DIM] = IMG_DATA; | ||||
| q7_t      output_data[IP1_OUT]; | ||||
|  | ||||
| //vector buffer: max(im2col buffer,average pool buffer, fully connected buffer) | ||||
| q7_t      col_buffer[2 * 5 * 5 * 32 * 2]; | ||||
|  | ||||
| q7_t      scratch_buffer[32 * 32 * 10 * 4]; | ||||
|  | ||||
| int main() | ||||
| { | ||||
|   #ifdef RTE_Compiler_EventRecorder | ||||
|   EventRecorderInitialize (EventRecordAll, 1);  // initialize and start Event Recorder | ||||
|   #endif | ||||
|  | ||||
|   printf("start execution\n"); | ||||
|   /* start the execution */ | ||||
|  | ||||
|   q7_t     *img_buffer1 = scratch_buffer; | ||||
|   q7_t     *img_buffer2 = img_buffer1 + 32 * 32 * 32; | ||||
|  | ||||
|   /* input pre-processing */ | ||||
|   int mean_data[3] = INPUT_MEAN_SHIFT; | ||||
|   unsigned int scale_data[3] = INPUT_RIGHT_SHIFT; | ||||
|   for (int i=0;i<32*32*3; i+=3) { | ||||
|     img_buffer2[i] =   (q7_t)__SSAT( ((((int)image_data[i]   - mean_data[0])<<7) + (0x1<<(scale_data[0]-1))) | ||||
|                              >> scale_data[0], 8); | ||||
|     img_buffer2[i+1] = (q7_t)__SSAT( ((((int)image_data[i+1] - mean_data[1])<<7) + (0x1<<(scale_data[1]-1))) | ||||
|                              >> scale_data[1], 8); | ||||
|     img_buffer2[i+2] = (q7_t)__SSAT( ((((int)image_data[i+2] - mean_data[2])<<7) + (0x1<<(scale_data[2]-1))) | ||||
|                              >> scale_data[2], 8); | ||||
|   } | ||||
|    | ||||
|   // conv1 img_buffer2 -> img_buffer1 | ||||
|   arm_convolve_HWC_q7_RGB(img_buffer2, CONV1_IM_DIM, CONV1_IM_CH, conv1_wt, CONV1_OUT_CH, CONV1_KER_DIM, CONV1_PADDING, | ||||
|                           CONV1_STRIDE, conv1_bias, CONV1_BIAS_LSHIFT, CONV1_OUT_RSHIFT, img_buffer1, CONV1_OUT_DIM, | ||||
|                           (q15_t *) col_buffer, NULL); | ||||
|  | ||||
|   arm_relu_q7(img_buffer1, CONV1_OUT_DIM * CONV1_OUT_DIM * CONV1_OUT_CH); | ||||
|  | ||||
|   // pool1 img_buffer1 -> img_buffer2 | ||||
|   arm_maxpool_q7_HWC(img_buffer1, CONV1_OUT_DIM, CONV1_OUT_CH, POOL1_KER_DIM, | ||||
|                      POOL1_PADDING, POOL1_STRIDE, POOL1_OUT_DIM, NULL, img_buffer2); | ||||
|  | ||||
|   // conv2 img_buffer2 -> img_buffer1 | ||||
|   arm_convolve_HWC_q7_fast(img_buffer2, CONV2_IM_DIM, CONV2_IM_CH, conv2_wt, CONV2_OUT_CH, CONV2_KER_DIM, | ||||
|                            CONV2_PADDING, CONV2_STRIDE, conv2_bias, CONV2_BIAS_LSHIFT, CONV2_OUT_RSHIFT, img_buffer1, | ||||
|                            CONV2_OUT_DIM, (q15_t *) col_buffer, NULL); | ||||
|  | ||||
|   arm_relu_q7(img_buffer1, CONV2_OUT_DIM * CONV2_OUT_DIM * CONV2_OUT_CH); | ||||
|  | ||||
|   // pool2 img_buffer1 -> img_buffer2 | ||||
|   arm_maxpool_q7_HWC(img_buffer1, CONV2_OUT_DIM, CONV2_OUT_CH, POOL2_KER_DIM, | ||||
|                      POOL2_PADDING, POOL2_STRIDE, POOL2_OUT_DIM, col_buffer, img_buffer2); | ||||
|  | ||||
| // conv3 img_buffer2 -> img_buffer1 | ||||
|   arm_convolve_HWC_q7_fast(img_buffer2, CONV3_IM_DIM, CONV3_IM_CH, conv3_wt, CONV3_OUT_CH, CONV3_KER_DIM, | ||||
|                            CONV3_PADDING, CONV3_STRIDE, conv3_bias, CONV3_BIAS_LSHIFT, CONV3_OUT_RSHIFT, img_buffer1, | ||||
|                            CONV3_OUT_DIM, (q15_t *) col_buffer, NULL); | ||||
|  | ||||
|   arm_relu_q7(img_buffer1, CONV3_OUT_DIM * CONV3_OUT_DIM * CONV3_OUT_CH); | ||||
|  | ||||
|   // pool3 img_buffer-> img_buffer2 | ||||
|   arm_maxpool_q7_HWC(img_buffer1, CONV3_OUT_DIM, CONV3_OUT_CH, POOL3_KER_DIM, | ||||
|                      POOL3_PADDING, POOL3_STRIDE, POOL3_OUT_DIM, col_buffer, img_buffer2); | ||||
|  | ||||
|   arm_fully_connected_q7_opt(img_buffer2, ip1_wt, IP1_DIM, IP1_OUT, IP1_BIAS_LSHIFT, IP1_OUT_RSHIFT, ip1_bias, | ||||
|                              output_data, (q15_t *) img_buffer1); | ||||
|  | ||||
|   arm_softmax_q7(output_data, 10, output_data); | ||||
|  | ||||
|   for (int i = 0; i < 10; i++) | ||||
|   { | ||||
|       printf("%d: %d\n", i, output_data[i]); | ||||
|   } | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -0,0 +1,43 @@ | ||||
| #define CONV1_IM_DIM 32 | ||||
| #define CONV1_IM_CH 3 | ||||
| #define CONV1_KER_DIM 5 | ||||
| #define CONV1_PADDING 2 | ||||
| #define CONV1_STRIDE 1 | ||||
| #define CONV1_OUT_CH 32 | ||||
| #define CONV1_OUT_DIM 32 | ||||
|  | ||||
| #define POOL1_KER_DIM 3 | ||||
| #define POOL1_STRIDE 2 | ||||
| #define POOL1_PADDING 0 | ||||
| #define POOL1_OUT_DIM 16 | ||||
|  | ||||
| #define CONV2_IM_DIM 16 | ||||
| #define CONV2_IM_CH 32 | ||||
| #define CONV2_KER_DIM 5 | ||||
| #define CONV2_PADDING 2 | ||||
| #define CONV2_STRIDE 1 | ||||
| #define CONV2_OUT_CH 16 | ||||
| #define CONV2_OUT_DIM 16 | ||||
|  | ||||
| #define POOL2_KER_DIM 3 | ||||
| #define POOL2_STRIDE 2 | ||||
| #define POOL2_PADDING 0 | ||||
| #define POOL2_OUT_DIM 8 | ||||
|  | ||||
| #define CONV3_IM_DIM 8 | ||||
| #define CONV3_IM_CH 16 | ||||
| #define CONV3_KER_DIM 5 | ||||
| #define CONV3_PADDING 2 | ||||
| #define CONV3_STRIDE 1 | ||||
| #define CONV3_OUT_CH 32 | ||||
| #define CONV3_OUT_DIM 8 | ||||
|  | ||||
| #define POOL3_KER_DIM 3 | ||||
| #define POOL3_STRIDE 2 | ||||
| #define POOL3_PADDING 0 | ||||
| #define POOL3_OUT_DIM 4 | ||||
|  | ||||
| #define IP1_DIM 4*4*32 | ||||
| #define IP1_IM_DIM 4 | ||||
| #define IP1_IM_CH 32 | ||||
| #define IP1_OUT 10 | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -0,0 +1,4 @@ | ||||
| CMSIS NN Lib example arm_nnexample_cifar10 for | ||||
|   Cortex-M4 and Cortex-M7. | ||||
|  | ||||
| The example is configured for uVision Simulator. | ||||
| @@ -0,0 +1,44 @@ | ||||
| /*------------------------------------------------------------------------------ | ||||
|  * MDK - Component ::Event Recorder | ||||
|  * Copyright (c) 2016 ARM Germany GmbH. All rights reserved. | ||||
|  *------------------------------------------------------------------------------ | ||||
|  * Name:    EventRecorderConf.h | ||||
|  * Purpose: Event Recorder Configuration | ||||
|  * Rev.:    V1.0.0 | ||||
|  *----------------------------------------------------------------------------*/ | ||||
|  | ||||
| //-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- | ||||
|  | ||||
| // <h>Event Recorder | ||||
|  | ||||
| //   <o>Number of Records | ||||
| //     <8=>8 <16=>16 <32=>32 <64=>64 <128=>128 <256=>256 <512=>512 <1024=>1024 | ||||
| //     <2048=>2048 <4096=>4096 <8192=>8192 <16384=>16384 <32768=>32768 | ||||
| //     <65536=>65536 <131072=>131072 <262144=>262144 <524288=>524288 | ||||
| //     <1048576=>1048576 | ||||
| //   <i>Configure size of Event Record Buffer (each record is 16 bytes) | ||||
| //   <i>Must be 2^n (min=8, max=1048576) | ||||
| #define EVENT_RECORD_COUNT      64U | ||||
|  | ||||
| //   <o>Time Stamp Source | ||||
| //      <0=> DWT Cycle Counter  <1=> SysTick | ||||
| //      <3=> User Timer (Normal Reset)  <4=> User Timer (Power-On Reset) | ||||
| //   <i>Selects source for 32-bit time stamp | ||||
| #define EVENT_TIMESTAMP_SOURCE  1 | ||||
|  | ||||
| //   <h>SysTick Configuration | ||||
| //   <i>Configure values when Time Stamp Source is set to SysTick | ||||
|  | ||||
| //     <o>SysTick Input Clock Frequency [Hz] <1-1000000000> | ||||
| //     <i>Defines SysTick input clock (typical identical with processor clock) | ||||
| #define SYSTICK_CLOCK           100000000U | ||||
|  | ||||
| //     <o>SysTick Interrupt Period [us] <1-1000000000> | ||||
| //     <i>Defines time period of the SysTick timer interrupt | ||||
| #define SYSTICK_PERIOD_US       1000U | ||||
|  | ||||
| //   </h> | ||||
|  | ||||
| // </h> | ||||
|  | ||||
| //------------- <<< end of configuration section >>> --------------------------- | ||||
| @@ -0,0 +1,24 @@ | ||||
|  | ||||
| /* | ||||
|  * Auto generated Run-Time-Environment Component Configuration File | ||||
|  *      *** Do not modify ! *** | ||||
|  * | ||||
|  * Project: 'arm_nnexamples_gru'  | ||||
|  * Target:  'ARMCM0'  | ||||
|  */ | ||||
|  | ||||
| #ifndef RTE_COMPONENTS_H | ||||
| #define RTE_COMPONENTS_H | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Define the Device Header File:  | ||||
|  */ | ||||
| #define CMSIS_device_header "ARMCM0.h" | ||||
|  | ||||
| #define RTE_Compiler_EventRecorder | ||||
|           #define RTE_Compiler_EventRecorder_DAP | ||||
| #define RTE_Compiler_IO_STDOUT          /* Compiler I/O: STDOUT */ | ||||
|           #define RTE_Compiler_IO_STDOUT_EVR      /* Compiler I/O: STDOUT EVR */ | ||||
|  | ||||
| #endif /* RTE_COMPONENTS_H */ | ||||
| @@ -0,0 +1,22 @@ | ||||
|  | ||||
| /* | ||||
|  * Auto generated Run-Time-Environment Component Configuration File | ||||
|  *      *** Do not modify ! *** | ||||
|  * | ||||
|  * Project: 'arm_nnexamples_gru'  | ||||
|  * Target:  'ARMCM3'  | ||||
|  */ | ||||
|  | ||||
| #ifndef RTE_COMPONENTS_H | ||||
| #define RTE_COMPONENTS_H | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Define the Device Header File:  | ||||
|  */ | ||||
| #define CMSIS_device_header "ARMCM3.h" | ||||
|  | ||||
| #define RTE_Compiler_IO_STDOUT          /* Compiler I/O: STDOUT */ | ||||
|           #define RTE_Compiler_IO_STDOUT_ITM      /* Compiler I/O: STDOUT ITM */ | ||||
|  | ||||
| #endif /* RTE_COMPONENTS_H */ | ||||
| @@ -0,0 +1,22 @@ | ||||
|  | ||||
| /* | ||||
|  * Auto generated Run-Time-Environment Component Configuration File | ||||
|  *      *** Do not modify ! *** | ||||
|  * | ||||
|  * Project: 'arm_nnexamples_gru'  | ||||
|  * Target:  'ARMCM4_FP'  | ||||
|  */ | ||||
|  | ||||
| #ifndef RTE_COMPONENTS_H | ||||
| #define RTE_COMPONENTS_H | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Define the Device Header File:  | ||||
|  */ | ||||
| #define CMSIS_device_header "ARMCM4_FP.h" | ||||
|  | ||||
| #define RTE_Compiler_IO_STDOUT          /* Compiler I/O: STDOUT */ | ||||
|           #define RTE_Compiler_IO_STDOUT_ITM      /* Compiler I/O: STDOUT ITM */ | ||||
|  | ||||
| #endif /* RTE_COMPONENTS_H */ | ||||
| @@ -0,0 +1,22 @@ | ||||
|  | ||||
| /* | ||||
|  * Auto generated Run-Time-Environment Component Configuration File | ||||
|  *      *** Do not modify ! *** | ||||
|  * | ||||
|  * Project: 'arm_nnexamples_gru'  | ||||
|  * Target:  'ARMCM7_SP'  | ||||
|  */ | ||||
|  | ||||
| #ifndef RTE_COMPONENTS_H | ||||
| #define RTE_COMPONENTS_H | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Define the Device Header File:  | ||||
|  */ | ||||
| #define CMSIS_device_header "ARMCM7_SP.h" | ||||
|  | ||||
| #define RTE_Compiler_IO_STDOUT          /* Compiler I/O: STDOUT */ | ||||
|           #define RTE_Compiler_IO_STDOUT_ITM      /* Compiler I/O: STDOUT ITM */ | ||||
|  | ||||
| #endif /* RTE_COMPONENTS_H */ | ||||
| @@ -0,0 +1,221 @@ | ||||
| /* ---------------------------------------------------------------------- | ||||
| * Copyright (C) 2010-2018 Arm Limited. All rights reserved. | ||||
| * | ||||
| * | ||||
| * Project:       CMSIS NN Library | ||||
| * Title:         arm_nnexamples_gru.cpp | ||||
| * | ||||
| * Description:   Gated Recurrent Unit Example | ||||
| * | ||||
| * Target Processor: Cortex-M4/Cortex-M7 | ||||
| * | ||||
| * Redistribution and use in source and binary forms, with or without | ||||
| * modification, are permitted provided that the following conditions | ||||
| * are met: | ||||
| *   - Redistributions of source code must retain the above copyright | ||||
| *     notice, this list of conditions and the following disclaimer. | ||||
| *   - Redistributions in binary form must reproduce the above copyright | ||||
| *     notice, this list of conditions and the following disclaimer in | ||||
| *     the documentation and/or other materials provided with the | ||||
| *     distribution. | ||||
| *   - Neither the name of Arm LIMITED nor the names of its contributors | ||||
| *     may be used to endorse or promote products derived from this | ||||
| *     software without specific prior written permission. | ||||
| * | ||||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||||
| * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||||
| * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||||
| * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||||
| * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||||
| * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||
| * POSSIBILITY OF SUCH DAMAGE. | ||||
| * -------------------------------------------------------------------- */ | ||||
|  | ||||
| /** | ||||
|  * @ingroup groupExamples | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * @defgroup GRUExample Gated Recurrent Unit Example | ||||
|  * | ||||
|  * \par Description: | ||||
|  * \par | ||||
|  * Demonstrates a gated recurrent unit (GRU) example with the use of fully-connected, | ||||
|  * Tanh/Sigmoid activation functions. | ||||
|  * | ||||
|  * \par Model definition: | ||||
|  * \par | ||||
|  * GRU is a type of recurrent neural network (RNN). It contains two sigmoid gates and one hidden | ||||
|  * state.  | ||||
|  * \par | ||||
|  * The computation can be summarized as: | ||||
|  * <pre>z[t] = sigmoid( W_z ⋅ {h[t-1],x[t]} ) | ||||
|  * r[t] = sigmoid( W_r ⋅ {h[t-1],x[t]} )  | ||||
|  * n[t] = tanh( W_n ⋅ [r[t] × {h[t-1], x[t]} )  | ||||
|  * h[t] = (1 - z[t]) × h[t-1] + z[t] × n[t] </pre> | ||||
|  * \image html GRU.gif "Gate Recurrent Unit Diagram" | ||||
|  * | ||||
|  * \par Variables Description: | ||||
|  * \par | ||||
|  * \li \c update_gate_weights, \c reset_gate_weights, \c hidden_state_weights are weights corresponding to update gate (W_z), reset gate (W_r), and hidden state (W_n). | ||||
|  * \li \c update_gate_bias, \c reset_gate_bias, \c hidden_state_bias are layer bias arrays | ||||
|  * \li \c test_input1, \c test_input2, \c test_history are the inputs and initial history | ||||
|  * | ||||
|  * \par | ||||
|  * The buffer is allocated as: | ||||
|  * \par | ||||
|  * | reset | input | history | update | hidden_state | | ||||
|  * \par | ||||
|  * In this way, the concatination is automatically done since (reset, input) and (input, history) | ||||
|  * are physically concatinated in memory. | ||||
|  * \par | ||||
|  *  The ordering of the weight matrix should be adjusted accordingly. | ||||
|  * | ||||
|   * | ||||
|  *  | ||||
|  * \par CMSIS DSP Software Library Functions Used: | ||||
|  * \par | ||||
|  * - arm_fully_connected_mat_q7_vec_q15_opt() | ||||
|  * - arm_nn_activations_direct_q15() | ||||
|  * - arm_mult_q15() | ||||
|  * - arm_offset_q15() | ||||
|  * - arm_sub_q15() | ||||
|  * - arm_copy_q15() | ||||
|  * | ||||
|  * <b> Refer  </b> | ||||
|  * \link arm_nnexamples_gru.cpp \endlink | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <math.h> | ||||
| #include "arm_nnexamples_gru_test_data.h" | ||||
| #include "arm_math.h" | ||||
| #include "arm_nnfunctions.h" | ||||
|  | ||||
| #ifdef _RTE_ | ||||
| #include "RTE_Components.h" | ||||
| #ifdef RTE_Compiler_EventRecorder | ||||
| #include "EventRecorder.h" | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| #define DIM_HISTORY 32 | ||||
| #define DIM_INPUT 32 | ||||
| #define DIM_VEC 64 | ||||
|  | ||||
| #define USE_X4 | ||||
|  | ||||
| #ifndef USE_X4 | ||||
| static q7_t update_gate_weights[DIM_VEC * DIM_HISTORY] = UPDATE_GATE_WEIGHT_X2; | ||||
| static q7_t reset_gate_weights[DIM_VEC * DIM_HISTORY] = RESET_GATE_WEIGHT_X2; | ||||
| static q7_t hidden_state_weights[DIM_VEC * DIM_HISTORY] = HIDDEN_STATE_WEIGHT_X2; | ||||
| #else | ||||
| static q7_t update_gate_weights[DIM_VEC * DIM_HISTORY] = UPDATE_GATE_WEIGHT_X4; | ||||
| static q7_t reset_gate_weights[DIM_VEC * DIM_HISTORY] = RESET_GATE_WEIGHT_X4; | ||||
| static q7_t hidden_state_weights[DIM_VEC * DIM_HISTORY] = HIDDEN_STATE_WEIGHT_X4; | ||||
| #endif | ||||
|  | ||||
| static q7_t update_gate_bias[DIM_HISTORY] = UPDATE_GATE_BIAS; | ||||
| static q7_t reset_gate_bias[DIM_HISTORY] = RESET_GATE_BIAS; | ||||
| static q7_t hidden_state_bias[DIM_HISTORY] = HIDDEN_STATE_BIAS; | ||||
|  | ||||
| static q15_t test_input1[DIM_INPUT] = INPUT_DATA1; | ||||
| static q15_t test_input2[DIM_INPUT] = INPUT_DATA2; | ||||
| static q15_t test_history[DIM_HISTORY] = HISTORY_DATA; | ||||
|  | ||||
| q15_t     scratch_buffer[DIM_HISTORY * 4 + DIM_INPUT]; | ||||
|  | ||||
| void gru_example(q15_t * scratch_input, uint16_t input_size, uint16_t history_size, | ||||
|                  q7_t * weights_update, q7_t * weights_reset, q7_t * weights_hidden_state, | ||||
|                  q7_t * bias_update, q7_t * bias_reset, q7_t * bias_hidden_state) | ||||
| { | ||||
|   q15_t    *reset = scratch_input; | ||||
|   q15_t    *input = scratch_input + history_size; | ||||
|   q15_t    *history = scratch_input + history_size + input_size; | ||||
|   q15_t    *update = scratch_input + 2 * history_size + input_size; | ||||
|   q15_t    *hidden_state = scratch_input + 3 * history_size + input_size; | ||||
|  | ||||
|   // reset gate calculation | ||||
|   // the range of the output can be adjusted with bias_shift and output_shift | ||||
| #ifndef USE_X4 | ||||
|   arm_fully_connected_mat_q7_vec_q15(input, weights_reset, input_size + history_size, history_size, 0, 15, bias_reset, | ||||
|                                      reset, NULL); | ||||
| #else | ||||
|   arm_fully_connected_mat_q7_vec_q15_opt(input, weights_reset, input_size + history_size, history_size, 0, 15, | ||||
|                                          bias_reset, reset, NULL); | ||||
| #endif | ||||
|   // sigmoid function, the size of the integer bit-width should be consistent with out_shift | ||||
|   arm_nn_activations_direct_q15(reset, history_size, 0, ARM_SIGMOID); | ||||
|   arm_mult_q15(history, reset, reset, history_size); | ||||
|  | ||||
|   // update gate calculation | ||||
|   // the range of the output can be adjusted with bias_shift and output_shift | ||||
| #ifndef USE_X4 | ||||
|   arm_fully_connected_mat_q7_vec_q15(input, weights_update, input_size + history_size, history_size, 0, 15, | ||||
|                                      bias_update, update, NULL); | ||||
| #else | ||||
|   arm_fully_connected_mat_q7_vec_q15_opt(input, weights_update, input_size + history_size, history_size, 0, 15, | ||||
|                                          bias_update, update, NULL); | ||||
| #endif | ||||
|  | ||||
|   // sigmoid function, the size of the integer bit-width should be consistent with out_shift | ||||
|   arm_nn_activations_direct_q15(update, history_size, 0, ARM_SIGMOID); | ||||
|  | ||||
|   // hidden state calculation | ||||
| #ifndef USE_X4 | ||||
|   arm_fully_connected_mat_q7_vec_q15(reset, weights_hidden_state, input_size + history_size, history_size, 0, 15, | ||||
|                                      bias_hidden_state, hidden_state, NULL); | ||||
| #else | ||||
|   arm_fully_connected_mat_q7_vec_q15_opt(reset, weights_hidden_state, input_size + history_size, history_size, 0, 15, | ||||
|                                          bias_hidden_state, hidden_state, NULL); | ||||
| #endif | ||||
|  | ||||
|   // tanh function, the size of the integer bit-width should be consistent with out_shift | ||||
|   arm_nn_activations_direct_q15(hidden_state, history_size, 0, ARM_TANH); | ||||
|   arm_mult_q15(update, hidden_state, hidden_state, history_size); | ||||
|  | ||||
|   // we calculate z - 1 here | ||||
|   // so final addition becomes substraction | ||||
|   arm_offset_q15(update, 0x8000, update, history_size); | ||||
|   // multiply history | ||||
|   arm_mult_q15(history, update, update, history_size); | ||||
|   // calculate history_out | ||||
|   arm_sub_q15(hidden_state, update, history, history_size); | ||||
|  | ||||
|   return; | ||||
| } | ||||
|  | ||||
| int main() | ||||
| { | ||||
|   #ifdef RTE_Compiler_EventRecorder | ||||
|   EventRecorderInitialize (EventRecordAll, 1);  // initialize and start Event Recorder | ||||
|   #endif | ||||
|  | ||||
|   printf("Start GRU execution\n"); | ||||
|   int       input_size = DIM_INPUT; | ||||
|   int       history_size = DIM_HISTORY; | ||||
|  | ||||
|   // copy over the input data  | ||||
|   arm_copy_q15(test_input1, scratch_buffer + history_size, input_size); | ||||
|   arm_copy_q15(test_history, scratch_buffer + history_size + input_size, history_size); | ||||
|  | ||||
|   gru_example(scratch_buffer, input_size, history_size, | ||||
|               update_gate_weights, reset_gate_weights, hidden_state_weights, | ||||
|               update_gate_bias, reset_gate_bias, hidden_state_bias); | ||||
|   printf("Complete first iteration on GRU\n"); | ||||
|  | ||||
|   arm_copy_q15(test_input2, scratch_buffer + history_size, input_size); | ||||
|   gru_example(scratch_buffer, input_size, history_size, | ||||
|               update_gate_weights, reset_gate_weights, hidden_state_weights, | ||||
|               update_gate_bias, reset_gate_bias, hidden_state_bias); | ||||
|   printf("Complete second iteration on GRU\n"); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -0,0 +1,4 @@ | ||||
| CMSIS NN Lib example arm_nnexample_gru0 for | ||||
|   Cortex-M4 and Cortex-M7. | ||||
|  | ||||
| The example is configured for uVision Simulator. | ||||
		Reference in New Issue
	
	Block a user