xref: /btstack/port/stm32-f4discovery-usb/Drivers/CMSIS/NN/Include/arm_nnsupportfunctions.h (revision a8f7f3fcbcd51f8d2e92aca076b6a9f812db358c)
1 /*
2  * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Licensed under the Apache License, Version 2.0 (the License); you may
7  * not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 /* ----------------------------------------------------------------------
20  * Project:      CMSIS NN Library
21  * Title:        arm_nnsupportfunctions.h
22  * Description:  Public header file of support functions for CMSIS NN Library
23  *
24  * $Date:        13. July 2018
25  * $Revision:    V.1.0.0
26  *
27  * Target Processor:  Cortex-M cores
28  * -------------------------------------------------------------------- */
29 
30 #ifndef _ARM_NNSUPPORTFUNCTIONS_H_
31 #define _ARM_NNSUPPORTFUNCTIONS_H_
32 
33 #include "arm_math.h"
34 #include "arm_common_tables.h"
35 //#include <cstring>
36 
37 #ifdef __cplusplus
38 extern    "C"
39 {
40 #endif
41 
42 /**
43  * @brief Union for SIMD access of Q31/Q15/Q7 types
44  */
45 union arm_nnword
46 {
47     q31_t     word;
48                /**< Q31 type */
49     q15_t     half_words[2];
50                /**< Q15 type */
51     q7_t      bytes[4];
52                /**< Q7 type */
53 };
54 
55 /**
56  * @brief Struct for specifying activation function types
57  *
58  */
59 typedef enum
60 {
61     ARM_SIGMOID = 0,
62                 /**< Sigmoid activation function */
63     ARM_TANH = 1,
64              /**< Tanh activation function */
65 } arm_nn_activation_type;
66 
67 /**
68  * @defgroup nndata_convert Neural Network Data Conversion Functions
69  *
70  * Perform data type conversion in-between neural network operations
71  *
72  */
73 
74 /**
75  * @brief Converts the elements of the Q7 vector to Q15 vector without left-shift
76  * @param[in]       *pSrc points to the Q7 input vector
77  * @param[out]      *pDst points to the Q15 output vector
78  * @param[in]       blockSize length of the input vector
79  * @return none.
80  *
81  */
82 
83 void      arm_q7_to_q15_no_shift(const q7_t * pSrc, q15_t * pDst, uint32_t blockSize);
84 
85 /**
86  * @brief  Converts the elements of the Q7 vector to reordered Q15 vector without left-shift
87  * @param[in]       *pSrc points to the Q7 input vector
88  * @param[out]      *pDst points to the Q15 output vector
89  * @param[in]       blockSize length of the input vector
90  * @return none.
91  *
92  */
93 
94 void      arm_q7_to_q15_reordered_no_shift(const q7_t * pSrc, q15_t * pDst, uint32_t blockSize);
95 
96 #if defined (ARM_MATH_DSP)
97 
98 /**
99  * @brief read and expand one Q7 word into two Q15 words
100  */
101 
read_and_pad(void * source,q31_t * out1,q31_t * out2)102 __STATIC_FORCEINLINE void *read_and_pad(void *source, q31_t * out1, q31_t * out2)
103 {
104         q31_t     inA = *__SIMD32(source)++;
105         q31_t     inAbuf1 = __SXTB16(__ROR(inA, 8));
106         q31_t     inAbuf2 = __SXTB16(inA);
107 
108 #ifndef ARM_MATH_BIG_ENDIAN
109         *out2 = __PKHTB(inAbuf1, inAbuf2, 16);
110         *out1 = __PKHBT(inAbuf2, inAbuf1, 16);
111 #else
112         *out1 = __PKHTB(inAbuf1, inAbuf2, 16);
113         *out2 = __PKHBT(inAbuf2, inAbuf1, 16);
114 #endif
115 
116         return source;
117 }
118 
119 /**
120  * @brief read and expand one Q7 word into two Q15 words with reordering
121  */
122 
read_and_pad_reordered(void * source,q31_t * out1,q31_t * out2)123 __STATIC_FORCEINLINE void *read_and_pad_reordered(void *source, q31_t * out1, q31_t * out2)
124 {
125         q31_t     inA = *__SIMD32(source)++;
126 #ifndef ARM_MATH_BIG_ENDIAN
127         *out2 = __SXTB16(__ROR(inA, 8));
128         *out1 = __SXTB16(inA);
129 #else
130         *out1 = __SXTB16(__ROR(inA, 8));
131         *out2 = __SXTB16(inA);
132 #endif
133 
134         return source;
135 }
136 #endif
137 
138 /**
139  * @defgroup NNBasicMath Basic Math Functions for Neural Network Computation
140  *
141  * Basic Math Functions for Neural Network Computation
142  *
143  */
144 
145 /**
146  * @brief           Q7 vector multiplication with variable output shifts
147  * @param[in]       *pSrcA        pointer to the first input vector
148  * @param[in]       *pSrcB        pointer to the second input vector
149  * @param[out]      *pDst         pointer to the output vector
150  * @param[in]       out_shift     amount of right-shift for output
151  * @param[in]       blockSize     number of samples in each vector
152  * @return none.
153  *
154  * <b>Scaling and Overflow Behavior:</b>
155  * \par
156  * The function uses saturating arithmetic.
157  * Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
158  */
159 
160 void arm_nn_mult_q15(
161   q15_t * pSrcA,
162   q15_t * pSrcB,
163   q15_t * pDst,
164   const uint16_t out_shift,
165   uint32_t blockSize);
166 
167 /**
168  * @brief           Q7 vector multiplication with variable output shifts
169  * @param[in]       *pSrcA        pointer to the first input vector
170  * @param[in]       *pSrcB        pointer to the second input vector
171  * @param[out]      *pDst         pointer to the output vector
172  * @param[in]       out_shift     amount of right-shift for output
173  * @param[in]       blockSize     number of samples in each vector
174  * @return none.
175  *
176  * <b>Scaling and Overflow Behavior:</b>
177  * \par
178  * The function uses saturating arithmetic.
179  * Results outside of the allowable Q7 range [0x80 0x7F] will be saturated.
180  */
181 
182 void arm_nn_mult_q7(
183   q7_t * pSrcA,
184   q7_t * pSrcB,
185   q7_t * pDst,
186   const uint16_t out_shift,
187   uint32_t blockSize);
188 
189 /**
190  * @brief defition to adding rouding offset
191  */
192 #ifndef ARM_NN_TRUNCATE
193     #define NN_ROUND(out_shift) ( 0x1 << (out_shift - 1) )
194 #else
195     #define NN_ROUND(out_shift) 0
196 #endif
197 
198 #ifdef __cplusplus
199 }
200 #endif
201 
202 #endif
203