1 /*
2  * SPDX-FileCopyrightText: Copyright 2024, Arm Limited and/or its affiliates <open-source-office@arm.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Licensed under the Apache License, Version 2.0 (the License); you may
7  * not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 /* ----------------------------------------------------------------------
20  * Project:      CMSIS NN Library
21  * Title:        arm_lstm_unidirectional_s16.c
22  * Description:  S16 LSTM function with S16 gate output
23  *
24  * $Date:        26 March 2024
25  * $Revision:    V.1.0.0
26  *
27  * Target Processor:  Cortex-M processors
28  *
29  * -------------------------------------------------------------------- */
30 
31 #include "arm_nnfunctions.h"
32 #include "arm_nnsupportfunctions.h"
33 /**
34  * @ingroup Public
35  */
36 
37 /**
38  * @addtogroup LSTM
39  * @{
40  */
41 
42 /*
43  * S16 LSTM function for TensorFlow Lite with S16 gate output
44  *
45  * Refer to header file for details.
46  *
47  */
48 
arm_lstm_unidirectional_s16(const int16_t * input,int16_t * output,const cmsis_nn_lstm_params * params,cmsis_nn_lstm_context * buffers)49 arm_cmsis_nn_status arm_lstm_unidirectional_s16(const int16_t *input,
50                                                 int16_t *output,
51                                                 const cmsis_nn_lstm_params *params,
52                                                 cmsis_nn_lstm_context *buffers)
53 {
54 
55     int16_t *hidden_in = NULL;
56     memset(buffers->cell_state, 0, params->batch_size * params->hidden_size * sizeof(int16_t));
57     if (params->time_major)
58     {
59         // First dimension is time, input/output for each time step is stored continously in memory
60         for (int t = 0; t < params->time_steps; t++)
61         {
62             const int16_t *data_in = input + (t * params->batch_size * params->input_size);
63             int16_t *hidden_out = output + (t * params->batch_size * params->hidden_size);
64             arm_cmsis_nn_status status = arm_nn_lstm_step_s16(data_in, hidden_in, hidden_out, params, buffers, 1);
65             if (status != ARM_CMSIS_NN_SUCCESS)
66             {
67                 return status;
68             }
69             // Output is used as recurrent input/hidden state for the next timestep.
70             hidden_in = &hidden_out[0];
71         }
72     }
73     else
74     {
75         // First dimension is time, add batch_offset to jump in memory for each batch
76         for (int t = 0; t < params->time_steps; t++)
77         {
78             const int16_t *data_in = input + (t * params->input_size);
79             int16_t *hidden_out = output + (t * params->hidden_size);
80             arm_cmsis_nn_status status =
81                 arm_nn_lstm_step_s16(data_in, hidden_in, hidden_out, params, buffers, params->time_steps);
82             if (status != ARM_CMSIS_NN_SUCCESS)
83             {
84                 return status;
85             }
86             // Output is used as recurrent input/hidden state for the next timestep.
87             hidden_in = &hidden_out[0];
88         }
89     }
90     return ARM_CMSIS_NN_SUCCESS;
91 }
92 
93 /**
94  * @} end of LSTM group
95  */
96