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