blob: 5381df527657e1677558308a4815cb372f3fa095 [file] [log] [blame]
Narumol Prangnawarate5339e72021-07-28 17:33:28 +01001//
Teresa Charlinacb3ec52023-04-03 19:57:00 +01002// Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved.
Narumol Prangnawarate5339e72021-07-28 17:33:28 +01003// SPDX-License-Identifier: MIT
4//
5
6#include "UnidirectionalSequenceLstmTestImpl.hpp"
7
8#include <armnn/utility/NumericCast.hpp>
9
Colm Donelan0c479742021-12-10 12:43:54 +000010#include <armnn/backends/TensorHandle.hpp>
Narumol Prangnawarate5339e72021-07-28 17:33:28 +010011
Sadik Armagana097d2a2021-11-24 15:47:28 +000012#include <armnnTestUtils/TensorCopyUtils.hpp>
Colm Donelan0c479742021-12-10 12:43:54 +000013#include <armnnTestUtils/WorkloadTestUtils.hpp>
Narumol Prangnawarate5339e72021-07-28 17:33:28 +010014
15#include <ResolveType.hpp>
16
17namespace {
18
19template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Cathal Corbettfd5bec42022-03-03 15:13:23 +000020LayerTestResult<T, 3>
21UnidirectionalSequenceLstmTimeMajorSingleBatchTestImpl(
22 armnn::IWorkloadFactory& workloadFactory,
23 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
24 const armnn::ITensorHandleFactory& tensorHandleFactory,
25 const std::vector<T>& input,
26 const std::vector<T>& outputExpected,
27 const armnn::TensorShape& inputShape,
28 const armnn::TensorShape& outputExpectedShape,
Teresa Charlinacb3ec52023-04-03 19:57:00 +010029 float qScale = 1.0f,
Cathal Corbettfd5bec42022-03-03 15:13:23 +000030 int32_t qOffset = 0,
31 armnn::DataType constantDataType = armnn::DataType::Float32)
32{
33 IgnoreUnused(memoryManager);
Mike Kelly12994962022-04-21 11:57:09 +010034 unsigned int batchSize = armnn::numeric_cast<unsigned int>(inputShape[0]);
Cathal Corbettfd5bec42022-03-03 15:13:23 +000035 unsigned int inputSize = armnn::numeric_cast<unsigned int>(inputShape[2]);
36 unsigned int outputSize = armnn::numeric_cast<unsigned int>(outputExpectedShape[2]);
37 unsigned numUnits = outputSize;
38
39 armnn::TensorInfo inputTensorInfo({1, batchSize , inputSize}, ArmnnType, qScale, qOffset );
40 armnn::TensorInfo cellStateInTensorInfo({batchSize , numUnits}, ArmnnType, qScale, qOffset);
41 armnn::TensorInfo outputStateInTensorInfo({batchSize , outputSize}, ArmnnType, qScale, qOffset);
Mike Kelly12994962022-04-21 11:57:09 +010042 armnn::TensorInfo outputStateOutTensorInfo({ batchSize, 1, outputSize }, ArmnnType, qScale, qOffset);
43 armnn::TensorInfo cellStateOutTensorInfo({ batchSize, 1, outputSize }, ArmnnType, qScale, qOffset);
Cathal Corbettfd5bec42022-03-03 15:13:23 +000044 armnn::TensorInfo outputTensorInfo({1, batchSize, outputSize}, ArmnnType, qScale, qOffset);
45
46 std::vector<T> inputVector;
47 inputVector.assign(input.data(), input.data() + (batchSize * inputSize));
48
49 std::vector<T> cellStateInVector(batchSize * numUnits, T());
50 std::vector<T> outputStateInVector(batchSize * outputSize, T());
51
Mike Kelly12994962022-04-21 11:57:09 +010052 std::vector<T> actualOutputStateOut(outputStateOutTensorInfo.GetNumElements());
53 std::vector<T> actualCellStateOut(cellStateOutTensorInfo.GetNumElements());
Cathal Corbettfd5bec42022-03-03 15:13:23 +000054 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
55
56 std::vector<T> outputVector;
57 outputVector.assign(outputExpected.data(), outputExpected.data() + (batchSize * outputSize));
58
59 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
60 std::unique_ptr<armnn::ITensorHandle> cellStateInHandle =
61 tensorHandleFactory.CreateTensorHandle(cellStateInTensorInfo);
62 std::unique_ptr<armnn::ITensorHandle> outputStateInHandle =
63 tensorHandleFactory.CreateTensorHandle(outputStateInTensorInfo);
64
Mike Kelly12994962022-04-21 11:57:09 +010065 std::unique_ptr<armnn::ITensorHandle> outputStateOutHandle =
66 tensorHandleFactory.CreateTensorHandle(outputStateOutTensorInfo);
67 std::unique_ptr<armnn::ITensorHandle> cellStateOutHandle =
68 tensorHandleFactory.CreateTensorHandle(cellStateOutTensorInfo);
Cathal Corbettfd5bec42022-03-03 15:13:23 +000069 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
70
71 armnn::UnidirectionalSequenceLstmQueueDescriptor data;
72 armnn::WorkloadInfo info;
73
74 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
75 AddInputToWorkload(data, info, outputStateInTensorInfo, outputStateInHandle.get());
76 AddInputToWorkload(data, info, cellStateInTensorInfo, cellStateInHandle.get());
77
Mike Kelly12994962022-04-21 11:57:09 +010078 AddOutputToWorkload(data, info, outputStateOutTensorInfo, outputStateOutHandle.get());
79 AddOutputToWorkload(data, info, cellStateOutTensorInfo, cellStateOutHandle.get());
Cathal Corbettfd5bec42022-03-03 15:13:23 +000080 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
81
82 armnn::TensorInfo tensorInfo4({numUnits}, constantDataType , qScale, qOffset);
83 armnn::TensorInfo tensorInfo8({numUnits, 2}, constantDataType, qScale, qOffset);
84 armnn::TensorInfo tensorInfo16({numUnits, 4}, constantDataType, qScale, qOffset);
85
86 std::vector<float> inputToInputWeights = {-0.45018822f, -0.02338299f, -0.0870589f,
87 -0.34550029f, 0.04266912f, -0.15680569f,
88 -0.34856534f, 0.43890524f};
89
90 std::vector<float> inputToForgetWeights = { 0.09701663f, 0.20334584f, -0.50592935f,
91 -0.31343272f, -0.40032279f, 0.44781327f,
92 0.01387155f, -0.35593212f};
93
94 std::vector<float> inputToCellWeights = { -0.50013041f, 0.1370284f, 0.11810488f, 0.2013163f,
95 -0.20583314f, 0.44344562f, 0.22077113f,
96 -0.29909778f};
97
98 std::vector<float> inputToOutputWeights = { -0.25065863f, -0.28290087f, 0.04613829f,
99 0.40525138f, 0.44272184f, 0.03897077f,
100 -0.1556896f, 0.19487578f};
101
102 std::vector<float> recurrentToInputWeights = {-0.0063535f, -0.2042388f, 0.31454784f,
103 -0.35746509f, 0.28902304f, 0.08183324f,
104 -0.16555229f, 0.02286911f, -0.13566875f,
105 0.03034258f, 0.48091322f, -0.12528998f,
106 0.24077177f, -0.51332325f, -0.33502164f,
107 0.10629296f};
108
109 std::vector<float> recurrentToForgetWeights = { -0.48684245f, -0.06655136f, 0.42224967f,
110 0.2112639f, 0.27654213f, 0.20864892f,
111 -0.07646349f, 0.45877004f, 0.00141793f,
112 -0.14609534f, 0.36447752f, 0.09196436f,
113 0.28053468f, 0.01560611f, -0.20127171f,
114 -0.01140004f};
115
116 std::vector<float> recurrentToCellWeights = { -0.3407414f, 0.24443203f, -0.2078532f,
117 0.26320225f, 0.05695659f, -0.00123841f,
118 -0.4744786f, -0.35869038f, -0.06418842f,
119 -0.13502428f, -0.501764f, 0.22830659f,
120 -0.46367589f, 0.26016325f, -0.03894562f,
121 -0.16368064f};
122
123 std::vector<float> recurrentToOutputWeights = { 0.43385774f, -0.17194885f, 0.2718237f,
124 0.09215671f, 0.24107647f, -0.39835793f,
125 0.18212086f, 0.01301402f, 0.48572797f,
126 -0.50656658f, 0.20047462f, -0.20607421f,
127 -0.51818722f, -0.15390486f, 0.0468148f,
128 0.39922136f};
129
130 std::vector<float> cellToInputWeights = {0., 0., 0., 0.};
131
132 std::vector<float> inputGateBias = {0., 0., 0., 0.};
133
134 std::vector<float> forgetGateBias = {1., 1., 1., 1.};
135
136 std::vector<float> cellBias = {0., 0., 0., 0.};
137
138 std::vector<float> outputGateBias = {0., 0., 0., 0.};
139
140 armnn::ScopedTensorHandle inputToInputWeightsTensor(tensorInfo8);
141 armnn::ScopedTensorHandle inputToForgetWeightsTensor(tensorInfo8);
142 armnn::ScopedTensorHandle inputToCellWeightsTensor(tensorInfo8);
143 armnn::ScopedTensorHandle inputToOutputWeightsTensor(tensorInfo8);
144 armnn::ScopedTensorHandle recurrentToInputWeightsTensor(tensorInfo16);
145 armnn::ScopedTensorHandle recurrentToForgetWeightsTensor(tensorInfo16);
146 armnn::ScopedTensorHandle recurrentToCellWeightsTensor(tensorInfo16);
147 armnn::ScopedTensorHandle recurrentToOutputWeightsTensor(tensorInfo16);
148 armnn::ScopedTensorHandle cellToInputWeightsTensor(tensorInfo4);
149 armnn::ScopedTensorHandle inputGateBiasTensor(tensorInfo4);
150 armnn::ScopedTensorHandle forgetGateBiasTensor(tensorInfo4);
151 armnn::ScopedTensorHandle cellBiasTensor(tensorInfo4);
152 armnn::ScopedTensorHandle outputGateBiasTensor(tensorInfo4);
153
154 AllocateAndCopyDataToITensorHandle(&inputToInputWeightsTensor, inputToInputWeights.data());
155 AllocateAndCopyDataToITensorHandle(&inputToForgetWeightsTensor, inputToForgetWeights.data());
156 AllocateAndCopyDataToITensorHandle(&inputToCellWeightsTensor, inputToCellWeights.data());
157 AllocateAndCopyDataToITensorHandle(&inputToOutputWeightsTensor, inputToOutputWeights.data());
158 AllocateAndCopyDataToITensorHandle(&recurrentToInputWeightsTensor, recurrentToInputWeights.data());
159 AllocateAndCopyDataToITensorHandle(&recurrentToForgetWeightsTensor, recurrentToForgetWeights.data());
160 AllocateAndCopyDataToITensorHandle(&recurrentToCellWeightsTensor, recurrentToCellWeights.data());
161 AllocateAndCopyDataToITensorHandle(&recurrentToOutputWeightsTensor, recurrentToOutputWeights.data());
162 AllocateAndCopyDataToITensorHandle(&cellToInputWeightsTensor, cellToInputWeights.data());
163 AllocateAndCopyDataToITensorHandle(&inputGateBiasTensor, inputGateBias.data());
164 AllocateAndCopyDataToITensorHandle(&forgetGateBiasTensor, forgetGateBias.data());
165 AllocateAndCopyDataToITensorHandle(&cellBiasTensor, cellBias.data());
166 AllocateAndCopyDataToITensorHandle(&outputGateBiasTensor, outputGateBias.data());
167
168 data.m_InputToInputWeights = &inputToInputWeightsTensor;
169 data.m_InputToForgetWeights = &inputToForgetWeightsTensor;
170 data.m_InputToCellWeights = &inputToCellWeightsTensor;
171 data.m_InputToOutputWeights = &inputToOutputWeightsTensor;
172 data.m_RecurrentToInputWeights = &recurrentToInputWeightsTensor;
173 data.m_RecurrentToForgetWeights = &recurrentToForgetWeightsTensor;
174 data.m_RecurrentToCellWeights = &recurrentToCellWeightsTensor;
175 data.m_RecurrentToOutputWeights = &recurrentToOutputWeightsTensor;
176 data.m_InputGateBias = &inputGateBiasTensor;
177 data.m_ForgetGateBias = &forgetGateBiasTensor;
178 data.m_CellBias = &cellBiasTensor;
179 data.m_OutputGateBias = &outputGateBiasTensor;
180
181 // Flags to set test configuration
182 data.m_Parameters.m_ActivationFunc = 4;
183 data.m_Parameters.m_CifgEnabled = false;
184 data.m_Parameters.m_PeepholeEnabled = false;
185 data.m_Parameters.m_ProjectionEnabled = false;
186 data.m_Parameters.m_ClippingThresCell = 10;
187 data.m_Parameters.m_ClippingThresProj = 0;
188 data.m_Parameters.m_TimeMajor = true;
189
190 std::unique_ptr<armnn::IWorkload> workload
191 = workloadFactory.CreateWorkload(armnn::LayerType::UnidirectionalSequenceLstm, data, info);
192 inputHandle->Allocate();
193 outputStateInHandle->Allocate();
194 cellStateInHandle->Allocate();
195
Mike Kelly12994962022-04-21 11:57:09 +0100196 outputStateOutHandle->Allocate();
197 cellStateOutHandle->Allocate();
Cathal Corbettfd5bec42022-03-03 15:13:23 +0000198 outputHandle->Allocate();
199
200 CopyDataToITensorHandle(inputHandle.get(), inputVector.data());
201 CopyDataToITensorHandle(outputStateInHandle.get(), outputStateInVector.data());
202 CopyDataToITensorHandle(cellStateInHandle.get(), cellStateInVector.data());
203
204 workload->Execute();
205
Mike Kelly12994962022-04-21 11:57:09 +0100206 CopyDataFromITensorHandle(actualOutputStateOut.data(), outputStateOutHandle.get());
207 CopyDataFromITensorHandle(actualCellStateOut.data(), cellStateOutHandle.get());
Cathal Corbettfd5bec42022-03-03 15:13:23 +0000208 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
209
210 return LayerTestResult<T, 3>(actualOutput,
211 outputVector,
212 outputHandle->GetShape(),
213 outputTensorInfo.GetShape());
214}
215
216template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100217LayerTestResult<T, 3> UnidirectionalSequenceLstmLayerFloat32TestImpl(
218 armnn::IWorkloadFactory& workloadFactory,
219 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
220 const armnn::ITensorHandleFactory& tensorHandleFactory,
221 const std::vector<T>& input,
222 const std::vector<T>& outputExpected,
223 const armnn::TensorShape& inputShape,
224 const armnn::TensorShape& outputExpectedShape,
Teresa Charlinacb3ec52023-04-03 19:57:00 +0100225 float qScale = 1.0f,
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100226 int32_t qOffset = 0,
Narumol Prangnawarat5f941242023-08-11 16:09:26 +0100227 armnn::DataType constantDataType = armnn::DataType::Float32)
228{
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100229 IgnoreUnused(memoryManager);
230 unsigned int batchSize = armnn::numeric_cast<unsigned int>(inputShape[0]);
231 unsigned int timeSize = armnn::numeric_cast<unsigned int>(inputShape[1]);
232 unsigned int inputSize = armnn::numeric_cast<unsigned int>(inputShape[2]);
233 unsigned int outputSize = armnn::numeric_cast<unsigned int>(outputExpectedShape[2]);
234 unsigned numUnits = outputSize;
235
236 armnn::TensorInfo inputTensorInfo({batchSize, timeSize, inputSize}, ArmnnType, qScale, qOffset);
237 armnn::TensorInfo cellStateInTensorInfo({batchSize, numUnits}, ArmnnType, qScale, qOffset);
238 armnn::TensorInfo outputStateInTensorInfo({batchSize, outputSize}, ArmnnType, qScale, qOffset);
Mike Kelly12994962022-04-21 11:57:09 +0100239 armnn::TensorInfo outputStateOutTensorInfo({batchSize, timeSize, outputSize}, ArmnnType, qScale, qOffset);
240 armnn::TensorInfo cellStateOutTensorInfo({batchSize, timeSize, outputSize}, ArmnnType, qScale, qOffset);
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100241 armnn::TensorInfo outputTensorInfo({batchSize, timeSize, outputSize}, ArmnnType, qScale, qOffset);
242
243 std::vector<T> inputVector;
244 inputVector.assign(input.data(), input.data() + (batchSize * timeSize * inputSize));
245
246 std::vector<T> cellStateInVector(batchSize * numUnits, T());
247 std::vector<T> outputStateInVector(batchSize * outputSize, T());
248
Mike Kelly12994962022-04-21 11:57:09 +0100249 std::vector<T> actualOutputStateOut(outputStateOutTensorInfo.GetNumElements());
250 std::vector<T> actualCellStateOut(cellStateOutTensorInfo.GetNumElements());
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100251 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
252
253 std::vector<T> outputVector;
254 outputVector.assign(outputExpected.data(), outputExpected.data() + (batchSize * timeSize * outputSize));
255
256 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
257 std::unique_ptr<armnn::ITensorHandle> cellStateInHandle =
258 tensorHandleFactory.CreateTensorHandle(cellStateInTensorInfo);
259 std::unique_ptr<armnn::ITensorHandle> outputStateInHandle =
260 tensorHandleFactory.CreateTensorHandle(outputStateInTensorInfo);
261
Mike Kelly12994962022-04-21 11:57:09 +0100262 std::unique_ptr<armnn::ITensorHandle> outputStateOutHandle =
263 tensorHandleFactory.CreateTensorHandle(outputStateOutTensorInfo);
264 std::unique_ptr<armnn::ITensorHandle> cellStateOutHandle =
265 tensorHandleFactory.CreateTensorHandle(cellStateOutTensorInfo);
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100266 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
267
268 armnn::UnidirectionalSequenceLstmQueueDescriptor data;
269 armnn::WorkloadInfo info;
270
271 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
272 AddInputToWorkload(data, info, outputStateInTensorInfo, outputStateInHandle.get());
273 AddInputToWorkload(data, info, cellStateInTensorInfo, cellStateInHandle.get());
274
Mike Kelly12994962022-04-21 11:57:09 +0100275 AddOutputToWorkload(data, info, outputStateOutTensorInfo, outputStateOutHandle.get());
276 AddOutputToWorkload(data, info, cellStateOutTensorInfo, cellStateOutHandle.get());
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100277 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
278
279 armnn::TensorInfo tensorInfo4({numUnits}, constantDataType, qScale, qOffset);
280 armnn::TensorInfo tensorInfo12({numUnits, 3}, constantDataType, qScale, qOffset);
281 armnn::TensorInfo tensorInfo16({numUnits, 4}, constantDataType, qScale, qOffset);
282
283 std::vector<float> inputToInputWeights = { -0.49536117f, -0.0556083915f, -0.102400711f,
284 -0.117484632f, 0.3298470976f, -0.1179017122f,
285 0.214305695f, 0.42135173085f, 0.003878414626f,
286 -0.348303917f, -0.1881275477f, 0.0343011027f };
287
288 std::vector<float> inputToForgetWeights = { 0.2415594226f, 0.15400093799f, 0.4566498398f,
289 -0.3810434485f, 0.268383264f, -0.009807467424f,
290 -0.3522925403f, -0.24275735512f, -0.28344226125f,
291 0.13512269116f, -0.4932442977f, -0.10039821991f };
292
293 std::vector<float> inputToCellWeights = { -0.2504855627f, 0.184490025045f, -0.2480507493f,
294 0.386399507f, -0.259465157985f, -0.16545993089f,
295 -0.4230232555f, 0.341664791103f, -0.18127849691f,
296 -0.2277662414f, -0.55275535589f, 0.34184026718f };
297
298 std::vector<float> inputToOutputWeights = { 0.2303854227f, 0.5218806862f, -0.4865379333f,
299 0.53969591851f, 0.23393625035f, -0.27140527306f,
300 0.50009280443f, 0.07511717046f, 0.3998299249f,
301 -0.51717478049f, 0.1889653282f, -0.367323637f };
302
303 std::vector<float> recurrentToInputWeights = { -0.128009796112f, 0.1995525098f, -0.07745539397f, 0.1558421701f,
304 -0.265254765766f, -0.38837709614f, -0.05636804124f, 0.4259087456f,
305 0.17628988623f, 0.3877420127f, 0.53300309181f, -0.0959980934f,
306 0.00302857416f, 0.3266998827f, -0.142509296562f, -0.04433270756f };
307
308 std::vector<float> recurrentToForgetWeights = { -0.09499983487f, -0.08814888417f, -0.04834804721f, 0.1516668247f,
309 -0.3967529535f, -0.06463699788f, 0.4952811002f, 0.003274492938f,
310 -0.0968840941f, 0.17928104102f, 0.0031281141592f, -0.3387276584f,
311 -0.3587934076f, 0.06705895066f, 0.22463923692f, 0.1961955726f };
312
313 std::vector<float> recurrentToCellWeights = { -0.21938985582f, -0.3023648226f, -0.1170005202f, -0.3509177422f,
314 -0.4286288613f, 0.2726137042f, 0.09216640889f, -0.06551410215f,
315 0.20453298098f, 0.2393476665f, 0.11846517771f, 0.2630801796f,
316 0.3954237699f, -0.19407111404f, 0.30412107706f, -0.27342408554f };
317
318 std::vector<float> recurrentToOutputWeights = { -0.32921677827f, 0.32624614238f, -0.1388191282f, -0.17879831790f,
319 -0.15185534954f, -0.16918526583f, -0.10087361183f, -0.5436913968f,
320 0.016758225858f, 0.30454617738f, -0.41493862867f, -0.005565764375f,
321 -0.12584099173f, -0.12319286912f, 0.2407919466f, -0.08879069983f };
322
323 std::vector<float> inputGateBias = { 0., 0., 0., 0. };
324
325 std::vector<float> forgetGateBias = { 1., 1., 1., 1. };
326
327 std::vector<float> cellBias = { 0., 0., 0., 0. };
328
329 std::vector<float> outputGateBias = { 0., 0., 0., 0. };
330
331 armnn::ScopedTensorHandle inputToInputWeightsTensor(tensorInfo12);
332 armnn::ScopedTensorHandle inputToForgetWeightsTensor(tensorInfo12);
333 armnn::ScopedTensorHandle inputToCellWeightsTensor(tensorInfo12);
334 armnn::ScopedTensorHandle inputToOutputWeightsTensor(tensorInfo12);
335 armnn::ScopedTensorHandle recurrentToInputWeightsTensor(tensorInfo16);
336 armnn::ScopedTensorHandle recurrentToForgetWeightsTensor(tensorInfo16);
337 armnn::ScopedTensorHandle recurrentToCellWeightsTensor(tensorInfo16);
338 armnn::ScopedTensorHandle recurrentToOutputWeightsTensor(tensorInfo16);
339 armnn::ScopedTensorHandle inputGateBiasTensor(tensorInfo4);
340 armnn::ScopedTensorHandle forgetGateBiasTensor(tensorInfo4);
341 armnn::ScopedTensorHandle cellBiasTensor(tensorInfo4);
342 armnn::ScopedTensorHandle outputGateBiasTensor(tensorInfo4);
343
344 AllocateAndCopyDataToITensorHandle(&inputToInputWeightsTensor, inputToInputWeights.data());
345 AllocateAndCopyDataToITensorHandle(&inputToForgetWeightsTensor, inputToForgetWeights.data());
346 AllocateAndCopyDataToITensorHandle(&inputToCellWeightsTensor, inputToCellWeights.data());
347 AllocateAndCopyDataToITensorHandle(&inputToOutputWeightsTensor, inputToOutputWeights.data());
348 AllocateAndCopyDataToITensorHandle(&recurrentToInputWeightsTensor, recurrentToInputWeights.data());
349 AllocateAndCopyDataToITensorHandle(&recurrentToForgetWeightsTensor, recurrentToForgetWeights.data());
350 AllocateAndCopyDataToITensorHandle(&recurrentToCellWeightsTensor, recurrentToCellWeights.data());
351 AllocateAndCopyDataToITensorHandle(&recurrentToOutputWeightsTensor, recurrentToOutputWeights.data());
352 AllocateAndCopyDataToITensorHandle(&inputGateBiasTensor, inputGateBias.data());
353 AllocateAndCopyDataToITensorHandle(&forgetGateBiasTensor, forgetGateBias.data());
354 AllocateAndCopyDataToITensorHandle(&cellBiasTensor, cellBias.data());
355 AllocateAndCopyDataToITensorHandle(&outputGateBiasTensor, outputGateBias.data());
356
357 data.m_InputToInputWeights = &inputToInputWeightsTensor;
358 data.m_InputToForgetWeights = &inputToForgetWeightsTensor;
359 data.m_InputToCellWeights = &inputToCellWeightsTensor;
360 data.m_InputToOutputWeights = &inputToOutputWeightsTensor;
361 data.m_RecurrentToInputWeights = &recurrentToInputWeightsTensor;
362 data.m_RecurrentToForgetWeights = &recurrentToForgetWeightsTensor;
363 data.m_RecurrentToCellWeights = &recurrentToCellWeightsTensor;
364 data.m_RecurrentToOutputWeights = &recurrentToOutputWeightsTensor;
365 data.m_InputGateBias = &inputGateBiasTensor;
366 data.m_ForgetGateBias = &forgetGateBiasTensor;
367 data.m_CellBias = &cellBiasTensor;
368 data.m_OutputGateBias = &outputGateBiasTensor;
369
370 // Flags to set test configuration
371 data.m_Parameters.m_ClippingThresCell = 10;
372 data.m_Parameters.m_ClippingThresProj = 0;
373 data.m_Parameters.m_ActivationFunc = 4;
374 data.m_Parameters.m_CifgEnabled = false;
375 data.m_Parameters.m_PeepholeEnabled = false;
376 data.m_Parameters.m_ProjectionEnabled = false;
377 data.m_Parameters.m_TimeMajor = false;
378
Teresa Charlin611c7fb2022-01-07 09:47:29 +0000379 std::unique_ptr<armnn::IWorkload> workload
380 = workloadFactory.CreateWorkload(armnn::LayerType::UnidirectionalSequenceLstm, data, info);
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100381 inputHandle->Allocate();
382 outputStateInHandle->Allocate();
383 cellStateInHandle->Allocate();
384
Mike Kelly12994962022-04-21 11:57:09 +0100385 outputStateOutHandle->Allocate();
386 cellStateOutHandle->Allocate();
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100387 outputHandle->Allocate();
388
389 CopyDataToITensorHandle(inputHandle.get(), inputVector.data());
390 CopyDataToITensorHandle(outputStateInHandle.get(), outputStateInVector.data());
391 CopyDataToITensorHandle(cellStateInHandle.get(), cellStateInVector.data());
392
393 workload->Execute();
394
Mike Kelly12994962022-04-21 11:57:09 +0100395 CopyDataFromITensorHandle(actualOutputStateOut.data(), outputStateOutHandle.get());
396 CopyDataFromITensorHandle(actualCellStateOut.data(), cellStateOutHandle.get());
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100397 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
398
399 return LayerTestResult<T, 3>(actualOutput,
400 outputVector,
401 outputHandle->GetShape(),
402 outputTensorInfo.GetShape());
403}
404
405template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
406LayerTestResult<T, 3>
407UnidirectionalSequenceLstmLayerFloat32TimeMajorTestImpl(
408 armnn::IWorkloadFactory& workloadFactory,
409 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
410 const armnn::ITensorHandleFactory& tensorHandleFactory,
411 const std::vector<T>& input,
412 const std::vector<T>& outputExpected,
413 const armnn::TensorShape& inputShape,
414 const armnn::TensorShape& outputExpectedShape,
Teresa Charlinacb3ec52023-04-03 19:57:00 +0100415 float qScale = 1.0f,
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100416 int32_t qOffset = 0,
Narumol Prangnawarat5f941242023-08-11 16:09:26 +0100417 armnn::DataType constantDataType = armnn::DataType::Float32)
418{
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100419 IgnoreUnused(memoryManager);
420 unsigned int batchSize = armnn::numeric_cast<unsigned int>(inputShape[1]);
421 unsigned int timeSize = armnn::numeric_cast<unsigned int>(inputShape[0]);
422 unsigned int inputSize = armnn::numeric_cast<unsigned int>(inputShape[2]);
423 unsigned int outputSize = armnn::numeric_cast<unsigned int>(outputExpectedShape[2]);
424 unsigned numUnits = outputSize;
425
426 armnn::TensorInfo inputTensorInfo({timeSize, batchSize, inputSize}, ArmnnType, qScale, qOffset);
427 armnn::TensorInfo cellStateInTensorInfo({batchSize, numUnits}, ArmnnType, qScale, qOffset);
428 armnn::TensorInfo outputStateInTensorInfo({batchSize, outputSize}, ArmnnType, qScale, qOffset);
Mike Kelly12994962022-04-21 11:57:09 +0100429 armnn::TensorInfo outputStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
430 armnn::TensorInfo cellStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100431 armnn::TensorInfo outputTensorInfo({timeSize, batchSize, outputSize}, ArmnnType, qScale, qOffset);
432
433 std::vector<T> inputVector;
434 inputVector.assign(input.data(), input.data() + (batchSize * timeSize * inputSize));
435
436 std::vector<T> cellStateInVector(batchSize * numUnits, T());
437 std::vector<T> outputStateInVector(batchSize * outputSize, T());
438
Mike Kelly12994962022-04-21 11:57:09 +0100439 std::vector<T> actualOutputStateOut(outputStateOutTensorInfo.GetNumElements());
440 std::vector<T> actualCellStateOut(cellStateOutTensorInfo.GetNumElements());
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100441 std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
442
443 std::vector<T> outputVector;
444 outputVector.assign(outputExpected.data(), outputExpected.data() + (batchSize * timeSize * outputSize));
445
446 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
447 std::unique_ptr<armnn::ITensorHandle> cellStateInHandle =
448 tensorHandleFactory.CreateTensorHandle(cellStateInTensorInfo);
449 std::unique_ptr<armnn::ITensorHandle> outputStateInHandle =
450 tensorHandleFactory.CreateTensorHandle(outputStateInTensorInfo);
451
Mike Kelly12994962022-04-21 11:57:09 +0100452 std::unique_ptr<armnn::ITensorHandle> outputStateOutHandle =
453 tensorHandleFactory.CreateTensorHandle(outputStateOutTensorInfo);
454 std::unique_ptr<armnn::ITensorHandle> cellStateOutHandle =
455 tensorHandleFactory.CreateTensorHandle(cellStateOutTensorInfo);
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100456 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
457
458 armnn::UnidirectionalSequenceLstmQueueDescriptor data;
459 armnn::WorkloadInfo info;
460
461 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
462 AddInputToWorkload(data, info, outputStateInTensorInfo, outputStateInHandle.get());
463 AddInputToWorkload(data, info, cellStateInTensorInfo, cellStateInHandle.get());
464
Mike Kelly12994962022-04-21 11:57:09 +0100465 AddOutputToWorkload(data, info, outputStateOutTensorInfo, outputStateOutHandle.get());
466 AddOutputToWorkload(data, info, cellStateOutTensorInfo, cellStateOutHandle.get());
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100467 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
468
469 armnn::TensorInfo tensorInfo4({numUnits}, constantDataType, qScale, qOffset);
470 armnn::TensorInfo tensorInfo12({numUnits, 3}, constantDataType, qScale, qOffset);
471 armnn::TensorInfo tensorInfo16({numUnits, 4}, constantDataType, qScale, qOffset);
472
473 std::vector<float> inputToInputWeights = { 0.27277296781539917f, 0.3813590407371521f, -0.394489049911499f,
474 0.2782636880874634f, -0.3793870210647583f, -0.018918335437774658f,
475 0.2724653482437134f, -0.19314253330230713f, -0.2947450876235962f,
476 -0.30253493785858154f, 0.4241350293159485f, -0.22560018301010132f };
477
478 std::vector<float> inputToForgetWeights = { -0.2667974531650543f, -0.05505800247192383f, -0.20932340621948242f,
479 -0.14345619082450867f, 0.09666192531585693f, -0.2604355812072754f,
480 -0.2681812047958374f, -0.3314584493637085f, 0.4485899806022644f,
481 -0.23467743396759033f, 0.5072842240333557f, -0.4192768931388855f };
482
483 std::vector<float> inputToCellWeights = { -0.15782442688941956f, -0.027530014514923096f, 0.4789854884147644f,
484 0.23227906227111816f, 0.28259342908859253f, -0.030095696449279785f,
485 0.10071521997451782f, -0.08535495400428772f, 0.18563997745513916f,
486 -0.3049069046974182f, -0.478048175573349f, 0.025234103202819824f };
487
488 std::vector<float> inputToOutputWeights = { -0.04584759473800659f, -0.2716066539287567f, 0.012970447540283203f,
489 -0.4729190170764923f, -0.37422770261764526f, 0.49352723360061646f,
490 0.3163864016532898f, -0.436781644821167f, -0.33074596524238586f,
491 -0.32885751128196716f, -0.40959352254867554f, -0.2124689817428589f };
492
493 std::vector<float> recurrentToInputWeights = { 0.23788475990f, -0.24948765337f, 0.50044941902f, 0.14431896805f,
494 -0.115940228137f, -0.717082679f, -0.17208620906f, 0.17850610617f,
495 -0.16702319684f, -0.11384502053f, -0.309785276245f, -0.3316611672f,
496 0.52380162477f, -0.06839632987f, -0.391478359627f, -0.10756178963f };
497
498 std::vector<float> recurrentToForgetWeights = { 0.11383482068f, 0.1676601767f, -0.08550968004f, 0.03399394089f,
499 0.08042152225f, -0.2133381964f, 0.05182432704f, 0.38161808255f,
500 -0.5018365979f, -0.08043262364f, 0.07894329014f, -0.07547105155f,
501 0.12047368288f, 0.2986997961f, 0.0485043078f, -0.13372567296f };
502
503 std::vector<float> recurrentToCellWeights = { 0.0433832928545f, 0.07587072294f, -0.120520234107f, 0.604576051f,
504 -0.434353142986f, 0.009314475068f, 0.005085289478f, 0.08488202038f,
505 -0.00025437487886f, 0.15245915082f, -0.1936587542f, 0.004754020f,
506 -0.1582719236f, 0.3307867646f, 0.0236605107784f, 0.307716339826f };
507
508 std::vector<float> recurrentToOutputWeights = { -0.079031050201f, 0.041414566286f, -0.583727357285f, 0.1025384515f,
509 -0.172372072937f, 0.09214124082f, 0.178184121827f, -0.2439443916f,
510 0.104485116899f, 0.2600405514f, 0.064414866268f, 0.24141204357f,
511 0.281875759363f, -0.14234502664f, 0.15126448862f, -0.24421440064f };
512
513 std::vector<float> inputGateBias = { 0., 0., 0., 0. };
514
515 std::vector<float> forgetGateBias = { 1., 1., 1., 1. };
516
517 std::vector<float> cellBias = { 0., 0., 0., 0. };
518
519 std::vector<float> outputGateBias = { 0., 0., 0., 0. };
520
521 armnn::ScopedTensorHandle inputToInputWeightsTensor(tensorInfo12);
522 armnn::ScopedTensorHandle inputToForgetWeightsTensor(tensorInfo12);
523 armnn::ScopedTensorHandle inputToCellWeightsTensor(tensorInfo12);
524 armnn::ScopedTensorHandle inputToOutputWeightsTensor(tensorInfo12);
525 armnn::ScopedTensorHandle recurrentToInputWeightsTensor(tensorInfo16);
526 armnn::ScopedTensorHandle recurrentToForgetWeightsTensor(tensorInfo16);
527 armnn::ScopedTensorHandle recurrentToCellWeightsTensor(tensorInfo16);
528 armnn::ScopedTensorHandle recurrentToOutputWeightsTensor(tensorInfo16);
529 armnn::ScopedTensorHandle inputGateBiasTensor(tensorInfo4);
530 armnn::ScopedTensorHandle forgetGateBiasTensor(tensorInfo4);
531 armnn::ScopedTensorHandle cellBiasTensor(tensorInfo4);
532 armnn::ScopedTensorHandle outputGateBiasTensor(tensorInfo4);
533
534 AllocateAndCopyDataToITensorHandle(&inputToInputWeightsTensor, inputToInputWeights.data());
535 AllocateAndCopyDataToITensorHandle(&inputToForgetWeightsTensor, inputToForgetWeights.data());
536 AllocateAndCopyDataToITensorHandle(&inputToCellWeightsTensor, inputToCellWeights.data());
537 AllocateAndCopyDataToITensorHandle(&inputToOutputWeightsTensor, inputToOutputWeights.data());
538 AllocateAndCopyDataToITensorHandle(&recurrentToInputWeightsTensor, recurrentToInputWeights.data());
539 AllocateAndCopyDataToITensorHandle(&recurrentToForgetWeightsTensor, recurrentToForgetWeights.data());
540 AllocateAndCopyDataToITensorHandle(&recurrentToCellWeightsTensor, recurrentToCellWeights.data());
541 AllocateAndCopyDataToITensorHandle(&recurrentToOutputWeightsTensor, recurrentToOutputWeights.data());
542 AllocateAndCopyDataToITensorHandle(&inputGateBiasTensor, inputGateBias.data());
543 AllocateAndCopyDataToITensorHandle(&forgetGateBiasTensor, forgetGateBias.data());
544 AllocateAndCopyDataToITensorHandle(&cellBiasTensor, cellBias.data());
545 AllocateAndCopyDataToITensorHandle(&outputGateBiasTensor, outputGateBias.data());
546
547 data.m_InputToInputWeights = &inputToInputWeightsTensor;
548 data.m_InputToForgetWeights = &inputToForgetWeightsTensor;
549 data.m_InputToCellWeights = &inputToCellWeightsTensor;
550 data.m_InputToOutputWeights = &inputToOutputWeightsTensor;
551 data.m_RecurrentToInputWeights = &recurrentToInputWeightsTensor;
552 data.m_RecurrentToForgetWeights = &recurrentToForgetWeightsTensor;
553 data.m_RecurrentToCellWeights = &recurrentToCellWeightsTensor;
554 data.m_RecurrentToOutputWeights = &recurrentToOutputWeightsTensor;
555 data.m_InputGateBias = &inputGateBiasTensor;
556 data.m_ForgetGateBias = &forgetGateBiasTensor;
557 data.m_CellBias = &cellBiasTensor;
558 data.m_OutputGateBias = &outputGateBiasTensor;
559
560 // Flags to set test configuration
561 data.m_Parameters.m_ClippingThresCell = 10;
562 data.m_Parameters.m_ClippingThresProj = 0;
563 data.m_Parameters.m_ActivationFunc = 4;
564 data.m_Parameters.m_CifgEnabled = false;
565 data.m_Parameters.m_PeepholeEnabled = false;
566 data.m_Parameters.m_ProjectionEnabled = false;
567 data.m_Parameters.m_TimeMajor = true;
568
Teresa Charlin611c7fb2022-01-07 09:47:29 +0000569 std::unique_ptr<armnn::IWorkload> workload
570 = workloadFactory.CreateWorkload(armnn::LayerType::UnidirectionalSequenceLstm, data, info);
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100571 inputHandle->Allocate();
572 outputStateInHandle->Allocate();
573 cellStateInHandle->Allocate();
574
Mike Kelly12994962022-04-21 11:57:09 +0100575 outputStateOutHandle->Allocate();
576 cellStateOutHandle->Allocate();
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100577 outputHandle->Allocate();
578
579 CopyDataToITensorHandle(inputHandle.get(), inputVector.data());
580 CopyDataToITensorHandle(outputStateInHandle.get(), outputStateInVector.data());
581 CopyDataToITensorHandle(cellStateInHandle.get(), cellStateInVector.data());
582
583 workload->Execute();
584
Mike Kelly12994962022-04-21 11:57:09 +0100585 CopyDataFromITensorHandle(actualOutputStateOut.data(), outputStateOutHandle.get());
586 CopyDataFromITensorHandle(actualCellStateOut.data(), cellStateOutHandle.get());
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100587 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
588
589 return LayerTestResult<T, 3>(actualOutput,
590 outputVector,
591 outputHandle->GetShape(),
592 outputTensorInfo.GetShape());
593}
594
595} // anonymous namespace
596
Cathal Corbettfd5bec42022-03-03 15:13:23 +0000597LayerTestResult<float, 3> UnidirectionalSequenceLstmLayerFloat32TimeMajorSingleBatchTest(
598 armnn::IWorkloadFactory& workloadFactory,
599 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
600 const armnn::ITensorHandleFactory& tensorHandleFactory)
601{
602 armnn::TensorInfo inputDesc({1, 2, 2}, armnn::DataType::Float32);
603 std::vector<float> input = {2., 3., 3., 4.};
604
605 armnn::TensorInfo outputDesc({1, 2, 4}, armnn::DataType::Float32);
606 std::vector<float> expectedOutput =
607 {-0.02973187f, 0.1229473f, 0.20885126f, -0.15358765f,
608 -0.0185422f, 0.11281417f, 0.24466537f, -0.1826292f};
609
610 return UnidirectionalSequenceLstmTimeMajorSingleBatchTestImpl<armnn::DataType::Float32>(
611 workloadFactory, memoryManager, tensorHandleFactory,
612 input, expectedOutput, inputDesc.GetShape(), outputDesc.GetShape());
613}
614
615LayerTestResult<float, 3> UnidirectionalSequenceLstmLayerFloat32BatchMajorSingleBatchTest(
616 armnn::IWorkloadFactory& workloadFactory,
617 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Narumol Prangnawarat5f941242023-08-11 16:09:26 +0100618 const armnn::ITensorHandleFactory& tensorHandleFactory)
619{
Cathal Corbettfd5bec42022-03-03 15:13:23 +0000620 armnn::TensorInfo inputInfo({3, 1, 3}, armnn::DataType::Float32);
621 std::vector<float> input = { 1., 2., 3., 4., 5., 4., 3., 2., 1. };
622
623 armnn::TensorInfo outputInfo({3, 1, 4}, armnn::DataType::Float32);
624 std::vector<float> expectedOutput = { -0.0714901f, -0.162117f, -0.175168f, -0.0232934f,
625 -0.0424661f, -0.231802f, -0.513374f, -0.00680323f,
626 -0.0668735f, 0.204078f, -0.42765f, -0.0312321f };
627 return UnidirectionalSequenceLstmLayerFloat32TestImpl<armnn::DataType::Float32>(
628 workloadFactory, memoryManager, tensorHandleFactory,
629 input, expectedOutput, inputInfo.GetShape(), outputInfo.GetShape());
630}
631
Narumol Prangnawarat5f941242023-08-11 16:09:26 +0100632LayerTestResult<float, 3> UnidirectionalSequenceLstmLayerFloat32TimeMajorSingleTimeTest(
633 armnn::IWorkloadFactory& workloadFactory,
634 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
635 const armnn::ITensorHandleFactory& tensorHandleFactory)
636{
637 armnn::TensorInfo inputInfo({ 1, 3, 3 }, armnn::DataType::Float32);
638 std::vector<float> input = { 1., 2., 3.,
639 4., 5., 6.,
640 7., 8., 9. };
641
642 armnn::TensorInfo outputInfo({ 1, 3, 4 }, armnn::DataType::Float32);
643 std::vector<float> expectedOutput =
644 { 0.13565768f, 0.12467254f, 0.02120903f, -0.05302038f,
645 0.1053334f, 0.08508634f, 0.00667238f, -0.00356043f,
646 0.05638668f, 0.02924093f, 0.00119751f, -0.00017249f };
647
648 return UnidirectionalSequenceLstmLayerFloat32TimeMajorTestImpl<armnn::DataType::Float32>(
649 workloadFactory, memoryManager, tensorHandleFactory,
650 input, expectedOutput, inputInfo.GetShape(), outputInfo.GetShape());
651}
652
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100653LayerTestResult<float, 3> UnidirectionalSequenceLstmLayerFloat32Test(
654 armnn::IWorkloadFactory& workloadFactory,
655 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Narumol Prangnawarat5f941242023-08-11 16:09:26 +0100656 const armnn::ITensorHandleFactory& tensorHandleFactory)
657{
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100658 armnn::TensorInfo inputInfo({3, 2, 3}, armnn::DataType::Float32);
659 std::vector<float> input = { 1., 2., 3., 4., 5., 4.,
660 3., 2., 1., 2., 3., 4.,
661 5., 4., 3., 2., 1., 2. };
662
663 armnn::TensorInfo outputInfo({3, 2, 4}, armnn::DataType::Float32);
664 std::vector<float> expectedOutput = { -0.07149004f, -0.1621171f, -0.17516759f, -0.0232934225f,
665 -0.16810727f, -0.41412935f, -0.5498753f, -0.00803578f,
666 -0.06687349f, 0.204077631f, -0.4276504f, -0.03123213f,
667 -0.12000261f, -0.0941918f, -0.45639035f, -0.02870186f,
668 -0.03429216f, 0.20824050f, -0.6569892f, -0.004152651f,
669 -0.10493034f, 0.14210969f, -0.58347696f, -0.03297536f };
670 return UnidirectionalSequenceLstmLayerFloat32TestImpl<armnn::DataType::Float32>(
671 workloadFactory, memoryManager, tensorHandleFactory,
672 input, expectedOutput, inputInfo.GetShape(), outputInfo.GetShape());
673}
674
675LayerTestResult<float, 3> UnidirectionalSequenceLstmLayerFloat32TimeMajorTest(
676 armnn::IWorkloadFactory& workloadFactory,
677 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
Narumol Prangnawarat5f941242023-08-11 16:09:26 +0100678 const armnn::ITensorHandleFactory& tensorHandleFactory)
679{
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100680 armnn::TensorInfo inputInfo({2, 3, 3}, armnn::DataType::Float32);
681 std::vector<float> input = { 1., 2., 3., 4., 5., 4.,
682 3., 2., 1., 2., 3., 4.,
683 5., 4., 3., 2., 1., 2. };
684
685 armnn::TensorInfo outputInfo({2, 3, 4}, armnn::DataType::Float32);
686 std::vector<float> expectedOutput = { 0.135657698f, 0.124672532f, 0.0212090332f, -0.0530203655f,
687 0.106138252f, 0.0404792242f, 0.0151643595f, -0.00675163185f,
688 -0.0128514022f, 0.0644884035f, 0.0709072053f, -0.0454045124f,
689 0.16288602f, 0.16649379f, 0.02770456f, -0.03698075f,
690 0.11171641f, 0.043119f , 0.0762981f , -0.01228541f,
691 0.10439701f, 0.21439962f, 0.11919238f, -0.08390583f };
692 return UnidirectionalSequenceLstmLayerFloat32TimeMajorTestImpl<armnn::DataType::Float32>(
693 workloadFactory, memoryManager, tensorHandleFactory,
694 input, expectedOutput, inputInfo.GetShape(), outputInfo.GetShape());
695}
696
697LayerTestResult<float, 3> UnidirectionalSequenceLstmLayerNoCifgWithPeepholeWithProjectionTest(
698 armnn::IWorkloadFactory& workloadFactory,
699 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
700 const armnn::ITensorHandleFactory& tensorHandleFactory)
701{
702 IgnoreUnused(memoryManager);
703 unsigned int batchSize = 2;
704 unsigned int timeSize = 3;
705 unsigned int outputSize = 5;
706 unsigned int inputSize = 4;
707 unsigned numUnits = 6;
708
709 armnn::TensorInfo inputTensorInfo({batchSize, timeSize, inputSize}, armnn::DataType::Float32);
710 armnn::TensorInfo cellStateInTensorInfo({batchSize , numUnits}, armnn::DataType::Float32);
711 armnn::TensorInfo outputStateInTensorInfo({batchSize , outputSize}, armnn::DataType::Float32);
Mike Kelly12994962022-04-21 11:57:09 +0100712 armnn::TensorInfo outputStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
713 armnn::TensorInfo cellStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100714 armnn::TensorInfo outputTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
715
716 const std::vector<float> inputVector = { 1., 2., 3., 4., 5., 4.,
717 3., 2., 1., 2., 3., 4.,
718 5., 4., 3., 2., 1., 2.,
719 1., 2., 3., 4., 5., 4.};
720
721 std::vector<float> cellStateInVector(batchSize * numUnits, 0.f);
722 std::vector<float> outputStateInVector(batchSize * outputSize, 0.f);
723
Mike Kelly12994962022-04-21 11:57:09 +0100724 std::vector<float> actualOutputStateOut(outputStateOutTensorInfo.GetNumElements());
725 std::vector<float> actualCellStateOut(cellStateOutTensorInfo.GetNumElements());
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100726 std::vector<float> actualOutput(outputTensorInfo.GetNumElements());
727
728 const std::vector<float> expectedOutput = { -0.0135612f, -0.0263441f, 0.0314008f, -0.00883455f, 0.00763052f,
729 -0.00126877f, -0.0292959f, 0.0449957f, -0.00976195f, -0.00492338f,
730 -0.0175702f, -0.0431753f, 0.0597117f, -0.0169154f, 0.0142087f,
731 0.00472515f, -0.0196355f, 0.0342524f, -0.00407936f, -0.0253189f,
732 -0.00512944f, -0.0293754f, 0.0512771f, -0.0151874f, -0.0246433f,
733 -0.00744986f, -0.0345103f, 0.0450666f, -0.00944991f, 0.0127171f };
734
735 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
736 std::unique_ptr<armnn::ITensorHandle> cellStateInHandle =
737 tensorHandleFactory.CreateTensorHandle(cellStateInTensorInfo);
738 std::unique_ptr<armnn::ITensorHandle> outputStateInHandle =
739 tensorHandleFactory.CreateTensorHandle(outputStateInTensorInfo);
Mike Kelly12994962022-04-21 11:57:09 +0100740
741 std::unique_ptr<armnn::ITensorHandle> outputStateOutHandle =
742 tensorHandleFactory.CreateTensorHandle(outputStateOutTensorInfo);
743 std::unique_ptr<armnn::ITensorHandle> cellStateOutHandle =
744 tensorHandleFactory.CreateTensorHandle(cellStateOutTensorInfo);
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100745 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
746
747 armnn::UnidirectionalSequenceLstmQueueDescriptor data;
748 armnn::WorkloadInfo info;
749
750 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
751 AddInputToWorkload(data, info, outputStateInTensorInfo, outputStateInHandle.get());
752 AddInputToWorkload(data, info, cellStateInTensorInfo, cellStateInHandle.get());
Mike Kelly12994962022-04-21 11:57:09 +0100753
754 AddOutputToWorkload(data, info, outputStateOutTensorInfo, outputStateOutHandle.get());
755 AddOutputToWorkload(data, info, cellStateOutTensorInfo, cellStateOutHandle.get());
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100756 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
757
758 armnn::TensorInfo tensorInfo5({outputSize}, armnn::DataType::Float32);
759 armnn::TensorInfo tensorInfo6({numUnits}, armnn::DataType::Float32);
760 armnn::TensorInfo tensorInfo6x4({numUnits, inputSize}, armnn::DataType::Float32);
761 armnn::TensorInfo tensorInfo6x5({numUnits, outputSize}, armnn::DataType::Float32);
762 armnn::TensorInfo tensorInfo5x6({outputSize, numUnits}, armnn::DataType::Float32);
763
764 std::vector<float> inputToInputWeights = { 0.021393683f, 0.06124551f, 0.046905167f, -0.014657677f,
765 -0.03149463f, 0.09171803f, 0.14647801f, 0.10797193f,
766 -0.0057968358f, 0.0019193048f, -0.2726754f, 0.10154029f,
767 -0.018539885f, 0.080349885f, -0.10262385f, -0.022599787f,
768 -0.09121155f, -0.008675967f, -0.045206103f, -0.0821282f,
769 -0.008045952f, 0.015478081f, 0.055217247f, 0.038719587f };
770
771 std::vector<float> inputToForgetWeights = { -0.0018401089f, -0.004852237f, 0.03698424f, 0.014181704f,
772 0.028273236f, -0.016726194f, -0.05249759f, -0.10204261f,
773 0.00861066f, -0.040979505f, -0.009899187f, 0.01923892f,
774 -0.028177269f, -0.08535103f, -0.14585495f, 0.10662567f,
775 -0.01909731f, -0.017883534f, -0.0047269356f, -0.045103323f,
776 0.0030784295f, 0.076784775f, 0.07463696f, 0.094531395f};
777
778 std::vector<float> inputToCellWeights = { -0.04580283f, -0.09549462f, -0.032418985f, -0.06454633f,
779 -0.043528453f, 0.043018587f, -0.049152344f, -0.12418144f,
780 -0.078985475f, -0.07596889f, 0.019484362f, -0.11434962f,
781 -0.0074034138f, -0.06314844f, -0.092981495f, 0.0062155537f,
782 -0.025034338f, -0.0028890965f, 0.048929527f, 0.06235075f,
783 0.10665918f, -0.032036792f, -0.08505916f, -0.10843358f };
784
785 std::vector<float> inputToOutputWeights = { -0.0998932f, -0.07201956f, -0.052803773f, -0.15629593f,
786 -0.15001918f, -0.07650751f, 0.02359855f, -0.075155355f,
787 -0.08037709f, -0.15093534f, 0.029517552f, -0.04751393f,
788 0.010350531f, -0.02664851f, -0.016839722f, -0.023121163f,
789 0.0077019283f, 0.012851257f, -0.05040649f, -0.0129761f,
790 -0.021737747f, -0.038305793f, -0.06870586f, -0.01481247f };
791
792 std::vector<float> inputGateBias = { 0.02234832f, 0.14757581f, 0.18176508f,
793 0.10380666f, 0.053110216f, -0.06928846f };
794
795 std::vector<float> forgetGateBias = { 0.035185695f, -0.042891346f, -0.03032477f,
796 0.23027696f, 0.11098921f, 0.08989442f };
797
798 std::vector<float> cellBias = { -0.024379363f, 0.0055531194f, 0.23377132f,
799 0.033463873f, -0.1483596f, 0.029460307f };
800
801 std::vector<float> outputGateBias = { 0.046159424f, -0.0012809046f, 0.03563469f,
802 0.12648113f, 0.027195795f, 0.35373217f };
803
804 std::vector<float> recurrentToInputWeights = { -0.001374326f, -0.078856036f, 0.10672688f, 0.029162422f,
805 -0.11585556f, 0.02557986f, -0.13446963f, -0.035785314f,
806 -0.01244275f, 0.025961924f, -0.02337298f, -0.044228926f,
807 -0.055839065f, -0.046598054f, -0.010546039f, -0.06900766f,
808 0.027239809f, 0.022582639f, -0.013296484f, -0.05459212f,
809 0.08981f, -0.045407712f, 0.08682226f, -0.06867011f,
810 -0.14390695f, -0.02916037f, 0.000996957f, 0.091420636f,
811 0.14283475f, -0.07390571f };
812
813 std::vector<float> recurrentToCellWeights = { -0.037322544f, 0.018592842f, 0.0056175636f, -0.06253426f,
814 0.055647098f, -0.05713207f, -0.05626563f, 0.005559383f,
815 0.03375411f, -0.025757805f, -0.088049285f, 0.06017052f,
816 -0.06570978f, 0.007384076f, 0.035123326f, -0.07920549f,
817 0.053676967f, 0.044480428f, -0.07663568f, 0.0071805613f,
818 0.08089997f, 0.05143358f, 0.038261272f, 0.03339287f,
819 -0.027673481f, 0.044746667f, 0.028349208f, 0.020090483f,
820 -0.019443132f, -0.030755889f };
821
822 std::vector<float> recurrentToForgetWeights = { -0.057784554f, -0.026057621f, -0.068447545f, -0.022581743f,
823 0.14811787f, 0.10826372f, 0.09471067f, 0.03987225f,
824 -0.0039523416f, 0.00030638507f, 0.053185795f, 0.10572994f,
825 0.08414449f, -0.022036452f, -0.00066928595f, -0.09203576f,
826 0.032950465f, -0.10985798f, -0.023809856f, 0.0021431844f,
827 -0.02196096f, -0.00326074f, 0.00058621005f, -0.074678116f,
828 -0.06193199f, 0.055729095f, 0.03736828f, 0.020123724f,
829 0.061878487f, -0.04729229f };
830
831 std::vector<float> recurrentToOutputWeights = { 0.025825322f, -0.05813119f, 0.09495884f,
832 -0.045984812f,-0.01255415f, -0.0026479573f,
833 -0.08196161f, -0.054914974f, -0.0046604523f,
834 -0.029587349f, -0.044576716f, -0.07480124f,
835 -0.082868785f, 0.023254942f, 0.027502948f,
836 -0.0039728214f, -0.08683098f, -0.08116779f,
837 -0.014675607f, -0.037924774f, -0.023314456f,
838 -0.007401714f, -0.09255757f, 0.029460307f,
839 -0.08829125f, -0.005139627f, -0.08989442f,
840 -0.0555066f, 0.13596267f, 0.025062224f };
841
842 std::vector<float> cellToInputWeights = { 0.040369894f, 0.030746894f, 0.24704495f,
843 0.018586371f, -0.037586458f, -0.15312155f };
844
845 std::vector<float> cellToForgetWeights = { -0.01998659f, -0.15568835f, -0.24248174f,
846 -0.012770197f, 0.041331276f, -0.072311886f };
847
848 std::vector<float> cellToOutputWeights = { 0.08286371f, -0.08261836f, -0.51210177f,
849 0.002913762f, 0.17764764f, -0.5495371f };
850
851 std::vector<float> projectionWeights = { -0.009802181f, 0.09401916f, 0.0717386f, -0.13895074f, 0.09641832f,
852 0.060420845f, 0.08539281f, 0.054285463f, 0.061395317f, 0.034448683f,
853 -0.042991187f, 0.019801661f, -0.16840284f, -0.015726732f, -0.23041931f,
854 -0.024478018f, -0.10959692f, -0.013875541f, 0.18600968f, -0.061274476f,
855 0.0138165f, -0.08160894f, -0.07661644f, 0.032372914f, 0.16169067f,
856 0.22465782f, -0.03993472f, -0.004017731f, 0.08633481f, -0.28869787f };
857
858 std::vector<float> projectionBiasVector(outputSize, 0.f); //{outputSize}
859
860 armnn::ScopedTensorHandle inputToInputWeightsTensor(tensorInfo6x4);
861 armnn::ScopedTensorHandle inputToForgetWeightsTensor(tensorInfo6x4);
862 armnn::ScopedTensorHandle inputToCellWeightsTensor(tensorInfo6x4);
863 armnn::ScopedTensorHandle inputToOutputWeightsTensor(tensorInfo6x4);
864 armnn::ScopedTensorHandle recurrentToForgetWeightsTensor(tensorInfo6x5);
865 armnn::ScopedTensorHandle recurrentToInputWeightsTensor(tensorInfo6x5);
866 armnn::ScopedTensorHandle recurrentToCellWeightsTensor(tensorInfo6x5);
867 armnn::ScopedTensorHandle recurrentToOutputWeightsTensor(tensorInfo6x5);
868 armnn::ScopedTensorHandle cellToInputWeightsTensor(tensorInfo6);
869 armnn::ScopedTensorHandle inputGateBiasTensor(tensorInfo6);
870 armnn::ScopedTensorHandle forgetGateBiasTensor(tensorInfo6);
871 armnn::ScopedTensorHandle cellBiasTensor(tensorInfo6);
872 armnn::ScopedTensorHandle outputGateBiasTensor(tensorInfo6);
873 armnn::ScopedTensorHandle cellToForgetWeightsTensor(tensorInfo6);
874 armnn::ScopedTensorHandle cellToOutputWeightsTensor(tensorInfo6);
875 armnn::ScopedTensorHandle projectionWeightsTensor(tensorInfo5x6);
876 armnn::ScopedTensorHandle projectionBiasTensor(tensorInfo5);
877
878 AllocateAndCopyDataToITensorHandle(&inputToInputWeightsTensor, inputToInputWeights.data());
879 AllocateAndCopyDataToITensorHandle(&inputToForgetWeightsTensor, inputToForgetWeights.data());
880 AllocateAndCopyDataToITensorHandle(&inputToCellWeightsTensor, inputToCellWeights.data());
881 AllocateAndCopyDataToITensorHandle(&inputToOutputWeightsTensor, inputToOutputWeights.data());
882 AllocateAndCopyDataToITensorHandle(&recurrentToInputWeightsTensor, recurrentToInputWeights.data());
883 AllocateAndCopyDataToITensorHandle(&recurrentToForgetWeightsTensor, recurrentToForgetWeights.data());
884 AllocateAndCopyDataToITensorHandle(&recurrentToCellWeightsTensor, recurrentToCellWeights.data());
885 AllocateAndCopyDataToITensorHandle(&recurrentToOutputWeightsTensor, recurrentToOutputWeights.data());
886 AllocateAndCopyDataToITensorHandle(&cellToInputWeightsTensor, cellToInputWeights.data());
887 AllocateAndCopyDataToITensorHandle(&inputGateBiasTensor, inputGateBias.data());
888 AllocateAndCopyDataToITensorHandle(&forgetGateBiasTensor, forgetGateBias.data());
889 AllocateAndCopyDataToITensorHandle(&cellBiasTensor, cellBias.data());
890 AllocateAndCopyDataToITensorHandle(&outputGateBiasTensor, outputGateBias.data());
891 AllocateAndCopyDataToITensorHandle(&cellToForgetWeightsTensor, cellToForgetWeights.data());
892 AllocateAndCopyDataToITensorHandle(&cellToOutputWeightsTensor, cellToOutputWeights.data());
893 AllocateAndCopyDataToITensorHandle(&projectionWeightsTensor, projectionWeights.data());
894 AllocateAndCopyDataToITensorHandle(&projectionBiasTensor, projectionBiasVector.data());
895
896 data.m_InputToInputWeights = &inputToInputWeightsTensor;
897 data.m_InputToForgetWeights = &inputToForgetWeightsTensor;
898 data.m_InputToCellWeights = &inputToCellWeightsTensor;
899 data.m_InputToOutputWeights = &inputToOutputWeightsTensor;
900 data.m_RecurrentToInputWeights = &recurrentToInputWeightsTensor;
901 data.m_RecurrentToForgetWeights = &recurrentToForgetWeightsTensor;
902 data.m_RecurrentToCellWeights = &recurrentToCellWeightsTensor;
903 data.m_RecurrentToOutputWeights = &recurrentToOutputWeightsTensor;
904 data.m_CellToInputWeights = &cellToInputWeightsTensor;
905 data.m_InputGateBias = &inputGateBiasTensor;
906 data.m_ForgetGateBias = &forgetGateBiasTensor;
907 data.m_CellBias = &cellBiasTensor;
908 data.m_OutputGateBias = &outputGateBiasTensor;
909 data.m_CellToForgetWeights = &cellToForgetWeightsTensor;
910 data.m_CellToOutputWeights = &cellToOutputWeightsTensor;
911 data.m_ProjectionWeights = &projectionWeightsTensor;
912 data.m_ProjectionBias = &projectionBiasTensor;
913
914 // Flags to set test configuration
915 data.m_Parameters.m_ActivationFunc = 4;
916 data.m_Parameters.m_CifgEnabled = false;
917 data.m_Parameters.m_PeepholeEnabled = true;
918 data.m_Parameters.m_ProjectionEnabled = true;
919 data.m_Parameters.m_LayerNormEnabled = false;
920 data.m_Parameters.m_TimeMajor = false;
921 data.m_Parameters.m_ClippingThresCell = 10.0f;
922
923
Teresa Charlin611c7fb2022-01-07 09:47:29 +0000924 std::unique_ptr<armnn::IWorkload> workload
925 = workloadFactory.CreateWorkload(armnn::LayerType::UnidirectionalSequenceLstm, data, info);
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100926 inputHandle->Allocate();
927 outputStateInHandle->Allocate();
928 cellStateInHandle->Allocate();
Mike Kelly12994962022-04-21 11:57:09 +0100929
930 outputStateOutHandle->Allocate();
931 cellStateOutHandle->Allocate();
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100932 outputHandle->Allocate();
933
934 CopyDataToITensorHandle(inputHandle.get(), inputVector.data());
935 CopyDataToITensorHandle(outputStateInHandle.get(), outputStateInVector.data());
936 CopyDataToITensorHandle(cellStateInHandle.get(), cellStateInVector.data());
937
938 workload->Execute();
939
Mike Kelly12994962022-04-21 11:57:09 +0100940 CopyDataFromITensorHandle(actualOutputStateOut.data(), outputStateOutHandle.get());
941 CopyDataFromITensorHandle(actualCellStateOut.data(), cellStateOutHandle.get());
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100942 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
943
944 return LayerTestResult<float, 3>(actualOutput,
945 expectedOutput,
946 outputHandle->GetShape(),
947 outputTensorInfo.GetShape());
948}
949
950LayerTestResult<float, 3> UnidirectionalSequenceLstmLayerNoCifgWithPeepholeWithProjectionWithLayerNormTest(
951 armnn::IWorkloadFactory& workloadFactory,
952 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
953 const armnn::ITensorHandleFactory& tensorHandleFactory)
954{
955 IgnoreUnused(memoryManager);
956 unsigned int batchSize = 3;
957 unsigned int timeSize = 2;
958 unsigned int outputSize = 4;
959 unsigned int inputSize = 3;
960 unsigned numUnits = 5;
961
962 armnn::TensorInfo inputTensorInfo({batchSize, timeSize, inputSize}, armnn::DataType::Float32);
963 armnn::TensorInfo cellStateInTensorInfo({batchSize , numUnits}, armnn::DataType::Float32);
964 armnn::TensorInfo outputStateInTensorInfo({batchSize , outputSize}, armnn::DataType::Float32);
Mike Kelly12994962022-04-21 11:57:09 +0100965 armnn::TensorInfo outputStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
966 armnn::TensorInfo cellStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100967 armnn::TensorInfo outputTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
968
969 const std::vector<float> inputVector = { 1., 2., 3., 4., 5., 4.,
970 3., 2., 1., 2., 3., 4.,
971 5., 4., 3., 2., 1., 2. };
972
973 std::vector<float> cellStateInVector(batchSize * numUnits, 0.f);
974 std::vector<float> outputStateInVector(batchSize * outputSize, 0.f);
975
Mike Kelly12994962022-04-21 11:57:09 +0100976 std::vector<float> actualOutputStateOut(outputStateOutTensorInfo.GetNumElements());
977 std::vector<float> actualCellStateOut(cellStateOutTensorInfo.GetNumElements());
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100978 std::vector<float> actualOutput(outputTensorInfo.GetNumElements());
979
980 const std::vector<float> expectedOutput = { 0.0642256f, 0.0343966f, 0.184122f, 0.114717f,
981 0.11458f, 0.0407109f, 0.300327f, 0.174301f,
982 0.0864761f, 0.0362912f, 0.178635f, 0.115689f,
983 0.108008f, 0.0386623f, 0.273471f, 0.167115f,
984 0.0859545f, 0.0331481f, 0.186051f, 0.11888f,
985 0.106649f, 0.0276847f, 0.229863f, 0.166958f };
986
987 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
988 std::unique_ptr<armnn::ITensorHandle> cellStateInHandle =
989 tensorHandleFactory.CreateTensorHandle(cellStateInTensorInfo);
990 std::unique_ptr<armnn::ITensorHandle> outputStateInHandle =
991 tensorHandleFactory.CreateTensorHandle(outputStateInTensorInfo);
992
Mike Kelly12994962022-04-21 11:57:09 +0100993 std::unique_ptr<armnn::ITensorHandle> outputStateOutHandle =
994 tensorHandleFactory.CreateTensorHandle(outputStateOutTensorInfo);
995 std::unique_ptr<armnn::ITensorHandle> cellStateOutHandle =
996 tensorHandleFactory.CreateTensorHandle(cellStateOutTensorInfo);
Narumol Prangnawarate5339e72021-07-28 17:33:28 +0100997 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
998
999 armnn::UnidirectionalSequenceLstmQueueDescriptor data;
1000 armnn::WorkloadInfo info;
1001
1002 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
1003 AddInputToWorkload(data, info, outputStateInTensorInfo, outputStateInHandle.get());
1004 AddInputToWorkload(data, info, cellStateInTensorInfo, cellStateInHandle.get());
1005
Mike Kelly12994962022-04-21 11:57:09 +01001006 AddOutputToWorkload(data, info, outputStateOutTensorInfo, outputStateOutHandle.get());
1007 AddOutputToWorkload(data, info, cellStateOutTensorInfo, cellStateOutHandle.get());
Narumol Prangnawarate5339e72021-07-28 17:33:28 +01001008 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
1009
1010 armnn::TensorInfo tensorInfo4({outputSize}, armnn::DataType::Float32);
1011 armnn::TensorInfo tensorInfo5({numUnits}, armnn::DataType::Float32);
1012 armnn::TensorInfo tensorInfo5x3({numUnits, inputSize}, armnn::DataType::Float32);
1013 armnn::TensorInfo tensorInfo5x4({numUnits, outputSize}, armnn::DataType::Float32);
1014 armnn::TensorInfo tensorInfo4x5({outputSize, numUnits}, armnn::DataType::Float32);
1015
1016 std::vector<float> inputToInputWeights = { -0.49536117f, -0.0556083915f, -0.102400711f,
1017 -0.117484632f, 0.3298470976f, -0.1179017122f,
1018 0.214305695f, 0.42135173085f, 0.003878414626f,
1019 -0.348303917f, -0.1881275477f, 0.0343011027f,
1020 -0.38837709614f, -0.05636804124f, 0.4259087456f};
1021
1022 std::vector<float> inputToForgetWeights = { 0.2415594226f, 0.15400093799f, 0.4566498398f,
1023 -0.3810434485f, 0.268383264f, -0.009807467424f,
1024 -0.3522925403f, -0.24275735512f, -0.28344226125f,
1025 0.13512269116f, -0.4932442977f, -0.10039821991f,
1026 0.2726137042f, 0.09216640889f, -0.06551410215f};
1027
1028 std::vector<float> inputToCellWeights = { -0.2504855627f, 0.184490025045f, -0.2480507493f,
1029 0.386399507f, -0.259465157985f, -0.16545993089f,
1030 -0.4230232555f, 0.341664791103f, -0.18127849691f,
1031 -0.2277662414f, -0.55275535589f, 0.34184026718f,
1032 0.3954237699f, -0.19407111404f, 0.30412107706f};
1033
1034 std::vector<float> inputToOutputWeights = { 0.2303854227f, 0.5218806862f, -0.4865379333f,
1035 0.53969591851f, 0.23393625035f, -0.27140527306f,
1036 0.50009280443f, 0.07511717046f, 0.3998299249f,
1037 -0.51717478049f, 0.1889653282f, -0.367323637f,
1038 -0.12584099173f, -0.12319286912f, 0.2407919466f};
1039
1040 std::vector<float> inputGateBias{ 0.03f, 0.15f, 0.22f, 0.38f, 0.05f };
1041 std::vector<float> forgetGateBias{ 0.1f, -0.3f, -0.2f, 0.1f, 0.4f };
1042 std::vector<float> cellBias{ -0.05f, 0.72f, 0.25f, 0.08f, 0.1f };
1043 std::vector<float> outputGateBias{ 0.05f, -0.01f, 0.2f, 0.1f, -0.2f };
1044
1045 std::vector<float> recurrentToInputWeights = { -0.128009796112f, 0.1995525098f, -0.07745539397f, 0.1558421701f,
1046 -0.265254765766f, -0.38837709614f, -0.05636804124f, 0.4259087456f,
1047 0.17628988623f, 0.3877420127f, 0.53300309181f, -0.0959980934f,
1048 0.00302857416f, 0.3266998827f, -0.142509296562f, -0.04433270756f,
1049 0.54066205f, -0.32668582f, -0.43562764f, -0.56094903f };
1050
1051 std::vector<float> recurrentToForgetWeights = { -0.09499983487f, -0.08814888417f, -0.04834804721f, 0.1516668247f,
1052 -0.3967529535f, -0.06463699788f, 0.4952811002f, 0.003274492938f,
1053 -0.0968840941f, 0.17928104102f, 0.0031281141592f, -0.3387276584f,
1054 -0.3587934076f, 0.06705895066f, 0.22463923692f, 0.1961955726f,
1055 0.01841056f, -0.32764608f, -0.33027974f, -0.10826075f };
1056
1057 std::vector<float> recurrentToCellWeights = { -0.21938985582f, -0.3023648226f, -0.1170005202f, -0.3509177422f,
1058 -0.4286288613f, 0.2726137042f, 0.09216640889f, -0.06551410215f,
1059 0.20453298098f, 0.2393476665f, 0.11846517771f, 0.2630801796f,
1060 0.3954237699f, -0.19407111404f, 0.30412107706f, -0.27342408554f,
1061 0.19069612f, -0.03026325f, -0.54532051f, 0.33003211f };
1062
1063 std::vector<float> recurrentToOutputWeights = { -0.32921677827f, 0.32624614238f, -0.1388191282f, -0.17879831790f,
1064 -0.15185534954f, -0.16918526583f, -0.10087361183f, -0.5436913968f,
1065 0.016758225858f, 0.30454617738f, -0.41493862867f, -0.005565764375f,
1066 -0.12584099173f, -0.12319286912f, 0.2407919466f, -0.08879069983f,
1067 0.11178309f, 0.09481031f, -0.26424935f, 0.46261835f };
1068
1069 std::vector<float> cellToInputWeights { 0.05f, 0.1f, 0.25f, 0.15f, -0.02f };
1070 std::vector<float> cellToForgetWeights { -0.02f, -0.15f, -0.25f, -0.03f, 0.15f };
1071 std::vector<float> cellToOutputWeights { 0.1f, -0.1f, -0.5f, 0.05f, 0.01f };
1072
1073 std::vector<float> projectionWeights{ -0.1f, 0.2f, 0.01f, -0.2f,
1074 0.1f, 0.5f, 0.3f, 0.08f,
1075 0.07f, 0.2f, -0.4f, 0.2f,
1076 0.5f, -0.4f, 0.3f, -0.2f,
1077 0.3f, 0.08f, -0.07f, 0.2f};
1078
1079 std::vector<float> projectionBiasVector(outputSize, 0.f); //{outputSize}
1080
1081 std::vector<float> inputLayerNormWeights{ 0.1f, 0.2f, 0.3f, 0.5f, 0.8f };
1082 std::vector<float> forgetLayerNormWeights{ 0.1f, 0.2f, 0.3f, 0.5f, 0.2f };
1083 std::vector<float> cellLayerNormWeights{ 0.7f, 0.2f, 0.3f, 0.8f, 0.5f };
1084 std::vector<float> outputLayerNormWeights{ 0.6f, 0.2f, 0.2f, 0.5f, 0.1f };
1085
1086 armnn::ScopedTensorHandle inputToInputWeightsTensor(tensorInfo5x3);
1087 armnn::ScopedTensorHandle inputToForgetWeightsTensor(tensorInfo5x3);
1088 armnn::ScopedTensorHandle inputToCellWeightsTensor(tensorInfo5x3);
1089 armnn::ScopedTensorHandle inputToOutputWeightsTensor(tensorInfo5x3);
1090 armnn::ScopedTensorHandle recurrentToForgetWeightsTensor(tensorInfo5x4);
1091 armnn::ScopedTensorHandle recurrentToInputWeightsTensor(tensorInfo5x4);
1092 armnn::ScopedTensorHandle recurrentToCellWeightsTensor(tensorInfo5x4);
1093 armnn::ScopedTensorHandle recurrentToOutputWeightsTensor(tensorInfo5x4);
1094 armnn::ScopedTensorHandle cellToInputWeightsTensor(tensorInfo5);
1095 armnn::ScopedTensorHandle inputGateBiasTensor(tensorInfo5);
1096 armnn::ScopedTensorHandle forgetGateBiasTensor(tensorInfo5);
1097 armnn::ScopedTensorHandle cellBiasTensor(tensorInfo5);
1098 armnn::ScopedTensorHandle outputGateBiasTensor(tensorInfo5);
1099 armnn::ScopedTensorHandle cellToForgetWeightsTensor(tensorInfo5);
1100 armnn::ScopedTensorHandle cellToOutputWeightsTensor(tensorInfo5);
1101 armnn::ScopedTensorHandle projectionWeightsTensor(tensorInfo4x5);
1102 armnn::ScopedTensorHandle projectionBiasTensor(tensorInfo4);
1103
1104 armnn::ScopedTensorHandle inputLayerNormWeightsTensor(tensorInfo5);
1105 armnn::ScopedTensorHandle forgetLayerNormWeightsTensor(tensorInfo5);
1106 armnn::ScopedTensorHandle cellLayerNormWeightsTensor(tensorInfo5);
1107 armnn::ScopedTensorHandle outputLayerNormWeightsTensor(tensorInfo5);
1108
1109 AllocateAndCopyDataToITensorHandle(&inputToInputWeightsTensor, inputToInputWeights.data());
1110 AllocateAndCopyDataToITensorHandle(&inputToForgetWeightsTensor, inputToForgetWeights.data());
1111 AllocateAndCopyDataToITensorHandle(&inputToCellWeightsTensor, inputToCellWeights.data());
1112 AllocateAndCopyDataToITensorHandle(&inputToOutputWeightsTensor, inputToOutputWeights.data());
1113 AllocateAndCopyDataToITensorHandle(&recurrentToInputWeightsTensor, recurrentToInputWeights.data());
1114 AllocateAndCopyDataToITensorHandle(&recurrentToForgetWeightsTensor, recurrentToForgetWeights.data());
1115 AllocateAndCopyDataToITensorHandle(&recurrentToCellWeightsTensor, recurrentToCellWeights.data());
1116 AllocateAndCopyDataToITensorHandle(&recurrentToOutputWeightsTensor, recurrentToOutputWeights.data());
1117 AllocateAndCopyDataToITensorHandle(&cellToInputWeightsTensor, cellToInputWeights.data());
1118 AllocateAndCopyDataToITensorHandle(&inputGateBiasTensor, inputGateBias.data());
1119 AllocateAndCopyDataToITensorHandle(&forgetGateBiasTensor, forgetGateBias.data());
1120 AllocateAndCopyDataToITensorHandle(&cellBiasTensor, cellBias.data());
1121 AllocateAndCopyDataToITensorHandle(&outputGateBiasTensor, outputGateBias.data());
1122 AllocateAndCopyDataToITensorHandle(&cellToForgetWeightsTensor, cellToForgetWeights.data());
1123 AllocateAndCopyDataToITensorHandle(&cellToOutputWeightsTensor, cellToOutputWeights.data());
1124 AllocateAndCopyDataToITensorHandle(&projectionWeightsTensor, projectionWeights.data());
1125 AllocateAndCopyDataToITensorHandle(&projectionBiasTensor, projectionBiasVector.data());
1126
1127 AllocateAndCopyDataToITensorHandle(&inputLayerNormWeightsTensor, inputLayerNormWeights.data());
1128 AllocateAndCopyDataToITensorHandle(&forgetLayerNormWeightsTensor, forgetLayerNormWeights.data());
1129 AllocateAndCopyDataToITensorHandle(&cellLayerNormWeightsTensor, cellLayerNormWeights.data());
1130 AllocateAndCopyDataToITensorHandle(&outputLayerNormWeightsTensor, outputLayerNormWeights.data());
1131
1132 data.m_InputToInputWeights = &inputToInputWeightsTensor;
1133 data.m_InputToForgetWeights = &inputToForgetWeightsTensor;
1134 data.m_InputToCellWeights = &inputToCellWeightsTensor;
1135 data.m_InputToOutputWeights = &inputToOutputWeightsTensor;
1136 data.m_RecurrentToInputWeights = &recurrentToInputWeightsTensor;
1137 data.m_RecurrentToForgetWeights = &recurrentToForgetWeightsTensor;
1138 data.m_RecurrentToCellWeights = &recurrentToCellWeightsTensor;
1139 data.m_RecurrentToOutputWeights = &recurrentToOutputWeightsTensor;
1140 data.m_CellToInputWeights = &cellToInputWeightsTensor;
1141 data.m_InputGateBias = &inputGateBiasTensor;
1142 data.m_ForgetGateBias = &forgetGateBiasTensor;
1143 data.m_CellBias = &cellBiasTensor;
1144 data.m_OutputGateBias = &outputGateBiasTensor;
1145 data.m_CellToForgetWeights = &cellToForgetWeightsTensor;
1146 data.m_CellToOutputWeights = &cellToOutputWeightsTensor;
1147 data.m_ProjectionWeights = &projectionWeightsTensor;
1148 data.m_ProjectionBias = &projectionBiasTensor;
1149
1150 data.m_InputLayerNormWeights = &inputLayerNormWeightsTensor;
1151 data.m_ForgetLayerNormWeights = &forgetLayerNormWeightsTensor;
1152 data.m_CellLayerNormWeights = &cellLayerNormWeightsTensor;
1153 data.m_OutputLayerNormWeights = &outputLayerNormWeightsTensor;
1154
1155 // Flags to set test configuration
1156 data.m_Parameters.m_ActivationFunc = 4;
1157 data.m_Parameters.m_CifgEnabled = false;
1158 data.m_Parameters.m_PeepholeEnabled = true;
1159 data.m_Parameters.m_ProjectionEnabled = true;
1160 data.m_Parameters.m_LayerNormEnabled = true;
1161 data.m_Parameters.m_TimeMajor = false;
1162 data.m_Parameters.m_ClippingThresCell = 10.0f;
1163
Teresa Charlin611c7fb2022-01-07 09:47:29 +00001164 std::unique_ptr<armnn::IWorkload> workload
1165 = workloadFactory.CreateWorkload(armnn::LayerType::UnidirectionalSequenceLstm, data, info);
Narumol Prangnawarate5339e72021-07-28 17:33:28 +01001166 inputHandle->Allocate();
1167 outputStateInHandle->Allocate();
1168 cellStateInHandle->Allocate();
Mike Kelly12994962022-04-21 11:57:09 +01001169
1170 outputStateOutHandle->Allocate();
1171 cellStateOutHandle->Allocate();
Narumol Prangnawarate5339e72021-07-28 17:33:28 +01001172 outputHandle->Allocate();
1173
1174 CopyDataToITensorHandle(inputHandle.get(), inputVector.data());
1175 CopyDataToITensorHandle(outputStateInHandle.get(), outputStateInVector.data());
1176 CopyDataToITensorHandle(cellStateInHandle.get(), cellStateInVector.data());
1177
1178 workload->Execute();
1179
Mike Kelly12994962022-04-21 11:57:09 +01001180 CopyDataFromITensorHandle(actualOutputStateOut.data(), outputStateOutHandle.get());
1181 CopyDataFromITensorHandle(actualCellStateOut.data(), cellStateOutHandle.get());
Narumol Prangnawarate5339e72021-07-28 17:33:28 +01001182 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
1183
1184 return LayerTestResult<float, 3>(actualOutput,
1185 expectedOutput,
1186 outputHandle->GetShape(),
1187 outputTensorInfo.GetShape());
1188}
1189
1190LayerTestResult<float, 3> UnidirectionalSequenceLstmWithCifgWithPeepholeNoProjectionTest(
1191 armnn::IWorkloadFactory& workloadFactory,
1192 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1193 const armnn::ITensorHandleFactory& tensorHandleFactory)
1194{
1195 IgnoreUnused(memoryManager);
1196 unsigned int batchSize = 3;
1197 unsigned int timeSize = 2;
1198 unsigned int inputSize = 3;
1199 unsigned int outputSize = 4;
1200 unsigned numUnits = outputSize;
1201
1202 armnn::TensorInfo inputTensorInfo({batchSize, timeSize, inputSize}, armnn::DataType::Float32);
1203 armnn::TensorInfo cellStateInTensorInfo({batchSize, numUnits}, armnn::DataType::Float32);
1204 armnn::TensorInfo outputStateInTensorInfo({batchSize, outputSize}, armnn::DataType::Float32);
Mike Kelly12994962022-04-21 11:57:09 +01001205 armnn::TensorInfo outputStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
1206 armnn::TensorInfo cellStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
Narumol Prangnawarate5339e72021-07-28 17:33:28 +01001207 armnn::TensorInfo outputTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
1208
1209 std::vector<float> inputVector = { 1., 2., 3., 4., 5., 4.,
1210 3., 2., 1., 2., 3., 4.,
1211 5., 4., 3., 2., 1., 2. };
1212
1213 std::vector<float> cellStateInVector(batchSize * numUnits, 0.f);
1214 std::vector<float> outputStateInVector(batchSize * outputSize, 0.f);
1215
Mike Kelly12994962022-04-21 11:57:09 +01001216 std::vector<float> actualOutputStateOut(outputStateOutTensorInfo.GetNumElements());
1217 std::vector<float> actualCellStateOut(cellStateOutTensorInfo.GetNumElements());
Narumol Prangnawarate5339e72021-07-28 17:33:28 +01001218 std::vector<float> actualOutput(outputTensorInfo.GetNumElements());
1219
1220 std::vector<float> outputVector = { -0.0129257f, -0.070531f, -0.153508f, -0.0392391f,
1221 -0.0300169f, -0.195717f, -0.528679f, -0.0818106f,
1222 -0.0332748f, 0.155429f, -0.353966f, -0.0801505f,
1223 -0.032312f, -0.0407911f, -0.435053f, -0.0932317f,
1224 -0.0108233f, 0.165584f, -0.640424f, -0.0447535f,
1225 -0.031675f, 0.125987f, -0.526695f, -0.110093f };
1226
1227 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
1228 std::unique_ptr<armnn::ITensorHandle> cellStateInHandle =
1229 tensorHandleFactory.CreateTensorHandle(cellStateInTensorInfo);
1230 std::unique_ptr<armnn::ITensorHandle> outputStateInHandle =
1231 tensorHandleFactory.CreateTensorHandle(outputStateInTensorInfo);
1232
Mike Kelly12994962022-04-21 11:57:09 +01001233 std::unique_ptr<armnn::ITensorHandle> outputStateOutHandle =
1234 tensorHandleFactory.CreateTensorHandle(outputStateOutTensorInfo);
1235 std::unique_ptr<armnn::ITensorHandle> cellStateOutHandle =
1236 tensorHandleFactory.CreateTensorHandle(cellStateOutTensorInfo);
Narumol Prangnawarate5339e72021-07-28 17:33:28 +01001237 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
1238
1239 armnn::UnidirectionalSequenceLstmQueueDescriptor data;
1240 armnn::WorkloadInfo info;
1241
1242 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
1243 AddInputToWorkload(data, info, outputStateInTensorInfo, outputStateInHandle.get());
1244 AddInputToWorkload(data, info, cellStateInTensorInfo, cellStateInHandle.get());
1245
Mike Kelly12994962022-04-21 11:57:09 +01001246 AddOutputToWorkload(data, info, outputStateOutTensorInfo, outputStateOutHandle.get());
1247 AddOutputToWorkload(data, info, cellStateOutTensorInfo, cellStateOutHandle.get());
Narumol Prangnawarate5339e72021-07-28 17:33:28 +01001248 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
1249
1250 armnn::TensorInfo tensorInfo4({numUnits}, armnn::DataType::Float32);
1251 armnn::TensorInfo tensorInfo12({numUnits, 3}, armnn::DataType::Float32);
1252 armnn::TensorInfo tensorInfo16({numUnits, 4}, armnn::DataType::Float32);
1253
1254 std::vector<float> inputToForgetWeights = { 0.2415594226f, 0.15400093799f, 0.4566498398f,
1255 -0.3810434485f, 0.268383264f, -0.009807467424f,
1256 -0.3522925403f, -0.24275735512f, -0.28344226125f,
1257 0.13512269116f, -0.4932442977f, -0.10039821991f };
1258
1259 std::vector<float> inputToCellWeights = { -0.2504855627f, 0.184490025045f, -0.2480507493f,
1260 0.386399507f, -0.259465157985f, -0.16545993089f,
1261 -0.4230232555f, 0.341664791103f, -0.18127849691f,
1262 -0.2277662414f, -0.55275535589f, 0.34184026718f };
1263
1264 std::vector<float> inputToOutputWeights = { 0.2303854227f, 0.5218806862f, -0.4865379333f,
1265 0.53969591851f, 0.23393625035f, -0.27140527306f,
1266 0.50009280443f, 0.07511717046f, 0.3998299249f,
1267 -0.51717478049f, 0.1889653282f, -0.367323637f };
1268
1269 std::vector<float> recurrentToForgetWeights = { -0.09499983487f, -0.08814888417f, -0.04834804721f, 0.1516668247f,
1270 -0.3967529535f, -0.06463699788f, 0.4952811002f, 0.003274492938f,
1271 -0.0968840941f, 0.17928104102f, 0.0031281141592f, -0.3387276584f,
1272 -0.3587934076f, 0.06705895066f, 0.22463923692f, 0.1961955726f };
1273
1274 std::vector<float> recurrentToCellWeights = { -0.21938985582f, -0.3023648226f, -0.1170005202f, -0.3509177422f,
1275 -0.4286288613f, 0.2726137042f, 0.09216640889f, -0.06551410215f,
1276 0.20453298098f, 0.2393476665f, 0.11846517771f, 0.2630801796f,
1277 0.3954237699f, -0.19407111404f, 0.30412107706f, -0.27342408554f };
1278
1279 std::vector<float> recurrentToOutputWeights = { -0.32921677827f, 0.32624614238f, -0.1388191282f, -0.17879831790f,
1280 -0.15185534954f, -0.16918526583f, -0.10087361183f, -0.5436913968f,
1281 0.016758225858f, 0.30454617738f, -0.41493862867f, -0.005565764375f,
1282 -0.12584099173f, -0.12319286912f, 0.2407919466f, -0.08879069983f };
1283
1284 std::vector<float> cellToForgetWeights{ 0.47485286f, -0.51955009f, -0.24458408f, 0.31544167f };
1285
1286 std::vector<float> cellToOutputWeights{ -0.17135078f, 0.82760304f, 0.85573703f, -0.77109635f };
1287
1288 std::vector<float> forgetGateBias = { 1., 1., 1., 1. };
1289
1290 std::vector<float> cellBias = { 0., 0., 0., 0. };
1291
1292 std::vector<float> outputGateBias = { 0., 0., 0., 0. };
1293
1294 armnn::ScopedTensorHandle inputToForgetWeightsTensor(tensorInfo12);
1295 armnn::ScopedTensorHandle inputToCellWeightsTensor(tensorInfo12);
1296 armnn::ScopedTensorHandle inputToOutputWeightsTensor(tensorInfo12);
1297 armnn::ScopedTensorHandle recurrentToForgetWeightsTensor(tensorInfo16);
1298 armnn::ScopedTensorHandle recurrentToCellWeightsTensor(tensorInfo16);
1299 armnn::ScopedTensorHandle recurrentToOutputWeightsTensor(tensorInfo16);
1300 armnn::ScopedTensorHandle cellToForgetWeightsTensor(tensorInfo4);
1301 armnn::ScopedTensorHandle cellToOutputWeightsTensor(tensorInfo4);
1302 armnn::ScopedTensorHandle forgetGateBiasTensor(tensorInfo4);
1303 armnn::ScopedTensorHandle cellBiasTensor(tensorInfo4);
1304 armnn::ScopedTensorHandle outputGateBiasTensor(tensorInfo4);
1305
1306 AllocateAndCopyDataToITensorHandle(&inputToForgetWeightsTensor, inputToForgetWeights.data());
1307 AllocateAndCopyDataToITensorHandle(&inputToCellWeightsTensor, inputToCellWeights.data());
1308 AllocateAndCopyDataToITensorHandle(&inputToOutputWeightsTensor, inputToOutputWeights.data());
1309 AllocateAndCopyDataToITensorHandle(&recurrentToForgetWeightsTensor, recurrentToForgetWeights.data());
1310 AllocateAndCopyDataToITensorHandle(&recurrentToCellWeightsTensor, recurrentToCellWeights.data());
1311 AllocateAndCopyDataToITensorHandle(&recurrentToOutputWeightsTensor, recurrentToOutputWeights.data());
1312 AllocateAndCopyDataToITensorHandle(&cellToForgetWeightsTensor, cellToForgetWeights.data());
1313 AllocateAndCopyDataToITensorHandle(&cellToOutputWeightsTensor, cellToOutputWeights.data());
1314 AllocateAndCopyDataToITensorHandle(&forgetGateBiasTensor, forgetGateBias.data());
1315 AllocateAndCopyDataToITensorHandle(&cellBiasTensor, cellBias.data());
1316 AllocateAndCopyDataToITensorHandle(&outputGateBiasTensor, outputGateBias.data());
1317
1318 data.m_InputToForgetWeights = &inputToForgetWeightsTensor;
1319 data.m_InputToCellWeights = &inputToCellWeightsTensor;
1320 data.m_InputToOutputWeights = &inputToOutputWeightsTensor;
1321 data.m_RecurrentToForgetWeights = &recurrentToForgetWeightsTensor;
1322 data.m_RecurrentToCellWeights = &recurrentToCellWeightsTensor;
1323 data.m_RecurrentToOutputWeights = &recurrentToOutputWeightsTensor;
1324 data.m_CellToForgetWeights = &cellToForgetWeightsTensor;
1325 data.m_CellToOutputWeights = &cellToOutputWeightsTensor;
1326 data.m_ForgetGateBias = &forgetGateBiasTensor;
1327 data.m_CellBias = &cellBiasTensor;
1328 data.m_OutputGateBias = &outputGateBiasTensor;
1329
1330 // Flags to set test configuration
1331 data.m_Parameters.m_ClippingThresCell = 10;
1332 data.m_Parameters.m_ClippingThresProj = 0;
1333 data.m_Parameters.m_ActivationFunc = 4;
1334 data.m_Parameters.m_CifgEnabled = true;
1335 data.m_Parameters.m_PeepholeEnabled = true;
1336 data.m_Parameters.m_ProjectionEnabled = false;
1337 data.m_Parameters.m_TimeMajor = false;
1338
Teresa Charlin611c7fb2022-01-07 09:47:29 +00001339 std::unique_ptr<armnn::IWorkload> workload
1340 = workloadFactory.CreateWorkload(armnn::LayerType::UnidirectionalSequenceLstm, data, info);
Narumol Prangnawarate5339e72021-07-28 17:33:28 +01001341 inputHandle->Allocate();
1342 outputStateInHandle->Allocate();
1343 cellStateInHandle->Allocate();
1344
Mike Kelly12994962022-04-21 11:57:09 +01001345 outputStateOutHandle->Allocate();
1346 cellStateOutHandle->Allocate();
Narumol Prangnawarate5339e72021-07-28 17:33:28 +01001347 outputHandle->Allocate();
1348
1349 CopyDataToITensorHandle(inputHandle.get(), inputVector.data());
1350 CopyDataToITensorHandle(outputStateInHandle.get(), outputStateInVector.data());
1351 CopyDataToITensorHandle(cellStateInHandle.get(), cellStateInVector.data());
1352
1353 workload->Execute();
1354
Mike Kelly12994962022-04-21 11:57:09 +01001355 CopyDataFromITensorHandle(actualOutputStateOut.data(), outputStateOutHandle.get());
1356 CopyDataFromITensorHandle(actualCellStateOut.data(), cellStateOutHandle.get());
Narumol Prangnawarate5339e72021-07-28 17:33:28 +01001357 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
1358
1359 return LayerTestResult<float, 3>(actualOutput,
1360 outputVector,
1361 outputHandle->GetShape(),
1362 outputTensorInfo.GetShape());
1363}
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001364
1365LayerTestResult<float, 3> UnidirectionalSequenceLstmLayerInt8Test(
1366 armnn::IWorkloadFactory& workloadFactory,
1367 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1368 const armnn::ITensorHandleFactory& tensorHandleFactory)
1369{
1370 IgnoreUnused(memoryManager);
1371 unsigned int batchSize = 3;
1372 unsigned int timeSize = 2;
1373 unsigned int inputSize = 3;
1374 unsigned int outputSize = 4;
1375 unsigned numUnits = outputSize;
1376
1377 armnn::TensorInfo inputTensorInfo({batchSize, timeSize, inputSize}, armnn::DataType::Float32);
1378 armnn::TensorInfo cellStateInTensorInfo({batchSize, numUnits}, armnn::DataType::Float32);
1379 armnn::TensorInfo outputStateInTensorInfo({batchSize, outputSize}, armnn::DataType::Float32);
Mike Kelly12994962022-04-21 11:57:09 +01001380 armnn::TensorInfo outputStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
1381 armnn::TensorInfo cellStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001382 armnn::TensorInfo outputTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
1383
1384 const std::vector<float> inputVector = { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.4f,
1385 0.3f, 0.2f, 0.1f, 0.2f, 0.3f, 0.4f,
1386 0.5f, 0.4f, 0.3f, 0.2f, 0.1f, 0.2f };
1387
1388 std::vector<float> cellStateInVector(batchSize * numUnits, 0.f);
1389 std::vector<float> outputStateInVector(batchSize * outputSize, 0.f);
1390
Mike Kelly12994962022-04-21 11:57:09 +01001391 std::vector<float> actualOutputStateOut(outputStateOutTensorInfo.GetNumElements());
1392 std::vector<float> actualCellStateOut(cellStateOutTensorInfo.GetNumElements());
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001393 std::vector<float> actualOutput(outputTensorInfo.GetNumElements());
1394
1395 const std::vector<float> outputVector = { -0.0142517f, -0.0198845f, -0.0120569f, -0.0116868f,
1396 -0.0350714f, -0.0343202f, -0.047504f, -0.0569789f,
1397 -0.0146346f, 0.0106663f, -0.0247238f, -0.0319502f,
1398 -0.0294759f, -0.0129935f, -0.0444175f, -0.0444354f,
1399 -0.0280855f, 0.00545101f, -0.051422f, -0.0463838f,
1400 -0.0310702f, 0.00915739f, -0.0625207f, -0.0482648f };
1401
1402 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
1403 std::unique_ptr<armnn::ITensorHandle> cellStateInHandle =
1404 tensorHandleFactory.CreateTensorHandle(cellStateInTensorInfo);
1405 std::unique_ptr<armnn::ITensorHandle> outputStateInHandle =
1406 tensorHandleFactory.CreateTensorHandle(outputStateInTensorInfo);
1407
Mike Kelly12994962022-04-21 11:57:09 +01001408 std::unique_ptr<armnn::ITensorHandle> outputStateOutHandle =
1409 tensorHandleFactory.CreateTensorHandle(outputStateOutTensorInfo);
1410 std::unique_ptr<armnn::ITensorHandle> cellStateOutHandle =
1411 tensorHandleFactory.CreateTensorHandle(cellStateOutTensorInfo);
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001412 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
1413
Mike Kelly12994962022-04-21 11:57:09 +01001414
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001415 armnn::UnidirectionalSequenceLstmQueueDescriptor data;
1416 armnn::WorkloadInfo info;
1417
1418 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
1419 AddInputToWorkload(data, info, outputStateInTensorInfo, outputStateInHandle.get());
1420 AddInputToWorkload(data, info, cellStateInTensorInfo, cellStateInHandle.get());
1421
Mike Kelly12994962022-04-21 11:57:09 +01001422 AddOutputToWorkload(data, info, outputStateOutTensorInfo, outputStateOutHandle.get());
1423 AddOutputToWorkload(data, info, cellStateOutTensorInfo, cellStateOutHandle.get());
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001424 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
1425
1426 armnn::TensorInfo tensorInfoNumFp({numUnits}, armnn::DataType::Float32);
1427 armnn::TensorInfo tensorInfoNumInput({numUnits, inputSize}, armnn::DataType::QAsymmS8, 0.1f, 0);
1428 armnn::TensorInfo tensorInfoNumOutput({numUnits, outputSize}, armnn::DataType::QAsymmS8, 0.1f, 0);
1429
1430 std::vector<int8_t> inputToInputWeights = { -4, -1, -1, -2, 3, -2, 2, 4, 1, -4, -2, 3 };
1431 std::vector<int8_t> inputToForgetWeights = { 2, 1, 4, -4, 3, -1, -3, -2, -3, 1, -4, -1 };
1432 std::vector<int8_t> inputToCellWeights = { -2, 1, -2, 4, -3, -2, -4, 3, -2, -2, -6, 3 };
1433 std::vector<int8_t> inputToOutputWeights = { 2, 5, -4, 5, 2, -3, 5, 7, 3, -5, 1, -4 };
1434
1435 std::vector<int8_t> recurrentToInputWeights = { -1, 1, -1, 1, -3, -4, -1, 4, 2, 3, 5, -1, 1, 3, -1, -1 };
1436 std::vector<int8_t> recurrentToForgetWeights = { -1, 1, -1, 1, -3, -4, -1, 4, 2, 3, 5, -1, 1, 3, -2, -1 };
1437 std::vector<int8_t> recurrentToCellWeights = { -2, -3, -1, -3, -4, 2, 1, -1, 2, 2, 1, 2, 3, -2, 3, -3 };
1438 std::vector<int8_t> recurrentToOutputWeights = { -3, 3, -1, -2, -2, -2, -1, -5, 1, 3, -4, -1, -1, -1, 2, -1 };
1439
1440 std::vector<float> inputGateBias = { 0., 0., 0., 0. };
1441 std::vector<float> forgetGateBias = { 1., 1., 1., 1. };
1442 std::vector<float> cellBias = { 0., 0., 0., 0. };
1443 std::vector<float> outputGateBias = { 0., 0., 0., 0. };
1444
1445 armnn::ScopedTensorHandle inputToInputWeightsTensor(tensorInfoNumInput);
1446 armnn::ScopedTensorHandle inputToForgetWeightsTensor(tensorInfoNumInput);
1447 armnn::ScopedTensorHandle inputToCellWeightsTensor(tensorInfoNumInput);
1448 armnn::ScopedTensorHandle inputToOutputWeightsTensor(tensorInfoNumInput);
1449 armnn::ScopedTensorHandle recurrentToInputWeightsTensor(tensorInfoNumOutput);
1450 armnn::ScopedTensorHandle recurrentToForgetWeightsTensor(tensorInfoNumOutput);
1451 armnn::ScopedTensorHandle recurrentToCellWeightsTensor(tensorInfoNumOutput);
1452 armnn::ScopedTensorHandle recurrentToOutputWeightsTensor(tensorInfoNumOutput);
1453 armnn::ScopedTensorHandle inputGateBiasTensor(tensorInfoNumFp);
1454 armnn::ScopedTensorHandle forgetGateBiasTensor(tensorInfoNumFp);
1455 armnn::ScopedTensorHandle cellBiasTensor(tensorInfoNumFp);
1456 armnn::ScopedTensorHandle outputGateBiasTensor(tensorInfoNumFp);
1457
1458 AllocateAndCopyDataToITensorHandle(&inputToInputWeightsTensor, inputToInputWeights.data());
1459 AllocateAndCopyDataToITensorHandle(&inputToForgetWeightsTensor, inputToForgetWeights.data());
1460 AllocateAndCopyDataToITensorHandle(&inputToCellWeightsTensor, inputToCellWeights.data());
1461 AllocateAndCopyDataToITensorHandle(&inputToOutputWeightsTensor, inputToOutputWeights.data());
1462 AllocateAndCopyDataToITensorHandle(&recurrentToInputWeightsTensor, recurrentToInputWeights.data());
1463 AllocateAndCopyDataToITensorHandle(&recurrentToForgetWeightsTensor, recurrentToForgetWeights.data());
1464 AllocateAndCopyDataToITensorHandle(&recurrentToCellWeightsTensor, recurrentToCellWeights.data());
1465 AllocateAndCopyDataToITensorHandle(&recurrentToOutputWeightsTensor, recurrentToOutputWeights.data());
1466 AllocateAndCopyDataToITensorHandle(&inputGateBiasTensor, inputGateBias.data());
1467 AllocateAndCopyDataToITensorHandle(&forgetGateBiasTensor, forgetGateBias.data());
1468 AllocateAndCopyDataToITensorHandle(&cellBiasTensor, cellBias.data());
1469 AllocateAndCopyDataToITensorHandle(&outputGateBiasTensor, outputGateBias.data());
1470
1471 data.m_InputToInputWeights = &inputToInputWeightsTensor;
1472 data.m_InputToForgetWeights = &inputToForgetWeightsTensor;
1473 data.m_InputToCellWeights = &inputToCellWeightsTensor;
1474 data.m_InputToOutputWeights = &inputToOutputWeightsTensor;
1475 data.m_RecurrentToInputWeights = &recurrentToInputWeightsTensor;
1476 data.m_RecurrentToForgetWeights = &recurrentToForgetWeightsTensor;
1477 data.m_RecurrentToCellWeights = &recurrentToCellWeightsTensor;
1478 data.m_RecurrentToOutputWeights = &recurrentToOutputWeightsTensor;
1479 data.m_InputGateBias = &inputGateBiasTensor;
1480 data.m_ForgetGateBias = &forgetGateBiasTensor;
1481 data.m_CellBias = &cellBiasTensor;
1482 data.m_OutputGateBias = &outputGateBiasTensor;
1483
1484 // Flags to set test configuration
1485 data.m_Parameters.m_ClippingThresCell = 10;
1486 data.m_Parameters.m_ClippingThresProj = 0;
1487 data.m_Parameters.m_ActivationFunc = 4;
1488 data.m_Parameters.m_CifgEnabled = false;
1489 data.m_Parameters.m_PeepholeEnabled = false;
1490 data.m_Parameters.m_ProjectionEnabled = false;
1491 data.m_Parameters.m_TimeMajor = false;
1492
Teresa Charlin611c7fb2022-01-07 09:47:29 +00001493 std::unique_ptr<armnn::IWorkload> workload
1494 = workloadFactory.CreateWorkload(armnn::LayerType::UnidirectionalSequenceLstm, data, info);
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001495 inputHandle->Allocate();
1496 outputStateInHandle->Allocate();
1497 cellStateInHandle->Allocate();
1498
Mike Kelly12994962022-04-21 11:57:09 +01001499 outputStateOutHandle->Allocate();
1500 cellStateOutHandle->Allocate();
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001501 outputHandle->Allocate();
1502
1503 CopyDataToITensorHandle(inputHandle.get(), inputVector.data());
1504 CopyDataToITensorHandle(outputStateInHandle.get(), outputStateInVector.data());
1505 CopyDataToITensorHandle(cellStateInHandle.get(), cellStateInVector.data());
1506
1507 workload->Execute();
1508
Mike Kelly12994962022-04-21 11:57:09 +01001509 CopyDataFromITensorHandle(actualOutputStateOut.data(), outputStateOutHandle.get());
1510 CopyDataFromITensorHandle(actualCellStateOut.data(), cellStateOutHandle.get());
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001511 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
1512
1513 return LayerTestResult<float, 3>(actualOutput,
1514 outputVector,
1515 outputHandle->GetShape(),
1516 outputTensorInfo.GetShape());
1517}
1518
1519LayerTestResult<float, 3> UnidirectionalSequenceLstmLayerInt8TimeMajorTest(
1520 armnn::IWorkloadFactory& workloadFactory,
1521 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1522 const armnn::ITensorHandleFactory& tensorHandleFactory)
1523{
1524 IgnoreUnused(memoryManager);
1525 unsigned int batchSize = 3;
1526 unsigned int timeSize = 2;
1527 unsigned int inputSize = 3;
1528 unsigned int outputSize = 4;
1529 unsigned numUnits = outputSize;
1530
1531 armnn::TensorInfo inputTensorInfo({timeSize, batchSize, inputSize}, armnn::DataType::Float32);
1532 armnn::TensorInfo cellStateInTensorInfo({batchSize, numUnits}, armnn::DataType::Float32);
1533 armnn::TensorInfo outputStateInTensorInfo({batchSize, outputSize}, armnn::DataType::Float32);
Mike Kelly12994962022-04-21 11:57:09 +01001534 armnn::TensorInfo outputStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
1535 armnn::TensorInfo cellStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001536 armnn::TensorInfo outputTensorInfo({timeSize, batchSize, outputSize}, armnn::DataType::Float32);
1537
1538 const std::vector<float> inputVector = { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.4f,
1539 0.3f, 0.2f, 0.1f, 0.2f, 0.3f, 0.4f,
1540 0.5f, 0.4f, 0.3f, 0.2f, 0.1f, 0.2f };
1541
1542 std::vector<float> cellStateInVector(batchSize * numUnits, 0.f);
1543 std::vector<float> outputStateInVector(batchSize * outputSize, 0.f);
1544
Mike Kelly12994962022-04-21 11:57:09 +01001545 std::vector<float> actualOutputStateOut(outputStateOutTensorInfo.GetNumElements());
1546 std::vector<float> actualCellStateOut(cellStateOutTensorInfo.GetNumElements());
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001547 std::vector<float> actualOutput(outputTensorInfo.GetNumElements());
1548
1549 const std::vector<float> outputVector = { -0.0142517f, -0.0198845f, -0.0120122f, -0.0116868f,
1550 -0.0261295f, -0.0188487f, -0.0345463f, -0.049733f,
1551 -0.0146346f, 0.0106663f, -0.0247238f, -0.0319502f,
1552 -0.0291863f, -0.0369402f, -0.0354071f, -0.0296529f,
1553 -0.0419539f, -0.00617731f, -0.0814796f, -0.0804005f,
1554 -0.0244737f, 0.0119905f, -0.0457527f, -0.0331862f };
1555 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
1556 std::unique_ptr<armnn::ITensorHandle> cellStateInHandle =
1557 tensorHandleFactory.CreateTensorHandle(cellStateInTensorInfo);
1558 std::unique_ptr<armnn::ITensorHandle> outputStateInHandle =
1559 tensorHandleFactory.CreateTensorHandle(outputStateInTensorInfo);
1560
Mike Kelly12994962022-04-21 11:57:09 +01001561 std::unique_ptr<armnn::ITensorHandle> outputStateOutHandle =
1562 tensorHandleFactory.CreateTensorHandle(outputStateOutTensorInfo);
1563 std::unique_ptr<armnn::ITensorHandle> cellStateOutHandle =
1564 tensorHandleFactory.CreateTensorHandle(cellStateOutTensorInfo);
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001565 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
1566
Mike Kelly12994962022-04-21 11:57:09 +01001567
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001568 armnn::UnidirectionalSequenceLstmQueueDescriptor data;
1569 armnn::WorkloadInfo info;
1570
1571 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
1572 AddInputToWorkload(data, info, outputStateInTensorInfo, outputStateInHandle.get());
1573 AddInputToWorkload(data, info, cellStateInTensorInfo, cellStateInHandle.get());
1574
Mike Kelly12994962022-04-21 11:57:09 +01001575 AddOutputToWorkload(data, info, outputStateOutTensorInfo, outputStateOutHandle.get());
1576 AddOutputToWorkload(data, info, cellStateOutTensorInfo, cellStateOutHandle.get());
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001577 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
1578
1579 armnn::TensorInfo tensorInfoNumFp({numUnits}, armnn::DataType::Float32);
1580 armnn::TensorInfo tensorInfoNumInput({numUnits, inputSize}, armnn::DataType::QAsymmS8, 0.1f, 0);
1581 armnn::TensorInfo tensorInfoNumOutput({numUnits, outputSize}, armnn::DataType::QAsymmS8, 0.1f, 0);
1582
1583 std::vector<int8_t> inputToInputWeights = { -4, -1, -1, -2, 3, -2, 2, 4, 1, -4, -2, 3 };
1584 std::vector<int8_t> inputToForgetWeights = { 2, 1, 4, -4, 3, -1, -3, -2, -3, 1, -4, -1 };
1585 std::vector<int8_t> inputToCellWeights = { -2, 1, -2, 4, -3, -2, -4, 3, -2, -2, -6, 3 };
1586 std::vector<int8_t> inputToOutputWeights = { 2, 5, -4, 5, 2, -3, 5, 7, 3, -5, 1, -4 };
1587
1588 std::vector<int8_t> recurrentToInputWeights = { -1, 1, -1, 1, -3, -4, -1, 4, 2, 3, 5, -1, 1, 3, -1, -1 };
1589 std::vector<int8_t> recurrentToForgetWeights = { -1, 1, -1, 1, -3, -4, -1, 4, 2, 3, 5, -1, 1, 3, -2, -1 };
1590 std::vector<int8_t> recurrentToCellWeights = { -2, -3, -1, -3, -4, 2, 1, -1, 2, 2, 1, 2, 3, -2, 3, -3 };
1591 std::vector<int8_t> recurrentToOutputWeights = { -3, 3, -1, -2, -2, -2, -1, -5, 1, 3, -4, -1, -1, -1, 2, -1 };
1592
1593
1594 std::vector<float> inputGateBias = { 0., 0., 0., 0. };
1595 std::vector<float> forgetGateBias = { 1., 1., 1., 1. };
1596 std::vector<float> cellBias = { 0., 0., 0., 0. };
1597 std::vector<float> outputGateBias = { 0., 0., 0., 0. };
1598
1599 armnn::ScopedTensorHandle inputToInputWeightsTensor(tensorInfoNumInput);
1600 armnn::ScopedTensorHandle inputToForgetWeightsTensor(tensorInfoNumInput);
1601 armnn::ScopedTensorHandle inputToCellWeightsTensor(tensorInfoNumInput);
1602 armnn::ScopedTensorHandle inputToOutputWeightsTensor(tensorInfoNumInput);
1603 armnn::ScopedTensorHandle recurrentToInputWeightsTensor(tensorInfoNumOutput);
1604 armnn::ScopedTensorHandle recurrentToForgetWeightsTensor(tensorInfoNumOutput);
1605 armnn::ScopedTensorHandle recurrentToCellWeightsTensor(tensorInfoNumOutput);
1606 armnn::ScopedTensorHandle recurrentToOutputWeightsTensor(tensorInfoNumOutput);
1607 armnn::ScopedTensorHandle inputGateBiasTensor(tensorInfoNumFp);
1608 armnn::ScopedTensorHandle forgetGateBiasTensor(tensorInfoNumFp);
1609 armnn::ScopedTensorHandle cellBiasTensor(tensorInfoNumFp);
1610 armnn::ScopedTensorHandle outputGateBiasTensor(tensorInfoNumFp);
1611
1612 AllocateAndCopyDataToITensorHandle(&inputToInputWeightsTensor, inputToInputWeights.data());
1613 AllocateAndCopyDataToITensorHandle(&inputToForgetWeightsTensor, inputToForgetWeights.data());
1614 AllocateAndCopyDataToITensorHandle(&inputToCellWeightsTensor, inputToCellWeights.data());
1615 AllocateAndCopyDataToITensorHandle(&inputToOutputWeightsTensor, inputToOutputWeights.data());
1616 AllocateAndCopyDataToITensorHandle(&recurrentToInputWeightsTensor, recurrentToInputWeights.data());
1617 AllocateAndCopyDataToITensorHandle(&recurrentToForgetWeightsTensor, recurrentToForgetWeights.data());
1618 AllocateAndCopyDataToITensorHandle(&recurrentToCellWeightsTensor, recurrentToCellWeights.data());
1619 AllocateAndCopyDataToITensorHandle(&recurrentToOutputWeightsTensor, recurrentToOutputWeights.data());
1620 AllocateAndCopyDataToITensorHandle(&inputGateBiasTensor, inputGateBias.data());
1621 AllocateAndCopyDataToITensorHandle(&forgetGateBiasTensor, forgetGateBias.data());
1622 AllocateAndCopyDataToITensorHandle(&cellBiasTensor, cellBias.data());
1623 AllocateAndCopyDataToITensorHandle(&outputGateBiasTensor, outputGateBias.data());
1624
1625 data.m_InputToInputWeights = &inputToInputWeightsTensor;
1626 data.m_InputToForgetWeights = &inputToForgetWeightsTensor;
1627 data.m_InputToCellWeights = &inputToCellWeightsTensor;
1628 data.m_InputToOutputWeights = &inputToOutputWeightsTensor;
1629 data.m_RecurrentToInputWeights = &recurrentToInputWeightsTensor;
1630 data.m_RecurrentToForgetWeights = &recurrentToForgetWeightsTensor;
1631 data.m_RecurrentToCellWeights = &recurrentToCellWeightsTensor;
1632 data.m_RecurrentToOutputWeights = &recurrentToOutputWeightsTensor;
1633 data.m_InputGateBias = &inputGateBiasTensor;
1634 data.m_ForgetGateBias = &forgetGateBiasTensor;
1635 data.m_CellBias = &cellBiasTensor;
1636 data.m_OutputGateBias = &outputGateBiasTensor;
1637
1638 // Flags to set test configuration
1639 data.m_Parameters.m_ClippingThresCell = 10;
1640 data.m_Parameters.m_ClippingThresProj = 0;
1641 data.m_Parameters.m_ActivationFunc = 4;
1642 data.m_Parameters.m_CifgEnabled = false;
1643 data.m_Parameters.m_PeepholeEnabled = false;
1644 data.m_Parameters.m_ProjectionEnabled = false;
1645 data.m_Parameters.m_TimeMajor = true;
1646
Teresa Charlin611c7fb2022-01-07 09:47:29 +00001647 std::unique_ptr<armnn::IWorkload> workload
1648 = workloadFactory.CreateWorkload(armnn::LayerType::UnidirectionalSequenceLstm, data, info);
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001649 inputHandle->Allocate();
1650 outputStateInHandle->Allocate();
1651 cellStateInHandle->Allocate();
1652
Mike Kelly12994962022-04-21 11:57:09 +01001653 outputStateOutHandle->Allocate();
1654 cellStateOutHandle->Allocate();
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001655 outputHandle->Allocate();
1656
1657 CopyDataToITensorHandle(inputHandle.get(), inputVector.data());
1658 CopyDataToITensorHandle(outputStateInHandle.get(), outputStateInVector.data());
1659 CopyDataToITensorHandle(cellStateInHandle.get(), cellStateInVector.data());
1660
1661 workload->Execute();
1662
Mike Kelly12994962022-04-21 11:57:09 +01001663 CopyDataFromITensorHandle(actualOutputStateOut.data(), outputStateOutHandle.get());
1664 CopyDataFromITensorHandle(actualCellStateOut.data(), cellStateOutHandle.get());
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001665 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
1666
1667 return LayerTestResult<float, 3>(actualOutput,
1668 outputVector,
1669 outputHandle->GetShape(),
1670 outputTensorInfo.GetShape());
1671}
1672
1673LayerTestResult<float, 3> UnidirectionalSequenceLstmLayerInt8NoCifgWithPeepholeWithProjectionTest(
1674 armnn::IWorkloadFactory& workloadFactory,
1675 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1676 const armnn::ITensorHandleFactory& tensorHandleFactory)
1677{
1678 IgnoreUnused(memoryManager);
1679 unsigned int batchSize = 3;
1680 unsigned int timeSize = 2;
1681 unsigned int outputSize = 4;
1682 unsigned int inputSize = 3;
1683 unsigned numUnits = 4;
1684
1685 armnn::TensorInfo inputTensorInfo({batchSize, timeSize, inputSize}, armnn::DataType::Float32);
1686 armnn::TensorInfo cellStateInTensorInfo({batchSize , numUnits}, armnn::DataType::Float32);
1687 armnn::TensorInfo outputStateInTensorInfo({batchSize , outputSize}, armnn::DataType::Float32);
Mike Kelly12994962022-04-21 11:57:09 +01001688 armnn::TensorInfo outputStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
1689 armnn::TensorInfo cellStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001690 armnn::TensorInfo outputTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
1691
1692 const std::vector<float> inputVector = { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.4f,
1693 0.3f, 0.2f, 0.1f, 0.2f, 0.3f, 0.4f,
1694 0.5f, 0.4f, 0.3f, 0.2f, 0.1f, 0.2f };
1695
1696 std::vector<float> cellStateInVector(batchSize * numUnits, 0.f);
1697 std::vector<float> outputStateInVector(batchSize * outputSize, 0.f);
1698
Mike Kelly12994962022-04-21 11:57:09 +01001699 std::vector<float> actualOutputStateOut(outputStateOutTensorInfo.GetNumElements());
1700 std::vector<float> actualCellStateOut(cellStateOutTensorInfo.GetNumElements());
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001701 std::vector<float> actualOutput(outputTensorInfo.GetNumElements());
1702
1703 const std::vector<float> expectedOutput = { 0.612103f, 1.56788f, 0.31966f, 1.42956f,
1704 0.909718f, 3.07916f, -0.560586f, 3.8907f,
1705 0.753671f, 1.77485f, 0.365122f, 1.60077f,
1706 0.812644f, 2.79092f, -0.605396f, 3.61742f,
1707 0.791857f, 1.64353f, 0.316588f, 1.55192f,
1708 0.807265f, 2.47012f, -0.539598f, 3.25654f };
1709
1710 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
1711 std::unique_ptr<armnn::ITensorHandle> cellStateInHandle =
1712 tensorHandleFactory.CreateTensorHandle(cellStateInTensorInfo);
1713 std::unique_ptr<armnn::ITensorHandle> outputStateInHandle =
1714 tensorHandleFactory.CreateTensorHandle(outputStateInTensorInfo);
Mike Kelly12994962022-04-21 11:57:09 +01001715
1716 std::unique_ptr<armnn::ITensorHandle> outputStateOutHandle =
1717 tensorHandleFactory.CreateTensorHandle(outputStateOutTensorInfo);
1718 std::unique_ptr<armnn::ITensorHandle> cellStateOutHandle =
1719 tensorHandleFactory.CreateTensorHandle(cellStateOutTensorInfo);
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001720 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
1721
1722 armnn::UnidirectionalSequenceLstmQueueDescriptor data;
1723 armnn::WorkloadInfo info;
1724
1725 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
1726 AddInputToWorkload(data, info, outputStateInTensorInfo, outputStateInHandle.get());
1727 AddInputToWorkload(data, info, cellStateInTensorInfo, cellStateInHandle.get());
Mike Kelly12994962022-04-21 11:57:09 +01001728
1729 AddOutputToWorkload(data, info, outputStateOutTensorInfo, outputStateOutHandle.get());
1730 AddOutputToWorkload(data, info, cellStateOutTensorInfo, cellStateOutHandle.get());
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001731 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
1732
1733 armnn::TensorInfo tensorInfoOut({outputSize}, armnn::DataType::Float32);
1734 armnn::TensorInfo tensorInfoNumFp({numUnits}, armnn::DataType::Float32);
1735 armnn::TensorInfo tensorInfoNum({numUnits}, armnn::DataType::QAsymmS8, 0.1f, 0);
1736 armnn::TensorInfo tensorInfoNumInput({numUnits, inputSize}, armnn::DataType::QAsymmS8, 0.1f, 0);
1737 armnn::TensorInfo tensorInfoNumOutput({numUnits, outputSize}, armnn::DataType::QAsymmS8, 0.1f, 0);
1738 armnn::TensorInfo tensorInfoOutNum({outputSize, numUnits}, armnn::DataType::QAsymmS8, 0.1f, 0);
1739
1740 std::vector<int8_t> inputToInputWeights = { -4, -1, -1, -2, 3, -2, 2, 4, 1, -4, -2, 3 };
1741 std::vector<int8_t> inputToForgetWeights = { 2, 1, 4, -4, 3, -1, -3, -2, -3, 1, -4, -1 };
1742 std::vector<int8_t> inputToCellWeights = { -2, 1, -2, 4, -3, -2, -4, 3, -2, -2, -6, 3 };
1743 std::vector<int8_t> inputToOutputWeights = { 2, 5, -4, 5, 2, -3, 5, 7, 3, -5, 1, -4 };
1744
1745 std::vector<int8_t> recurrentToInputWeights = { -1, 1, -1, 1, -3, -4, -1, 4, 2, 3, 5, -1, 1, 3, -1, -1 };
1746 std::vector<int8_t> recurrentToForgetWeights = { -1, 1, -1, 1, -3, -4, -1, 4, 2, 3, 5, -1, 1, 3, -2, -1 };
1747 std::vector<int8_t> recurrentToCellWeights = { -2, -3, -1, -3, -4, 2, 1, -1, 2, 2, 1, 2, 3, -2, 3, -3 };
1748 std::vector<int8_t> recurrentToOutputWeights = { -3, 3, -1, -2, -2, -2, -1, -5, 1, 3, -4, -1, -1, -1, 2, -1 };
1749
1750 std::vector<float> inputGateBias = { 0.02234832f, 0.14757581f, 0.18176508f, 0.10380666f};
1751 std::vector<float> forgetGateBias = { 0.035185695f, -0.042891346f, -0.3032477f, 0.23027696f};
1752 std::vector<float> cellBias = { -0.124379363f, 0.55531194f, 0.23377132f, 0.033463873f };
1753 std::vector<float> outputGateBias = { 0.046159424f, -0.12809046f, 0.03563469f, 0.12648113f };
1754
1755 std::vector<int8_t> cellToInputWeights = { 5, 10, 25, 15 };
1756 std::vector<int8_t> cellToForgetWeights = { -5, 15, 25, 3 };
1757 std::vector<int8_t> cellToOutputWeights = { 10, -10, -5, 50 };
1758
1759 std::vector<int8_t> projectionWeights = { -25, 51, 3, -5, 25, 127, 77, 20, 18, 51, -10, 51, -25, 88, 77, -13 };
1760
1761 std::vector<float> projectionBiasVector(outputSize, 0.f); //{outputSize}
1762
1763 armnn::ScopedTensorHandle inputToInputWeightsTensor(tensorInfoNumInput);
1764 armnn::ScopedTensorHandle inputToForgetWeightsTensor(tensorInfoNumInput);
1765 armnn::ScopedTensorHandle inputToCellWeightsTensor(tensorInfoNumInput);
1766 armnn::ScopedTensorHandle inputToOutputWeightsTensor(tensorInfoNumInput);
1767 armnn::ScopedTensorHandle recurrentToForgetWeightsTensor(tensorInfoNumOutput);
1768 armnn::ScopedTensorHandle recurrentToInputWeightsTensor(tensorInfoNumOutput);
1769 armnn::ScopedTensorHandle recurrentToCellWeightsTensor(tensorInfoNumOutput);
1770 armnn::ScopedTensorHandle recurrentToOutputWeightsTensor(tensorInfoNumOutput);
1771 armnn::ScopedTensorHandle cellToInputWeightsTensor(tensorInfoNum);
1772 armnn::ScopedTensorHandle inputGateBiasTensor(tensorInfoNumFp);
1773 armnn::ScopedTensorHandle forgetGateBiasTensor(tensorInfoNumFp);
1774 armnn::ScopedTensorHandle cellBiasTensor(tensorInfoNumFp);
1775 armnn::ScopedTensorHandle outputGateBiasTensor(tensorInfoNumFp);
1776 armnn::ScopedTensorHandle cellToForgetWeightsTensor(tensorInfoNum);
1777 armnn::ScopedTensorHandle cellToOutputWeightsTensor(tensorInfoNum);
1778 armnn::ScopedTensorHandle projectionWeightsTensor(tensorInfoOutNum);
1779 armnn::ScopedTensorHandle projectionBiasTensor(tensorInfoOut);
1780
1781 AllocateAndCopyDataToITensorHandle(&inputToInputWeightsTensor, inputToInputWeights.data());
1782 AllocateAndCopyDataToITensorHandle(&inputToForgetWeightsTensor, inputToForgetWeights.data());
1783 AllocateAndCopyDataToITensorHandle(&inputToCellWeightsTensor, inputToCellWeights.data());
1784 AllocateAndCopyDataToITensorHandle(&inputToOutputWeightsTensor, inputToOutputWeights.data());
1785 AllocateAndCopyDataToITensorHandle(&recurrentToInputWeightsTensor, recurrentToInputWeights.data());
1786 AllocateAndCopyDataToITensorHandle(&recurrentToForgetWeightsTensor, recurrentToForgetWeights.data());
1787 AllocateAndCopyDataToITensorHandle(&recurrentToCellWeightsTensor, recurrentToCellWeights.data());
1788 AllocateAndCopyDataToITensorHandle(&recurrentToOutputWeightsTensor, recurrentToOutputWeights.data());
1789 AllocateAndCopyDataToITensorHandle(&cellToInputWeightsTensor, cellToInputWeights.data());
1790 AllocateAndCopyDataToITensorHandle(&inputGateBiasTensor, inputGateBias.data());
1791 AllocateAndCopyDataToITensorHandle(&forgetGateBiasTensor, forgetGateBias.data());
1792 AllocateAndCopyDataToITensorHandle(&cellBiasTensor, cellBias.data());
1793 AllocateAndCopyDataToITensorHandle(&outputGateBiasTensor, outputGateBias.data());
1794 AllocateAndCopyDataToITensorHandle(&cellToForgetWeightsTensor, cellToForgetWeights.data());
1795 AllocateAndCopyDataToITensorHandle(&cellToOutputWeightsTensor, cellToOutputWeights.data());
1796 AllocateAndCopyDataToITensorHandle(&projectionWeightsTensor, projectionWeights.data());
1797 AllocateAndCopyDataToITensorHandle(&projectionBiasTensor, projectionBiasVector.data());
1798
1799 data.m_InputToInputWeights = &inputToInputWeightsTensor;
1800 data.m_InputToForgetWeights = &inputToForgetWeightsTensor;
1801 data.m_InputToCellWeights = &inputToCellWeightsTensor;
1802 data.m_InputToOutputWeights = &inputToOutputWeightsTensor;
1803 data.m_RecurrentToInputWeights = &recurrentToInputWeightsTensor;
1804 data.m_RecurrentToForgetWeights = &recurrentToForgetWeightsTensor;
1805 data.m_RecurrentToCellWeights = &recurrentToCellWeightsTensor;
1806 data.m_RecurrentToOutputWeights = &recurrentToOutputWeightsTensor;
1807 data.m_CellToInputWeights = &cellToInputWeightsTensor;
1808 data.m_InputGateBias = &inputGateBiasTensor;
1809 data.m_ForgetGateBias = &forgetGateBiasTensor;
1810 data.m_CellBias = &cellBiasTensor;
1811 data.m_OutputGateBias = &outputGateBiasTensor;
1812 data.m_CellToForgetWeights = &cellToForgetWeightsTensor;
1813 data.m_CellToOutputWeights = &cellToOutputWeightsTensor;
1814 data.m_ProjectionWeights = &projectionWeightsTensor;
1815 data.m_ProjectionBias = &projectionBiasTensor;
1816
1817 // Flags to set test configuration
1818 data.m_Parameters.m_ActivationFunc = 4;
1819 data.m_Parameters.m_CifgEnabled = false;
1820 data.m_Parameters.m_PeepholeEnabled = true;
1821 data.m_Parameters.m_ProjectionEnabled = true;
1822 data.m_Parameters.m_LayerNormEnabled = false;
1823 data.m_Parameters.m_TimeMajor = false;
1824 data.m_Parameters.m_ClippingThresCell = 10.0f;
1825
1826
Teresa Charlin611c7fb2022-01-07 09:47:29 +00001827 std::unique_ptr<armnn::IWorkload> workload
1828 = workloadFactory.CreateWorkload(armnn::LayerType::UnidirectionalSequenceLstm, data, info);
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001829 inputHandle->Allocate();
1830 outputStateInHandle->Allocate();
1831 cellStateInHandle->Allocate();
Mike Kelly12994962022-04-21 11:57:09 +01001832
1833 outputStateOutHandle->Allocate();
1834 cellStateOutHandle->Allocate();
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001835 outputHandle->Allocate();
1836
1837 CopyDataToITensorHandle(inputHandle.get(), inputVector.data());
1838 CopyDataToITensorHandle(outputStateInHandle.get(), outputStateInVector.data());
1839 CopyDataToITensorHandle(cellStateInHandle.get(), cellStateInVector.data());
1840
1841 workload->Execute();
1842
Mike Kelly12994962022-04-21 11:57:09 +01001843 CopyDataFromITensorHandle(actualOutputStateOut.data(), outputStateOutHandle.get());
1844 CopyDataFromITensorHandle(actualCellStateOut.data(), cellStateOutHandle.get());
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001845 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
1846
1847 return LayerTestResult<float, 3>(actualOutput,
1848 expectedOutput,
1849 outputHandle->GetShape(),
1850 outputTensorInfo.GetShape());
1851}
1852
1853LayerTestResult<float, 3> UnidirectionalSequenceLstmLayerInt8NoCifgWithPeepholeWithProjectionWithLayerNormTest(
1854 armnn::IWorkloadFactory& workloadFactory,
1855 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
1856 const armnn::ITensorHandleFactory& tensorHandleFactory)
1857{
1858 IgnoreUnused(memoryManager);
1859 unsigned int batchSize = 3;
1860 unsigned int timeSize = 2;
1861 unsigned int outputSize = 4;
1862 unsigned int inputSize = 3;
1863 unsigned numUnits = 5;
1864
1865 armnn::TensorInfo inputTensorInfo({batchSize, timeSize, inputSize}, armnn::DataType::Float32);
1866 armnn::TensorInfo cellStateInTensorInfo({batchSize , numUnits}, armnn::DataType::Float32);
1867 armnn::TensorInfo outputStateInTensorInfo({batchSize , outputSize}, armnn::DataType::Float32);
Mike Kelly12994962022-04-21 11:57:09 +01001868 armnn::TensorInfo outputStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
1869 armnn::TensorInfo cellStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001870 armnn::TensorInfo outputTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
1871
1872 const std::vector<float> inputVector = { 1., 8., 3., 4., 5., 4.,
1873 3., 2., 1., 2., 3., 4.,
1874 5., 4., 3., 2., 1., 2. };
1875
1876 std::vector<float> cellStateInVector(batchSize * numUnits, 0.f);
1877 std::vector<float> outputStateInVector(batchSize * outputSize, 0.f);
1878
Mike Kelly12994962022-04-21 11:57:09 +01001879 std::vector<float> actualOutputStateOut(outputStateOutTensorInfo.GetNumElements());
1880 std::vector<float> actualCellStateOut(cellStateOutTensorInfo.GetNumElements());
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001881 std::vector<float> actualOutput(outputTensorInfo.GetNumElements());
1882
1883 const std::vector<float> expectedOutput = { 0.0471276f, 0.0168155f, 0.0789885f, 0.16550f,
1884 0.0643133f, -0.0400722f, 0.100593f, 0.197722f,
1885 0.0465562f, -0.0600682f, 0.0622087f, 0.115053f,
1886 0.056287f, -0.0566218f, 0.0856832f, 0.148484f,
1887 0.0457859f, -0.0588112f, 0.0623636f, 0.114333f,
1888 0.0509271f, -0.0754262f, 0.058600f, 0.0801288f };
1889
1890 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
1891 std::unique_ptr<armnn::ITensorHandle> cellStateInHandle =
1892 tensorHandleFactory.CreateTensorHandle(cellStateInTensorInfo);
1893 std::unique_ptr<armnn::ITensorHandle> outputStateInHandle =
1894 tensorHandleFactory.CreateTensorHandle(outputStateInTensorInfo);
1895
Mike Kelly12994962022-04-21 11:57:09 +01001896 std::unique_ptr<armnn::ITensorHandle> outputStateOutHandle =
1897 tensorHandleFactory.CreateTensorHandle(outputStateOutTensorInfo);
1898 std::unique_ptr<armnn::ITensorHandle> cellStateOutHandle =
1899 tensorHandleFactory.CreateTensorHandle(cellStateOutTensorInfo);
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001900 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
1901
1902 armnn::UnidirectionalSequenceLstmQueueDescriptor data;
1903 armnn::WorkloadInfo info;
1904
1905 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
1906 AddInputToWorkload(data, info, outputStateInTensorInfo, outputStateInHandle.get());
1907 AddInputToWorkload(data, info, cellStateInTensorInfo, cellStateInHandle.get());
1908
Mike Kelly12994962022-04-21 11:57:09 +01001909 AddOutputToWorkload(data, info, outputStateOutTensorInfo, outputStateOutHandle.get());
1910 AddOutputToWorkload(data, info, cellStateOutTensorInfo, cellStateOutHandle.get());
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01001911 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
1912
1913 armnn::TensorInfo tensorInfoOut({outputSize}, armnn::DataType::Float32);
1914 armnn::TensorInfo tensorInfoNumFp({numUnits}, armnn::DataType::Float32);
1915 armnn::TensorInfo tensorInfoNum({numUnits}, armnn::DataType::QAsymmS8, 0.1f, 0);
1916 armnn::TensorInfo tensorInfoNumInput({numUnits, inputSize}, armnn::DataType::QAsymmS8, 0.1f, 0);
1917 armnn::TensorInfo tensorInfoNumOutput({numUnits, outputSize}, armnn::DataType::QAsymmS8, 0.1f, 0);
1918 armnn::TensorInfo tensorInfoOutNum({outputSize, numUnits}, armnn::DataType::QAsymmS8, 0.1f, 0);
1919
1920 std::vector<int8_t> inputToInputWeights = { -4, -1, -1, -2, 3, -2, 2, 4, 1, -4, -2, 3, 2, 2, -4 };
1921 std::vector<int8_t> inputToForgetWeights = { 2, 1, 4, -4, 3, -1, -3, -2, -3, 1, -4, -1, -3, -2, -4 };
1922 std::vector<int8_t> inputToCellWeights = { -2, 1, -2, 4, -3, -2, -4, 3, -2, -2, -6, 3, 2, 5, -4 };
1923 std::vector<int8_t> inputToOutputWeights = { 2, 5, -4, 5, 2, -3, 5, 7, 3, -5, 1, -4, -4, -1, -1 };
1924
1925 std::vector<float> inputGateBias = { 0.03f, 0.15f, 0.22f, 0.38f, 0.05f };
1926 std::vector<float> forgetGateBias = { 0.1f, -0.3f, -0.2f, 0.1f, 0.4f };
1927 std::vector<float> cellBias = { -0.05f, 0.72f, 0.25f, 0.08f, 0.1f };
1928 std::vector<float> outputGateBias = { 0.05f, -0.01f, 0.2f, 0.1f, -0.2f };
1929
1930 std::vector<int8_t> recurrentToInputWeights = { -1, 1, -1, 1, -3, -4, -1, 4, 2, 3,
1931 5, -1, 1, 3, -1, -1, -1, 4, 2, 3 };
1932
1933 std::vector<int8_t> recurrentToForgetWeights = { -1, 1, -1, 1, -3, -4, -1, 4, 2, 3,
1934 5, -1, 1, 3, -2, -1, -1, 2, 2, 1 };
1935
1936 std::vector<int8_t> recurrentToCellWeights = { -2, -3, -1, -3, -4, 2, 1, -1, 2, 2,
1937 1, 2, 3, -2, 3, -3, -1, -5, 1, 3 };
1938
1939 std::vector<int8_t> recurrentToOutputWeights = { -3, 3, -1, -2, -2, -2, -1, -5, 1, 3,
1940 -4, -1, -1, -1, 2, -1, 5, 1, -3, -4 };
1941
1942 std::vector<int8_t> cellToInputWeights = { 5, 3, 8, -5, 2 };
1943 std::vector<int8_t> cellToForgetWeights = { -2, -7, 5, -3, 4 };
1944 std::vector<int8_t> cellToOutputWeights = { 9, -10 , -5, 5, 1 };
1945
1946 std::vector<int8_t> projectionWeights = { -1, 2, 1, -2, 1, 5, 3, 8, 7, 2,
1947 -4, 2, 5, -4, 3, -2, 3, 8, -7, 2 };
1948
1949 std::vector<float> projectionBiasVector(outputSize, 0.f); //{outputSize}
1950
1951 std::vector<float> inputLayerNormWeights = { 0.1f, 0.2f, -0.3f, -0.1f, 0.5f };
1952 std::vector<float> forgetLayerNormWeights = { -0.1f, 0.2f, 0.3f, 0.5f, 0.2f };
1953 std::vector<float> cellLayerNormWeights = { 0.5f, 0.2f, 0.3f, 0.4f, -0.5f };
1954 std::vector<float> outputLayerNormWeights = { 0.6f, -0.2f, -0.2f, 0.5f, 0.1f };
1955
1956 armnn::ScopedTensorHandle inputToInputWeightsTensor(tensorInfoNumInput);
1957 armnn::ScopedTensorHandle inputToForgetWeightsTensor(tensorInfoNumInput);
1958 armnn::ScopedTensorHandle inputToCellWeightsTensor(tensorInfoNumInput);
1959 armnn::ScopedTensorHandle inputToOutputWeightsTensor(tensorInfoNumInput);
1960 armnn::ScopedTensorHandle recurrentToForgetWeightsTensor(tensorInfoNumOutput);
1961 armnn::ScopedTensorHandle recurrentToInputWeightsTensor(tensorInfoNumOutput);
1962 armnn::ScopedTensorHandle recurrentToCellWeightsTensor(tensorInfoNumOutput);
1963 armnn::ScopedTensorHandle recurrentToOutputWeightsTensor(tensorInfoNumOutput);
1964 armnn::ScopedTensorHandle cellToInputWeightsTensor(tensorInfoNum);
1965 armnn::ScopedTensorHandle inputGateBiasTensor(tensorInfoNumFp);
1966 armnn::ScopedTensorHandle forgetGateBiasTensor(tensorInfoNumFp);
1967 armnn::ScopedTensorHandle cellBiasTensor(tensorInfoNumFp);
1968 armnn::ScopedTensorHandle outputGateBiasTensor(tensorInfoNumFp);
1969 armnn::ScopedTensorHandle cellToForgetWeightsTensor(tensorInfoNum);
1970 armnn::ScopedTensorHandle cellToOutputWeightsTensor(tensorInfoNum);
1971 armnn::ScopedTensorHandle projectionWeightsTensor(tensorInfoOutNum);
1972 armnn::ScopedTensorHandle projectionBiasTensor(tensorInfoOut);
1973
1974 armnn::ScopedTensorHandle inputLayerNormWeightsTensor(tensorInfoNumFp);
1975 armnn::ScopedTensorHandle forgetLayerNormWeightsTensor(tensorInfoNumFp);
1976 armnn::ScopedTensorHandle cellLayerNormWeightsTensor(tensorInfoNumFp);
1977 armnn::ScopedTensorHandle outputLayerNormWeightsTensor(tensorInfoNumFp);
1978
1979 AllocateAndCopyDataToITensorHandle(&inputToInputWeightsTensor, inputToInputWeights.data());
1980 AllocateAndCopyDataToITensorHandle(&inputToForgetWeightsTensor, inputToForgetWeights.data());
1981 AllocateAndCopyDataToITensorHandle(&inputToCellWeightsTensor, inputToCellWeights.data());
1982 AllocateAndCopyDataToITensorHandle(&inputToOutputWeightsTensor, inputToOutputWeights.data());
1983 AllocateAndCopyDataToITensorHandle(&recurrentToInputWeightsTensor, recurrentToInputWeights.data());
1984 AllocateAndCopyDataToITensorHandle(&recurrentToForgetWeightsTensor, recurrentToForgetWeights.data());
1985 AllocateAndCopyDataToITensorHandle(&recurrentToCellWeightsTensor, recurrentToCellWeights.data());
1986 AllocateAndCopyDataToITensorHandle(&recurrentToOutputWeightsTensor, recurrentToOutputWeights.data());
1987 AllocateAndCopyDataToITensorHandle(&cellToInputWeightsTensor, cellToInputWeights.data());
1988 AllocateAndCopyDataToITensorHandle(&inputGateBiasTensor, inputGateBias.data());
1989 AllocateAndCopyDataToITensorHandle(&forgetGateBiasTensor, forgetGateBias.data());
1990 AllocateAndCopyDataToITensorHandle(&cellBiasTensor, cellBias.data());
1991 AllocateAndCopyDataToITensorHandle(&outputGateBiasTensor, outputGateBias.data());
1992 AllocateAndCopyDataToITensorHandle(&cellToForgetWeightsTensor, cellToForgetWeights.data());
1993 AllocateAndCopyDataToITensorHandle(&cellToOutputWeightsTensor, cellToOutputWeights.data());
1994 AllocateAndCopyDataToITensorHandle(&projectionWeightsTensor, projectionWeights.data());
1995 AllocateAndCopyDataToITensorHandle(&projectionBiasTensor, projectionBiasVector.data());
1996
1997 AllocateAndCopyDataToITensorHandle(&inputLayerNormWeightsTensor, inputLayerNormWeights.data());
1998 AllocateAndCopyDataToITensorHandle(&forgetLayerNormWeightsTensor, forgetLayerNormWeights.data());
1999 AllocateAndCopyDataToITensorHandle(&cellLayerNormWeightsTensor, cellLayerNormWeights.data());
2000 AllocateAndCopyDataToITensorHandle(&outputLayerNormWeightsTensor, outputLayerNormWeights.data());
2001
2002 data.m_InputToInputWeights = &inputToInputWeightsTensor;
2003 data.m_InputToForgetWeights = &inputToForgetWeightsTensor;
2004 data.m_InputToCellWeights = &inputToCellWeightsTensor;
2005 data.m_InputToOutputWeights = &inputToOutputWeightsTensor;
2006 data.m_RecurrentToInputWeights = &recurrentToInputWeightsTensor;
2007 data.m_RecurrentToForgetWeights = &recurrentToForgetWeightsTensor;
2008 data.m_RecurrentToCellWeights = &recurrentToCellWeightsTensor;
2009 data.m_RecurrentToOutputWeights = &recurrentToOutputWeightsTensor;
2010 data.m_CellToInputWeights = &cellToInputWeightsTensor;
2011 data.m_InputGateBias = &inputGateBiasTensor;
2012 data.m_ForgetGateBias = &forgetGateBiasTensor;
2013 data.m_CellBias = &cellBiasTensor;
2014 data.m_OutputGateBias = &outputGateBiasTensor;
2015 data.m_CellToForgetWeights = &cellToForgetWeightsTensor;
2016 data.m_CellToOutputWeights = &cellToOutputWeightsTensor;
2017 data.m_ProjectionWeights = &projectionWeightsTensor;
2018 data.m_ProjectionBias = &projectionBiasTensor;
2019
2020 data.m_InputLayerNormWeights = &inputLayerNormWeightsTensor;
2021 data.m_ForgetLayerNormWeights = &forgetLayerNormWeightsTensor;
2022 data.m_CellLayerNormWeights = &cellLayerNormWeightsTensor;
2023 data.m_OutputLayerNormWeights = &outputLayerNormWeightsTensor;
2024
2025 // Flags to set test configuration
2026 data.m_Parameters.m_ActivationFunc = 4;
2027 data.m_Parameters.m_CifgEnabled = false;
2028 data.m_Parameters.m_PeepholeEnabled = true;
2029 data.m_Parameters.m_ProjectionEnabled = true;
2030 data.m_Parameters.m_LayerNormEnabled = true;
2031 data.m_Parameters.m_TimeMajor = false;
2032 data.m_Parameters.m_ClippingThresCell = 10.0f;
2033
Teresa Charlin611c7fb2022-01-07 09:47:29 +00002034 std::unique_ptr<armnn::IWorkload> workload
2035 = workloadFactory.CreateWorkload(armnn::LayerType::UnidirectionalSequenceLstm, data, info);
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01002036 inputHandle->Allocate();
2037 outputStateInHandle->Allocate();
2038 cellStateInHandle->Allocate();
Mike Kelly12994962022-04-21 11:57:09 +01002039
2040 outputStateOutHandle->Allocate();
2041 cellStateOutHandle->Allocate();
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01002042 outputHandle->Allocate();
2043
2044 CopyDataToITensorHandle(inputHandle.get(), inputVector.data());
2045 CopyDataToITensorHandle(outputStateInHandle.get(), outputStateInVector.data());
2046 CopyDataToITensorHandle(cellStateInHandle.get(), cellStateInVector.data());
2047
2048 workload->Execute();
2049
Mike Kelly12994962022-04-21 11:57:09 +01002050 CopyDataFromITensorHandle(actualOutputStateOut.data(), outputStateOutHandle.get());
2051 CopyDataFromITensorHandle(actualCellStateOut.data(), cellStateOutHandle.get());
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01002052 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
2053
2054 return LayerTestResult<float, 3>(actualOutput,
2055 expectedOutput,
2056 outputHandle->GetShape(),
2057 outputTensorInfo.GetShape());
2058}
2059
2060LayerTestResult<float, 3> UnidirectionalSequenceLstmInt8WithCifgWithPeepholeNoProjectionTest(
2061 armnn::IWorkloadFactory& workloadFactory,
2062 const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
2063 const armnn::ITensorHandleFactory& tensorHandleFactory)
2064{
2065 IgnoreUnused(memoryManager);
2066 unsigned int batchSize = 3;
2067 unsigned int timeSize = 2;
2068 unsigned int inputSize = 3;
2069 unsigned int outputSize = 4;
2070 unsigned numUnits = outputSize;
2071
2072 armnn::TensorInfo inputTensorInfo({batchSize, timeSize, inputSize}, armnn::DataType::Float32);
2073 armnn::TensorInfo cellStateInTensorInfo({batchSize, numUnits}, armnn::DataType::Float32);
2074 armnn::TensorInfo outputStateInTensorInfo({batchSize, outputSize}, armnn::DataType::Float32);
Mike Kelly12994962022-04-21 11:57:09 +01002075 armnn::TensorInfo outputStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
2076 armnn::TensorInfo cellStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01002077 armnn::TensorInfo outputTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
2078
2079 const std::vector<float> inputVector = { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.4f,
2080 0.3f, 0.2f, 0.1f, 0.2f, 0.3f, 0.4f,
2081 0.5f, 0.4f, 0.3f, 0.2f, 0.1f, 0.2f };
2082
2083 std::vector<float> cellStateInVector(batchSize * numUnits, 0.f);
2084 std::vector<float> outputStateInVector(batchSize * outputSize, 0.f);
2085
Mike Kelly12994962022-04-21 11:57:09 +01002086 std::vector<float> actualOutputStateOut(outputStateOutTensorInfo.GetNumElements());
2087 std::vector<float> actualCellStateOut(cellStateOutTensorInfo.GetNumElements());
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01002088 std::vector<float> actualOutput(outputTensorInfo.GetNumElements());
2089
2090 const std::vector<float> outputVector = { -0.0072104f, -0.00991171f, -0.00650478f, -0.00713055f,
2091 -0.0191782f, -0.0161269f, -0.0233683f, -0.054299f,
2092 -0.00783725f, 0.00635271f, -0.0126718f, -0.022613f,
2093 -0.0161351f, -0.00775868f, -0.021054f, -0.0339778f,
2094 -0.0146392f, 0.00330261f, -0.0258733f, -0.0407797f,
2095 -0.0174297f, 0.0050105f, -0.0266275f, -0.0362564f };
2096
2097 std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
2098 std::unique_ptr<armnn::ITensorHandle> cellStateInHandle =
2099 tensorHandleFactory.CreateTensorHandle(cellStateInTensorInfo);
2100 std::unique_ptr<armnn::ITensorHandle> outputStateInHandle =
2101 tensorHandleFactory.CreateTensorHandle(outputStateInTensorInfo);
2102
Mike Kelly12994962022-04-21 11:57:09 +01002103 std::unique_ptr<armnn::ITensorHandle> outputStateOutHandle =
2104 tensorHandleFactory.CreateTensorHandle(outputStateOutTensorInfo);
2105 std::unique_ptr<armnn::ITensorHandle> cellStateOutHandle =
2106 tensorHandleFactory.CreateTensorHandle(cellStateOutTensorInfo);
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01002107 std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
2108
2109 armnn::UnidirectionalSequenceLstmQueueDescriptor data;
2110 armnn::WorkloadInfo info;
2111
2112 AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
2113 AddInputToWorkload(data, info, outputStateInTensorInfo, outputStateInHandle.get());
2114 AddInputToWorkload(data, info, cellStateInTensorInfo, cellStateInHandle.get());
2115
Mike Kelly12994962022-04-21 11:57:09 +01002116 AddOutputToWorkload(data, info, outputStateOutTensorInfo, outputStateOutHandle.get());
2117 AddOutputToWorkload(data, info, cellStateOutTensorInfo, cellStateOutHandle.get());
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01002118 AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
2119
2120 armnn::TensorInfo tensorInfoNumFp({numUnits}, armnn::DataType::Float32);
2121 armnn::TensorInfo tensorInfoNum({numUnits}, armnn::DataType::QAsymmS8, 0.1f, 0);
2122 armnn::TensorInfo tensorInfoNumInput({numUnits, inputSize}, armnn::DataType::QAsymmS8, 0.1f, 0);
2123 armnn::TensorInfo tensorInfoNumOutput({numUnits, outputSize}, armnn::DataType::QAsymmS8, 0.1f, 0);
2124
2125 std::vector<int8_t> inputToForgetWeights = { 2, 1, 4, -4, 3, -1, -3, -2, -3, 1, -4, -1 };
2126 std::vector<int8_t> inputToCellWeights = { -2, 1, -2, 4, -3, -2, -4, 3, -2, -2, -6, 3 };
2127 std::vector<int8_t> inputToOutputWeights = { 2, 5, -4, 5, 2, -3, 5, 7, 3, -5, 1, -4 };
2128
2129 std::vector<int8_t> recurrentToForgetWeights = { -1, 1, -1, 1, -3, -4, -1, 4, 2, 3, 5, -1, 1, 3, -2, -1 };
2130 std::vector<int8_t> recurrentToCellWeights = { -2, -3, -1, -3, -4, 2, 1, -1, 2, 2, 1, 2, 3, -2, 3, -3 };
2131 std::vector<int8_t> recurrentToOutputWeights = { -3, 3, -1, -2, -2, -2, -1, -5, 1, 3, -4, -1, -1, -1, 2, -1 };
2132
2133 std::vector<int8_t> cellToForgetWeights = { 47, -52, -24, 31 };
2134 std::vector<int8_t> cellToOutputWeights = { -17, 82, 85, -77 };
2135
2136 std::vector<float> forgetGateBias = { 1., 1., 1., 1. };
2137 std::vector<float> cellBias = { 0., 0., 0., 0. };
2138 std::vector<float> outputGateBias = { 0., 0., 0., 0. };
2139
2140 armnn::ScopedTensorHandle inputToForgetWeightsTensor(tensorInfoNumInput);
2141 armnn::ScopedTensorHandle inputToCellWeightsTensor(tensorInfoNumInput);
2142 armnn::ScopedTensorHandle inputToOutputWeightsTensor(tensorInfoNumInput);
2143 armnn::ScopedTensorHandle recurrentToForgetWeightsTensor(tensorInfoNumOutput);
2144 armnn::ScopedTensorHandle recurrentToCellWeightsTensor(tensorInfoNumOutput);
2145 armnn::ScopedTensorHandle recurrentToOutputWeightsTensor(tensorInfoNumOutput);
2146 armnn::ScopedTensorHandle cellToForgetWeightsTensor(tensorInfoNum);
2147 armnn::ScopedTensorHandle cellToOutputWeightsTensor(tensorInfoNum);
2148 armnn::ScopedTensorHandle forgetGateBiasTensor(tensorInfoNumFp);
2149 armnn::ScopedTensorHandle cellBiasTensor(tensorInfoNumFp);
2150 armnn::ScopedTensorHandle outputGateBiasTensor(tensorInfoNumFp);
2151
2152 AllocateAndCopyDataToITensorHandle(&inputToForgetWeightsTensor, inputToForgetWeights.data());
2153 AllocateAndCopyDataToITensorHandle(&inputToCellWeightsTensor, inputToCellWeights.data());
2154 AllocateAndCopyDataToITensorHandle(&inputToOutputWeightsTensor, inputToOutputWeights.data());
2155 AllocateAndCopyDataToITensorHandle(&recurrentToForgetWeightsTensor, recurrentToForgetWeights.data());
2156 AllocateAndCopyDataToITensorHandle(&recurrentToCellWeightsTensor, recurrentToCellWeights.data());
2157 AllocateAndCopyDataToITensorHandle(&recurrentToOutputWeightsTensor, recurrentToOutputWeights.data());
2158 AllocateAndCopyDataToITensorHandle(&cellToForgetWeightsTensor, cellToForgetWeights.data());
2159 AllocateAndCopyDataToITensorHandle(&cellToOutputWeightsTensor, cellToOutputWeights.data());
2160 AllocateAndCopyDataToITensorHandle(&forgetGateBiasTensor, forgetGateBias.data());
2161 AllocateAndCopyDataToITensorHandle(&cellBiasTensor, cellBias.data());
2162 AllocateAndCopyDataToITensorHandle(&outputGateBiasTensor, outputGateBias.data());
2163
2164 data.m_InputToForgetWeights = &inputToForgetWeightsTensor;
2165 data.m_InputToCellWeights = &inputToCellWeightsTensor;
2166 data.m_InputToOutputWeights = &inputToOutputWeightsTensor;
2167 data.m_RecurrentToForgetWeights = &recurrentToForgetWeightsTensor;
2168 data.m_RecurrentToCellWeights = &recurrentToCellWeightsTensor;
2169 data.m_RecurrentToOutputWeights = &recurrentToOutputWeightsTensor;
2170 data.m_CellToForgetWeights = &cellToForgetWeightsTensor;
2171 data.m_CellToOutputWeights = &cellToOutputWeightsTensor;
2172 data.m_ForgetGateBias = &forgetGateBiasTensor;
2173 data.m_CellBias = &cellBiasTensor;
2174 data.m_OutputGateBias = &outputGateBiasTensor;
2175
2176 // Flags to set test configuration
2177 data.m_Parameters.m_ClippingThresCell = 10;
2178 data.m_Parameters.m_ClippingThresProj = 0;
2179 data.m_Parameters.m_ActivationFunc = 4;
2180 data.m_Parameters.m_CifgEnabled = true;
2181 data.m_Parameters.m_PeepholeEnabled = true;
2182 data.m_Parameters.m_ProjectionEnabled = false;
2183 data.m_Parameters.m_TimeMajor = false;
2184
Teresa Charlin611c7fb2022-01-07 09:47:29 +00002185 std::unique_ptr<armnn::IWorkload> workload
2186 = workloadFactory.CreateWorkload(armnn::LayerType::UnidirectionalSequenceLstm, data, info);
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01002187 inputHandle->Allocate();
2188 outputStateInHandle->Allocate();
2189 cellStateInHandle->Allocate();
2190
Mike Kelly12994962022-04-21 11:57:09 +01002191 outputStateOutHandle->Allocate();
2192 cellStateOutHandle->Allocate();
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01002193 outputHandle->Allocate();
2194
2195 CopyDataToITensorHandle(inputHandle.get(), inputVector.data());
2196 CopyDataToITensorHandle(outputStateInHandle.get(), outputStateInVector.data());
2197 CopyDataToITensorHandle(cellStateInHandle.get(), cellStateInVector.data());
2198
2199 workload->Execute();
2200
Mike Kelly12994962022-04-21 11:57:09 +01002201 CopyDataFromITensorHandle(actualOutputStateOut.data(), outputStateOutHandle.get());
2202 CopyDataFromITensorHandle(actualCellStateOut.data(), cellStateOutHandle.get());
Narumol Prangnawaratbd575b22021-08-31 16:53:54 +01002203 CopyDataFromITensorHandle(actualOutput.data(), outputHandle.get());
2204
2205 return LayerTestResult<float, 3>(actualOutput,
2206 outputVector,
2207 outputHandle->GetShape(),
2208 outputTensorInfo.GetShape());
Mike Kelly12994962022-04-21 11:57:09 +01002209}