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