ArmNN
 20.02
LstmTestImpl.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "LstmTestImpl.hpp"
7 
8 #include <QuantizeHelper.hpp>
9 
10 
12 
15 
19 
20 #include <test/TensorHelpers.hpp>
21 
22 #include <boost/multi_array.hpp>
23 
24 namespace
25 {
26 
27 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
28 void LstmUtilsVectorBatchVectorAddTestImpl(
29  boost::multi_array<float, 1>& vec,
30  boost::multi_array<float, 2>& batchVec,
31  uint32_t vSize,
32  uint32_t nBatch,
33  boost::multi_array<float, 2>& expectedOutput )
34 {
35  float qScale = 0.0f;
36  int32_t qOffset = 0;
37  armnn::TensorInfo tensorInfo({nBatch, vSize}, ArmnnType, qScale, qOffset );
38 
39  // Make encoder and decoder
40  std::unique_ptr<armnn::Decoder<float>> vecDecoder = armnn::MakeDecoder<float>(tensorInfo, vec.data());
41  std::unique_ptr<armnn::Decoder<float>> batchVecDecoder = armnn::MakeDecoder<float>(tensorInfo, batchVec.data());
42  std::unique_ptr<armnn::Encoder<float>> batchVecEncoder = armnn::MakeEncoder<float>(tensorInfo, batchVec.data());
43 
44  VectorBatchVectorAdd(*vecDecoder, vSize, *batchVecDecoder, nBatch, *batchVecEncoder);
45 
46  // check shape and compare values
47  BOOST_TEST(CompareTensors(batchVec, expectedOutput));
48 
49  // check if iterator is back at start position
50  batchVecEncoder->Set(1.0f);
51  BOOST_TEST(batchVec[0][0] == 1.0f);
52 }
53 
54 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
55 void LstmUtilsZeroVectorTestImpl(
56  boost::multi_array<float, 1>& input,
57  uint32_t vSize,
58  boost::multi_array<float, 1>& expectedOutput)
59 {
60  float qScale = 0.0f;
61  int32_t qOffset = 0;
62 
63  armnn::TensorInfo tensorInfo({vSize}, ArmnnType, qScale, qOffset );
64 
65  // Make encoder for input
66  std::unique_ptr<armnn::Encoder<float>> outputEncoder = armnn::MakeEncoder<float>(tensorInfo, input.data());
67 
68  // call ZeroVector
69  ZeroVector(*outputEncoder, vSize);
70 
71  // check shape and compare values
72  BOOST_TEST(CompareTensors(input, expectedOutput));
73 
74  // check if iterator is back at start position
75  outputEncoder->Set(1.0f);
76  BOOST_TEST(input[0] == 1.0f);
77 
78 }
79 
80 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
81 void LstmUtilsMeanStddevNormalizationTestImpl(
82  boost::multi_array<float, 2>& input,
83  uint32_t vSize,
84  uint32_t nBatch,
85  boost::multi_array<float, 2>& expectedOutput)
86 {
87  float qScale = 0.0f;
88  int32_t qOffset = 0;
89  armnn::TensorInfo tensorInfo({nBatch, vSize}, ArmnnType, qScale, qOffset );
90 
91  // Make encoder and decoder for input
92  std::unique_ptr<armnn::Decoder<float>> inputDecoder = armnn::MakeDecoder<float>(tensorInfo, input.data());
93  std::unique_ptr<armnn::Encoder<float>> outputEncoder = armnn::MakeEncoder<float>(tensorInfo, input.data());
94 
95  MeanStddevNormalization(*inputDecoder, *outputEncoder, vSize, nBatch, 1e-8f);
96 
97  // check shape and compare values
98  BOOST_TEST(CompareTensors(input, expectedOutput));
99 
100  // check if iterator is back at start position
101  outputEncoder->Set(1.0f);
102  BOOST_TEST(input[0][0] == 1.0f);
103 }
104 
105 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
106 void LstmUtilsVectorBatchVectorCwiseProductTestImpl(
107  boost::multi_array<float, 1>& vec,
108  boost::multi_array<float, 2>& batchVec,
109  uint32_t vSize,
110  uint32_t nBatch,
111  boost::multi_array<float, 2>& expectedOutput)
112 {
113  float qScale = 0.0f;
114  int32_t qOffset = 0;
115  armnn::TensorInfo tensorInfo({nBatch, vSize}, ArmnnType, qScale, qOffset );
116 
117  // Make encoder and decoder
118  std::unique_ptr<armnn::Decoder<float>> vecDecoder = armnn::MakeDecoder<float>(tensorInfo, vec.data());
119  std::unique_ptr<armnn::Decoder<float>> batchVecDecoder = armnn::MakeDecoder<float>(tensorInfo, batchVec.data());
120  std::unique_ptr<armnn::Encoder<float>> batchVecEncoder = armnn::MakeEncoder<float>(tensorInfo, batchVec.data());
121 
122  VectorBatchVectorCwiseProduct(*vecDecoder, vSize, *batchVecDecoder, nBatch, *batchVecEncoder);
123 
124  // check shape and compare values
125  BOOST_TEST(CompareTensors(batchVec, expectedOutput));
126 
127  // check if iterator is back at start position
128  batchVecEncoder->Set(1.0f);
129  BOOST_TEST(batchVec[0][0] == 1.0f);
130 }
131 
132 // Lstm Layer tests:
133 // *********************************** //
134 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
136 LstmNoCifgNoPeepholeNoProjectionTestImpl(
137  armnn::IWorkloadFactory& workloadFactory,
139  const boost::multi_array<T, 2>& input,
140  const boost::multi_array<T, 2>& outputExpected,
141  float qScale = 0.0f,
142  int32_t qOffset = 0,
143  armnn::DataType constantDataType = armnn::DataType::Float32)
144 {
145  IgnoreUnused(memoryManager);
146  unsigned int batchSize = boost::numeric_cast<unsigned int>(input.shape()[0]);
147  unsigned int inputSize = boost::numeric_cast<unsigned int>(input.shape()[1]);
148  unsigned int outputSize = boost::numeric_cast<unsigned int>(outputExpected.shape()[1]);
149  // cellSize and outputSize have the same size when there is no projection.
150  unsigned numUnits = outputSize;
151 
152  armnn::TensorInfo inputTensorInfo({batchSize , inputSize}, ArmnnType, qScale, qOffset );
153  armnn::TensorInfo cellStateInTensorInfo({batchSize , numUnits}, ArmnnType, qScale, qOffset);
154  armnn::TensorInfo outputStateInTensorInfo({batchSize , outputSize}, ArmnnType, qScale, qOffset);
155 
156  armnn::TensorInfo scratchBufferTensorInfo({batchSize, numUnits * 4}, ArmnnType, qScale, qOffset);
157  armnn::TensorInfo cellStateOutTensorInfo({batchSize, numUnits}, ArmnnType, qScale, qOffset);
158  armnn::TensorInfo outputStateOutTensorInfo({batchSize, outputSize}, ArmnnType, qScale, qOffset);
159  armnn::TensorInfo outputTensorInfo({batchSize, outputSize}, ArmnnType, qScale, qOffset);
160 
161  LayerTestResult<T, 2> ret(outputTensorInfo);
162 
163  std::vector<float> inputVector;
164  inputVector.assign(input.data(), input.data() + (batchSize * inputSize));
165  auto inputTensor = MakeTensor<float,2>(inputTensorInfo, inputVector);
166 
167  std::vector<float> cellStateInVector(batchSize * numUnits, 0.f);
168  auto cellStateInTensor = MakeTensor<float,2>(cellStateInTensorInfo, cellStateInVector);
169 
170  std::vector<float> outputStateInVector(batchSize * outputSize, 0.f);
171  auto outputStateInTensor = MakeTensor<float,2>(outputStateInTensorInfo, outputStateInVector);
172 
173  std::vector<float> scratchBufferVector(batchSize * numUnits * 4, 0.f);
174  auto scratchBufferTensor = MakeTensor<float,2>(scratchBufferTensorInfo, scratchBufferVector);
175 
176  std::vector<float> outputStateOutVector(batchSize * outputSize, 0.f);
177  auto outputStateOutTensor = MakeTensor<float,2>(outputStateOutTensorInfo, outputStateOutVector);
178 
179  std::vector<float> cellStateOutVector(batchSize * numUnits, 0.f);
180  auto cellStateOutTensor = MakeTensor<float,2>(cellStateOutTensorInfo, cellStateOutVector);
181 
182  std::vector<float> outputVector;
183  outputVector.assign(outputExpected.data(), outputExpected.data() + (batchSize * outputSize));
184  ret.outputExpected = MakeTensor<float, 2>(outputTensorInfo, outputVector);
185 
186  std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
187  std::unique_ptr<armnn::ITensorHandle> cellStateInHandle =
188  workloadFactory.CreateTensorHandle(cellStateInTensorInfo);
189  std::unique_ptr<armnn::ITensorHandle> outputStateInHandle =
190  workloadFactory.CreateTensorHandle(outputStateInTensorInfo);
191 
192  std::unique_ptr<armnn::ITensorHandle> scratchHandle = workloadFactory.CreateTensorHandle(scratchBufferTensorInfo);
193  std::unique_ptr<armnn::ITensorHandle> outputStateOutHandle =
194  workloadFactory.CreateTensorHandle(outputStateOutTensorInfo);
195  std::unique_ptr<armnn::ITensorHandle> cellStateOutHandle =
196  workloadFactory.CreateTensorHandle(cellStateOutTensorInfo);
197  std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
198 
199 
202 
203  AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
204  AddInputToWorkload(data, info, outputStateInTensorInfo, outputStateInHandle.get());
205  AddInputToWorkload(data, info, cellStateInTensorInfo, cellStateInHandle.get());
206 
207  AddOutputToWorkload(data, info, scratchBufferTensorInfo, scratchHandle.get());
208  AddOutputToWorkload(data, info, outputStateOutTensorInfo, outputStateOutHandle.get());
209  AddOutputToWorkload(data, info, cellStateOutTensorInfo, cellStateOutHandle.get());
210  AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
211 
212  armnn::TensorInfo tensorInfo4({numUnits}, constantDataType , qScale, qOffset);
213  armnn::TensorInfo tensorInfo8({numUnits, 2}, constantDataType, qScale, qOffset);
214  armnn::TensorInfo tensorInfo16({numUnits, 4}, constantDataType, qScale, qOffset);
215 
216  auto inputToInputWeights = MakeTensor<float, 2>(tensorInfo8, {-0.45018822f, -0.02338299f, -0.0870589f,
217  -0.34550029f, 0.04266912f, -0.15680569f,
218  -0.34856534f, 0.43890524f});
219 
220  auto inputToForgetWeights = MakeTensor<float, 2>(tensorInfo8, {0.09701663f, 0.20334584f, -0.50592935f,
221  -0.31343272f, -0.40032279f, 0.44781327f,
222  0.01387155f, -0.35593212f});
223 
224  auto inputToCellWeights = MakeTensor<float, 2>(tensorInfo8, {-0.50013041f, 0.1370284f, 0.11810488f, 0.2013163f,
225  -0.20583314f, 0.44344562f, 0.22077113f,
226  -0.29909778f});
227 
228  auto inputToOutputWeights = MakeTensor<float, 2>(tensorInfo8, {-0.25065863f, -0.28290087f, 0.04613829f,
229  0.40525138f, 0.44272184f, 0.03897077f,
230  -0.1556896f, 0.19487578f});
231 
232  auto recurrentToInputWeights = MakeTensor<float, 2>(tensorInfo16, {-0.0063535f, -0.2042388f, 0.31454784f,
233  -0.35746509f, 0.28902304f, 0.08183324f,
234  -0.16555229f, 0.02286911f, -0.13566875f,
235  0.03034258f, 0.48091322f, -0.12528998f,
236  0.24077177f, -0.51332325f, -0.33502164f,
237  0.10629296f});
238 
239  auto recurrentToForgetWeights = MakeTensor<float, 2>(tensorInfo16, {-0.48684245f, -0.06655136f, 0.42224967f,
240  0.2112639f, 0.27654213f, 0.20864892f,
241  -0.07646349f, 0.45877004f, 0.00141793f,
242  -0.14609534f, 0.36447752f, 0.09196436f,
243  0.28053468f, 0.01560611f, -0.20127171f,
244  -0.01140004f});
245 
246  auto recurrentToCellWeights = MakeTensor<float, 2>(tensorInfo16, {-0.3407414f, 0.24443203f, -0.2078532f,
247  0.26320225f, 0.05695659f, -0.00123841f,
248  -0.4744786f, -0.35869038f, -0.06418842f,
249  -0.13502428f, -0.501764f, 0.22830659f,
250  -0.46367589f, 0.26016325f, -0.03894562f,
251  -0.16368064f});
252 
253  auto recurrentToOutputWeights = MakeTensor<float, 2>(tensorInfo16, {0.43385774f, -0.17194885f, 0.2718237f,
254  0.09215671f, 0.24107647f, -0.39835793f,
255  0.18212086f, 0.01301402f, 0.48572797f,
256  -0.50656658f, 0.20047462f, -0.20607421f,
257  -0.51818722f, -0.15390486f, 0.0468148f,
258  0.39922136f});
259 
260  auto cellToInputWeights = MakeTensor<float, 1>(tensorInfo4, {0., 0., 0., 0.});
261 
262  auto inputGateBias = MakeTensor<float, 1>(tensorInfo4, {0., 0., 0., 0.});
263 
264  auto forgetGateBias = MakeTensor<float, 1>(tensorInfo4, {1., 1., 1., 1.});
265 
266  auto cellBias = MakeTensor<float, 1>(tensorInfo4, {0., 0., 0., 0.});
267 
268  auto outputGateBias = MakeTensor<float, 1>(tensorInfo4, {0., 0., 0., 0.});
269 
270  armnn::ScopedCpuTensorHandle inputToInputWeightsTensor(tensorInfo8);
271  armnn::ScopedCpuTensorHandle inputToForgetWeightsTensor(tensorInfo8);
272  armnn::ScopedCpuTensorHandle inputToCellWeightsTensor(tensorInfo8);
273  armnn::ScopedCpuTensorHandle inputToOutputWeightsTensor(tensorInfo8);
274  armnn::ScopedCpuTensorHandle recurrentToInputWeightsTensor(tensorInfo16);
275  armnn::ScopedCpuTensorHandle recurrentToForgetWeightsTensor(tensorInfo16);
276  armnn::ScopedCpuTensorHandle recurrentToCellWeightsTensor(tensorInfo16);
277  armnn::ScopedCpuTensorHandle recurrentToOutputWeightsTensor(tensorInfo16);
278  armnn::ScopedCpuTensorHandle cellToInputWeightsTensor(tensorInfo4);
279  armnn::ScopedCpuTensorHandle inputGateBiasTensor(tensorInfo4);
280  armnn::ScopedCpuTensorHandle forgetGateBiasTensor(tensorInfo4);
281  armnn::ScopedCpuTensorHandle cellBiasTensor(tensorInfo4);
282  armnn::ScopedCpuTensorHandle outputGateBiasTensor(tensorInfo4);
283 
284  AllocateAndCopyDataToITensorHandle(&inputToInputWeightsTensor, &inputToInputWeights[0][0]);
285  AllocateAndCopyDataToITensorHandle(&inputToForgetWeightsTensor, &inputToForgetWeights[0][0]);
286  AllocateAndCopyDataToITensorHandle(&inputToCellWeightsTensor, &inputToCellWeights[0][0]);
287  AllocateAndCopyDataToITensorHandle(&inputToOutputWeightsTensor, &inputToOutputWeights[0][0]);
288  AllocateAndCopyDataToITensorHandle(&recurrentToInputWeightsTensor, &recurrentToInputWeights[0][0]);
289  AllocateAndCopyDataToITensorHandle(&recurrentToForgetWeightsTensor, &recurrentToForgetWeights[0][0]);
290  AllocateAndCopyDataToITensorHandle(&recurrentToCellWeightsTensor, &recurrentToCellWeights[0][0]);
291  AllocateAndCopyDataToITensorHandle(&recurrentToOutputWeightsTensor, &recurrentToOutputWeights[0][0]);
292  AllocateAndCopyDataToITensorHandle(&cellToInputWeightsTensor, &cellToInputWeights[0]);
293  AllocateAndCopyDataToITensorHandle(&inputGateBiasTensor, &inputGateBias[0]);
294  AllocateAndCopyDataToITensorHandle(&forgetGateBiasTensor, &forgetGateBias[0]);
295  AllocateAndCopyDataToITensorHandle(&cellBiasTensor, &cellBias[0]);
296  AllocateAndCopyDataToITensorHandle(&outputGateBiasTensor, &outputGateBias[0]);
297 
298  data.m_InputToInputWeights = &inputToInputWeightsTensor;
299  data.m_InputToForgetWeights = &inputToForgetWeightsTensor;
300  data.m_InputToCellWeights = &inputToCellWeightsTensor;
301  data.m_InputToOutputWeights = &inputToOutputWeightsTensor;
302  data.m_RecurrentToInputWeights = &recurrentToInputWeightsTensor;
303  data.m_RecurrentToForgetWeights = &recurrentToForgetWeightsTensor;
304  data.m_RecurrentToCellWeights = &recurrentToCellWeightsTensor;
305  data.m_RecurrentToOutputWeights = &recurrentToOutputWeightsTensor;
306  data.m_InputGateBias = &inputGateBiasTensor;
307  data.m_ForgetGateBias = &forgetGateBiasTensor;
308  data.m_CellBias = &cellBiasTensor;
309  data.m_OutputGateBias = &outputGateBiasTensor;
310 
311  // Flags to set test configuration
313  data.m_Parameters.m_CifgEnabled = false;
314  data.m_Parameters.m_PeepholeEnabled = false;
315  data.m_Parameters.m_ProjectionEnabled = false;
316 
317  std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateLstm(data, info);
318  inputHandle->Allocate();
319  outputStateInHandle->Allocate();
320  cellStateInHandle->Allocate();
321 
322  scratchHandle->Allocate();
323  outputStateOutHandle->Allocate();
324  cellStateOutHandle->Allocate();
325  outputHandle->Allocate();
326 
327  CopyDataToITensorHandle(inputHandle.get(), &inputTensor[0][0]);
328  CopyDataToITensorHandle(outputStateInHandle.get(), &outputStateInTensor[0][0]);
329  CopyDataToITensorHandle(cellStateInHandle.get(), &cellStateInTensor[0][0]);
330 
331  workload->Execute();
332 
333  CopyDataFromITensorHandle(&ret.output[0][0], outputHandle.get());
334 
335  return ret;
336 }
337 
338 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
340 LstmLayerNoCifgWithPeepholeWithProjectionTestImpl(armnn::IWorkloadFactory& workloadFactory,
342  const boost::multi_array<T, 2>& input,
343  const boost::multi_array<T, 2>& outputExpected,
344  float qScale = 0.0f,
345  int32_t qOffset = 0,
346  armnn::DataType constantDataType = armnn::DataType::Float32)
347 {
348  IgnoreUnused(memoryManager);
349  unsigned int batchSize = 2;
350  unsigned int outputSize = 16;
351  unsigned int inputSize = 5;
352  unsigned numUnits = 20;
353 
354  armnn::TensorInfo inputTensorInfo({batchSize , inputSize}, ArmnnType, qScale, qOffset);
355  armnn::TensorInfo cellStateInTensorInfo({batchSize , numUnits}, ArmnnType, qScale, qOffset);
356  armnn::TensorInfo outputStateInTensorInfo({batchSize , outputSize}, ArmnnType, qScale, qOffset);
357 
358  // Scratch buffer size without CIFG [batchSize, numUnits * 4]
359  armnn::TensorInfo scratchBufferTensorInfo({batchSize, numUnits * 4}, ArmnnType, qScale, qOffset);
360  armnn::TensorInfo cellStateOutTensorInfo({batchSize, numUnits}, ArmnnType, qScale, qOffset);
361  armnn::TensorInfo outputStateOutTensorInfo({batchSize, outputSize}, ArmnnType, qScale, qOffset);
362  armnn::TensorInfo outputTensorInfo({batchSize, outputSize}, ArmnnType, qScale, qOffset);
363 
364  LayerTestResult<T, 2> ret(outputTensorInfo);
365 
366  std::vector<float> inputVector;
367  inputVector.assign(input.data(), input.data() + (batchSize * inputSize));
368  auto inputTensor = MakeTensor<float,2>(inputTensorInfo, inputVector);
369 
370  std::vector<float> cellStateInVector(batchSize * numUnits, 0.f);
371  auto cellStateInTensor = MakeTensor<float,2>(cellStateInTensorInfo, cellStateInVector);
372 
373  std::vector<float> outputStateInVector(batchSize * outputSize, 0.f);
374  auto outputStateInTensor = MakeTensor<float,2>(outputStateInTensorInfo, outputStateInVector);
375 
376  std::vector<float> scratchBufferVector(batchSize * numUnits * 4, 0.f);
377  auto scratchBufferTensor = MakeTensor<float,2>(scratchBufferTensorInfo, scratchBufferVector);
378 
379  std::vector<float> outputStateOutVector(batchSize * outputSize, 0.f);
380  auto outputStateOutTensor = MakeTensor<float,2>(outputStateOutTensorInfo, outputStateOutVector);
381 
382  std::vector<float> cellStateOutVector(batchSize * numUnits, 0.f);
383  auto cellStateOutTensor = MakeTensor<float,2>(cellStateOutTensorInfo, cellStateOutVector);
384 
385  std::vector<float> outputVector;
386  outputVector.assign(outputExpected.data(), outputExpected.data() + (batchSize * outputSize));
387  ret.outputExpected = MakeTensor<float, 2>(outputTensorInfo, outputVector);
388 
389  std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
390  std::unique_ptr<armnn::ITensorHandle> cellStateInHandle =
391  workloadFactory.CreateTensorHandle(cellStateInTensorInfo);
392  std::unique_ptr<armnn::ITensorHandle> outputStateInHandle =
393  workloadFactory.CreateTensorHandle(outputStateInTensorInfo);
394 
395  std::unique_ptr<armnn::ITensorHandle> scratchHandle = workloadFactory.CreateTensorHandle(scratchBufferTensorInfo);
396  std::unique_ptr<armnn::ITensorHandle> outputStateOutHandle =
397  workloadFactory.CreateTensorHandle(outputStateOutTensorInfo);
398  std::unique_ptr<armnn::ITensorHandle> cellStateOutHandle =
399  workloadFactory.CreateTensorHandle(cellStateOutTensorInfo);
400  std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
401 
403  armnn::WorkloadInfo info;
404 
405  AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
406  AddInputToWorkload(data, info, outputStateInTensorInfo, outputStateInHandle.get());
407  AddInputToWorkload(data, info, cellStateInTensorInfo, cellStateInHandle.get());
408 
409  AddOutputToWorkload(data, info, scratchBufferTensorInfo, scratchHandle.get());
410  AddOutputToWorkload(data, info, outputStateOutTensorInfo, outputStateOutHandle.get());
411  AddOutputToWorkload(data, info, cellStateOutTensorInfo, cellStateOutHandle.get());
412  AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
413 
414  armnn::TensorInfo tensorInfo16({outputSize}, constantDataType, qScale, qOffset);
415  armnn::TensorInfo tensorInfo20({numUnits}, constantDataType, qScale, qOffset);
416  armnn::TensorInfo tensorInfo20x5({numUnits, inputSize}, constantDataType, qScale, qOffset);
417  armnn::TensorInfo tensorInfo20x16({numUnits, outputSize}, constantDataType, qScale, qOffset);
418  armnn::TensorInfo tensorInfo16x20({outputSize, numUnits}, constantDataType, qScale, qOffset);
419 
420  auto inputToInputWeights =
421  MakeTensor<float, 2>(tensorInfo20x5, {0.021393683f,0.06124551f, 0.046905167f,-0.014657677f,-0.03149463f,
422  0.09171803f, 0.14647801f,0.10797193f, -0.0057968358f,0.0019193048f,
423  -0.2726754f, 0.10154029f, -0.018539885f, 0.080349885f, -0.10262385f,
424  -0.022599787f,-0.09121155f, -0.008675967f, -0.045206103f,-0.0821282f,
425  -0.008045952f,0.015478081f, 0.055217247f, 0.038719587f, 0.044153627f,
426  -0.06453243f,0.05031825f, -0.046935108f, -0.008164439f, 0.014574226f,
427  -0.1671009f, -0.15519552f, -0.16819797f,-0.13971269f,-0.11953059f,
428  0.25005487f, -0.22790983f, 0.009855087f, -0.028140958f, -0.11200698f,
429  0.11295408f, -0.0035217577f, 0.054485075f, 0.05184695f, 0.064711206f,
430  0.10989193f, 0.11674786f, 0.03490607f, 0.07727357f, 0.11390585f,
431  -0.1863375f, -0.1034451f, -0.13945189f, -0.049401227f, -0.18767063f,
432  0.042483903f, 0.14233552f, 0.13832581f, 0.18350165f, 0.14545603f,
433  -0.028545704f,0.024939531f,0.050929718f,0.0076203286f,-0.0029723682f,
434  -0.042484224f, -0.11827596f, -0.09171104f, -0.10808628f,-0.16327988f,
435  -0.2273378f, -0.0993647f, -0.017155107f,0.0023917493f,0.049272764f,
436  0.0038534778f, 0.054764505f, 0.089753784f, 0.06947234f, 0.08014476f,
437  -0.04544234f, -0.0497073f,-0.07135631f, -0.048929106f,-0.004042012f,
438  -0.009284026f, 0.018042054f, 0.0036860977f,-0.07427302f, -0.11434604f,
439  -0.018995456f, 0.031487543f, 0.012834908f,0.019977754f,0.044256654f,
440  -0.39292613f, -0.18519334f, -0.11651281f,-0.06809892f, 0.011373677f
441  });
442 
443  auto inputToForgetWeights =
444  MakeTensor<float, 2>(tensorInfo20x5, {-0.0018401089f, -0.004852237f,0.03698424f, 0.014181704f,0.028273236f,
445  -0.016726194f, -0.05249759f,-0.10204261f, 0.00861066f,-0.040979505f,
446  -0.009899187f,0.01923892f,-0.028177269f, -0.08535103f,-0.14585495f,
447  0.10662567f,-0.01909731f,-0.017883534f,-0.0047269356f,-0.045103323f,
448  0.0030784295f,0.076784775f,0.07463696f, 0.094531395f,0.0814421f,
449  -0.12257899f, -0.033945758f,-0.031303465f, 0.045630626f,0.06843887f,
450  -0.13492945f, -0.012480007f,-0.0811829f, -0.07224499f,-0.09628791f,
451  0.045100946f,0.0012300825f, 0.013964662f, 0.099372394f,0.02543059f,
452  0.06958324f, 0.034257296f, 0.0482646f, 0.06267997f,0.052625068f,
453  0.12784666f, 0.07077897f, 0.025725935f, 0.04165009f,0.07241905f,
454  0.018668644f, -0.037377294f,-0.06277783f,-0.08833636f,-0.040120605f,
455  -0.011405586f,-0.007808335f,-0.010301386f,-0.005102167f,0.027717464f,
456  0.05483423f, 0.11449111f, 0.11289652f,0.10939839f, 0.13396506f,
457  -0.08402166f,-0.01901462f, -0.044678304f,-0.07720565f,0.014350063f,
458  -0.11757958f, -0.0652038f, -0.08185733f,-0.076754324f,-0.092614375f,
459  0.10405491f, 0.052960336f, 0.035755895f,0.035839386f,-0.012540553f,
460  0.036881298f, 0.02913376f, 0.03420159f,0.05448447f,-0.054523353f,
461  0.02582715f, 0.02327355f, -0.011857179f,-0.0011980024f,-0.034641717f,
462  -0.026125094f,-0.17582615f,-0.15923657f,-0.27486774f,-0.0006143371f,
463  0.0001771948f, -8.470171e-05f, 0.02651807f,0.045790765f,0.06956496f
464  });
465 
466  auto inputToCellWeights =
467  MakeTensor<float, 2>(tensorInfo20x5, {-0.04580283f, -0.09549462f, -0.032418985f, -0.06454633f,
468  -0.043528453f, 0.043018587f, -0.049152344f, -0.12418144f,
469  -0.078985475f, -0.07596889f, 0.019484362f, -0.11434962f,
470  -0.0074034138f, -0.06314844f, -0.092981495f, 0.0062155537f,
471  -0.025034338f, -0.0028890965f, 0.048929527f, 0.06235075f,
472  0.10665918f, -0.032036792f, -0.08505916f, -0.10843358f,
473  -0.13002433f, -0.036816437f, -0.02130134f, -0.016518239f,
474  0.0047691227f, -0.0025825808f, 0.066017866f, 0.029991534f,
475  -0.10652836f, -0.1037554f, -0.13056071f, -0.03266643f,
476  -0.033702414f, -0.006473424f, -0.04611692f, 0.014419339f,
477  -0.025174323f, 0.0396852f, 0.081777506f, 0.06157468f,
478  0.10210095f, -0.009658194f, 0.046511717f, 0.03603906f,
479  0.0069369148f, 0.015960095f, -0.06507666f, 0.09551598f,
480  0.053568836f, 0.06408714f, 0.12835667f, -0.008714329f,
481  -0.20211966f, -0.12093674f, 0.029450472f, 0.2849013f,
482  -0.029227901f, 0.1164364f, -0.08560263f, 0.09941786f,
483  -0.036999565f, -0.028842626f, -0.0033637602f, -0.017012902f,
484  -0.09720865f, -0.11193351f, -0.029155117f, -0.017936034f,
485  -0.009768936f, -0.04223324f, -0.036159635f, 0.06505112f,
486  -0.021742892f, -0.023377212f, -0.07221364f, -0.06430552f,
487  0.05453865f, 0.091149814f, 0.06387331f, 0.007518393f,
488  0.055960953f, 0.069779344f, 0.046411168f, 0.10509911f,
489  0.07463894f, 0.0075130584f, 0.012850982f, 0.04555431f,
490  0.056955688f, 0.06555285f, 0.050801456f, -0.009862683f,
491  0.00826772f, -0.026555609f, -0.0073611983f, -0.0014897042f
492  });
493 
494  auto inputToOutputWeights =
495  MakeTensor<float, 2>(tensorInfo20x5, {-0.0998932f, -0.07201956f, -0.052803773f,-0.15629593f,-0.15001918f,
496  -0.07650751f,0.02359855f, -0.075155355f, -0.08037709f, -0.15093534f,
497  0.029517552f, -0.04751393f, 0.010350531f,-0.02664851f, -0.016839722f,
498  -0.023121163f, 0.0077019283f, 0.012851257f, -0.05040649f,-0.0129761f,
499  -0.021737747f,-0.038305793f,-0.06870586f, -0.01481247f,-0.001285394f,
500  0.10124236f, 0.083122835f, 0.053313006f,-0.062235646f,-0.075637154f,
501  -0.027833903f, 0.029774971f, 0.1130802f, 0.09218906f, 0.09506135f,
502  -0.086665764f,-0.037162706f,-0.038880914f,-0.035832845f,-0.014481564f,
503  -0.09825003f,-0.12048569f,-0.097665586f,-0.05287633f, -0.0964047f,
504  -0.11366429f, 0.035777505f, 0.13568819f, 0.052451383f,0.050649304f,
505  0.05798951f, -0.021852335f,-0.099848844f,0.014740475f,-0.078897946f,
506  0.04974699f, 0.014160473f, 0.06973932f, 0.04964942f, 0.033364646f,
507  0.08190124f, 0.025535367f, 0.050893165f, 0.048514254f,0.06945813f,
508  -0.078907564f,-0.06707616f, -0.11844508f, -0.09986688f,-0.07509403f,
509  0.06263226f, 0.14925587f, 0.20188436f, 0.12098451f,0.14639415f,
510  0.0015017595f, -0.014267382f, -0.03417257f,0.012711468f,0.0028300495f,
511  -0.024758482f, -0.05098548f,-0.0821182f, 0.014225672f, 0.021544158f,
512  0.08949725f, 0.07505268f, -0.0020780868f, 0.04908258f,0.06476295f,
513  -0.022907063f,0.027562456f,0.040185735f, 0.019567577f,-0.015598739f,
514  -0.049097303f, -0.017121866f, -0.083368234f,-0.02332002f,-0.0840956f
515  });
516 
517  auto inputGateBias =
518  MakeTensor<float, 1>(tensorInfo20, {0.02234832f, 0.14757581f, 0.18176508f, 0.10380666f, 0.053110216f,
519  -0.06928846f, -0.13942584f, -0.11816189f, 0.19483899f, 0.03652339f,
520  -0.10250295f, 0.036714908f, -0.18426876f, 0.036065217f, 0.21810818f,
521  0.02383196f, -0.043370757f, 0.08690144f, -0.04444982f, 0.00030581196f
522  });
523 
524  auto forgetGateBias =
525  MakeTensor<float, 1>(tensorInfo20, {0.035185695f, -0.042891346f, -0.03032477f, 0.23027696f,
526  0.11098921f, 0.15378423f, 0.09263801f, 0.09790885f,
527  0.09508917f, 0.061199076f, 0.07665568f, -0.015443159f,
528  -0.03499149f, 0.046190713f, 0.08895977f, 0.10899629f,
529  0.40694186f, 0.06030037f, 0.012413437f, -0.06108739f
530  });
531 
532  auto cellBias =
533  MakeTensor<float, 1>(tensorInfo20, {-0.024379363f, 0.0055531194f, 0.23377132f, 0.033463873f,
534  -0.1483596f, -0.10639995f, -0.091433935f, 0.058573797f,
535  -0.06809782f, -0.07889636f, -0.043246906f, -0.09829136f,
536  -0.4279842f, 0.034901652f, 0.18797937f, 0.0075234566f,
537  0.016178843f, 0.1749513f, 0.13975595f, 0.92058027f
538  });
539 
540  auto outputGateBias =
541  MakeTensor<float, 1>(tensorInfo20, {0.046159424f, -0.0012809046f, 0.03563469f, 0.12648113f, 0.027195795f,
542  0.35373217f, -0.018957434f, 0.008907322f, -0.0762701f, 0.12018895f,
543  0.04216877f, 0.0022856654f, 0.040952638f, 0.3147856f, 0.08225149f,
544  -0.057416286f, -0.14995944f, -0.008040261f, 0.13208859f, 0.029760877f
545  });
546 
547  auto recurrentToInputWeights =
548  MakeTensor<float, 2>(tensorInfo20x16, {-0.001374326f, -0.078856036f, 0.10672688f, 0.029162422f,
549  -0.11585556f, 0.02557986f, -0.13446963f, -0.035785314f,
550  -0.01244275f, 0.025961924f, -0.02337298f, -0.044228926f,
551  -0.055839065f, -0.046598054f, -0.010546039f, -0.06900766f,
552  0.027239809f, 0.022582639f, -0.013296484f, -0.05459212f,
553  0.08981f, -0.045407712f, 0.08682226f, -0.06867011f,
554  -0.14390695f, -0.02916037f, 0.000996957f, 0.091420636f,
555  0.14283475f, -0.07390571f, -0.06402044f, 0.062524505f,
556  -0.093129106f, 0.04860203f, -0.08364217f, -0.08119002f,
557  0.009352075f, 0.22920375f, 0.0016303885f, 0.11583097f,
558  -0.13732095f, 0.012405723f, -0.07551853f, 0.06343048f,
559  0.12162708f, -0.031923793f, -0.014335606f, 0.01790974f,
560  -0.10650317f, -0.0724401f, 0.08554849f, -0.05727212f,
561  0.06556731f, -0.042729504f, -0.043227166f, 0.011683251f,
562  -0.013082158f, -0.029302018f, -0.010899579f, -0.062036745f,
563  -0.022509435f, -0.00964907f, -0.01567329f, 0.04260106f,
564  -0.07787477f, -0.11576462f, 0.017356863f, 0.048673786f,
565  -0.017577527f, -0.05527947f, -0.082487635f, -0.040137455f,
566  -0.10820036f, -0.04666372f, 0.022746278f, -0.07851417f,
567  0.01068115f, 0.032956902f, 0.022433773f, 0.0026891115f,
568  0.08944216f, -0.0685835f, 0.010513544f, 0.07228705f,
569  0.02032331f, -0.059686817f, -0.0005566496f, -0.086984694f,
570  0.040414046f, -0.1380399f, 0.094208956f, -0.05722982f,
571  0.012092817f, -0.04989123f, -0.086576f, -0.003399834f,
572  -0.04696032f, -0.045747425f, 0.10091314f, 0.048676282f,
573  -0.029037097f, 0.031399418f, -0.0040285117f, 0.047237843f,
574  0.09504992f, 0.041799378f, -0.049185462f, -0.031518843f,
575  -0.10516937f, 0.026374253f, 0.10058866f, -0.0033195973f,
576  -0.041975245f, 0.0073591834f, 0.0033782164f, -0.004325073f,
577  -0.10167381f, 0.042500053f, -0.01447153f, 0.06464186f,
578  -0.017142897f, 0.03312627f, 0.009205989f, 0.024138335f,
579  -0.011337001f, 0.035530265f, -0.010912711f, 0.0706555f,
580  -0.005894094f, 0.051841937f, -0.1401738f, -0.02351249f,
581  0.0365468f, 0.07590991f, 0.08838724f, 0.021681072f,
582  -0.10086113f, 0.019608743f, -0.06195883f, 0.077335775f,
583  0.023646897f, -0.095322326f, 0.02233014f, 0.09756986f,
584  -0.048691444f, -0.009579111f, 0.07595467f, 0.11480546f,
585  -0.09801813f, 0.019894179f, 0.08502348f, 0.004032281f,
586  0.037211012f, 0.068537936f, -0.048005626f, -0.091520436f,
587  -0.028379958f, -0.01556313f, 0.06554592f, -0.045599163f,
588  -0.01672207f, -0.020169014f, -0.011877351f, -0.20212261f,
589  0.010889619f, 0.0047078193f, 0.038385306f, 0.08540671f,
590  -0.017140968f, -0.0035865551f, 0.016678626f, 0.005633034f,
591  0.015963363f, 0.00871737f, 0.060130805f, 0.028611384f,
592  0.10109069f, -0.015060172f, -0.07894427f, 0.06401885f,
593  0.011584063f, -0.024466386f, 0.0047652307f, -0.09041358f,
594  0.030737216f, -0.0046374933f, 0.14215417f, -0.11823516f,
595  0.019899689f, 0.006106124f, -0.027092824f, 0.0786356f,
596  0.05052217f, -0.058925f, -0.011402121f, -0.024987547f,
597  -0.0013661642f, -0.06832946f, -0.015667673f, -0.1083353f,
598  -0.00096863037f, -0.06988685f, -0.053350925f, -0.027275559f,
599  -0.033664223f, -0.07978348f, -0.025200296f, -0.017207067f,
600  -0.058403496f, -0.055697463f, 0.005798788f, 0.12965427f,
601  -0.062582195f, 0.0013350133f, -0.10482091f, 0.0379771f,
602  0.072521195f, -0.0029455067f, -0.13797039f, -0.03628521f,
603  0.013806405f, -0.017858358f, -0.01008298f, -0.07700066f,
604  -0.017081132f, 0.019358726f, 0.0027079724f, 0.004635139f,
605  0.062634714f, -0.02338735f, -0.039547626f, -0.02050681f,
606  0.03385117f, -0.083611414f, 0.002862572f, -0.09421313f,
607  0.058618143f, -0.08598433f, 0.00972939f, 0.023867095f,
608  -0.053934585f, -0.023203006f, 0.07452513f, -0.048767887f,
609  -0.07314807f, -0.056307215f, -0.10433547f, -0.06440842f,
610  0.04328182f, 0.04389765f, -0.020006588f, -0.09076438f,
611  -0.11652589f, -0.021705797f, 0.03345259f, -0.010329105f,
612  -0.025767034f, 0.013057034f, -0.07316461f, -0.10145612f,
613  0.06358255f, 0.18531723f, 0.07759293f, 0.12006465f,
614  0.1305557f, 0.058638252f, -0.03393652f, 0.09622831f,
615  -0.16253184f, -2.4580743e-06f, 0.079869635f, -0.070196845f,
616  -0.005644518f, 0.06857898f, -0.12598175f, -0.035084512f,
617  0.03156317f, -0.12794146f, -0.031963028f, 0.04692781f,
618  0.030070418f, 0.0071660685f, -0.095516115f, -0.004643372f,
619  0.040170413f, -0.062104587f, -0.0037324072f, 0.0554317f,
620  0.08184801f, -0.019164372f, 0.06791302f, 0.034257166f,
621  -0.10307039f, 0.021943003f, 0.046745934f, 0.0790918f,
622  -0.0265588f, -0.007824208f, 0.042546265f, -0.00977924f,
623  -0.0002440307f, -0.017384544f, -0.017990116f, 0.12252321f,
624  -0.014512694f, -0.08251313f, 0.08861942f, 0.13589665f,
625  0.026351685f, 0.012641483f, 0.07466548f, 0.044301085f,
626  -0.045414884f, -0.051112458f, 0.03444247f, -0.08502782f,
627  -0.04106223f, -0.028126027f, 0.028473156f, 0.10467447f
628  });
629 
630  auto recurrentToForgetWeights =
631  MakeTensor<float, 2>(tensorInfo20x16, {-0.057784554f, -0.026057621f, -0.068447545f, -0.022581743f,
632  0.14811787f, 0.10826372f, 0.09471067f, 0.03987225f,
633  -0.0039523416f, 0.00030638507f, 0.053185795f, 0.10572994f,
634  0.08414449f, -0.022036452f, -0.00066928595f, -0.09203576f,
635  0.032950465f, -0.10985798f, -0.023809856f, 0.0021431844f,
636  -0.02196096f, -0.00326074f, 0.00058621005f, -0.074678116f,
637  -0.06193199f, 0.055729095f, 0.03736828f, 0.020123724f,
638  0.061878487f, -0.04729229f, 0.034919553f, -0.07585433f,
639  -0.04421272f, -0.044019096f, 0.085488975f, 0.04058006f,
640  -0.06890133f, -0.030951202f, -0.024628663f, -0.07672815f,
641  0.034293607f, 0.08556707f, -0.05293577f, -0.033561368f,
642  -0.04899627f, 0.0241671f, 0.015736353f, -0.095442444f,
643  -0.029564252f, 0.016493602f, -0.035026584f, 0.022337519f,
644  -0.026871363f, 0.004780428f, 0.0077918363f, -0.03601621f,
645  0.016435321f, -0.03263031f, -0.09543275f, -0.047392778f,
646  0.013454138f, 0.028934088f, 0.01685226f, -0.086110644f,
647  -0.046250615f, -0.01847454f, 0.047608484f, 0.07339695f,
648  0.034546845f, -0.04881143f, 0.009128804f, -0.08802852f,
649  0.03761666f, 0.008096139f, -0.014454086f, 0.014361001f,
650  -0.023502491f, -0.0011840804f, -0.07607001f, 0.001856849f,
651  -0.06509276f, -0.006021153f, -0.08570962f, -0.1451793f,
652  0.060212336f, 0.055259194f, 0.06974018f, 0.049454916f,
653  -0.027794661f, -0.08077226f, -0.016179763f, 0.1169753f,
654  0.17213494f, -0.0056326236f, -0.053934924f, -0.0124349f,
655  -0.11520337f, 0.05409887f, 0.088759385f, 0.0019655675f,
656  0.0042065294f, 0.03881498f, 0.019844765f, 0.041858196f,
657  -0.05695512f, 0.047233116f, 0.038937137f, -0.06542224f,
658  0.014429736f, -0.09719407f, 0.13908425f, -0.05379757f,
659  0.012321099f, 0.082840554f, -0.029899208f, 0.044217527f,
660  0.059855383f, 0.07711018f, -0.045319796f, 0.0948846f,
661  -0.011724666f, -0.0033288454f, -0.033542685f, -0.04764985f,
662  -0.13873616f, 0.040668588f, 0.034832682f, -0.015319203f,
663  -0.018715994f, 0.046002675f, 0.0599172f, -0.043107376f,
664  0.0294216f, -0.002314414f, -0.022424703f, 0.0030315618f,
665  0.0014641669f, 0.0029166266f, -0.11878115f, 0.013738511f,
666  0.12375372f, -0.0006038222f, 0.029104086f, 0.087442465f,
667  0.052958444f, 0.07558703f, 0.04817258f, 0.044462286f,
668  -0.015213451f, -0.08783778f, -0.0561384f, -0.003008196f,
669  0.047060397f, -0.002058388f, 0.03429439f, -0.018839769f,
670  0.024734668f, 0.024614193f, -0.042046934f, 0.09597743f,
671  -0.0043254104f, 0.04320769f, 0.0064070094f, -0.0019131786f,
672  -0.02558259f, -0.022822596f, -0.023273505f, -0.02464396f,
673  -0.10991725f, -0.006240552f, 0.0074488563f, 0.024044557f,
674  0.04383914f, -0.046476185f, 0.028658995f, 0.060410924f,
675  0.050786525f, 0.009452605f, -0.0073054377f, -0.024810238f,
676  0.0052906186f, 0.0066939713f, -0.0020913032f, 0.014515517f,
677  0.015898481f, 0.021362653f, -0.030262267f, 0.016587038f,
678  -0.011442813f, 0.041154444f, -0.007631438f, -0.03423484f,
679  -0.010977775f, 0.036152758f, 0.0066366293f, 0.11915515f,
680  0.02318443f, -0.041350313f, 0.021485701f, -0.10906167f,
681  -0.028218046f, -0.00954771f, 0.020531068f, -0.11995105f,
682  -0.03672871f, 0.024019798f, 0.014255957f, -0.05221243f,
683  -0.00661567f, -0.04630967f, 0.033188973f, 0.10107534f,
684  -0.014027541f, 0.030796422f, -0.10270911f, -0.035999842f,
685  0.15443139f, 0.07684145f, 0.036571592f, -0.035900835f,
686  -0.0034699554f, 0.06209149f, 0.015920248f, -0.031122351f,
687  -0.03858649f, 0.01849943f, 0.13872518f, 0.01503974f,
688  0.069941424f, -0.06948533f, -0.0088794185f, 0.061282158f,
689  -0.047401894f, 0.03100163f, -0.041533746f, -0.10430945f,
690  0.044574402f, -0.01425562f, -0.024290353f, 0.034563623f,
691  0.05866852f, 0.023947537f, -0.09445152f, 0.035450947f,
692  0.02247216f, -0.0042998926f, 0.061146557f, -0.10250651f,
693  0.020881841f, -0.06747029f, 0.10062043f, -0.0023941975f,
694  0.03532124f, -0.016341697f, 0.09685456f, -0.016764693f,
695  0.051808182f, 0.05875331f, -0.04536488f, 0.001626336f,
696  -0.028892258f, -0.01048663f, -0.009793449f, -0.017093895f,
697  0.010987891f, 0.02357273f, -0.00010856845f, 0.0099760275f,
698  -0.001845119f, -0.03551521f, 0.0018358806f, 0.05763657f,
699  -0.01769146f, 0.040995963f, 0.02235177f, -0.060430344f,
700  0.11475477f, -0.023854522f, 0.10071741f, 0.0686208f,
701  -0.014250481f, 0.034261297f, 0.047418304f, 0.08562733f,
702  -0.030519066f, 0.0060542435f, 0.014653856f, -0.038836084f,
703  0.04096551f, 0.032249358f, -0.08355519f, -0.026823482f,
704  0.056386515f, -0.010401743f, -0.028396193f, 0.08507674f,
705  0.014410365f, 0.020995233f, 0.17040324f, 0.11511526f,
706  0.02459721f, 0.0066619175f, 0.025853224f, -0.023133837f,
707  -0.081302024f, 0.017264642f, -0.009585969f, 0.09491168f,
708  -0.051313367f, 0.054532815f, -0.014298593f, 0.10657464f,
709  0.007076659f, 0.10964551f, 0.0409152f, 0.008275321f,
710  -0.07283536f, 0.07937492f, 0.04192024f, -0.1075027f
711  });
712 
713  auto recurrentToCellWeights =
714  MakeTensor<float, 2>(tensorInfo20x16, {-0.037322544f, 0.018592842f, 0.0056175636f, -0.06253426f,
715  0.055647098f, -0.05713207f, -0.05626563f, 0.005559383f,
716  0.03375411f, -0.025757805f, -0.088049285f, 0.06017052f,
717  -0.06570978f, 0.007384076f, 0.035123326f, -0.07920549f,
718  0.053676967f, 0.044480428f, -0.07663568f, 0.0071805613f,
719  0.08089997f, 0.05143358f, 0.038261272f, 0.03339287f,
720  -0.027673481f, 0.044746667f, 0.028349208f, 0.020090483f,
721  -0.019443132f, -0.030755889f, -0.0040000007f, 0.04465846f,
722  -0.021585021f, 0.0031670958f, 0.0053199246f, -0.056117613f,
723  -0.10893326f, 0.076739706f, -0.08509834f, -0.027997585f,
724  0.037871376f, 0.01449768f, -0.09002357f, -0.06111149f,
725  -0.046195522f, 0.0422062f, -0.005683705f, -0.1253618f,
726  -0.012925729f, -0.04890792f, 0.06985068f, 0.037654128f,
727  0.03398274f, -0.004781977f, 0.007032333f, -0.031787455f,
728  0.010868644f, -0.031489216f, 0.09525667f, 0.013939797f,
729  0.0058680447f, 0.0167067f, 0.02668468f, -0.04797466f,
730  -0.048885044f, -0.12722108f, 0.035304096f, 0.06554885f,
731  0.00972396f, -0.039238118f, -0.05159735f, -0.11329045f,
732  0.1613692f, -0.03750952f, 0.06529313f, -0.071974665f,
733  -0.11769596f, 0.015524369f, -0.0013754242f, -0.12446318f,
734  0.02786344f, -0.014179351f, 0.005264273f, 0.14376344f,
735  0.015983658f, 0.03406988f, -0.06939408f, 0.040699873f,
736  0.02111075f, 0.09669095f, 0.041345075f, -0.08316494f,
737  -0.07684199f, -0.045768797f, 0.032298047f, -0.041805092f,
738  0.0119405f, 0.0061010392f, 0.12652606f, 0.0064572375f,
739  -0.024950314f, 0.11574242f, 0.04508852f, -0.04335324f,
740  0.06760663f, -0.027437469f, 0.07216407f, 0.06977076f,
741  -0.05438599f, 0.034033038f, -0.028602652f, 0.05346137f,
742  0.043184172f, -0.037189785f, 0.10420091f, 0.00882477f,
743  -0.054019816f, -0.074273005f, -0.030617684f, -0.0028467078f,
744  0.024302477f, -0.0038869337f, 0.005332455f, 0.0013399826f,
745  0.04361412f, -0.007001822f, 0.09631092f, -0.06702025f,
746  -0.042049985f, -0.035070654f, -0.04103342f, -0.10273396f,
747  0.0544271f, 0.037184782f, -0.13150354f, -0.0058036847f,
748  -0.008264958f, 0.042035464f, 0.05891794f, 0.029673764f,
749  0.0063542654f, 0.044788733f, 0.054816857f, 0.062257513f,
750  -0.00093483756f, 0.048938446f, -0.004952862f, -0.007730018f,
751  -0.04043371f, -0.017094059f, 0.07229206f, -0.023670016f,
752  -0.052195564f, -0.025616996f, -0.01520939f, 0.045104615f,
753  -0.007376126f, 0.003533447f, 0.006570588f, 0.056037236f,
754  0.12436656f, 0.051817212f, 0.028532185f, -0.08686856f,
755  0.11868599f, 0.07663395f, -0.07323171f, 0.03463402f,
756  -0.050708205f, -0.04458982f, -0.11590894f, 0.021273347f,
757  0.1251325f, -0.15313013f, -0.12224372f, 0.17228661f,
758  0.023029093f, 0.086124025f, 0.006445803f, -0.03496501f,
759  0.028332196f, 0.04449512f, -0.042436164f, -0.026587414f,
760  -0.006041347f, -0.09292539f, -0.05678812f, 0.03897832f,
761  0.09465633f, 0.008115513f, -0.02171956f, 0.08304309f,
762  0.071401566f, 0.019622514f, 0.032163795f, -0.004167056f,
763  0.02295182f, 0.030739572f, 0.056506045f, 0.004612461f,
764  0.06524936f, 0.059999723f, 0.046395954f, -0.0045512207f,
765  -0.1335546f, -0.030136576f, 0.11584653f, -0.014678886f,
766  0.0020118146f, -0.09688814f, -0.0790206f, 0.039770417f,
767  -0.0329582f, 0.07922767f, 0.029322514f, 0.026405897f,
768  0.04207835f, -0.07073373f, 0.063781224f, 0.0859677f,
769  -0.10925287f, -0.07011058f, 0.048005477f, 0.03438226f,
770  -0.09606514f, -0.006669445f, -0.043381985f, 0.04240257f,
771  -0.06955775f, -0.06769346f, 0.043903265f, -0.026784198f,
772  -0.017840602f, 0.024307009f, -0.040079936f, -0.019946516f,
773  0.045318738f, -0.12233574f, 0.026170589f, 0.0074471775f,
774  0.15978073f, 0.10185836f, 0.10298046f, -0.015476589f,
775  -0.039390966f, -0.072174534f, 0.0739445f, -0.1211869f,
776  -0.0347889f, -0.07943156f, 0.014809798f, -0.12412325f,
777  -0.0030663363f, 0.039695457f, 0.0647603f, -0.08291318f,
778  -0.018529687f, -0.004423833f, 0.0037507233f, 0.084633216f,
779  -0.01514876f, -0.056505352f, -0.012800942f, -0.06994386f,
780  0.012962922f, -0.031234352f, 0.07029052f, 0.016418684f,
781  0.03618972f, 0.055686004f, -0.08663945f, -0.017404709f,
782  -0.054761406f, 0.029065743f, 0.052404847f, 0.020238016f,
783  0.0048197987f, -0.0214882f, 0.07078733f, 0.013016777f,
784  0.06262858f, 0.009184685f, 0.020785125f, -0.043904778f,
785  -0.0270329f, -0.03299152f, -0.060088247f, -0.015162964f,
786  -0.001828936f, 0.12642565f, -0.056757294f, 0.013586685f,
787  0.09232601f, -0.035886683f, 0.06000002f, 0.05229691f,
788  -0.052580316f, -0.082029596f, -0.010794592f, 0.012947712f,
789  -0.036429964f, -0.085508935f, -0.13127148f, -0.017744139f,
790  0.031502828f, 0.036232427f, -0.031581745f, 0.023051167f,
791  -0.05325106f, -0.03421577f, 0.028793324f, -0.034633752f,
792  -0.009881397f, -0.043551125f, -0.018609839f, 0.0019097115f,
793  -0.008799762f, 0.056595087f, 0.0022273948f, 0.055752404f
794  });
795 
796  auto recurrentToOutputWeights =
797  MakeTensor<float, 2>(tensorInfo20x16, {0.025825322f, -0.05813119f, 0.09495884f,-0.045984812f, -0.01255415f,
798  -0.0026479573f,-0.08196161f,-0.054914974f,-0.0046604523f,
799  -0.029587349f, -0.044576716f, -0.07480124f, -0.082868785f,
800  0.023254942f, 0.027502948f, -0.0039728214f, -0.08683098f,
801  -0.08116779f, -0.014675607f, -0.037924774f, -0.023314456f,
802  -0.007401714f, -0.09255757f, 0.029460307f, -0.08829125f,
803  -0.005139627f, -0.08989442f, -0.0555066f, 0.13596267f,
804  -0.025062224f, -0.048351806f, -0.03850004f, 0.07266485f,
805  -0.022414139f, 0.05940088f, 0.075114764f, 0.09597592f,
806  -0.010211725f, -0.0049794707f, -0.011523867f, -0.025980417f,
807  0.072999895f, 0.11091378f, -0.081685916f, 0.014416728f,
808  0.043229222f, 0.034178585f, -0.07530371f, 0.035837382f,
809  -0.085607f, -0.007721233f, -0.03287832f, -0.043848954f,
810  -0.06404588f, -0.06632928f, -0.073643476f, 0.008214239f,
811  -0.045984086f, 0.039764922f, 0.03474462f, 0.060612556f,
812  -0.080590084f, 0.049127717f, 0.04151091f, -0.030063879f,
813  0.008801774f, -0.023021035f, -0.019558564f, 0.05158114f,
814  -0.010947698f, -0.011825728f, 0.0075720972f, 0.0699727f,
815  -0.0039981045f, 0.069350146f, 0.08799282f, 0.016156472f,
816  0.035502106f, 0.11695009f, 0.006217345f, 0.13392477f,
817  -0.037875112f, 0.025745004f, 0.08940699f, -0.00924166f,
818  0.0046702605f, -0.036598757f, -0.08811812f, 0.10522024f,
819  -0.032441203f, 0.008176899f, -0.04454919f, 0.07058152f,
820  0.0067963637f, 0.039206743f, 0.03259838f, 0.03725492f,
821  -0.09515802f, 0.013326398f, -0.052055415f, -0.025676316f,
822  0.03198509f, -0.015951829f, -0.058556724f, 0.036879618f,
823  0.043357447f, 0.028362012f, -0.05908629f, 0.0059240665f,
824  -0.04995891f, -0.019187413f,0.0276265f, -0.01628143f, 0.0025863599f,
825  0.08800015f, 0.035250366f, -0.022165963f, -0.07328642f,
826  -0.009415526f, -0.07455109f, 0.11690406f, 0.0363299f,
827  0.07411125f, 0.042103454f, -0.009660886f, 0.019076364f,
828  0.018299393f, -0.046004917f, 0.08891175f,0.0431396f, -0.026327137f,
829  -0.051502608f, 0.08979574f, -0.051670972f, 0.04940282f,
830  -0.07491107f, -0.021240504f, 0.022596184f, -0.034280192f,
831  0.060163025f, -0.058211457f, -0.051837247f, -0.01349775f,
832  -0.04639988f, -0.035936575f, -0.011681591f, 0.064818054f,
833  0.0073146066f, -0.021745546f, -0.043124277f, -0.06471268f,
834  -0.07053354f, -0.029321948f, -0.05330136f, 0.016933719f,
835  -0.053782392f, 0.13747959f, -0.1361751f, -0.11569455f,
836  0.0033329215f, 0.05693899f, -0.053219706f, 0.063698f,
837  0.07977434f, -0.07924483f, 0.06936997f, 0.0034815092f,
838  -0.007305279f, -0.037325785f, -0.07251102f, -0.033633437f,
839  -0.08677009f, 0.091591336f, -0.14165086f, 0.021752775f,
840  0.019683983f, 0.0011612234f, -0.058154266f, 0.049996935f,
841  0.0288841f, -0.0024567875f, -0.14345716f, 0.010955264f,-0.10234828f,
842  0.1183656f, -0.0010731248f, -0.023590032f,-0.072285876f,-0.0724771f,
843  -0.026382286f, -0.0014920527f, 0.042667855f, 0.0018776858f,
844  0.02986552f, 0.009814309f, 0.0733756f, 0.12289186f,
845  0.018043943f, -0.0458958f, 0.049412545f, 0.033632483f,
846  0.05495232f, 0.036686596f, -0.013781798f, -0.010036754f,
847  0.02576849f, -0.08307328f, 0.010112348f, 0.042521734f,
848  -0.05869831f, -0.071689695f, 0.03876447f, -0.13275425f, -0.0352966f,
849  -0.023077697f, 0.10285965f, 0.084736146f, 0.15568255f,
850  -0.00040734606f, 0.027835453f, -0.10292561f, -0.032401145f,
851  0.10053256f, -0.026142767f, -0.08271222f, -0.0030240538f,
852  -0.016368777f, 0.1070414f, 0.042672627f, 0.013456989f,
853  -0.0437609f, -0.022309763f, 0.11576483f, 0.04108048f,
854  0.061026827f, -0.0190714f, -0.0869359f, 0.037901703f, 0.0610107f,
855  0.07202949f, 0.01675338f, 0.086139716f, -0.08795751f,
856  -0.014898893f, -0.023771819f, -0.01965048f, 0.007955471f,
857  -0.043740474f, 0.03346837f, -0.10549954f, 0.090567775f,
858  0.042013682f, -0.03176985f, 0.12569028f, -0.02421228f,
859  -0.029526481f, 0.023851605f, 0.031539805f, 0.05292009f,
860  -0.02344001f, -0.07811758f, -0.08834428f, 0.10094801f,
861  0.16594367f, -0.06861939f, -0.021256343f, -0.041093912f,
862  -0.06669611f, 0.035498552f, 0.021757556f, -0.09302526f,
863  -0.015403468f, -0.06614931f, -0.051798206f, -0.013874718f,
864  0.03630673f, 0.010412845f, -0.08077351f, 0.046185967f,
865  0.0035662893f, 0.03541868f, -0.094149634f, -0.034814864f,
866  0.003128424f, -0.020674974f, -0.03944324f, -0.008110165f,
867  -0.11113267f, 0.08484226f, 0.043586485f, 0.040582247f,
868  0.0968012f, -0.065249965f, -0.028036479f, 0.0050708856f,
869  0.0017462453f, 0.0326779f, 0.041296225f, 0.09164146f,
870  -0.047743853f, -0.015952192f, -0.034451712f, 0.084197424f,
871  -0.05347844f, -0.11768019f, 0.085926116f, -0.08251791f,
872  -0.045081906f, 0.0948852f, 0.068401024f, 0.024856757f,
873  0.06978981f, -0.057309967f, -0.012775832f, -0.0032452994f,
874  0.01977615f, -0.041040014f, -0.024264973f,0.063464895f, 0.05431621f
875  });
876 
877  auto cellToInputWeights =
878  MakeTensor<float, 1>(tensorInfo20, {0.040369894f, 0.030746894f, 0.24704495f, 0.018586371f, -0.037586458f,
879  -0.15312155f, -0.11812848f, -0.11465643f, 0.20259799f, 0.11418174f,
880  -0.10116027f, -0.011334949f, 0.12411352f, -0.076769054f,-0.052169047f,
881  0.21198851f, -0.38871562f, -0.09061183f, -0.09683246f, -0.21929175f
882  });
883 
884 
885  auto cellToForgetWeights =
886  MakeTensor<float, 1>(tensorInfo20, {-0.01998659f,-0.15568835f,-0.24248174f, -0.012770197f, 0.041331276f,
887  -0.072311886f, -0.052123554f,-0.0066330447f,-0.043891653f,0.036225766f,
888  -0.047248036f, 0.021479502f,0.033189066f, 0.11952997f, -0.020432774f,
889  0.64658105f, -0.06650122f, -0.03467612f, 0.095340036f, 0.23647355f
890  });
891 
892  auto cellToOutputWeights =
893  MakeTensor<float, 1>(tensorInfo20, {0.08286371f, -0.08261836f, -0.51210177f, 0.002913762f, 0.17764764f,
894  -0.5495371f, -0.08460716f, -0.24552552f, 0.030037103f, 0.04123544f,
895  -0.11940523f, 0.007358328f, 0.1890978f, 0.4833202f, -0.34441817f,
896  0.36312827f, -0.26375428f, 0.1457655f, -0.19724406f, 0.15548733f
897  });
898 
899  auto projectionWeights =
900  MakeTensor<float, 2>(tensorInfo16x20,
901  {-0.009802181f, 0.09401916f, 0.0717386f, -0.13895074f, 0.09641832f,
902  0.060420845f, 0.08539281f, 0.054285463f, 0.061395317f, 0.034448683f,
903  -0.042991187f, 0.019801661f, -0.16840284f, -0.015726732f, -0.23041931f,
904  -0.024478018f, -0.10959692f, -0.013875541f, 0.18600968f, -0.061274476f,
905  0.0138165f, -0.08160894f, -0.07661644f, 0.032372914f, 0.16169067f,
906  0.22465782f, -0.03993472f, -0.004017731f, 0.08633481f, -0.28869787f,
907  0.08682067f, 0.17240396f, 0.014975425f, 0.056431185f, 0.031037588f,
908  0.16702051f, 0.0077946745f, 0.15140012f, 0.29405436f, 0.120285f,
909  -0.188994f, -0.027265169f, 0.043389652f, -0.022061434f, 0.014777949f,
910  -0.20203483f, 0.094781205f, 0.19100232f, 0.13987629f, -0.036132768f,
911  -0.06426278f, -0.05108664f, 0.13221376f, 0.009441198f, -0.16715929f,
912  0.15859416f, -0.040437475f, 0.050779544f, -0.022187516f, 0.012166504f,
913  0.027685808f, -0.07675938f, -0.0055694645f, -0.09444123f, 0.0046453946f,
914  0.050794356f, 0.10770313f, -0.20790008f, -0.07149004f, -0.11425117f,
915  0.008225835f, -0.035802525f, 0.14374903f, 0.15262283f, 0.048710253f,
916  0.1847461f, -0.007487823f, 0.11000021f, -0.09542012f, 0.22619456f,
917  -0.029149994f, 0.08527916f, 0.009043713f, 0.0042746216f, 0.016261552f,
918  0.022461696f, 0.12689082f, -0.043589946f, -0.12035478f, -0.08361797f,
919  -0.050666027f, -0.1248618f, -0.1275799f, -0.071875185f, 0.07377272f,
920  0.09944291f, -0.18897448f, -0.1593054f, -0.06526116f, -0.040107165f,
921  -0.004618631f, -0.067624845f, -0.007576253f, 0.10727444f, 0.041546922f,
922  -0.20424393f, 0.06907816f, 0.050412357f, 0.00724631f, 0.039827548f,
923  0.12449835f, 0.10747581f, 0.13708383f, 0.09134148f, -0.12617786f,
924  -0.06428341f, 0.09956831f, 0.1208086f, -0.14676677f, -0.0727722f,
925  0.1126304f, 0.010139365f, 0.015571211f, -0.038128063f, 0.022913318f,
926  -0.042050496f, 0.16842307f, -0.060597885f, 0.10531834f, -0.06411776f,
927  -0.07451711f, -0.03410368f, -0.13393489f, 0.06534304f, 0.003620307f,
928  0.04490757f, 0.05970546f, 0.05197996f, 0.02839995f, 0.10434969f,
929  -0.013699693f, -0.028353551f, -0.07260381f, 0.047201227f, -0.024575593f,
930  -0.036445823f, 0.07155557f, 0.009672501f, -0.02328883f, 0.009533515f,
931  -0.03606021f, -0.07421458f, -0.028082801f, -0.2678904f, -0.13221288f,
932  0.18419984f, -0.13012612f, -0.014588381f, -0.035059117f, -0.04824723f,
933  0.07830115f, -0.056184657f, 0.03277091f, 0.025466874f, 0.14494097f,
934  -0.12522776f, -0.098633975f, -0.10766018f, -0.08317623f, 0.08594209f,
935  0.07749552f, 0.039474737f, 0.1776665f, -0.07409566f, -0.0477268f,
936  0.29323658f, 0.10801441f, 0.1154011f, 0.013952499f, 0.10739139f,
937  0.10708251f, -0.051456142f, 0.0074137426f, -0.10430189f, 0.10034707f,
938  0.045594677f, 0.0635285f, -0.0715442f, -0.089667566f, -0.10811871f,
939  0.00026344223f, 0.08298446f, -0.009525053f, 0.006585689f, -0.24567553f,
940  -0.09450807f, 0.09648481f, 0.026996298f, -0.06419476f, -0.04752702f,
941  -0.11063944f, -0.23441927f, -0.17608605f, -0.052156363f, 0.067035615f,
942  0.19271925f, -0.0032889997f, -0.043264326f, 0.09663576f, -0.057112187f,
943  -0.10100678f, 0.0628376f, 0.04447668f, 0.017961001f, -0.10094388f,
944  -0.10190601f, 0.18335468f, 0.10494553f, -0.052095775f, -0.0026118709f,
945  0.10539724f, -0.04383912f, -0.042349473f, 0.08438151f, -0.1947263f,
946  0.02251204f, 0.11216432f, -0.10307853f, 0.17351969f, -0.039091777f,
947  0.08066188f, -0.00561982f, 0.12633002f, 0.11335965f, -0.0088127935f,
948  -0.019777594f, 0.06864014f, -0.059751723f, 0.016233567f, -0.06894641f,
949  -0.28651384f, -0.004228674f, 0.019708522f, -0.16305895f, -0.07468996f,
950  -0.0855457f, 0.099339016f, -0.07580735f, -0.13775392f, 0.08434318f,
951  0.08330512f, -0.12131499f, 0.031935584f, 0.09180414f, -0.08876437f,
952  -0.08049874f, 0.008753825f, 0.03498998f, 0.030215185f, 0.03907079f,
953  0.089751154f, 0.029194152f, -0.03337423f, -0.019092513f, 0.04331237f,
954  0.04299654f, -0.036394123f, -0.12915532f, 0.09793732f, 0.07512415f,
955  -0.11319543f, -0.032502122f, 0.15661901f, 0.07671967f, -0.005491124f,
956  -0.19379048f, -0.218606f, 0.21448623f, 0.017840758f, 0.1416943f,
957  -0.07051762f, 0.19488361f, 0.02664691f, -0.18104725f, -0.09334311f,
958  0.15026465f, -0.15493552f, -0.057762887f, -0.11604192f, -0.262013f,
959  -0.01391798f, 0.012185008f, 0.11156489f, -0.07483202f, 0.06693364f,
960  -0.26151478f, 0.046425626f, 0.036540434f, -0.16435726f, 0.17338543f,
961  -0.21401681f, -0.11385144f, -0.08283257f, -0.069031075f, 0.030635102f,
962  0.010969227f, 0.11109743f, 0.010919218f, 0.027526086f, 0.13519906f,
963  0.01891392f, -0.046839405f, -0.040167913f, 0.017953383f, -0.09700955f,
964  0.0061885654f, -0.07000971f, 0.026893595f, -0.038844477f, 0.14543656f
965  });
966 
967  std::vector<float> projectionBiasVector(outputSize, 0.f);
968  auto projectionBias = MakeTensor<float,1>(tensorInfo16, projectionBiasVector);
969 
970  armnn::ScopedCpuTensorHandle inputToInputWeightsTensor(tensorInfo20x5);
971  armnn::ScopedCpuTensorHandle inputToForgetWeightsTensor(tensorInfo20x5);
972  armnn::ScopedCpuTensorHandle inputToCellWeightsTensor(tensorInfo20x5);
973  armnn::ScopedCpuTensorHandle inputToOutputWeightsTensor(tensorInfo20x5);
974  armnn::ScopedCpuTensorHandle recurrentToForgetWeightsTensor(tensorInfo20x16);
975  armnn::ScopedCpuTensorHandle recurrentToInputWeightsTensor(tensorInfo20x16);
976  armnn::ScopedCpuTensorHandle recurrentToCellWeightsTensor(tensorInfo20x16);
977  armnn::ScopedCpuTensorHandle recurrentToOutputWeightsTensor(tensorInfo20x16);
978  armnn::ScopedCpuTensorHandle cellToInputWeightsTensor(tensorInfo20);
979  armnn::ScopedCpuTensorHandle inputGateBiasTensor(tensorInfo20);
980  armnn::ScopedCpuTensorHandle forgetGateBiasTensor(tensorInfo20);
981  armnn::ScopedCpuTensorHandle cellBiasTensor(tensorInfo20);
982  armnn::ScopedCpuTensorHandle outputGateBiasTensor(tensorInfo20);
983  armnn::ScopedCpuTensorHandle cellToForgetWeightsTensor(tensorInfo20);
984  armnn::ScopedCpuTensorHandle cellToOutputWeightsTensor(tensorInfo20);
985  armnn::ScopedCpuTensorHandle projectionWeightsTensor(tensorInfo16x20);
986  armnn::ScopedCpuTensorHandle projectionBiasTensor(tensorInfo16);
987 
988  AllocateAndCopyDataToITensorHandle(&inputToInputWeightsTensor, &inputToInputWeights[0][0]);
989  AllocateAndCopyDataToITensorHandle(&inputToForgetWeightsTensor, &inputToForgetWeights[0][0]);
990  AllocateAndCopyDataToITensorHandle(&inputToCellWeightsTensor, &inputToCellWeights[0][0]);
991  AllocateAndCopyDataToITensorHandle(&inputToOutputWeightsTensor, &inputToOutputWeights[0][0]);
992  AllocateAndCopyDataToITensorHandle(&recurrentToInputWeightsTensor, &recurrentToInputWeights[0][0]);
993  AllocateAndCopyDataToITensorHandle(&recurrentToForgetWeightsTensor, &recurrentToForgetWeights[0][0]);
994  AllocateAndCopyDataToITensorHandle(&recurrentToCellWeightsTensor, &recurrentToCellWeights[0][0]);
995  AllocateAndCopyDataToITensorHandle(&recurrentToOutputWeightsTensor, &recurrentToOutputWeights[0][0]);
996  AllocateAndCopyDataToITensorHandle(&cellToInputWeightsTensor, &cellToInputWeights[0]);
997  AllocateAndCopyDataToITensorHandle(&inputGateBiasTensor, &inputGateBias[0]);
998  AllocateAndCopyDataToITensorHandle(&forgetGateBiasTensor, &forgetGateBias[0]);
999  AllocateAndCopyDataToITensorHandle(&cellBiasTensor, &cellBias[0]);
1000  AllocateAndCopyDataToITensorHandle(&outputGateBiasTensor, &outputGateBias[0]);
1001  AllocateAndCopyDataToITensorHandle(&cellToForgetWeightsTensor, &cellToForgetWeights[0]);
1002  AllocateAndCopyDataToITensorHandle(&cellToOutputWeightsTensor, &cellToOutputWeights[0]);
1003  AllocateAndCopyDataToITensorHandle(&projectionWeightsTensor, &projectionWeights[0][0]);
1004  AllocateAndCopyDataToITensorHandle(&projectionBiasTensor, &projectionBias[0]);
1005 
1006  data.m_InputToInputWeights = &inputToInputWeightsTensor;
1007  data.m_InputToForgetWeights = &inputToForgetWeightsTensor;
1008  data.m_InputToCellWeights = &inputToCellWeightsTensor;
1009  data.m_InputToOutputWeights = &inputToOutputWeightsTensor;
1010  data.m_RecurrentToInputWeights = &recurrentToInputWeightsTensor;
1011  data.m_RecurrentToForgetWeights = &recurrentToForgetWeightsTensor;
1012  data.m_RecurrentToCellWeights = &recurrentToCellWeightsTensor;
1013  data.m_RecurrentToOutputWeights = &recurrentToOutputWeightsTensor;
1014  data.m_CellToInputWeights = &cellToInputWeightsTensor;
1015  data.m_InputGateBias = &inputGateBiasTensor;
1016  data.m_ForgetGateBias = &forgetGateBiasTensor;
1017  data.m_CellBias = &cellBiasTensor;
1018  data.m_OutputGateBias = &outputGateBiasTensor;
1019  data.m_CellToForgetWeights = &cellToForgetWeightsTensor;
1020  data.m_CellToOutputWeights = &cellToOutputWeightsTensor;
1021  data.m_ProjectionWeights = &projectionWeightsTensor;
1022  data.m_ProjectionBias = &projectionBiasTensor;
1023 
1024  // Flags to set test configuration
1025  data.m_Parameters.m_ActivationFunc = 4;
1026  data.m_Parameters.m_CifgEnabled = false;
1027  data.m_Parameters.m_PeepholeEnabled = true;
1028  data.m_Parameters.m_ProjectionEnabled = true;
1029 
1030 
1031  std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateLstm(data, info);
1032  inputHandle->Allocate();
1033  outputStateInHandle->Allocate();
1034  cellStateInHandle->Allocate();
1035 
1036  scratchHandle->Allocate();
1037  outputStateOutHandle->Allocate();
1038  cellStateOutHandle->Allocate();
1039  outputHandle->Allocate();
1040 
1041  CopyDataToITensorHandle(inputHandle.get(), &inputTensor[0][0]);
1042  CopyDataToITensorHandle(outputStateInHandle.get(), &outputStateInTensor[0][0]);
1043  CopyDataToITensorHandle(cellStateInHandle.get(), &cellStateInTensor[0][0]);
1044 
1045  workload->Execute();
1046 
1047  CopyDataFromITensorHandle(&ret.output[0][0], outputHandle.get());
1048 
1049  return ret;
1050 
1051 }
1052 
1053 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
1054 LayerTestResult<T, 2> LstmLayerWithCifgWithPeepholeNoProjectionTestImpl(
1055  armnn::IWorkloadFactory& workloadFactory,
1057  const boost::multi_array<T, 2>& input,
1058  const boost::multi_array<T, 2>& outputExpected,
1059  float qScale = 0.0f,
1060  int32_t qOffset = 0,
1061  armnn::DataType constantDataType = armnn::DataType::Float32)
1062 {
1063  IgnoreUnused(memoryManager);
1064  bool cifgEnabled = true;
1065  bool peepholeEnabled = true;
1066  bool projectionEnabled = false;
1067  // These are not the input and the output of Lstm yet
1068  unsigned int batchSize = boost::numeric_cast<unsigned int>(input.shape()[0]);
1069  unsigned int inputSize = boost::numeric_cast<unsigned int>(input.shape()[1]);
1070 
1071  unsigned int outputSize = boost::numeric_cast<unsigned int>(outputExpected.shape()[1]);
1072 
1073  const unsigned int cellSize = outputSize;
1074 
1075  // Decide the shape of all input tensors
1076  armnn::TensorInfo inputTensorInfo({batchSize , inputSize}, ArmnnType, qScale, qOffset); // change to ArmnnType
1077  armnn::TensorInfo outputStateInTensorInfo({batchSize, outputSize}, ArmnnType, qScale, qOffset);
1078  armnn::TensorInfo cellStateInTensorInfo({batchSize, cellSize}, ArmnnType, qScale, qOffset);
1079 
1080  unsigned int scratchBufferSize = cifgEnabled ? cellSize * 3 : cellSize * 4;
1081  armnn::TensorInfo scratchBufferTensorInfo({batchSize, scratchBufferSize}, ArmnnType, qScale, qOffset);
1082  armnn::TensorInfo outputStateOutTensorInfo({batchSize, outputSize}, ArmnnType, qScale, qOffset);
1083  armnn::TensorInfo cellStateOutTensorInfo({batchSize, cellSize}, ArmnnType, qScale, qOffset);
1084  armnn::TensorInfo outputTensorInfo({batchSize, outputSize}, ArmnnType, qScale, qOffset);
1085 
1086  // List of inputs
1087  std::vector<float> inputData;
1088  inputData.assign(input.data(), input.data() + batchSize*inputSize);
1089  auto inputTensor = MakeTensor<float,2>(inputTensorInfo, inputData);
1090 
1091  std::vector<float> outputStateInVector(batchSize * outputSize, 0.f);
1092  auto outputStateInTensor = MakeTensor<float, 2>(outputStateInTensorInfo, outputStateInVector);
1093 
1094  std::vector<float> cellStateInVector(batchSize * cellSize, 0.f);
1095  auto cellStateInTensor = MakeTensor<float, 2>(cellStateInTensorInfo, cellStateInVector);
1096 
1097 
1098  // Prepare all the weights in the descriptor for LSTM
1100  armnn::TensorInfo tensorInfoInput({cellSize, inputSize}, constantDataType, qScale, qOffset);
1101  armnn::TensorInfo tensorInfoOutput({cellSize, outputSize}, constantDataType, qScale, qOffset);
1102  armnn::TensorInfo tensorInfoNumUnits({cellSize}, constantDataType, qScale, qOffset);
1103 
1104  auto inputToCellWeights = MakeTensor<float, 2>(tensorInfoInput,
1105  {-0.49770179f, -0.27711356f, -0.09624726f, 0.05100781f,
1106  0.04717243f, 0.48944736f, -0.38535351f,
1107  -0.17212132f});
1108  auto inputToForgetWeights = MakeTensor<float, 2>(tensorInfoInput,
1109  {-0.55291498f, -0.42866567f, 0.13056988f,
1110  -0.3633365f, -0.22755712f, 0.28253698f, 0.24407166f,
1111  0.33826375f});
1112  auto inputToOutputWeights = MakeTensor<float, 2>(tensorInfoInput,
1113  {0.10725588f, -0.02335852f, -0.55932593f,
1114  -0.09426838f, -0.44257352f, 0.54939759f,
1115  0.01533556f, 0.42751634f});
1116  auto cellBias = MakeTensor<float, 1>(tensorInfoNumUnits, {0.f, 0.f, 0.f, 0.f});
1117  auto forgetGateBias = MakeTensor<float, 1>(tensorInfoNumUnits, {1.f, 1.f, 1.f, 1.f});
1118  auto outputGateBias = MakeTensor<float, 1>(tensorInfoNumUnits, {0.f, 0.f, 0.f, 0.f});
1119 
1120  auto recurrentToCellWeights = MakeTensor<float, 2>(tensorInfoOutput,
1121  {0.54066205f, -0.32668582f, -0.43562764f, -0.56094903f, 0.42957711f,
1122  0.01841056f, -0.32764608f, -0.33027974f, -0.10826075f, 0.20675004f,
1123  0.19069612f, -0.03026325f, -0.54532051f, 0.33003211f, 0.44901288f,
1124  0.21193194f});
1125  auto recurrentToForgetWeights = MakeTensor<float, 2>(tensorInfoOutput,
1126  {-0.13832897f, -0.0515101f, -0.2359007f, -0.16661474f, -0.14340827f,
1127  0.36986142f, 0.23414481f, 0.55899f, 0.10798943f, -0.41174671f, 0.17751795f,
1128  -0.34484994f, -0.35874045f, -0.11352962f, 0.27268326f, 0.54058349f});
1129 
1130  auto recurrentToOutputWeights = MakeTensor<float, 2>(tensorInfoOutput,
1131  {0.41613156f, 0.42610586f, -0.16495961f, -0.5663873f, 0.30579174f, -0.05115908f,
1132  -0.33941799f, 0.23364776f, 0.11178309f, 0.09481031f, -0.26424935f, 0.46261835f,
1133  0.50248802f, 0.26114327f, -0.43736315f, 0.33149987f});
1134 
1135  auto cellToForgetWeights = MakeTensor<float, 1>(tensorInfoNumUnits,
1136  {0.47485286f, -0.51955009f, -0.24458408f, 0.31544167f});
1137  auto cellToOutputWeights = MakeTensor<float, 1>(tensorInfoNumUnits,
1138  {-0.17135078f, 0.82760304f, 0.85573703f, -0.77109635f});
1139 
1140  armnn::ScopedCpuTensorHandle inputToCellWeightsTensor(tensorInfoInput);
1141  armnn::ScopedCpuTensorHandle inputToForgetWeightsTensor(tensorInfoInput);
1142  armnn::ScopedCpuTensorHandle inputToOutputWeightsTensor(tensorInfoInput);
1143 
1144  armnn::ScopedCpuTensorHandle cellBiasTensor(tensorInfoNumUnits);
1145  armnn::ScopedCpuTensorHandle forgetGateBiasTensor(tensorInfoNumUnits);
1146  armnn::ScopedCpuTensorHandle outputGateBiasTensor(tensorInfoNumUnits);
1147 
1148  armnn::ScopedCpuTensorHandle recurrentToCellWeightsTensor(tensorInfoOutput);
1149  armnn::ScopedCpuTensorHandle recurrentToForgetWeightsTensor(tensorInfoOutput);
1150  armnn::ScopedCpuTensorHandle recurrentToOutputWeightsTensor(tensorInfoOutput);
1151 
1152 
1153  armnn::ScopedCpuTensorHandle cellToForgetWeightsTensor(tensorInfoNumUnits);
1154  armnn::ScopedCpuTensorHandle cellToOutputWeightsTensor(tensorInfoNumUnits);
1155 
1156  AllocateAndCopyDataToITensorHandle(&inputToCellWeightsTensor, &inputToCellWeights[0][0]);
1157  AllocateAndCopyDataToITensorHandle(&inputToForgetWeightsTensor, &inputToForgetWeights[0][0]);
1158  AllocateAndCopyDataToITensorHandle(&inputToOutputWeightsTensor, &inputToOutputWeights[0][0]);
1159 
1160  AllocateAndCopyDataToITensorHandle(&cellBiasTensor, &cellBias[0]);
1161  AllocateAndCopyDataToITensorHandle(&forgetGateBiasTensor, &forgetGateBias[0]);
1162  AllocateAndCopyDataToITensorHandle(&outputGateBiasTensor, &outputGateBias[0]);
1163 
1164  AllocateAndCopyDataToITensorHandle(&recurrentToCellWeightsTensor, &recurrentToCellWeights[0][0]);
1165  AllocateAndCopyDataToITensorHandle(&recurrentToForgetWeightsTensor, &recurrentToForgetWeights[0][0]);
1166  AllocateAndCopyDataToITensorHandle(&recurrentToOutputWeightsTensor, &recurrentToOutputWeights[0][0]);
1167 
1168  AllocateAndCopyDataToITensorHandle(&cellToForgetWeightsTensor, &cellToForgetWeights[0]);
1169  AllocateAndCopyDataToITensorHandle(&cellToOutputWeightsTensor, &cellToOutputWeights[0]);
1170 
1171 
1172  data.m_InputToCellWeights = &inputToCellWeightsTensor;
1173  data.m_InputToForgetWeights = &inputToForgetWeightsTensor;
1174  data.m_InputToOutputWeights = &inputToOutputWeightsTensor;
1175 
1176  data.m_CellBias = &cellBiasTensor;
1177  data.m_ForgetGateBias = &forgetGateBiasTensor;
1178  data.m_OutputGateBias = &outputGateBiasTensor;
1179 
1180  data.m_RecurrentToCellWeights = &recurrentToCellWeightsTensor;
1181  data.m_RecurrentToForgetWeights = &recurrentToForgetWeightsTensor;
1182  data.m_RecurrentToOutputWeights = &recurrentToOutputWeightsTensor;
1183 
1184  data.m_CellToForgetWeights = &cellToForgetWeightsTensor;
1185  data.m_CellToOutputWeights = &cellToOutputWeightsTensor;
1186 
1187  // other parameters for the descriptor
1188  data.m_Parameters.m_CifgEnabled = cifgEnabled;
1189  data.m_Parameters.m_ProjectionEnabled = projectionEnabled;
1190  data.m_Parameters.m_PeepholeEnabled = peepholeEnabled;
1191 
1192  data.m_Parameters.m_ActivationFunc = 4;
1193  data.m_Parameters.m_ClippingThresProj = 0.0;
1194  data.m_Parameters.m_ClippingThresCell = 0.0;
1195 
1196 
1197  // List of outputs
1198  std::vector<float> scratchBufferVector(batchSize * scratchBufferSize, 0.f);
1199  auto scratchBufferTensor = MakeTensor<float,2>(scratchBufferTensorInfo, scratchBufferVector);
1200  LayerTestResult<T, 2> ret0(scratchBufferTensorInfo);
1201 
1202  // Output state for a certain time step
1203  std::vector<float> outputStateOutVector(batchSize * outputSize, 0.f);
1204  auto outputStateOutTensor = MakeTensor<float,2>(outputStateOutTensorInfo, outputStateOutVector);
1205  LayerTestResult<T, 2> ret1(outputStateOutTensorInfo);
1206 
1207  // Cell state for a certain time step
1208  std::vector<float> cellStateOutVector(batchSize * cellSize, 0.f);
1209  auto cellStateOutTensor = MakeTensor<float,2>(cellStateOutTensorInfo, cellStateOutVector);
1210  LayerTestResult<T, 2> ret2(cellStateOutTensorInfo);
1211 
1212  // Output for a certain time step
1213  std::vector<float> outputVector(batchSize * outputSize, 0.f);
1214  auto outputTensor = MakeTensor<float, 2>(outputTensorInfo, outputVector);
1215  std::vector<float> outputData;
1216  outputData.assign(outputExpected.data(), outputExpected.data() + batchSize*outputSize);
1217  LayerTestResult<T, 2> ret3(outputTensorInfo);
1218  ret3.outputExpected = MakeTensor<float, 2>(outputTensorInfo, outputData);
1219 
1220  // Prepare the inputs and outputs for the workload
1221  std::unique_ptr<armnn::ITensorHandle> inputHandle =
1222  workloadFactory.CreateTensorHandle(inputTensorInfo);
1223  std::unique_ptr<armnn::ITensorHandle> outputStateInHandle =
1224  workloadFactory.CreateTensorHandle(outputStateInTensorInfo);
1225  std::unique_ptr<armnn::ITensorHandle> cellStateInHandle =
1226  workloadFactory.CreateTensorHandle(cellStateInTensorInfo);
1227 
1228  std::unique_ptr<armnn::ITensorHandle> scratchBufferHandle =
1229  workloadFactory.CreateTensorHandle(scratchBufferTensorInfo);
1230  std::unique_ptr<armnn::ITensorHandle> outputStateOutHandle =
1231  workloadFactory.CreateTensorHandle(outputStateOutTensorInfo);
1232  std::unique_ptr<armnn::ITensorHandle> cellStateOutHandle =
1233  workloadFactory.CreateTensorHandle(cellStateOutTensorInfo);
1234  std::unique_ptr<armnn::ITensorHandle> outputHandle =
1235  workloadFactory.CreateTensorHandle(outputTensorInfo);
1236 
1237  armnn::WorkloadInfo info;
1238  AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
1239  AddInputToWorkload(data, info, outputStateInTensorInfo, outputStateInHandle.get());
1240  AddInputToWorkload(data, info, cellStateInTensorInfo, cellStateInHandle.get());
1241 
1242  AddOutputToWorkload(data, info, scratchBufferTensorInfo, scratchBufferHandle.get());
1243  AddOutputToWorkload(data, info, outputStateOutTensorInfo, outputStateOutHandle.get());
1244  AddOutputToWorkload(data, info, cellStateOutTensorInfo, cellStateOutHandle.get());
1245  AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
1246 
1247  std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateLstm(data, info);
1248 
1249 
1250  inputHandle->Allocate();
1251  outputStateInHandle->Allocate();
1252  cellStateInHandle->Allocate();
1253 
1254  scratchBufferHandle->Allocate();
1255  outputStateOutHandle->Allocate();
1256  cellStateOutHandle->Allocate();
1257  outputHandle->Allocate();
1258 
1259 
1260  CopyDataToITensorHandle(inputHandle.get(), &inputTensor[0][0]);
1261  CopyDataToITensorHandle(outputStateInHandle.get(), &outputStateInTensor[0][0]);
1262  CopyDataToITensorHandle(cellStateInHandle.get(), &cellStateInTensor[0][0]);
1263 
1264  CopyDataToITensorHandle(scratchBufferHandle.get(), &scratchBufferTensor[0][0]);
1265  CopyDataToITensorHandle(outputStateOutHandle.get(), &outputStateOutTensor[0][0]);
1266  CopyDataToITensorHandle(cellStateOutHandle.get(), &cellStateOutTensor[0][0]);
1267 
1268  workload->Execute();
1269 
1270  CopyDataFromITensorHandle(&ret0.output[0][0], scratchBufferHandle.get());
1271  CopyDataFromITensorHandle(&ret1.output[0][0], outputStateOutHandle.get());
1272  CopyDataFromITensorHandle(&ret2.output[0][0], cellStateOutHandle.get());
1273  CopyDataFromITensorHandle(&ret3.output[0][0], outputHandle.get());
1274 
1275  return ret3;
1276 }
1277 
1278 template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
1280 LstmLayerNoCifgWithPeepholeWithProjectionWithLayerNormTestImpl(armnn::IWorkloadFactory& workloadFactory,
1282  const boost::multi_array<T, 2>& input,
1283  const boost::multi_array<T, 2>& outputExpected,
1284  float qScale = 0.0f,
1285  int32_t qOffset = 0,
1286  armnn::DataType constantDataType = armnn::DataType::Float32)
1287 {
1288  IgnoreUnused(memoryManager);
1289  unsigned int batchSize = 2;
1290  unsigned int outputSize = 3;
1291  unsigned int inputSize = 5;
1292  unsigned numUnits = 4;
1293 
1294  armnn::TensorInfo inputTensorInfo({batchSize , inputSize}, ArmnnType, qScale, qOffset);
1295  armnn::TensorInfo cellStateInTensorInfo({batchSize , numUnits}, ArmnnType, qScale, qOffset);
1296  armnn::TensorInfo outputStateInTensorInfo({batchSize , outputSize}, ArmnnType, qScale, qOffset);
1297 
1298  // Scratch buffer size without CIFG [batchSize, numUnits * 4]
1299  armnn::TensorInfo scratchBufferTensorInfo({batchSize, numUnits * 4}, ArmnnType, qScale, qOffset);
1300  armnn::TensorInfo cellStateOutTensorInfo({batchSize, numUnits}, ArmnnType, qScale, qOffset);
1301  armnn::TensorInfo outputStateOutTensorInfo({batchSize, outputSize}, ArmnnType, qScale, qOffset);
1302  armnn::TensorInfo outputTensorInfo({batchSize, outputSize}, ArmnnType, qScale, qOffset);
1303 
1304  LayerTestResult<T, 2> ret(outputTensorInfo);
1305 
1306  std::vector<float> inputVector;
1307  inputVector.assign(input.data(), input.data() + (batchSize * inputSize));
1308  auto inputTensor = MakeTensor<float,2>(inputTensorInfo, inputVector);
1309 
1310  std::vector<float> cellStateInVector(batchSize * numUnits, 0.f);
1311  auto cellStateInTensor = MakeTensor<float,2>(cellStateInTensorInfo, cellStateInVector);
1312 
1313  std::vector<float> outputStateInVector(batchSize * outputSize, 0.f);
1314  auto outputStateInTensor = MakeTensor<float,2>(outputStateInTensorInfo, outputStateInVector);
1315 
1316  std::vector<float> scratchBufferVector(batchSize * numUnits * 4, 0.f);
1317  auto scratchBufferTensor = MakeTensor<float,2>(scratchBufferTensorInfo, scratchBufferVector);
1318 
1319  std::vector<float> outputStateOutVector(batchSize * outputSize, 0.f);
1320  auto outputStateOutTensor = MakeTensor<float,2>(outputStateOutTensorInfo, outputStateOutVector);
1321 
1322  std::vector<float> cellStateOutVector(batchSize * numUnits, 0.f);
1323  auto cellStateOutTensor = MakeTensor<float,2>(cellStateOutTensorInfo, cellStateOutVector);
1324 
1325  std::vector<float> outputVector;
1326  outputVector.assign(outputExpected.data(), outputExpected.data() + (batchSize * outputSize));
1327  ret.outputExpected = MakeTensor<float, 2>(outputTensorInfo, outputVector);
1328 
1329  std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
1330  std::unique_ptr<armnn::ITensorHandle> cellStateInHandle =
1331  workloadFactory.CreateTensorHandle(cellStateInTensorInfo);
1332  std::unique_ptr<armnn::ITensorHandle> outputStateInHandle =
1333  workloadFactory.CreateTensorHandle(outputStateInTensorInfo);
1334 
1335  std::unique_ptr<armnn::ITensorHandle> scratchHandle = workloadFactory.CreateTensorHandle(scratchBufferTensorInfo);
1336  std::unique_ptr<armnn::ITensorHandle> outputStateOutHandle =
1337  workloadFactory.CreateTensorHandle(outputStateOutTensorInfo);
1338  std::unique_ptr<armnn::ITensorHandle> cellStateOutHandle =
1339  workloadFactory.CreateTensorHandle(cellStateOutTensorInfo);
1340  std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
1341 
1343  armnn::WorkloadInfo info;
1344 
1345  AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
1346  AddInputToWorkload(data, info, outputStateInTensorInfo, outputStateInHandle.get());
1347  AddInputToWorkload(data, info, cellStateInTensorInfo, cellStateInHandle.get());
1348 
1349  AddOutputToWorkload(data, info, scratchBufferTensorInfo, scratchHandle.get());
1350  AddOutputToWorkload(data, info, outputStateOutTensorInfo, outputStateOutHandle.get());
1351  AddOutputToWorkload(data, info, cellStateOutTensorInfo, cellStateOutHandle.get());
1352  AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
1353 
1354  armnn::TensorInfo tensorInfo3({outputSize}, constantDataType, qScale, qOffset);
1355  armnn::TensorInfo tensorInfo4({numUnits}, constantDataType, qScale, qOffset);
1356  armnn::TensorInfo tensorInfo4x5({numUnits, inputSize}, constantDataType, qScale, qOffset);
1357  armnn::TensorInfo tensorInfo4x3({numUnits, outputSize}, constantDataType, qScale, qOffset);
1358  armnn::TensorInfo tensorInfo3x4({outputSize, numUnits}, constantDataType, qScale, qOffset);
1359 
1360  auto inputToInputWeights =
1361  MakeTensor<float, 2>(tensorInfo4x5, { 0.5f, 0.6f, 0.7f, -0.8f, -0.9f,
1362  0.1f, 0.2f, 0.3f, -0.4f, 0.5f,
1363  -0.8f, 0.7f, -0.6f, 0.5f, -0.4f,
1364  -0.5f, -0.4f, -0.3f, -0.2f, -0.1f}); //{numUnits, inputSize}
1365 
1366  auto inputToForgetWeights =
1367  MakeTensor<float, 2>(tensorInfo4x5, {-0.6f, -0.1f, 0.3f, 0.2f, 0.9f,
1368  -0.5f, -0.2f, -0.4f, 0.3f, -0.8f,
1369  -0.4f, 0.3f, -0.5f, -0.4f, -0.6f,
1370  0.3f, -0.4f, -0.6f, -0.5f, -0.5f}); //{numUnits, inputSize}
1371 
1372  auto inputToCellWeights =
1373  MakeTensor<float, 2>(tensorInfo4x5, {-0.4f, -0.3f, -0.2f, -0.1f, -0.5f,
1374  0.5f, -0.2f, -0.3f, -0.2f, -0.6f,
1375  0.6f, -0.1f, -0.4f, -0.3f, -0.7f,
1376  0.7f, -0.9f, -0.5f, 0.8f, 0.6f}); //{numUnits, inputSize}
1377 
1378  auto inputToOutputWeights =
1379  MakeTensor<float, 2>(tensorInfo4x5, {-0.8f, -0.4f, -0.2f, -0.9f, -0.1f,
1380  -0.7f, 0.3f, -0.3f, -0.8f, -0.2f,
1381  0.6f, -0.2f, 0.4f, -0.7f, -0.3f,
1382  -0.5f, 0.1f, 0.5f, -0.6f, -0.4f}); //{numUnits, inputSize}
1383 
1384  auto inputGateBias =
1385  MakeTensor<float, 1>(tensorInfo4, {0.03f, 0.15f, 0.22f, 0.38f}); //{numUnits}
1386 
1387  auto forgetGateBias =
1388  MakeTensor<float, 1>(tensorInfo4, {0.1f, -0.3f, -0.2f, 0.1f}); //{numUnits}
1389 
1390  auto cellBias =
1391  MakeTensor<float, 1>(tensorInfo4, {-0.05f, 0.72f, 0.25f, 0.08f}); //{numUnits}
1392 
1393  auto outputGateBias =
1394  MakeTensor<float, 1>(tensorInfo4, {0.05f, -0.01f, 0.2f, 0.1f}); //{numUnits}
1395 
1396  auto recurrentToInputWeights =
1397  MakeTensor<float, 2>(tensorInfo4x3, {-0.2f, -0.3f, 0.4f,
1398  0.1f, -0.5f, 0.9f,
1399  -0.2f, -0.3f, -0.7f,
1400  0.05f, -0.2f, -0.6f}); //{numUnits, outputSize}
1401 
1402  auto recurrentToCellWeights =
1403  MakeTensor<float, 2>(tensorInfo4x3, {-0.3f, 0.2f, 0.1f,
1404  -0.3f, 0.8f, -0.08f,
1405  -0.2f, 0.3f, 0.8f,
1406  -0.6f, -0.1f, 0.2f}); //{numUnits, outputSize}
1407 
1408  auto recurrentToForgetWeights =
1409  MakeTensor<float, 2>(tensorInfo4x3, {-0.5f, -0.3f, -0.5f,
1410  -0.2f, 0.6f, 0.4f,
1411  0.9f, 0.3f, -0.1f,
1412  0.2f, 0.5f, 0.2f}); //{numUnits, outputSize}
1413 
1414  auto recurrentToOutputWeights =
1415  MakeTensor<float, 2>(tensorInfo4x3, { 0.3f, -0.1f, 0.1f,
1416  -0.2f, -0.5f, -0.7f,
1417  -0.2f, -0.6f, -0.1f,
1418  -0.4f, -0.7f, -0.2f}); //{numUnits, outputSize}
1419 
1420  auto cellToInputWeights =
1421  MakeTensor<float, 1>(tensorInfo4, {0.05f, 0.1f, 0.25f, 0.15f}); //{numUnits}
1422 
1423  auto cellToForgetWeights =
1424  MakeTensor<float, 1>(tensorInfo4, {-0.02f, -0.15f, -0.25f, -0.03f}); //{numUnits}
1425 
1426  auto cellToOutputWeights =
1427  MakeTensor<float, 1>(tensorInfo4, {0.1f, -0.1f, -0.5f, 0.05f}); //{numUnits}
1428 
1429  auto projectionWeights =
1430  MakeTensor<float, 2>(tensorInfo3x4,
1431  {-0.1f, 0.2f, 0.01f, -0.2f,
1432  0.1f, 0.5f, 0.3f, 0.08f,
1433  0.07f, 0.2f, -0.4f, 0.2f}); //{outputSize, numUnits}
1434 
1435  std::vector<float> projectionBiasVector(outputSize, 0.f);
1436  auto projectionBias = MakeTensor<float,1>(tensorInfo3, projectionBiasVector); //{outputSize}
1437 
1438  auto inputLayerNormWeights =
1439  MakeTensor<float, 1>(tensorInfo4, {0.1f, 0.2f, 0.3f, 0.5f}); //{numUnits}
1440 
1441  auto forgetLayerNormWeights =
1442  MakeTensor<float, 1>(tensorInfo4, {0.2f, 0.2f, 0.4f, 0.3f}); //{numUnits}
1443 
1444  auto cellLayerNormWeights =
1445  MakeTensor<float, 1>(tensorInfo4, {0.7f, 0.2f, 0.3f, 0.8f}); //{numUnits}
1446 
1447  auto outputLayerNormWeights =
1448  MakeTensor<float, 1>(tensorInfo4, {0.6f, 0.2f, 0.2f, 0.5f}); //{numUnits}
1449 
1450 
1451  armnn::ScopedCpuTensorHandle inputToInputWeightsTensor(tensorInfo4x5);
1452  armnn::ScopedCpuTensorHandle inputToForgetWeightsTensor(tensorInfo4x5);
1453  armnn::ScopedCpuTensorHandle inputToCellWeightsTensor(tensorInfo4x5);
1454  armnn::ScopedCpuTensorHandle inputToOutputWeightsTensor(tensorInfo4x5);
1455  armnn::ScopedCpuTensorHandle recurrentToForgetWeightsTensor(tensorInfo4x3);
1456  armnn::ScopedCpuTensorHandle recurrentToInputWeightsTensor(tensorInfo4x3);
1457  armnn::ScopedCpuTensorHandle recurrentToCellWeightsTensor(tensorInfo4x3);
1458  armnn::ScopedCpuTensorHandle recurrentToOutputWeightsTensor(tensorInfo4x3);
1459  armnn::ScopedCpuTensorHandle cellToInputWeightsTensor(tensorInfo4);
1460  armnn::ScopedCpuTensorHandle inputGateBiasTensor(tensorInfo4);
1461  armnn::ScopedCpuTensorHandle forgetGateBiasTensor(tensorInfo4);
1462  armnn::ScopedCpuTensorHandle cellBiasTensor(tensorInfo4);
1463  armnn::ScopedCpuTensorHandle outputGateBiasTensor(tensorInfo4);
1464  armnn::ScopedCpuTensorHandle cellToForgetWeightsTensor(tensorInfo4);
1465  armnn::ScopedCpuTensorHandle cellToOutputWeightsTensor(tensorInfo4);
1466  armnn::ScopedCpuTensorHandle projectionWeightsTensor(tensorInfo3x4);
1467  armnn::ScopedCpuTensorHandle projectionBiasTensor(tensorInfo3);
1468 
1469  armnn::ScopedCpuTensorHandle inputLayerNormWeightsTensor(tensorInfo4);
1470  armnn::ScopedCpuTensorHandle forgetLayerNormWeightsTensor(tensorInfo4);
1471  armnn::ScopedCpuTensorHandle cellLayerNormWeightsTensor(tensorInfo4);
1472  armnn::ScopedCpuTensorHandle outputLayerNormWeightsTensor(tensorInfo4);
1473 
1474  AllocateAndCopyDataToITensorHandle(&inputToInputWeightsTensor, &inputToInputWeights[0][0]);
1475  AllocateAndCopyDataToITensorHandle(&inputToForgetWeightsTensor, &inputToForgetWeights[0][0]);
1476  AllocateAndCopyDataToITensorHandle(&inputToCellWeightsTensor, &inputToCellWeights[0][0]);
1477  AllocateAndCopyDataToITensorHandle(&inputToOutputWeightsTensor, &inputToOutputWeights[0][0]);
1478  AllocateAndCopyDataToITensorHandle(&recurrentToInputWeightsTensor, &recurrentToInputWeights[0][0]);
1479  AllocateAndCopyDataToITensorHandle(&recurrentToForgetWeightsTensor, &recurrentToForgetWeights[0][0]);
1480  AllocateAndCopyDataToITensorHandle(&recurrentToCellWeightsTensor, &recurrentToCellWeights[0][0]);
1481  AllocateAndCopyDataToITensorHandle(&recurrentToOutputWeightsTensor, &recurrentToOutputWeights[0][0]);
1482  AllocateAndCopyDataToITensorHandle(&cellToInputWeightsTensor, &cellToInputWeights[0]);
1483  AllocateAndCopyDataToITensorHandle(&inputGateBiasTensor, &inputGateBias[0]);
1484  AllocateAndCopyDataToITensorHandle(&forgetGateBiasTensor, &forgetGateBias[0]);
1485  AllocateAndCopyDataToITensorHandle(&cellBiasTensor, &cellBias[0]);
1486  AllocateAndCopyDataToITensorHandle(&outputGateBiasTensor, &outputGateBias[0]);
1487  AllocateAndCopyDataToITensorHandle(&cellToForgetWeightsTensor, &cellToForgetWeights[0]);
1488  AllocateAndCopyDataToITensorHandle(&cellToOutputWeightsTensor, &cellToOutputWeights[0]);
1489  AllocateAndCopyDataToITensorHandle(&projectionWeightsTensor, &projectionWeights[0][0]);
1490  AllocateAndCopyDataToITensorHandle(&projectionBiasTensor, &projectionBias[0]);
1491 
1492  AllocateAndCopyDataToITensorHandle(&inputLayerNormWeightsTensor, &inputLayerNormWeights[0]);
1493  AllocateAndCopyDataToITensorHandle(&forgetLayerNormWeightsTensor, &forgetLayerNormWeights[0]);
1494  AllocateAndCopyDataToITensorHandle(&cellLayerNormWeightsTensor, &cellLayerNormWeights[0]);
1495  AllocateAndCopyDataToITensorHandle(&outputLayerNormWeightsTensor, &outputLayerNormWeights[0]);
1496 
1497  data.m_InputToInputWeights = &inputToInputWeightsTensor;
1498  data.m_InputToForgetWeights = &inputToForgetWeightsTensor;
1499  data.m_InputToCellWeights = &inputToCellWeightsTensor;
1500  data.m_InputToOutputWeights = &inputToOutputWeightsTensor;
1501  data.m_RecurrentToInputWeights = &recurrentToInputWeightsTensor;
1502  data.m_RecurrentToForgetWeights = &recurrentToForgetWeightsTensor;
1503  data.m_RecurrentToCellWeights = &recurrentToCellWeightsTensor;
1504  data.m_RecurrentToOutputWeights = &recurrentToOutputWeightsTensor;
1505  data.m_CellToInputWeights = &cellToInputWeightsTensor;
1506  data.m_InputGateBias = &inputGateBiasTensor;
1507  data.m_ForgetGateBias = &forgetGateBiasTensor;
1508  data.m_CellBias = &cellBiasTensor;
1509  data.m_OutputGateBias = &outputGateBiasTensor;
1510  data.m_CellToForgetWeights = &cellToForgetWeightsTensor;
1511  data.m_CellToOutputWeights = &cellToOutputWeightsTensor;
1512  data.m_ProjectionWeights = &projectionWeightsTensor;
1513  data.m_ProjectionBias = &projectionBiasTensor;
1514 
1515  data.m_InputLayerNormWeights = &inputLayerNormWeightsTensor;
1516  data.m_ForgetLayerNormWeights = &forgetLayerNormWeightsTensor;
1517  data.m_CellLayerNormWeights = &cellLayerNormWeightsTensor;
1518  data.m_OutputLayerNormWeights = &outputLayerNormWeightsTensor;
1519 
1520  // Flags to set test configuration
1521  data.m_Parameters.m_ActivationFunc = 4;
1522  data.m_Parameters.m_CifgEnabled = false;
1523  data.m_Parameters.m_PeepholeEnabled = true;
1524  data.m_Parameters.m_ProjectionEnabled = true;
1525  data.m_Parameters.m_LayerNormEnabled = true;
1526 
1527 
1528  std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateLstm(data, info);
1529  inputHandle->Allocate();
1530  outputStateInHandle->Allocate();
1531  cellStateInHandle->Allocate();
1532 
1533  scratchHandle->Allocate();
1534  outputStateOutHandle->Allocate();
1535  cellStateOutHandle->Allocate();
1536  outputHandle->Allocate();
1537 
1538  CopyDataToITensorHandle(inputHandle.get(), &inputTensor[0][0]);
1539  CopyDataToITensorHandle(outputStateInHandle.get(), &outputStateInTensor[0][0]);
1540  CopyDataToITensorHandle(cellStateInHandle.get(), &cellStateInTensor[0][0]);
1541 
1542  workload->Execute();
1543 
1544  CopyDataFromITensorHandle(&ret.output[0][0], outputHandle.get());
1545 
1546  return ret;
1547 }
1548 
1549 LayerTestResult<uint8_t, 2> QuantizedLstmTestImpl(
1550  armnn::IWorkloadFactory& workloadFactory,
1552  const boost::multi_array<uint8_t, 2>& input,
1553  const boost::multi_array<uint8_t, 2>& outputExpected)
1554 {
1555  IgnoreUnused(memoryManager);
1556  auto numBatches = boost::numeric_cast<unsigned int>(input.shape()[0]);
1557  auto inputSize = boost::numeric_cast<unsigned int>(input.shape()[1]);
1558  auto outputSize = boost::numeric_cast<unsigned int>(outputExpected.shape()[1]);
1559 
1560  // Scale/Offset for input/output, cellState In/Out, weights, bias
1561  float inputOutputScale = 0.0078125f;
1562  int32_t inputOutputOffset = 128;
1563 
1564  float cellStateScale = 0.00048828125f;
1565  int32_t cellStateOffset = 0;
1566 
1567  float weightsScale = 0.00408021f;
1568  int32_t weightsOffset = 100;
1569 
1570  float biasScale = 3.1876640625e-05f;
1571  int32_t biasOffset = 0;
1572 
1573  // Input/Output tensor info
1574  armnn::TensorInfo inputInfo({numBatches , inputSize},
1576  inputOutputScale,
1577  inputOutputOffset);
1578 
1579  armnn::TensorInfo cellStateInfo({numBatches , outputSize},
1581  cellStateScale,
1582  cellStateOffset);
1583 
1584  armnn::TensorInfo outputStateInfo({numBatches , outputSize},
1586  inputOutputScale,
1587  inputOutputOffset);
1588 
1589  LayerTestResult<uint8_t, 2> ret(outputStateInfo);
1590 
1591  // Input0
1592  std::vector<uint8_t> inputVector;
1593  inputVector.assign(input.data(), input.data() + (numBatches * inputSize));
1594  auto inputTensor = MakeTensor<uint8_t, 2>(inputInfo, inputVector);
1595 
1596  // Input1
1597  std::vector<int16_t> cellStateInVector = {876, 1034, 955, -909, 761, 1029, 796, -1036}; // 13
1598  auto cellStateInTensor = MakeTensor<int16_t, 2>(cellStateInfo, cellStateInVector);
1599 
1600  // Input2
1601  std::vector<uint8_t> outputStateInVector = {136, 150, 140, 115, 135, 152, 138, 112}; // 14
1602  auto outputStateInTensor = MakeTensor<uint8_t, 2>(outputStateInfo, outputStateInVector);
1603 
1604  // Output0
1605  std::vector<int16_t> cellStateOutVector = {1485, 1177, 1373, -1023, 1019, 1355, 1097, -1235}; // 0
1606  auto cellStateOutTensor = MakeTensor<int16_t, 2>(cellStateInfo, cellStateOutVector);
1607 
1608  // Output1
1609  std::vector<uint8_t> outputVector; // 1
1610  outputVector.assign(outputExpected.data(), outputExpected.data() + (numBatches * outputSize));
1611  ret.outputExpected = MakeTensor<uint8_t, 2>(outputStateInfo, outputVector);
1612 
1613  // Create tensor handles
1614  std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputInfo);
1615  std::unique_ptr<armnn::ITensorHandle> cellStateInHandle =
1616  workloadFactory.CreateTensorHandle(cellStateInfo);
1617  std::unique_ptr<armnn::ITensorHandle> outputStateInHandle =
1618  workloadFactory.CreateTensorHandle(outputStateInfo);
1619 
1620  std::unique_ptr<armnn::ITensorHandle> cellStateOutHandle =
1621  workloadFactory.CreateTensorHandle(cellStateInfo);
1622  std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputStateInfo);
1623 
1625  armnn::WorkloadInfo info;
1626 
1627  // Add inputs and outputs to workload
1628  AddInputToWorkload(data, info, inputInfo, inputHandle.get());
1629  AddInputToWorkload(data, info, cellStateInfo, cellStateInHandle.get());
1630  AddInputToWorkload(data, info, outputStateInfo, outputStateInHandle.get());
1631 
1632  AddOutputToWorkload(data, info, cellStateInfo, cellStateOutHandle.get());
1633  AddOutputToWorkload(data, info, outputStateInfo, outputHandle.get());
1634 
1635  // Weights and bias tensor and quantization info
1636  armnn::TensorInfo inputWeightsInfo({outputSize, inputSize},
1638  weightsScale,
1639  weightsOffset);
1640 
1641  armnn::TensorInfo recurrentWeightsInfo({outputSize, outputSize},
1643  weightsScale,
1644  weightsOffset);
1645 
1646  armnn::TensorInfo biasInfo({outputSize}, armnn::DataType::Signed32, biasScale, biasOffset);
1647 
1648  // Weights and bias tensor data
1649  auto inputToInputWeights = MakeTensor<uint8_t, 2>(inputWeightsInfo, {146, 250, 235, 171, 10, 218, 171, 108});
1650  auto inputToForgetWeights = MakeTensor<uint8_t, 2>(inputWeightsInfo, {24, 50, 132, 179, 158, 110, 3, 169});
1651  auto inputToCellWeights = MakeTensor<uint8_t, 2>(inputWeightsInfo, {133, 34, 29, 49, 206, 109, 54, 183});
1652  auto inputToOutputWeights = MakeTensor<uint8_t, 2>(inputWeightsInfo, {195, 187, 11, 99, 109, 10, 218, 48});
1653 
1654  auto recurrentToInputWeights = MakeTensor<uint8_t, 2>(recurrentWeightsInfo,
1655  {254, 206, 77, 168, 71, 20, 215, 6, 223, 7, 118, 225, 59, 130, 174, 26});
1656  auto recurrentToForgetWeights = MakeTensor<uint8_t, 2>(recurrentWeightsInfo,
1657  {137, 240, 103, 52, 68, 51, 237, 112, 0, 220, 89, 23, 69, 4, 207, 253});
1658  auto recurrentToCellWeights = MakeTensor<uint8_t, 2>(recurrentWeightsInfo,
1659  {172, 60, 205, 65, 14, 0, 140, 168, 240, 223, 133, 56, 142, 64, 246, 216});
1660  auto recurrentToOutputWeights = MakeTensor<uint8_t, 2>(recurrentWeightsInfo,
1661  {106, 214, 67, 23, 59, 158, 45, 3, 119, 132, 49, 205, 129, 218, 11, 98});
1662 
1663  auto inputGateBias = MakeTensor<int32_t, 1>(biasInfo, {-7876, 13488, -726, 32839});
1664  auto forgetGateBias = MakeTensor<int32_t, 1>(biasInfo, {9206, -46884, -11693, -38724});
1665  auto cellBias = MakeTensor<int32_t, 1>(biasInfo, {39481, 48624, 48976, -21419});
1666  auto outputGateBias = MakeTensor<int32_t, 1>(biasInfo, {-58999, -17050, -41852, -40538});
1667 
1668  // ScopedCpuTensorHandles
1669  armnn::ScopedCpuTensorHandle inputToInputWeightsTensor(inputWeightsInfo);
1670  armnn::ScopedCpuTensorHandle inputToForgetWeightsTensor(inputWeightsInfo);
1671  armnn::ScopedCpuTensorHandle inputToCellWeightsTensor(inputWeightsInfo);
1672  armnn::ScopedCpuTensorHandle inputToOutputWeightsTensor(inputWeightsInfo);
1673 
1674  armnn::ScopedCpuTensorHandle recurrentToInputWeightsTensor(recurrentWeightsInfo);
1675  armnn::ScopedCpuTensorHandle recurrentToForgetWeightsTensor(recurrentWeightsInfo);
1676  armnn::ScopedCpuTensorHandle recurrentToCellWeightsTensor(recurrentWeightsInfo);
1677  armnn::ScopedCpuTensorHandle recurrentToOutputWeightsTensor(recurrentWeightsInfo);
1678 
1679  armnn::ScopedCpuTensorHandle inputGateBiasTensor(biasInfo);
1680  armnn::ScopedCpuTensorHandle forgetGateBiasTensor(biasInfo);
1681  armnn::ScopedCpuTensorHandle cellBiasTensor(biasInfo);
1682  armnn::ScopedCpuTensorHandle outputGateBiasTensor(biasInfo);
1683 
1684  // Allocate and copy data
1685  AllocateAndCopyDataToITensorHandle(&inputToInputWeightsTensor, &inputToInputWeights[0][0]);
1686  AllocateAndCopyDataToITensorHandle(&inputToForgetWeightsTensor, &inputToForgetWeights[0][0]);
1687  AllocateAndCopyDataToITensorHandle(&inputToCellWeightsTensor, &inputToCellWeights[0][0]);
1688  AllocateAndCopyDataToITensorHandle(&inputToOutputWeightsTensor, &inputToOutputWeights[0][0]);
1689 
1690  AllocateAndCopyDataToITensorHandle(&recurrentToInputWeightsTensor, &recurrentToInputWeights[0][0]);
1691  AllocateAndCopyDataToITensorHandle(&recurrentToForgetWeightsTensor, &recurrentToForgetWeights[0][0]);
1692  AllocateAndCopyDataToITensorHandle(&recurrentToCellWeightsTensor, &recurrentToCellWeights[0][0]);
1693  AllocateAndCopyDataToITensorHandle(&recurrentToOutputWeightsTensor, &recurrentToOutputWeights[0][0]);
1694 
1695  AllocateAndCopyDataToITensorHandle(&inputGateBiasTensor, &inputGateBias[0]);
1696  AllocateAndCopyDataToITensorHandle(&forgetGateBiasTensor, &forgetGateBias[0]);
1697  AllocateAndCopyDataToITensorHandle(&cellBiasTensor, &cellBias[0]);
1698  AllocateAndCopyDataToITensorHandle(&outputGateBiasTensor, &outputGateBias[0]);
1699 
1700  // Setup queue descriptor
1701  data.m_InputToInputWeights = &inputToInputWeightsTensor;
1702  data.m_InputToForgetWeights = &inputToForgetWeightsTensor;
1703  data.m_InputToCellWeights = &inputToCellWeightsTensor;
1704  data.m_InputToOutputWeights = &inputToOutputWeightsTensor;
1705 
1706  data.m_RecurrentToInputWeights = &recurrentToInputWeightsTensor;
1707  data.m_RecurrentToForgetWeights = &recurrentToForgetWeightsTensor;
1708  data.m_RecurrentToCellWeights = &recurrentToCellWeightsTensor;
1709  data.m_RecurrentToOutputWeights = &recurrentToOutputWeightsTensor;
1710 
1711  data.m_InputGateBias = &inputGateBiasTensor;
1712  data.m_ForgetGateBias = &forgetGateBiasTensor;
1713  data.m_CellBias = &cellBiasTensor;
1714  data.m_OutputGateBias = &outputGateBiasTensor;
1715 
1716  // Create workload and allocate tensor handles
1717  std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateQuantizedLstm(data, info);
1718  inputHandle->Allocate();
1719  outputStateInHandle->Allocate();
1720  cellStateInHandle->Allocate();
1721 
1722  cellStateOutHandle->Allocate();
1723  outputHandle->Allocate();
1724 
1725  CopyDataToITensorHandle(inputHandle.get(), &inputTensor[0][0]);
1726  CopyDataToITensorHandle(outputStateInHandle.get(), &outputStateInTensor[0][0]);
1727  CopyDataToITensorHandle(cellStateInHandle.get(), &cellStateInTensor[0][0]);
1728 
1729  workload->Execute();
1730 
1731  CopyDataFromITensorHandle(&ret.output[0][0], outputHandle.get());
1732 
1733  return ret;
1734 }
1735 
1736 } // anonymous namespace
1737 
1738 #if defined(ARMNNREF_ENABLED)
1739 
1740 // The LSTM test units are run only for the reference backend at the moment
1741 
1742 void LstmUtilsZeroVectorTest()
1743 {
1745  boost::multi_array<float, 1> input = MakeTensor<float, 1>(inputDesc, std::vector<float>(
1746  {2., 3., 3., 4.}));
1747 
1748  boost::multi_array<float, 1> expectedOutput = MakeTensor<float, 1>(inputDesc, std::vector<float>(
1749  {0., 0., 0., 0.}));
1750 
1751  return LstmUtilsZeroVectorTestImpl<armnn::DataType::Float32>(input, 4, expectedOutput);
1752 }
1753 
1754 void LstmUtilsMeanStddevNormalizationNoneZeroInputTest()
1755 {
1756  uint32_t batchSize = 2;
1757  uint32_t vecSize = 4;
1758  armnn::TensorInfo inputDesc({batchSize, vecSize}, armnn::DataType::Float32);
1759  boost::multi_array<float, 2> input = MakeTensor<float, 2>(inputDesc, std::vector<float>(
1760  { 0.1f, 0.2f, 0.3f, 0.4f, //batch 0
1761  0.9f, 1.0f, 1.1f, 1.2f })); //batch 1
1762 
1763  boost::multi_array<float, 2> expectedOutput = MakeTensor<float, 2>(inputDesc, std::vector<float>(
1764  { -1.34164071f, -0.447213531f, 0.44721365f, 1.34164071f, //batch 0
1765  -1.34163153f, -0.447210163f, 0.447211236f, 1.3416326f })); //batch 1
1766 
1767  return LstmUtilsMeanStddevNormalizationTestImpl<armnn::DataType::Float32>(input,
1768  vecSize, batchSize, expectedOutput);
1769 }
1770 
1771 void LstmUtilsMeanStddevNormalizationAllZeroInputTest()
1772 {
1773  uint32_t batchSize = 2;
1774  uint32_t vecSize = 4;
1775  armnn::TensorInfo inputDesc({batchSize, vecSize}, armnn::DataType::Float32);
1776  boost::multi_array<float, 2> input = MakeTensor<float, 2>(inputDesc, std::vector<float>(
1777  { 0.0f, 0.0f, 0.0f, 0.0f, //batch 0
1778  0.0f, 0.0f, 0.0f, 0.0f })); //batch 1
1779 
1780  boost::multi_array<float, 2> expectedOutput = MakeTensor<float, 2>(inputDesc, std::vector<float>(
1781  { 0.0f, 0.0f, 0.0f, 0.0f, //batch 0
1782  0.0f, 0.0f, 0.0f, 0.0f })); //batch 1
1783 
1784  return LstmUtilsMeanStddevNormalizationTestImpl<armnn::DataType::Float32>(input,
1785  vecSize, batchSize, expectedOutput);
1786 }
1787 
1788 void LstmUtilsMeanStddevNormalizationMixedZeroInputTest()
1789 {
1790  uint32_t batchSize = 2;
1791  uint32_t vecSize = 4;
1792  armnn::TensorInfo inputDesc({batchSize, vecSize}, armnn::DataType::Float32);
1793  boost::multi_array<float, 2> input = MakeTensor<float, 2>(inputDesc, std::vector<float>(
1794  { 0.0f, 0.0f, 0.0f, 0.0f, //batch 0
1795  0.1f, 0.2f, 0.3f, 0.4f })); //batch 1
1796 
1797  boost::multi_array<float, 2> expectedOutput = MakeTensor<float, 2>(inputDesc, std::vector<float>(
1798  { 0.0f, 0.0f, 0.0f, 0.0f, //batch 0
1799  -1.34164071f, -0.447213531f, 0.44721365f, 1.34164071f })); //batch 1
1800 
1801  return LstmUtilsMeanStddevNormalizationTestImpl<armnn::DataType::Float32>(input,
1802  vecSize, batchSize, expectedOutput);
1803 }
1804 
1805 void LstmUtilsVectorBatchVectorCwiseProductTest()
1806 {
1807  uint32_t batchSize = 4;
1808  uint32_t vecSize = 29;
1809  armnn::TensorInfo vecDesc({vecSize}, armnn::DataType::Float32);
1810  boost::multi_array<float, 1> vector = MakeTensor<float, 1>(vecDesc, std::vector<float>(
1811  { 1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f, 9.9f, 10.1f,
1812  11.11f, 12.12f, 13.13f, 14.14f, 15.15f, 16.16f, 17.17f, 18.18f, 19.19f, 20.2f,
1813  21.21f, 22.22f, 23.23f, 24.24f, 25.25f, 26.26f, 27.27f, 28.28f, 0.0f}));
1814 
1815  armnn::TensorInfo batchVecDesc({batchSize, vecSize}, armnn::DataType::Float32);
1816  boost::multi_array<float, 2> batchVector = MakeTensor<float, 2>(batchVecDesc, std::vector<float>(
1817  { /* batch 0 */
1818  1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f, 9.9f, 10.1f,
1819  11.11f, 12.12f, 13.13f, 14.14f, 15.15f, 16.16f, 17.17f, 18.18f, 19.19f, 20.2f,
1820  21.21f, 22.22f, 23.23f, 24.24f, 25.25f, 26.26f, 27.27f, 28.28f, 0.0f,
1821  /* batch 1 */
1822  -1.1f, -2.2f, -3.3f, -4.4f, -5.5f, -6.6f, -7.7f, -8.8f, -9.9f, -10.1f,
1823  -11.11f, -12.12f, -13.13f, -14.14f, -15.15f, -16.16f, -17.17f, -18.18f, -19.19f, -20.2f,
1824  -21.21f, -22.22f, -23.23f, -24.24f, -25.25f, -26.26f, -27.27f, -28.28f, 0.0f,
1825  /* batch 2 */
1826  1.1f, -2.2f, 3.3f, -4.4f, 5.5f, -6.6f, 7.7f, -8.8f, 9.9f, -10.1f,
1827  11.11f, -12.12f, 13.13f, -14.14f, 15.15f, -16.16f, 17.17f, -18.18f, 19.19f, -20.2f,
1828  21.21f, -22.22f, 23.23f, -24.24f, 25.25f, -26.26f, 27.27f, -28.28f, 0.0f,
1829  /* batch 3 */
1830  -1.1f, 2.2f, -3.3f, 4.4f, -5.5f, 6.6f, -7.7f, 8.8f, -9.9f, 10.1f,
1831  -11.11f, 12.12f, -13.13f, 14.14f, -15.15f, 16.16f, -17.17f, 18.18f, -19.19f, 20.2f,
1832  -21.21f, 22.22f, -23.23f, 24.24f, -25.25f, 26.26f, -27.27f, 28.28f, 0.0f}));
1833 
1834  // Expect output = input * output + output.
1835  boost::multi_array<float, 2> expectedOutput = MakeTensor<float, 2>(batchVecDesc, std::vector<float>(
1836  { /* batch 0 */
1837  1.210000f, 4.840000f, 10.889999f, 19.360001f, 30.250000f, 43.559998f,
1838  59.289997f, 77.440002f, 98.009995f, 102.010010f, 123.432091f, 146.894394f,
1839  172.396896f, 199.939606f, 229.522491f, 261.145599f, 294.808899f, 330.512421f,
1840  368.256134f, 408.040039f, 449.864075f, 493.728363f, 539.632874f, 587.577576f,
1841  637.562500f, 689.587585f, 743.652954f, 799.758423f, 0.000000f,
1842  /* batch 1 */
1843  -1.210000f, -4.840000f, -10.889999f, -19.360001f, -30.250000f, -43.559998f,
1844  -59.289997f, -77.440002f, -98.009995f, -102.010010f, -123.432091f, -146.894394f,
1845  -172.396896f, -199.939606f, -229.522491f, -261.145599f, -294.808899f, -330.512421f,
1846  -368.256134f, -408.040039f, -449.864075f, -493.728363f, -539.632874f, -587.577576f,
1847  -637.562500f, -689.587585f, -743.652954f, -799.758423f, 0.000000f,
1848  /* batch 2 */
1849  1.210000f, -4.840000f, 10.889999f, -19.360001f, 30.250000f, -43.559998f,
1850  59.289997f, -77.440002f, 98.009995f, -102.010010f, 123.432091f, -146.894394f,
1851  172.396896f, -199.939606f, 229.522491f, -261.145599f, 294.808899f, -330.512421f,
1852  368.256134f, -408.040039f, 449.864075f, -493.728363f, 539.632874f, -587.577576f,
1853  637.562500f, -689.587585f, 743.652954f, -799.758423f, 0.000000f,
1854  /* batch 3 */
1855  -1.210000f, 4.840000f, -10.889999f, 19.360001f, -30.250000f, 43.559998f,
1856  -59.289997f, 77.440002f, -98.009995f, 102.010010f, -123.432091f, 146.894394f,
1857  -172.396896f, 199.939606f, -229.522491f, 261.145599f, -294.808899f, 330.512421f,
1858  -368.256134f, 408.040039f, -449.864075f, 493.728363f, -539.632874f, 587.577576f,
1859  -637.562500f, 689.587585f, -743.652954f, 799.758423f, 0.000000f}));
1860 
1861  return LstmUtilsVectorBatchVectorCwiseProductTestImpl<armnn::DataType::Float32>(vector, batchVector,
1862  vecSize, batchSize, expectedOutput);
1863 }
1864 
1865 void LstmUtilsVectorBatchVectorAddTest()
1866 {
1867  uint32_t batchSize = 2;
1868  uint32_t vecSize = 3;
1869  armnn::TensorInfo vecDesc({vecSize}, armnn::DataType::Float32);
1870  boost::multi_array<float, 1> vector = MakeTensor<float, 1>(vecDesc, std::vector<float>(
1871  { 0.0f, -0.5f, 1.0f}));
1872 
1873  armnn::TensorInfo batchVecDesc({batchSize, vecSize}, armnn::DataType::Float32);
1874  boost::multi_array<float, 2> batchVector = MakeTensor<float, 2>(batchVecDesc, std::vector<float>(
1875  { 1.0f, 2.0f, 3.0f, //batch 0
1876  4.0f, 5.0f, 6.0f})); //batch 1
1877 
1878  boost::multi_array<float, 2> expectedOutput = MakeTensor<float, 2>(batchVecDesc, std::vector<float>(
1879  { 1.0f, 1.5f, 4.0f,
1880  4.0f, 4.5f, 7.0f}));
1881 
1882  return LstmUtilsVectorBatchVectorAddTestImpl<armnn::DataType::Float32>(vector, batchVector,
1883  vecSize, batchSize, expectedOutput);
1884 }
1885 
1886 #endif
1887 
1889  armnn::IWorkloadFactory& workloadFactory,
1891 {
1892  armnn::TensorInfo inputDesc({ 2, 2 }, armnn::DataType::Float32);
1893  boost::multi_array<float, 2> input = MakeTensor<float, 2>(inputDesc, std::vector<float>(
1894  { 2., 3., 3., 4. }));
1895 
1896  armnn::TensorInfo outputDesc({ 2, 4 }, armnn::DataType::Float32);
1897  boost::multi_array<float, 2> expectedOutput = MakeTensor<float, 2>(outputDesc, std::vector<float>(
1898  {-0.36444446f, -0.00352185f, 0.12886585f, -0.05163646f,
1899  -0.42734814f, -0.00478661f, 0.13455015f, -0.03560682f}));
1900  return LstmLayerWithCifgWithPeepholeNoProjectionTestImpl<armnn::DataType::Float32>(
1901  workloadFactory, memoryManager, input, expectedOutput);
1902 }
1903 
1905  armnn::IWorkloadFactory& workloadFactory,
1907 {
1908  armnn::TensorInfo inputDesc({ 2, 5 }, armnn::DataType::Float32);
1909  boost::multi_array<float, 2> input = MakeTensor<float, 2>(inputDesc, std::vector<float>(
1910  {0.787926f, 0.151646f, 0.071352f, 0.118426f, 0.458058f,
1911  0.295743f, 0.544053f, 0.690064f, 0.858138f, 0.497181f}));
1912 
1913  armnn::TensorInfo outputDesc({ 2, 16 }, armnn::DataType::Float32);
1914  boost::multi_array<float, 2> expectedOutput = MakeTensor<float, 2>(outputDesc, std::vector<float>(
1915  {-0.00396806f, 0.029352f, -0.00279226f, 0.0159977f, -0.00835576f,
1916  -0.0211779f, 0.0283512f, -0.0114597f, 0.00907307f, -0.0244004f,
1917  -0.0152191f, -0.0259063f, 0.00914318f, 0.00415118f, 0.017147f,
1918  0.0134203f, -0.013869f, 0.0287268f, -0.00334693f, 0.00733398f, -0.0287926f,
1919  -0.0186926f, 0.0193662f, -0.0115437f, 0.00422612f, -0.0345232f,
1920  0.00223253f, -0.00957321f, 0.0210624f, 0.013331f, 0.0150954f,
1921  0.02168f}));
1922  return LstmLayerNoCifgWithPeepholeWithProjectionTestImpl<armnn::DataType::Float32>(
1923  workloadFactory, memoryManager, input, expectedOutput);
1924 }
1925 
1927  armnn::IWorkloadFactory& workloadFactory,
1929 {
1930  armnn::TensorInfo inputDesc({2, 2}, armnn::DataType::Float32);
1931  boost::multi_array<float, 2> input = MakeTensor<float, 2>(inputDesc, std::vector<float>(
1932  {2., 3., 3., 4.}));
1933 
1934  armnn::TensorInfo outputDesc({2, 4}, armnn::DataType::Float32);
1935  boost::multi_array<float, 2> expectedOutput = MakeTensor<float, 2>(outputDesc, std::vector<float>(
1936  {{-0.02973187f, 0.1229473f, 0.20885126f, -0.15358765f,
1937  -0.0185422f, 0.11281417f, 0.24466537f, -0.1826292f}}));
1938 
1939  return LstmNoCifgNoPeepholeNoProjectionTestImpl<armnn::DataType::Float32>(
1940  workloadFactory, memoryManager, input, expectedOutput);
1941 }
1942 
1944  armnn::IWorkloadFactory& workloadFactory,
1946 {
1947  armnn::TensorInfo inputDesc({ 2, 5 }, armnn::DataType::Float32);
1948  boost::multi_array<float, 2> input = MakeTensor<float, 2>(inputDesc, std::vector<float>(
1949  {0.7f, 0.8f, 0.1f, 0.2f, 0.3f, //batch 0
1950  0.3f, 0.2f, 0.9f, 0.8f, 0.1f})); //batch 1
1951 
1952  armnn::TensorInfo outputDesc({ 2, 3 }, armnn::DataType::Float32);
1953  boost::multi_array<float, 2> expectedOutput = MakeTensor<float, 2>(outputDesc, std::vector<float>(
1954  { 0.0244077f, 0.128027f, -0.00170918f, //batch 0
1955  -0.00692428f, 0.0848741f, 0.063445f})); //batch 1
1956  return LstmLayerNoCifgWithPeepholeWithProjectionWithLayerNormTestImpl<armnn::DataType::Float32>(
1957  workloadFactory, memoryManager, input, expectedOutput);
1958 }
1959 
1961  armnn::IWorkloadFactory& workloadFactory,
1963 {
1964  const float qScale = 1.0f;
1965  const int32_t qOffset = 0;
1966 
1967  const armnn::DataType datatype = armnn::DataType::QSymmS16;
1968  const armnn::DataType constantDatatype = armnn::DataType::QAsymmU8;
1969 
1970  armnn::TensorInfo inputDesc({2, 2}, datatype);
1971  boost::multi_array<int16_t , 2> input = MakeTensor<int16_t , 2>(
1972  inputDesc,
1973  armnnUtils::QuantizedVector<int16_t>({ 2.f, 3.f, 3.f, 4.f }, qScale, qOffset));
1974 
1975  armnn::TensorInfo outputDesc({2, 4}, datatype);
1976  boost::multi_array<int16_t, 2> expectedOutput = MakeTensor<int16_t, 2>(
1977  outputDesc,
1978  armnnUtils::QuantizedVector<int16_t>(
1979  {
1980  -0.02973187f, 0.12294730f, 0.20885126f, -0.15358765f,
1981  -0.01854220f, 0.11281417f, 0.24466537f, -0.18262920f
1982  },
1983  qScale, qOffset));
1984 
1985  return LstmNoCifgNoPeepholeNoProjectionTestImpl<datatype>(
1986  workloadFactory, memoryManager, input, expectedOutput, qScale, qOffset, constantDatatype);
1987 
1988 }
1989 
1991  armnn::IWorkloadFactory& workloadFactory,
1993 {
1994  const float qScale = 1.0f;
1995  const int32_t qOffset = 0;
1996 
1997  const armnn::DataType datatype = armnn::DataType::QSymmS16;
1998  const armnn::DataType constantDatatype = armnn::DataType::QAsymmU8;
1999 
2000  armnn::TensorInfo inputDesc({ 2, 2 }, datatype);
2001  boost::multi_array<int16_t, 2> input =
2002  MakeTensor<int16_t, 2>(
2003  inputDesc,
2004  armnnUtils::QuantizedVector<int16_t>({ 2.f, 3.f, 3.f, 4.f }, qScale, qOffset));
2005 
2006  armnn::TensorInfo outputDesc({ 2, 4 }, datatype);
2007  boost::multi_array<int16_t, 2> expectedOutput =
2008  MakeTensor<int16_t, 2>(
2009  outputDesc,
2010  armnnUtils::QuantizedVector<int16_t>(
2011  {
2012  -0.36444446f, -0.00352185f, 0.12886585f, -0.05163646f,
2013  -0.42734814f, -0.00478661f, 0.13455015f, -0.03560682f
2014  },
2015  qScale, qOffset));
2016 
2017  return LstmLayerWithCifgWithPeepholeNoProjectionTestImpl<datatype>(
2018  workloadFactory, memoryManager, input, expectedOutput, qScale, qOffset, constantDatatype);
2019 }
2020 
2022  armnn::IWorkloadFactory& workloadFactory,
2024 {
2025  const float qScale = 2.0f;
2026  const int32_t qOffset = 0;
2027 
2028  const armnn::DataType datatype = armnn::DataType::QSymmS16;
2029  const armnn::DataType constantDatatype = armnn::DataType::QAsymmU8;
2030 
2031  armnn::TensorInfo inputDesc({ 2, 5 }, datatype);
2032  boost::multi_array<int16_t, 2> input =
2033  MakeTensor<int16_t, 2>(
2034  inputDesc,
2035  armnnUtils::QuantizedVector<int16_t>(
2036  {
2037  0.787926f, 0.151646f, 0.071352f, 0.118426f, 0.458058f,
2038  0.295743f, 0.544053f, 0.690064f, 0.858138f, 0.497181f
2039  },
2040  qScale, qOffset));
2041 
2042  armnn::TensorInfo outputDesc({ 2, 16 }, datatype);
2043  boost::multi_array<int16_t, 2> expectedOutput =
2044  MakeTensor<int16_t, 2>(
2045  outputDesc,
2046  armnnUtils::QuantizedVector<int16_t>(
2047  {
2048  -0.00396806f, 0.02935200f, -0.00279226f, 0.01599770f,
2049  -0.00835576f, -0.02117790f, 0.02835120f, -0.01145970f,
2050  0.00907307f, -0.02440040f, -0.01521910f, -0.02590630f,
2051  0.00914318f, 0.00415118f, 0.01714700f, 0.01342030f,
2052  -0.01386900f, 0.02872680f, -0.00334693f, 0.00733398f,
2053  -0.02879260f, -0.01869260f, 0.01936620f, -0.01154370f,
2054  0.00422612f, -0.03452320f, 0.00223253f, -0.00957321f,
2055  0.02106240f, 0.01333100f, 0.01509540f, 0.02168000f
2056  },
2057  qScale, qOffset));
2058 
2059  return LstmLayerNoCifgWithPeepholeWithProjectionTestImpl<datatype>(
2060  workloadFactory, memoryManager, input, expectedOutput, qScale, qOffset, constantDatatype);
2061 }
2062 
2064  armnn::IWorkloadFactory& workloadFactory,
2066 {
2067  const float qScale = 1.0f;
2068  const int32_t qOffset = 0;
2069 
2070  const armnn::DataType datatype = armnn::DataType::QSymmS16; // datatype & constants set to QSymm16
2071 
2072  armnn::TensorInfo inputDesc({2, 2}, datatype);
2073  boost::multi_array<int16_t , 2> input =
2074  MakeTensor<int16_t , 2>(inputDesc,
2075  armnnUtils::QuantizedVector<int16_t>({ 2.f, 3.f, 3.f, 4.f }, qScale, qOffset));
2076 
2077  armnn::TensorInfo outputDesc({2, 4}, datatype);
2078  boost::multi_array<int16_t, 2> expectedOutput =
2079  MakeTensor<int16_t, 2>(
2080  outputDesc,
2081  armnnUtils::QuantizedVector<int16_t>(
2082  {
2083  -0.02973187f, 0.12294730f, 0.20885126f, -0.15358765f,
2084  -0.01854220f, 0.11281417f, 0.24466537f, -0.18262920f
2085  },
2086  qScale, qOffset));
2087 
2088  return LstmNoCifgNoPeepholeNoProjectionTestImpl<datatype>(
2089  workloadFactory, memoryManager, input, expectedOutput, qScale, qOffset, datatype);
2090 }
2091 
2092 //
2093 // QuantizedLstm
2094 //
2095 
2097  armnn::IWorkloadFactory& workloadFactory,
2099 {
2100  armnn::TensorInfo inputDesc({2, 2}, armnn::DataType::QAsymmU8);
2101  boost::multi_array<uint8_t, 2> input = MakeTensor<uint8_t, 2>(inputDesc, std::vector<uint8_t>(
2102  {166, 179, 50, 150}));
2103 
2104  armnn::TensorInfo outputDesc({2, 4}, armnn::DataType::QAsymmU8);
2105  boost::multi_array<uint8_t, 2> expectedOutput = MakeTensor<uint8_t, 2>(outputDesc, std::vector<uint8_t>(
2106  {140, 151, 146, 112, 136, 156, 142, 112 }));
2107 
2108  return QuantizedLstmTestImpl(workloadFactory, memoryManager, input, expectedOutput);
2109 }
void MeanStddevNormalization(armnn::Decoder< float > &input_vector, armnn::Encoder< float > &output_vector, uint32_t v_size, uint32_t n_batch, float normalization_epsilon)
Definition: LstmUtils.cpp:40
void VectorBatchVectorAdd(armnn::Decoder< float > &vector, uint32_t vSize, armnn::Decoder< float > &batchVector, uint32_t nBatch, armnn::Encoder< float > &outResult)
Definition: LstmUtils.cpp:16
bool m_ProjectionEnabled
Enable/disable the projection layer.
const ConstCpuTensorHandle * m_RecurrentToForgetWeights
const ConstCpuTensorHandle * m_InputGateBias
const ConstCpuTensorHandle * m_RecurrentToForgetWeights
LayerTestResult< int16_t, 2 > LstmLayerInt16NoCifgWithPeepholeWithProjectionTest(armnn::IWorkloadFactory &workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager)
const ConstCpuTensorHandle * m_CellToOutputWeights
const ConstCpuTensorHandle * m_InputToCellWeights
const ConstCpuTensorHandle * m_InputToOutputWeights
LayerTestResult< float, 2 > LstmLayerFloat32NoCifgWithPeepholeWithProjectionTest(armnn::IWorkloadFactory &workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager)
const ConstCpuTensorHandle * m_InputToCellWeights
boost::test_tools::predicate_result CompareTensors(const boost::multi_array< T, n > &a, const boost::multi_array< T, n > &b, bool compareBoolean=false)
const ConstCpuTensorHandle * m_ProjectionBias
virtual std::unique_ptr< IWorkload > CreateLstm(const LstmQueueDescriptor &descriptor, const WorkloadInfo &info) const
const ConstCpuTensorHandle * m_OutputGateBias
virtual std::unique_ptr< IWorkload > CreateQuantizedLstm(const QuantizedLstmQueueDescriptor &descriptor, const WorkloadInfo &info) const
const ConstCpuTensorHandle * m_CellToInputWeights
const ConstCpuTensorHandle * m_CellLayerNormWeights
void ZeroVector(armnn::Encoder< float > &vector, uint32_t vSize)
Definition: LstmUtils.cpp:76
void IgnoreUnused(Ts &&...)
const ConstCpuTensorHandle * m_CellToForgetWeights
const ConstCpuTensorHandle * m_CellBias
const ConstCpuTensorHandle * m_RecurrentToInputWeights
void VectorBatchVectorCwiseProduct(armnn::Decoder< float > &vector, uint32_t vSize, armnn::Decoder< float > &batchVector, uint32_t nBatch, armnn::Encoder< float > &outResult)
Definition: LstmUtils.cpp:152
const ConstCpuTensorHandle * m_InputLayerNormWeights
const ConstCpuTensorHandle * m_OutputLayerNormWeights
DataType
Definition: Types.hpp:32
const ConstCpuTensorHandle * m_ForgetGateBias
std::shared_ptr< IMemoryManager > IMemoryManagerSharedPtr
const ConstCpuTensorHandle * m_ForgetGateBias
const ConstCpuTensorHandle * m_InputToInputWeights
bool m_PeepholeEnabled
Enable/disable peephole.
const ConstCpuTensorHandle * m_RecurrentToInputWeights
std::enable_if_t< std::is_unsigned< Source >::value &&std::is_unsigned< Dest >::value, Dest > numeric_cast(Source source)
Definition: NumericCast.hpp:33
const ConstCpuTensorHandle * m_RecurrentToCellWeights
void AllocateAndCopyDataToITensorHandle(armnn::ITensorHandle *tensorHandle, const void *memory)
void CopyDataFromITensorHandle(void *memory, const armnn::ITensorHandle *tensorHandle)
LayerTestResult< int16_t, 2 > LstmLayerInt16WithCifgWithPeepholeNoProjectionTest(armnn::IWorkloadFactory &workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager)
const ConstCpuTensorHandle * m_RecurrentToOutputWeights
uint32_t m_ActivationFunc
The activation function to use.
virtual std::unique_ptr< ITensorHandle > CreateTensorHandle(const TensorInfo &tensorInfo, const bool IsMemoryManaged=true) const =0
LayerTestResult< float, 2 > LstmLayerFloat32WithCifgWithPeepholeNoProjectionTest(armnn::IWorkloadFactory &workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager)
bool m_CifgEnabled
Enable/disable cifg (coupled input & forget gate).
const ConstCpuTensorHandle * m_RecurrentToOutputWeights
LayerTestResult< int16_t, 2 > LstmLayerInt16NoCifgNoPeepholeNoProjectionTest(armnn::IWorkloadFactory &workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager)
LayerTestResult< int16_t, 2 > LstmLayerInt16NoCifgNoPeepholeNoProjectionInt16ConstantTest(armnn::IWorkloadFactory &workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager)
const ConstCpuTensorHandle * m_ForgetLayerNormWeights
const ConstCpuTensorHandle * m_CellBias
LayerTestResult< uint8_t, 2 > QuantizedLstmTest(armnn::IWorkloadFactory &workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager)
const ConstCpuTensorHandle * m_OutputGateBias
const ConstCpuTensorHandle * m_InputGateBias
bool m_LayerNormEnabled
Enable/disable layer normalization.
Contains information about inputs and outputs to a layer.
const ConstCpuTensorHandle * m_RecurrentToCellWeights
const ConstCpuTensorHandle * m_InputToForgetWeights
LayerTestResult< float, 2 > LstmLayerFloat32NoCifgNoPeepholeNoProjectionTest(armnn::IWorkloadFactory &workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager)
const ConstCpuTensorHandle * m_InputToOutputWeights
const ConstCpuTensorHandle * m_InputToInputWeights
LayerTestResult< float, 2 > LstmLayerFloat32NoCifgWithPeepholeWithProjectionWithLayerNormTest(armnn::IWorkloadFactory &workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr &memoryManager)
const ConstCpuTensorHandle * m_ProjectionWeights
void CopyDataToITensorHandle(armnn::ITensorHandle *tensorHandle, const void *memory)
const ConstCpuTensorHandle * m_InputToForgetWeights