1 //
2 // Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #include "../DriverTestHelpers.hpp"
7
8 #include <1.3/HalPolicy.hpp>
9
10 #include <array>
11
12 using ArmnnDriver = armnn_driver::ArmnnDriver;
13 using DriverOptions = armnn_driver::DriverOptions;
14
15 using namespace driverTestHelpers;
16 using namespace android::hardware;
17
18 using HalPolicy = hal_1_3::HalPolicy;
19
20 static const float TOLERANCE = 1.0f;
21
22 namespace
23 {
24
25 template<typename T>
CreateRequestArgument(const std::vector<T> & value,unsigned int poolIndex)26 RequestArgument CreateRequestArgument(const std::vector<T>& value, unsigned int poolIndex)
27 {
28 V1_0::DataLocation inputInloc = {};
29 inputInloc.poolIndex = poolIndex;
30 inputInloc.offset = 0;
31 inputInloc.length = value.size() * sizeof(T);
32 RequestArgument inputRequestArgument = {};
33 inputRequestArgument.location = inputInloc;
34 inputRequestArgument.dimensions = hidl_vec<uint32_t>{};
35 return inputRequestArgument;
36 }
37
38 // Helper function to create an OperandLifeTime::NO_VALUE for testing.
39 // To be used on optional input operands that have no values - these are valid and should be tested.
CreateNoValueLifeTime(const hidl_vec<uint32_t> & dimensions)40 HalPolicy::OperandLifeTime CreateNoValueLifeTime(const hidl_vec<uint32_t>& dimensions)
41 {
42 // Only create a NO_VALUE for optional operands that have no elements
43 if (dimensions.size() == 0 || dimensions[0] == 0)
44 {
45 return HalPolicy::OperandLifeTime::NO_VALUE;
46 }
47 return HalPolicy::OperandLifeTime::CONSTANT_COPY;
48 }
49
ExecuteModel(const armnn_driver::hal_1_3::HalPolicy::Model & model,armnn_driver::ArmnnDriver & driver,const V1_0::Request & request)50 void ExecuteModel(const armnn_driver::hal_1_3::HalPolicy::Model& model,
51 armnn_driver::ArmnnDriver& driver,
52 const V1_0::Request& request)
53 {
54 android::sp<V1_3::IPreparedModel> preparedModel = PrepareModel_1_3(model, driver);
55 if (preparedModel.get() != nullptr)
56 {
57 Execute(preparedModel, request);
58 }
59 }
60
61 // Add our own tests here since we skip the qlstm tests which Google supplies (because of non-const weights)
QLstmTestImpl(const hidl_vec<uint32_t> & inputDimensions,const std::vector<int8_t> & inputValue,const hidl_vec<uint32_t> & inputToInputWeightsDimensions,const std::vector<int8_t> & inputToInputWeightsValue,const hidl_vec<uint32_t> & inputToForgetWeightsDimensions,const std::vector<int8_t> & inputToForgetWeightsValue,const hidl_vec<uint32_t> & inputToCellWeightsDimensions,const std::vector<int8_t> & inputToCellWeightsValue,const hidl_vec<uint32_t> & inputToOutputWeightsDimensions,const std::vector<int8_t> & inputToOutputWeightsValue,const hidl_vec<uint32_t> & recurrentToInputWeightsDimensions,const std::vector<int8_t> & recurrentToInputWeightsValue,const hidl_vec<uint32_t> & recurrentToForgetWeightsDimensions,const std::vector<int8_t> & recurrentToForgetWeightsValue,const hidl_vec<uint32_t> & recurrentToCellWeightsDimensions,const std::vector<int8_t> & recurrentToCellWeightsValue,const hidl_vec<uint32_t> & recurrentToOutputWeightsDimensions,const std::vector<int8_t> & recurrentToOutputWeightsValue,const hidl_vec<uint32_t> & cellToInputWeightsDimensions,const std::vector<int16_t> & cellToInputWeightsValue,const hidl_vec<uint32_t> & cellToForgetWeightsDimensions,const std::vector<int16_t> & cellToForgetWeightsValue,const hidl_vec<uint32_t> & cellToOutputWeightsDimensions,const std::vector<int16_t> & cellToOutputWeightsValue,const hidl_vec<uint32_t> & inputGateBiasDimensions,const std::vector<int32_t> & inputGateBiasValue,const hidl_vec<uint32_t> & forgetGateBiasDimensions,const std::vector<int32_t> & forgetGateBiasValue,const hidl_vec<uint32_t> & cellBiasDimensions,const std::vector<int32_t> & cellBiasValue,const hidl_vec<uint32_t> & outputGateBiasDimensions,const std::vector<int32_t> & outputGateBiasValue,const hidl_vec<uint32_t> & projectionWeightsDimensions,const std::vector<int8_t> & projectionWeightsValue,const hidl_vec<uint32_t> & projectionBiasDimensions,const std::vector<int32_t> & projectionBiasValue,const hidl_vec<uint32_t> & outputPreviousTimeStepInDimensions,const std::vector<int8_t> & outputPreviousTimeStepInValue,const hidl_vec<uint32_t> & cellStatePreviousTimeStepInDimensions,const std::vector<int16_t> & cellStatePreviousTimeStepInValue,const hidl_vec<uint32_t> & inputLayerNormWeightsDimensions,const std::vector<int16_t> & inputLayerNormWeightsValue,const hidl_vec<uint32_t> & forgetLayerNormWeightsDimensions,const std::vector<int16_t> & forgetLayerNormWeightsValue,const hidl_vec<uint32_t> & cellLayerNormWeightsDimensions,const std::vector<int16_t> & cellLayerNormWeightsValue,const hidl_vec<uint32_t> & outputLayerNormWeightsDimensions,const std::vector<int16_t> & outputLayerNormWeightsValue,const float & cellClipValue,const float & projectionClipValue,const float & matMulInputGateValue,const float & matMulForgetGateValue,const float & matMulCellGateValue,const float & matMulOutputGateValue,const int32_t & projInputZeroPointValue,const float & projInputScaleValue,const hidl_vec<uint32_t> & outputStateOutDimensions,const std::vector<int8_t> & outputStateOutValue,const hidl_vec<uint32_t> & cellStateOutDimensions,const std::vector<int16_t> & cellStateOutValue,const hidl_vec<uint32_t> & outputDimensions,const std::vector<int8_t> & outputValue,armnn::Compute compute)62 void QLstmTestImpl(const hidl_vec<uint32_t>& inputDimensions,
63 const std::vector<int8_t>& inputValue,
64 const hidl_vec<uint32_t>& inputToInputWeightsDimensions,
65 const std::vector<int8_t>& inputToInputWeightsValue,
66 const hidl_vec<uint32_t>& inputToForgetWeightsDimensions,
67 const std::vector<int8_t>& inputToForgetWeightsValue,
68 const hidl_vec<uint32_t>& inputToCellWeightsDimensions,
69 const std::vector<int8_t>& inputToCellWeightsValue,
70 const hidl_vec<uint32_t>& inputToOutputWeightsDimensions,
71 const std::vector<int8_t>& inputToOutputWeightsValue,
72 const hidl_vec<uint32_t>& recurrentToInputWeightsDimensions,
73 const std::vector<int8_t>& recurrentToInputWeightsValue,
74 const hidl_vec<uint32_t>& recurrentToForgetWeightsDimensions,
75 const std::vector<int8_t>& recurrentToForgetWeightsValue,
76 const hidl_vec<uint32_t>& recurrentToCellWeightsDimensions,
77 const std::vector<int8_t>& recurrentToCellWeightsValue,
78 const hidl_vec<uint32_t>& recurrentToOutputWeightsDimensions,
79 const std::vector<int8_t>& recurrentToOutputWeightsValue,
80 const hidl_vec<uint32_t>& cellToInputWeightsDimensions,
81 const std::vector<int16_t>& cellToInputWeightsValue,
82 const hidl_vec<uint32_t>& cellToForgetWeightsDimensions,
83 const std::vector<int16_t>& cellToForgetWeightsValue,
84 const hidl_vec<uint32_t>& cellToOutputWeightsDimensions,
85 const std::vector<int16_t>& cellToOutputWeightsValue,
86 const hidl_vec<uint32_t>& inputGateBiasDimensions,
87 const std::vector<int32_t>& inputGateBiasValue,
88 const hidl_vec<uint32_t>& forgetGateBiasDimensions,
89 const std::vector<int32_t>& forgetGateBiasValue,
90 const hidl_vec<uint32_t>& cellBiasDimensions,
91 const std::vector<int32_t>& cellBiasValue,
92 const hidl_vec<uint32_t>& outputGateBiasDimensions,
93 const std::vector<int32_t>& outputGateBiasValue,
94 const hidl_vec<uint32_t>& projectionWeightsDimensions,
95 const std::vector<int8_t>& projectionWeightsValue,
96 const hidl_vec<uint32_t>& projectionBiasDimensions,
97 const std::vector<int32_t>& projectionBiasValue,
98 const hidl_vec<uint32_t>& outputPreviousTimeStepInDimensions,
99 const std::vector<int8_t>& outputPreviousTimeStepInValue,
100 const hidl_vec<uint32_t>& cellStatePreviousTimeStepInDimensions,
101 const std::vector<int16_t>& cellStatePreviousTimeStepInValue,
102 const hidl_vec<uint32_t>& inputLayerNormWeightsDimensions,
103 const std::vector<int16_t>& inputLayerNormWeightsValue,
104 const hidl_vec<uint32_t>& forgetLayerNormWeightsDimensions,
105 const std::vector<int16_t>& forgetLayerNormWeightsValue,
106 const hidl_vec<uint32_t>& cellLayerNormWeightsDimensions,
107 const std::vector<int16_t>& cellLayerNormWeightsValue,
108 const hidl_vec<uint32_t>& outputLayerNormWeightsDimensions,
109 const std::vector<int16_t>& outputLayerNormWeightsValue,
110 const float& cellClipValue,
111 const float& projectionClipValue,
112 const float& matMulInputGateValue,
113 const float& matMulForgetGateValue,
114 const float& matMulCellGateValue,
115 const float& matMulOutputGateValue,
116 const int32_t& projInputZeroPointValue,
117 const float& projInputScaleValue,
118 const hidl_vec<uint32_t>& outputStateOutDimensions,
119 const std::vector<int8_t>& outputStateOutValue,
120 const hidl_vec<uint32_t>& cellStateOutDimensions,
121 const std::vector<int16_t>& cellStateOutValue,
122 const hidl_vec<uint32_t>& outputDimensions,
123 const std::vector<int8_t>& outputValue,
124 armnn::Compute compute)
125 {
126 auto driver = std::make_unique<ArmnnDriver>(DriverOptions(compute));
127 HalPolicy::Model model = {};
128
129 // Scale/Offset quantization info
130 float inputScale = 0.0078125f;
131 int32_t inputOffset = 0;
132
133 int32_t hiddenStateZeroPoint = 0;
134 float hiddenStateScale = 0.007f;
135
136 float outputScale = hiddenStateScale;
137 int32_t outputOffset = hiddenStateZeroPoint;
138
139 float cellStateScale = 3.05176e-05f;
140 float cellWeightsScale = 1.0f;
141 int32_t cellStateOffset = 0;
142
143 float weightsScale = 0.00784314f;
144 int32_t weightsOffset = 0;
145
146 float layerNormScale = 3.05182e-05f;
147 int32_t layerNormOffset = 0;
148
149 float biasScale = layerNormScale / 1024;
150 int32_t biasOffset = 0;
151
152 // Inputs:
153 // 00: The input to the LSTM cell. Type: ANEURALNETWORKS_TENSOR_QUANT8_ASYMM_SIGNED Shape: [batchSize, inputSize]
154 AddInputOperand<HalPolicy>(model,
155 inputDimensions,
156 HalPolicy::OperandType::TENSOR_QUANT8_ASYMM_SIGNED,
157 inputScale,
158 inputOffset);
159
160 // 01: The input-to-input weights. Optional. Type: ANEURALNETWORKS_TENSOR_QUANT8_SYMM Shape: [numUnits, inputSize]
161 AddTensorOperand<HalPolicy>(model,
162 inputToInputWeightsDimensions,
163 inputToInputWeightsValue,
164 HalPolicy::OperandType::TENSOR_QUANT8_SYMM,
165 CreateNoValueLifeTime(inputToInputWeightsDimensions),
166 weightsScale,
167 weightsOffset);
168
169 // 02: The input-to-forget weights. Type: ANEURALNETWORKS_TENSOR_QUANT8_SYMM Shape: [numUnits, inputSize]
170 AddTensorOperand<HalPolicy>(model,
171 inputToForgetWeightsDimensions,
172 inputToForgetWeightsValue,
173 HalPolicy::OperandType::TENSOR_QUANT8_SYMM,
174 CreateNoValueLifeTime(inputToForgetWeightsDimensions),
175 weightsScale,
176 weightsOffset);
177
178 // 03: The input-to-cell weights. Type: ANEURALNETWORKS_TENSOR_QUANT8_SYMM Shape: [numUnits, inputSize]
179 AddTensorOperand<HalPolicy>(model,
180 inputToCellWeightsDimensions,
181 inputToCellWeightsValue,
182 HalPolicy::OperandType::TENSOR_QUANT8_SYMM,
183 CreateNoValueLifeTime(inputToCellWeightsDimensions),
184 weightsScale,
185 weightsOffset);
186
187 // 04: The input-to-output weights. Type: ANEURALNETWORKS_TENSOR_QUANT8_SYMM Shape: [numUnits, inputSize]
188 AddTensorOperand<HalPolicy>(model,
189 inputToOutputWeightsDimensions,
190 inputToOutputWeightsValue,
191 HalPolicy::OperandType::TENSOR_QUANT8_SYMM,
192 CreateNoValueLifeTime(inputToOutputWeightsDimensions),
193 weightsScale,
194 weightsOffset);
195
196 // 05: The recurrent-to-input weights. Optional. Type: ANEURALNETWORKS_TENSOR_QUANT8_SYMM
197 // Shape: [numUnits, outputSize]
198 AddTensorOperand<HalPolicy>(model,
199 recurrentToInputWeightsDimensions,
200 recurrentToInputWeightsValue,
201 HalPolicy::OperandType::TENSOR_QUANT8_SYMM,
202 CreateNoValueLifeTime(recurrentToInputWeightsDimensions),
203 weightsScale,
204 weightsOffset);
205
206 // 06: The recurrent-to-forget weights. Type: ANEURALNETWORKS_TENSOR_QUANT8_SYMM Shape: [numUnits, outputSize]
207 AddTensorOperand<HalPolicy>(model,
208 recurrentToForgetWeightsDimensions,
209 recurrentToForgetWeightsValue,
210 HalPolicy::OperandType::TENSOR_QUANT8_SYMM,
211 CreateNoValueLifeTime(recurrentToForgetWeightsDimensions),
212 weightsScale,
213 weightsOffset);
214
215 // 07: The recurrent-to-cell weights. Type: ANEURALNETWORKS_TENSOR_QUANT8_SYMM Shape: [numUnits, outputSize]
216 AddTensorOperand<HalPolicy>(model,
217 recurrentToCellWeightsDimensions,
218 recurrentToCellWeightsValue,
219 HalPolicy::OperandType::TENSOR_QUANT8_SYMM,
220 CreateNoValueLifeTime(recurrentToCellWeightsDimensions),
221 weightsScale,
222 weightsOffset);
223
224 // 08: The recurrent-to-output weights. Type: ANEURALNETWORKS_TENSOR_QUANT8_SYMM Shape: [numUnits, outputSize]
225 AddTensorOperand<HalPolicy>(model,
226 recurrentToOutputWeightsDimensions,
227 recurrentToOutputWeightsValue,
228 HalPolicy::OperandType::TENSOR_QUANT8_SYMM,
229 CreateNoValueLifeTime(recurrentToOutputWeightsDimensions),
230 weightsScale,
231 weightsOffset);
232
233 // 09: The cell-to-input weights (for peephole). Optional. Type: ANEURALNETWORKS_TENSOR_QUANT16_SYMM
234 // Shape: [numUnits]
235 AddTensorOperand<HalPolicy>(model,
236 cellToInputWeightsDimensions,
237 cellToInputWeightsValue,
238 HalPolicy::OperandType::TENSOR_QUANT16_SYMM ,
239 CreateNoValueLifeTime(cellToInputWeightsDimensions),
240 cellWeightsScale,
241 weightsOffset);
242
243 // 10: The cell-to-forget weights (for peephole). Optional. Type: ANEURALNETWORKS_TENSOR_QUANT16_SYMM
244 // Shape: [numUnits].
245 AddTensorOperand<HalPolicy>(model,
246 cellToForgetWeightsDimensions,
247 cellToForgetWeightsValue,
248 HalPolicy::OperandType::TENSOR_QUANT16_SYMM,
249 CreateNoValueLifeTime(cellToForgetWeightsDimensions),
250 cellWeightsScale,
251 weightsOffset);
252
253 // 11: The cell-to-output weights (for peephole). Optional. Type: ANEURALNETWORKS_TENSOR_QUANT16_SYMM
254 // Shape: [numUnits]
255 AddTensorOperand<HalPolicy>(model,
256 cellToOutputWeightsDimensions,
257 cellToOutputWeightsValue,
258 HalPolicy::OperandType::TENSOR_QUANT16_SYMM,
259 CreateNoValueLifeTime(cellToOutputWeightsDimensions),
260 cellWeightsScale,
261 weightsOffset);
262
263 // 12: The input gate bias. Quantized with scale being the product of input and weights scales
264 // and zeroPoint equal to 0. Optional. Type: ANEURALNETWORKS_TENSOR_INT32 Shape: [numUnits]
265 AddTensorOperand<HalPolicy>(model,
266 inputGateBiasDimensions,
267 inputGateBiasValue,
268 HalPolicy::OperandType::TENSOR_INT32,
269 CreateNoValueLifeTime(inputGateBiasDimensions),
270 biasScale,
271 biasOffset);
272
273 // 13: The forget gate bias. Quantized with scale being the product of input and weights scales
274 // and zeroPoint equal to 0. Type: ANEURALNETWORKS_TENSOR_INT32 Shape: [numUnits]
275 AddTensorOperand<HalPolicy>(model,
276 forgetGateBiasDimensions,
277 forgetGateBiasValue,
278 HalPolicy::OperandType::TENSOR_INT32,
279 CreateNoValueLifeTime(forgetGateBiasDimensions),
280 biasScale,
281 biasOffset);
282
283 // 14: The cell bias. Quantized with scale being the product of input and weights scales and zeroPoint equal to 0.
284 // Type: ANEURALNETWORKS_TENSOR_INT32 Shape: [numUnits]
285 AddTensorOperand<HalPolicy>(model,
286 cellBiasDimensions,
287 cellBiasValue,
288 HalPolicy::OperandType::TENSOR_INT32,
289 CreateNoValueLifeTime(cellBiasDimensions),
290 biasScale,
291 biasOffset);
292
293 // 15: The output gate bias. Quantized with scale being the product of input and weights scales
294 // and zeroPoint equal to 0. Type: ANEURALNETWORKS_TENSOR_INT32 Shape: [numUnits]
295 AddTensorOperand<HalPolicy>(model,
296 outputGateBiasDimensions,
297 outputGateBiasValue,
298 HalPolicy::OperandType::TENSOR_INT32,
299 CreateNoValueLifeTime(outputGateBiasDimensions),
300 biasScale,
301 biasOffset);
302
303 // 16: The projection weights. Optional. Type: ANEURALNETWORKS_TENSOR_QUANT8_SYMM Shape: [outputSize, numUnits]
304 AddTensorOperand<HalPolicy>(model,
305 projectionWeightsDimensions,
306 projectionWeightsValue,
307 HalPolicy::OperandType::TENSOR_QUANT8_SYMM,
308 CreateNoValueLifeTime(projectionWeightsDimensions),
309 0.00392157f,
310 weightsOffset);
311
312 // 17: The projection bias. Quantized with scale being the product of input and weights scales
313 // and zeroPoint equal to 0. Optional. Type: ANEURALNETWORKS_TENSOR_INT32 Shape: [outputSize]
314 AddTensorOperand<HalPolicy>(model,
315 projectionBiasDimensions,
316 projectionBiasValue,
317 HalPolicy::OperandType::TENSOR_INT32,
318 CreateNoValueLifeTime(projectionBiasDimensions),
319 0.0f,
320 biasOffset);
321
322 // 18: The output from the previous time step. Type: ANEURALNETWORKS_TENSOR_QUANT8_ASYMM_SIGNED
323 // Shape: [batchSize, outputSize]
324 AddInputOperand<HalPolicy>(model,
325 outputPreviousTimeStepInDimensions,
326 HalPolicy::OperandType::TENSOR_QUANT8_ASYMM_SIGNED,
327 cellStateScale,
328 inputOffset);
329
330 // 19: The cell state from the previous time step. Type: ANEURALNETWORKS_TENSOR_QUANT16_SYMM
331 // Shape: [batchSize, numUnits]
332 AddInputOperand<HalPolicy>(model,
333 cellStatePreviousTimeStepInDimensions,
334 HalPolicy::OperandType::TENSOR_QUANT16_SYMM,
335 cellStateScale,
336 cellStateOffset);
337
338 // If any of the tensors have a value all normalization tensors are set
339 if (!inputLayerNormWeightsValue.empty() ||
340 !forgetLayerNormWeightsValue.empty() ||
341 !cellLayerNormWeightsValue.empty() ||
342 !outputLayerNormWeightsValue.empty())
343 {
344 // Normalization:
345 // 20: The input layer normalization weights. Used to rescale normalized inputs to activation at input gate.
346 // Optional. Type: ANEURALNETWORKS_TENSOR_QUANT16_SYMM Shape: [numUnits]
347 AddTensorOperand<HalPolicy>(model,
348 inputLayerNormWeightsDimensions,
349 inputLayerNormWeightsValue,
350 HalPolicy::OperandType::TENSOR_QUANT16_SYMM,
351 CreateNoValueLifeTime(inputLayerNormWeightsDimensions),
352 layerNormScale,
353 layerNormOffset);
354
355 // 21: The forget layer normalization weights. Used to rescale normalized inputs to activation at forget gate.
356 // Optional. Type: ANEURALNETWORKS_TENSOR_QUANT16_SYMM Shape: [numUnits]
357 AddTensorOperand<HalPolicy>(model,
358 forgetLayerNormWeightsDimensions,
359 forgetLayerNormWeightsValue,
360 HalPolicy::OperandType::TENSOR_QUANT16_SYMM,
361 CreateNoValueLifeTime(forgetLayerNormWeightsDimensions),
362 layerNormScale,
363 layerNormOffset);
364
365 // 22: The cell layer normalization weights. Used to rescale normalized inputs to activation at cell gate.
366 // Optional. Type: ANEURALNETWORKS_TENSOR_QUANT16_SYMM Shape: [numUnits]
367 AddTensorOperand<HalPolicy>(model,
368 cellLayerNormWeightsDimensions,
369 cellLayerNormWeightsValue,
370 HalPolicy::OperandType::TENSOR_QUANT16_SYMM,
371 CreateNoValueLifeTime(cellLayerNormWeightsDimensions),
372 layerNormScale,
373 layerNormOffset);
374
375 // 23: The output layer normalization weights. Used to rescale normalized inputs to activation at output gate.
376 // Optional. Type: ANEURALNETWORKS_TENSOR_QUANT16_SYMM Shape: [numUnits]
377 AddTensorOperand<HalPolicy>(model,
378 outputLayerNormWeightsDimensions,
379 outputLayerNormWeightsValue,
380 HalPolicy::OperandType::TENSOR_QUANT16_SYMM,
381 CreateNoValueLifeTime(outputLayerNormWeightsDimensions),
382 layerNormScale,
383 layerNormOffset);
384 }
385
386 // Constant scalar values
387 // 24: The cell clip. If provided the cell state is clipped by this value prior to the cell output activation.
388 // Optional. Type: ANEURALNETWORKS_FLOAT32.
389 AddFloatOperand<HalPolicy>(model, cellClipValue);
390
391 // Constant scalar values
392 // 25: The projection clip. If provided and projection is enabled, this is used for clipping the projected values.
393 // Optional. Type: ANEURALNETWORKS_FLOAT32.
394 AddFloatOperand<HalPolicy>(model, projectionClipValue);
395
396 // Constant scalar values
397 // 26: The scale of the intermediate result of matmul, i.e. input to layer normalization, at input gate.
398 // Type: ANEURALNETWORKS_FLOAT32.
399 AddFloatOperand<HalPolicy>(model, matMulInputGateValue);
400
401 // Constant scalar values
402 // 27: The scale of the intermediate result of matmul, i.e. input to layer normalization, at forget gate.
403 // Type: ANEURALNETWORKS_FLOAT32.
404 AddFloatOperand<HalPolicy>(model, matMulForgetGateValue);
405
406 // Constant scalar values
407 // 28: The scale of the intermediate result of matmul, i.e. input to layer normalization, at cell gate.
408 // Type: ANEURALNETWORKS_FLOAT32.
409 AddFloatOperand<HalPolicy>(model, matMulCellGateValue);
410
411 // Constant scalar values
412 // 29: The scale of the intermediate result of matmul, i.e. input to layer normalization, at output gate.
413 // Type: ANEURALNETWORKS_FLOAT32.
414 AddFloatOperand<HalPolicy>(model, matMulOutputGateValue);
415
416 // Constant scalar values
417 // 30: The zero point of the hidden state, i.e. input to projection. Type: ANEURALNETWORKS_INT32.
418 AddIntOperand<HalPolicy>(model, projInputZeroPointValue);
419
420 // Constant scalar values
421 // 31: The scale of the hidden state, i.e. input to projection. Type: ANEURALNETWORKS_FLOAT32.
422 AddFloatOperand<HalPolicy>(model, projInputScaleValue);
423
424 // Outputs:
425 // 0: The output state (out). Type: ANEURALNETWORKS_TENSOR_QUANT8_ASYMM_SIGNED Shape: [batchSize, outputSize]
426 AddOutputOperand<HalPolicy>(model,
427 outputStateOutDimensions,
428 HalPolicy::OperandType::TENSOR_QUANT8_ASYMM_SIGNED,
429 cellStateScale,
430 cellStateScale);
431
432 // 1: The cell state (out). Type: ANEURALNETWORKS_TENSOR_QUANT16_SYMM Shape: [batchSize, numUnits].
433 AddOutputOperand<HalPolicy>(model,
434 cellStateOutDimensions,
435 HalPolicy::OperandType::TENSOR_QUANT16_SYMM,
436 cellStateScale,
437 cellStateOffset);
438
439 // 2: The output. This is effectively the same as the current "output state (out)" value.
440 // Type: ANEURALNETWORKS_TENSOR_QUANT8_ASYMM_SIGNED Shape: [batchSize, outputSize]
441 AddOutputOperand<HalPolicy>(model,
442 outputDimensions,
443 HalPolicy::OperandType::TENSOR_QUANT8_ASYMM_SIGNED,
444 cellStateScale,
445 cellStateScale);
446
447 // make the QUANTIZED_LSTM operation
448 model.main.operations.resize(1);
449 model.main.operations[0].type = HalPolicy::OperationType::QUANTIZED_LSTM;
450
451 model.main.operations[0].inputs = hidl_vec<uint32_t> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
452 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
453 24, 25, 26, 27, 28, 29, 30, 31};
454 model.main.operations[0].outputs = hidl_vec<uint32_t> {32, 33, 34};
455
456 // define the input values
457 hidl_vec<RequestArgument> inputArguments;
458 inputArguments.resize(3);
459
460 inputArguments[0] = CreateRequestArgument<int8_t>(inputValue, 0);
461 inputArguments[1] = CreateRequestArgument<int8_t>(outputPreviousTimeStepInValue, 1);
462 inputArguments[2] = CreateRequestArgument<int16_t>(cellStatePreviousTimeStepInValue, 2);
463
464 // define the expected output values
465 hidl_vec<RequestArgument> outputArguments;
466 outputArguments.resize(3);
467
468 outputArguments[0] = CreateRequestArgument<int8_t>(outputStateOutValue, 3);
469 outputArguments[1] = CreateRequestArgument<int16_t>(cellStateOutValue, 4);
470 outputArguments[2] = CreateRequestArgument<int8_t>(outputValue, 5);
471
472 android::hardware::neuralnetworks::V1_0::Request request = {};
473 request.inputs = inputArguments;
474 request.outputs = outputArguments;
475
476 // set the input data
477 AddPoolAndSetData(inputValue.size(), request, inputValue.data());
478 AddPoolAndSetData(outputPreviousTimeStepInValue.size(), request, outputPreviousTimeStepInValue.data());
479 AddPoolAndSetData(cellStatePreviousTimeStepInValue.size(), request, cellStatePreviousTimeStepInValue.data());
480
481 // add memory for the outputs
482 android::sp<IMemory> outputStateOutMemory = AddPoolAndGetData<int8_t>(outputStateOutValue.size(), request);
483 int8_t* outputStateOutData = static_cast<int8_t*>(static_cast<void*>(outputStateOutMemory->getPointer()));
484
485 android::sp<IMemory> cellStateOutMemory = AddPoolAndGetData<int16_t>(cellStateOutValue.size(), request);
486 int16_t* cellStateOutData = static_cast<int16_t*>(static_cast<void*>(cellStateOutMemory->getPointer()));
487
488 android::sp<IMemory> outputMemory = AddPoolAndGetData<int8_t>(outputValue.size(), request);
489 int8_t* outputData = static_cast<int8_t*>(static_cast<void*>(outputMemory->getPointer()));
490
491 // make the prepared model and run the execution
492 ExecuteModel(model, *driver, request);
493
494 // check the results
495 for (size_t i = 0; i < outputStateOutValue.size(); ++i)
496 {
497 DOCTEST_CHECK_MESSAGE(outputStateOutValue[i] == doctest::Approx( outputStateOutData[i] ).epsilon(TOLERANCE),
498 "outputStateOut[" << i << "]: " << outputStateOutValue[i] << " != "
499 << outputStateOutData[i]);
500 }
501
502 // CELL STATE OUTPUT Does not match currently: IVGCVSW-4860 Verify remaining VTS tests (2) for QLSTM
503 // Comment out for now
504 // for (size_t i = 0; i < cellStateOutValue.size(); ++i)
505 // {
506 // BOOST_TEST(TolerantCompareEqual(cellStateOutValue[i], cellStateOutData[i]),
507 // "cellStateOut[" << i << "]: " << cellStateOutValue[i] << " != " << cellStateOutData[i]);
508 //}
509
510 for (size_t i = 0; i < outputValue.size(); ++i)
511 {
512 DOCTEST_CHECK_MESSAGE(outputValue[i] == doctest::Approx( outputData[i] ).epsilon(TOLERANCE),
513 "output[" << i << "]: " << outputValue[i] << " != " << outputData[i]);
514 }
515 }
516
QLstmWithProjection(armnn::Compute compute)517 void QLstmWithProjection(armnn::Compute compute)
518 {
519 // This replicates android/frameworks/ml/nn/runtime/test/specs/V1_3/qlstm_projection.mod.py
520 // with values from android/frameworks/ml/nn/runtime/test/generated/spec_V1_3/qlstm_projection.example.cpp
521 // and weights, biases and scalars passed as CONSTANT_COPY tensors (instead of SUBGRAPH_INPUT tensors).
522
523 uint32_t batchSize = 2;
524 uint32_t inputSize = 5;
525 uint32_t outputSize = 3;
526 uint32_t numUnits = 4;
527
528 // Inputs:
529 hidl_vec<uint32_t> inputDimensions{batchSize, inputSize};
530 std::vector<int8_t> inputValue{ 90, 102, 13, 26, 38, 102, 13, 26, 51, 64};
531
532 hidl_vec<uint32_t> inputToInputWeightsDimensions{numUnits, inputSize};
533 std::vector<int8_t> inputToInputWeightsValue{ 64, 77, 89, -102,
534 -115, 13, 25, 38,
535 -51, 64, -102, 89,
536 -77, 64, -51, -64,
537 -51, -38, -25, -13 };
538
539 hidl_vec<uint32_t> inputToForgetWeightsDimensions{numUnits, inputSize};
540 std::vector<int8_t> inputToForgetWeightsValue{ -77, -13, 38, 25,
541 115, -64, -25, -51,
542 38, -102, -51, 38,
543 -64, -51, -77, 38,
544 -51, -77, -64, -64 };
545
546 hidl_vec<uint32_t> inputToCellWeightsDimensions{numUnits, inputSize};
547 std::vector<int8_t> inputToCellWeightsValue{ -51, -38, -25, -13,
548 -64, 64, -25, -38,
549 -25, -77, 77, -13,
550 -51, -38, -89, 89,
551 -115, -64, 102, 77 };
552
553 hidl_vec<uint32_t> inputToOutputWeightsDimensions{numUnits, inputSize};
554 std::vector<int8_t> inputToOutputWeightsValue{ -102, -51, -25, -115,
555 -13, -89, 38, -38,
556 -102, -25, 77, -25,
557 51, -89, -38, -64,
558 13, 64, -77, -51 };
559
560 hidl_vec<uint32_t> recurrentToInputWeightsDimensions{numUnits, outputSize};
561 std::vector<int8_t> recurrentToInputWeightsValue{ -25, -38, 51, 13, -64, 115, -25, -38, -89, 6, -25, -77 };
562
563 hidl_vec<uint32_t> recurrentToForgetWeightsDimensions{numUnits, outputSize};
564 std::vector<int8_t> recurrentToForgetWeightsValue{ -64, -38, -64, -25, 77, 51, 115, 38, -13, 25, 64, 25 };
565
566 hidl_vec<uint32_t> recurrentToCellWeightsDimensions{numUnits, outputSize};
567 std::vector<int8_t> recurrentToCellWeightsValue{ -38, 25, 13, -38, 102, -10, -25, 38, 102, -77, -13, 25 };
568
569 hidl_vec<uint32_t> recurrentToOutputWeightsDimensions{numUnits, outputSize};
570 std::vector<int8_t> recurrentToOutputWeightsValue{ 38, -13, 13, -25, -64, -89, -25, -77, -13, -51, -89, -25 };
571
572 hidl_vec<uint32_t> cellToInputWeightsDimensions{0};
573 std::vector<int16_t> cellToInputWeightsValue;
574
575 hidl_vec<uint32_t> cellToForgetWeightsDimensions{0};
576 std::vector<int16_t> cellToForgetWeightsValue;
577
578 hidl_vec<uint32_t> cellToOutputWeightsDimensions{0};
579 std::vector<int16_t> cellToOutputWeightsValue;
580
581 hidl_vec<uint32_t> inputGateBiasDimensions{numUnits};
582 std::vector<int32_t> inputGateBiasValue{ 644245, 3221226, 4724464, 8160438 };
583
584 hidl_vec<uint32_t> forgetGateBiasDimensions{numUnits};
585 std::vector<int32_t> forgetGateBiasValue{ 2147484, -6442451, -4294968, 2147484 };
586
587 hidl_vec<uint32_t> cellBiasDimensions{numUnits};
588 std::vector<int32_t> cellBiasValue{-1073742, 15461883, 5368709, 1717987 };
589
590 hidl_vec<uint32_t> outputGateBiasDimensions{numUnits};
591 std::vector<int32_t> outputGateBiasValue{ 1073742, -214748, 4294968, 2147484 };
592
593 hidl_vec<uint32_t> projectionWeightsDimensions{outputSize, numUnits};
594 std::vector<int8_t> projectionWeightsValue{ -25, 51, 3, -51, 25, 127, 77, 20, 18, 51, -102, 51 };
595
596 hidl_vec<uint32_t> projectionBiasDimensions{outputSize};
597 std::vector<int32_t> projectionBiasValue{ 0, 0, 0 };
598
599 hidl_vec<uint32_t> outputStateInDimensions{batchSize, outputSize};
600 std::vector<int8_t> outputStateInValue{ 0, 0, 0, 0, 0, 0 };
601
602 hidl_vec<uint32_t> cellStateInDimensions{batchSize, numUnits};
603 std::vector<int16_t> cellStateInValue{ 0, 0, 0, 0, 0, 0, 0, 0 };
604
605 // Normalization:
606 hidl_vec<uint32_t> inputLayerNormWeightsDimensions{numUnits};
607 std::vector<int16_t> inputLayerNormWeightsValue{ 3277, 6553, 9830, 16384 };
608
609 hidl_vec<uint32_t> forgetLayerNormWeightsDimensions{numUnits};
610 std::vector<int16_t> forgetLayerNormWeightsValue{ 6553, 6553, 13107, 9830 };
611
612 hidl_vec<uint32_t> cellLayerNormWeightsDimensions{numUnits};
613 std::vector<int16_t> cellLayerNormWeightsValue{ 22937, 6553, 9830, 26214 };
614
615 hidl_vec<uint32_t> outputLayerNormWeightsDimensions{numUnits};
616 std::vector<int16_t> outputLayerNormWeightsValue{ 19660, 6553, 6553, 16384 };
617
618 float cellClipValue = 0.0f;
619 float projectionClipValue = 0.0f;
620 float inputIntermediateScale = 0.007059f;
621 float forgetIntermediateScale = 0.007812f;
622 float cellIntermediateScale = 0.007059f;
623 float outputIntermediateScale = 0.007812f;
624 int32_t hiddenStateZeroPoint = 0;
625 float hiddenStateScale = 0.007f;
626
627 // Outputs:
628 hidl_vec<uint32_t> outputStateOutDimensions{batchSize, outputSize};
629 std::vector<int8_t> outputStateOutValue{ 127, 127, -108, -67, 127, 127 };
630
631 hidl_vec<uint32_t> cellStateOutDimensions{batchSize, numUnits};
632 std::vector<int16_t> cellStateOutValue { -14650, 8939, 5771, 6715, -11843, 7847, 1508, 12939 };
633
634 hidl_vec<uint32_t> outputDimensions{batchSize, outputSize};
635 std::vector<int8_t> outputValue { 127, 127, -108, -67, 127, 127 };
636
637 QLstmTestImpl(inputDimensions, inputValue,
638 inputToInputWeightsDimensions, inputToInputWeightsValue,
639 inputToForgetWeightsDimensions, inputToForgetWeightsValue,
640 inputToCellWeightsDimensions, inputToCellWeightsValue,
641 inputToOutputWeightsDimensions, inputToOutputWeightsValue,
642 recurrentToInputWeightsDimensions, recurrentToInputWeightsValue,
643 recurrentToForgetWeightsDimensions, recurrentToForgetWeightsValue,
644 recurrentToCellWeightsDimensions, recurrentToCellWeightsValue,
645 recurrentToOutputWeightsDimensions, recurrentToOutputWeightsValue,
646 cellToInputWeightsDimensions, cellToInputWeightsValue,
647 cellToForgetWeightsDimensions, cellToForgetWeightsValue,
648 cellToOutputWeightsDimensions, cellToOutputWeightsValue,
649 inputGateBiasDimensions, inputGateBiasValue,
650 forgetGateBiasDimensions, forgetGateBiasValue,
651 cellBiasDimensions, cellBiasValue,
652 outputGateBiasDimensions, outputGateBiasValue,
653 projectionWeightsDimensions, projectionWeightsValue,
654 projectionBiasDimensions, projectionBiasValue,
655 outputStateInDimensions, outputStateInValue,
656 cellStateInDimensions, cellStateInValue,
657 inputLayerNormWeightsDimensions, inputLayerNormWeightsValue,
658 forgetLayerNormWeightsDimensions, forgetLayerNormWeightsValue,
659 cellLayerNormWeightsDimensions, cellLayerNormWeightsValue,
660 outputLayerNormWeightsDimensions, outputLayerNormWeightsValue,
661 cellClipValue,
662 projectionClipValue,
663 inputIntermediateScale,
664 forgetIntermediateScale,
665 cellIntermediateScale,
666 outputIntermediateScale,
667 hiddenStateZeroPoint,
668 hiddenStateScale,
669 outputStateOutDimensions, outputStateOutValue,
670 cellStateOutDimensions, cellStateOutValue,
671 outputDimensions, outputValue,
672 compute);
673 }
674
QLstmWithNoProjection(armnn::Compute compute)675 void QLstmWithNoProjection(armnn::Compute compute)
676 {
677 // This replicates android/frameworks/ml/nn/runtime/test/specs/V1_3/qlstm_noprojection.mod.py
678 // with values from android/frameworks/ml/nn/runtime/test/generated/spec_V1_3/qlstm_noprojection.example.cpp
679 // and weights, biases and scalars passed as CONSTANT_COPY tensors (instead of SUBGRAPH_INPUT tensors).
680
681 uint32_t batchSize = 2;
682 uint32_t inputSize = 5;
683 uint32_t outputSize = 4;
684 uint32_t numUnits = 4;
685
686 // Inputs:
687 hidl_vec<uint32_t> inputDimensions{batchSize, inputSize};
688 std::vector<int8_t> inputValue { 90, 102, 13, 26, 38, 102, 13, 26, 51, 64 };
689
690 hidl_vec<uint32_t> inputToInputWeightsDimensions{0, 0};
691 std::vector<int8_t> inputToInputWeightsValue;
692
693 hidl_vec<uint32_t> inputToForgetWeightsDimensions{numUnits, inputSize};
694 std::vector<int8_t> inputToForgetWeightsValue { -77, -13, 38, 25, 115,
695 -64, -25, -51, 38, -102,
696 -51, 38, -64, -51, -77,
697 38, -51, -77, -64, -64 };
698
699 hidl_vec<uint32_t> inputToCellWeightsDimensions{numUnits, inputSize};
700 std::vector<int8_t> inputToCellWeightsValue { -51, -38, -25, -13, -64,
701 64, -25, -38, -25, -77,
702 77, -13, -51, -38, -89,
703 89, -115, -64, 102, 77 };
704
705 hidl_vec<uint32_t> inputToOutputWeightsDimensions{numUnits, inputSize};
706 std::vector<int8_t> inputToOutputWeightsValue { -102, -51, -25, -115, -13,
707 -89, 38, -38, -102, -25,
708 77, -25, 51, -89, -38,
709 -64, 13, 64, -77, -51 };
710
711 hidl_vec<uint32_t> recurrentToInputWeightsDimensions{0, 0};
712 std::vector<int8_t> recurrentToInputWeightsValue;
713
714 hidl_vec<uint32_t> recurrentToForgetWeightsDimensions{numUnits, outputSize};
715 std::vector<int8_t> recurrentToForgetWeightsValue { -64, -38, -64, -25,
716 77, 51, 115, 38,
717 -13, 25, 64, 25,
718 25, 38, -13, 51 };
719
720 hidl_vec<uint32_t> recurrentToCellWeightsDimensions{numUnits, outputSize};
721 std::vector<int8_t> recurrentToCellWeightsValue { -38, 25, 13, -38,
722 102, -10, -25, 38,
723 102, -77, -13, 25,
724 38, -13, 25, 64 };
725
726 hidl_vec<uint32_t> recurrentToOutputWeightsDimensions{numUnits, outputSize};
727 std::vector<int8_t> recurrentToOutputWeightsValue { 38, -13, 13, -25,
728 -64, -89, -25, -77,
729 -13, -51, -89, -25,
730 13, 64, 25, -38 };
731
732 hidl_vec<uint32_t> cellToInputWeightsDimensions{0};
733 std::vector<int16_t> cellToInputWeightsValue;
734
735 hidl_vec<uint32_t> cellToForgetWeightsDimensions{0};
736 std::vector<int16_t> cellToForgetWeightsValue;
737
738 hidl_vec<uint32_t> cellToOutputWeightsDimensions{0};
739 std::vector<int16_t> cellToOutputWeightsValue;
740
741 hidl_vec<uint32_t> inputGateBiasDimensions{0};
742 std::vector<int32_t> inputGateBiasValue;
743
744 hidl_vec<uint32_t> forgetGateBiasDimensions{numUnits};
745 std::vector<int32_t> forgetGateBiasValue { 2147484, -6442451, -4294968, 2147484 };
746
747 hidl_vec<uint32_t> cellBiasDimensions{numUnits};
748 std::vector<int32_t> cellBiasValue { -1073742, 15461883, 5368709, 1717987 };
749
750 hidl_vec<uint32_t> outputGateBiasDimensions{numUnits};
751 std::vector<int32_t> outputGateBiasValue { 1073742, -214748, 4294968, 2147484 };
752
753 hidl_vec<uint32_t> projectionWeightsDimensions{0, 0};
754 std::vector<int8_t> projectionWeightsValue;
755
756 hidl_vec<uint32_t> projectionBiasDimensions{0};
757 std::vector<int32_t> projectionBiasValue;
758
759 hidl_vec<uint32_t> outputStateInDimensions{batchSize, outputSize};
760 std::vector<int8_t> outputStateInValue { 0, 0, 0, 0, 0, 0, 0, 0 };
761
762 hidl_vec<uint32_t> cellStateInDimensions{batchSize, numUnits};
763 std::vector<int16_t> cellStateInValue { 0, 0, 0, 0, 0, 0, 0, 0 };
764
765 // Normalization:
766 hidl_vec<uint32_t> inputLayerNormWeightsDimensions{0};
767 std::vector<int16_t> inputLayerNormWeightsValue;
768
769 hidl_vec<uint32_t> forgetLayerNormWeightsDimensions{numUnits};
770 std::vector<int16_t> forgetLayerNormWeightsValue { 6553, 6553, 13107, 9830 };
771
772 hidl_vec<uint32_t> cellLayerNormWeightsDimensions{numUnits};
773 std::vector<int16_t> cellLayerNormWeightsValue { 22937, 6553, 9830, 26214 };
774
775 hidl_vec<uint32_t> outputLayerNormWeightsDimensions{numUnits};
776 std::vector<int16_t> outputLayerNormWeightsValue { 19660, 6553, 6553, 16384 };
777
778 float cellClipValue = 0.0f;
779 float projectionClipValue = 0.0f;
780 float inputIntermediateScale = 0.007059f;
781 float forgetIntermediateScale = 0.007812f;
782 float cellIntermediateScale = 0.007059f;
783 float outputIntermediateScale = 0.007812f;
784 int32_t hiddenStateZeroPoint = 0;
785 float hiddenStateScale = 0.007f;
786
787 // Outputs:
788 hidl_vec<uint32_t> outputStateOutDimensions{batchSize, outputSize};
789 std::vector<int8_t> outputStateOutValue { -15, 21, 14, 20, -15, 15, 5, 27 };
790
791 hidl_vec<uint32_t> cellStateOutDimensions{batchSize, numUnits};
792 std::vector<int16_t> cellStateOutValue { -11692, 9960, 5491, 8861, -9422, 7726, 2056, 13149 };
793
794 hidl_vec<uint32_t> outputDimensions{batchSize, outputSize};
795 std::vector<int8_t> outputValue { -15, 21, 14, 20, -15, 15, 5, 27 };
796
797 QLstmTestImpl(inputDimensions, inputValue,
798 inputToInputWeightsDimensions, inputToInputWeightsValue,
799 inputToForgetWeightsDimensions, inputToForgetWeightsValue,
800 inputToCellWeightsDimensions, inputToCellWeightsValue,
801 inputToOutputWeightsDimensions, inputToOutputWeightsValue,
802 recurrentToInputWeightsDimensions, recurrentToInputWeightsValue,
803 recurrentToForgetWeightsDimensions, recurrentToForgetWeightsValue,
804 recurrentToCellWeightsDimensions, recurrentToCellWeightsValue,
805 recurrentToOutputWeightsDimensions, recurrentToOutputWeightsValue,
806 cellToInputWeightsDimensions, cellToInputWeightsValue,
807 cellToForgetWeightsDimensions, cellToForgetWeightsValue,
808 cellToOutputWeightsDimensions, cellToOutputWeightsValue,
809 inputGateBiasDimensions, inputGateBiasValue,
810 forgetGateBiasDimensions, forgetGateBiasValue,
811 cellBiasDimensions, cellBiasValue,
812 outputGateBiasDimensions, outputGateBiasValue,
813 projectionWeightsDimensions, projectionWeightsValue,
814 projectionBiasDimensions, projectionBiasValue,
815 outputStateInDimensions, outputStateInValue,
816 cellStateInDimensions, cellStateInValue,
817 inputLayerNormWeightsDimensions, inputLayerNormWeightsValue,
818 forgetLayerNormWeightsDimensions, forgetLayerNormWeightsValue,
819 cellLayerNormWeightsDimensions, cellLayerNormWeightsValue,
820 outputLayerNormWeightsDimensions, outputLayerNormWeightsValue,
821 cellClipValue,
822 projectionClipValue,
823 inputIntermediateScale,
824 forgetIntermediateScale,
825 cellIntermediateScale,
826 outputIntermediateScale,
827 hiddenStateZeroPoint,
828 hiddenStateScale,
829 outputStateOutDimensions, outputStateOutValue,
830 cellStateOutDimensions, cellStateOutValue,
831 outputDimensions, outputValue,
832 compute);
833 }
834
DynamicOutputQLstmWithNoProjection(armnn::Compute compute)835 void DynamicOutputQLstmWithNoProjection(armnn::Compute compute)
836 {
837 // This replicates android/frameworks/ml/nn/runtime/test/specs/V1_3/qlstm_noprojection.mod.py
838 // with values from android/frameworks/ml/nn/runtime/test/generated/spec_V1_3/qlstm_noprojection.example.cpp
839 // and weights, biases and scalars passed as CONSTANT_COPY tensors (instead of SUBGRAPH_INPUT tensors)
840 // and made cellStateOutput dynamic.
841
842 uint32_t batchSize = 2;
843 uint32_t inputSize = 5;
844 uint32_t outputSize = 4;
845 uint32_t numUnits = 4;
846
847 // Inputs:
848 hidl_vec<uint32_t> inputDimensions{batchSize, inputSize};
849 std::vector<int8_t> inputValue { 90, 102, 13, 26, 38, 102, 13, 26, 51, 64 };
850
851 hidl_vec<uint32_t> inputToInputWeightsDimensions{0, 0};
852 std::vector<int8_t> inputToInputWeightsValue;
853
854 hidl_vec<uint32_t> inputToForgetWeightsDimensions{numUnits, inputSize};
855 std::vector<int8_t> inputToForgetWeightsValue { -77, -13, 38, 25, 115,
856 -64, -25, -51, 38, -102,
857 -51, 38, -64, -51, -77,
858 38, -51, -77, -64, -64 };
859
860 hidl_vec<uint32_t> inputToCellWeightsDimensions{numUnits, inputSize};
861 std::vector<int8_t> inputToCellWeightsValue { -51, -38, -25, -13, -64,
862 64, -25, -38, -25, -77,
863 77, -13, -51, -38, -89,
864 89, -115, -64, 102, 77 };
865
866 hidl_vec<uint32_t> inputToOutputWeightsDimensions{numUnits, inputSize};
867 std::vector<int8_t> inputToOutputWeightsValue { -102, -51, -25, -115, -13,
868 -89, 38, -38, -102, -25,
869 77, -25, 51, -89, -38,
870 -64, 13, 64, -77, -51 };
871
872 hidl_vec<uint32_t> recurrentToInputWeightsDimensions{0, 0};
873 std::vector<int8_t> recurrentToInputWeightsValue;
874
875 hidl_vec<uint32_t> recurrentToForgetWeightsDimensions{numUnits, outputSize};
876 std::vector<int8_t> recurrentToForgetWeightsValue { -64, -38, -64, -25,
877 77, 51, 115, 38,
878 -13, 25, 64, 25,
879 25, 38, -13, 51 };
880
881 hidl_vec<uint32_t> recurrentToCellWeightsDimensions{numUnits, outputSize};
882 std::vector<int8_t> recurrentToCellWeightsValue { -38, 25, 13, -38,
883 102, -10, -25, 38,
884 102, -77, -13, 25,
885 38, -13, 25, 64 };
886
887 hidl_vec<uint32_t> recurrentToOutputWeightsDimensions{numUnits, outputSize};
888 std::vector<int8_t> recurrentToOutputWeightsValue { 38, -13, 13, -25,
889 -64, -89, -25, -77,
890 -13, -51, -89, -25,
891 13, 64, 25, -38 };
892
893 hidl_vec<uint32_t> cellToInputWeightsDimensions{0};
894 std::vector<int16_t> cellToInputWeightsValue;
895
896 hidl_vec<uint32_t> cellToForgetWeightsDimensions{0};
897 std::vector<int16_t> cellToForgetWeightsValue;
898
899 hidl_vec<uint32_t> cellToOutputWeightsDimensions{0};
900 std::vector<int16_t> cellToOutputWeightsValue;
901
902 hidl_vec<uint32_t> inputGateBiasDimensions{0};
903 std::vector<int32_t> inputGateBiasValue;
904
905 hidl_vec<uint32_t> forgetGateBiasDimensions{numUnits};
906 std::vector<int32_t> forgetGateBiasValue { 2147484, -6442451, -4294968, 2147484 };
907
908 hidl_vec<uint32_t> cellBiasDimensions{numUnits};
909 std::vector<int32_t> cellBiasValue { -1073742, 15461883, 5368709, 1717987 };
910
911 hidl_vec<uint32_t> outputGateBiasDimensions{numUnits};
912 std::vector<int32_t> outputGateBiasValue { 1073742, -214748, 4294968, 2147484 };
913
914 hidl_vec<uint32_t> projectionWeightsDimensions{0, 0};
915 std::vector<int8_t> projectionWeightsValue;
916
917 hidl_vec<uint32_t> projectionBiasDimensions{0};
918 std::vector<int32_t> projectionBiasValue;
919
920 hidl_vec<uint32_t> outputStateInDimensions{batchSize, outputSize};
921 std::vector<int8_t> outputStateInValue { 0, 0, 0, 0, 0, 0, 0, 0 };
922
923 hidl_vec<uint32_t> cellStateInDimensions{batchSize, numUnits};
924 std::vector<int16_t> cellStateInValue { 0, 0, 0, 0, 0, 0, 0, 0 };
925
926 // Normalization:
927 hidl_vec<uint32_t> inputLayerNormWeightsDimensions{0};
928 std::vector<int16_t> inputLayerNormWeightsValue;
929
930 hidl_vec<uint32_t> forgetLayerNormWeightsDimensions{numUnits};
931 std::vector<int16_t> forgetLayerNormWeightsValue { 6553, 6553, 13107, 9830 };
932
933 hidl_vec<uint32_t> cellLayerNormWeightsDimensions{numUnits};
934 std::vector<int16_t> cellLayerNormWeightsValue { 22937, 6553, 9830, 26214 };
935
936 hidl_vec<uint32_t> outputLayerNormWeightsDimensions{numUnits};
937 std::vector<int16_t> outputLayerNormWeightsValue { 19660, 6553, 6553, 16384 };
938
939 float cellClipValue = 0.0f;
940 float projectionClipValue = 0.0f;
941 float inputIntermediateScale = 0.007059f;
942 float forgetIntermediateScale = 0.007812f;
943 float cellIntermediateScale = 0.007059f;
944 float outputIntermediateScale = 0.007812f;
945 int32_t hiddenStateZeroPoint = 0;
946 float hiddenStateScale = 0.007f;
947
948 // Outputs:
949 hidl_vec<uint32_t> outputStateOutDimensions{batchSize, outputSize};
950 std::vector<int8_t> outputStateOutValue { -15, 21, 14, 20, -15, 15, 5, 27 };
951
952 hidl_vec<uint32_t> cellStateOutDimensions{};
953 std::vector<int16_t> cellStateOutValue { -11692, 9960, 5491, 8861, -9422, 7726, 2056, 13149 };
954
955 hidl_vec<uint32_t> outputDimensions{batchSize, outputSize};
956 std::vector<int8_t> outputValue { -15, 21, 14, 20, -15, 15, 5, 27 };
957
958 QLstmTestImpl(inputDimensions, inputValue,
959 inputToInputWeightsDimensions, inputToInputWeightsValue,
960 inputToForgetWeightsDimensions, inputToForgetWeightsValue,
961 inputToCellWeightsDimensions, inputToCellWeightsValue,
962 inputToOutputWeightsDimensions, inputToOutputWeightsValue,
963 recurrentToInputWeightsDimensions, recurrentToInputWeightsValue,
964 recurrentToForgetWeightsDimensions, recurrentToForgetWeightsValue,
965 recurrentToCellWeightsDimensions, recurrentToCellWeightsValue,
966 recurrentToOutputWeightsDimensions, recurrentToOutputWeightsValue,
967 cellToInputWeightsDimensions, cellToInputWeightsValue,
968 cellToForgetWeightsDimensions, cellToForgetWeightsValue,
969 cellToOutputWeightsDimensions, cellToOutputWeightsValue,
970 inputGateBiasDimensions, inputGateBiasValue,
971 forgetGateBiasDimensions, forgetGateBiasValue,
972 cellBiasDimensions, cellBiasValue,
973 outputGateBiasDimensions, outputGateBiasValue,
974 projectionWeightsDimensions, projectionWeightsValue,
975 projectionBiasDimensions, projectionBiasValue,
976 outputStateInDimensions, outputStateInValue,
977 cellStateInDimensions, cellStateInValue,
978 inputLayerNormWeightsDimensions, inputLayerNormWeightsValue,
979 forgetLayerNormWeightsDimensions, forgetLayerNormWeightsValue,
980 cellLayerNormWeightsDimensions, cellLayerNormWeightsValue,
981 outputLayerNormWeightsDimensions, outputLayerNormWeightsValue,
982 cellClipValue,
983 projectionClipValue,
984 inputIntermediateScale,
985 forgetIntermediateScale,
986 cellIntermediateScale,
987 outputIntermediateScale,
988 hiddenStateZeroPoint,
989 hiddenStateScale,
990 outputStateOutDimensions, outputStateOutValue,
991 cellStateOutDimensions, cellStateOutValue,
992 outputDimensions, outputValue,
993 compute);
994 }
995
996 } // anonymous namespace
997
998 // Support is not added yet
999 //TEST_CASE(QLSTMWithProjectionTest, COMPUTE_DEVICES)
1000 //{
1001 // QLstmWithProjection(sample);
1002 //}
1003
1004 DOCTEST_TEST_SUITE("QLSTMTests_CpuRef")
1005 {
1006
1007 DOCTEST_TEST_CASE("QLSTMWithNoProjectionTest_CpuRef")
1008 {
1009 QLstmWithNoProjection(armnn::Compute::CpuRef);
1010 }
1011
1012 DOCTEST_TEST_CASE("DynamicOutputQLstmWithNoProjection_CpuRef")
1013 {
1014 DynamicOutputQLstmWithNoProjection(armnn::Compute::CpuRef);
1015 }
1016
1017 }
1018 #ifdef ARMCOMPUTECL_ENABLED
1019 DOCTEST_TEST_SUITE("QLSTMTests_CpuAcc")
1020 {
1021
1022 DOCTEST_TEST_CASE("QLSTMWithNoProjectionTest_CpuAcc")
1023 {
1024 QLstmWithNoProjection(armnn::Compute::CpuAcc);
1025 }
1026
1027 DOCTEST_TEST_CASE("DynamicOutputQLstmWithNoProjection_CpuAcc")
1028 {
1029 DynamicOutputQLstmWithNoProjection(armnn::Compute::CpuAcc);
1030 }
1031
1032 }
1033 #endif
1034