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