arm_nnfunctions.h 111 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184
  1. /*
  2. * Copyright (C) 2010-2020 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. * Project: CMSIS NN Library
  20. * Title: arm_nnfunctions.h
  21. * Description: Public header file for CMSIS NN Library
  22. *
  23. * $Date: April 1, 2020
  24. * $Revision: V.1.2.6
  25. *
  26. * Target Processor: Cortex-M cores
  27. * -------------------------------------------------------------------- */
  28. /**
  29. \mainpage CMSIS NN Software Library
  30. *
  31. * Introduction
  32. * ------------
  33. *
  34. * This user manual describes the CMSIS NN software library,
  35. * a collection of efficient neural network kernels developed to maximize the
  36. * performance and minimize the memory footprint of neural networks on Cortex-M processor cores.
  37. *
  38. * The library is divided into a number of functions each covering a specific category:
  39. * - Convolution Functions
  40. * - Activation Functions
  41. * - Fully-connected Layer Functions
  42. * - Pooling Functions
  43. * - Softmax Functions
  44. * - Basic math Functions
  45. *
  46. * The library has separate functions for operating on different weight and activation data
  47. * types including 8-bit integers (q7_t) and 16-bit integers (q15_t). The descrition of the
  48. * kernels are included in the function description. The implementation details are also
  49. * described in this paper [1].
  50. *
  51. * Function Classification
  52. * --------
  53. * The functions can be classified into two segments
  54. * - Legacy functions supporting ARM's internal symmetric quantization(8 bits).
  55. * - Functions that support TensorFlow Lite framework with symmetric quantization(8 bits).
  56. *
  57. * The legacy functions can be identified with their suffix of _q7 or _q15 and are no new development is done there. The article in [2] describes in detail
  58. * how to run a network using the legacy functions.
  59. *
  60. * The functions supporting TensorFlow Lite framework is identified by the _s8 suffix and can be invoked from TFL micro. The functions are bit exact to
  61. * TensorFlow Lite. Refer to the TensorFlow's documentation in [3] on how to run a TensorFlow Lite model using optimized CMSIS-NN kernels.
  62. *
  63. * Block Diagram
  64. * --------
  65. * \image html CMSIS-NN-OVERVIEW.PNG
  66. *
  67. * Examples
  68. * --------
  69. *
  70. * The library ships with a number of examples which demonstrate how to use the library functions.
  71. *
  72. * Pre-processor Macros
  73. * ------------
  74. *
  75. * Each library project have different pre-processor macros.
  76. *
  77. * - ARM_MATH_DSP:
  78. *
  79. * Define macro ARM_MATH_DSP, If the silicon supports DSP instructions(DSP extension).
  80. *
  81. * - ARM_MATH_MVEI:
  82. *
  83. * Define macro ARM_MATH_MVEI, If the silicon supports M-Profile Vector Extension.
  84. * - ARM_MATH_AUTOVECTORIZE
  85. * Used in conjucture with ARM_MATH_MVEI to let the compiler auto vectorize for the functions that uses inline assembly.
  86. * It does not affect functions that use C or intrinsics.
  87. * - ARM_MATH_BIG_ENDIAN:
  88. *
  89. * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. This is supported only for the legacy functions i.e, functions targetted at
  90. * TensorFlow Lite do not support big endianness. By default library builds for little endian targets.
  91. *
  92. * - ARM_NN_TRUNCATE:
  93. *
  94. * Define macro ARM_NN_TRUNCATE to use floor instead of round-to-the-nearest-int for the computation.
  95. *
  96. * Upcoming Interface Change
  97. * --------
  98. * Starting from the 1.4.0 next release, CMSIS-NN will gradually switch to a new API interface to:
  99. *
  100. * -# have a stable API
  101. * -# avoid passing many variables by value
  102. * -# improve security
  103. * -# improve validation
  104. * -# improve code readability
  105. *
  106. * The upcoming API interface change will be based on "struct" and only affect the TensorFlowLite micro compliant APIs [4] (functions with _s8 suffix)
  107. *
  108. * Below you can find a snapshot of how the new API interface will look like (names can change)
  109. *
  110. * i.e. arm_convolve_1x1_s8_fast
  111. *
  112. * Current API interface | New API interface proposal
  113. * ------------- | -------------
  114. * const q7_t *input | const cmsis_nn_context &ctx
  115. * const uint16_t input_x | const cmsis_nn_conv_params &params
  116. * const uint16_t input_y | const cmsis_nn_dims &input_dims
  117. * const uint16_t input_ch | const q7_t *input_data
  118. * const uint16_t input_batches | const cmsis_nn_dims &filter_dims
  119. * const q7_t *kernel | const q7_t *filter_data
  120. * const uint16_t output_ch | const cmsis_nn_dims &bias_dims
  121. * const uint16_t pad_x | const q31_t *bias_data
  122. * const uint16_t pad_y | const cmsis_nn_dims &output_dims
  123. * const uint16_t stride_x | q7_t *output_data
  124. * const uint16_t stride_y | <br>
  125. * const int32_t *bias | <br>
  126. * q7_t *output | <br>
  127. * const int32_t *output_shift | <br>
  128. * const int32_t *output_mult | <br>
  129. * const int32_t out_offset | <br>
  130. * const int32_t input_offset | <br>
  131. * const int32_t out_activation_min | <br>
  132. * const int32_t out_activation_max | <br>
  133. * const uint16_t output_x | <br>
  134. * const uint16_t output_y | <br>
  135. * q15_t *buffer_a | <br>
  136. *
  137. * Copyright Notice
  138. * ------------
  139. *
  140. * Copyright (C) 2010-2019 Arm Limited. All rights reserved.
  141. *
  142. * [1] CMSIS-NN: Efficient Neural Network Kernels for Arm Cortex-M CPUs https://arxiv.org/abs/1801.06601
  143. *
  144. * [2] Converting a Neural Network for Arm Cortex-M with CMSIS-NN
  145. * https://developer.arm.com/solutions/machine-learning-on-arm/developer-material/how-to-guides/converting-a-neural-network-for-arm-cortex-m-with-cmsis-nn/single-page
  146. * [3] https://www.tensorflow.org/lite/microcontrollers/library
  147. *
  148. * [4] https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/NN#legacy-vs-tfl-micro-compliant-apis
  149. */
  150. /**
  151. * @defgroup groupNN Neural Network Functions
  152. * A collection of functions to perform basic operations for neural network layers. Functions with a _s8 suffix support
  153. * TensorFlow Lite framework.
  154. */
  155. #ifndef _ARM_NNFUNCTIONS_H
  156. #define _ARM_NNFUNCTIONS_H
  157. #include "arm_nnsupportfunctions.h"
  158. #include "arm_nn_tables.h"
  159. #define USE_INTRINSIC
  160. //#define ARM_NN_TRUNCATE /* This config the rounding model to floor or round to the nearest int */
  161. #ifdef __cplusplus
  162. extern "C"
  163. {
  164. #endif
  165. /**
  166. * @defgroup NNConv Convolution Functions
  167. *
  168. * Collection of convolution, depthwise convolution functions and their variants.
  169. *
  170. * The convolution is implemented in 2 steps: im2col and GEMM
  171. *
  172. * im2col is a process of converting each patch of image data into
  173. * a column. After im2col, the convolution is computed as matrix-matrix
  174. * multiplication.
  175. *
  176. * To reduce the memory footprint, the im2col is performed partially.
  177. * Each iteration, only a few column (i.e., patches) are generated and
  178. * computed with GEMM kernels similar to CMSIS-DSP arm_mat_mult functions.
  179. *
  180. */
  181. /**
  182. * @brief Basic s8 convolution function
  183. * @param[in] input pointer to input tensor. Range: int8, format: [N,H,W,in_ch]
  184. * @param[in] input_x input tensor width
  185. * @param[in] input_y input tensor height
  186. * @param[in] input_ch number of input tensor channels
  187. * @param[in] input_batches number of input batches
  188. * @param[in] kernel pointer to kernel weights. Range: int8, format: [out_ch, H, W, in_ch]
  189. * @param[in] output_ch number of filters, i.e., output tensor channels
  190. * @param[in] kernel_x filter/kernel width
  191. * @param[in] kernel_y filter/kernel height
  192. * @param[in] pad_x padding along width
  193. * @param[in] pad_y padding along height
  194. * @param[in] stride_x convolution stride x
  195. * @param[in] stride_y convolution stride y
  196. * @param[in] bias pointer to per output channel bias. Range: int32
  197. * @param[in,out] output pointer to output tensor. format: [H, W, out_ch]
  198. * @param[in] output_shift pointer to per output channel requantization shift parameter.
  199. * @param[in] output_mult pointer to per output channel requantization multiplier parameter.
  200. * @param[in] out_offset output tensor offset. Range: int8
  201. * @param[in] input_offset input tensor offset. Range: int8
  202. * @param[in] output_activation_min Minimum value to clamp the output to. Range: int8
  203. * @param[in] output_activation_max Minimum value to clamp the output to. Range: int8
  204. * @param[in] output_x output tensor width
  205. * @param[in] output_y output tensor height
  206. * @param[in] buffer_a pointer to buffer space used for input optimization(partial im2col) and is necessary
  207. * when ARM_MATH_DSP is defined.
  208. * Required space: (2 * input_ch * kernel_x * kernel_y) * sizeof(q15_t) bytes
  209. * Use arm_convolve_s8_get_buffer_size() to get the size.
  210. * @return The function returns <code>ARM_MATH_SUCCESS</code>
  211. *
  212. * @details
  213. * 1. Supported framework: TensorFlow Lite micro
  214. * 2. q7 is used as data type eventhough it is s8 data. It is done so to be consistent with existing APIs.
  215. * 3. Additional memory is required for optimization. Refer to argument 'buffer_a' for details.
  216. *
  217. */
  218. arm_status arm_convolve_s8(const q7_t *input,
  219. const uint16_t input_x,
  220. const uint16_t input_y,
  221. const uint16_t input_ch,
  222. const uint16_t input_batches,
  223. const q7_t *kernel,
  224. const uint16_t output_ch,
  225. const uint16_t kernel_x,
  226. const uint16_t kernel_y,
  227. const uint16_t pad_x,
  228. const uint16_t pad_y,
  229. const uint16_t stride_x,
  230. const uint16_t stride_y,
  231. const int32_t *bias,
  232. q7_t *output,
  233. const int32_t *output_shift,
  234. const int32_t *output_mult,
  235. const int32_t out_offset,
  236. const int32_t input_offset,
  237. const int32_t output_activation_min,
  238. const int32_t output_activation_max,
  239. const uint16_t output_x,
  240. const uint16_t output_y,
  241. q15_t *buffer_a);
  242. /**
  243. * @brief Get the required buffer size for s8 convolution function
  244. * @param[in] input_ch number of input tensor channels
  245. * @param[in] kernel_x filter/kernel width
  246. * @param[in] kernel_y filter/kernel height
  247. * @return The function returns required buffer size
  248. *
  249. */
  250. int32_t arm_convolve_s8_get_buffer_size(const uint16_t input_ch,
  251. const uint16_t kernel_x,
  252. const uint16_t kernel_y);
  253. /**
  254. * @brief Basic Q7 convolution function
  255. * @param[in] Im_in pointer to input tensor
  256. * @param[in] dim_im_in input tensor dimension
  257. * @param[in] ch_im_in number of input tensor channels
  258. * @param[in] wt pointer to kernel weights
  259. * @param[in] ch_im_out number of filters, i.e., output tensor channels
  260. * @param[in] dim_kernel filter kernel size
  261. * @param[in] padding padding sizes
  262. * @param[in] stride convolution stride
  263. * @param[in] bias pointer to bias
  264. * @param[in] bias_shift amount of left-shift for bias
  265. * @param[in] out_shift amount of right-shift for output
  266. * @param[in,out] Im_out pointer to output tensor
  267. * @param[in] dim_im_out output tensor dimension
  268. * @param[in,out] bufferA pointer to buffer space for input
  269. * @param[in,out] bufferB pointer to buffer space for output
  270. * @return The function returns <code>ARM_MATH_SUCCESS</code>
  271. *
  272. */
  273. arm_status arm_convolve_HWC_q7_basic(const q7_t * Im_in,
  274. const uint16_t dim_im_in,
  275. const uint16_t ch_im_in,
  276. const q7_t * wt,
  277. const uint16_t ch_im_out,
  278. const uint16_t dim_kernel,
  279. const uint16_t padding,
  280. const uint16_t stride,
  281. const q7_t * bias,
  282. const uint16_t bias_shift,
  283. const uint16_t out_shift,
  284. q7_t * Im_out,
  285. const uint16_t dim_im_out,
  286. q15_t * bufferA,
  287. q7_t * bufferB);
  288. /**
  289. * @brief Basic Q7 convolution function (non-square shape)
  290. * @param[in] Im_in pointer to input tensor
  291. * @param[in] dim_im_in_x input tensor dimension x
  292. * @param[in] dim_im_in_y input tensor dimension y
  293. * @param[in] ch_im_in number of input tensor channels
  294. * @param[in] wt pointer to kernel weights
  295. * @param[in] ch_im_out number of filters, i.e., output tensor channels
  296. * @param[in] dim_kernel_x filter kernel size x
  297. * @param[in] dim_kernel_y filter kernel size y
  298. * @param[in] padding_x padding size x
  299. * @param[in] padding_y padding size y
  300. * @param[in] stride_x convolution stride x
  301. * @param[in] stride_y convolution stride y
  302. * @param[in] bias pointer to bias
  303. * @param[in] bias_shift amount of left-shift for bias
  304. * @param[in] out_shift amount of right-shift for output
  305. * @param[in,out] Im_out pointer to output tensor
  306. * @param[in] dim_im_out_x output tensor dimension x
  307. * @param[in] dim_im_out_y output tensor dimension y
  308. * @param[in,out] bufferA pointer to buffer space for input
  309. * @param[in,out] bufferB pointer to buffer space for output
  310. * @return The function returns <code>ARM_MATH_SUCCESS</code>
  311. */
  312. arm_status arm_convolve_HWC_q7_basic_nonsquare(const q7_t * Im_in,
  313. const uint16_t dim_im_in_x,
  314. const uint16_t dim_im_in_y,
  315. const uint16_t ch_im_in,
  316. const q7_t * wt,
  317. const uint16_t ch_im_out,
  318. const uint16_t dim_kernel_x,
  319. const uint16_t dim_kernel_y,
  320. const uint16_t padding_x,
  321. const uint16_t padding_y,
  322. const uint16_t stride_x,
  323. const uint16_t stride_y,
  324. const q7_t * bias,
  325. const uint16_t bias_shift,
  326. const uint16_t out_shift,
  327. q7_t * Im_out,
  328. const uint16_t dim_im_out_x,
  329. const uint16_t dim_im_out_y,
  330. q15_t * bufferA,
  331. q7_t * bufferB);
  332. /**
  333. * @brief Basic Q15 convolution function
  334. * @param[in] Im_in pointer to input tensor
  335. * @param[in] dim_im_in input tensor dimension
  336. * @param[in] ch_im_in number of input tensor channels
  337. * @param[in] wt pointer to kernel weights
  338. * @param[in] ch_im_out number of filters, i.e., output tensor channels
  339. * @param[in] dim_kernel filter kernel size
  340. * @param[in] padding padding sizes
  341. * @param[in] stride convolution stride
  342. * @param[in] bias pointer to bias
  343. * @param[in] bias_shift amount of left-shift for bias
  344. * @param[in] out_shift amount of right-shift for output
  345. * @param[in,out] Im_out pointer to output tensor
  346. * @param[in] dim_im_out output tensor dimension
  347. * @param[in,out] bufferA pointer to buffer space for input
  348. * @param[in,out] bufferB pointer to buffer space for output
  349. * @return The function returns <code>ARM_MATH_SUCCESS</code>
  350. *
  351. */
  352. arm_status arm_convolve_HWC_q15_basic(const q15_t * Im_in,
  353. const uint16_t dim_im_in,
  354. const uint16_t ch_im_in,
  355. const q15_t * wt,
  356. const uint16_t ch_im_out,
  357. const uint16_t dim_kernel,
  358. const uint16_t padding,
  359. const uint16_t stride,
  360. const q15_t * bias,
  361. const uint16_t bias_shift,
  362. const uint16_t out_shift,
  363. q15_t * Im_out,
  364. const uint16_t dim_im_out,
  365. q15_t * bufferA,
  366. q7_t * bufferB);
  367. /**
  368. * @brief Fast Q7 convolution function
  369. * @param[in] Im_in pointer to input tensor
  370. * @param[in] dim_im_in input tensor dimension
  371. * @param[in] ch_im_in number of input tensor channels
  372. * @param[in] wt pointer to kernel weights
  373. * @param[in] ch_im_out number of filters, i.e., output tensor channels
  374. * @param[in] dim_kernel filter kernel size
  375. * @param[in] padding padding sizes
  376. * @param[in] stride convolution stride
  377. * @param[in] bias pointer to bias
  378. * @param[in] bias_shift amount of left-shift for bias
  379. * @param[in] out_shift amount of right-shift for output
  380. * @param[in,out] Im_out pointer to output tensor
  381. * @param[in] dim_im_out output tensor dimension
  382. * @param[in,out] bufferA pointer to buffer space for input
  383. * @param[in,out] bufferB pointer to buffer space for output
  384. * @return The function returns either
  385. * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
  386. *
  387. * This function is the version with full list of optimization tricks, but with
  388. * some contraints:
  389. * ch_im_in is multiple of 4
  390. * ch_im_out is multiple of 2
  391. */
  392. arm_status arm_convolve_HWC_q7_fast(const q7_t * Im_in,
  393. const uint16_t dim_im_in,
  394. const uint16_t ch_im_in,
  395. const q7_t * wt,
  396. const uint16_t ch_im_out,
  397. const uint16_t dim_kernel,
  398. const uint16_t padding,
  399. const uint16_t stride,
  400. const q7_t * bias,
  401. const uint16_t bias_shift,
  402. const uint16_t out_shift,
  403. q7_t * Im_out,
  404. const uint16_t dim_im_out,
  405. q15_t * bufferA,
  406. q7_t * bufferB);
  407. /**
  408. * @brief Fast Q7 convolution function (non-sqaure shape)
  409. * @param[in] Im_in pointer to input tensor
  410. * @param[in] dim_im_in_x input tensor dimension x
  411. * @param[in] dim_im_in_y input tensor dimension y
  412. * @param[in] ch_im_in number of input tensor channels
  413. * @param[in] wt pointer to kernel weights
  414. * @param[in] ch_im_out number of filters, i.e., output tensor channels
  415. * @param[in] dim_kernel_x filter kernel size x
  416. * @param[in] dim_kernel_y filter kernel size y
  417. * @param[in] padding_x padding size x
  418. * @param[in] padding_y padding size y
  419. * @param[in] stride_x convolution stride x
  420. * @param[in] stride_y convolution stride y
  421. * @param[in] bias pointer to bias
  422. * @param[in] bias_shift amount of left-shift for bias
  423. * @param[in] out_shift amount of right-shift for output
  424. * @param[in,out] Im_out pointer to output tensor
  425. * @param[in] dim_im_out_x output tensor dimension x
  426. * @param[in] dim_im_out_y output tensor dimension y
  427. * @param[in,out] bufferA pointer to buffer space for input
  428. * @param[in,out] bufferB pointer to buffer space for output
  429. * @return The function returns either
  430. * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
  431. *
  432. * This function is the version with full list of optimization tricks, but with
  433. * some contraints:
  434. * ch_im_in is multiple of 4
  435. * ch_im_out is multiple of 2
  436. */
  437. arm_status arm_convolve_HWC_q7_fast_nonsquare(const q7_t * Im_in,
  438. const uint16_t dim_im_in_x,
  439. const uint16_t dim_im_in_y,
  440. const uint16_t ch_im_in,
  441. const q7_t * wt,
  442. const uint16_t ch_im_out,
  443. const uint16_t dim_kernel_x,
  444. const uint16_t dim_kernel_y,
  445. const uint16_t padding_x,
  446. const uint16_t padding_y,
  447. const uint16_t stride_x,
  448. const uint16_t stride_y,
  449. const q7_t * bias,
  450. const uint16_t bias_shift,
  451. const uint16_t out_shift,
  452. q7_t * Im_out,
  453. const uint16_t dim_im_out_x,
  454. const uint16_t dim_im_out_y,
  455. q15_t * bufferA,
  456. q7_t * bufferB);
  457. /**
  458. * @brief Fast Q7 version of 1x1 convolution (non-sqaure shape)
  459. * @param[in] Im_in pointer to input tensor
  460. * @param[in] dim_im_in_x input tensor dimension x
  461. * @param[in] dim_im_in_y input tensor dimension y
  462. * @param[in] ch_im_in number of input tensor channels
  463. * @param[in] wt pointer to kernel weights
  464. * @param[in] ch_im_out number of filters, i.e., output tensor channels
  465. * @param[in] dim_kernel_x filter kernel size x
  466. * @param[in] dim_kernel_y filter kernel size y
  467. * @param[in] padding_x padding size x
  468. * @param[in] padding_y padding size y
  469. * @param[in] stride_x convolution stride x
  470. * @param[in] stride_y convolution stride y
  471. * @param[in] bias pointer to bias
  472. * @param[in] bias_shift amount of left-shift for bias
  473. * @param[in] out_shift amount of right-shift for output
  474. * @param[in,out] Im_out pointer to output tensor
  475. * @param[in] dim_im_out_x output tensor dimension x
  476. * @param[in] dim_im_out_y output tensor dimension y
  477. * @param[in,out] bufferA pointer to buffer space for input
  478. * @param[in,out] bufferB pointer to buffer space for output
  479. * @return The function returns either
  480. * <code>ARM_MATH_SIZE_MISMATCH</code> if argument constraints fail. or,
  481. * <code>ARM_MATH_SUCCESS</code> on successful completion.
  482. *
  483. * This function implement convolution with 1x1 kernel size (i.e., dim_kernel_x=1
  484. * and dim_kernel_y=1). It can be used for
  485. * second half of MobileNets after depthwise separable convolution.
  486. *
  487. * This function is the version with full list of optimization tricks, but with
  488. * some contraints:
  489. * ch_im_in is multiple of 4
  490. * ch_im_out is multiple of 2
  491. */
  492. arm_status arm_convolve_1x1_HWC_q7_fast_nonsquare(const q7_t * Im_in,
  493. const uint16_t dim_im_in_x,
  494. const uint16_t dim_im_in_y,
  495. const uint16_t ch_im_in,
  496. const q7_t * wt,
  497. const uint16_t ch_im_out,
  498. const uint16_t dim_kernel_x,
  499. const uint16_t dim_kernel_y,
  500. const uint16_t padding_x,
  501. const uint16_t padding_y,
  502. const uint16_t stride_x,
  503. const uint16_t stride_y,
  504. const q7_t * bias,
  505. const uint16_t bias_shift,
  506. const uint16_t out_shift,
  507. q7_t * Im_out,
  508. const uint16_t dim_im_out_x,
  509. const uint16_t dim_im_out_y,
  510. q15_t * bufferA,
  511. q7_t * bufferB);
  512. /**
  513. * @brief Fast s8 version for 1x1 convolution (non-square shape)
  514. * @param[in] input pointer to input tensor. Format: [N, H, W, in_ch]
  515. * @param[in] input_x input tensor dimension x
  516. * @param[in] input_y input tensor dimension y
  517. * @param[in] input_ch number of input tensor channels
  518. * @param[in] input_batches number of input batches
  519. * @param[in] kernel pointer to kernel weights. Format: [out_ch, H, W, in_ch]
  520. * @param[in] output_ch number of filters, i.e., output tensor channels
  521. * @param[in] pad_x padding size x
  522. * @param[in] pad_y padding size y
  523. * @param[in] stride_x convolution stride x
  524. * @param[in] stride_y convolution stride y
  525. * @param[in] bias pointer to per channel bias. Range : int32
  526. * @param[in,out] output pointer to output tensor. Format: [H, W, out_ch]
  527. * @param[in] output_shift pointer to per output channel requantization shift parameter.
  528. * @param[in] output_mult pointer to per output channel requantization multiplier parameter.
  529. * @param[in] out_offset output tensor offset. Range: int8
  530. * @param[in] input_offset input tensor offset. Range: -127 to 128
  531. * @param[in] out_activation_min Minimum value to clamp the output to. Range: int8
  532. * @param[in] out_activation_max Minimum value to clamp the output to. Range: int8
  533. * @param[in] output_x output tensor width
  534. * @param[in] output_y output tensor height
  535. * @param[in] buffer_a pointer to buffer space used if required by the implementation
  536. * Use arm_convolve_1x1_s8_fast_get_buffer_size() to get the size
  537. * @return The function returns either
  538. * <code>ARM_MATH_SIZE_MISMATCH</code> if argument constraints fail. or,
  539. * <code>ARM_MATH_SUCCESS</code> on successful completion.
  540. *
  541. * @details
  542. * - Supported framework : TensorFlow Lite Micro
  543. * - The following constrains on the arguments apply
  544. * -# input_ch is a multiple of 4
  545. * -# padding equals 0
  546. * -# Stride equals 1
  547. * -# kernel dimension is 1x1 (Not provided in the argument list)
  548. *
  549. */
  550. arm_status arm_convolve_1x1_s8_fast(const q7_t *input,
  551. const uint16_t input_x,
  552. const uint16_t input_y,
  553. const uint16_t input_ch,
  554. const uint16_t input_batches,
  555. const q7_t *kernel,
  556. const uint16_t output_ch,
  557. const uint16_t pad_x,
  558. const uint16_t pad_y,
  559. const uint16_t stride_x,
  560. const uint16_t stride_y,
  561. const int32_t *bias,
  562. q7_t *output,
  563. const int32_t *output_shift,
  564. const int32_t *output_mult,
  565. const int32_t out_offset,
  566. const int32_t input_offset,
  567. const int32_t out_activation_min,
  568. const int32_t out_activation_max,
  569. const uint16_t output_x,
  570. const uint16_t output_y,
  571. q15_t *buffer_a);
  572. /**
  573. * @brief Get the required buffer size for the fast 1x1 convolution
  574. * (non-square shape) s8 convolution function
  575. * @param[in] input_ch number of input tensor channels
  576. * @return The function returns required buffer size
  577. *
  578. */
  579. int32_t arm_convolve_1x1_s8_fast_get_buffer_size(const uint16_t input_ch);
  580. /**
  581. * @brief 1xn convolution
  582. * @param[in] input pointer to input tensor. Format: [N, H, W, in_ch]
  583. * @param[in] input_x input tensor dimension x
  584. * @param[in] input_ch number of input tensor channels
  585. * @param[in] input_batches argument is not used.
  586. * @param[in] kernel pointer to kernel weights. Format: [out_ch, H, W, in_ch]
  587. * @param[in] output_ch number of filters, i.e., output tensor channels
  588. * @param[in] kernel_x kernel width along x
  589. * @param[in] pad_x padding along x
  590. * @param[in] stride_x stride along x
  591. * @param[in] bias pointer to per channel bias. Range : int32
  592. * @param[out] output pointer to output tensor. Format: [H, W, out_ch]
  593. * @param[in] output_shift pointer to per output channel requantization shift parameter.
  594. * @param[in] output_mult pointer to per output channel requantization multiplier parameter.
  595. * @param[in] out_offset output tensor offset. Range: int8
  596. * @param[in] input_offset input tensor offset. Range: -127 to 128
  597. * @param[in] out_activation_min Minimum value to clamp the output to. Range: int8
  598. * @param[in] out_activation_max Minimum value to clamp the output to. Range: int8
  599. * @param[in] output_x output tensor width
  600. * @param[in] buffer_a pointer to buffer space used for input optimization and is necessary
  601. * when ARM_MATH_DSP is defined but not ARM_MATH_MVEI.
  602. * Required space: 2 * input_ch * sizeof(q15_t) bytes
  603. * Use arm_convolve_1_x_n_s8_get_buffer_size() to get the size
  604. * @return The function returns either
  605. * <code>ARM_MATH_SIZE_MISMATCH</code> if argument constraints fail. or,
  606. * <code>ARM_MATH_SUCCESS</code> on successful completion.
  607. *
  608. * @details
  609. * - Supported framework : TensorFlow Lite Micro
  610. * - The following constrains on the arguments apply
  611. * -# input_batches equals 1
  612. * -# ouput_x is a multiple of 4
  613. * -# Explicit constraints(since it is for 1xN convolution)
  614. * -## input_y equals 1
  615. * -## output_y equals 1
  616. * -## kernel_y equals 1
  617. *@todo Remove constraint on output_x to make the function generic.
  618. *
  619. */
  620. arm_status arm_convolve_1_x_n_s8(const q7_t *input,
  621. const uint16_t input_x,
  622. const uint16_t input_ch,
  623. const uint16_t input_batches,
  624. const q7_t *kernel,
  625. const uint16_t output_ch,
  626. const uint16_t kernel_x,
  627. const uint16_t pad_x,
  628. const uint16_t stride_x,
  629. const int32_t *bias,
  630. q7_t *output,
  631. const int32_t *output_shift,
  632. const int32_t *output_mult,
  633. const int32_t out_offset,
  634. const int32_t input_offset,
  635. const int32_t out_activation_min,
  636. const int32_t out_activation_max,
  637. const uint16_t output_x,
  638. q15_t *buffer_a);
  639. /**
  640. * @brief Get the required additional buffer size for 1xn convolution
  641. *
  642. * @param[in] input_ch number of input tensor channels
  643. * @param[in] kernel_x filter/kernel width
  644. * @param[in] kernel_y filter/kernel height
  645. * @return The function returns required buffer size(bytes)
  646. *
  647. */
  648. int32_t arm_convolve_1_x_n_s8_get_buffer_size(const uint16_t input_ch,
  649. const uint16_t kernel_x,
  650. const uint16_t kernel_y);
  651. /**
  652. * @brief Q7 version of convolution for RGB image
  653. * @param[in] Im_in pointer to input tensor
  654. * @param[in] dim_im_in input tensor dimension
  655. * @param[in] ch_im_in number of input tensor channels
  656. * @param[in] wt pointer to kernel weights
  657. * @param[in] ch_im_out number of filters, i.e., output tensor channels
  658. * @param[in] dim_kernel filter kernel size
  659. * @param[in] padding padding sizes
  660. * @param[in] stride convolution stride
  661. * @param[in] bias pointer to bias
  662. * @param[in] bias_shift amount of left-shift for bias
  663. * @param[in] out_shift amount of right-shift for output
  664. * @param[in,out] Im_out pointer to output tensor
  665. * @param[in] dim_im_out output tensor dimension
  666. * @param[in,out] bufferA pointer to buffer space for input
  667. * @param[in,out] bufferB pointer to buffer space for output
  668. * @return The function returns either
  669. * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
  670. *
  671. * This kernel is written exclusively for convolution with ch_im_in
  672. * equals 3. This applies on the first layer of CNNs which has input
  673. * image with RGB format.
  674. */
  675. arm_status arm_convolve_HWC_q7_RGB(const q7_t * Im_in,
  676. const uint16_t dim_im_in,
  677. const uint16_t ch_im_in,
  678. const q7_t * wt,
  679. const uint16_t ch_im_out,
  680. const uint16_t dim_kernel,
  681. const uint16_t padding,
  682. const uint16_t stride,
  683. const q7_t * bias,
  684. const uint16_t bias_shift,
  685. const uint16_t out_shift,
  686. q7_t * Im_out,
  687. const uint16_t dim_im_out,
  688. q15_t * bufferA,
  689. q7_t * bufferB);
  690. /**
  691. * @brief Fast Q15 convolution function
  692. * @param[in] Im_in pointer to input tensor
  693. * @param[in] dim_im_in input tensor dimension
  694. * @param[in] ch_im_in number of input tensor channels
  695. * @param[in] wt pointer to kernel weights
  696. * @param[in] ch_im_out number of filters, i.e., output tensor channels
  697. * @param[in] dim_kernel filter kernel size
  698. * @param[in] padding padding sizes
  699. * @param[in] stride convolution stride
  700. * @param[in] bias pointer to bias
  701. * @param[in] bias_shift amount of left-shift for bias
  702. * @param[in] out_shift amount of right-shift for output
  703. * @param[in,out] Im_out pointer to output tensor
  704. * @param[in] dim_im_out output tensor dimension
  705. * @param[in,out] bufferA pointer to buffer space for input
  706. * @param[in,out] bufferB pointer to buffer space for output
  707. * @return The function returns either
  708. * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
  709. *
  710. * This function is the version with full list of optimization tricks, but with
  711. * some contraints:
  712. * ch_im_in is multiple of 2
  713. * ch_im_out is multiple of 2
  714. */
  715. arm_status arm_convolve_HWC_q15_fast(const q15_t * Im_in,
  716. const uint16_t dim_im_in,
  717. const uint16_t ch_im_in,
  718. const q15_t * wt,
  719. const uint16_t ch_im_out,
  720. const uint16_t dim_kernel,
  721. const uint16_t padding,
  722. const uint16_t stride,
  723. const q15_t * bias,
  724. const uint16_t bias_shift,
  725. const uint16_t out_shift,
  726. q15_t * Im_out,
  727. const uint16_t dim_im_out,
  728. q15_t * bufferA,
  729. q7_t * bufferB);
  730. /**
  731. * @brief Fast Q15 convolution function (non-sqaure shape)
  732. * @param[in] Im_in pointer to input tensor
  733. * @param[in] dim_im_in_x input tensor dimension x
  734. * @param[in] dim_im_in_y input tensor dimension y
  735. * @param[in] ch_im_in number of input tensor channels
  736. * @param[in] wt pointer to kernel weights
  737. * @param[in] ch_im_out number of filters, i.e., output tensor channels
  738. * @param[in] dim_kernel_x filter kernel size x
  739. * @param[in] dim_kernel_y filter kernel size y
  740. * @param[in] padding_x padding size x
  741. * @param[in] padding_y padding size y
  742. * @param[in] stride_x convolution stride x
  743. * @param[in] stride_y convolution stride y
  744. * @param[in] bias pointer to bias
  745. * @param[in] bias_shift amount of left-shift for bias
  746. * @param[in] out_shift amount of right-shift for output
  747. * @param[in,out] Im_out pointer to output tensor
  748. * @param[in] dim_im_out_x output tensor dimension x
  749. * @param[in] dim_im_out_y output tensor dimension y
  750. * @param[in,out] bufferA pointer to buffer space for input
  751. * @param[in,out] bufferB pointer to buffer space for output
  752. * @return The function returns either
  753. * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
  754. *
  755. * @details
  756. *
  757. * <b>Buffer size:</b>
  758. *
  759. * bufferA size: 2*ch_im_in*dim_kernel*dim_kernel
  760. *
  761. * bufferB size: 0
  762. *
  763. * <b>Input dimension constraints:</b>
  764. *
  765. * ch_im_in is multiple of 2
  766. *
  767. * ch_im_out is multipe of 2
  768. *
  769. */
  770. arm_status
  771. arm_convolve_HWC_q15_fast_nonsquare(const q15_t * Im_in,
  772. const uint16_t dim_im_in_x,
  773. const uint16_t dim_im_in_y,
  774. const uint16_t ch_im_in,
  775. const q15_t * wt,
  776. const uint16_t ch_im_out,
  777. const uint16_t dim_kernel_x,
  778. const uint16_t dim_kernel_y,
  779. const uint16_t padding_x,
  780. const uint16_t padding_y,
  781. const uint16_t stride_x,
  782. const uint16_t stride_y,
  783. const q15_t * bias,
  784. const uint16_t bias_shift,
  785. const uint16_t out_shift,
  786. q15_t * Im_out,
  787. const uint16_t dim_im_out_x,
  788. const uint16_t dim_im_out_y,
  789. q15_t * bufferA,
  790. q7_t * bufferB);
  791. /**
  792. * @brief Q7 depthwise separable convolution function
  793. * @param[in] Im_in pointer to input tensor
  794. * @param[in] dim_im_in input tensor dimension
  795. * @param[in] ch_im_in number of input tensor channels
  796. * @param[in] wt pointer to kernel weights
  797. * @param[in] ch_im_out number of filters, i.e., output tensor channels
  798. * @param[in] dim_kernel filter kernel size
  799. * @param[in] padding padding sizes
  800. * @param[in] stride convolution stride
  801. * @param[in] bias pointer to bias
  802. * @param[in] bias_shift amount of left-shift for bias
  803. * @param[in] out_shift amount of right-shift for output
  804. * @param[in,out] Im_out pointer to output tensor
  805. * @param[in] dim_im_out output tensor dimension
  806. * @param[in,out] bufferA pointer to buffer space for input
  807. * @param[in,out] bufferB pointer to buffer space for output
  808. * @return The function returns either
  809. * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
  810. *
  811. * This function is the version with full list of optimization tricks, but with
  812. * some contraints:
  813. * ch_im_in is multiple of 2
  814. * ch_im_out is multiple of 2
  815. */
  816. arm_status arm_depthwise_separable_conv_HWC_q7(const q7_t * Im_in,
  817. const uint16_t dim_im_in,
  818. const uint16_t ch_im_in,
  819. const q7_t * wt,
  820. const uint16_t ch_im_out,
  821. const uint16_t dim_kernel,
  822. const uint16_t padding,
  823. const uint16_t stride,
  824. const q7_t * bias,
  825. const uint16_t bias_shift,
  826. const uint16_t out_shift,
  827. q7_t * Im_out,
  828. const uint16_t dim_im_out,
  829. q15_t * bufferA,
  830. q7_t * bufferB);
  831. /**
  832. * @brief Q7 depthwise separable convolution function (non-square shape)
  833. * @param[in] Im_in pointer to input tensor
  834. * @param[in] dim_im_in_x input tensor dimension x
  835. * @param[in] dim_im_in_y input tensor dimension y
  836. * @param[in] ch_im_in number of input tensor channels
  837. * @param[in] wt pointer to kernel weights
  838. * @param[in] ch_im_out number of filters, i.e., output tensor channels
  839. * @param[in] dim_kernel_x filter kernel size x
  840. * @param[in] dim_kernel_y filter kernel size y
  841. * @param[in] padding_x padding sizes x
  842. * @param[in] padding_y padding sizes y
  843. * @param[in] stride_x convolution stride x
  844. * @param[in] stride_y convolution stride y
  845. * @param[in] bias pointer to bias
  846. * @param[in] bias_shift amount of left-shift for bias
  847. * @param[in] out_shift amount of right-shift for output
  848. * @param[in,out] Im_out pointer to output tensor
  849. * @param[in] dim_im_out_x output tensor dimension x
  850. * @param[in] dim_im_out_y output tensor dimension y
  851. * @param[in,out] bufferA pointer to buffer space for input
  852. * @param[in,out] bufferB pointer to buffer space for output
  853. * @return The function returns either
  854. * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
  855. *
  856. * This function is the version with full list of optimization tricks, but with
  857. * some contraints:
  858. * ch_im_in is multiple of 2
  859. * ch_im_out is multiple of 2
  860. */
  861. arm_status arm_depthwise_separable_conv_HWC_q7_nonsquare(const q7_t * Im_in,
  862. const uint16_t dim_im_in_x,
  863. const uint16_t dim_im_in_y,
  864. const uint16_t ch_im_in,
  865. const q7_t * wt,
  866. const uint16_t ch_im_out,
  867. const uint16_t dim_kernel_x,
  868. const uint16_t dim_kernel_y,
  869. const uint16_t padding_x,
  870. const uint16_t padding_y,
  871. const uint16_t stride_x,
  872. const uint16_t stride_y,
  873. const q7_t * bias,
  874. const uint16_t bias_shift,
  875. const uint16_t out_shift,
  876. q7_t * Im_out,
  877. const uint16_t dim_im_out_x,
  878. const uint16_t dim_im_out_y,
  879. q15_t * bufferA,
  880. q7_t * bufferB);
  881. /**
  882. * @brief Basic s8 depthwise convolution function
  883. * @param[in] input pointer to input tensor. Range: int8, format: [H,W,in_ch]
  884. * @param[in] input_x input tensor width
  885. * @param[in] input_y input tensor height
  886. * @param[in] input_ch number of input tensor channels
  887. * @param[in] kernel pointer to kernel weights. Range: int8, format: [in_ch, H, W, out_ch]
  888. * @param[in] output_ch Number of output channels. output_ch = ch_mult * input_ch
  889. * @param[in] ch_mult channel multiplier.
  890. * @param[in] kernel_x filter/kernel width
  891. * @param[in] kernel_y filter/kernel height
  892. * @param[in] pad_x padding along width
  893. * @param[in] pad_y padding along height
  894. * @param[in] stride_x convolution stride along width
  895. * @param[in] stride_y convolution stride along height
  896. * @param[in] bias pointer to per output channel bias. Range: int32
  897. * @param[in,out] output pointer to output tensor. Format: [H, W, out_ch]
  898. * @param[in] output_shift pointer to per output channel requantization shift parameter.
  899. * @param[in] output_mult pointer to per output channel requantization multiplier parameter.
  900. * @param[in] output_x output tensor width
  901. * @param[in] output_y output tensor height
  902. * @param[in] output_offset offset to elements of output tensor. Range: int8
  903. * @param[in] input_offset offset to elements of input tensor. Range: -127 to 128
  904. * @param[in] output_activation_min Minimum value to clamp the output to. Range: int8
  905. * @param[in] output_activation_max Minimum value to clamp the output to. Range: int8
  906. * @param[in] dilation_x dilation along x. Not used. Dilation factor of 1 is used.
  907. * @param[in] dilation_y dilation along y. Not used. Dilation factor of 1 is used.
  908. * @param[in] buffer_a Not used.
  909. *
  910. * @return The function returns <code>ARM_MATH_SUCCESS</code>
  911. *
  912. * @details
  913. * 1. Supported framework: TensorFlow Lite
  914. * 2. q7 is used as data type eventhough it is s8 data. It is done so to be consistent with existing APIs.
  915. * 3. Optimization using DSP extension is not available for the generic case where channel multiplier is > 1.
  916. *
  917. */
  918. arm_status arm_depthwise_conv_s8(const q7_t *input,
  919. const uint16_t input_x,
  920. const uint16_t input_y,
  921. const uint16_t input_ch,
  922. const q7_t *kernel,
  923. const uint16_t output_ch,
  924. const uint16_t ch_mult,
  925. const uint16_t kernel_x,
  926. const uint16_t kernel_y,
  927. const uint16_t pad_x,
  928. const uint16_t pad_y,
  929. const uint16_t stride_x,
  930. const uint16_t stride_y,
  931. const int32_t *bias,
  932. q7_t *output,
  933. const int32_t *output_shift,
  934. const int32_t *output_mult,
  935. const uint16_t output_x,
  936. const uint16_t output_y,
  937. const int32_t output_offset,
  938. const int32_t input_offset,
  939. const int32_t output_activation_min,
  940. const int32_t output_activation_max,
  941. const uint16_t dilation_x,
  942. const uint16_t dilation_y,
  943. q15_t *buffer_a);
  944. /**
  945. * @brief Optimized s8 depthwise convolution function for 3x3 kernel size with constraint that in_channel equals out_channel
  946. * @param[in] input pointer to input tensor. Range: int8, format: [H,W,in_ch]
  947. * @param[in] input_x input tensor width
  948. * @param[in] input_y input tensor height
  949. * @param[in] input_ch number of input tensor channels
  950. * @param[in] kernel pointer to kernel weights. Range: int8, Format: [in_ch, H, W, out_ch]
  951. * @param[in] output_ch Number of output channels.
  952. * @param[in] pad_x padding along width
  953. * @param[in] pad_y padding along height
  954. * @param[in] stride_x convolution stride along width
  955. * @param[in] stride_y convolution stride along height
  956. * @param[in] bias pointer to per output channel bias. Range: int8
  957. * @param[in,out] output pointer to output tensor. Format: [H, W, out_ch]
  958. * @param[in] output_shift pointer to per output channel requantization shift parameter.
  959. * @param[in] output_mult pointer to per output channel requantization multiplier parameter.
  960. * @param[in] output_x output tensor width
  961. * @param[in] output_y output tensor height
  962. * @param[in] output_offset offset to elements of output tensor
  963. * @param[in] input_offset offset to elements of input tensor
  964. * @param[in] output_activation_min Minimum value to clamp the output to. Range: int8
  965. * @param[in] output_activation_max Minimum value to clamp the output to. Range: int8
  966. * @param[in] dilation_x dilation along x. Not used. Dilation factor of 1 is used.
  967. * @param[in] dilation_y dilation along y. Not used. Dilation factor of 1 is used.
  968. * @param[in] buffer_a Buffer for partial im2col optimization. Not used.
  969. *
  970. * @return The function returns one of the following
  971. * <code>ARM_MATH_SIZE_MISMATCH</code> - Unsupported dimension of tensors
  972. * <code>ARM_MATH_ARGUMENT_ERROR</code> - Unsupported pad size along the x axis
  973. * <code>ARM_MATH_SUCCESS</code> - Successful operation
  974. *
  975. * @details
  976. * Supported framework: TensorFlow Lite
  977. *
  978. */
  979. arm_status arm_depthwise_conv_3x3_s8(const int8_t *input,
  980. const int32_t input_x,
  981. const int32_t input_y,
  982. const int32_t input_ch,
  983. const int8_t *kernel,
  984. const int32_t output_ch,
  985. const int32_t pad_x,
  986. const int32_t pad_y,
  987. const int32_t stride_x,
  988. const int32_t stride_y,
  989. const int32_t *bias,
  990. int8_t *output,
  991. const int32_t *output_shift,
  992. const int32_t *output_mult,
  993. const int32_t output_x,
  994. const int32_t output_y,
  995. const int32_t output_offset,
  996. const int32_t input_offset,
  997. const int32_t output_activation_min,
  998. const int32_t output_activation_max,
  999. const int32_t dilation_x,
  1000. const int32_t dilation_y,
  1001. int16_t *buffer_a);
  1002. /**
  1003. * @brief Optimized s8 depthwise convolution function with constraint that in_channel equals out_channel
  1004. * @param[in] input pointer to input tensor. Range: int8, format: [H,W,in_ch]
  1005. * @param[in] input_x input tensor width
  1006. * @param[in] input_y input tensor height
  1007. * @param[in] input_ch number of input tensor channels
  1008. * @param[in] kernel pointer to kernel weights. Range: int8, Format: [in_ch, H, W, out_ch]
  1009. * @param[in] output_ch Number of output channels.
  1010. * @param[in] kernel_x filter/kernel width
  1011. * @param[in] kernel_y filter/kernel height
  1012. * @param[in] pad_x padding along width
  1013. * @param[in] pad_y padding along height
  1014. * @param[in] stride_x convolution stride along width
  1015. * @param[in] stride_y convolution stride along height
  1016. * @param[in] bias pointer to per output channel bias. Range: int8
  1017. * @param[in,out] output pointer to output tensor. Format: [H, W, out_ch]
  1018. * @param[in] output_shift pointer to per output channel requantization shift parameter.
  1019. * @param[in] output_mult pointer to per output channel requantization multiplier parameter.
  1020. * @param[in] output_x output tensor width
  1021. * @param[in] output_y output tensor height
  1022. * @param[in] output_offset offset to elements of output tensor
  1023. * @param[in] input_offset offset to elements of input tensor
  1024. * @param[in] output_activation_min Minimum value to clamp the output to. Range: int8
  1025. * @param[in] output_activation_max Minimum value to clamp the output to. Range: int8
  1026. * @param[in] dilation_x dilation along x. Not used. Dilation factor of 1 is used.
  1027. * @param[in] dilation_y dilation along y. Not used. Dilation factor of 1 is used.
  1028. * @param[in] buffer_a Buffer for partial im2col optimization. This is mandatory when
  1029. * ARM_MATH_DSP is defined.
  1030. * Required space: (2 * input_ch * kernel_x * kernel_y) * sizeof(q15_t) bytes
  1031. * Use arm_depthwise_conv_s8_opt_get_buffer_size() to get the size.
  1032. *
  1033. * @return The function returns one of the following
  1034. * <code>ARM_MATH_SIZE_MISMATCH</code> - Unsupported dimension of tensors
  1035. * <code>ARM_MATH_SUCCESS</code> - Successful operation
  1036. *
  1037. * @note If number of channels is not a multiple of 4, upto 3 elements outside the boundary will be read out
  1038. * for the following if MVE optimizations(Arm Helium Technology) are used.
  1039. * - Output shift
  1040. * - Output multiplier
  1041. * - Output bias
  1042. * - kernel
  1043. *
  1044. * @details
  1045. * 1. Supported framework: TensorFlow Lite
  1046. * 2. q7 is used as data type eventhough it is s8 data. It is done so to be consistent with existing APIs.
  1047. * 3. Reccomended when number of channels is 4 or greater.
  1048. *
  1049. */
  1050. arm_status arm_depthwise_conv_s8_opt(const q7_t *input,
  1051. const uint16_t input_x,
  1052. const uint16_t input_y,
  1053. const uint16_t input_ch,
  1054. const q7_t *kernel,
  1055. const uint16_t output_ch,
  1056. const uint16_t kernel_x,
  1057. const uint16_t kernel_y,
  1058. const uint16_t pad_x,
  1059. const uint16_t pad_y,
  1060. const uint16_t stride_x,
  1061. const uint16_t stride_y,
  1062. const int32_t *bias,
  1063. q7_t *output,
  1064. const int32_t *output_shift,
  1065. const int32_t *output_mult,
  1066. const uint16_t output_x,
  1067. const uint16_t output_y,
  1068. const int32_t output_offset,
  1069. const int32_t input_offset,
  1070. const int32_t output_activation_min,
  1071. const int32_t output_activation_max,
  1072. const uint16_t dilation_x,
  1073. const uint16_t dilation_y,
  1074. q15_t *buffer_a);
  1075. /**
  1076. * @brief Get the required buffer size for optimized s8 depthwise convolution
  1077. * function with constraint that in_channel equals out_channel.
  1078. * @param[in] input_ch number of input tensor channels
  1079. * @param[in] kernel_x filter/kernel width
  1080. * @param[in] kernel_y filter/kernel height
  1081. * @return The function returns required buffer size
  1082. *
  1083. */
  1084. int32_t arm_depthwise_conv_s8_opt_get_buffer_size(const uint16_t input_ch,
  1085. const uint16_t kernel_x,
  1086. const uint16_t kernel_y);
  1087. /**
  1088. * @defgroup FC Fully-connected Layer Functions
  1089. *
  1090. * Collection of fully-connected and matrix multiplication functions.
  1091. *
  1092. * Fully-connected layer is basically a matrix-vector multiplication
  1093. * with bias. The matrix is the weights and the input/output vectors
  1094. * are the activation values. Supported {weight, activation} precisions
  1095. * include {8-bit, 8-bit}, {16-bit, 16-bit}, and {8-bit, 16-bit}.
  1096. *
  1097. * Here we have two types of kernel functions. The basic function
  1098. * implements the function using regular GEMV approach. The opt functions
  1099. * operates with weights in interleaved formats.
  1100. *
  1101. */
  1102. /**
  1103. * @brief Q7 basic fully-connected layer function
  1104. * @param[in] pV pointer to input vector
  1105. * @param[in] pM pointer to matrix weights
  1106. * @param[in] dim_vec length of the vector
  1107. * @param[in] num_of_rows number of rows in weight matrix
  1108. * @param[in] bias_shift amount of left-shift for bias
  1109. * @param[in] out_shift amount of right-shift for output
  1110. * @param[in] bias pointer to bias
  1111. * @param[in,out] pOut pointer to output vector
  1112. * @param[in,out] vec_buffer pointer to buffer space for input
  1113. * @return The function returns <code>ARM_MATH_SUCCESS</code>
  1114. *
  1115. */
  1116. arm_status arm_fully_connected_q7(const q7_t * pV,
  1117. const q7_t * pM,
  1118. const uint16_t dim_vec,
  1119. const uint16_t num_of_rows,
  1120. const uint16_t bias_shift,
  1121. const uint16_t out_shift,
  1122. const q7_t * bias,
  1123. q7_t * pOut,
  1124. q15_t * vec_buffer);
  1125. /**
  1126. * @brief S8 basic fully-connected and matrix multiplication layer function for TF Lite
  1127. * @param[in] pInput pointer to pInput vector
  1128. * @param[in] pWeight pointer to matrix weights
  1129. * @param[in] col_dim dimension of the input vector
  1130. * @param[in] row_dim dimension of the output vector
  1131. * @param[in] nb_batches number of batches
  1132. * @param[in] input_offset tensor offset for input. Range: -127 to 128
  1133. * @param[in] filter_offset tensor offset for filter. Range: -127 to 128
  1134. * @param[in] out_mult requantization parameter
  1135. * @param[in] out_shift requantization parameter
  1136. * @param[in] output_offset tensor offset for output. Range: int8
  1137. * @param[in] pBias pointer to bias
  1138. * @param[out] pOut pointer to output vector
  1139. * @param[in] output_activation_min for clamping
  1140. * @param[in] output_activation_max for clamping
  1141. * @param[in] vec_buffer pointer to buffer space used for optimization and is necessary
  1142. * when ARM_MATH_DSP is defined but not
  1143. * ARM_MATH_MVEI.
  1144. * Required space: col_dim * sizeof(q15_t) bytes
  1145. * Use arm_fully_connected_s8_get_buffer_size() to get the size.
  1146. * @return The function returns ARM_MATH_SUCCESS
  1147. *
  1148. * @details
  1149. *
  1150. * <b>Buffer size:</b>
  1151. *
  1152. * vec_buffer size: col_dim of word16.
  1153. *
  1154. * This basic function is designed to work with regular pWeight
  1155. * matrix without interleaving.
  1156. *
  1157. * 1. Supported framework: TensorFlow Lite
  1158. * 2. q7 is used as data type eventhough it is s8 data. It is done so to be consistent with existing APIs.
  1159. *
  1160. */
  1161. arm_status
  1162. arm_fully_connected_s8(const int8_t *pInput,
  1163. const int8_t *pWeight,
  1164. const uint16_t col_dim,
  1165. const uint16_t row_dim,
  1166. const uint16_t nb_batches,
  1167. const int32_t input_offset,
  1168. const int32_t filter_offset,
  1169. const int32_t out_mult,
  1170. const int32_t out_shift,
  1171. const int32_t output_offset,
  1172. const int32_t *pBias,
  1173. int8_t *pOut,
  1174. const int32_t output_activation_min,
  1175. const int32_t output_activation_max,
  1176. q15_t *vec_buffer);
  1177. /**
  1178. * @brief Get the required buffer size for S8 basic fully-connected and
  1179. * matrix multiplication layer function for TF Lite
  1180. * @param[in] col_dim dimension of the input vector
  1181. * @return The function returns required buffer size
  1182. *
  1183. */
  1184. int32_t arm_fully_connected_s8_get_buffer_size(const uint16_t col_dim);
  1185. /**
  1186. * @brief Q7 opt fully-connected layer function
  1187. * @param[in] pV pointer to input vector
  1188. * @param[in] pM pointer to matrix weights
  1189. * @param[in] dim_vec length of the vector
  1190. * @param[in] num_of_rows number of rows in weight matrix
  1191. * @param[in] bias_shift amount of left-shift for bias
  1192. * @param[in] out_shift amount of right-shift for output
  1193. * @param[in] bias pointer to bias
  1194. * @param[in,out] pOut pointer to output vector
  1195. * @param[in,out] vec_buffer pointer to buffer space for input
  1196. * @return The function returns <code>ARM_MATH_SUCCESS</code>
  1197. *
  1198. */
  1199. arm_status arm_fully_connected_q7_opt(const q7_t * pV,
  1200. const q7_t * pM,
  1201. const uint16_t dim_vec,
  1202. const uint16_t num_of_rows,
  1203. const uint16_t bias_shift,
  1204. const uint16_t out_shift,
  1205. const q7_t * bias,
  1206. q7_t * pOut,
  1207. q15_t * vec_buffer);
  1208. /**
  1209. * @brief Q15 basic fully-connected layer function
  1210. * @param[in] pV pointer to input vector
  1211. * @param[in] pM pointer to matrix weights
  1212. * @param[in] dim_vec length of the vector
  1213. * @param[in] num_of_rows number of rows in weight matrix
  1214. * @param[in] bias_shift amount of left-shift for bias
  1215. * @param[in] out_shift amount of right-shift for output
  1216. * @param[in] bias pointer to bias
  1217. * @param[in,out] pOut pointer to output vector
  1218. * @param[in,out] vec_buffer pointer to buffer space for input
  1219. * @return The function returns <code>ARM_MATH_SUCCESS</code>
  1220. *
  1221. */
  1222. arm_status arm_fully_connected_q15(const q15_t * pV,
  1223. const q15_t * pM,
  1224. const uint16_t dim_vec,
  1225. const uint16_t num_of_rows,
  1226. const uint16_t bias_shift,
  1227. const uint16_t out_shift,
  1228. const q15_t * bias,
  1229. q15_t * pOut,
  1230. q15_t * vec_buffer);
  1231. /**
  1232. * @brief Q15 opt fully-connected layer function
  1233. * @param[in] pV pointer to input vector
  1234. * @param[in] pM pointer to matrix weights
  1235. * @param[in] dim_vec length of the vector
  1236. * @param[in] num_of_rows number of rows in weight matrix
  1237. * @param[in] bias_shift amount of left-shift for bias
  1238. * @param[in] out_shift amount of right-shift for output
  1239. * @param[in] bias pointer to bias
  1240. * @param[in,out] pOut pointer to output vector
  1241. * @param[in,out] vec_buffer pointer to buffer space for input
  1242. * @return The function returns <code>ARM_MATH_SUCCESS</code>
  1243. *
  1244. */
  1245. arm_status arm_fully_connected_q15_opt(const q15_t * pV,
  1246. const q15_t * pM,
  1247. const uint16_t dim_vec,
  1248. const uint16_t num_of_rows,
  1249. const uint16_t bias_shift,
  1250. const uint16_t out_shift,
  1251. const q15_t * bias,
  1252. q15_t * pOut,
  1253. q15_t * vec_buffer);
  1254. /**
  1255. * @brief Mixed Q15-Q7 fully-connected layer function
  1256. * @param[in] pV pointer to input vector
  1257. * @param[in] pM pointer to matrix weights
  1258. * @param[in] dim_vec length of the vector
  1259. * @param[in] num_of_rows number of rows in weight matrix
  1260. * @param[in] bias_shift amount of left-shift for bias
  1261. * @param[in] out_shift amount of right-shift for output
  1262. * @param[in] bias pointer to bias
  1263. * @param[in,out] pOut pointer to output vector
  1264. * @param[in,out] vec_buffer pointer to buffer space for input
  1265. * @return The function returns <code>ARM_MATH_SUCCESS</code>
  1266. *
  1267. */
  1268. arm_status arm_fully_connected_mat_q7_vec_q15(const q15_t * pV,
  1269. const q7_t * pM,
  1270. const uint16_t dim_vec,
  1271. const uint16_t num_of_rows,
  1272. const uint16_t bias_shift,
  1273. const uint16_t out_shift,
  1274. const q7_t * bias,
  1275. q15_t * pOut,
  1276. q15_t * vec_buffer);
  1277. /**
  1278. * @brief Mixed Q15-Q7 opt fully-connected layer function
  1279. * @param[in] pV pointer to input vector
  1280. * @param[in] pM pointer to matrix weights
  1281. * @param[in] dim_vec length of the vector
  1282. * @param[in] num_of_rows number of rows in weight matrix
  1283. * @param[in] bias_shift amount of left-shift for bias
  1284. * @param[in] out_shift amount of right-shift for output
  1285. * @param[in] bias pointer to bias
  1286. * @param[in,out] pOut pointer to output vector
  1287. * @param[in,out] vec_buffer pointer to buffer space for input
  1288. * @return The function returns <code>ARM_MATH_SUCCESS</code>
  1289. *
  1290. */
  1291. arm_status arm_fully_connected_mat_q7_vec_q15_opt(const q15_t * pV,
  1292. const q7_t * pM,
  1293. const uint16_t dim_vec,
  1294. const uint16_t num_of_rows,
  1295. const uint16_t bias_shift,
  1296. const uint16_t out_shift,
  1297. const q7_t * bias,
  1298. q15_t * pOut,
  1299. q15_t * vec_buffer);
  1300. /**
  1301. * @brief Matrix-Multiplication Kernels for Convolution
  1302. *
  1303. * These functions are used within convolution layer functions for
  1304. * matrix multiplication.
  1305. *
  1306. * The implementation is similar to CMSIS-DSP arm_mat_mult functions
  1307. * with one Q7 and one Q15 operands. The Q15 operand is the im2col
  1308. * output which is always with 2 columns.
  1309. *
  1310. */
  1311. /**
  1312. * @brief Matrix-multiplication function for convolution
  1313. * @param[in] pA pointer to operand A
  1314. * @param[in] pInBuffer pointer to operand B, always conssists of 2 vectors
  1315. * @param[in] ch_im_out numRow of A
  1316. * @param[in] numCol_A numCol of A
  1317. * @param[in] bias_shift amount of left-shift for bias
  1318. * @param[in] out_shift amount of right-shift for output
  1319. * @param[in] bias the bias
  1320. * @param[in,out] pOut pointer to output
  1321. * @return The function returns the incremented output pointer
  1322. */
  1323. q7_t *arm_nn_mat_mult_kernel_q7_q15(const q7_t * pA,
  1324. const q15_t * pInBuffer,
  1325. const uint16_t ch_im_out,
  1326. const uint16_t numCol_A,
  1327. const uint16_t bias_shift,
  1328. const uint16_t out_shift,
  1329. const q7_t * bias,
  1330. q7_t * pOut);
  1331. /**
  1332. * @brief Matrix-multiplication function for convolution with per-channel requantization.
  1333. * @param[in] input_a pointer to operand A
  1334. * @param[in] input_b pointer to operand B, always consists of 2 vectors.
  1335. * @param[in] output_ch number of rows of A
  1336. * @param[in] out_shift pointer to per output channel requantization shift parameter.
  1337. * @param[in] out_mult pointer to per output channel requantization multiplier parameter.
  1338. * @param[in] out_offset output tensor offset.
  1339. * @param[in] activation_min minimum value to clamp the output to. Range : int8
  1340. * @param[in] activation_max maximum value to clamp the output to. Range : int8
  1341. * @param[in] num_col_a number of columns of A
  1342. * @param[in] output_bias per output channel bias. Range : int32
  1343. * @param[in,out] out_0 pointer to output
  1344. * @return The function returns one of the two
  1345. * 1. The incremented output pointer for a successful operation or
  1346. * 2. NULL if implementation is not available.
  1347. *
  1348. * @details This function does the matrix multiplication of weight matrix for all output channels
  1349. * with 2 columns from im2col and produces two elements/output_channel. The outputs are
  1350. * clamped in the range provided by activation min and max.
  1351. * Supported framework: TensorFlow Lite micro.
  1352. */
  1353. q7_t *arm_nn_mat_mult_kernel_s8_s16(const q7_t *input_a,
  1354. const q15_t *input_b,
  1355. const uint16_t output_ch,
  1356. const int32_t *out_shift,
  1357. const int32_t *out_mult,
  1358. const int32_t out_offset,
  1359. const int16_t activation_min,
  1360. const int16_t activation_max,
  1361. const uint16_t num_col_a,
  1362. const int32_t *const output_bias,
  1363. q7_t *out_0);
  1364. /**
  1365. * @brief Matrix-multiplication of re-ordered input B with A.
  1366. *
  1367. * @details For arguments, refer arm_nn_mat_mult_kernel_s8_s16. The re-ordering is a consequence
  1368. * of sign extension done by the SXTB16 command on input_b. The outputs are clamped in the range
  1369. * provided by activation min and max.
  1370. * * @details
  1371. * - Supported framework : TensorFlow Lite Micro
  1372. * - The following constrains on the arguments apply
  1373. * -# num_col_a is a multiple of 4
  1374. * -# output_ch is a multiple of 2
  1375. *
  1376. */
  1377. q7_t *arm_nn_mat_mult_kernel_s8_s16_reordered(const q7_t *input_a,
  1378. const q15_t *input_b,
  1379. const uint16_t output_ch,
  1380. const int32_t *out_shift,
  1381. const int32_t *out_mult,
  1382. const int32_t out_offset,
  1383. const int16_t activation_min,
  1384. const int16_t activation_max,
  1385. const uint16_t num_col_a,
  1386. const int32_t *const output_bias,
  1387. q7_t *out_0);
  1388. /**
  1389. * @brief Matrix-multiplication function for convolution with reordered columns
  1390. * @param[in] pA pointer to operand A
  1391. * @param[in] pInBuffer pointer to operand B, always conssists of 2 vectors
  1392. * @param[in] ch_im_out numRow of A
  1393. * @param[in] numCol_A numCol of A
  1394. * @param[in] bias_shift amount of left-shift for bias
  1395. * @param[in] out_shift amount of right-shift for output
  1396. * @param[in] bias the bias
  1397. * @param[in,out] pOut pointer to output
  1398. * @return The function returns the incremented output pointer
  1399. *
  1400. * @details This function assumes that data in pInBuffer are reordered
  1401. */
  1402. q7_t *arm_nn_mat_mult_kernel_q7_q15_reordered(const q7_t * pA,
  1403. const q15_t * pInBuffer,
  1404. const uint16_t ch_im_out,
  1405. const uint16_t numCol_A,
  1406. const uint16_t bias_shift,
  1407. const uint16_t out_shift,
  1408. const q7_t * bias,
  1409. q7_t * pOut);
  1410. #ifdef __cplusplus
  1411. }
  1412. #endif
  1413. /*
  1414. * Other functions
  1415. * These layers are typically not timing critical
  1416. * Basic implementation is supported here
  1417. */
  1418. #ifdef __cplusplus
  1419. extern "C"
  1420. {
  1421. #endif
  1422. /**
  1423. * @defgroup BasicMath Basic math functions
  1424. *
  1425. * Element wise add and multiplication functions.
  1426. *
  1427. */
  1428. /**
  1429. * @brief s8 element wise add of two vectors
  1430. * @param[in] input_1_vect pointer to input vector 1
  1431. * @param[in] input_2_vect pointer to input vector 2
  1432. * @param[in] input_1_offset offset for input 1. Range: Range: -127 to 128
  1433. * @param[in] input_1_mult multiplier for input 1
  1434. * @param[in] input_1_shift shift for input 1
  1435. * @param[in] input_2_offset offset for input 2. Range: Range: -127 to 128
  1436. * @param[in] input_2_mult multiplier for input 2
  1437. * @param[in] input_2_shift shift for input 2
  1438. * @param[in] left_shift input left shift
  1439. * @param[in,out] output pointer to output vector
  1440. * @param[in] out_offset output offset
  1441. * @param[in] out_mult output multiplier
  1442. * @param[in] out_shift output shift
  1443. * @param[in] out_activation_min minimum value to clamp output to
  1444. * @param[in] out_activation_max maximum value to clamp output to
  1445. * @param[in] block_size number of samples
  1446. * @return The function returns ARM_MATH_SUCCESS
  1447. */
  1448. arm_status arm_elementwise_add_s8(const int8_t *input_1_vect,
  1449. const int8_t *input_2_vect,
  1450. const int32_t input_1_offset,
  1451. const int32_t input_1_mult,
  1452. const int32_t input_1_shift,
  1453. const int32_t input_2_offset,
  1454. const int32_t input_2_mult,
  1455. const int32_t input_2_shift,
  1456. const int32_t left_shift,
  1457. int8_t *output,
  1458. const int32_t out_offset,
  1459. const int32_t out_mult,
  1460. const int32_t out_shift,
  1461. const int32_t out_activation_min,
  1462. const int32_t out_activation_max,
  1463. const uint32_t block_size);
  1464. /**
  1465. * @brief s8 element wise multiplication
  1466. * @param[in] input_1_vect pointer to input vector 1
  1467. * @param[in] input_2_vect pointer to input vector 2
  1468. * @param[in] input_1_offset offset for input 1. Range: Range: -127 to 128
  1469. * @param[in] input_2_offset offset for input 2. Range: Range: -127 to 128
  1470. * @param[in,out] output pointer to output vector
  1471. * @param[in] out_offset output offset
  1472. * @param[in] out_mult output multiplier
  1473. * @param[in] out_shift output shift
  1474. * @param[in] out_activation_min minimum value to clamp output to
  1475. * @param[in] out_activation_max maximum value to clamp output to
  1476. * @param[in] block_size number of samples
  1477. * @return The function returns ARM_MATH_SUCCESS
  1478. *
  1479. * @details Supported framework: TensorFlow Lite micro
  1480. */
  1481. arm_status arm_elementwise_mul_s8(const int8_t *input_1_vect,
  1482. const int8_t *input_2_vect,
  1483. const int32_t input_1_offset,
  1484. const int32_t input_2_offset,
  1485. int8_t *output,
  1486. const int32_t out_offset,
  1487. const int32_t out_mult,
  1488. const int32_t out_shift,
  1489. const int32_t out_activation_min,
  1490. const int32_t out_activation_max,
  1491. const uint32_t block_size);
  1492. /**
  1493. * @defgroup Acti Activation Functions
  1494. *
  1495. * Perform activation layers, including ReLU (Rectified Linear Unit),
  1496. * sigmoid and tanh
  1497. *
  1498. */
  1499. /**
  1500. * @brief Q7 RELU function
  1501. * @param[in,out] data pointer to input
  1502. * @param[in] size number of elements
  1503. * @return none.
  1504. */
  1505. void arm_relu_q7(q7_t *data, uint16_t size);
  1506. /**
  1507. * @brief s8 ReLU6 function
  1508. * @param[in,out] data pointer to input
  1509. * @param[in] size number of elements
  1510. */
  1511. void arm_relu6_s8(q7_t *data, uint16_t size);
  1512. /**
  1513. * @brief Q15 RELU function
  1514. * @param[in,out] data pointer to input
  1515. * @param[in] size number of elements
  1516. * @return none.
  1517. */
  1518. void arm_relu_q15(q15_t *data, uint16_t size);
  1519. /**
  1520. * @brief Q7 neural network activation function using direct table look-up
  1521. * @param[in,out] data pointer to input
  1522. * @param[in] size number of elements
  1523. * @param[in] int_width bit-width of the integer part, assume to be smaller than 3
  1524. * @param[in] type type of activation functions
  1525. * @return none.
  1526. */
  1527. void arm_nn_activations_direct_q7(q7_t * data, uint16_t size, uint16_t int_width,
  1528. arm_nn_activation_type type);
  1529. /**
  1530. * @brief Q15 neural network activation function using direct table look-up
  1531. * @param[in,out] data pointer to input
  1532. * @param[in] size number of elements
  1533. * @param[in] int_width bit-width of the integer part, assume to be smaller than 3
  1534. * @param[in] type type of activation functions
  1535. * @return none.
  1536. *
  1537. * @details
  1538. *
  1539. * This is the direct table look-up approach.
  1540. *
  1541. * Assume here the integer part of the fixed-point is <= 3.
  1542. * More than 3 just not making much sense, makes no difference with
  1543. * saturation followed by any of these activation functions.
  1544. */
  1545. void arm_nn_activations_direct_q15(q15_t * data, uint16_t size, uint16_t int_width,
  1546. arm_nn_activation_type type);
  1547. /**
  1548. * @defgroup Pooling Pooling Functions
  1549. *
  1550. * Perform pooling functions, including max pooling and average pooling
  1551. *
  1552. */
  1553. /**
  1554. * @brief Q7 max pooling function
  1555. * @param[in] Im_in pointer to input tensor
  1556. * @param[in] dim_im_in input tensor dimension
  1557. * @param[in] ch_im_in number of input tensor channels
  1558. * @param[in] dim_kernel filter kernel size
  1559. * @param[in] padding padding sizes
  1560. * @param[in] stride convolution stride
  1561. * @param[in] dim_im_out output tensor dimension
  1562. * @param[in,out] bufferA pointer to buffer space for input
  1563. * @param[in,out] Im_out pointer to output tensor
  1564. * @return none.
  1565. *
  1566. */
  1567. void arm_maxpool_q7_HWC(q7_t * Im_in,
  1568. const uint16_t dim_im_in,
  1569. const uint16_t ch_im_in,
  1570. const uint16_t dim_kernel,
  1571. const uint16_t padding,
  1572. const uint16_t stride,
  1573. const uint16_t dim_im_out,
  1574. q7_t * bufferA,
  1575. q7_t * Im_out);
  1576. /**
  1577. * @brief Q7 average pooling function
  1578. * @param[in] Im_in pointer to input tensor
  1579. * @param[in] dim_im_in input tensor dimension
  1580. * @param[in] ch_im_in number of input tensor channels
  1581. * @param[in] dim_kernel filter kernel size
  1582. * @param[in] padding padding sizes
  1583. * @param[in] stride convolution stride
  1584. * @param[in] dim_im_out output tensor dimension
  1585. * @param[in,out] bufferA pointer to buffer space for input
  1586. * @param[in,out] Im_out pointer to output tensor
  1587. * @return none.
  1588. *
  1589. */
  1590. void arm_avepool_q7_HWC(q7_t * Im_in,
  1591. const uint16_t dim_im_in,
  1592. const uint16_t ch_im_in,
  1593. const uint16_t dim_kernel,
  1594. const uint16_t padding,
  1595. const uint16_t stride,
  1596. const uint16_t dim_im_out,
  1597. q7_t * bufferA,
  1598. q7_t * Im_out);
  1599. /**
  1600. * @brief s8 average pooling function
  1601. * @param[in] dim_src_height input tensor dimension
  1602. * @param[in] dim_src_width input tensor dimension
  1603. * @param[in] dim_dst_height output tensor dimension
  1604. * @param[in] dim_dst_width output tensor dimension
  1605. * @param[in] stride_height stride along y
  1606. * @param[in] stride_width stride along x
  1607. * @param[in] dim_kernel_height filter kernel size along y
  1608. * @param[in] dim_kernel_width filter kernel size along x
  1609. * @param[in] padding_height padding size along y
  1610. * @param[in] padding_width padding size along x
  1611. * @param[in] act_min Min clamping
  1612. * @param[in] act_max Max clamping
  1613. * @param[in] ch_src number of input tensor channels
  1614. * @param[in,out] src pointer to input tensor
  1615. * @param[in] bufferA temporary buffer used for optimization and is necessary when
  1616. * ARM_MATH_DSP is defined.
  1617. * Required space: (ch_src * dim_dst_width) * sizeof(q15_t) bytes
  1618. * Use arm_avgpool_s8_get_buffer_size() to get the size
  1619. * @param[in,out] dst pointer to output tensor
  1620. * @return The function returns one of the following
  1621. * <code>ARM_MATH_SIZE_MISMATCH</code> - Unsupported dimension of tensors
  1622. * <code>ARM_MATH_SUCCESS</code> - Successful operation
  1623. * <code>ARM_MATH_ARGUMENT_ERROR</code> - Implementation not available
  1624. *
  1625. * @details
  1626. * - Supported Framework: TensorFlow Lite
  1627. *
  1628. */
  1629. arm_status arm_avgpool_s8(const int dim_src_height,
  1630. const int dim_src_width,
  1631. const int dim_dst_height,
  1632. const int dim_dst_width,
  1633. const int stride_height,
  1634. const int stride_width,
  1635. const int dim_kernel_height,
  1636. const int dim_kernel_width,
  1637. const int padding_height,
  1638. const int padding_width,
  1639. const int act_min,
  1640. const int act_max,
  1641. const int ch_src,
  1642. int8_t *src,
  1643. int16_t *bufferA,
  1644. int8_t *dst);
  1645. /**
  1646. * @brief Get the required buffer size for S8 average pooling function
  1647. * @param[in] dim_dst_width output tensor dimension
  1648. * @param[in] ch_src number of input tensor channels
  1649. * @return The function returns required buffer size
  1650. *
  1651. */
  1652. int32_t arm_avgpool_s8_get_buffer_size(const int dim_dst_width,
  1653. const int ch_src);
  1654. /**
  1655. * @brief s8 DSP optimized max pooling function
  1656. * @param[in] input_y input tensor dimension along y
  1657. * @param[in] input_x input tensor dimension along x
  1658. * @param[in] output_y output tensor dimension along y
  1659. * @param[in] output_x output tensor dimension along x
  1660. * @param[in] stride_y stride along y
  1661. * @param[in] stride_x stride along x
  1662. * @param[in] kernel_y filter kernel size along y
  1663. * @param[in] kernel_x filter kernel size along x
  1664. * @param[in] pad_y padding size along y
  1665. * @param[in] pad_x padding size along x
  1666. * @param[in] act_min Activation min. Lower limit to clamp output to. Range: int8
  1667. * @param[in] act_max Activation max. Upper limit to clamp output to. Range: int8
  1668. * @param[in] depth number of input channels
  1669. * @param[in] input pointer to input tensor
  1670. * @param[in] tmp_buffer Not used.
  1671. * @param[in,out] output pointer to output tensor
  1672. * @return The function returns one of the following
  1673. * <code>ARM_MATH_SIZE_MISMATCH</code> - Unsupported dimension of tensors
  1674. * <code>ARM_MATH_SUCCESS</code> - Successful operation
  1675. * <code>ARM_MATH_ARGUMENT_ERROR</code> - Implementation not available
  1676. * @note The input data is corrupted by this function.
  1677. * @details This optimized implementation is recommended when depth is >= 4 and dimensions are large.
  1678. *
  1679. */
  1680. arm_status arm_max_pool_s8_opt(const uint16_t input_y,
  1681. const uint16_t input_x,
  1682. const uint16_t output_y,
  1683. const uint16_t output_x,
  1684. const uint16_t stride_y,
  1685. const uint16_t stride_x,
  1686. const uint16_t kernel_y,
  1687. const uint16_t kernel_x,
  1688. const uint16_t pad_y,
  1689. const uint16_t pad_x,
  1690. const int8_t act_min,
  1691. const int8_t act_max,
  1692. const uint16_t depth,
  1693. int8_t *input,
  1694. int16_t *tmp_buffer,
  1695. int8_t *output);
  1696. /**
  1697. * @brief s8 pure C max pooling function
  1698. * @param[in] input_y input tensor dimension along y
  1699. * @param[in] input_x input tensor dimension along x
  1700. * @param[in] output_y output tensor dimension along y
  1701. * @param[in] output_x output tensor dimension along x
  1702. * @param[in] stride_y stride along y
  1703. * @param[in] stride_x stride along x
  1704. * @param[in] kernel_y filter kernel size along y
  1705. * @param[in] kernel_x filter kernel size along x
  1706. * @param[in] pad_y padding size along y
  1707. * @param[in] pad_x padding size along x
  1708. * @param[in] act_min Activation min. Lower limit to clamp output to. Range: int8
  1709. * @param[in] act_max Activation max. Upper limit to clamp output to. Range: int8
  1710. * @param[in] channel_in number of input channels
  1711. * @param[in] input pointer to input tensor
  1712. * @param[in] tmp_buffer Not used.
  1713. * @param[in,out] output pointer to output tensor
  1714. * @return The function returns one of the following
  1715. * <code>ARM_MATH_SIZE_MISMATCH</code> - Unsupported dimension of tensors
  1716. * <code>ARM_MATH_SUCCESS</code> - Successful operation
  1717. * <code>ARM_MATH_ARGUMENT_ERROR</code> - Implementation not available
  1718. *
  1719. * @details
  1720. * - This basic implementation is recommended when number of channels is less than 4 and/or
  1721. * dimensions are small.
  1722. *
  1723. */
  1724. arm_status arm_max_pool_s8(const uint16_t input_y,
  1725. const uint16_t input_x,
  1726. const uint16_t output_y,
  1727. const uint16_t output_x,
  1728. const uint16_t stride_y,
  1729. const uint16_t stride_x,
  1730. const uint16_t kernel_y,
  1731. const uint16_t kernel_x,
  1732. const uint16_t pad_y,
  1733. const uint16_t pad_x,
  1734. const int8_t act_min,
  1735. const int8_t act_max,
  1736. const uint16_t channel_in,
  1737. int8_t *input,
  1738. int16_t *tmp_buffer,
  1739. int8_t *output);
  1740. /**
  1741. * @defgroup Softmax Softmax Functions
  1742. *
  1743. * EXP(2) based softmax functions.
  1744. *
  1745. */
  1746. /**
  1747. * @brief Q7 softmax function
  1748. * @param[in] vec_in pointer to input vector
  1749. * @param[in] dim_vec input vector dimension
  1750. * @param[out] p_out pointer to output vector
  1751. *
  1752. * @note This function is an optimized version which is not bit-accurate with
  1753. * TensorFlow Lite's kernel
  1754. *
  1755. */
  1756. void arm_softmax_q7(const q7_t * vec_in, const uint16_t dim_vec, q7_t * p_out);
  1757. /**
  1758. * @brief Q7 softmax function with batch parameter
  1759. * @param[in] vec_in pointer to input vector
  1760. * @param[in] nb_batches number of batches
  1761. * @param[in] dim_vec input vector dimension
  1762. * @param[out] p_out pointer to output vector
  1763. * @return none.
  1764. *
  1765. * @note This function is an optimized version which is not bit-accurate with
  1766. * TensorFlow Lite's kernel
  1767. *
  1768. */
  1769. void arm_softmax_with_batch_q7(const q7_t * vec_in, const uint16_t nb_batches,const uint16_t dim_vec, q7_t * p_out );
  1770. /**
  1771. * @brief Q15 softmax function
  1772. * @param[in] vec_in pointer to input vector
  1773. * @param[in] dim_vec input vector dimension
  1774. * @param[out] p_out pointer to output vector
  1775. * @return none.
  1776. *
  1777. * @note This function is an optimized version which is not bit-accurate with
  1778. * TensorFlow Lite's kernel
  1779. *
  1780. */
  1781. void arm_softmax_q15(const q15_t * vec_in, const uint16_t dim_vec, q15_t * p_out);
  1782. /**
  1783. * @brief S8 softmax function
  1784. * @param[in] input Pointer to the input tensor
  1785. * @param[in] num_rows Number of rows in the input tensor
  1786. * @param[in] row_size Number of elements in each input row
  1787. * @param[in] mult Input quantization multiplier
  1788. * @param[in] shift Input quantization shift within the range [0, 31]
  1789. * @param[in] diff_min Minimum difference with max in row. Used to check if
  1790. * the quantized exponential operation can be performed
  1791. * @param[out] output Pointer to the output tensor
  1792. *
  1793. * @note Supported framework: TensorFlow Lite micro (bit-accurate)
  1794. *
  1795. */
  1796. void arm_softmax_s8(const int8_t *input,
  1797. const int32_t num_rows,
  1798. const int32_t row_size,
  1799. const int32_t mult,
  1800. const int32_t shift,
  1801. const int8_t diff_min,
  1802. int8_t *output);
  1803. /**
  1804. * @brief U8 softmax function
  1805. * @param[in] input Pointer to the input tensor
  1806. * @param[in] num_rows Number of rows in the input tensor
  1807. * @param[in] row_size Number of elements in each input row
  1808. * @param[in] mult Input quantization multiplier
  1809. * @param[in] shift Input quantization shift within the range [0, 31]
  1810. * @param[in] diff_min Minimum difference with max in row. Used to check if
  1811. * the quantized exponential operation can be performed
  1812. * @param[out] output Pointer to the output tensor
  1813. *
  1814. * @note Supported framework: TensorFlow Lite micro (bit-accurate)
  1815. *
  1816. */
  1817. void arm_softmax_u8(const uint8_t *input,
  1818. const int32_t num_rows,
  1819. const int32_t row_size,
  1820. const int32_t mult,
  1821. const int32_t shift,
  1822. const int32_t diff_min,
  1823. uint8_t *output);
  1824. /**
  1825. * @brief uint8 depthwise convolution function with asymmetric quantization for even number of channel multiplier
  1826. * and input channels. Unless specified otherwise, arguments are mandatory.
  1827. *
  1828. * @param[in] input Pointer to input tensor
  1829. * @param[in] input_x Width of input tensor
  1830. * @param[in] input_y Height of input tensor
  1831. * @param[in] input_ch Channels in input tensor
  1832. * @param[in] kernel Pointer to kernel weights
  1833. * @param[in] kernel_x Width of kernel
  1834. * @param[in] kernel_y Height of kernel
  1835. * @param[in] ch_mult Number of channel multiplier
  1836. * @param[in] pad_x Padding sizes x
  1837. * @param[in] pad_y Padding sizes y
  1838. * @param[in] stride_x Convolution stride along the width
  1839. * @param[in] stride_y Convolution stride along the height
  1840. * @param[in] dilation_x Dilation along width. Not used and intended for future enhancement.
  1841. * @param[in] dilation_y Dilation along height. Not used and intended for future enhancement.
  1842. * @param[in] bias Pointer to optional bias values. If no bias is
  1843. * availble, NULL is expected
  1844. * @param[in] input_offset Input tensor zero offset
  1845. * @param[in] filter_offset Kernel tensor zero offset
  1846. * @param[in] output_offset Output tensor zero offset
  1847. * @param[in,out] output Pointer to output tensor
  1848. * @param[in] output_x Width of output tensor
  1849. * @param[in] output_y Height of output tensor
  1850. * @param[in] output_activation_min Minimum value to clamp the output to. Range : {0, 255}
  1851. * @param[in] output_activation_max Minimum value to clamp the output to. Range : {0, 255}
  1852. * @param[in] out_shift Amount of right-shift for output
  1853. * @param[in] out_mult Output multiplier for requantization
  1854. * @return The function returns one of the following
  1855. * <code>ARM_MATH_SIZE_MISMATCH</code> - Unsupported dimension of tensors
  1856. * <code>ARM_MATH_SUCCESS</code> - Successful operation
  1857. * <code>ARM_MATH_ARGUMENT_ERROR</code> - Implementation not available
  1858. *
  1859. * <b> Input constraints</b>
  1860. * ch_mult is multiple of 2
  1861. * kernel_x is multiple of 2
  1862. *
  1863. */
  1864. arm_status arm_depthwise_conv_u8_basic_ver1(const uint8_t *input,
  1865. const uint16_t input_x,
  1866. const uint16_t input_y,
  1867. const uint16_t input_ch,
  1868. const uint8_t *kernel,
  1869. const uint16_t kernel_x,
  1870. const uint16_t kernel_y,
  1871. const int16_t ch_mult,
  1872. const int16_t pad_x,
  1873. const int16_t pad_y,
  1874. const int16_t stride_x,
  1875. const int16_t stride_y,
  1876. const int16_t dilation_x,
  1877. const int16_t dilation_y,
  1878. const int32_t *bias,
  1879. const int32_t input_offset,
  1880. const int32_t filter_offset,
  1881. const int32_t output_offset,
  1882. uint8_t *output,
  1883. const uint16_t output_x,
  1884. const uint16_t output_y,
  1885. const int32_t output_activation_min,
  1886. const int32_t output_activation_max,
  1887. const int32_t out_shift,
  1888. const int32_t out_mult);
  1889. /**
  1890. * @defgroup Reshape Reshape Functions
  1891. *
  1892. */
  1893. /**
  1894. * @brief Reshape a s8 vector into another with different shape
  1895. * @param[in] input points to the s8 input vector
  1896. * @param[out] output points to the s8 output vector
  1897. * @param[in] total_size total size of the input and output vectors in bytes
  1898. *
  1899. * @note The output is expected to be in a memory area that does not overlap with the input's
  1900. *
  1901. */
  1902. void arm_reshape_s8(const int8_t *input,
  1903. int8_t *output,
  1904. const uint32_t total_size);
  1905. /**
  1906. * @defgroup Concatenation Concatenation Functions
  1907. *
  1908. */
  1909. /**
  1910. * @brief int8/uint8 concatenation function to be used for concatenating N-tensors along the X axis
  1911. * This function should be called for each input tensor to concatenate. The argument offset_x
  1912. * will be used to store the input tensor in the correct position in the output tensor
  1913. *
  1914. * i.e. offset_x = 0
  1915. * for(i = 0 i < num_input_tensors; ++i)
  1916. * {
  1917. * arm_concatenation_s8_x(&input[i], ..., &output, ..., ..., offset_x)
  1918. * offset_x += input_x[i]
  1919. * }
  1920. *
  1921. * This function assumes that the output tensor has:
  1922. * -# The same height of the input tensor
  1923. * -# The same number of channels of the input tensor
  1924. * -# The same batch size of the input tensor
  1925. *
  1926. * Unless specified otherwise, arguments are mandatory.
  1927. *
  1928. * @note This function, data layout independent, can be used to concatenate either int8 or uint8 tensors because does not involve any arithmetic operation
  1929. *
  1930. * @param[in] input Pointer to input tensor
  1931. * @param[in] input_x Width of input tensor
  1932. * @param[in] input_y Height of input tensor
  1933. * @param[in] input_z Channels in input tensor
  1934. * @param[in] input_w Batch size in input tensor
  1935. * @param[out] output Pointer to output tensor
  1936. * @param[in] output_x Width of output tensor
  1937. * @param[in] offset_x The offset (in number of elements) on the X axis to start concatenating the input tensor
  1938. * It is user responsibility to provide the correct value
  1939. *
  1940. * <b> Input constraints</b>
  1941. * offset_x is less than output_x
  1942. *
  1943. */
  1944. void arm_concatenation_s8_x(const int8_t *input,
  1945. const uint16_t input_x,
  1946. const uint16_t input_y,
  1947. const uint16_t input_z,
  1948. const uint16_t input_w,
  1949. int8_t *output,
  1950. const uint16_t output_x,
  1951. const uint32_t offset_x);
  1952. /**
  1953. * @brief int8/uint8 concatenation function to be used for concatenating N-tensors along the Y axis
  1954. * This function should be called for each input tensor to concatenate. The argument offset_y
  1955. * will be used to store the input tensor in the correct position in the output tensor
  1956. *
  1957. * i.e. offset_y = 0
  1958. * for(i = 0 i < num_input_tensors; ++i)
  1959. * {
  1960. * arm_concatenation_s8_y(&input[i], ..., &output, ..., ..., offset_y)
  1961. * offset_y += input_y[i]
  1962. * }
  1963. *
  1964. * This function assumes that the output tensor has:
  1965. * -# The same width of the input tensor
  1966. * -# The same number of channels of the input tensor
  1967. * -# The same batch size of the input tensor
  1968. *
  1969. * Unless specified otherwise, arguments are mandatory.
  1970. *
  1971. * @note This function, data layout independent, can be used to concatenate either int8 or uint8 tensors because does not involve any arithmetic operation
  1972. *
  1973. * @param[in] input Pointer to input tensor
  1974. * @param[in] input_x Width of input tensor
  1975. * @param[in] input_y Height of input tensor
  1976. * @param[in] input_z Channels in input tensor
  1977. * @param[in] input_w Batch size in input tensor
  1978. * @param[out] output Pointer to output tensor
  1979. * @param[in] output_y Height of output tensor
  1980. * @param[in] offset_y The offset on the Y axis to start concatenating the input tensor
  1981. * It is user responsibility to provide the correct value
  1982. *
  1983. * <b> Input constraints</b>
  1984. * offset_y is less than output_y
  1985. *
  1986. */
  1987. void arm_concatenation_s8_y(const int8_t *input,
  1988. const uint16_t input_x,
  1989. const uint16_t input_y,
  1990. const uint16_t input_z,
  1991. const uint16_t input_w,
  1992. int8_t *output,
  1993. const uint16_t output_y,
  1994. const uint32_t offset_y);
  1995. /**
  1996. * @brief int8/uint8 concatenation function to be used for concatenating N-tensors along the Z axis
  1997. * This function should be called for each input tensor to concatenate. The argument offset_z
  1998. * will be used to store the input tensor in the correct position in the output tensor
  1999. *
  2000. * i.e. offset_z = 0
  2001. * for(i = 0 i < num_input_tensors; ++i)
  2002. * {
  2003. * arm_concatenation_s8_z(&input[i], ..., &output, ..., ..., offset_z)
  2004. * offset_z += input_z[i]
  2005. * }
  2006. *
  2007. * This function assumes that the output tensor has:
  2008. * -# The same width of the input tensor
  2009. * -# The same height of the input tensor
  2010. * -# The same batch size of the input tensor
  2011. *
  2012. * Unless specified otherwise, arguments are mandatory.
  2013. *
  2014. * @note This function, data layout independent, can be used to concatenate either int8 or uint8 tensors because does not involve any arithmetic operation
  2015. *
  2016. * @param[in] input Pointer to input tensor
  2017. * @param[in] input_x Width of input tensor
  2018. * @param[in] input_y Height of input tensor
  2019. * @param[in] input_z Channels in input tensor
  2020. * @param[in] input_w Batch size in input tensor
  2021. * @param[out] output Pointer to output tensor
  2022. * @param[in] output_z Channels in output tensor
  2023. * @param[in] offset_z The offset on the Z axis to start concatenating the input tensor
  2024. * It is user responsibility to provide the correct value
  2025. *
  2026. * <b> Input constraints</b>
  2027. * offset_z is less than output_z
  2028. *
  2029. */
  2030. void arm_concatenation_s8_z(const int8_t *input,
  2031. const uint16_t input_x,
  2032. const uint16_t input_y,
  2033. const uint16_t input_z,
  2034. const uint16_t input_w,
  2035. int8_t *output,
  2036. const uint16_t output_z,
  2037. const uint32_t offset_z);
  2038. /**
  2039. * @brief int8/uint8 concatenation function to be used for concatenating N-tensors along the W axis (Batch size)
  2040. * This function should be called for each input tensor to concatenate. The argument offset_w
  2041. * will be used to store the input tensor in the correct position in the output tensor
  2042. *
  2043. * i.e. offset_w = 0
  2044. * for(i = 0 i < num_input_tensors; ++i)
  2045. * {
  2046. * arm_concatenation_s8_w(&input[i], ..., &output, ..., ..., offset_w)
  2047. * offset_w += input_w[i]
  2048. * }
  2049. *
  2050. * This function assumes that the output tensor has:
  2051. * -# The same width of the input tensor
  2052. * -# The same height of the input tensor
  2053. * -# The same number o channels of the input tensor
  2054. *
  2055. * Unless specified otherwise, arguments are mandatory.
  2056. *
  2057. * @note This function, data layout independent, can be used to concatenate either int8 or uint8 tensors because does not involve any arithmetic operation
  2058. *
  2059. * @param[in] input Pointer to input tensor
  2060. * @param[in] input_x Width of input tensor
  2061. * @param[in] input_y Height of input tensor
  2062. * @param[in] input_z Channels in input tensor
  2063. * @param[in] input_w Batch size in input tensor
  2064. * @param[out] output Pointer to output tensor
  2065. * @param[in] offset_w The offset on the W axis to start concatenating the input tensor
  2066. * It is user responsibility to provide the correct value
  2067. *
  2068. */
  2069. void arm_concatenation_s8_w(const int8_t *input,
  2070. const uint16_t input_x,
  2071. const uint16_t input_y,
  2072. const uint16_t input_z,
  2073. const uint16_t input_w,
  2074. int8_t *output,
  2075. const uint32_t offset_w);
  2076. #ifdef __cplusplus
  2077. }
  2078. #endif
  2079. #endif