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