xref: /aosp_15_r20/external/android-nn-driver/test/1.3/QLstm.cpp (revision 3e777be0405cee09af5d5785ff37f7cfb5bee59a)
1*3e777be0SXin Li //
2*3e777be0SXin Li // Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
3*3e777be0SXin Li // SPDX-License-Identifier: MIT
4*3e777be0SXin Li //
5*3e777be0SXin Li 
6*3e777be0SXin Li #include "../DriverTestHelpers.hpp"
7*3e777be0SXin Li 
8*3e777be0SXin Li #include <1.3/HalPolicy.hpp>
9*3e777be0SXin Li 
10*3e777be0SXin Li #include <array>
11*3e777be0SXin Li 
12*3e777be0SXin Li using ArmnnDriver   = armnn_driver::ArmnnDriver;
13*3e777be0SXin Li using DriverOptions = armnn_driver::DriverOptions;
14*3e777be0SXin Li 
15*3e777be0SXin Li using namespace driverTestHelpers;
16*3e777be0SXin Li using namespace android::hardware;
17*3e777be0SXin Li 
18*3e777be0SXin Li using HalPolicy = hal_1_3::HalPolicy;
19*3e777be0SXin Li 
20*3e777be0SXin Li static const float TOLERANCE = 1.0f;
21*3e777be0SXin Li 
22*3e777be0SXin Li namespace
23*3e777be0SXin Li {
24*3e777be0SXin Li 
25*3e777be0SXin Li template<typename T>
CreateRequestArgument(const std::vector<T> & value,unsigned int poolIndex)26*3e777be0SXin Li RequestArgument CreateRequestArgument(const std::vector<T>& value, unsigned int poolIndex)
27*3e777be0SXin Li {
28*3e777be0SXin Li     V1_0::DataLocation inputInloc = {};
29*3e777be0SXin Li     inputInloc.poolIndex = poolIndex;
30*3e777be0SXin Li     inputInloc.offset = 0;
31*3e777be0SXin Li     inputInloc.length = value.size() * sizeof(T);
32*3e777be0SXin Li     RequestArgument inputRequestArgument = {};
33*3e777be0SXin Li     inputRequestArgument.location = inputInloc;
34*3e777be0SXin Li     inputRequestArgument.dimensions = hidl_vec<uint32_t>{};
35*3e777be0SXin Li     return inputRequestArgument;
36*3e777be0SXin Li }
37*3e777be0SXin Li 
38*3e777be0SXin Li // Helper function to create an OperandLifeTime::NO_VALUE for testing.
39*3e777be0SXin Li // To be used on optional input operands that have no values - these are valid and should be tested.
CreateNoValueLifeTime(const hidl_vec<uint32_t> & dimensions)40*3e777be0SXin Li HalPolicy::OperandLifeTime CreateNoValueLifeTime(const hidl_vec<uint32_t>& dimensions)
41*3e777be0SXin Li {
42*3e777be0SXin Li     // Only create a NO_VALUE for optional operands that have no elements
43*3e777be0SXin Li     if (dimensions.size() == 0 || dimensions[0] == 0)
44*3e777be0SXin Li     {
45*3e777be0SXin Li         return HalPolicy::OperandLifeTime::NO_VALUE;
46*3e777be0SXin Li     }
47*3e777be0SXin Li     return HalPolicy::OperandLifeTime::CONSTANT_COPY;
48*3e777be0SXin Li }
49*3e777be0SXin Li 
ExecuteModel(const armnn_driver::hal_1_3::HalPolicy::Model & model,armnn_driver::ArmnnDriver & driver,const V1_0::Request & request)50*3e777be0SXin Li void ExecuteModel(const armnn_driver::hal_1_3::HalPolicy::Model& model,
51*3e777be0SXin Li                   armnn_driver::ArmnnDriver& driver,
52*3e777be0SXin Li                   const V1_0::Request& request)
53*3e777be0SXin Li {
54*3e777be0SXin Li     android::sp<V1_3::IPreparedModel> preparedModel = PrepareModel_1_3(model, driver);
55*3e777be0SXin Li     if (preparedModel.get() != nullptr)
56*3e777be0SXin Li     {
57*3e777be0SXin Li         Execute(preparedModel, request);
58*3e777be0SXin Li     }
59*3e777be0SXin Li }
60*3e777be0SXin Li 
61*3e777be0SXin Li // Add our own tests here since we skip the qlstm tests which Google supplies (because of non-const weights)
QLstmTestImpl(const hidl_vec<uint32_t> & inputDimensions,const std::vector<int8_t> & inputValue,const hidl_vec<uint32_t> & inputToInputWeightsDimensions,const std::vector<int8_t> & inputToInputWeightsValue,const hidl_vec<uint32_t> & inputToForgetWeightsDimensions,const std::vector<int8_t> & inputToForgetWeightsValue,const hidl_vec<uint32_t> & inputToCellWeightsDimensions,const std::vector<int8_t> & inputToCellWeightsValue,const hidl_vec<uint32_t> & inputToOutputWeightsDimensions,const std::vector<int8_t> & inputToOutputWeightsValue,const hidl_vec<uint32_t> & recurrentToInputWeightsDimensions,const std::vector<int8_t> & recurrentToInputWeightsValue,const hidl_vec<uint32_t> & recurrentToForgetWeightsDimensions,const std::vector<int8_t> & recurrentToForgetWeightsValue,const hidl_vec<uint32_t> & recurrentToCellWeightsDimensions,const std::vector<int8_t> & recurrentToCellWeightsValue,const hidl_vec<uint32_t> & recurrentToOutputWeightsDimensions,const std::vector<int8_t> & recurrentToOutputWeightsValue,const hidl_vec<uint32_t> & cellToInputWeightsDimensions,const std::vector<int16_t> & cellToInputWeightsValue,const hidl_vec<uint32_t> & cellToForgetWeightsDimensions,const std::vector<int16_t> & cellToForgetWeightsValue,const hidl_vec<uint32_t> & cellToOutputWeightsDimensions,const std::vector<int16_t> & cellToOutputWeightsValue,const hidl_vec<uint32_t> & inputGateBiasDimensions,const std::vector<int32_t> & inputGateBiasValue,const hidl_vec<uint32_t> & forgetGateBiasDimensions,const std::vector<int32_t> & forgetGateBiasValue,const hidl_vec<uint32_t> & cellBiasDimensions,const std::vector<int32_t> & cellBiasValue,const hidl_vec<uint32_t> & outputGateBiasDimensions,const std::vector<int32_t> & outputGateBiasValue,const hidl_vec<uint32_t> & projectionWeightsDimensions,const std::vector<int8_t> & projectionWeightsValue,const hidl_vec<uint32_t> & projectionBiasDimensions,const std::vector<int32_t> & projectionBiasValue,const hidl_vec<uint32_t> & outputPreviousTimeStepInDimensions,const std::vector<int8_t> & outputPreviousTimeStepInValue,const hidl_vec<uint32_t> & cellStatePreviousTimeStepInDimensions,const std::vector<int16_t> & cellStatePreviousTimeStepInValue,const hidl_vec<uint32_t> & inputLayerNormWeightsDimensions,const std::vector<int16_t> & inputLayerNormWeightsValue,const hidl_vec<uint32_t> & forgetLayerNormWeightsDimensions,const std::vector<int16_t> & forgetLayerNormWeightsValue,const hidl_vec<uint32_t> & cellLayerNormWeightsDimensions,const std::vector<int16_t> & cellLayerNormWeightsValue,const hidl_vec<uint32_t> & outputLayerNormWeightsDimensions,const std::vector<int16_t> & outputLayerNormWeightsValue,const float & cellClipValue,const float & projectionClipValue,const float & matMulInputGateValue,const float & matMulForgetGateValue,const float & matMulCellGateValue,const float & matMulOutputGateValue,const int32_t & projInputZeroPointValue,const float & projInputScaleValue,const hidl_vec<uint32_t> & outputStateOutDimensions,const std::vector<int8_t> & outputStateOutValue,const hidl_vec<uint32_t> & cellStateOutDimensions,const std::vector<int16_t> & cellStateOutValue,const hidl_vec<uint32_t> & outputDimensions,const std::vector<int8_t> & outputValue,armnn::Compute compute)62*3e777be0SXin Li void QLstmTestImpl(const hidl_vec<uint32_t>&   inputDimensions,
63*3e777be0SXin Li                    const std::vector<int8_t>&   inputValue,
64*3e777be0SXin Li                    const hidl_vec<uint32_t>&    inputToInputWeightsDimensions,
65*3e777be0SXin Li                    const std::vector<int8_t>&   inputToInputWeightsValue,
66*3e777be0SXin Li                    const hidl_vec<uint32_t>&    inputToForgetWeightsDimensions,
67*3e777be0SXin Li                    const std::vector<int8_t>&   inputToForgetWeightsValue,
68*3e777be0SXin Li                    const hidl_vec<uint32_t>&    inputToCellWeightsDimensions,
69*3e777be0SXin Li                    const std::vector<int8_t>&   inputToCellWeightsValue,
70*3e777be0SXin Li                    const hidl_vec<uint32_t>&    inputToOutputWeightsDimensions,
71*3e777be0SXin Li                    const std::vector<int8_t>&   inputToOutputWeightsValue,
72*3e777be0SXin Li                    const hidl_vec<uint32_t>&    recurrentToInputWeightsDimensions,
73*3e777be0SXin Li                    const std::vector<int8_t>&   recurrentToInputWeightsValue,
74*3e777be0SXin Li                    const hidl_vec<uint32_t>&    recurrentToForgetWeightsDimensions,
75*3e777be0SXin Li                    const std::vector<int8_t>&   recurrentToForgetWeightsValue,
76*3e777be0SXin Li                    const hidl_vec<uint32_t>&    recurrentToCellWeightsDimensions,
77*3e777be0SXin Li                    const std::vector<int8_t>&   recurrentToCellWeightsValue,
78*3e777be0SXin Li                    const hidl_vec<uint32_t>&    recurrentToOutputWeightsDimensions,
79*3e777be0SXin Li                    const std::vector<int8_t>&   recurrentToOutputWeightsValue,
80*3e777be0SXin Li                    const hidl_vec<uint32_t>&    cellToInputWeightsDimensions,
81*3e777be0SXin Li                    const std::vector<int16_t>&  cellToInputWeightsValue,
82*3e777be0SXin Li                    const hidl_vec<uint32_t>&    cellToForgetWeightsDimensions,
83*3e777be0SXin Li                    const std::vector<int16_t>&  cellToForgetWeightsValue,
84*3e777be0SXin Li                    const hidl_vec<uint32_t>&    cellToOutputWeightsDimensions,
85*3e777be0SXin Li                    const std::vector<int16_t>&  cellToOutputWeightsValue,
86*3e777be0SXin Li                    const hidl_vec<uint32_t>&    inputGateBiasDimensions,
87*3e777be0SXin Li                    const std::vector<int32_t>&  inputGateBiasValue,
88*3e777be0SXin Li                    const hidl_vec<uint32_t>&    forgetGateBiasDimensions,
89*3e777be0SXin Li                    const std::vector<int32_t>&  forgetGateBiasValue,
90*3e777be0SXin Li                    const hidl_vec<uint32_t>&    cellBiasDimensions,
91*3e777be0SXin Li                    const std::vector<int32_t>&  cellBiasValue,
92*3e777be0SXin Li                    const hidl_vec<uint32_t>&    outputGateBiasDimensions,
93*3e777be0SXin Li                    const std::vector<int32_t>&  outputGateBiasValue,
94*3e777be0SXin Li                    const hidl_vec<uint32_t>&    projectionWeightsDimensions,
95*3e777be0SXin Li                    const std::vector<int8_t>&   projectionWeightsValue,
96*3e777be0SXin Li                    const hidl_vec<uint32_t>&    projectionBiasDimensions,
97*3e777be0SXin Li                    const std::vector<int32_t>&  projectionBiasValue,
98*3e777be0SXin Li                    const hidl_vec<uint32_t>&    outputPreviousTimeStepInDimensions,
99*3e777be0SXin Li                    const std::vector<int8_t>&   outputPreviousTimeStepInValue,
100*3e777be0SXin Li                    const hidl_vec<uint32_t>&    cellStatePreviousTimeStepInDimensions,
101*3e777be0SXin Li                    const std::vector<int16_t>&  cellStatePreviousTimeStepInValue,
102*3e777be0SXin Li                    const hidl_vec<uint32_t>&    inputLayerNormWeightsDimensions,
103*3e777be0SXin Li                    const std::vector<int16_t>&  inputLayerNormWeightsValue,
104*3e777be0SXin Li                    const hidl_vec<uint32_t>&    forgetLayerNormWeightsDimensions,
105*3e777be0SXin Li                    const std::vector<int16_t>&  forgetLayerNormWeightsValue,
106*3e777be0SXin Li                    const hidl_vec<uint32_t>&    cellLayerNormWeightsDimensions,
107*3e777be0SXin Li                    const std::vector<int16_t>&  cellLayerNormWeightsValue,
108*3e777be0SXin Li                    const hidl_vec<uint32_t>&    outputLayerNormWeightsDimensions,
109*3e777be0SXin Li                    const std::vector<int16_t>&  outputLayerNormWeightsValue,
110*3e777be0SXin Li                    const float&                 cellClipValue,
111*3e777be0SXin Li                    const float&                 projectionClipValue,
112*3e777be0SXin Li                    const float&                 matMulInputGateValue,
113*3e777be0SXin Li                    const float&                 matMulForgetGateValue,
114*3e777be0SXin Li                    const float&                 matMulCellGateValue,
115*3e777be0SXin Li                    const float&                 matMulOutputGateValue,
116*3e777be0SXin Li                    const int32_t&               projInputZeroPointValue,
117*3e777be0SXin Li                    const float&                 projInputScaleValue,
118*3e777be0SXin Li                    const hidl_vec<uint32_t>&    outputStateOutDimensions,
119*3e777be0SXin Li                    const std::vector<int8_t>&   outputStateOutValue,
120*3e777be0SXin Li                    const hidl_vec<uint32_t>&    cellStateOutDimensions,
121*3e777be0SXin Li                    const std::vector<int16_t>&  cellStateOutValue,
122*3e777be0SXin Li                    const hidl_vec<uint32_t>&    outputDimensions,
123*3e777be0SXin Li                    const std::vector<int8_t>&   outputValue,
124*3e777be0SXin Li                    armnn::Compute               compute)
125*3e777be0SXin Li {
126*3e777be0SXin Li     auto driver = std::make_unique<ArmnnDriver>(DriverOptions(compute));
127*3e777be0SXin Li     HalPolicy::Model model = {};
128*3e777be0SXin Li 
129*3e777be0SXin Li     // Scale/Offset quantization info
130*3e777be0SXin Li     float inputScale    = 0.0078125f;
131*3e777be0SXin Li     int32_t inputOffset = 0;
132*3e777be0SXin Li 
133*3e777be0SXin Li     int32_t hiddenStateZeroPoint = 0;
134*3e777be0SXin Li     float hiddenStateScale       = 0.007f;
135*3e777be0SXin Li 
136*3e777be0SXin Li     float outputScale    = hiddenStateScale;
137*3e777be0SXin Li     int32_t outputOffset = hiddenStateZeroPoint;
138*3e777be0SXin Li 
139*3e777be0SXin Li     float cellStateScale    = 3.05176e-05f;
140*3e777be0SXin Li     float cellWeightsScale  = 1.0f;
141*3e777be0SXin Li     int32_t cellStateOffset = 0;
142*3e777be0SXin Li 
143*3e777be0SXin Li     float weightsScale    = 0.00784314f;
144*3e777be0SXin Li     int32_t weightsOffset = 0;
145*3e777be0SXin Li 
146*3e777be0SXin Li     float layerNormScale    = 3.05182e-05f;
147*3e777be0SXin Li     int32_t layerNormOffset = 0;
148*3e777be0SXin Li 
149*3e777be0SXin Li     float biasScale    = layerNormScale / 1024;
150*3e777be0SXin Li     int32_t biasOffset = 0;
151*3e777be0SXin Li 
152*3e777be0SXin Li     // Inputs:
153*3e777be0SXin Li     // 00: The input to the LSTM cell. Type: ANEURALNETWORKS_TENSOR_QUANT8_ASYMM_SIGNED Shape: [batchSize, inputSize]
154*3e777be0SXin Li     AddInputOperand<HalPolicy>(model,
155*3e777be0SXin Li                                inputDimensions,
156*3e777be0SXin Li                                HalPolicy::OperandType::TENSOR_QUANT8_ASYMM_SIGNED,
157*3e777be0SXin Li                                inputScale,
158*3e777be0SXin Li                                inputOffset);
159*3e777be0SXin Li 
160*3e777be0SXin Li     // 01: The input-to-input weights. Optional. Type: ANEURALNETWORKS_TENSOR_QUANT8_SYMM Shape: [numUnits, inputSize]
161*3e777be0SXin Li     AddTensorOperand<HalPolicy>(model,
162*3e777be0SXin Li                                 inputToInputWeightsDimensions,
163*3e777be0SXin Li                                 inputToInputWeightsValue,
164*3e777be0SXin Li                                 HalPolicy::OperandType::TENSOR_QUANT8_SYMM,
165*3e777be0SXin Li                                 CreateNoValueLifeTime(inputToInputWeightsDimensions),
166*3e777be0SXin Li                                 weightsScale,
167*3e777be0SXin Li                                 weightsOffset);
168*3e777be0SXin Li 
169*3e777be0SXin Li     // 02: The input-to-forget weights. Type: ANEURALNETWORKS_TENSOR_QUANT8_SYMM Shape: [numUnits, inputSize]
170*3e777be0SXin Li     AddTensorOperand<HalPolicy>(model,
171*3e777be0SXin Li                                 inputToForgetWeightsDimensions,
172*3e777be0SXin Li                                 inputToForgetWeightsValue,
173*3e777be0SXin Li                                 HalPolicy::OperandType::TENSOR_QUANT8_SYMM,
174*3e777be0SXin Li                                 CreateNoValueLifeTime(inputToForgetWeightsDimensions),
175*3e777be0SXin Li                                 weightsScale,
176*3e777be0SXin Li                                 weightsOffset);
177*3e777be0SXin Li 
178*3e777be0SXin Li     // 03: The input-to-cell weights. Type: ANEURALNETWORKS_TENSOR_QUANT8_SYMM Shape: [numUnits, inputSize]
179*3e777be0SXin Li     AddTensorOperand<HalPolicy>(model,
180*3e777be0SXin Li                                 inputToCellWeightsDimensions,
181*3e777be0SXin Li                                 inputToCellWeightsValue,
182*3e777be0SXin Li                                 HalPolicy::OperandType::TENSOR_QUANT8_SYMM,
183*3e777be0SXin Li                                 CreateNoValueLifeTime(inputToCellWeightsDimensions),
184*3e777be0SXin Li                                 weightsScale,
185*3e777be0SXin Li                                 weightsOffset);
186*3e777be0SXin Li 
187*3e777be0SXin Li     // 04: The input-to-output weights. Type: ANEURALNETWORKS_TENSOR_QUANT8_SYMM Shape: [numUnits, inputSize]
188*3e777be0SXin Li     AddTensorOperand<HalPolicy>(model,
189*3e777be0SXin Li                                 inputToOutputWeightsDimensions,
190*3e777be0SXin Li                                 inputToOutputWeightsValue,
191*3e777be0SXin Li                                 HalPolicy::OperandType::TENSOR_QUANT8_SYMM,
192*3e777be0SXin Li                                 CreateNoValueLifeTime(inputToOutputWeightsDimensions),
193*3e777be0SXin Li                                 weightsScale,
194*3e777be0SXin Li                                 weightsOffset);
195*3e777be0SXin Li 
196*3e777be0SXin Li     // 05: The recurrent-to-input weights. Optional. Type: ANEURALNETWORKS_TENSOR_QUANT8_SYMM
197*3e777be0SXin Li     //     Shape: [numUnits, outputSize]
198*3e777be0SXin Li     AddTensorOperand<HalPolicy>(model,
199*3e777be0SXin Li                                 recurrentToInputWeightsDimensions,
200*3e777be0SXin Li                                 recurrentToInputWeightsValue,
201*3e777be0SXin Li                                 HalPolicy::OperandType::TENSOR_QUANT8_SYMM,
202*3e777be0SXin Li                                 CreateNoValueLifeTime(recurrentToInputWeightsDimensions),
203*3e777be0SXin Li                                 weightsScale,
204*3e777be0SXin Li                                 weightsOffset);
205*3e777be0SXin Li 
206*3e777be0SXin Li     // 06: The recurrent-to-forget weights. Type: ANEURALNETWORKS_TENSOR_QUANT8_SYMM Shape: [numUnits, outputSize]
207*3e777be0SXin Li     AddTensorOperand<HalPolicy>(model,
208*3e777be0SXin Li                                 recurrentToForgetWeightsDimensions,
209*3e777be0SXin Li                                 recurrentToForgetWeightsValue,
210*3e777be0SXin Li                                 HalPolicy::OperandType::TENSOR_QUANT8_SYMM,
211*3e777be0SXin Li                                 CreateNoValueLifeTime(recurrentToForgetWeightsDimensions),
212*3e777be0SXin Li                                 weightsScale,
213*3e777be0SXin Li                                 weightsOffset);
214*3e777be0SXin Li 
215*3e777be0SXin Li     // 07: The recurrent-to-cell weights. Type: ANEURALNETWORKS_TENSOR_QUANT8_SYMM Shape: [numUnits, outputSize]
216*3e777be0SXin Li     AddTensorOperand<HalPolicy>(model,
217*3e777be0SXin Li                                 recurrentToCellWeightsDimensions,
218*3e777be0SXin Li                                 recurrentToCellWeightsValue,
219*3e777be0SXin Li                                 HalPolicy::OperandType::TENSOR_QUANT8_SYMM,
220*3e777be0SXin Li                                 CreateNoValueLifeTime(recurrentToCellWeightsDimensions),
221*3e777be0SXin Li                                 weightsScale,
222*3e777be0SXin Li                                 weightsOffset);
223*3e777be0SXin Li 
224*3e777be0SXin Li     // 08: The recurrent-to-output weights. Type: ANEURALNETWORKS_TENSOR_QUANT8_SYMM Shape: [numUnits, outputSize]
225*3e777be0SXin Li     AddTensorOperand<HalPolicy>(model,
226*3e777be0SXin Li                                 recurrentToOutputWeightsDimensions,
227*3e777be0SXin Li                                 recurrentToOutputWeightsValue,
228*3e777be0SXin Li                                 HalPolicy::OperandType::TENSOR_QUANT8_SYMM,
229*3e777be0SXin Li                                 CreateNoValueLifeTime(recurrentToOutputWeightsDimensions),
230*3e777be0SXin Li                                 weightsScale,
231*3e777be0SXin Li                                 weightsOffset);
232*3e777be0SXin Li 
233*3e777be0SXin Li     // 09: The cell-to-input weights (for peephole). Optional. Type: ANEURALNETWORKS_TENSOR_QUANT16_SYMM
234*3e777be0SXin Li     //     Shape: [numUnits]
235*3e777be0SXin Li     AddTensorOperand<HalPolicy>(model,
236*3e777be0SXin Li                                 cellToInputWeightsDimensions,
237*3e777be0SXin Li                                 cellToInputWeightsValue,
238*3e777be0SXin Li                                 HalPolicy::OperandType::TENSOR_QUANT16_SYMM ,
239*3e777be0SXin Li                                 CreateNoValueLifeTime(cellToInputWeightsDimensions),
240*3e777be0SXin Li                                 cellWeightsScale,
241*3e777be0SXin Li                                 weightsOffset);
242*3e777be0SXin Li 
243*3e777be0SXin Li     // 10: The cell-to-forget weights (for peephole). Optional. Type: ANEURALNETWORKS_TENSOR_QUANT16_SYMM
244*3e777be0SXin Li     //     Shape: [numUnits].
245*3e777be0SXin Li     AddTensorOperand<HalPolicy>(model,
246*3e777be0SXin Li                                 cellToForgetWeightsDimensions,
247*3e777be0SXin Li                                 cellToForgetWeightsValue,
248*3e777be0SXin Li                                 HalPolicy::OperandType::TENSOR_QUANT16_SYMM,
249*3e777be0SXin Li                                 CreateNoValueLifeTime(cellToForgetWeightsDimensions),
250*3e777be0SXin Li                                 cellWeightsScale,
251*3e777be0SXin Li                                 weightsOffset);
252*3e777be0SXin Li 
253*3e777be0SXin Li     // 11: The cell-to-output weights (for peephole). Optional. Type: ANEURALNETWORKS_TENSOR_QUANT16_SYMM
254*3e777be0SXin Li     //     Shape: [numUnits]
255*3e777be0SXin Li     AddTensorOperand<HalPolicy>(model,
256*3e777be0SXin Li                                 cellToOutputWeightsDimensions,
257*3e777be0SXin Li                                 cellToOutputWeightsValue,
258*3e777be0SXin Li                                 HalPolicy::OperandType::TENSOR_QUANT16_SYMM,
259*3e777be0SXin Li                                 CreateNoValueLifeTime(cellToOutputWeightsDimensions),
260*3e777be0SXin Li                                 cellWeightsScale,
261*3e777be0SXin Li                                 weightsOffset);
262*3e777be0SXin Li 
263*3e777be0SXin Li     // 12: The input gate bias. Quantized with scale being the product of input and weights scales
264*3e777be0SXin Li     //     and zeroPoint equal to 0. Optional. Type: ANEURALNETWORKS_TENSOR_INT32 Shape: [numUnits]
265*3e777be0SXin Li     AddTensorOperand<HalPolicy>(model,
266*3e777be0SXin Li                                 inputGateBiasDimensions,
267*3e777be0SXin Li                                 inputGateBiasValue,
268*3e777be0SXin Li                                 HalPolicy::OperandType::TENSOR_INT32,
269*3e777be0SXin Li                                 CreateNoValueLifeTime(inputGateBiasDimensions),
270*3e777be0SXin Li                                 biasScale,
271*3e777be0SXin Li                                 biasOffset);
272*3e777be0SXin Li 
273*3e777be0SXin Li     // 13: The forget gate bias. Quantized with scale being the product of input and weights scales
274*3e777be0SXin Li     //     and zeroPoint equal to 0. Type: ANEURALNETWORKS_TENSOR_INT32 Shape: [numUnits]
275*3e777be0SXin Li     AddTensorOperand<HalPolicy>(model,
276*3e777be0SXin Li                                 forgetGateBiasDimensions,
277*3e777be0SXin Li                                 forgetGateBiasValue,
278*3e777be0SXin Li                                 HalPolicy::OperandType::TENSOR_INT32,
279*3e777be0SXin Li                                 CreateNoValueLifeTime(forgetGateBiasDimensions),
280*3e777be0SXin Li                                 biasScale,
281*3e777be0SXin Li                                 biasOffset);
282*3e777be0SXin Li 
283*3e777be0SXin Li     // 14: The cell bias. Quantized with scale being the product of input and weights scales and zeroPoint equal to 0.
284*3e777be0SXin Li     //     Type: ANEURALNETWORKS_TENSOR_INT32 Shape: [numUnits]
285*3e777be0SXin Li     AddTensorOperand<HalPolicy>(model,
286*3e777be0SXin Li                                 cellBiasDimensions,
287*3e777be0SXin Li                                 cellBiasValue,
288*3e777be0SXin Li                                 HalPolicy::OperandType::TENSOR_INT32,
289*3e777be0SXin Li                                 CreateNoValueLifeTime(cellBiasDimensions),
290*3e777be0SXin Li                                 biasScale,
291*3e777be0SXin Li                                 biasOffset);
292*3e777be0SXin Li 
293*3e777be0SXin Li     // 15: The output gate bias. Quantized with scale being the product of input and weights scales
294*3e777be0SXin Li     //     and zeroPoint equal to 0. Type: ANEURALNETWORKS_TENSOR_INT32 Shape: [numUnits]
295*3e777be0SXin Li     AddTensorOperand<HalPolicy>(model,
296*3e777be0SXin Li                                 outputGateBiasDimensions,
297*3e777be0SXin Li                                 outputGateBiasValue,
298*3e777be0SXin Li                                 HalPolicy::OperandType::TENSOR_INT32,
299*3e777be0SXin Li                                 CreateNoValueLifeTime(outputGateBiasDimensions),
300*3e777be0SXin Li                                 biasScale,
301*3e777be0SXin Li                                 biasOffset);
302*3e777be0SXin Li 
303*3e777be0SXin Li     // 16: The projection weights. Optional. Type: ANEURALNETWORKS_TENSOR_QUANT8_SYMM Shape: [outputSize, numUnits]
304*3e777be0SXin Li     AddTensorOperand<HalPolicy>(model,
305*3e777be0SXin Li                                 projectionWeightsDimensions,
306*3e777be0SXin Li                                 projectionWeightsValue,
307*3e777be0SXin Li                                 HalPolicy::OperandType::TENSOR_QUANT8_SYMM,
308*3e777be0SXin Li                                 CreateNoValueLifeTime(projectionWeightsDimensions),
309*3e777be0SXin Li                                 0.00392157f,
310*3e777be0SXin Li                                 weightsOffset);
311*3e777be0SXin Li 
312*3e777be0SXin Li     // 17: The projection bias. Quantized with scale being the product of input and weights scales
313*3e777be0SXin Li     //     and zeroPoint equal to 0. Optional. Type: ANEURALNETWORKS_TENSOR_INT32 Shape: [outputSize]
314*3e777be0SXin Li     AddTensorOperand<HalPolicy>(model,
315*3e777be0SXin Li                                 projectionBiasDimensions,
316*3e777be0SXin Li                                 projectionBiasValue,
317*3e777be0SXin Li                                 HalPolicy::OperandType::TENSOR_INT32,
318*3e777be0SXin Li                                 CreateNoValueLifeTime(projectionBiasDimensions),
319*3e777be0SXin Li                                 0.0f,
320*3e777be0SXin Li                                 biasOffset);
321*3e777be0SXin Li 
322*3e777be0SXin Li     // 18: The output from the previous time step. Type: ANEURALNETWORKS_TENSOR_QUANT8_ASYMM_SIGNED
323*3e777be0SXin Li     //     Shape: [batchSize, outputSize]
324*3e777be0SXin Li     AddInputOperand<HalPolicy>(model,
325*3e777be0SXin Li                                outputPreviousTimeStepInDimensions,
326*3e777be0SXin Li                                HalPolicy::OperandType::TENSOR_QUANT8_ASYMM_SIGNED,
327*3e777be0SXin Li                                cellStateScale,
328*3e777be0SXin Li                                inputOffset);
329*3e777be0SXin Li 
330*3e777be0SXin Li     // 19: The cell state from the previous time step. Type: ANEURALNETWORKS_TENSOR_QUANT16_SYMM
331*3e777be0SXin Li     //     Shape: [batchSize, numUnits]
332*3e777be0SXin Li     AddInputOperand<HalPolicy>(model,
333*3e777be0SXin Li                                cellStatePreviousTimeStepInDimensions,
334*3e777be0SXin Li                                HalPolicy::OperandType::TENSOR_QUANT16_SYMM,
335*3e777be0SXin Li                                cellStateScale,
336*3e777be0SXin Li                                cellStateOffset);
337*3e777be0SXin Li 
338*3e777be0SXin Li     // If any of the tensors have a value all normalization tensors are set
339*3e777be0SXin Li     if (!inputLayerNormWeightsValue.empty()  ||
340*3e777be0SXin Li         !forgetLayerNormWeightsValue.empty() ||
341*3e777be0SXin Li         !cellLayerNormWeightsValue.empty()   ||
342*3e777be0SXin Li         !outputLayerNormWeightsValue.empty())
343*3e777be0SXin Li     {
344*3e777be0SXin Li         // Normalization:
345*3e777be0SXin Li         // 20: The input layer normalization weights. Used to rescale normalized inputs to activation at input gate.
346*3e777be0SXin Li         //      Optional. Type: ANEURALNETWORKS_TENSOR_QUANT16_SYMM Shape: [numUnits]
347*3e777be0SXin Li         AddTensorOperand<HalPolicy>(model,
348*3e777be0SXin Li                                     inputLayerNormWeightsDimensions,
349*3e777be0SXin Li                                     inputLayerNormWeightsValue,
350*3e777be0SXin Li                                     HalPolicy::OperandType::TENSOR_QUANT16_SYMM,
351*3e777be0SXin Li                                     CreateNoValueLifeTime(inputLayerNormWeightsDimensions),
352*3e777be0SXin Li                                     layerNormScale,
353*3e777be0SXin Li                                     layerNormOffset);
354*3e777be0SXin Li 
355*3e777be0SXin Li         // 21: The forget layer normalization weights. Used to rescale normalized inputs to activation at forget gate.
356*3e777be0SXin Li         //     Optional. Type: ANEURALNETWORKS_TENSOR_QUANT16_SYMM Shape: [numUnits]
357*3e777be0SXin Li         AddTensorOperand<HalPolicy>(model,
358*3e777be0SXin Li                                     forgetLayerNormWeightsDimensions,
359*3e777be0SXin Li                                     forgetLayerNormWeightsValue,
360*3e777be0SXin Li                                     HalPolicy::OperandType::TENSOR_QUANT16_SYMM,
361*3e777be0SXin Li                                     CreateNoValueLifeTime(forgetLayerNormWeightsDimensions),
362*3e777be0SXin Li                                     layerNormScale,
363*3e777be0SXin Li                                     layerNormOffset);
364*3e777be0SXin Li 
365*3e777be0SXin Li         // 22: The cell layer normalization weights. Used to rescale normalized inputs to activation at cell gate.
366*3e777be0SXin Li         //     Optional. Type: ANEURALNETWORKS_TENSOR_QUANT16_SYMM Shape: [numUnits]
367*3e777be0SXin Li         AddTensorOperand<HalPolicy>(model,
368*3e777be0SXin Li                                     cellLayerNormWeightsDimensions,
369*3e777be0SXin Li                                     cellLayerNormWeightsValue,
370*3e777be0SXin Li                                     HalPolicy::OperandType::TENSOR_QUANT16_SYMM,
371*3e777be0SXin Li                                     CreateNoValueLifeTime(cellLayerNormWeightsDimensions),
372*3e777be0SXin Li                                     layerNormScale,
373*3e777be0SXin Li                                     layerNormOffset);
374*3e777be0SXin Li 
375*3e777be0SXin Li         // 23: The output layer normalization weights. Used to rescale normalized inputs to activation at output gate.
376*3e777be0SXin Li         //     Optional. Type: ANEURALNETWORKS_TENSOR_QUANT16_SYMM Shape: [numUnits]
377*3e777be0SXin Li         AddTensorOperand<HalPolicy>(model,
378*3e777be0SXin Li                                     outputLayerNormWeightsDimensions,
379*3e777be0SXin Li                                     outputLayerNormWeightsValue,
380*3e777be0SXin Li                                     HalPolicy::OperandType::TENSOR_QUANT16_SYMM,
381*3e777be0SXin Li                                     CreateNoValueLifeTime(outputLayerNormWeightsDimensions),
382*3e777be0SXin Li                                     layerNormScale,
383*3e777be0SXin Li                                     layerNormOffset);
384*3e777be0SXin Li     }
385*3e777be0SXin Li 
386*3e777be0SXin Li     // Constant scalar values
387*3e777be0SXin Li     // 24: The cell clip. If provided the cell state is clipped by this value prior to the cell output activation.
388*3e777be0SXin Li     //     Optional. Type: ANEURALNETWORKS_FLOAT32.
389*3e777be0SXin Li     AddFloatOperand<HalPolicy>(model, cellClipValue);
390*3e777be0SXin Li 
391*3e777be0SXin Li     // Constant scalar values
392*3e777be0SXin Li     // 25: The projection clip. If provided and projection is enabled, this is used for clipping the projected values.
393*3e777be0SXin Li     //     Optional. Type: ANEURALNETWORKS_FLOAT32.
394*3e777be0SXin Li     AddFloatOperand<HalPolicy>(model, projectionClipValue);
395*3e777be0SXin Li 
396*3e777be0SXin Li     // Constant scalar values
397*3e777be0SXin Li     // 26: The scale of the intermediate result of matmul, i.e. input to layer normalization, at input gate.
398*3e777be0SXin Li     //     Type: ANEURALNETWORKS_FLOAT32.
399*3e777be0SXin Li     AddFloatOperand<HalPolicy>(model, matMulInputGateValue);
400*3e777be0SXin Li 
401*3e777be0SXin Li     // Constant scalar values
402*3e777be0SXin Li     // 27: The scale of the intermediate result of matmul, i.e. input to layer normalization, at forget gate.
403*3e777be0SXin Li     //     Type: ANEURALNETWORKS_FLOAT32.
404*3e777be0SXin Li     AddFloatOperand<HalPolicy>(model, matMulForgetGateValue);
405*3e777be0SXin Li 
406*3e777be0SXin Li     // Constant scalar values
407*3e777be0SXin Li     // 28: The scale of the intermediate result of matmul, i.e. input to layer normalization, at cell gate.
408*3e777be0SXin Li     //     Type: ANEURALNETWORKS_FLOAT32.
409*3e777be0SXin Li     AddFloatOperand<HalPolicy>(model, matMulCellGateValue);
410*3e777be0SXin Li 
411*3e777be0SXin Li     // Constant scalar values
412*3e777be0SXin Li     // 29: The scale of the intermediate result of matmul, i.e. input to layer normalization, at output gate.
413*3e777be0SXin Li     //     Type: ANEURALNETWORKS_FLOAT32.
414*3e777be0SXin Li     AddFloatOperand<HalPolicy>(model, matMulOutputGateValue);
415*3e777be0SXin Li 
416*3e777be0SXin Li     // Constant scalar values
417*3e777be0SXin Li     // 30: The zero point of the hidden state, i.e. input to projection. Type: ANEURALNETWORKS_INT32.
418*3e777be0SXin Li     AddIntOperand<HalPolicy>(model, projInputZeroPointValue);
419*3e777be0SXin Li 
420*3e777be0SXin Li     // Constant scalar values
421*3e777be0SXin Li     // 31: The scale of the hidden state, i.e. input to projection. Type: ANEURALNETWORKS_FLOAT32.
422*3e777be0SXin Li     AddFloatOperand<HalPolicy>(model, projInputScaleValue);
423*3e777be0SXin Li 
424*3e777be0SXin Li     // Outputs:
425*3e777be0SXin Li     //  0: The output state (out). Type: ANEURALNETWORKS_TENSOR_QUANT8_ASYMM_SIGNED Shape: [batchSize, outputSize]
426*3e777be0SXin Li     AddOutputOperand<HalPolicy>(model,
427*3e777be0SXin Li                                 outputStateOutDimensions,
428*3e777be0SXin Li                                 HalPolicy::OperandType::TENSOR_QUANT8_ASYMM_SIGNED,
429*3e777be0SXin Li                                 cellStateScale,
430*3e777be0SXin Li                                 cellStateScale);
431*3e777be0SXin Li 
432*3e777be0SXin Li     //  1: The cell state (out). Type: ANEURALNETWORKS_TENSOR_QUANT16_SYMM Shape: [batchSize, numUnits].
433*3e777be0SXin Li     AddOutputOperand<HalPolicy>(model,
434*3e777be0SXin Li                                 cellStateOutDimensions,
435*3e777be0SXin Li                                 HalPolicy::OperandType::TENSOR_QUANT16_SYMM,
436*3e777be0SXin Li                                 cellStateScale,
437*3e777be0SXin Li                                 cellStateOffset);
438*3e777be0SXin Li 
439*3e777be0SXin Li     //  2: The output. This is effectively the same as the current "output state (out)" value.
440*3e777be0SXin Li     //     Type: ANEURALNETWORKS_TENSOR_QUANT8_ASYMM_SIGNED Shape: [batchSize, outputSize]
441*3e777be0SXin Li     AddOutputOperand<HalPolicy>(model,
442*3e777be0SXin Li                                 outputDimensions,
443*3e777be0SXin Li                                 HalPolicy::OperandType::TENSOR_QUANT8_ASYMM_SIGNED,
444*3e777be0SXin Li                                 cellStateScale,
445*3e777be0SXin Li                                 cellStateScale);
446*3e777be0SXin Li 
447*3e777be0SXin Li     // make the QUANTIZED_LSTM operation
448*3e777be0SXin Li     model.main.operations.resize(1);
449*3e777be0SXin Li     model.main.operations[0].type = HalPolicy::OperationType::QUANTIZED_LSTM;
450*3e777be0SXin Li 
451*3e777be0SXin Li     model.main.operations[0].inputs = hidl_vec<uint32_t> { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,
452*3e777be0SXin Li                                                           12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
453*3e777be0SXin Li                                                           24, 25, 26, 27, 28, 29, 30, 31};
454*3e777be0SXin Li     model.main.operations[0].outputs = hidl_vec<uint32_t> {32, 33, 34};
455*3e777be0SXin Li 
456*3e777be0SXin Li     // define the input values
457*3e777be0SXin Li     hidl_vec<RequestArgument> inputArguments;
458*3e777be0SXin Li     inputArguments.resize(3);
459*3e777be0SXin Li 
460*3e777be0SXin Li     inputArguments[0] = CreateRequestArgument<int8_t>(inputValue, 0);
461*3e777be0SXin Li     inputArguments[1] = CreateRequestArgument<int8_t>(outputPreviousTimeStepInValue, 1);
462*3e777be0SXin Li     inputArguments[2] = CreateRequestArgument<int16_t>(cellStatePreviousTimeStepInValue, 2);
463*3e777be0SXin Li 
464*3e777be0SXin Li     // define the expected output values
465*3e777be0SXin Li     hidl_vec<RequestArgument> outputArguments;
466*3e777be0SXin Li     outputArguments.resize(3);
467*3e777be0SXin Li 
468*3e777be0SXin Li     outputArguments[0] = CreateRequestArgument<int8_t>(outputStateOutValue, 3);
469*3e777be0SXin Li     outputArguments[1] = CreateRequestArgument<int16_t>(cellStateOutValue, 4);
470*3e777be0SXin Li     outputArguments[2] = CreateRequestArgument<int8_t>(outputValue, 5);
471*3e777be0SXin Li 
472*3e777be0SXin Li     android::hardware::neuralnetworks::V1_0::Request request = {};
473*3e777be0SXin Li     request.inputs  = inputArguments;
474*3e777be0SXin Li     request.outputs = outputArguments;
475*3e777be0SXin Li 
476*3e777be0SXin Li     // set the input data
477*3e777be0SXin Li     AddPoolAndSetData(inputValue.size(), request, inputValue.data());
478*3e777be0SXin Li     AddPoolAndSetData(outputPreviousTimeStepInValue.size(), request, outputPreviousTimeStepInValue.data());
479*3e777be0SXin Li     AddPoolAndSetData(cellStatePreviousTimeStepInValue.size(), request, cellStatePreviousTimeStepInValue.data());
480*3e777be0SXin Li 
481*3e777be0SXin Li     // add memory for the outputs
482*3e777be0SXin Li     android::sp<IMemory> outputStateOutMemory = AddPoolAndGetData<int8_t>(outputStateOutValue.size(), request);
483*3e777be0SXin Li     int8_t* outputStateOutData = static_cast<int8_t*>(static_cast<void*>(outputStateOutMemory->getPointer()));
484*3e777be0SXin Li 
485*3e777be0SXin Li     android::sp<IMemory> cellStateOutMemory = AddPoolAndGetData<int16_t>(cellStateOutValue.size(), request);
486*3e777be0SXin Li     int16_t* cellStateOutData = static_cast<int16_t*>(static_cast<void*>(cellStateOutMemory->getPointer()));
487*3e777be0SXin Li 
488*3e777be0SXin Li     android::sp<IMemory> outputMemory = AddPoolAndGetData<int8_t>(outputValue.size(), request);
489*3e777be0SXin Li     int8_t* outputData = static_cast<int8_t*>(static_cast<void*>(outputMemory->getPointer()));
490*3e777be0SXin Li 
491*3e777be0SXin Li     // make the prepared model and run the execution
492*3e777be0SXin Li     ExecuteModel(model, *driver, request);
493*3e777be0SXin Li 
494*3e777be0SXin Li     // check the results
495*3e777be0SXin Li     for (size_t i = 0; i < outputStateOutValue.size(); ++i)
496*3e777be0SXin Li     {
497*3e777be0SXin Li         DOCTEST_CHECK_MESSAGE(outputStateOutValue[i] == doctest::Approx( outputStateOutData[i] ).epsilon(TOLERANCE),
498*3e777be0SXin Li                               "outputStateOut[" << i << "]: " << outputStateOutValue[i] << " != "
499*3e777be0SXin Li                               << outputStateOutData[i]);
500*3e777be0SXin Li     }
501*3e777be0SXin Li 
502*3e777be0SXin Li     // CELL STATE OUTPUT Does not match currently: IVGCVSW-4860 Verify remaining VTS tests (2) for QLSTM
503*3e777be0SXin Li     // Comment out for now
504*3e777be0SXin Li     // for (size_t i = 0; i < cellStateOutValue.size(); ++i)
505*3e777be0SXin Li     // {
506*3e777be0SXin Li     //    BOOST_TEST(TolerantCompareEqual(cellStateOutValue[i], cellStateOutData[i]),
507*3e777be0SXin Li     //               "cellStateOut[" << i << "]: " << cellStateOutValue[i] << " != " << cellStateOutData[i]);
508*3e777be0SXin Li     //}
509*3e777be0SXin Li 
510*3e777be0SXin Li     for (size_t i = 0; i < outputValue.size(); ++i)
511*3e777be0SXin Li     {
512*3e777be0SXin Li         DOCTEST_CHECK_MESSAGE(outputValue[i] == doctest::Approx( outputData[i] ).epsilon(TOLERANCE),
513*3e777be0SXin Li                               "output[" << i << "]: " << outputValue[i] << " != " << outputData[i]);
514*3e777be0SXin Li     }
515*3e777be0SXin Li }
516*3e777be0SXin Li 
QLstmWithProjection(armnn::Compute compute)517*3e777be0SXin Li void QLstmWithProjection(armnn::Compute compute)
518*3e777be0SXin Li {
519*3e777be0SXin Li     // This replicates android/frameworks/ml/nn/runtime/test/specs/V1_3/qlstm_projection.mod.py
520*3e777be0SXin Li     // with values from android/frameworks/ml/nn/runtime/test/generated/spec_V1_3/qlstm_projection.example.cpp
521*3e777be0SXin Li     // and weights, biases and scalars passed as CONSTANT_COPY tensors (instead of SUBGRAPH_INPUT tensors).
522*3e777be0SXin Li 
523*3e777be0SXin Li     uint32_t batchSize  = 2;
524*3e777be0SXin Li     uint32_t inputSize  = 5;
525*3e777be0SXin Li     uint32_t outputSize = 3;
526*3e777be0SXin Li     uint32_t numUnits   = 4;
527*3e777be0SXin Li 
528*3e777be0SXin Li     // Inputs:
529*3e777be0SXin Li     hidl_vec<uint32_t> inputDimensions{batchSize, inputSize};
530*3e777be0SXin Li     std::vector<int8_t> inputValue{ 90, 102, 13, 26, 38, 102, 13, 26, 51, 64};
531*3e777be0SXin Li 
532*3e777be0SXin Li     hidl_vec<uint32_t> inputToInputWeightsDimensions{numUnits, inputSize};
533*3e777be0SXin Li     std::vector<int8_t> inputToInputWeightsValue{   64,  77,   89, -102,
534*3e777be0SXin Li                                                   -115,  13,   25,   38,
535*3e777be0SXin Li                                                    -51,  64, -102,   89,
536*3e777be0SXin Li                                                    -77,  64,  -51,  -64,
537*3e777be0SXin Li                                                    -51, -38,  -25,  -13 };
538*3e777be0SXin Li 
539*3e777be0SXin Li     hidl_vec<uint32_t> inputToForgetWeightsDimensions{numUnits, inputSize};
540*3e777be0SXin Li     std::vector<int8_t> inputToForgetWeightsValue{ -77,  -13,  38,  25,
541*3e777be0SXin Li                                                    115,  -64, -25, -51,
542*3e777be0SXin Li                                                     38, -102, -51,  38,
543*3e777be0SXin Li                                                    -64,  -51, -77,  38,
544*3e777be0SXin Li                                                    -51,  -77, -64, -64 };
545*3e777be0SXin Li 
546*3e777be0SXin Li     hidl_vec<uint32_t> inputToCellWeightsDimensions{numUnits, inputSize};
547*3e777be0SXin Li     std::vector<int8_t> inputToCellWeightsValue{  -51, -38, -25, -13,
548*3e777be0SXin Li                                                   -64,  64, -25, -38,
549*3e777be0SXin Li                                                   -25, -77,  77, -13,
550*3e777be0SXin Li                                                   -51, -38, -89,  89,
551*3e777be0SXin Li                                                  -115, -64, 102,  77 };
552*3e777be0SXin Li 
553*3e777be0SXin Li     hidl_vec<uint32_t> inputToOutputWeightsDimensions{numUnits, inputSize};
554*3e777be0SXin Li     std::vector<int8_t> inputToOutputWeightsValue{ -102, -51, -25, -115,
555*3e777be0SXin Li                                                     -13, -89,  38,  -38,
556*3e777be0SXin Li                                                    -102, -25,  77,  -25,
557*3e777be0SXin Li                                                      51, -89, -38,  -64,
558*3e777be0SXin Li                                                      13,  64, -77,  -51 };
559*3e777be0SXin Li 
560*3e777be0SXin Li     hidl_vec<uint32_t> recurrentToInputWeightsDimensions{numUnits, outputSize};
561*3e777be0SXin Li     std::vector<int8_t> recurrentToInputWeightsValue{ -25, -38, 51, 13, -64, 115, -25, -38, -89, 6, -25, -77 };
562*3e777be0SXin Li 
563*3e777be0SXin Li     hidl_vec<uint32_t> recurrentToForgetWeightsDimensions{numUnits, outputSize};
564*3e777be0SXin Li     std::vector<int8_t> recurrentToForgetWeightsValue{ -64, -38, -64, -25, 77, 51, 115, 38, -13, 25, 64, 25 };
565*3e777be0SXin Li 
566*3e777be0SXin Li     hidl_vec<uint32_t> recurrentToCellWeightsDimensions{numUnits, outputSize};
567*3e777be0SXin Li     std::vector<int8_t> recurrentToCellWeightsValue{ -38, 25, 13, -38, 102, -10, -25, 38, 102, -77, -13, 25 };
568*3e777be0SXin Li 
569*3e777be0SXin Li     hidl_vec<uint32_t> recurrentToOutputWeightsDimensions{numUnits, outputSize};
570*3e777be0SXin Li     std::vector<int8_t> recurrentToOutputWeightsValue{ 38, -13, 13, -25, -64, -89, -25, -77, -13, -51, -89, -25 };
571*3e777be0SXin Li 
572*3e777be0SXin Li     hidl_vec<uint32_t> cellToInputWeightsDimensions{0};
573*3e777be0SXin Li     std::vector<int16_t> cellToInputWeightsValue;
574*3e777be0SXin Li 
575*3e777be0SXin Li     hidl_vec<uint32_t> cellToForgetWeightsDimensions{0};
576*3e777be0SXin Li     std::vector<int16_t> cellToForgetWeightsValue;
577*3e777be0SXin Li 
578*3e777be0SXin Li     hidl_vec<uint32_t> cellToOutputWeightsDimensions{0};
579*3e777be0SXin Li     std::vector<int16_t> cellToOutputWeightsValue;
580*3e777be0SXin Li 
581*3e777be0SXin Li     hidl_vec<uint32_t> inputGateBiasDimensions{numUnits};
582*3e777be0SXin Li     std::vector<int32_t> inputGateBiasValue{ 644245, 3221226, 4724464, 8160438 };
583*3e777be0SXin Li 
584*3e777be0SXin Li     hidl_vec<uint32_t> forgetGateBiasDimensions{numUnits};
585*3e777be0SXin Li     std::vector<int32_t> forgetGateBiasValue{ 2147484, -6442451, -4294968, 2147484 };
586*3e777be0SXin Li 
587*3e777be0SXin Li     hidl_vec<uint32_t> cellBiasDimensions{numUnits};
588*3e777be0SXin Li     std::vector<int32_t> cellBiasValue{-1073742, 15461883, 5368709, 1717987 };
589*3e777be0SXin Li 
590*3e777be0SXin Li     hidl_vec<uint32_t> outputGateBiasDimensions{numUnits};
591*3e777be0SXin Li     std::vector<int32_t> outputGateBiasValue{ 1073742, -214748, 4294968, 2147484 };
592*3e777be0SXin Li 
593*3e777be0SXin Li     hidl_vec<uint32_t> projectionWeightsDimensions{outputSize, numUnits};
594*3e777be0SXin Li     std::vector<int8_t> projectionWeightsValue{ -25, 51, 3, -51, 25, 127, 77, 20, 18, 51, -102, 51 };
595*3e777be0SXin Li 
596*3e777be0SXin Li     hidl_vec<uint32_t> projectionBiasDimensions{outputSize};
597*3e777be0SXin Li     std::vector<int32_t> projectionBiasValue{ 0, 0, 0 };
598*3e777be0SXin Li 
599*3e777be0SXin Li     hidl_vec<uint32_t> outputStateInDimensions{batchSize, outputSize};
600*3e777be0SXin Li     std::vector<int8_t> outputStateInValue{ 0, 0, 0, 0, 0, 0 };
601*3e777be0SXin Li 
602*3e777be0SXin Li     hidl_vec<uint32_t> cellStateInDimensions{batchSize, numUnits};
603*3e777be0SXin Li     std::vector<int16_t> cellStateInValue{ 0, 0, 0, 0, 0, 0, 0, 0 };
604*3e777be0SXin Li 
605*3e777be0SXin Li     // Normalization:
606*3e777be0SXin Li     hidl_vec<uint32_t> inputLayerNormWeightsDimensions{numUnits};
607*3e777be0SXin Li     std::vector<int16_t> inputLayerNormWeightsValue{ 3277, 6553, 9830, 16384 };
608*3e777be0SXin Li 
609*3e777be0SXin Li     hidl_vec<uint32_t> forgetLayerNormWeightsDimensions{numUnits};
610*3e777be0SXin Li     std::vector<int16_t> forgetLayerNormWeightsValue{ 6553, 6553, 13107, 9830 };
611*3e777be0SXin Li 
612*3e777be0SXin Li     hidl_vec<uint32_t> cellLayerNormWeightsDimensions{numUnits};
613*3e777be0SXin Li     std::vector<int16_t> cellLayerNormWeightsValue{ 22937, 6553, 9830, 26214 };
614*3e777be0SXin Li 
615*3e777be0SXin Li     hidl_vec<uint32_t> outputLayerNormWeightsDimensions{numUnits};
616*3e777be0SXin Li     std::vector<int16_t> outputLayerNormWeightsValue{ 19660, 6553, 6553, 16384 };
617*3e777be0SXin Li 
618*3e777be0SXin Li     float cellClipValue           = 0.0f;
619*3e777be0SXin Li     float projectionClipValue     = 0.0f;
620*3e777be0SXin Li     float inputIntermediateScale  = 0.007059f;
621*3e777be0SXin Li     float forgetIntermediateScale = 0.007812f;
622*3e777be0SXin Li     float cellIntermediateScale   = 0.007059f;
623*3e777be0SXin Li     float outputIntermediateScale = 0.007812f;
624*3e777be0SXin Li     int32_t hiddenStateZeroPoint  = 0;
625*3e777be0SXin Li     float hiddenStateScale        = 0.007f;
626*3e777be0SXin Li 
627*3e777be0SXin Li     // Outputs:
628*3e777be0SXin Li     hidl_vec<uint32_t> outputStateOutDimensions{batchSize, outputSize};
629*3e777be0SXin Li     std::vector<int8_t> outputStateOutValue{ 127, 127, -108, -67, 127, 127 };
630*3e777be0SXin Li 
631*3e777be0SXin Li     hidl_vec<uint32_t> cellStateOutDimensions{batchSize, numUnits};
632*3e777be0SXin Li     std::vector<int16_t> cellStateOutValue { -14650, 8939, 5771, 6715, -11843, 7847, 1508, 12939 };
633*3e777be0SXin Li 
634*3e777be0SXin Li     hidl_vec<uint32_t> outputDimensions{batchSize, outputSize};
635*3e777be0SXin Li     std::vector<int8_t> outputValue { 127, 127, -108, -67, 127, 127 };
636*3e777be0SXin Li 
637*3e777be0SXin Li     QLstmTestImpl(inputDimensions,                       inputValue,
638*3e777be0SXin Li                   inputToInputWeightsDimensions,         inputToInputWeightsValue,
639*3e777be0SXin Li                   inputToForgetWeightsDimensions,        inputToForgetWeightsValue,
640*3e777be0SXin Li                   inputToCellWeightsDimensions,          inputToCellWeightsValue,
641*3e777be0SXin Li                   inputToOutputWeightsDimensions,        inputToOutputWeightsValue,
642*3e777be0SXin Li                   recurrentToInputWeightsDimensions,     recurrentToInputWeightsValue,
643*3e777be0SXin Li                   recurrentToForgetWeightsDimensions,    recurrentToForgetWeightsValue,
644*3e777be0SXin Li                   recurrentToCellWeightsDimensions,      recurrentToCellWeightsValue,
645*3e777be0SXin Li                   recurrentToOutputWeightsDimensions,    recurrentToOutputWeightsValue,
646*3e777be0SXin Li                   cellToInputWeightsDimensions,          cellToInputWeightsValue,
647*3e777be0SXin Li                   cellToForgetWeightsDimensions,         cellToForgetWeightsValue,
648*3e777be0SXin Li                   cellToOutputWeightsDimensions,         cellToOutputWeightsValue,
649*3e777be0SXin Li                   inputGateBiasDimensions,               inputGateBiasValue,
650*3e777be0SXin Li                   forgetGateBiasDimensions,              forgetGateBiasValue,
651*3e777be0SXin Li                   cellBiasDimensions,                    cellBiasValue,
652*3e777be0SXin Li                   outputGateBiasDimensions,              outputGateBiasValue,
653*3e777be0SXin Li                   projectionWeightsDimensions,           projectionWeightsValue,
654*3e777be0SXin Li                   projectionBiasDimensions,              projectionBiasValue,
655*3e777be0SXin Li                   outputStateInDimensions,               outputStateInValue,
656*3e777be0SXin Li                   cellStateInDimensions,                 cellStateInValue,
657*3e777be0SXin Li                   inputLayerNormWeightsDimensions,       inputLayerNormWeightsValue,
658*3e777be0SXin Li                   forgetLayerNormWeightsDimensions,      forgetLayerNormWeightsValue,
659*3e777be0SXin Li                   cellLayerNormWeightsDimensions,        cellLayerNormWeightsValue,
660*3e777be0SXin Li                   outputLayerNormWeightsDimensions,      outputLayerNormWeightsValue,
661*3e777be0SXin Li                   cellClipValue,
662*3e777be0SXin Li                   projectionClipValue,
663*3e777be0SXin Li                   inputIntermediateScale,
664*3e777be0SXin Li                   forgetIntermediateScale,
665*3e777be0SXin Li                   cellIntermediateScale,
666*3e777be0SXin Li                   outputIntermediateScale,
667*3e777be0SXin Li                   hiddenStateZeroPoint,
668*3e777be0SXin Li                   hiddenStateScale,
669*3e777be0SXin Li                   outputStateOutDimensions,              outputStateOutValue,
670*3e777be0SXin Li                   cellStateOutDimensions,                cellStateOutValue,
671*3e777be0SXin Li                   outputDimensions,                      outputValue,
672*3e777be0SXin Li                   compute);
673*3e777be0SXin Li }
674*3e777be0SXin Li 
QLstmWithNoProjection(armnn::Compute compute)675*3e777be0SXin Li void QLstmWithNoProjection(armnn::Compute compute)
676*3e777be0SXin Li {
677*3e777be0SXin Li     // This replicates android/frameworks/ml/nn/runtime/test/specs/V1_3/qlstm_noprojection.mod.py
678*3e777be0SXin Li     // with values from android/frameworks/ml/nn/runtime/test/generated/spec_V1_3/qlstm_noprojection.example.cpp
679*3e777be0SXin Li     // and weights, biases and scalars passed as CONSTANT_COPY tensors (instead of SUBGRAPH_INPUT tensors).
680*3e777be0SXin Li 
681*3e777be0SXin Li     uint32_t batchSize  = 2;
682*3e777be0SXin Li     uint32_t inputSize  = 5;
683*3e777be0SXin Li     uint32_t outputSize = 4;
684*3e777be0SXin Li     uint32_t numUnits   = 4;
685*3e777be0SXin Li 
686*3e777be0SXin Li     // Inputs:
687*3e777be0SXin Li     hidl_vec<uint32_t> inputDimensions{batchSize, inputSize};
688*3e777be0SXin Li     std::vector<int8_t> inputValue { 90, 102, 13, 26, 38, 102, 13, 26, 51, 64 };
689*3e777be0SXin Li 
690*3e777be0SXin Li     hidl_vec<uint32_t> inputToInputWeightsDimensions{0, 0};
691*3e777be0SXin Li     std::vector<int8_t> inputToInputWeightsValue;
692*3e777be0SXin Li 
693*3e777be0SXin Li     hidl_vec<uint32_t> inputToForgetWeightsDimensions{numUnits, inputSize};
694*3e777be0SXin Li     std::vector<int8_t> inputToForgetWeightsValue { -77, -13,  38,  25,  115,
695*3e777be0SXin Li                                                     -64, -25, -51,  38, -102,
696*3e777be0SXin Li                                                     -51,  38, -64, -51,  -77,
697*3e777be0SXin Li                                                      38, -51, -77, -64,  -64 };
698*3e777be0SXin Li 
699*3e777be0SXin Li     hidl_vec<uint32_t> inputToCellWeightsDimensions{numUnits, inputSize};
700*3e777be0SXin Li     std::vector<int8_t> inputToCellWeightsValue { -51,  -38, -25, -13, -64,
701*3e777be0SXin Li                                                    64,  -25, -38, -25, -77,
702*3e777be0SXin Li                                                    77,  -13, -51, -38, -89,
703*3e777be0SXin Li                                                    89, -115, -64, 102,  77 };
704*3e777be0SXin Li 
705*3e777be0SXin Li     hidl_vec<uint32_t> inputToOutputWeightsDimensions{numUnits, inputSize};
706*3e777be0SXin Li     std::vector<int8_t> inputToOutputWeightsValue { -102, -51, -25, -115, -13,
707*3e777be0SXin Li                                                      -89,  38, -38, -102, -25,
708*3e777be0SXin Li                                                       77, -25,  51,  -89, -38,
709*3e777be0SXin Li                                                      -64,  13,  64,  -77, -51 };
710*3e777be0SXin Li 
711*3e777be0SXin Li     hidl_vec<uint32_t> recurrentToInputWeightsDimensions{0, 0};
712*3e777be0SXin Li     std::vector<int8_t> recurrentToInputWeightsValue;
713*3e777be0SXin Li 
714*3e777be0SXin Li     hidl_vec<uint32_t> recurrentToForgetWeightsDimensions{numUnits, outputSize};
715*3e777be0SXin Li     std::vector<int8_t> recurrentToForgetWeightsValue { -64, -38, -64, -25,
716*3e777be0SXin Li                                                          77,  51, 115,  38,
717*3e777be0SXin Li                                                         -13,  25,  64,  25,
718*3e777be0SXin Li                                                          25,  38, -13,  51 };
719*3e777be0SXin Li 
720*3e777be0SXin Li     hidl_vec<uint32_t> recurrentToCellWeightsDimensions{numUnits, outputSize};
721*3e777be0SXin Li     std::vector<int8_t> recurrentToCellWeightsValue { -38,  25,  13, -38,
722*3e777be0SXin Li                                                       102, -10, -25,  38,
723*3e777be0SXin Li                                                       102, -77, -13,  25,
724*3e777be0SXin Li                                                        38, -13,  25,  64 };
725*3e777be0SXin Li 
726*3e777be0SXin Li     hidl_vec<uint32_t> recurrentToOutputWeightsDimensions{numUnits, outputSize};
727*3e777be0SXin Li     std::vector<int8_t> recurrentToOutputWeightsValue {  38, -13,  13, -25,
728*3e777be0SXin Li                                                         -64, -89, -25, -77,
729*3e777be0SXin Li                                                         -13, -51, -89, -25,
730*3e777be0SXin Li                                                          13,  64,  25, -38 };
731*3e777be0SXin Li 
732*3e777be0SXin Li     hidl_vec<uint32_t> cellToInputWeightsDimensions{0};
733*3e777be0SXin Li     std::vector<int16_t> cellToInputWeightsValue;
734*3e777be0SXin Li 
735*3e777be0SXin Li     hidl_vec<uint32_t> cellToForgetWeightsDimensions{0};
736*3e777be0SXin Li     std::vector<int16_t> cellToForgetWeightsValue;
737*3e777be0SXin Li 
738*3e777be0SXin Li     hidl_vec<uint32_t> cellToOutputWeightsDimensions{0};
739*3e777be0SXin Li     std::vector<int16_t> cellToOutputWeightsValue;
740*3e777be0SXin Li 
741*3e777be0SXin Li     hidl_vec<uint32_t> inputGateBiasDimensions{0};
742*3e777be0SXin Li     std::vector<int32_t> inputGateBiasValue;
743*3e777be0SXin Li 
744*3e777be0SXin Li     hidl_vec<uint32_t> forgetGateBiasDimensions{numUnits};
745*3e777be0SXin Li     std::vector<int32_t> forgetGateBiasValue { 2147484, -6442451, -4294968, 2147484 };
746*3e777be0SXin Li 
747*3e777be0SXin Li     hidl_vec<uint32_t> cellBiasDimensions{numUnits};
748*3e777be0SXin Li     std::vector<int32_t> cellBiasValue { -1073742, 15461883, 5368709, 1717987 };
749*3e777be0SXin Li 
750*3e777be0SXin Li     hidl_vec<uint32_t> outputGateBiasDimensions{numUnits};
751*3e777be0SXin Li     std::vector<int32_t> outputGateBiasValue { 1073742, -214748, 4294968, 2147484 };
752*3e777be0SXin Li 
753*3e777be0SXin Li     hidl_vec<uint32_t> projectionWeightsDimensions{0, 0};
754*3e777be0SXin Li     std::vector<int8_t> projectionWeightsValue;
755*3e777be0SXin Li 
756*3e777be0SXin Li     hidl_vec<uint32_t> projectionBiasDimensions{0};
757*3e777be0SXin Li     std::vector<int32_t> projectionBiasValue;
758*3e777be0SXin Li 
759*3e777be0SXin Li     hidl_vec<uint32_t> outputStateInDimensions{batchSize, outputSize};
760*3e777be0SXin Li     std::vector<int8_t> outputStateInValue { 0, 0, 0, 0, 0, 0, 0, 0 };
761*3e777be0SXin Li 
762*3e777be0SXin Li     hidl_vec<uint32_t> cellStateInDimensions{batchSize, numUnits};
763*3e777be0SXin Li     std::vector<int16_t> cellStateInValue { 0, 0, 0, 0, 0, 0, 0, 0 };
764*3e777be0SXin Li 
765*3e777be0SXin Li     // Normalization:
766*3e777be0SXin Li     hidl_vec<uint32_t> inputLayerNormWeightsDimensions{0};
767*3e777be0SXin Li     std::vector<int16_t> inputLayerNormWeightsValue;
768*3e777be0SXin Li 
769*3e777be0SXin Li     hidl_vec<uint32_t> forgetLayerNormWeightsDimensions{numUnits};
770*3e777be0SXin Li     std::vector<int16_t> forgetLayerNormWeightsValue { 6553, 6553, 13107, 9830 };
771*3e777be0SXin Li 
772*3e777be0SXin Li     hidl_vec<uint32_t> cellLayerNormWeightsDimensions{numUnits};
773*3e777be0SXin Li     std::vector<int16_t> cellLayerNormWeightsValue { 22937, 6553, 9830, 26214 };
774*3e777be0SXin Li 
775*3e777be0SXin Li     hidl_vec<uint32_t> outputLayerNormWeightsDimensions{numUnits};
776*3e777be0SXin Li     std::vector<int16_t> outputLayerNormWeightsValue { 19660, 6553, 6553, 16384 };
777*3e777be0SXin Li 
778*3e777be0SXin Li     float cellClipValue           = 0.0f;
779*3e777be0SXin Li     float projectionClipValue     = 0.0f;
780*3e777be0SXin Li     float inputIntermediateScale  = 0.007059f;
781*3e777be0SXin Li     float forgetIntermediateScale = 0.007812f;
782*3e777be0SXin Li     float cellIntermediateScale   = 0.007059f;
783*3e777be0SXin Li     float outputIntermediateScale = 0.007812f;
784*3e777be0SXin Li     int32_t hiddenStateZeroPoint  = 0;
785*3e777be0SXin Li     float hiddenStateScale        = 0.007f;
786*3e777be0SXin Li 
787*3e777be0SXin Li     // Outputs:
788*3e777be0SXin Li     hidl_vec<uint32_t> outputStateOutDimensions{batchSize, outputSize};
789*3e777be0SXin Li     std::vector<int8_t> outputStateOutValue { -15, 21, 14, 20, -15, 15, 5, 27 };
790*3e777be0SXin Li 
791*3e777be0SXin Li     hidl_vec<uint32_t> cellStateOutDimensions{batchSize, numUnits};
792*3e777be0SXin Li     std::vector<int16_t> cellStateOutValue { -11692, 9960, 5491, 8861, -9422, 7726, 2056, 13149 };
793*3e777be0SXin Li 
794*3e777be0SXin Li     hidl_vec<uint32_t> outputDimensions{batchSize, outputSize};
795*3e777be0SXin Li     std::vector<int8_t> outputValue { -15, 21, 14, 20, -15, 15, 5, 27 };
796*3e777be0SXin Li 
797*3e777be0SXin Li     QLstmTestImpl(inputDimensions,                       inputValue,
798*3e777be0SXin Li                   inputToInputWeightsDimensions,         inputToInputWeightsValue,
799*3e777be0SXin Li                   inputToForgetWeightsDimensions,        inputToForgetWeightsValue,
800*3e777be0SXin Li                   inputToCellWeightsDimensions,          inputToCellWeightsValue,
801*3e777be0SXin Li                   inputToOutputWeightsDimensions,        inputToOutputWeightsValue,
802*3e777be0SXin Li                   recurrentToInputWeightsDimensions,     recurrentToInputWeightsValue,
803*3e777be0SXin Li                   recurrentToForgetWeightsDimensions,    recurrentToForgetWeightsValue,
804*3e777be0SXin Li                   recurrentToCellWeightsDimensions,      recurrentToCellWeightsValue,
805*3e777be0SXin Li                   recurrentToOutputWeightsDimensions,    recurrentToOutputWeightsValue,
806*3e777be0SXin Li                   cellToInputWeightsDimensions,          cellToInputWeightsValue,
807*3e777be0SXin Li                   cellToForgetWeightsDimensions,         cellToForgetWeightsValue,
808*3e777be0SXin Li                   cellToOutputWeightsDimensions,         cellToOutputWeightsValue,
809*3e777be0SXin Li                   inputGateBiasDimensions,               inputGateBiasValue,
810*3e777be0SXin Li                   forgetGateBiasDimensions,              forgetGateBiasValue,
811*3e777be0SXin Li                   cellBiasDimensions,                    cellBiasValue,
812*3e777be0SXin Li                   outputGateBiasDimensions,              outputGateBiasValue,
813*3e777be0SXin Li                   projectionWeightsDimensions,           projectionWeightsValue,
814*3e777be0SXin Li                   projectionBiasDimensions,              projectionBiasValue,
815*3e777be0SXin Li                   outputStateInDimensions,               outputStateInValue,
816*3e777be0SXin Li                   cellStateInDimensions,                 cellStateInValue,
817*3e777be0SXin Li                   inputLayerNormWeightsDimensions,       inputLayerNormWeightsValue,
818*3e777be0SXin Li                   forgetLayerNormWeightsDimensions,      forgetLayerNormWeightsValue,
819*3e777be0SXin Li                   cellLayerNormWeightsDimensions,        cellLayerNormWeightsValue,
820*3e777be0SXin Li                   outputLayerNormWeightsDimensions,      outputLayerNormWeightsValue,
821*3e777be0SXin Li                   cellClipValue,
822*3e777be0SXin Li                   projectionClipValue,
823*3e777be0SXin Li                   inputIntermediateScale,
824*3e777be0SXin Li                   forgetIntermediateScale,
825*3e777be0SXin Li                   cellIntermediateScale,
826*3e777be0SXin Li                   outputIntermediateScale,
827*3e777be0SXin Li                   hiddenStateZeroPoint,
828*3e777be0SXin Li                   hiddenStateScale,
829*3e777be0SXin Li                   outputStateOutDimensions,              outputStateOutValue,
830*3e777be0SXin Li                   cellStateOutDimensions,                cellStateOutValue,
831*3e777be0SXin Li                   outputDimensions,                      outputValue,
832*3e777be0SXin Li                   compute);
833*3e777be0SXin Li }
834*3e777be0SXin Li 
DynamicOutputQLstmWithNoProjection(armnn::Compute compute)835*3e777be0SXin Li void DynamicOutputQLstmWithNoProjection(armnn::Compute compute)
836*3e777be0SXin Li {
837*3e777be0SXin Li     // This replicates android/frameworks/ml/nn/runtime/test/specs/V1_3/qlstm_noprojection.mod.py
838*3e777be0SXin Li     // with values from android/frameworks/ml/nn/runtime/test/generated/spec_V1_3/qlstm_noprojection.example.cpp
839*3e777be0SXin Li     // and weights, biases and scalars passed as CONSTANT_COPY tensors (instead of SUBGRAPH_INPUT tensors)
840*3e777be0SXin Li     // and made cellStateOutput dynamic.
841*3e777be0SXin Li 
842*3e777be0SXin Li     uint32_t batchSize  = 2;
843*3e777be0SXin Li     uint32_t inputSize  = 5;
844*3e777be0SXin Li     uint32_t outputSize = 4;
845*3e777be0SXin Li     uint32_t numUnits   = 4;
846*3e777be0SXin Li 
847*3e777be0SXin Li     // Inputs:
848*3e777be0SXin Li     hidl_vec<uint32_t> inputDimensions{batchSize, inputSize};
849*3e777be0SXin Li     std::vector<int8_t> inputValue { 90, 102, 13, 26, 38, 102, 13, 26, 51, 64 };
850*3e777be0SXin Li 
851*3e777be0SXin Li     hidl_vec<uint32_t> inputToInputWeightsDimensions{0, 0};
852*3e777be0SXin Li     std::vector<int8_t> inputToInputWeightsValue;
853*3e777be0SXin Li 
854*3e777be0SXin Li     hidl_vec<uint32_t> inputToForgetWeightsDimensions{numUnits, inputSize};
855*3e777be0SXin Li     std::vector<int8_t> inputToForgetWeightsValue { -77, -13,  38,  25,  115,
856*3e777be0SXin Li                                                     -64, -25, -51,  38, -102,
857*3e777be0SXin Li                                                     -51,  38, -64, -51,  -77,
858*3e777be0SXin Li                                                     38, -51, -77, -64,  -64 };
859*3e777be0SXin Li 
860*3e777be0SXin Li     hidl_vec<uint32_t> inputToCellWeightsDimensions{numUnits, inputSize};
861*3e777be0SXin Li     std::vector<int8_t> inputToCellWeightsValue { -51,  -38, -25, -13, -64,
862*3e777be0SXin Li                                                   64,  -25, -38, -25, -77,
863*3e777be0SXin Li                                                   77,  -13, -51, -38, -89,
864*3e777be0SXin Li                                                   89, -115, -64, 102,  77 };
865*3e777be0SXin Li 
866*3e777be0SXin Li     hidl_vec<uint32_t> inputToOutputWeightsDimensions{numUnits, inputSize};
867*3e777be0SXin Li     std::vector<int8_t> inputToOutputWeightsValue { -102, -51, -25, -115, -13,
868*3e777be0SXin Li                                                     -89,  38, -38, -102, -25,
869*3e777be0SXin Li                                                     77, -25,  51,  -89, -38,
870*3e777be0SXin Li                                                     -64,  13,  64,  -77, -51 };
871*3e777be0SXin Li 
872*3e777be0SXin Li     hidl_vec<uint32_t> recurrentToInputWeightsDimensions{0, 0};
873*3e777be0SXin Li     std::vector<int8_t> recurrentToInputWeightsValue;
874*3e777be0SXin Li 
875*3e777be0SXin Li     hidl_vec<uint32_t> recurrentToForgetWeightsDimensions{numUnits, outputSize};
876*3e777be0SXin Li     std::vector<int8_t> recurrentToForgetWeightsValue { -64, -38, -64, -25,
877*3e777be0SXin Li                                                         77,  51, 115,  38,
878*3e777be0SXin Li                                                         -13,  25,  64,  25,
879*3e777be0SXin Li                                                         25,  38, -13,  51 };
880*3e777be0SXin Li 
881*3e777be0SXin Li     hidl_vec<uint32_t> recurrentToCellWeightsDimensions{numUnits, outputSize};
882*3e777be0SXin Li     std::vector<int8_t> recurrentToCellWeightsValue { -38,  25,  13, -38,
883*3e777be0SXin Li                                                       102, -10, -25,  38,
884*3e777be0SXin Li                                                       102, -77, -13,  25,
885*3e777be0SXin Li                                                       38, -13,  25,  64 };
886*3e777be0SXin Li 
887*3e777be0SXin Li     hidl_vec<uint32_t> recurrentToOutputWeightsDimensions{numUnits, outputSize};
888*3e777be0SXin Li     std::vector<int8_t> recurrentToOutputWeightsValue {  38, -13,  13, -25,
889*3e777be0SXin Li                                                          -64, -89, -25, -77,
890*3e777be0SXin Li                                                          -13, -51, -89, -25,
891*3e777be0SXin Li                                                          13,  64,  25, -38 };
892*3e777be0SXin Li 
893*3e777be0SXin Li     hidl_vec<uint32_t> cellToInputWeightsDimensions{0};
894*3e777be0SXin Li     std::vector<int16_t> cellToInputWeightsValue;
895*3e777be0SXin Li 
896*3e777be0SXin Li     hidl_vec<uint32_t> cellToForgetWeightsDimensions{0};
897*3e777be0SXin Li     std::vector<int16_t> cellToForgetWeightsValue;
898*3e777be0SXin Li 
899*3e777be0SXin Li     hidl_vec<uint32_t> cellToOutputWeightsDimensions{0};
900*3e777be0SXin Li     std::vector<int16_t> cellToOutputWeightsValue;
901*3e777be0SXin Li 
902*3e777be0SXin Li     hidl_vec<uint32_t> inputGateBiasDimensions{0};
903*3e777be0SXin Li     std::vector<int32_t> inputGateBiasValue;
904*3e777be0SXin Li 
905*3e777be0SXin Li     hidl_vec<uint32_t> forgetGateBiasDimensions{numUnits};
906*3e777be0SXin Li     std::vector<int32_t> forgetGateBiasValue { 2147484, -6442451, -4294968, 2147484 };
907*3e777be0SXin Li 
908*3e777be0SXin Li     hidl_vec<uint32_t> cellBiasDimensions{numUnits};
909*3e777be0SXin Li     std::vector<int32_t> cellBiasValue { -1073742, 15461883, 5368709, 1717987 };
910*3e777be0SXin Li 
911*3e777be0SXin Li     hidl_vec<uint32_t> outputGateBiasDimensions{numUnits};
912*3e777be0SXin Li     std::vector<int32_t> outputGateBiasValue { 1073742, -214748, 4294968, 2147484 };
913*3e777be0SXin Li 
914*3e777be0SXin Li     hidl_vec<uint32_t> projectionWeightsDimensions{0, 0};
915*3e777be0SXin Li     std::vector<int8_t> projectionWeightsValue;
916*3e777be0SXin Li 
917*3e777be0SXin Li     hidl_vec<uint32_t> projectionBiasDimensions{0};
918*3e777be0SXin Li     std::vector<int32_t> projectionBiasValue;
919*3e777be0SXin Li 
920*3e777be0SXin Li     hidl_vec<uint32_t> outputStateInDimensions{batchSize, outputSize};
921*3e777be0SXin Li     std::vector<int8_t> outputStateInValue { 0, 0, 0, 0, 0, 0, 0, 0 };
922*3e777be0SXin Li 
923*3e777be0SXin Li     hidl_vec<uint32_t> cellStateInDimensions{batchSize, numUnits};
924*3e777be0SXin Li     std::vector<int16_t> cellStateInValue { 0, 0, 0, 0, 0, 0, 0, 0 };
925*3e777be0SXin Li 
926*3e777be0SXin Li     // Normalization:
927*3e777be0SXin Li     hidl_vec<uint32_t> inputLayerNormWeightsDimensions{0};
928*3e777be0SXin Li     std::vector<int16_t> inputLayerNormWeightsValue;
929*3e777be0SXin Li 
930*3e777be0SXin Li     hidl_vec<uint32_t> forgetLayerNormWeightsDimensions{numUnits};
931*3e777be0SXin Li     std::vector<int16_t> forgetLayerNormWeightsValue { 6553, 6553, 13107, 9830 };
932*3e777be0SXin Li 
933*3e777be0SXin Li     hidl_vec<uint32_t> cellLayerNormWeightsDimensions{numUnits};
934*3e777be0SXin Li     std::vector<int16_t> cellLayerNormWeightsValue { 22937, 6553, 9830, 26214 };
935*3e777be0SXin Li 
936*3e777be0SXin Li     hidl_vec<uint32_t> outputLayerNormWeightsDimensions{numUnits};
937*3e777be0SXin Li     std::vector<int16_t> outputLayerNormWeightsValue { 19660, 6553, 6553, 16384 };
938*3e777be0SXin Li 
939*3e777be0SXin Li     float cellClipValue           = 0.0f;
940*3e777be0SXin Li     float projectionClipValue     = 0.0f;
941*3e777be0SXin Li     float inputIntermediateScale  = 0.007059f;
942*3e777be0SXin Li     float forgetIntermediateScale = 0.007812f;
943*3e777be0SXin Li     float cellIntermediateScale   = 0.007059f;
944*3e777be0SXin Li     float outputIntermediateScale = 0.007812f;
945*3e777be0SXin Li     int32_t hiddenStateZeroPoint  = 0;
946*3e777be0SXin Li     float hiddenStateScale        = 0.007f;
947*3e777be0SXin Li 
948*3e777be0SXin Li     // Outputs:
949*3e777be0SXin Li     hidl_vec<uint32_t> outputStateOutDimensions{batchSize, outputSize};
950*3e777be0SXin Li     std::vector<int8_t> outputStateOutValue { -15, 21, 14, 20, -15, 15, 5, 27 };
951*3e777be0SXin Li 
952*3e777be0SXin Li     hidl_vec<uint32_t> cellStateOutDimensions{};
953*3e777be0SXin Li     std::vector<int16_t> cellStateOutValue { -11692, 9960, 5491, 8861, -9422, 7726, 2056, 13149 };
954*3e777be0SXin Li 
955*3e777be0SXin Li     hidl_vec<uint32_t> outputDimensions{batchSize, outputSize};
956*3e777be0SXin Li     std::vector<int8_t> outputValue { -15, 21, 14, 20, -15, 15, 5, 27 };
957*3e777be0SXin Li 
958*3e777be0SXin Li     QLstmTestImpl(inputDimensions,                       inputValue,
959*3e777be0SXin Li                   inputToInputWeightsDimensions,         inputToInputWeightsValue,
960*3e777be0SXin Li                   inputToForgetWeightsDimensions,        inputToForgetWeightsValue,
961*3e777be0SXin Li                   inputToCellWeightsDimensions,          inputToCellWeightsValue,
962*3e777be0SXin Li                   inputToOutputWeightsDimensions,        inputToOutputWeightsValue,
963*3e777be0SXin Li                   recurrentToInputWeightsDimensions,     recurrentToInputWeightsValue,
964*3e777be0SXin Li                   recurrentToForgetWeightsDimensions,    recurrentToForgetWeightsValue,
965*3e777be0SXin Li                   recurrentToCellWeightsDimensions,      recurrentToCellWeightsValue,
966*3e777be0SXin Li                   recurrentToOutputWeightsDimensions,    recurrentToOutputWeightsValue,
967*3e777be0SXin Li                   cellToInputWeightsDimensions,          cellToInputWeightsValue,
968*3e777be0SXin Li                   cellToForgetWeightsDimensions,         cellToForgetWeightsValue,
969*3e777be0SXin Li                   cellToOutputWeightsDimensions,         cellToOutputWeightsValue,
970*3e777be0SXin Li                   inputGateBiasDimensions,               inputGateBiasValue,
971*3e777be0SXin Li                   forgetGateBiasDimensions,              forgetGateBiasValue,
972*3e777be0SXin Li                   cellBiasDimensions,                    cellBiasValue,
973*3e777be0SXin Li                   outputGateBiasDimensions,              outputGateBiasValue,
974*3e777be0SXin Li                   projectionWeightsDimensions,           projectionWeightsValue,
975*3e777be0SXin Li                   projectionBiasDimensions,              projectionBiasValue,
976*3e777be0SXin Li                   outputStateInDimensions,               outputStateInValue,
977*3e777be0SXin Li                   cellStateInDimensions,                 cellStateInValue,
978*3e777be0SXin Li                   inputLayerNormWeightsDimensions,       inputLayerNormWeightsValue,
979*3e777be0SXin Li                   forgetLayerNormWeightsDimensions,      forgetLayerNormWeightsValue,
980*3e777be0SXin Li                   cellLayerNormWeightsDimensions,        cellLayerNormWeightsValue,
981*3e777be0SXin Li                   outputLayerNormWeightsDimensions,      outputLayerNormWeightsValue,
982*3e777be0SXin Li                   cellClipValue,
983*3e777be0SXin Li                   projectionClipValue,
984*3e777be0SXin Li                   inputIntermediateScale,
985*3e777be0SXin Li                   forgetIntermediateScale,
986*3e777be0SXin Li                   cellIntermediateScale,
987*3e777be0SXin Li                   outputIntermediateScale,
988*3e777be0SXin Li                   hiddenStateZeroPoint,
989*3e777be0SXin Li                   hiddenStateScale,
990*3e777be0SXin Li                   outputStateOutDimensions,              outputStateOutValue,
991*3e777be0SXin Li                   cellStateOutDimensions,                cellStateOutValue,
992*3e777be0SXin Li                   outputDimensions,                      outputValue,
993*3e777be0SXin Li                   compute);
994*3e777be0SXin Li }
995*3e777be0SXin Li 
996*3e777be0SXin Li } // anonymous namespace
997*3e777be0SXin Li 
998*3e777be0SXin Li // Support is not added yet
999*3e777be0SXin Li //TEST_CASE(QLSTMWithProjectionTest, COMPUTE_DEVICES)
1000*3e777be0SXin Li //{
1001*3e777be0SXin Li //     QLstmWithProjection(sample);
1002*3e777be0SXin Li //}
1003*3e777be0SXin Li 
1004*3e777be0SXin Li DOCTEST_TEST_SUITE("QLSTMTests_CpuRef")
1005*3e777be0SXin Li {
1006*3e777be0SXin Li 
1007*3e777be0SXin Li     DOCTEST_TEST_CASE("QLSTMWithNoProjectionTest_CpuRef")
1008*3e777be0SXin Li     {
1009*3e777be0SXin Li         QLstmWithNoProjection(armnn::Compute::CpuRef);
1010*3e777be0SXin Li     }
1011*3e777be0SXin Li 
1012*3e777be0SXin Li     DOCTEST_TEST_CASE("DynamicOutputQLstmWithNoProjection_CpuRef")
1013*3e777be0SXin Li     {
1014*3e777be0SXin Li         DynamicOutputQLstmWithNoProjection(armnn::Compute::CpuRef);
1015*3e777be0SXin Li     }
1016*3e777be0SXin Li 
1017*3e777be0SXin Li }
1018*3e777be0SXin Li #ifdef ARMCOMPUTECL_ENABLED
1019*3e777be0SXin Li DOCTEST_TEST_SUITE("QLSTMTests_CpuAcc")
1020*3e777be0SXin Li {
1021*3e777be0SXin Li 
1022*3e777be0SXin Li     DOCTEST_TEST_CASE("QLSTMWithNoProjectionTest_CpuAcc")
1023*3e777be0SXin Li     {
1024*3e777be0SXin Li         QLstmWithNoProjection(armnn::Compute::CpuAcc);
1025*3e777be0SXin Li     }
1026*3e777be0SXin Li 
1027*3e777be0SXin Li     DOCTEST_TEST_CASE("DynamicOutputQLstmWithNoProjection_CpuAcc")
1028*3e777be0SXin Li     {
1029*3e777be0SXin Li         DynamicOutputQLstmWithNoProjection(armnn::Compute::CpuAcc);
1030*3e777be0SXin Li     }
1031*3e777be0SXin Li 
1032*3e777be0SXin Li }
1033*3e777be0SXin Li #endif
1034