xref: /aosp_15_r20/external/armnn/src/armnnSerializer/test/LstmSerializationTests.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1 //
2 // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "../Serializer.hpp"
7 #include "SerializerTestUtils.hpp"
8 
9 #include <armnn/Descriptors.hpp>
10 #include <armnn/INetwork.hpp>
11 #include <armnn/IRuntime.hpp>
12 #include <armnnDeserializer/IDeserializer.hpp>
13 #include <armnn/utility/IgnoreUnused.hpp>
14 #include <armnn/LstmParams.hpp>
15 #include <armnn/QuantizedLstmParams.hpp>
16 
17 #include <doctest/doctest.h>
18 #include <fmt/format.h>
19 
20 
21 TEST_SUITE("SerializerTests")
22 {
23 template<typename Descriptor>
ConstantVector2LstmInputParams(const std::vector<armnn::ConstTensor> & constants,Descriptor & descriptor)24 armnn::LstmInputParams ConstantVector2LstmInputParams(const std::vector<armnn::ConstTensor>& constants,
25                                                       Descriptor& descriptor)
26 {
27     armnn::LstmInputParams lstmInputParams;
28     size_t i = 0;
29 
30     // Inserting basic paramters
31     lstmInputParams.m_InputToForgetWeights     = &constants[i++];
32     lstmInputParams.m_InputToCellWeights       = &constants[i++];
33     lstmInputParams.m_InputToOutputWeights     = &constants[i++];
34     lstmInputParams.m_RecurrentToForgetWeights = &constants[i++];
35     lstmInputParams.m_RecurrentToCellWeights   = &constants[i++];
36     lstmInputParams.m_RecurrentToOutputWeights = &constants[i++];
37     lstmInputParams.m_ForgetGateBias           = &constants[i++];
38     lstmInputParams.m_CellBias                 = &constants[i++];
39     lstmInputParams.m_OutputGateBias           = &constants[i++];
40     if (!descriptor.m_CifgEnabled)
41     {
42         lstmInputParams.m_InputToInputWeights     = &constants[i++];
43         lstmInputParams.m_RecurrentToInputWeights = &constants[i++];
44         lstmInputParams.m_InputGateBias           = &constants[i++];
45     }
46 
47     if (descriptor.m_PeepholeEnabled)
48     {
49         if (!descriptor.m_CifgEnabled)
50         {
51             lstmInputParams.m_CellToInputWeights = &constants[i++];
52         }
53         lstmInputParams.m_CellToForgetWeights = &constants[i++];
54         lstmInputParams.m_CellToOutputWeights = &constants[i++];
55     }
56 
57     if (descriptor.m_ProjectionEnabled)
58     {
59         lstmInputParams.m_ProjectionWeights = &constants[i++];
60         lstmInputParams.m_ProjectionBias    = &constants[i++];
61     }
62 
63     if (descriptor.m_LayerNormEnabled)
64     {
65         if (!descriptor.m_CifgEnabled)
66         {
67             lstmInputParams.m_InputLayerNormWeights = &constants[i++];
68         }
69         lstmInputParams.m_ForgetLayerNormWeights = &constants[i++];
70         lstmInputParams.m_CellLayerNormWeights   = &constants[i++];
71         lstmInputParams.m_OutputLayerNormWeights = &constants[i++];
72     }
73 
74     return lstmInputParams;
75 }
76 
77 // Works for Lstm, UnidirectionalSequenceLstm and QLstm (QuantizedLstm uses different parameters)
78 template<typename Descriptor>
79 class VerifyLstmLayer : public LayerVerifierBaseWithDescriptor<Descriptor>
80 {
81 public:
VerifyLstmLayer(const std::string & layerName,const std::vector<armnn::TensorInfo> & inputInfos,const std::vector<armnn::TensorInfo> & outputInfos,const Descriptor & descriptor,const armnn::LstmInputParams & inputParams)82     VerifyLstmLayer(const std::string& layerName,
83                     const std::vector<armnn::TensorInfo>& inputInfos,
84                     const std::vector<armnn::TensorInfo>& outputInfos,
85                     const Descriptor& descriptor,
86                     const armnn::LstmInputParams& inputParams)
87         : LayerVerifierBaseWithDescriptor<Descriptor>(layerName, inputInfos, outputInfos, descriptor)
88         , m_InputParams(inputParams) {}
89 
ExecuteStrategy(const armnn::IConnectableLayer * layer,const armnn::BaseDescriptor & descriptor,const std::vector<armnn::ConstTensor> & constants,const char * name,const armnn::LayerBindingId id=0)90     void ExecuteStrategy(const armnn::IConnectableLayer* layer,
91                          const armnn::BaseDescriptor& descriptor,
92                          const std::vector<armnn::ConstTensor>& constants,
93                          const char* name,
94                          const armnn::LayerBindingId id = 0) override
95     {
96         armnn::IgnoreUnused(constants, id);
97         switch (layer->GetType())
98         {
99             case armnn::LayerType::Input: break;
100             case armnn::LayerType::Output: break;
101             case armnn::LayerType::Lstm:
102             case armnn::LayerType::UnidirectionalSequenceLstm:
103             {
104                 this->VerifyNameAndConnections(layer, name);
105                 const Descriptor& internalDescriptor = static_cast<const Descriptor&>(descriptor);
106                 this->VerifyDescriptor(internalDescriptor);
107                 armnn::LstmInputParams lstmParams = ConstantVector2LstmInputParams(constants, internalDescriptor);
108                 VerifyInputParameters(lstmParams);
109                 break;
110             }
111             case armnn::LayerType::QLstm:
112             {
113                 this->VerifyNameAndConnections(layer, name);
114                 const Descriptor& internalDescriptor = static_cast<const Descriptor&>(descriptor);
115                 this->VerifyDescriptor(internalDescriptor);
116                 armnn::LstmInputParams lstmParams = ConstantVector2LstmInputParams(constants, internalDescriptor);
117                 VerifyInputParameters(lstmParams);
118                 break;
119             }
120             default:
121             {
122                 throw armnn::Exception("Unexpected layer type in Lstm test model");
123             }
124         }
125     }
126 
127 protected:
VerifyInputParameters(const armnn::LstmInputParams & params)128     void VerifyInputParameters(const armnn::LstmInputParams& params)
129     {
130         this->VerifyConstTensors(
131             "m_InputToInputWeights", m_InputParams.m_InputToInputWeights, params.m_InputToInputWeights);
132         this->VerifyConstTensors(
133             "m_InputToForgetWeights", m_InputParams.m_InputToForgetWeights, params.m_InputToForgetWeights);
134         this->VerifyConstTensors(
135             "m_InputToCellWeights", m_InputParams.m_InputToCellWeights, params.m_InputToCellWeights);
136         this->VerifyConstTensors(
137             "m_InputToOutputWeights", m_InputParams.m_InputToOutputWeights, params.m_InputToOutputWeights);
138         this->VerifyConstTensors(
139             "m_RecurrentToInputWeights", m_InputParams.m_RecurrentToInputWeights, params.m_RecurrentToInputWeights);
140         this->VerifyConstTensors(
141             "m_RecurrentToForgetWeights", m_InputParams.m_RecurrentToForgetWeights, params.m_RecurrentToForgetWeights);
142         this->VerifyConstTensors(
143             "m_RecurrentToCellWeights", m_InputParams.m_RecurrentToCellWeights, params.m_RecurrentToCellWeights);
144         this->VerifyConstTensors(
145             "m_RecurrentToOutputWeights", m_InputParams.m_RecurrentToOutputWeights, params.m_RecurrentToOutputWeights);
146         this->VerifyConstTensors(
147             "m_CellToInputWeights", m_InputParams.m_CellToInputWeights, params.m_CellToInputWeights);
148         this->VerifyConstTensors(
149             "m_CellToForgetWeights", m_InputParams.m_CellToForgetWeights, params.m_CellToForgetWeights);
150         this->VerifyConstTensors(
151             "m_CellToOutputWeights", m_InputParams.m_CellToOutputWeights, params.m_CellToOutputWeights);
152         this->VerifyConstTensors(
153             "m_InputGateBias", m_InputParams.m_InputGateBias, params.m_InputGateBias);
154         this->VerifyConstTensors(
155             "m_ForgetGateBias", m_InputParams.m_ForgetGateBias, params.m_ForgetGateBias);
156         this->VerifyConstTensors(
157             "m_CellBias", m_InputParams.m_CellBias, params.m_CellBias);
158         this->VerifyConstTensors(
159             "m_OutputGateBias", m_InputParams.m_OutputGateBias, params.m_OutputGateBias);
160         this->VerifyConstTensors(
161             "m_ProjectionWeights", m_InputParams.m_ProjectionWeights, params.m_ProjectionWeights);
162         this->VerifyConstTensors(
163             "m_ProjectionBias", m_InputParams.m_ProjectionBias, params.m_ProjectionBias);
164         this->VerifyConstTensors(
165             "m_InputLayerNormWeights", m_InputParams.m_InputLayerNormWeights, params.m_InputLayerNormWeights);
166         this->VerifyConstTensors(
167             "m_ForgetLayerNormWeights", m_InputParams.m_ForgetLayerNormWeights, params.m_ForgetLayerNormWeights);
168         this->VerifyConstTensors(
169             "m_CellLayerNormWeights", m_InputParams.m_CellLayerNormWeights, params.m_CellLayerNormWeights);
170         this->VerifyConstTensors(
171             "m_OutputLayerNormWeights", m_InputParams.m_OutputLayerNormWeights, params.m_OutputLayerNormWeights);
172     }
173 
174 private:
175     armnn::LstmInputParams m_InputParams;
176 };
177 
178 TEST_CASE("SerializeDeserializeLstmCifgPeepholeNoProjection")
179 {
180     armnn::LstmDescriptor descriptor;
181     descriptor.m_ActivationFunc = 4;
182     descriptor.m_ClippingThresProj = 0.0f;
183     descriptor.m_ClippingThresCell = 0.0f;
184     descriptor.m_CifgEnabled = true; // if this is true then we DON'T need to set the OptCifgParams
185     descriptor.m_ProjectionEnabled = false;
186     descriptor.m_PeepholeEnabled = true;
187 
188     const uint32_t batchSize = 1;
189     const uint32_t inputSize = 2;
190     const uint32_t numUnits = 4;
191     const uint32_t outputSize = numUnits;
192 
193     armnn::TensorInfo inputWeightsInfo1({numUnits, inputSize}, armnn::DataType::Float32, 0.0f, 0, true);
194     std::vector<float> inputToForgetWeightsData = GenerateRandomData<float>(inputWeightsInfo1.GetNumElements());
195     armnn::ConstTensor inputToForgetWeights(inputWeightsInfo1, inputToForgetWeightsData);
196 
197     std::vector<float> inputToCellWeightsData = GenerateRandomData<float>(inputWeightsInfo1.GetNumElements());
198     armnn::ConstTensor inputToCellWeights(inputWeightsInfo1, inputToCellWeightsData);
199 
200     std::vector<float> inputToOutputWeightsData = GenerateRandomData<float>(inputWeightsInfo1.GetNumElements());
201     armnn::ConstTensor inputToOutputWeights(inputWeightsInfo1, inputToOutputWeightsData);
202 
203     armnn::TensorInfo inputWeightsInfo2({numUnits, outputSize}, armnn::DataType::Float32, 0.0f, 0, true);
204     std::vector<float> recurrentToForgetWeightsData = GenerateRandomData<float>(inputWeightsInfo2.GetNumElements());
205     armnn::ConstTensor recurrentToForgetWeights(inputWeightsInfo2, recurrentToForgetWeightsData);
206 
207     std::vector<float> recurrentToCellWeightsData = GenerateRandomData<float>(inputWeightsInfo2.GetNumElements());
208     armnn::ConstTensor recurrentToCellWeights(inputWeightsInfo2, recurrentToCellWeightsData);
209 
210     std::vector<float> recurrentToOutputWeightsData = GenerateRandomData<float>(inputWeightsInfo2.GetNumElements());
211     armnn::ConstTensor recurrentToOutputWeights(inputWeightsInfo2, recurrentToOutputWeightsData);
212 
213     armnn::TensorInfo inputWeightsInfo3({numUnits}, armnn::DataType::Float32, 0.0f, 0, true);
214     std::vector<float> cellToForgetWeightsData = GenerateRandomData<float>(inputWeightsInfo3.GetNumElements());
215     armnn::ConstTensor cellToForgetWeights(inputWeightsInfo3, cellToForgetWeightsData);
216 
217     std::vector<float> cellToOutputWeightsData = GenerateRandomData<float>(inputWeightsInfo3.GetNumElements());
218     armnn::ConstTensor cellToOutputWeights(inputWeightsInfo3, cellToOutputWeightsData);
219 
220     std::vector<float> forgetGateBiasData(numUnits, 1.0f);
221     armnn::ConstTensor forgetGateBias(inputWeightsInfo3, forgetGateBiasData);
222 
223     std::vector<float> cellBiasData(numUnits, 0.0f);
224     armnn::ConstTensor cellBias(inputWeightsInfo3, cellBiasData);
225 
226     std::vector<float> outputGateBiasData(numUnits, 0.0f);
227     armnn::ConstTensor outputGateBias(inputWeightsInfo3, outputGateBiasData);
228 
229     armnn::LstmInputParams params;
230     params.m_InputToForgetWeights = &inputToForgetWeights;
231     params.m_InputToCellWeights = &inputToCellWeights;
232     params.m_InputToOutputWeights = &inputToOutputWeights;
233     params.m_RecurrentToForgetWeights = &recurrentToForgetWeights;
234     params.m_RecurrentToCellWeights = &recurrentToCellWeights;
235     params.m_RecurrentToOutputWeights = &recurrentToOutputWeights;
236     params.m_ForgetGateBias = &forgetGateBias;
237     params.m_CellBias = &cellBias;
238     params.m_OutputGateBias = &outputGateBias;
239     params.m_CellToForgetWeights = &cellToForgetWeights;
240     params.m_CellToOutputWeights = &cellToOutputWeights;
241 
242     armnn::INetworkPtr network = armnn::INetwork::Create();
243     armnn::IConnectableLayer* const inputLayer   = network->AddInputLayer(0);
244     armnn::IConnectableLayer* const cellStateIn = network->AddInputLayer(1);
245     armnn::IConnectableLayer* const outputStateIn = network->AddInputLayer(2);
246     const std::string layerName("lstm");
247     armnn::IConnectableLayer* const lstmLayer = network->AddLstmLayer(descriptor, params, layerName.c_str());
248     armnn::IConnectableLayer* const scratchBuffer  = network->AddOutputLayer(0);
249     armnn::IConnectableLayer* const outputStateOut  = network->AddOutputLayer(1);
250     armnn::IConnectableLayer* const cellStateOut  = network->AddOutputLayer(2);
251     armnn::IConnectableLayer* const outputLayer  = network->AddOutputLayer(3);
252 
253     // connect up
254     armnn::TensorInfo inputTensorInfo({ batchSize, inputSize }, armnn::DataType::Float32);
255     armnn::TensorInfo cellStateTensorInfo({ batchSize, numUnits}, armnn::DataType::Float32);
256     armnn::TensorInfo outputStateTensorInfo({ batchSize, outputSize }, armnn::DataType::Float32);
257     armnn::TensorInfo lstmTensorInfoScratchBuff({ batchSize, numUnits * 3 }, armnn::DataType::Float32);
258 
259     inputLayer->GetOutputSlot(0).Connect(lstmLayer->GetInputSlot(0));
260     inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
261 
262     outputStateIn->GetOutputSlot(0).Connect(lstmLayer->GetInputSlot(1));
263     outputStateIn->GetOutputSlot(0).SetTensorInfo(outputStateTensorInfo);
264 
265     cellStateIn->GetOutputSlot(0).Connect(lstmLayer->GetInputSlot(2));
266     cellStateIn->GetOutputSlot(0).SetTensorInfo(cellStateTensorInfo);
267 
268     lstmLayer->GetOutputSlot(0).Connect(scratchBuffer->GetInputSlot(0));
269     lstmLayer->GetOutputSlot(0).SetTensorInfo(lstmTensorInfoScratchBuff);
270 
271     lstmLayer->GetOutputSlot(1).Connect(outputStateOut->GetInputSlot(0));
272     lstmLayer->GetOutputSlot(1).SetTensorInfo(outputStateTensorInfo);
273 
274     lstmLayer->GetOutputSlot(2).Connect(cellStateOut->GetInputSlot(0));
275     lstmLayer->GetOutputSlot(2).SetTensorInfo(cellStateTensorInfo);
276 
277     lstmLayer->GetOutputSlot(3).Connect(outputLayer->GetInputSlot(0));
278     lstmLayer->GetOutputSlot(3).SetTensorInfo(outputStateTensorInfo);
279 
280     armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
281     CHECK(deserializedNetwork);
282 
283     VerifyLstmLayer<armnn::LstmDescriptor> checker(
284         layerName,
285         {inputTensorInfo, outputStateTensorInfo, cellStateTensorInfo},
286         {lstmTensorInfoScratchBuff, outputStateTensorInfo, cellStateTensorInfo, outputStateTensorInfo},
287         descriptor,
288         params);
289     deserializedNetwork->ExecuteStrategy(checker);
290 }
291 
292 TEST_CASE("SerializeDeserializeLstmNoCifgWithPeepholeAndProjection")
293 {
294     armnn::LstmDescriptor descriptor;
295     descriptor.m_ActivationFunc = 4;
296     descriptor.m_ClippingThresProj = 0.0f;
297     descriptor.m_ClippingThresCell = 0.0f;
298     descriptor.m_CifgEnabled = false; // if this is true then we DON'T need to set the OptCifgParams
299     descriptor.m_ProjectionEnabled = true;
300     descriptor.m_PeepholeEnabled = true;
301 
302     const uint32_t batchSize = 2;
303     const uint32_t inputSize = 5;
304     const uint32_t numUnits = 20;
305     const uint32_t outputSize = 16;
306 
307     armnn::TensorInfo tensorInfo20x5({numUnits, inputSize}, armnn::DataType::Float32, 0.0f, 0, true);
308     std::vector<float> inputToInputWeightsData = GenerateRandomData<float>(tensorInfo20x5.GetNumElements());
309     armnn::ConstTensor inputToInputWeights(tensorInfo20x5, inputToInputWeightsData);
310 
311     std::vector<float> inputToForgetWeightsData = GenerateRandomData<float>(tensorInfo20x5.GetNumElements());
312     armnn::ConstTensor inputToForgetWeights(tensorInfo20x5, inputToForgetWeightsData);
313 
314     std::vector<float> inputToCellWeightsData = GenerateRandomData<float>(tensorInfo20x5.GetNumElements());
315     armnn::ConstTensor inputToCellWeights(tensorInfo20x5, inputToCellWeightsData);
316 
317     std::vector<float> inputToOutputWeightsData = GenerateRandomData<float>(tensorInfo20x5.GetNumElements());
318     armnn::ConstTensor inputToOutputWeights(tensorInfo20x5, inputToOutputWeightsData);
319 
320     armnn::TensorInfo tensorInfo20({numUnits}, armnn::DataType::Float32, 0.0f, 0, true);
321     std::vector<float> inputGateBiasData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
322     armnn::ConstTensor inputGateBias(tensorInfo20, inputGateBiasData);
323 
324     std::vector<float> forgetGateBiasData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
325     armnn::ConstTensor forgetGateBias(tensorInfo20, forgetGateBiasData);
326 
327     std::vector<float> cellBiasData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
328     armnn::ConstTensor cellBias(tensorInfo20, cellBiasData);
329 
330     std::vector<float> outputGateBiasData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
331     armnn::ConstTensor outputGateBias(tensorInfo20, outputGateBiasData);
332 
333     armnn::TensorInfo tensorInfo20x16({numUnits, outputSize}, armnn::DataType::Float32, 0.0f, 0, true);
334     std::vector<float> recurrentToInputWeightsData = GenerateRandomData<float>(tensorInfo20x16.GetNumElements());
335     armnn::ConstTensor recurrentToInputWeights(tensorInfo20x16, recurrentToInputWeightsData);
336 
337     std::vector<float> recurrentToForgetWeightsData = GenerateRandomData<float>(tensorInfo20x16.GetNumElements());
338     armnn::ConstTensor recurrentToForgetWeights(tensorInfo20x16, recurrentToForgetWeightsData);
339 
340     std::vector<float> recurrentToCellWeightsData = GenerateRandomData<float>(tensorInfo20x16.GetNumElements());
341     armnn::ConstTensor recurrentToCellWeights(tensorInfo20x16, recurrentToCellWeightsData);
342 
343     std::vector<float> recurrentToOutputWeightsData = GenerateRandomData<float>(tensorInfo20x16.GetNumElements());
344     armnn::ConstTensor recurrentToOutputWeights(tensorInfo20x16, recurrentToOutputWeightsData);
345 
346     std::vector<float> cellToInputWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
347     armnn::ConstTensor cellToInputWeights(tensorInfo20, cellToInputWeightsData);
348 
349     std::vector<float> cellToForgetWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
350     armnn::ConstTensor cellToForgetWeights(tensorInfo20, cellToForgetWeightsData);
351 
352     std::vector<float> cellToOutputWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
353     armnn::ConstTensor cellToOutputWeights(tensorInfo20,  cellToOutputWeightsData);
354 
355     armnn::TensorInfo tensorInfo16x20({outputSize, numUnits}, armnn::DataType::Float32, 0.0f, 0, true);
356     std::vector<float> projectionWeightsData = GenerateRandomData<float>(tensorInfo16x20.GetNumElements());
357     armnn::ConstTensor projectionWeights(tensorInfo16x20, projectionWeightsData);
358 
359     armnn::TensorInfo tensorInfo16({outputSize}, armnn::DataType::Float32, 0.0f, 0, true);
360     std::vector<float> projectionBiasData(outputSize, 0.f);
361     armnn::ConstTensor projectionBias(tensorInfo16, projectionBiasData);
362 
363     armnn::LstmInputParams params;
364     params.m_InputToForgetWeights = &inputToForgetWeights;
365     params.m_InputToCellWeights = &inputToCellWeights;
366     params.m_InputToOutputWeights = &inputToOutputWeights;
367     params.m_RecurrentToForgetWeights = &recurrentToForgetWeights;
368     params.m_RecurrentToCellWeights = &recurrentToCellWeights;
369     params.m_RecurrentToOutputWeights = &recurrentToOutputWeights;
370     params.m_ForgetGateBias = &forgetGateBias;
371     params.m_CellBias = &cellBias;
372     params.m_OutputGateBias = &outputGateBias;
373 
374     // additional params because: descriptor.m_CifgEnabled = false
375     params.m_InputToInputWeights = &inputToInputWeights;
376     params.m_RecurrentToInputWeights = &recurrentToInputWeights;
377     params.m_CellToInputWeights = &cellToInputWeights;
378     params.m_InputGateBias = &inputGateBias;
379 
380     // additional params because: descriptor.m_ProjectionEnabled = true
381     params.m_ProjectionWeights = &projectionWeights;
382     params.m_ProjectionBias = &projectionBias;
383 
384     // additional params because: descriptor.m_PeepholeEnabled = true
385     params.m_CellToForgetWeights = &cellToForgetWeights;
386     params.m_CellToOutputWeights = &cellToOutputWeights;
387 
388     armnn::INetworkPtr network = armnn::INetwork::Create();
389     armnn::IConnectableLayer* const inputLayer   = network->AddInputLayer(0);
390     armnn::IConnectableLayer* const cellStateIn = network->AddInputLayer(1);
391     armnn::IConnectableLayer* const outputStateIn = network->AddInputLayer(2);
392     const std::string layerName("lstm");
393     armnn::IConnectableLayer* const lstmLayer = network->AddLstmLayer(descriptor, params, layerName.c_str());
394     armnn::IConnectableLayer* const scratchBuffer  = network->AddOutputLayer(0);
395     armnn::IConnectableLayer* const outputStateOut  = network->AddOutputLayer(1);
396     armnn::IConnectableLayer* const cellStateOut  = network->AddOutputLayer(2);
397     armnn::IConnectableLayer* const outputLayer  = network->AddOutputLayer(3);
398 
399     // connect up
400     armnn::TensorInfo inputTensorInfo({ batchSize, inputSize }, armnn::DataType::Float32);
401     armnn::TensorInfo cellStateTensorInfo({ batchSize, numUnits}, armnn::DataType::Float32);
402     armnn::TensorInfo outputStateTensorInfo({ batchSize, outputSize }, armnn::DataType::Float32);
403     armnn::TensorInfo lstmTensorInfoScratchBuff({ batchSize, numUnits * 4 }, armnn::DataType::Float32);
404 
405     inputLayer->GetOutputSlot(0).Connect(lstmLayer->GetInputSlot(0));
406     inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
407 
408     outputStateIn->GetOutputSlot(0).Connect(lstmLayer->GetInputSlot(1));
409     outputStateIn->GetOutputSlot(0).SetTensorInfo(outputStateTensorInfo);
410 
411     cellStateIn->GetOutputSlot(0).Connect(lstmLayer->GetInputSlot(2));
412     cellStateIn->GetOutputSlot(0).SetTensorInfo(cellStateTensorInfo);
413 
414     lstmLayer->GetOutputSlot(0).Connect(scratchBuffer->GetInputSlot(0));
415     lstmLayer->GetOutputSlot(0).SetTensorInfo(lstmTensorInfoScratchBuff);
416 
417     lstmLayer->GetOutputSlot(1).Connect(outputStateOut->GetInputSlot(0));
418     lstmLayer->GetOutputSlot(1).SetTensorInfo(outputStateTensorInfo);
419 
420     lstmLayer->GetOutputSlot(2).Connect(cellStateOut->GetInputSlot(0));
421     lstmLayer->GetOutputSlot(2).SetTensorInfo(cellStateTensorInfo);
422 
423     lstmLayer->GetOutputSlot(3).Connect(outputLayer->GetInputSlot(0));
424     lstmLayer->GetOutputSlot(3).SetTensorInfo(outputStateTensorInfo);
425 
426     armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
427     CHECK(deserializedNetwork);
428 
429     VerifyLstmLayer<armnn::LstmDescriptor> checker(
430         layerName,
431         {inputTensorInfo, outputStateTensorInfo, cellStateTensorInfo},
432         {lstmTensorInfoScratchBuff, outputStateTensorInfo, cellStateTensorInfo, outputStateTensorInfo},
433         descriptor,
434         params);
435     deserializedNetwork->ExecuteStrategy(checker);
436 }
437 
438 TEST_CASE("SerializeDeserializeLstmNoCifgWithPeepholeWithProjectionWithLayerNorm")
439 {
440     armnn::LstmDescriptor descriptor;
441     descriptor.m_ActivationFunc = 4;
442     descriptor.m_ClippingThresProj = 0.0f;
443     descriptor.m_ClippingThresCell = 0.0f;
444     descriptor.m_CifgEnabled = false; // if this is true then we DON'T need to set the OptCifgParams
445     descriptor.m_ProjectionEnabled = true;
446     descriptor.m_PeepholeEnabled = true;
447     descriptor.m_LayerNormEnabled = true;
448 
449     const uint32_t batchSize = 2;
450     const uint32_t inputSize = 5;
451     const uint32_t numUnits = 20;
452     const uint32_t outputSize = 16;
453 
454     armnn::TensorInfo tensorInfo20x5({numUnits, inputSize}, armnn::DataType::Float32, 0.0f, 0, true);
455     std::vector<float> inputToInputWeightsData = GenerateRandomData<float>(tensorInfo20x5.GetNumElements());
456     armnn::ConstTensor inputToInputWeights(tensorInfo20x5, inputToInputWeightsData);
457 
458     std::vector<float> inputToForgetWeightsData = GenerateRandomData<float>(tensorInfo20x5.GetNumElements());
459     armnn::ConstTensor inputToForgetWeights(tensorInfo20x5, inputToForgetWeightsData);
460 
461     std::vector<float> inputToCellWeightsData = GenerateRandomData<float>(tensorInfo20x5.GetNumElements());
462     armnn::ConstTensor inputToCellWeights(tensorInfo20x5, inputToCellWeightsData);
463 
464     std::vector<float> inputToOutputWeightsData = GenerateRandomData<float>(tensorInfo20x5.GetNumElements());
465     armnn::ConstTensor inputToOutputWeights(tensorInfo20x5, inputToOutputWeightsData);
466 
467     armnn::TensorInfo tensorInfo20({numUnits}, armnn::DataType::Float32, 0.0f, 0, true);
468     std::vector<float> inputGateBiasData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
469     armnn::ConstTensor inputGateBias(tensorInfo20, inputGateBiasData);
470 
471     std::vector<float> forgetGateBiasData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
472     armnn::ConstTensor forgetGateBias(tensorInfo20, forgetGateBiasData);
473 
474     std::vector<float> cellBiasData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
475     armnn::ConstTensor cellBias(tensorInfo20, cellBiasData);
476 
477     std::vector<float> outputGateBiasData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
478     armnn::ConstTensor outputGateBias(tensorInfo20, outputGateBiasData);
479 
480     armnn::TensorInfo tensorInfo20x16({numUnits, outputSize}, armnn::DataType::Float32, 0.0f, 0, true);
481     std::vector<float> recurrentToInputWeightsData = GenerateRandomData<float>(tensorInfo20x16.GetNumElements());
482     armnn::ConstTensor recurrentToInputWeights(tensorInfo20x16, recurrentToInputWeightsData);
483 
484     std::vector<float> recurrentToForgetWeightsData = GenerateRandomData<float>(tensorInfo20x16.GetNumElements());
485     armnn::ConstTensor recurrentToForgetWeights(tensorInfo20x16, recurrentToForgetWeightsData);
486 
487     std::vector<float> recurrentToCellWeightsData = GenerateRandomData<float>(tensorInfo20x16.GetNumElements());
488     armnn::ConstTensor recurrentToCellWeights(tensorInfo20x16, recurrentToCellWeightsData);
489 
490     std::vector<float> recurrentToOutputWeightsData = GenerateRandomData<float>(tensorInfo20x16.GetNumElements());
491     armnn::ConstTensor recurrentToOutputWeights(tensorInfo20x16, recurrentToOutputWeightsData);
492 
493     std::vector<float> cellToInputWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
494     armnn::ConstTensor cellToInputWeights(tensorInfo20, cellToInputWeightsData);
495 
496     std::vector<float> cellToForgetWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
497     armnn::ConstTensor cellToForgetWeights(tensorInfo20, cellToForgetWeightsData);
498 
499     std::vector<float> cellToOutputWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
500     armnn::ConstTensor cellToOutputWeights(tensorInfo20,  cellToOutputWeightsData);
501 
502     armnn::TensorInfo tensorInfo16x20({outputSize, numUnits}, armnn::DataType::Float32, 0.0f, 0, true);
503     std::vector<float> projectionWeightsData = GenerateRandomData<float>(tensorInfo16x20.GetNumElements());
504     armnn::ConstTensor projectionWeights(tensorInfo16x20, projectionWeightsData);
505 
506     armnn::TensorInfo tensorInfo16({outputSize}, armnn::DataType::Float32, 0.0f, 0, true);
507     std::vector<float> projectionBiasData(outputSize, 0.f);
508     armnn::ConstTensor projectionBias(tensorInfo16, projectionBiasData);
509 
510     std::vector<float> inputLayerNormWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
511     armnn::ConstTensor inputLayerNormWeights(tensorInfo20, forgetGateBiasData);
512 
513     std::vector<float> forgetLayerNormWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
514     armnn::ConstTensor forgetLayerNormWeights(tensorInfo20, forgetGateBiasData);
515 
516     std::vector<float> cellLayerNormWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
517     armnn::ConstTensor cellLayerNormWeights(tensorInfo20, forgetGateBiasData);
518 
519     std::vector<float> outLayerNormWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
520     armnn::ConstTensor outLayerNormWeights(tensorInfo20, forgetGateBiasData);
521 
522     armnn::LstmInputParams params;
523     params.m_InputToForgetWeights = &inputToForgetWeights;
524     params.m_InputToCellWeights = &inputToCellWeights;
525     params.m_InputToOutputWeights = &inputToOutputWeights;
526     params.m_RecurrentToForgetWeights = &recurrentToForgetWeights;
527     params.m_RecurrentToCellWeights = &recurrentToCellWeights;
528     params.m_RecurrentToOutputWeights = &recurrentToOutputWeights;
529     params.m_ForgetGateBias = &forgetGateBias;
530     params.m_CellBias = &cellBias;
531     params.m_OutputGateBias = &outputGateBias;
532 
533     // additional params because: descriptor.m_CifgEnabled = false
534     params.m_InputToInputWeights = &inputToInputWeights;
535     params.m_RecurrentToInputWeights = &recurrentToInputWeights;
536     params.m_CellToInputWeights = &cellToInputWeights;
537     params.m_InputGateBias = &inputGateBias;
538 
539     // additional params because: descriptor.m_ProjectionEnabled = true
540     params.m_ProjectionWeights = &projectionWeights;
541     params.m_ProjectionBias = &projectionBias;
542 
543     // additional params because: descriptor.m_PeepholeEnabled = true
544     params.m_CellToForgetWeights = &cellToForgetWeights;
545     params.m_CellToOutputWeights = &cellToOutputWeights;
546 
547     // additional params because: despriptor.m_LayerNormEnabled = true
548     params.m_InputLayerNormWeights = &inputLayerNormWeights;
549     params.m_ForgetLayerNormWeights = &forgetLayerNormWeights;
550     params.m_CellLayerNormWeights = &cellLayerNormWeights;
551     params.m_OutputLayerNormWeights = &outLayerNormWeights;
552 
553     armnn::INetworkPtr network = armnn::INetwork::Create();
554     armnn::IConnectableLayer* const inputLayer   = network->AddInputLayer(0);
555     armnn::IConnectableLayer* const cellStateIn = network->AddInputLayer(1);
556     armnn::IConnectableLayer* const outputStateIn = network->AddInputLayer(2);
557     const std::string layerName("lstm");
558     armnn::IConnectableLayer* const lstmLayer = network->AddLstmLayer(descriptor, params, layerName.c_str());
559     armnn::IConnectableLayer* const scratchBuffer  = network->AddOutputLayer(0);
560     armnn::IConnectableLayer* const outputStateOut  = network->AddOutputLayer(1);
561     armnn::IConnectableLayer* const cellStateOut  = network->AddOutputLayer(2);
562     armnn::IConnectableLayer* const outputLayer  = network->AddOutputLayer(3);
563 
564     // connect up
565     armnn::TensorInfo inputTensorInfo({ batchSize, inputSize }, armnn::DataType::Float32);
566     armnn::TensorInfo cellStateTensorInfo({ batchSize, numUnits}, armnn::DataType::Float32);
567     armnn::TensorInfo outputStateTensorInfo({ batchSize, outputSize }, armnn::DataType::Float32);
568     armnn::TensorInfo lstmTensorInfoScratchBuff({ batchSize, numUnits * 4 }, armnn::DataType::Float32);
569 
570     inputLayer->GetOutputSlot(0).Connect(lstmLayer->GetInputSlot(0));
571     inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
572 
573     outputStateIn->GetOutputSlot(0).Connect(lstmLayer->GetInputSlot(1));
574     outputStateIn->GetOutputSlot(0).SetTensorInfo(outputStateTensorInfo);
575 
576     cellStateIn->GetOutputSlot(0).Connect(lstmLayer->GetInputSlot(2));
577     cellStateIn->GetOutputSlot(0).SetTensorInfo(cellStateTensorInfo);
578 
579     lstmLayer->GetOutputSlot(0).Connect(scratchBuffer->GetInputSlot(0));
580     lstmLayer->GetOutputSlot(0).SetTensorInfo(lstmTensorInfoScratchBuff);
581 
582     lstmLayer->GetOutputSlot(1).Connect(outputStateOut->GetInputSlot(0));
583     lstmLayer->GetOutputSlot(1).SetTensorInfo(outputStateTensorInfo);
584 
585     lstmLayer->GetOutputSlot(2).Connect(cellStateOut->GetInputSlot(0));
586     lstmLayer->GetOutputSlot(2).SetTensorInfo(cellStateTensorInfo);
587 
588     lstmLayer->GetOutputSlot(3).Connect(outputLayer->GetInputSlot(0));
589     lstmLayer->GetOutputSlot(3).SetTensorInfo(outputStateTensorInfo);
590 
591     armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
592     CHECK(deserializedNetwork);
593 
594     VerifyLstmLayer<armnn::LstmDescriptor> checker(
595             layerName,
596             {inputTensorInfo, outputStateTensorInfo, cellStateTensorInfo},
597             {lstmTensorInfoScratchBuff, outputStateTensorInfo, cellStateTensorInfo, outputStateTensorInfo},
598             descriptor,
599             params);
600     deserializedNetwork->ExecuteStrategy(checker);
601 }
602 
603 TEST_CASE("EnsureLstmLayersBackwardCompatibility")
604 {
605     // The hex data below is a flat buffer containing a lstm layer with no Cifg, with peephole and projection
606     // enabled. That data was obtained before additional layer normalization parameters where added to the
607     // lstm serializer. That way it can be tested if a lstm model with the old parameter configuration can
608     // still be loaded
609     const std::vector<uint8_t> lstmNoCifgWithPeepholeAndProjectionModel =
610     {
611         0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x0A, 0x00,
612         0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
613         0xDC, 0x29, 0x00, 0x00, 0x38, 0x29, 0x00, 0x00, 0xB4, 0x28, 0x00, 0x00, 0x94, 0x01, 0x00, 0x00, 0x3C, 0x01,
614         0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
615         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00,
616         0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x70, 0xD6, 0xFF, 0xFF,
617         0x00, 0x00, 0x00, 0x0B, 0x04, 0x00, 0x00, 0x00, 0x06, 0xD7, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x88, 0xD7,
618         0xFF, 0xFF, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xF6, 0xD6, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00,
619         0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
620         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621         0xE8, 0xD7, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xC8, 0xD6, 0xFF, 0xFF, 0x00, 0x00,
622         0x00, 0x0B, 0x04, 0x00, 0x00, 0x00, 0x5E, 0xD7, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0xE0, 0xD7, 0xFF, 0xFF,
623         0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4E, 0xD7, 0xFF, 0xFF, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00,
624         0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
625         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xD8,
626         0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0xD7, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x0B,
627         0x04, 0x00, 0x00, 0x00, 0xB6, 0xD7, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x38, 0xD8, 0xFF, 0xFF, 0x08, 0x00,
628         0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xA6, 0xD7, 0xFF, 0xFF, 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
629         0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630         0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0xD8, 0xFF, 0xFF,
631         0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, 0xD7, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x0B, 0x04, 0x00,
632         0x00, 0x00, 0x0E, 0xD8, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x16, 0xD8, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00,
633         0xFA, 0xD7, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00,
634         0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
635         0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0xD8, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
636         0x00, 0x00, 0x6C, 0xD8, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x23, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00,
637         0x12, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0xE0, 0x25, 0x00, 0x00, 0xD0, 0x25,
638         0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x48, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0C, 0x00,
639         0x10, 0x00, 0x14, 0x00, 0x18, 0x00, 0x1C, 0x00, 0x20, 0x00, 0x24, 0x00, 0x28, 0x00, 0x2C, 0x00, 0x30, 0x00,
640         0x34, 0x00, 0x38, 0x00, 0x3C, 0x00, 0x40, 0x00, 0x44, 0x00, 0x26, 0x00, 0x00, 0x00, 0xC4, 0x23, 0x00, 0x00,
641         0xF8, 0x21, 0x00, 0x00, 0x2C, 0x20, 0x00, 0x00, 0xF0, 0x1A, 0x00, 0x00, 0xB4, 0x15, 0x00, 0x00, 0x78, 0x10,
642         0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x68, 0x0F, 0x00, 0x00, 0xE0, 0x0E, 0x00, 0x00, 0x14, 0x0D, 0x00, 0x00,
643         0xD8, 0x07, 0x00, 0x00, 0x50, 0x07, 0x00, 0x00, 0xC8, 0x06, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x14, 0x01,
644         0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xEE, 0xD7, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03,
645         0x64, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xFE, 0xD8, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00,
646         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xD8, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01,
651         0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x72, 0xD8,
652         0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0x64, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x82, 0xD9, 0xFF, 0xFF,
653         0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
654         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
655         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
656         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
657         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xD8,
658         0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
659         0x14, 0x00, 0x00, 0x00, 0xF6, 0xD8, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0x54, 0x00, 0x00, 0x00, 0x04, 0x00,
660         0x00, 0x00, 0x06, 0xDA, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
661         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
662         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
663         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
664         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0xD9, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00,
665         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x6A, 0xD9, 0xFF, 0xFF, 0x00, 0x00,
666         0x00, 0x03, 0x14, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7A, 0xDA, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00,
667         0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
668         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
669         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
670         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
671         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
672         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
673         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
674         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
675         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
676         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
677         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
678         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
679         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
680         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
681         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
682         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
683         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
684         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
685         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
686         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
687         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
688         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
689         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
690         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
691         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
692         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
693         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
694         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
695         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
696         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
697         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
698         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
699         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
700         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
701         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
702         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
703         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
704         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
705         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
706         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
707         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
708         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
709         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
710         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
711         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
712         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
713         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
714         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
715         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
716         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
717         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
718         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
719         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
720         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
721         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
722         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
723         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
724         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
725         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
726         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
727         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
728         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
729         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
730         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
731         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
732         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
733         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
734         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
735         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
736         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
737         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
738         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xDE, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00,
739         0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xA2, 0xDE,
740         0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0x64, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xB2, 0xDF, 0xFF, 0xFF,
741         0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
742         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
743         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
744         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
745         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xDF,
746         0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
747         0x14, 0x00, 0x00, 0x00, 0x26, 0xDF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0x64, 0x00, 0x00, 0x00, 0x04, 0x00,
748         0x00, 0x00, 0x36, 0xE0, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
749         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
750         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
751         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
752         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
753         0x00, 0x00, 0x00, 0x00, 0x92, 0xDF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
754         0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xAA, 0xDF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03,
755         0x14, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xBA, 0xE0, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x40, 0x01,
756         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
757         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
758         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
759         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
760         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
761         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
762         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
763         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
764         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
765         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
766         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
767         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
768         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
769         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
770         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
771         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
772         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
773         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
774         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
775         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
776         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
777         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
778         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
779         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
780         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
781         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
782         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
783         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
784         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
785         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
786         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
787         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
788         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
789         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
790         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
791         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
792         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
793         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
794         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
795         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
796         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
797         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
798         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
799         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
800         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
801         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
802         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
803         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
804         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
805         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
806         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
807         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
808         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
809         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
810         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
811         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
812         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
813         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
814         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
815         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
816         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
817         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
818         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
819         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
820         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
821         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
822         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
823         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
824         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
825         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
826         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
827         0x00, 0x00, 0x00, 0x00, 0xC6, 0xE4, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
828         0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xE2, 0xE4, 0xFF, 0xFF,
829         0x00, 0x00, 0x00, 0x03, 0xA4, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xF2, 0xE5, 0xFF, 0xFF, 0x04, 0x00,
830         0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
831         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
832         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
833         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
834         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
835         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
836         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
837         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
838         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
839         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
840         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
841         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
842         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
843         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
844         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
845         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
846         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
847         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
848         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
849         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
850         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
851         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
852         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8E, 0xE6, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01,
853         0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00,
854         0x00, 0x00, 0xAA, 0xE6, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0x64, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
855         0xBA, 0xE7, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
856         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
857         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
858         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
859         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
860         0x00, 0x00, 0x16, 0xE7, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
861         0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x2E, 0xE7, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0x64, 0x00,
862         0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3E, 0xE8, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
863         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
864         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
865         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
866         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
867         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9A, 0xE7, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00,
868         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xB2, 0xE7, 0xFF, 0xFF,
869         0x00, 0x00, 0x00, 0x03, 0x64, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xC2, 0xE8, 0xFF, 0xFF, 0x04, 0x00,
870         0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
871         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
872         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
873         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
874         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xE8, 0xFF, 0xFF,
875         0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00,
876         0x00, 0x00, 0x36, 0xE8, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0x14, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
877         0x46, 0xE9, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
878         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
879         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
880         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
881         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
882         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
883         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
884         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
885         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
886         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
887         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
888         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
889         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
890         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
891         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
892         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
893         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
894         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
895         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
896         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
897         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
898         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
899         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
900         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
901         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
902         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
903         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
904         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
905         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
906         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
907         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
908         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
909         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
910         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
911         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
912         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
913         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
914         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
915         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
916         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
917         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
918         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
919         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
920         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
921         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
922         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
923         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
924         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
925         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
926         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
927         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
928         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
929         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
930         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
931         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
932         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
933         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
934         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
935         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
936         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
937         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
938         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
939         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
940         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
941         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
942         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
943         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
944         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
945         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
946         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
947         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
948         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0xED, 0xFF, 0xFF,
949         0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00,
950         0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x6E, 0xED, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0x14, 0x05, 0x00, 0x00,
951         0x04, 0x00, 0x00, 0x00, 0x7E, 0xEE, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00,
952         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
953         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
954         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
955         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
956         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
957         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
958         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
959         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
960         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
961         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
962         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
963         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
964         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
965         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
966         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
967         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
968         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
969         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
970         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
971         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
972         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
973         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
974         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
975         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
976         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
977         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
978         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
979         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
980         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
981         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
982         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
983         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
984         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
985         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
986         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
987         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
988         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
989         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
990         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
991         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
992         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
993         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
994         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
995         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
996         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
997         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
998         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
999         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1000         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1001         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1002         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1003         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1004         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1005         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1006         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1007         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1008         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1009         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1010         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1011         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1012         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1013         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1014         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1015         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1016         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1017         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1018         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1019         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1020         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1021         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1022         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1023         0x8A, 0xF2, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
1024         0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xA6, 0xF2, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03,
1025         0x14, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xB6, 0xF3, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x40, 0x01,
1026         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1027         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1028         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1029         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1030         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1031         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1032         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1033         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1034         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1035         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1036         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1037         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1038         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1039         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1040         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1041         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1042         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1043         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1044         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1045         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1046         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1047         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1048         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1049         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1050         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1051         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1052         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1053         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1054         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1055         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1056         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1057         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1058         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1059         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1060         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1061         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1062         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1063         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1064         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1065         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1066         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1067         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1068         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1069         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1070         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1071         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1072         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1073         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1074         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1075         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1076         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1077         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1078         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1079         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1080         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1081         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1082         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1083         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1084         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1085         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1086         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1087         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1088         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1089         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1090         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1091         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1092         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1093         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1094         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1095         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1096         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1097         0x00, 0x00, 0x00, 0x00, 0xC2, 0xF7, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
1098         0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xDE, 0xF7, 0xFF, 0xFF,
1099         0x00, 0x00, 0x00, 0x03, 0xA4, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xEE, 0xF8, 0xFF, 0xFF, 0x04, 0x00,
1100         0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1101         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1102         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1103         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1104         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1105         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1106         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1107         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1108         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1109         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1110         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1111         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1112         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1113         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1114         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1115         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1116         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1117         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1118         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1119         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1120         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1121         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1122         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xF9, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01,
1123         0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00,
1124         0x00, 0x00, 0xA6, 0xF9, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xA4, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1125         0xB6, 0xFA, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1126         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1127         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1128         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1129         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1130         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1131         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1132         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1133         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1134         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1135         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1136         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1137         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1138         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1139         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1140         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1141         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1142         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1143         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1144         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1145         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1146         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1147         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0xFB,
1148         0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1149         0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x6E, 0xFB, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xA4, 0x01,
1150         0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7E, 0xFC, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
1151         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1152         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1153         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1154         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1155         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1156         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1157         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1158         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1159         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1160         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1161         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1162         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1163         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1164         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1165         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1166         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1167         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1168         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1169         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1170         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1171         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1172         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1173         0x00, 0x00, 0x00, 0x00, 0x1A, 0xFD, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
1174         0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0C, 0x00,
1175         0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
1176         0x01, 0x01, 0x04, 0x00, 0x00, 0x00, 0x2E, 0xFE, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1177         0x22, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6C, 0x73,
1178         0x74, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00,
1179         0xB4, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x00, 0x30, 0x00,
1180         0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1181         0xA6, 0xFD, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
1182         0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3C, 0xFF, 0xFF, 0xFF, 0x02, 0x00, 0x00, 0x00,
1183         0x04, 0x00, 0x00, 0x00, 0xCE, 0xFD, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
1184         0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x64, 0xFF, 0xFF, 0xFF,
1185         0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xF6, 0xFD, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00,
1186         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1187         0xB4, 0xFE, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0x1A, 0xFE, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00,
1188         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
1189         0xF0, 0xFF, 0xFF, 0xFF, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
1190         0x10, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1191         0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
1192         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0xFE, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x00,
1193         0x7E, 0xFF, 0xFF, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00,
1194         0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x76, 0xFF, 0xFF, 0xFF, 0x02, 0x00, 0x00, 0x00,
1195         0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
1196         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1197         0x68, 0xFF, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00, 0xCE, 0xFE, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00,
1198         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1199         0x08, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x0C, 0x00,
1200         0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
1201         0x08, 0x00, 0x0E, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00,
1202         0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x18, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x14, 0x00,
1203         0x0E, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00,
1204         0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1205         0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00,
1206         0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6E, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00,
1207         0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x08, 0x00,
1208         0x0C, 0x00, 0x07, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x00,
1209         0xF6, 0xFF, 0xFF, 0xFF, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x0A, 0x00, 0x04, 0x00, 0x06, 0x00,
1210         0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00,
1211         0x0C, 0x00, 0x10, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00,
1212         0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1213         0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00,
1214         0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x08, 0x00, 0x07, 0x00, 0x0C, 0x00,
1215         0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
1216         0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00
1217     };
1218 
1219     armnn::INetworkPtr deserializedNetwork =
1220         DeserializeNetwork(std::string(lstmNoCifgWithPeepholeAndProjectionModel.begin(),
1221                                        lstmNoCifgWithPeepholeAndProjectionModel.end()));
1222 
1223     CHECK(deserializedNetwork);
1224 
1225     // generating the same model parameters which where used to serialize the model (Layer norm is not specified)
1226     armnn::LstmDescriptor descriptor;
1227     descriptor.m_ActivationFunc    = 4;
1228     descriptor.m_ClippingThresProj = 0.0f;
1229     descriptor.m_ClippingThresCell = 0.0f;
1230     descriptor.m_CifgEnabled       = false;
1231     descriptor.m_ProjectionEnabled = true;
1232     descriptor.m_PeepholeEnabled   = true;
1233 
1234     const uint32_t batchSize  = 2u;
1235     const uint32_t inputSize  = 5u;
1236     const uint32_t numUnits   = 20u;
1237     const uint32_t outputSize = 16u;
1238 
1239     armnn::TensorInfo tensorInfo20x5({numUnits, inputSize}, armnn::DataType::Float32, 0.0f, 0, true);
1240     std::vector<float> inputToInputWeightsData(tensorInfo20x5.GetNumElements(), 0.0f);
1241     armnn::ConstTensor inputToInputWeights(tensorInfo20x5, inputToInputWeightsData);
1242 
1243     std::vector<float> inputToForgetWeightsData(tensorInfo20x5.GetNumElements(), 0.0f);
1244     armnn::ConstTensor inputToForgetWeights(tensorInfo20x5, inputToForgetWeightsData);
1245 
1246     std::vector<float> inputToCellWeightsData(tensorInfo20x5.GetNumElements(), 0.0f);
1247     armnn::ConstTensor inputToCellWeights(tensorInfo20x5, inputToCellWeightsData);
1248 
1249     std::vector<float> inputToOutputWeightsData(tensorInfo20x5.GetNumElements(), 0.0f);
1250     armnn::ConstTensor inputToOutputWeights(tensorInfo20x5, inputToOutputWeightsData);
1251 
1252     armnn::TensorInfo tensorInfo20({numUnits}, armnn::DataType::Float32, 0.0f, 0, true);
1253     std::vector<float> inputGateBiasData(tensorInfo20.GetNumElements(), 0.0f);
1254     armnn::ConstTensor inputGateBias(tensorInfo20, inputGateBiasData);
1255 
1256     std::vector<float> forgetGateBiasData(tensorInfo20.GetNumElements(), 0.0f);
1257     armnn::ConstTensor forgetGateBias(tensorInfo20, forgetGateBiasData);
1258 
1259     std::vector<float> cellBiasData(tensorInfo20.GetNumElements(), 0.0f);
1260     armnn::ConstTensor cellBias(tensorInfo20, cellBiasData);
1261 
1262     std::vector<float> outputGateBiasData(tensorInfo20.GetNumElements(), 0.0f);
1263     armnn::ConstTensor outputGateBias(tensorInfo20, outputGateBiasData);
1264 
1265     armnn::TensorInfo tensorInfo20x16({numUnits, outputSize}, armnn::DataType::Float32, 0.0f, 0, true);
1266     std::vector<float> recurrentToInputWeightsData(tensorInfo20x16.GetNumElements(), 0.0f);
1267     armnn::ConstTensor recurrentToInputWeights(tensorInfo20x16, recurrentToInputWeightsData);
1268 
1269     std::vector<float> recurrentToForgetWeightsData(tensorInfo20x16.GetNumElements(), 0.0f);
1270     armnn::ConstTensor recurrentToForgetWeights(tensorInfo20x16, recurrentToForgetWeightsData);
1271 
1272     std::vector<float> recurrentToCellWeightsData(tensorInfo20x16.GetNumElements(), 0.0f);
1273     armnn::ConstTensor recurrentToCellWeights(tensorInfo20x16, recurrentToCellWeightsData);
1274 
1275     std::vector<float> recurrentToOutputWeightsData(tensorInfo20x16.GetNumElements(), 0.0f);
1276     armnn::ConstTensor recurrentToOutputWeights(tensorInfo20x16, recurrentToOutputWeightsData);
1277 
1278     std::vector<float> cellToInputWeightsData(tensorInfo20.GetNumElements(), 0.0f);
1279     armnn::ConstTensor cellToInputWeights(tensorInfo20, cellToInputWeightsData);
1280 
1281     std::vector<float> cellToForgetWeightsData(tensorInfo20.GetNumElements(), 0.0f);
1282     armnn::ConstTensor cellToForgetWeights(tensorInfo20, cellToForgetWeightsData);
1283 
1284     std::vector<float> cellToOutputWeightsData(tensorInfo20.GetNumElements(), 0.0f);
1285     armnn::ConstTensor cellToOutputWeights(tensorInfo20,  cellToOutputWeightsData);
1286 
1287     armnn::TensorInfo tensorInfo16x20({outputSize, numUnits}, armnn::DataType::Float32, 0.0f, 0, true);
1288     std::vector<float> projectionWeightsData(tensorInfo16x20.GetNumElements(), 0.0f);
1289     armnn::ConstTensor projectionWeights(tensorInfo16x20, projectionWeightsData);
1290 
1291     armnn::TensorInfo tensorInfo16({outputSize}, armnn::DataType::Float32, 0.0f, 0, true);
1292     std::vector<float> projectionBiasData(outputSize, 0.0f);
1293     armnn::ConstTensor projectionBias(tensorInfo16, projectionBiasData);
1294 
1295     armnn::LstmInputParams params;
1296     params.m_InputToForgetWeights     = &inputToForgetWeights;
1297     params.m_InputToCellWeights       = &inputToCellWeights;
1298     params.m_InputToOutputWeights     = &inputToOutputWeights;
1299     params.m_RecurrentToForgetWeights = &recurrentToForgetWeights;
1300     params.m_RecurrentToCellWeights   = &recurrentToCellWeights;
1301     params.m_RecurrentToOutputWeights = &recurrentToOutputWeights;
1302     params.m_ForgetGateBias           = &forgetGateBias;
1303     params.m_CellBias                 = &cellBias;
1304     params.m_OutputGateBias           = &outputGateBias;
1305 
1306     // additional params because: descriptor.m_CifgEnabled = false
1307     params.m_InputToInputWeights      = &inputToInputWeights;
1308     params.m_RecurrentToInputWeights  = &recurrentToInputWeights;
1309     params.m_CellToInputWeights       = &cellToInputWeights;
1310     params.m_InputGateBias            = &inputGateBias;
1311 
1312     // additional params because: descriptor.m_ProjectionEnabled = true
1313     params.m_ProjectionWeights        = &projectionWeights;
1314     params.m_ProjectionBias           = &projectionBias;
1315 
1316     // additional params because: descriptor.m_PeepholeEnabled = true
1317     params.m_CellToForgetWeights      = &cellToForgetWeights;
1318     params.m_CellToOutputWeights      = &cellToOutputWeights;
1319 
1320     const std::string layerName("lstm");
1321     armnn::TensorInfo inputTensorInfo({ batchSize, inputSize }, armnn::DataType::Float32, 0.0f , 0);
1322     armnn::TensorInfo cellStateTensorInfo({ batchSize, numUnits}, armnn::DataType::Float32, 0.0f , 0);
1323     armnn::TensorInfo outputStateTensorInfo({ batchSize, outputSize }, armnn::DataType::Float32, 0.0f , 0);
1324     armnn::TensorInfo lstmTensorInfoScratchBuff({ batchSize, numUnits * 4 }, armnn::DataType::Float32, 0.0f , 0);
1325 
1326     VerifyLstmLayer<armnn::LstmDescriptor> checker(
1327             layerName,
1328             {inputTensorInfo, outputStateTensorInfo, cellStateTensorInfo},
1329             {lstmTensorInfoScratchBuff, outputStateTensorInfo, cellStateTensorInfo, outputStateTensorInfo},
1330             descriptor,
1331             params);
1332     deserializedNetwork->ExecuteStrategy(checker);
1333 }
1334 
ConstantsVector2QuantizedLstmInputParams(const std::vector<armnn::ConstTensor> & constants)1335 armnn::QuantizedLstmInputParams ConstantsVector2QuantizedLstmInputParams(
1336         const std::vector<armnn::ConstTensor>& constants)
1337 {
1338     armnn::QuantizedLstmInputParams params;
1339 
1340     // index for constants vector
1341     size_t i = 0;
1342 
1343     // Get input parameters
1344     params.m_InputToInputWeights  = &constants[i++];
1345     params.m_InputToForgetWeights = &constants[i++];
1346     params.m_InputToCellWeights   = &constants[i++];
1347     params.m_InputToOutputWeights = &constants[i++];
1348 
1349     params.m_RecurrentToInputWeights  = &constants[i++];
1350     params.m_RecurrentToForgetWeights = &constants[i++];
1351     params.m_RecurrentToCellWeights   = &constants[i++];
1352     params.m_RecurrentToOutputWeights = &constants[i++];
1353 
1354     params.m_InputGateBias  = &constants[i++];
1355     params.m_ForgetGateBias = &constants[i++];
1356     params.m_CellBias       = &constants[i++];
1357     params.m_OutputGateBias = &constants[i++];
1358 
1359     return params;
1360 }
1361 
1362 class VerifyQuantizedLstmLayer : public LayerVerifierBase
1363 {
1364 
1365 public:
VerifyQuantizedLstmLayer(const std::string & layerName,const std::vector<armnn::TensorInfo> & inputInfos,const std::vector<armnn::TensorInfo> & outputInfos,const armnn::QuantizedLstmInputParams & inputParams)1366     VerifyQuantizedLstmLayer(const std::string& layerName,
1367                              const std::vector<armnn::TensorInfo>& inputInfos,
1368                              const std::vector<armnn::TensorInfo>& outputInfos,
1369                              const armnn::QuantizedLstmInputParams& inputParams)
1370         : LayerVerifierBase(layerName, inputInfos, outputInfos), m_InputParams(inputParams) {}
1371 
ExecuteStrategy(const armnn::IConnectableLayer * layer,const armnn::BaseDescriptor & descriptor,const std::vector<armnn::ConstTensor> & constants,const char * name,const armnn::LayerBindingId id=0)1372     void ExecuteStrategy(const armnn::IConnectableLayer* layer,
1373                          const armnn::BaseDescriptor& descriptor,
1374                          const std::vector<armnn::ConstTensor>& constants,
1375                          const char* name,
1376                          const armnn::LayerBindingId id = 0) override
1377     {
1378         armnn::IgnoreUnused(descriptor, constants, id);
1379         switch (layer->GetType())
1380         {
1381             case armnn::LayerType::Input: break;
1382             case armnn::LayerType::Output: break;
1383             case armnn::LayerType::QuantizedLstm:
1384             {
1385                 VerifyNameAndConnections(layer, name);
1386                 armnn::QuantizedLstmInputParams params = ConstantsVector2QuantizedLstmInputParams(constants);
1387                 VerifyInputParameters(params);
1388                 break;
1389             }
1390             default:
1391             {
1392                 throw armnn::Exception(fmt::format("Unexpected layer type in QuantizedLstm test model:",
1393                                                            layer->GetName()));
1394             }
1395         }
1396     }
1397 
1398 protected:
VerifyInputParameters(const armnn::QuantizedLstmInputParams & params)1399     void VerifyInputParameters(const armnn::QuantizedLstmInputParams& params)
1400     {
1401         VerifyConstTensors("m_InputToInputWeights",
1402                            m_InputParams.m_InputToInputWeights, params.m_InputToInputWeights);
1403         VerifyConstTensors("m_InputToForgetWeights",
1404                            m_InputParams.m_InputToForgetWeights, params.m_InputToForgetWeights);
1405         VerifyConstTensors("m_InputToCellWeights",
1406                            m_InputParams.m_InputToCellWeights, params.m_InputToCellWeights);
1407         VerifyConstTensors("m_InputToOutputWeights",
1408                            m_InputParams.m_InputToOutputWeights, params.m_InputToOutputWeights);
1409         VerifyConstTensors("m_RecurrentToInputWeights",
1410                            m_InputParams.m_RecurrentToInputWeights, params.m_RecurrentToInputWeights);
1411         VerifyConstTensors("m_RecurrentToForgetWeights",
1412                            m_InputParams.m_RecurrentToForgetWeights, params.m_RecurrentToForgetWeights);
1413         VerifyConstTensors("m_RecurrentToCellWeights",
1414                            m_InputParams.m_RecurrentToCellWeights, params.m_RecurrentToCellWeights);
1415         VerifyConstTensors("m_RecurrentToOutputWeights",
1416                            m_InputParams.m_RecurrentToOutputWeights, params.m_RecurrentToOutputWeights);
1417         VerifyConstTensors("m_InputGateBias",
1418                            m_InputParams.m_InputGateBias, params.m_InputGateBias);
1419         VerifyConstTensors("m_ForgetGateBias",
1420                            m_InputParams.m_ForgetGateBias, params.m_ForgetGateBias);
1421         VerifyConstTensors("m_CellBias",
1422                            m_InputParams.m_CellBias, params.m_CellBias);
1423         VerifyConstTensors("m_OutputGateBias",
1424                            m_InputParams.m_OutputGateBias, params.m_OutputGateBias);
1425     }
1426 
1427 private:
1428     armnn::QuantizedLstmInputParams m_InputParams;
1429 };
1430 
1431 TEST_CASE("SerializeDeserializeQuantizedLstm")
1432 {
1433     const uint32_t batchSize = 1;
1434     const uint32_t inputSize = 2;
1435     const uint32_t numUnits = 4;
1436     const uint32_t outputSize = numUnits;
1437 
1438     // Scale/Offset for input/output, cellState In/Out, weights, bias
1439     float inputOutputScale = 0.0078125f;
1440     int32_t inputOutputOffset = 128;
1441 
1442     float cellStateScale = 0.00048828125f;
1443     int32_t cellStateOffset = 0;
1444 
1445     float weightsScale = 0.00408021f;
1446     int32_t weightsOffset = 100;
1447 
1448     float biasScale = 3.1876640625e-05f;
1449     int32_t biasOffset = 0;
1450 
1451     // The shape of weight data is {outputSize, inputSize} = {4, 2}
1452     armnn::TensorShape inputToInputWeightsShape = {4, 2};
1453     std::vector<uint8_t> inputToInputWeightsData = {1, 2, 3, 4, 5, 6, 7, 8};
1454     armnn::TensorInfo inputToInputWeightsInfo(inputToInputWeightsShape,
1455                                               armnn::DataType::QAsymmU8,
1456                                               weightsScale,
1457                                               weightsOffset,
1458                                               true);
1459     armnn::ConstTensor inputToInputWeights(inputToInputWeightsInfo, inputToInputWeightsData);
1460 
1461     armnn::TensorShape inputToForgetWeightsShape = {4, 2};
1462     std::vector<uint8_t> inputToForgetWeightsData = {1, 2, 3, 4, 5, 6, 7, 8};
1463     armnn::TensorInfo inputToForgetWeightsInfo(inputToForgetWeightsShape,
1464                                                armnn::DataType::QAsymmU8,
1465                                                weightsScale,
1466                                                weightsOffset,
1467                                                true);
1468     armnn::ConstTensor inputToForgetWeights(inputToForgetWeightsInfo, inputToForgetWeightsData);
1469 
1470     armnn::TensorShape inputToCellWeightsShape = {4, 2};
1471     std::vector<uint8_t> inputToCellWeightsData = {1, 2, 3, 4, 5, 6, 7, 8};
1472     armnn::TensorInfo inputToCellWeightsInfo(inputToCellWeightsShape,
1473                                              armnn::DataType::QAsymmU8,
1474                                              weightsScale,
1475                                              weightsOffset,
1476                                              true);
1477     armnn::ConstTensor inputToCellWeights(inputToCellWeightsInfo, inputToCellWeightsData);
1478 
1479     armnn::TensorShape inputToOutputWeightsShape = {4, 2};
1480     std::vector<uint8_t> inputToOutputWeightsData = {1, 2, 3, 4, 5, 6, 7, 8};
1481     armnn::TensorInfo inputToOutputWeightsInfo(inputToOutputWeightsShape,
1482                                                armnn::DataType::QAsymmU8,
1483                                                weightsScale,
1484                                                weightsOffset,
1485                                                true);
1486     armnn::ConstTensor inputToOutputWeights(inputToOutputWeightsInfo, inputToOutputWeightsData);
1487 
1488     // The shape of recurrent weight data is {outputSize, outputSize} = {4, 4}
1489     armnn::TensorShape recurrentToInputWeightsShape = {4, 4};
1490     std::vector<uint8_t> recurrentToInputWeightsData = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
1491     armnn::TensorInfo recurrentToInputWeightsInfo(recurrentToInputWeightsShape,
1492                                                   armnn::DataType::QAsymmU8,
1493                                                   weightsScale,
1494                                                   weightsOffset,
1495                                                   true);
1496     armnn::ConstTensor recurrentToInputWeights(recurrentToInputWeightsInfo, recurrentToInputWeightsData);
1497 
1498     armnn::TensorShape recurrentToForgetWeightsShape = {4, 4};
1499     std::vector<uint8_t> recurrentToForgetWeightsData = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
1500     armnn::TensorInfo recurrentToForgetWeightsInfo(recurrentToForgetWeightsShape,
1501                                                    armnn::DataType::QAsymmU8,
1502                                                    weightsScale,
1503                                                    weightsOffset,
1504                                                    true);
1505     armnn::ConstTensor recurrentToForgetWeights(recurrentToForgetWeightsInfo, recurrentToForgetWeightsData);
1506 
1507     armnn::TensorShape recurrentToCellWeightsShape = {4, 4};
1508     std::vector<uint8_t> recurrentToCellWeightsData = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
1509     armnn::TensorInfo recurrentToCellWeightsInfo(recurrentToCellWeightsShape,
1510                                                  armnn::DataType::QAsymmU8,
1511                                                  weightsScale,
1512                                                  weightsOffset,
1513                                                  true);
1514     armnn::ConstTensor recurrentToCellWeights(recurrentToCellWeightsInfo, recurrentToCellWeightsData);
1515 
1516     armnn::TensorShape recurrentToOutputWeightsShape = {4, 4};
1517     std::vector<uint8_t> recurrentToOutputWeightsData = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
1518     armnn::TensorInfo recurrentToOutputWeightsInfo(recurrentToOutputWeightsShape,
1519                                                    armnn::DataType::QAsymmU8,
1520                                                    weightsScale,
1521                                                    weightsOffset,
1522                                                    true);
1523     armnn::ConstTensor recurrentToOutputWeights(recurrentToOutputWeightsInfo, recurrentToOutputWeightsData);
1524 
1525     // The shape of bias data is {outputSize} = {4}
1526     armnn::TensorShape inputGateBiasShape = {4};
1527     std::vector<int32_t> inputGateBiasData = {1, 2, 3, 4};
1528     armnn::TensorInfo inputGateBiasInfo(inputGateBiasShape,
1529                                         armnn::DataType::Signed32,
1530                                         biasScale,
1531                                         biasOffset,
1532                                         true);
1533     armnn::ConstTensor inputGateBias(inputGateBiasInfo, inputGateBiasData);
1534 
1535     armnn::TensorShape forgetGateBiasShape = {4};
1536     std::vector<int32_t> forgetGateBiasData = {1, 2, 3, 4};
1537     armnn::TensorInfo forgetGateBiasInfo(forgetGateBiasShape,
1538                                          armnn::DataType::Signed32,
1539                                          biasScale,
1540                                          biasOffset,
1541                                          true);
1542     armnn::ConstTensor forgetGateBias(forgetGateBiasInfo, forgetGateBiasData);
1543 
1544     armnn::TensorShape cellBiasShape = {4};
1545     std::vector<int32_t> cellBiasData = {1, 2, 3, 4};
1546     armnn::TensorInfo cellBiasInfo(cellBiasShape,
1547                                    armnn::DataType::Signed32,
1548                                    biasScale,
1549                                    biasOffset,
1550                                    true);
1551     armnn::ConstTensor cellBias(cellBiasInfo, cellBiasData);
1552 
1553     armnn::TensorShape outputGateBiasShape = {4};
1554     std::vector<int32_t> outputGateBiasData = {1, 2, 3, 4};
1555     armnn::TensorInfo outputGateBiasInfo(outputGateBiasShape,
1556                                          armnn::DataType::Signed32,
1557                                          biasScale,
1558                                          biasOffset,
1559                                          true);
1560     armnn::ConstTensor outputGateBias(outputGateBiasInfo, outputGateBiasData);
1561 
1562     armnn::QuantizedLstmInputParams params;
1563     params.m_InputToInputWeights = &inputToInputWeights;
1564     params.m_InputToForgetWeights = &inputToForgetWeights;
1565     params.m_InputToCellWeights = &inputToCellWeights;
1566     params.m_InputToOutputWeights = &inputToOutputWeights;
1567     params.m_RecurrentToInputWeights = &recurrentToInputWeights;
1568     params.m_RecurrentToForgetWeights = &recurrentToForgetWeights;
1569     params.m_RecurrentToCellWeights = &recurrentToCellWeights;
1570     params.m_RecurrentToOutputWeights = &recurrentToOutputWeights;
1571     params.m_InputGateBias = &inputGateBias;
1572     params.m_ForgetGateBias = &forgetGateBias;
1573     params.m_CellBias = &cellBias;
1574     params.m_OutputGateBias = &outputGateBias;
1575 
1576     armnn::INetworkPtr network = armnn::INetwork::Create();
1577     armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1578     armnn::IConnectableLayer* const cellStateIn = network->AddInputLayer(1);
1579     armnn::IConnectableLayer* const outputStateIn = network->AddInputLayer(2);
1580     const std::string layerName("QuantizedLstm");
1581     armnn::IConnectableLayer* const quantizedLstmLayer = network->AddQuantizedLstmLayer(params, layerName.c_str());
1582     armnn::IConnectableLayer* const cellStateOut = network->AddOutputLayer(0);
1583     armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(1);
1584 
1585     // Connect up
1586     armnn::TensorInfo inputTensorInfo({ batchSize, inputSize },
1587                                       armnn::DataType::QAsymmU8,
1588                                       inputOutputScale,
1589                                       inputOutputOffset);
1590     armnn::TensorInfo cellStateTensorInfo({ batchSize, numUnits },
1591                                           armnn::DataType::QSymmS16,
1592                                           cellStateScale,
1593                                           cellStateOffset);
1594     armnn::TensorInfo outputStateTensorInfo({ batchSize, outputSize },
1595                                             armnn::DataType::QAsymmU8,
1596                                             inputOutputScale,
1597                                             inputOutputOffset);
1598 
1599     inputLayer->GetOutputSlot(0).Connect(quantizedLstmLayer->GetInputSlot(0));
1600     inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
1601 
1602     cellStateIn->GetOutputSlot(0).Connect(quantizedLstmLayer->GetInputSlot(1));
1603     cellStateIn->GetOutputSlot(0).SetTensorInfo(cellStateTensorInfo);
1604 
1605     outputStateIn->GetOutputSlot(0).Connect(quantizedLstmLayer->GetInputSlot(2));
1606     outputStateIn->GetOutputSlot(0).SetTensorInfo(outputStateTensorInfo);
1607 
1608     quantizedLstmLayer->GetOutputSlot(0).Connect(cellStateOut->GetInputSlot(0));
1609     quantizedLstmLayer->GetOutputSlot(0).SetTensorInfo(cellStateTensorInfo);
1610 
1611     quantizedLstmLayer->GetOutputSlot(1).Connect(outputLayer->GetInputSlot(0));
1612     quantizedLstmLayer->GetOutputSlot(1).SetTensorInfo(outputStateTensorInfo);
1613 
1614     armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1615     CHECK(deserializedNetwork);
1616 
1617     VerifyQuantizedLstmLayer checker(layerName,
1618                                      {inputTensorInfo, cellStateTensorInfo, outputStateTensorInfo},
1619                                      {cellStateTensorInfo, outputStateTensorInfo},
1620                                      params);
1621 
1622     deserializedNetwork->ExecuteStrategy(checker);
1623 }
1624 
1625 TEST_CASE("SerializeDeserializeQLstmBasic")
1626 {
1627     armnn::QLstmDescriptor descriptor;
1628 
1629     descriptor.m_CifgEnabled       = true;
1630     descriptor.m_ProjectionEnabled = false;
1631     descriptor.m_PeepholeEnabled   = false;
1632     descriptor.m_LayerNormEnabled  = false;
1633 
1634     descriptor.m_CellClip       = 0.0f;
1635     descriptor.m_ProjectionClip = 0.0f;
1636 
1637     descriptor.m_InputIntermediateScale  = 0.00001f;
1638     descriptor.m_ForgetIntermediateScale = 0.00001f;
1639     descriptor.m_CellIntermediateScale   = 0.00001f;
1640     descriptor.m_OutputIntermediateScale = 0.00001f;
1641 
1642     descriptor.m_HiddenStateScale     = 0.07f;
1643     descriptor.m_HiddenStateZeroPoint = 0;
1644 
1645     const unsigned int numBatches = 2;
1646     const unsigned int inputSize  = 5;
1647     const unsigned int outputSize = 4;
1648     const unsigned int numUnits   = 4;
1649 
1650     // Scale/Offset quantization info
1651     float inputScale    = 0.0078f;
1652     int32_t inputOffset = 0;
1653 
1654     float outputScale    = 0.0078f;
1655     int32_t outputOffset = 0;
1656 
1657     float cellStateScale    = 3.5002e-05f;
1658     int32_t cellStateOffset = 0;
1659 
1660     float weightsScale    = 0.007f;
1661     int32_t weightsOffset = 0;
1662 
1663     float biasScale    = 3.5002e-05f / 1024;
1664     int32_t biasOffset = 0;
1665 
1666     // Weights and bias tensor and quantization info
1667     armnn::TensorInfo inputWeightsInfo({numUnits, inputSize},
1668                                        armnn::DataType::QSymmS8,
1669                                        weightsScale,
1670                                        weightsOffset,
1671                                        true);
1672 
1673     armnn::TensorInfo recurrentWeightsInfo({numUnits, outputSize},
1674                                            armnn::DataType::QSymmS8,
1675                                            weightsScale,
1676                                            weightsOffset,
1677                                            true);
1678 
1679     armnn::TensorInfo biasInfo({numUnits}, armnn::DataType::Signed32, biasScale, biasOffset, true);
1680 
1681     std::vector<int8_t> inputToForgetWeightsData = GenerateRandomData<int8_t>(inputWeightsInfo.GetNumElements());
1682     std::vector<int8_t> inputToCellWeightsData   = GenerateRandomData<int8_t>(inputWeightsInfo.GetNumElements());
1683     std::vector<int8_t> inputToOutputWeightsData = GenerateRandomData<int8_t>(inputWeightsInfo.GetNumElements());
1684 
1685     armnn::ConstTensor inputToForgetWeights(inputWeightsInfo, inputToForgetWeightsData);
1686     armnn::ConstTensor inputToCellWeights(inputWeightsInfo, inputToCellWeightsData);
1687     armnn::ConstTensor inputToOutputWeights(inputWeightsInfo, inputToOutputWeightsData);
1688 
1689     std::vector<int8_t> recurrentToForgetWeightsData =
1690             GenerateRandomData<int8_t>(recurrentWeightsInfo.GetNumElements());
1691     std::vector<int8_t> recurrentToCellWeightsData   =
1692             GenerateRandomData<int8_t>(recurrentWeightsInfo.GetNumElements());
1693     std::vector<int8_t> recurrentToOutputWeightsData =
1694             GenerateRandomData<int8_t>(recurrentWeightsInfo.GetNumElements());
1695 
1696     armnn::ConstTensor recurrentToForgetWeights(recurrentWeightsInfo, recurrentToForgetWeightsData);
1697     armnn::ConstTensor recurrentToCellWeights(recurrentWeightsInfo, recurrentToCellWeightsData);
1698     armnn::ConstTensor recurrentToOutputWeights(recurrentWeightsInfo, recurrentToOutputWeightsData);
1699 
1700     std::vector<int32_t> forgetGateBiasData(numUnits, 1);
1701     std::vector<int32_t> cellBiasData(numUnits, 0);
1702     std::vector<int32_t> outputGateBiasData(numUnits, 0);
1703 
1704     armnn::ConstTensor forgetGateBias(biasInfo, forgetGateBiasData);
1705     armnn::ConstTensor cellBias(biasInfo, cellBiasData);
1706     armnn::ConstTensor outputGateBias(biasInfo, outputGateBiasData);
1707 
1708     // Set up params
1709     armnn::LstmInputParams params;
1710     params.m_InputToForgetWeights = &inputToForgetWeights;
1711     params.m_InputToCellWeights   = &inputToCellWeights;
1712     params.m_InputToOutputWeights = &inputToOutputWeights;
1713 
1714     params.m_RecurrentToForgetWeights = &recurrentToForgetWeights;
1715     params.m_RecurrentToCellWeights   = &recurrentToCellWeights;
1716     params.m_RecurrentToOutputWeights = &recurrentToOutputWeights;
1717 
1718     params.m_ForgetGateBias = &forgetGateBias;
1719     params.m_CellBias       = &cellBias;
1720     params.m_OutputGateBias = &outputGateBias;
1721 
1722     // Create network
1723     armnn::INetworkPtr network = armnn::INetwork::Create();
1724     const std::string layerName("qLstm");
1725 
1726     armnn::IConnectableLayer* const input         = network->AddInputLayer(0);
1727     armnn::IConnectableLayer* const outputStateIn = network->AddInputLayer(1);
1728     armnn::IConnectableLayer* const cellStateIn   = network->AddInputLayer(2);
1729 
1730     armnn::IConnectableLayer* const qLstmLayer = network->AddQLstmLayer(descriptor, params, layerName.c_str());
1731 
1732     armnn::IConnectableLayer* const outputStateOut = network->AddOutputLayer(0);
1733     armnn::IConnectableLayer* const cellStateOut   = network->AddOutputLayer(1);
1734     armnn::IConnectableLayer* const outputLayer    = network->AddOutputLayer(2);
1735 
1736     // Input/Output tensor info
1737     armnn::TensorInfo inputInfo({numBatches , inputSize},
1738                                 armnn::DataType::QAsymmS8,
1739                                 inputScale,
1740                                 inputOffset);
1741 
1742     armnn::TensorInfo cellStateInfo({numBatches , numUnits},
1743                                     armnn::DataType::QSymmS16,
1744                                     cellStateScale,
1745                                     cellStateOffset);
1746 
1747     armnn::TensorInfo outputStateInfo({numBatches , outputSize},
1748                                       armnn::DataType::QAsymmS8,
1749                                       outputScale,
1750                                       outputOffset);
1751 
1752     // Connect input/output slots
1753     input->GetOutputSlot(0).Connect(qLstmLayer->GetInputSlot(0));
1754     input->GetOutputSlot(0).SetTensorInfo(inputInfo);
1755 
1756     outputStateIn->GetOutputSlot(0).Connect(qLstmLayer->GetInputSlot(1));
1757     outputStateIn->GetOutputSlot(0).SetTensorInfo(cellStateInfo);
1758 
1759     cellStateIn->GetOutputSlot(0).Connect(qLstmLayer->GetInputSlot(2));
1760     cellStateIn->GetOutputSlot(0).SetTensorInfo(outputStateInfo);
1761 
1762     qLstmLayer->GetOutputSlot(0).Connect(outputStateOut->GetInputSlot(0));
1763     qLstmLayer->GetOutputSlot(0).SetTensorInfo(outputStateInfo);
1764 
1765     qLstmLayer->GetOutputSlot(1).Connect(cellStateOut->GetInputSlot(0));
1766     qLstmLayer->GetOutputSlot(1).SetTensorInfo(cellStateInfo);
1767 
1768     qLstmLayer->GetOutputSlot(2).Connect(outputLayer->GetInputSlot(0));
1769     qLstmLayer->GetOutputSlot(2).SetTensorInfo(outputStateInfo);
1770 
1771     armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1772     CHECK(deserializedNetwork);
1773 
1774     VerifyLstmLayer<armnn::QLstmDescriptor> checker(
1775             layerName,
1776             {inputInfo, cellStateInfo, outputStateInfo},
1777             {outputStateInfo, cellStateInfo, outputStateInfo},
1778             descriptor,
1779             params);
1780 
1781     deserializedNetwork->ExecuteStrategy(checker);
1782 }
1783 
1784 TEST_CASE("SerializeDeserializeQLstmCifgLayerNorm")
1785 {
1786     armnn::QLstmDescriptor descriptor;
1787 
1788     // CIFG params are used when CIFG is disabled
1789     descriptor.m_CifgEnabled       = true;
1790     descriptor.m_ProjectionEnabled = false;
1791     descriptor.m_PeepholeEnabled   = false;
1792     descriptor.m_LayerNormEnabled  = true;
1793 
1794     descriptor.m_CellClip       = 0.0f;
1795     descriptor.m_ProjectionClip = 0.0f;
1796 
1797     descriptor.m_InputIntermediateScale  = 0.00001f;
1798     descriptor.m_ForgetIntermediateScale = 0.00001f;
1799     descriptor.m_CellIntermediateScale   = 0.00001f;
1800     descriptor.m_OutputIntermediateScale = 0.00001f;
1801 
1802     descriptor.m_HiddenStateScale     = 0.07f;
1803     descriptor.m_HiddenStateZeroPoint = 0;
1804 
1805     const unsigned int numBatches = 2;
1806     const unsigned int inputSize  = 5;
1807     const unsigned int outputSize = 4;
1808     const unsigned int numUnits   = 4;
1809 
1810     // Scale/Offset quantization info
1811     float inputScale    = 0.0078f;
1812     int32_t inputOffset = 0;
1813 
1814     float outputScale    = 0.0078f;
1815     int32_t outputOffset = 0;
1816 
1817     float cellStateScale    = 3.5002e-05f;
1818     int32_t cellStateOffset = 0;
1819 
1820     float weightsScale    = 0.007f;
1821     int32_t weightsOffset = 0;
1822 
1823     float layerNormScale    = 3.5002e-05f;
1824     int32_t layerNormOffset = 0;
1825 
1826     float biasScale    = layerNormScale / 1024;
1827     int32_t biasOffset = 0;
1828 
1829     // Weights and bias tensor and quantization info
1830     armnn::TensorInfo inputWeightsInfo({numUnits, inputSize},
1831                                        armnn::DataType::QSymmS8,
1832                                        weightsScale,
1833                                        weightsOffset,
1834                                        true);
1835 
1836     armnn::TensorInfo recurrentWeightsInfo({numUnits, outputSize},
1837                                            armnn::DataType::QSymmS8,
1838                                            weightsScale,
1839                                            weightsOffset,
1840                                            true);
1841 
1842     armnn::TensorInfo biasInfo({numUnits},
1843                                armnn::DataType::Signed32,
1844                                biasScale,
1845                                biasOffset,
1846                                true);
1847 
1848     armnn::TensorInfo layerNormWeightsInfo({numUnits},
1849                                            armnn::DataType::QSymmS16,
1850                                            layerNormScale,
1851                                            layerNormOffset,
1852                                            true);
1853 
1854     // Mandatory params
1855     std::vector<int8_t> inputToForgetWeightsData = GenerateRandomData<int8_t>(inputWeightsInfo.GetNumElements());
1856     std::vector<int8_t> inputToCellWeightsData   = GenerateRandomData<int8_t>(inputWeightsInfo.GetNumElements());
1857     std::vector<int8_t> inputToOutputWeightsData = GenerateRandomData<int8_t>(inputWeightsInfo.GetNumElements());
1858 
1859     armnn::ConstTensor inputToForgetWeights(inputWeightsInfo, inputToForgetWeightsData);
1860     armnn::ConstTensor inputToCellWeights(inputWeightsInfo, inputToCellWeightsData);
1861     armnn::ConstTensor inputToOutputWeights(inputWeightsInfo, inputToOutputWeightsData);
1862 
1863     std::vector<int8_t> recurrentToForgetWeightsData =
1864             GenerateRandomData<int8_t>(recurrentWeightsInfo.GetNumElements());
1865     std::vector<int8_t> recurrentToCellWeightsData   =
1866             GenerateRandomData<int8_t>(recurrentWeightsInfo.GetNumElements());
1867     std::vector<int8_t> recurrentToOutputWeightsData =
1868             GenerateRandomData<int8_t>(recurrentWeightsInfo.GetNumElements());
1869 
1870     armnn::ConstTensor recurrentToForgetWeights(recurrentWeightsInfo, recurrentToForgetWeightsData);
1871     armnn::ConstTensor recurrentToCellWeights(recurrentWeightsInfo, recurrentToCellWeightsData);
1872     armnn::ConstTensor recurrentToOutputWeights(recurrentWeightsInfo, recurrentToOutputWeightsData);
1873 
1874     std::vector<int32_t> forgetGateBiasData(numUnits, 1);
1875     std::vector<int32_t> cellBiasData(numUnits, 0);
1876     std::vector<int32_t> outputGateBiasData(numUnits, 0);
1877 
1878     armnn::ConstTensor forgetGateBias(biasInfo, forgetGateBiasData);
1879     armnn::ConstTensor cellBias(biasInfo, cellBiasData);
1880     armnn::ConstTensor outputGateBias(biasInfo, outputGateBiasData);
1881 
1882     // Layer Norm
1883     std::vector<int16_t> forgetLayerNormWeightsData =
1884             GenerateRandomData<int16_t>(layerNormWeightsInfo.GetNumElements());
1885     std::vector<int16_t> cellLayerNormWeightsData =
1886             GenerateRandomData<int16_t>(layerNormWeightsInfo.GetNumElements());
1887     std::vector<int16_t> outputLayerNormWeightsData =
1888             GenerateRandomData<int16_t>(layerNormWeightsInfo.GetNumElements());
1889 
1890     armnn::ConstTensor forgetLayerNormWeights(layerNormWeightsInfo, forgetLayerNormWeightsData);
1891     armnn::ConstTensor cellLayerNormWeights(layerNormWeightsInfo, cellLayerNormWeightsData);
1892     armnn::ConstTensor outputLayerNormWeights(layerNormWeightsInfo, outputLayerNormWeightsData);
1893 
1894     // Set up params
1895     armnn::LstmInputParams params;
1896 
1897     // Mandatory params
1898     params.m_InputToForgetWeights = &inputToForgetWeights;
1899     params.m_InputToCellWeights   = &inputToCellWeights;
1900     params.m_InputToOutputWeights = &inputToOutputWeights;
1901 
1902     params.m_RecurrentToForgetWeights = &recurrentToForgetWeights;
1903     params.m_RecurrentToCellWeights   = &recurrentToCellWeights;
1904     params.m_RecurrentToOutputWeights = &recurrentToOutputWeights;
1905 
1906     params.m_ForgetGateBias = &forgetGateBias;
1907     params.m_CellBias       = &cellBias;
1908     params.m_OutputGateBias = &outputGateBias;
1909 
1910     // Layer Norm
1911     params.m_ForgetLayerNormWeights = &forgetLayerNormWeights;
1912     params.m_CellLayerNormWeights   = &cellLayerNormWeights;
1913     params.m_OutputLayerNormWeights = &outputLayerNormWeights;
1914 
1915     // Create network
1916     armnn::INetworkPtr network = armnn::INetwork::Create();
1917     const std::string layerName("qLstm");
1918 
1919     armnn::IConnectableLayer* const input         = network->AddInputLayer(0);
1920     armnn::IConnectableLayer* const outputStateIn = network->AddInputLayer(1);
1921     armnn::IConnectableLayer* const cellStateIn   = network->AddInputLayer(2);
1922 
1923     armnn::IConnectableLayer* const qLstmLayer = network->AddQLstmLayer(descriptor, params, layerName.c_str());
1924 
1925     armnn::IConnectableLayer* const outputStateOut  = network->AddOutputLayer(0);
1926     armnn::IConnectableLayer* const cellStateOut  = network->AddOutputLayer(1);
1927     armnn::IConnectableLayer* const outputLayer  = network->AddOutputLayer(2);
1928 
1929     // Input/Output tensor info
1930     armnn::TensorInfo inputInfo({numBatches , inputSize},
1931                                 armnn::DataType::QAsymmS8,
1932                                 inputScale,
1933                                 inputOffset);
1934 
1935     armnn::TensorInfo cellStateInfo({numBatches , numUnits},
1936                                     armnn::DataType::QSymmS16,
1937                                     cellStateScale,
1938                                     cellStateOffset);
1939 
1940     armnn::TensorInfo outputStateInfo({numBatches , outputSize},
1941                                       armnn::DataType::QAsymmS8,
1942                                       outputScale,
1943                                       outputOffset);
1944 
1945     // Connect input/output slots
1946     input->GetOutputSlot(0).Connect(qLstmLayer->GetInputSlot(0));
1947     input->GetOutputSlot(0).SetTensorInfo(inputInfo);
1948 
1949     outputStateIn->GetOutputSlot(0).Connect(qLstmLayer->GetInputSlot(1));
1950     outputStateIn->GetOutputSlot(0).SetTensorInfo(cellStateInfo);
1951 
1952     cellStateIn->GetOutputSlot(0).Connect(qLstmLayer->GetInputSlot(2));
1953     cellStateIn->GetOutputSlot(0).SetTensorInfo(outputStateInfo);
1954 
1955     qLstmLayer->GetOutputSlot(0).Connect(outputStateOut->GetInputSlot(0));
1956     qLstmLayer->GetOutputSlot(0).SetTensorInfo(outputStateInfo);
1957 
1958     qLstmLayer->GetOutputSlot(1).Connect(cellStateOut->GetInputSlot(0));
1959     qLstmLayer->GetOutputSlot(1).SetTensorInfo(cellStateInfo);
1960 
1961     qLstmLayer->GetOutputSlot(2).Connect(outputLayer->GetInputSlot(0));
1962     qLstmLayer->GetOutputSlot(2).SetTensorInfo(outputStateInfo);
1963 
1964     armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1965     CHECK(deserializedNetwork);
1966 
1967     VerifyLstmLayer<armnn::QLstmDescriptor> checker(layerName,
1968                                                     {inputInfo, cellStateInfo, outputStateInfo},
1969                                                     {outputStateInfo, cellStateInfo, outputStateInfo},
1970                                                     descriptor,
1971                                                     params);
1972 
1973     deserializedNetwork->ExecuteStrategy(checker);
1974 }
1975 
1976 TEST_CASE("SerializeDeserializeQLstmAdvanced")
1977 {
1978     armnn::QLstmDescriptor descriptor;
1979 
1980     descriptor.m_CifgEnabled       = false;
1981     descriptor.m_ProjectionEnabled = true;
1982     descriptor.m_PeepholeEnabled   = true;
1983     descriptor.m_LayerNormEnabled  = true;
1984 
1985     descriptor.m_CellClip       = 0.1f;
1986     descriptor.m_ProjectionClip = 0.1f;
1987 
1988     descriptor.m_InputIntermediateScale  = 0.00001f;
1989     descriptor.m_ForgetIntermediateScale = 0.00001f;
1990     descriptor.m_CellIntermediateScale   = 0.00001f;
1991     descriptor.m_OutputIntermediateScale = 0.00001f;
1992 
1993     descriptor.m_HiddenStateScale     = 0.07f;
1994     descriptor.m_HiddenStateZeroPoint = 0;
1995 
1996     const unsigned int numBatches = 2;
1997     const unsigned int inputSize  = 5;
1998     const unsigned int outputSize = 4;
1999     const unsigned int numUnits   = 4;
2000 
2001     // Scale/Offset quantization info
2002     float inputScale    = 0.0078f;
2003     int32_t inputOffset = 0;
2004 
2005     float outputScale    = 0.0078f;
2006     int32_t outputOffset = 0;
2007 
2008     float cellStateScale    = 3.5002e-05f;
2009     int32_t cellStateOffset = 0;
2010 
2011     float weightsScale    = 0.007f;
2012     int32_t weightsOffset = 0;
2013 
2014     float layerNormScale    = 3.5002e-05f;
2015     int32_t layerNormOffset = 0;
2016 
2017     float biasScale    = layerNormScale / 1024;
2018     int32_t biasOffset = 0;
2019 
2020     // Weights and bias tensor and quantization info
2021     armnn::TensorInfo inputWeightsInfo({numUnits, inputSize},
2022                                        armnn::DataType::QSymmS8,
2023                                        weightsScale,
2024                                        weightsOffset,
2025                                        true);
2026 
2027     armnn::TensorInfo recurrentWeightsInfo({numUnits, outputSize},
2028                                            armnn::DataType::QSymmS8,
2029                                            weightsScale,
2030                                            weightsOffset,
2031                                            true);
2032 
2033     armnn::TensorInfo biasInfo({numUnits},
2034                                armnn::DataType::Signed32,
2035                                biasScale,
2036                                biasOffset,
2037                                true);
2038 
2039     armnn::TensorInfo peepholeWeightsInfo({numUnits},
2040                                           armnn::DataType::QSymmS16,
2041                                           weightsScale,
2042                                           weightsOffset,
2043                                           true);
2044 
2045     armnn::TensorInfo layerNormWeightsInfo({numUnits},
2046                                            armnn::DataType::QSymmS16,
2047                                            layerNormScale,
2048                                            layerNormOffset,
2049                                            true);
2050 
2051     armnn::TensorInfo projectionWeightsInfo({outputSize, numUnits},
2052                                              armnn::DataType::QSymmS8,
2053                                              weightsScale,
2054                                              weightsOffset,
2055                                              true);
2056 
2057     // Mandatory params
2058     std::vector<int8_t> inputToForgetWeightsData = GenerateRandomData<int8_t>(inputWeightsInfo.GetNumElements());
2059     std::vector<int8_t> inputToCellWeightsData   = GenerateRandomData<int8_t>(inputWeightsInfo.GetNumElements());
2060     std::vector<int8_t> inputToOutputWeightsData = GenerateRandomData<int8_t>(inputWeightsInfo.GetNumElements());
2061 
2062     armnn::ConstTensor inputToForgetWeights(inputWeightsInfo, inputToForgetWeightsData);
2063     armnn::ConstTensor inputToCellWeights(inputWeightsInfo, inputToCellWeightsData);
2064     armnn::ConstTensor inputToOutputWeights(inputWeightsInfo, inputToOutputWeightsData);
2065 
2066     std::vector<int8_t> recurrentToForgetWeightsData =
2067             GenerateRandomData<int8_t>(recurrentWeightsInfo.GetNumElements());
2068     std::vector<int8_t> recurrentToCellWeightsData   =
2069             GenerateRandomData<int8_t>(recurrentWeightsInfo.GetNumElements());
2070     std::vector<int8_t> recurrentToOutputWeightsData =
2071             GenerateRandomData<int8_t>(recurrentWeightsInfo.GetNumElements());
2072 
2073     armnn::ConstTensor recurrentToForgetWeights(recurrentWeightsInfo, recurrentToForgetWeightsData);
2074     armnn::ConstTensor recurrentToCellWeights(recurrentWeightsInfo, recurrentToCellWeightsData);
2075     armnn::ConstTensor recurrentToOutputWeights(recurrentWeightsInfo, recurrentToOutputWeightsData);
2076 
2077     std::vector<int32_t> forgetGateBiasData(numUnits, 1);
2078     std::vector<int32_t> cellBiasData(numUnits, 0);
2079     std::vector<int32_t> outputGateBiasData(numUnits, 0);
2080 
2081     armnn::ConstTensor forgetGateBias(biasInfo, forgetGateBiasData);
2082     armnn::ConstTensor cellBias(biasInfo, cellBiasData);
2083     armnn::ConstTensor outputGateBias(biasInfo, outputGateBiasData);
2084 
2085     // CIFG
2086     std::vector<int8_t> inputToInputWeightsData = GenerateRandomData<int8_t>(inputWeightsInfo.GetNumElements());
2087     std::vector<int8_t> recurrentToInputWeightsData =
2088             GenerateRandomData<int8_t>(recurrentWeightsInfo.GetNumElements());
2089     std::vector<int32_t> inputGateBiasData(numUnits, 1);
2090 
2091     armnn::ConstTensor inputToInputWeights(inputWeightsInfo, inputToInputWeightsData);
2092     armnn::ConstTensor recurrentToInputWeights(recurrentWeightsInfo, recurrentToInputWeightsData);
2093     armnn::ConstTensor inputGateBias(biasInfo, inputGateBiasData);
2094 
2095     // Peephole
2096     std::vector<int16_t> cellToInputWeightsData  = GenerateRandomData<int16_t>(peepholeWeightsInfo.GetNumElements());
2097     std::vector<int16_t> cellToForgetWeightsData = GenerateRandomData<int16_t>(peepholeWeightsInfo.GetNumElements());
2098     std::vector<int16_t> cellToOutputWeightsData = GenerateRandomData<int16_t>(peepholeWeightsInfo.GetNumElements());
2099 
2100     armnn::ConstTensor cellToInputWeights(peepholeWeightsInfo, cellToInputWeightsData);
2101     armnn::ConstTensor cellToForgetWeights(peepholeWeightsInfo, cellToForgetWeightsData);
2102     armnn::ConstTensor cellToOutputWeights(peepholeWeightsInfo, cellToOutputWeightsData);
2103 
2104     // Projection
2105     std::vector<int8_t> projectionWeightsData = GenerateRandomData<int8_t>(projectionWeightsInfo.GetNumElements());
2106     std::vector<int32_t> projectionBiasData(outputSize, 1);
2107 
2108     armnn::ConstTensor projectionWeights(projectionWeightsInfo, projectionWeightsData);
2109     armnn::ConstTensor projectionBias(biasInfo, projectionBiasData);
2110 
2111     // Layer Norm
2112     std::vector<int16_t> inputLayerNormWeightsData =
2113             GenerateRandomData<int16_t>(layerNormWeightsInfo.GetNumElements());
2114     std::vector<int16_t> forgetLayerNormWeightsData =
2115             GenerateRandomData<int16_t>(layerNormWeightsInfo.GetNumElements());
2116     std::vector<int16_t> cellLayerNormWeightsData =
2117             GenerateRandomData<int16_t>(layerNormWeightsInfo.GetNumElements());
2118     std::vector<int16_t> outputLayerNormWeightsData =
2119             GenerateRandomData<int16_t>(layerNormWeightsInfo.GetNumElements());
2120 
2121     armnn::ConstTensor inputLayerNormWeights(layerNormWeightsInfo, inputLayerNormWeightsData);
2122     armnn::ConstTensor forgetLayerNormWeights(layerNormWeightsInfo, forgetLayerNormWeightsData);
2123     armnn::ConstTensor cellLayerNormWeights(layerNormWeightsInfo, cellLayerNormWeightsData);
2124     armnn::ConstTensor outputLayerNormWeights(layerNormWeightsInfo, outputLayerNormWeightsData);
2125 
2126     // Set up params
2127     armnn::LstmInputParams params;
2128 
2129     // Mandatory params
2130     params.m_InputToForgetWeights = &inputToForgetWeights;
2131     params.m_InputToCellWeights   = &inputToCellWeights;
2132     params.m_InputToOutputWeights = &inputToOutputWeights;
2133 
2134     params.m_RecurrentToForgetWeights = &recurrentToForgetWeights;
2135     params.m_RecurrentToCellWeights   = &recurrentToCellWeights;
2136     params.m_RecurrentToOutputWeights = &recurrentToOutputWeights;
2137 
2138     params.m_ForgetGateBias = &forgetGateBias;
2139     params.m_CellBias       = &cellBias;
2140     params.m_OutputGateBias = &outputGateBias;
2141 
2142     // CIFG
2143     params.m_InputToInputWeights     = &inputToInputWeights;
2144     params.m_RecurrentToInputWeights = &recurrentToInputWeights;
2145     params.m_InputGateBias           = &inputGateBias;
2146 
2147     // Peephole
2148     params.m_CellToInputWeights  = &cellToInputWeights;
2149     params.m_CellToForgetWeights = &cellToForgetWeights;
2150     params.m_CellToOutputWeights = &cellToOutputWeights;
2151 
2152     // Projection
2153     params.m_ProjectionWeights = &projectionWeights;
2154     params.m_ProjectionBias    = &projectionBias;
2155 
2156     // Layer Norm
2157     params.m_InputLayerNormWeights  = &inputLayerNormWeights;
2158     params.m_ForgetLayerNormWeights = &forgetLayerNormWeights;
2159     params.m_CellLayerNormWeights   = &cellLayerNormWeights;
2160     params.m_OutputLayerNormWeights = &outputLayerNormWeights;
2161 
2162     // Create network
2163     armnn::INetworkPtr network = armnn::INetwork::Create();
2164     const std::string layerName("qLstm");
2165 
2166     armnn::IConnectableLayer* const input         = network->AddInputLayer(0);
2167     armnn::IConnectableLayer* const outputStateIn = network->AddInputLayer(1);
2168     armnn::IConnectableLayer* const cellStateIn   = network->AddInputLayer(2);
2169 
2170     armnn::IConnectableLayer* const qLstmLayer = network->AddQLstmLayer(descriptor, params, layerName.c_str());
2171 
2172     armnn::IConnectableLayer* const outputStateOut = network->AddOutputLayer(0);
2173     armnn::IConnectableLayer* const cellStateOut   = network->AddOutputLayer(1);
2174     armnn::IConnectableLayer* const outputLayer    = network->AddOutputLayer(2);
2175 
2176     // Input/Output tensor info
2177     armnn::TensorInfo inputInfo({numBatches , inputSize},
2178                                 armnn::DataType::QAsymmS8,
2179                                 inputScale,
2180                                 inputOffset);
2181 
2182     armnn::TensorInfo cellStateInfo({numBatches , numUnits},
2183                                     armnn::DataType::QSymmS16,
2184                                     cellStateScale,
2185                                     cellStateOffset);
2186 
2187     armnn::TensorInfo outputStateInfo({numBatches , outputSize},
2188                                       armnn::DataType::QAsymmS8,
2189                                       outputScale,
2190                                       outputOffset);
2191 
2192     // Connect input/output slots
2193     input->GetOutputSlot(0).Connect(qLstmLayer->GetInputSlot(0));
2194     input->GetOutputSlot(0).SetTensorInfo(inputInfo);
2195 
2196     outputStateIn->GetOutputSlot(0).Connect(qLstmLayer->GetInputSlot(1));
2197     outputStateIn->GetOutputSlot(0).SetTensorInfo(cellStateInfo);
2198 
2199     cellStateIn->GetOutputSlot(0).Connect(qLstmLayer->GetInputSlot(2));
2200     cellStateIn->GetOutputSlot(0).SetTensorInfo(outputStateInfo);
2201 
2202     qLstmLayer->GetOutputSlot(0).Connect(outputStateOut->GetInputSlot(0));
2203     qLstmLayer->GetOutputSlot(0).SetTensorInfo(outputStateInfo);
2204 
2205     qLstmLayer->GetOutputSlot(1).Connect(cellStateOut->GetInputSlot(0));
2206     qLstmLayer->GetOutputSlot(1).SetTensorInfo(cellStateInfo);
2207 
2208     qLstmLayer->GetOutputSlot(2).Connect(outputLayer->GetInputSlot(0));
2209     qLstmLayer->GetOutputSlot(2).SetTensorInfo(outputStateInfo);
2210 
2211     armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2212     CHECK(deserializedNetwork);
2213 
2214     VerifyLstmLayer<armnn::QLstmDescriptor> checker(layerName,
2215                                                     {inputInfo, cellStateInfo, outputStateInfo},
2216                                                     {outputStateInfo, cellStateInfo, outputStateInfo},
2217                                                     descriptor,
2218                                                     params);
2219 
2220     deserializedNetwork->ExecuteStrategy(checker);
2221 }
2222 
2223 TEST_CASE("SerializeDeserializeUnidirectionalSequenceLstmCifgPeepholeNoProjection")
2224 {
2225     armnn::UnidirectionalSequenceLstmDescriptor descriptor;
2226     descriptor.m_ActivationFunc = 4;
2227     descriptor.m_ClippingThresProj = 0.0f;
2228     descriptor.m_ClippingThresCell = 0.0f;
2229     descriptor.m_CifgEnabled = true; // if this is true then we DON'T need to set the OptCifgParams
2230     descriptor.m_ProjectionEnabled = false;
2231     descriptor.m_PeepholeEnabled = true;
2232     descriptor.m_TimeMajor = false;
2233 
2234     const uint32_t batchSize = 1;
2235     const uint32_t timeSize = 2;
2236     const uint32_t inputSize = 2;
2237     const uint32_t numUnits = 4;
2238     const uint32_t outputSize = numUnits;
2239 
2240     armnn::TensorInfo inputWeightsInfo1({numUnits, inputSize}, armnn::DataType::Float32, 0.0f, 0, true);
2241     std::vector<float> inputToForgetWeightsData = GenerateRandomData<float>(inputWeightsInfo1.GetNumElements());
2242     armnn::ConstTensor inputToForgetWeights(inputWeightsInfo1, inputToForgetWeightsData);
2243 
2244     std::vector<float> inputToCellWeightsData = GenerateRandomData<float>(inputWeightsInfo1.GetNumElements());
2245     armnn::ConstTensor inputToCellWeights(inputWeightsInfo1, inputToCellWeightsData);
2246 
2247     std::vector<float> inputToOutputWeightsData = GenerateRandomData<float>(inputWeightsInfo1.GetNumElements());
2248     armnn::ConstTensor inputToOutputWeights(inputWeightsInfo1, inputToOutputWeightsData);
2249 
2250     armnn::TensorInfo inputWeightsInfo2({numUnits, outputSize}, armnn::DataType::Float32, 0.0f, 0, true);
2251     std::vector<float> recurrentToForgetWeightsData = GenerateRandomData<float>(inputWeightsInfo2.GetNumElements());
2252     armnn::ConstTensor recurrentToForgetWeights(inputWeightsInfo2, recurrentToForgetWeightsData);
2253 
2254     std::vector<float> recurrentToCellWeightsData = GenerateRandomData<float>(inputWeightsInfo2.GetNumElements());
2255     armnn::ConstTensor recurrentToCellWeights(inputWeightsInfo2, recurrentToCellWeightsData);
2256 
2257     std::vector<float> recurrentToOutputWeightsData = GenerateRandomData<float>(inputWeightsInfo2.GetNumElements());
2258     armnn::ConstTensor recurrentToOutputWeights(inputWeightsInfo2, recurrentToOutputWeightsData);
2259 
2260     armnn::TensorInfo inputWeightsInfo3({numUnits}, armnn::DataType::Float32, 0.0f, 0, true);
2261     std::vector<float> cellToForgetWeightsData = GenerateRandomData<float>(inputWeightsInfo3.GetNumElements());
2262     armnn::ConstTensor cellToForgetWeights(inputWeightsInfo3, cellToForgetWeightsData);
2263 
2264     std::vector<float> cellToOutputWeightsData = GenerateRandomData<float>(inputWeightsInfo3.GetNumElements());
2265     armnn::ConstTensor cellToOutputWeights(inputWeightsInfo3, cellToOutputWeightsData);
2266 
2267     std::vector<float> forgetGateBiasData(numUnits, 1.0f);
2268     armnn::ConstTensor forgetGateBias(inputWeightsInfo3, forgetGateBiasData);
2269 
2270     std::vector<float> cellBiasData(numUnits, 0.0f);
2271     armnn::ConstTensor cellBias(inputWeightsInfo3, cellBiasData);
2272 
2273     std::vector<float> outputGateBiasData(numUnits, 0.0f);
2274     armnn::ConstTensor outputGateBias(inputWeightsInfo3, outputGateBiasData);
2275 
2276     armnn::LstmInputParams params;
2277     params.m_InputToForgetWeights = &inputToForgetWeights;
2278     params.m_InputToCellWeights = &inputToCellWeights;
2279     params.m_InputToOutputWeights = &inputToOutputWeights;
2280     params.m_RecurrentToForgetWeights = &recurrentToForgetWeights;
2281     params.m_RecurrentToCellWeights = &recurrentToCellWeights;
2282     params.m_RecurrentToOutputWeights = &recurrentToOutputWeights;
2283     params.m_ForgetGateBias = &forgetGateBias;
2284     params.m_CellBias = &cellBias;
2285     params.m_OutputGateBias = &outputGateBias;
2286     params.m_CellToForgetWeights = &cellToForgetWeights;
2287     params.m_CellToOutputWeights = &cellToOutputWeights;
2288 
2289     armnn::INetworkPtr network = armnn::INetwork::Create();
2290     armnn::IConnectableLayer* const inputLayer   = network->AddInputLayer(0);
2291     armnn::IConnectableLayer* const cellStateIn = network->AddInputLayer(1);
2292     armnn::IConnectableLayer* const outputStateIn = network->AddInputLayer(2);
2293     const std::string layerName("UnidirectionalSequenceLstm");
2294     armnn::IConnectableLayer* const unidirectionalSequenceLstmLayer =
2295         network->AddUnidirectionalSequenceLstmLayer(descriptor, params, layerName.c_str());
2296     armnn::IConnectableLayer* const outputLayer  = network->AddOutputLayer(0);
2297 
2298     // connect up
2299     armnn::TensorInfo inputTensorInfo({ batchSize, timeSize, inputSize }, armnn::DataType::Float32);
2300     armnn::TensorInfo cellStateTensorInfo({ batchSize, numUnits}, armnn::DataType::Float32);
2301     armnn::TensorInfo outputStateTensorInfo({ batchSize, outputSize }, armnn::DataType::Float32);
2302     armnn::TensorInfo outputStateOutTensorInfo({ batchSize, timeSize, outputSize }, armnn::DataType::Float32);
2303     armnn::TensorInfo cellStateOutTensorInfo({ batchSize, outputSize }, armnn::DataType::Float32);
2304     armnn::TensorInfo outputTensorInfo({ batchSize, timeSize, outputSize }, armnn::DataType::Float32);
2305 
2306     inputLayer->GetOutputSlot(0).Connect(unidirectionalSequenceLstmLayer->GetInputSlot(0));
2307     inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
2308 
2309     outputStateIn->GetOutputSlot(0).Connect(unidirectionalSequenceLstmLayer->GetInputSlot(1));
2310     outputStateIn->GetOutputSlot(0).SetTensorInfo(outputStateTensorInfo);
2311 
2312     cellStateIn->GetOutputSlot(0).Connect(unidirectionalSequenceLstmLayer->GetInputSlot(2));
2313     cellStateIn->GetOutputSlot(0).SetTensorInfo(cellStateTensorInfo);
2314 
2315     unidirectionalSequenceLstmLayer->GetOutputSlot(0).SetTensorInfo(outputStateOutTensorInfo);
2316     unidirectionalSequenceLstmLayer->GetOutputSlot(1).SetTensorInfo(cellStateOutTensorInfo);
2317     unidirectionalSequenceLstmLayer->GetOutputSlot(2).Connect(outputLayer->GetInputSlot(0));
2318     unidirectionalSequenceLstmLayer->GetOutputSlot(2).SetTensorInfo(outputTensorInfo);
2319 
2320     armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2321     CHECK(deserializedNetwork);
2322 
2323     VerifyLstmLayer<armnn::UnidirectionalSequenceLstmDescriptor> checker(
2324         layerName,
2325         {inputTensorInfo, outputStateTensorInfo, cellStateTensorInfo},
2326         {outputStateOutTensorInfo, cellStateOutTensorInfo, outputTensorInfo},
2327         descriptor,
2328         params);
2329     deserializedNetwork->ExecuteStrategy(checker);
2330 }
2331 
2332 TEST_CASE("SerializeDeserializeUnidirectionalSequenceLstmNoCifgWithPeepholeAndProjection")
2333 {
2334     armnn::UnidirectionalSequenceLstmDescriptor descriptor;
2335     descriptor.m_ActivationFunc = 4;
2336     descriptor.m_ClippingThresProj = 0.0f;
2337     descriptor.m_ClippingThresCell = 0.0f;
2338     descriptor.m_CifgEnabled = false; // if this is true then we DON'T need to set the OptCifgParams
2339     descriptor.m_ProjectionEnabled = true;
2340     descriptor.m_PeepholeEnabled = true;
2341     descriptor.m_TimeMajor = false;
2342 
2343     const uint32_t batchSize = 2;
2344     const uint32_t timeSize = 2;
2345     const uint32_t inputSize = 5;
2346     const uint32_t numUnits = 20;
2347     const uint32_t outputSize = 16;
2348 
2349     armnn::TensorInfo tensorInfo20x5({numUnits, inputSize}, armnn::DataType::Float32, 0.0f, 0, true);
2350     std::vector<float> inputToInputWeightsData = GenerateRandomData<float>(tensorInfo20x5.GetNumElements());
2351     armnn::ConstTensor inputToInputWeights(tensorInfo20x5, inputToInputWeightsData);
2352 
2353     std::vector<float> inputToForgetWeightsData = GenerateRandomData<float>(tensorInfo20x5.GetNumElements());
2354     armnn::ConstTensor inputToForgetWeights(tensorInfo20x5, inputToForgetWeightsData);
2355 
2356     std::vector<float> inputToCellWeightsData = GenerateRandomData<float>(tensorInfo20x5.GetNumElements());
2357     armnn::ConstTensor inputToCellWeights(tensorInfo20x5, inputToCellWeightsData);
2358 
2359     std::vector<float> inputToOutputWeightsData = GenerateRandomData<float>(tensorInfo20x5.GetNumElements());
2360     armnn::ConstTensor inputToOutputWeights(tensorInfo20x5, inputToOutputWeightsData);
2361 
2362     armnn::TensorInfo tensorInfo20({numUnits}, armnn::DataType::Float32, 0.0f, 0, true);
2363     std::vector<float> inputGateBiasData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2364     armnn::ConstTensor inputGateBias(tensorInfo20, inputGateBiasData);
2365 
2366     std::vector<float> forgetGateBiasData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2367     armnn::ConstTensor forgetGateBias(tensorInfo20, forgetGateBiasData);
2368 
2369     std::vector<float> cellBiasData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2370     armnn::ConstTensor cellBias(tensorInfo20, cellBiasData);
2371 
2372     std::vector<float> outputGateBiasData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2373     armnn::ConstTensor outputGateBias(tensorInfo20, outputGateBiasData);
2374 
2375     armnn::TensorInfo tensorInfo20x16({numUnits, outputSize}, armnn::DataType::Float32, 0.0f, 0, true);
2376     std::vector<float> recurrentToInputWeightsData = GenerateRandomData<float>(tensorInfo20x16.GetNumElements());
2377     armnn::ConstTensor recurrentToInputWeights(tensorInfo20x16, recurrentToInputWeightsData);
2378 
2379     std::vector<float> recurrentToForgetWeightsData = GenerateRandomData<float>(tensorInfo20x16.GetNumElements());
2380     armnn::ConstTensor recurrentToForgetWeights(tensorInfo20x16, recurrentToForgetWeightsData);
2381 
2382     std::vector<float> recurrentToCellWeightsData = GenerateRandomData<float>(tensorInfo20x16.GetNumElements());
2383     armnn::ConstTensor recurrentToCellWeights(tensorInfo20x16, recurrentToCellWeightsData);
2384 
2385     std::vector<float> recurrentToOutputWeightsData = GenerateRandomData<float>(tensorInfo20x16.GetNumElements());
2386     armnn::ConstTensor recurrentToOutputWeights(tensorInfo20x16, recurrentToOutputWeightsData);
2387 
2388     std::vector<float> cellToInputWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2389     armnn::ConstTensor cellToInputWeights(tensorInfo20, cellToInputWeightsData);
2390 
2391     std::vector<float> cellToForgetWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2392     armnn::ConstTensor cellToForgetWeights(tensorInfo20, cellToForgetWeightsData);
2393 
2394     std::vector<float> cellToOutputWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2395     armnn::ConstTensor cellToOutputWeights(tensorInfo20,  cellToOutputWeightsData);
2396 
2397     armnn::TensorInfo tensorInfo16x20({outputSize, numUnits}, armnn::DataType::Float32, 0.0f, 0, true);
2398     std::vector<float> projectionWeightsData = GenerateRandomData<float>(tensorInfo16x20.GetNumElements());
2399     armnn::ConstTensor projectionWeights(tensorInfo16x20, projectionWeightsData);
2400 
2401     armnn::TensorInfo tensorInfo16({outputSize}, armnn::DataType::Float32, 0.0f, 0, true);
2402     std::vector<float> projectionBiasData(outputSize, 0.f);
2403     armnn::ConstTensor projectionBias(tensorInfo16, projectionBiasData);
2404 
2405     armnn::LstmInputParams params;
2406     params.m_InputToForgetWeights = &inputToForgetWeights;
2407     params.m_InputToCellWeights = &inputToCellWeights;
2408     params.m_InputToOutputWeights = &inputToOutputWeights;
2409     params.m_RecurrentToForgetWeights = &recurrentToForgetWeights;
2410     params.m_RecurrentToCellWeights = &recurrentToCellWeights;
2411     params.m_RecurrentToOutputWeights = &recurrentToOutputWeights;
2412     params.m_ForgetGateBias = &forgetGateBias;
2413     params.m_CellBias = &cellBias;
2414     params.m_OutputGateBias = &outputGateBias;
2415 
2416     // additional params because: descriptor.m_CifgEnabled = false
2417     params.m_InputToInputWeights = &inputToInputWeights;
2418     params.m_RecurrentToInputWeights = &recurrentToInputWeights;
2419     params.m_CellToInputWeights = &cellToInputWeights;
2420     params.m_InputGateBias = &inputGateBias;
2421 
2422     // additional params because: descriptor.m_ProjectionEnabled = true
2423     params.m_ProjectionWeights = &projectionWeights;
2424     params.m_ProjectionBias = &projectionBias;
2425 
2426     // additional params because: descriptor.m_PeepholeEnabled = true
2427     params.m_CellToForgetWeights = &cellToForgetWeights;
2428     params.m_CellToOutputWeights = &cellToOutputWeights;
2429 
2430     armnn::INetworkPtr network = armnn::INetwork::Create();
2431     armnn::IConnectableLayer* const inputLayer   = network->AddInputLayer(0);
2432     armnn::IConnectableLayer* const cellStateIn = network->AddInputLayer(1);
2433     armnn::IConnectableLayer* const outputStateIn = network->AddInputLayer(2);
2434     const std::string layerName("unidirectionalSequenceLstm");
2435     armnn::IConnectableLayer* const unidirectionalSequenceLstmLayer =
2436         network->AddUnidirectionalSequenceLstmLayer(descriptor, params, layerName.c_str());
2437     armnn::IConnectableLayer* const outputLayer  = network->AddOutputLayer(0);
2438 
2439     // connect up
2440     armnn::TensorInfo inputTensorInfo({ batchSize, timeSize, inputSize }, armnn::DataType::Float32);
2441     armnn::TensorInfo cellStateTensorInfo({ batchSize, numUnits}, armnn::DataType::Float32);
2442     armnn::TensorInfo outputStateTensorInfo({ batchSize, outputSize }, armnn::DataType::Float32);
2443     armnn::TensorInfo outputStateOutTensorInfo({ batchSize, timeSize, outputSize }, armnn::DataType::Float32);
2444     armnn::TensorInfo cellStateOutTensorInfo({ batchSize, outputSize }, armnn::DataType::Float32);
2445     armnn::TensorInfo outputTensorInfo({ batchSize, timeSize, outputSize }, armnn::DataType::Float32);
2446 
2447     inputLayer->GetOutputSlot(0).Connect(unidirectionalSequenceLstmLayer->GetInputSlot(0));
2448     inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
2449 
2450     outputStateIn->GetOutputSlot(0).Connect(unidirectionalSequenceLstmLayer->GetInputSlot(1));
2451     outputStateIn->GetOutputSlot(0).SetTensorInfo(outputStateTensorInfo);
2452 
2453     cellStateIn->GetOutputSlot(0).Connect(unidirectionalSequenceLstmLayer->GetInputSlot(2));
2454     cellStateIn->GetOutputSlot(0).SetTensorInfo(cellStateTensorInfo);
2455 
2456     unidirectionalSequenceLstmLayer->GetOutputSlot(0).SetTensorInfo(outputStateOutTensorInfo);
2457     unidirectionalSequenceLstmLayer->GetOutputSlot(1).SetTensorInfo(cellStateOutTensorInfo);
2458     unidirectionalSequenceLstmLayer->GetOutputSlot(2).Connect(outputLayer->GetInputSlot(0));
2459     unidirectionalSequenceLstmLayer->GetOutputSlot(2).SetTensorInfo(outputTensorInfo);
2460 
2461     armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2462     CHECK(deserializedNetwork);
2463 
2464     VerifyLstmLayer<armnn::UnidirectionalSequenceLstmDescriptor> checker(
2465         layerName,
2466         {inputTensorInfo, outputStateTensorInfo, cellStateTensorInfo},
2467         {outputStateOutTensorInfo, cellStateOutTensorInfo, outputTensorInfo},
2468         descriptor,
2469         params);
2470     deserializedNetwork->ExecuteStrategy(checker);
2471 }
2472 
2473 TEST_CASE("SerializeDeserializeUnidirectionalSequenceLstmNoCifgWithPeepholeWithProjectionWithLayerNorm")
2474 {
2475     armnn::UnidirectionalSequenceLstmDescriptor descriptor;
2476     descriptor.m_ActivationFunc = 4;
2477     descriptor.m_ClippingThresProj = 0.0f;
2478     descriptor.m_ClippingThresCell = 0.0f;
2479     descriptor.m_CifgEnabled = false; // if this is true then we DON'T need to set the OptCifgParams
2480     descriptor.m_ProjectionEnabled = true;
2481     descriptor.m_PeepholeEnabled = true;
2482     descriptor.m_LayerNormEnabled = true;
2483     descriptor.m_TimeMajor = false;
2484 
2485     const uint32_t batchSize = 2;
2486     const uint32_t timeSize = 2;
2487     const uint32_t inputSize = 5;
2488     const uint32_t numUnits = 20;
2489     const uint32_t outputSize = 16;
2490 
2491     armnn::TensorInfo tensorInfo20x5({numUnits, inputSize}, armnn::DataType::Float32, 0.0f, 0, true);
2492     std::vector<float> inputToInputWeightsData = GenerateRandomData<float>(tensorInfo20x5.GetNumElements());
2493     armnn::ConstTensor inputToInputWeights(tensorInfo20x5, inputToInputWeightsData);
2494 
2495     std::vector<float> inputToForgetWeightsData = GenerateRandomData<float>(tensorInfo20x5.GetNumElements());
2496     armnn::ConstTensor inputToForgetWeights(tensorInfo20x5, inputToForgetWeightsData);
2497 
2498     std::vector<float> inputToCellWeightsData = GenerateRandomData<float>(tensorInfo20x5.GetNumElements());
2499     armnn::ConstTensor inputToCellWeights(tensorInfo20x5, inputToCellWeightsData);
2500 
2501     std::vector<float> inputToOutputWeightsData = GenerateRandomData<float>(tensorInfo20x5.GetNumElements());
2502     armnn::ConstTensor inputToOutputWeights(tensorInfo20x5, inputToOutputWeightsData);
2503 
2504     armnn::TensorInfo tensorInfo20({numUnits}, armnn::DataType::Float32, 0.0f, 0, true);
2505     std::vector<float> inputGateBiasData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2506     armnn::ConstTensor inputGateBias(tensorInfo20, inputGateBiasData);
2507 
2508     std::vector<float> forgetGateBiasData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2509     armnn::ConstTensor forgetGateBias(tensorInfo20, forgetGateBiasData);
2510 
2511     std::vector<float> cellBiasData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2512     armnn::ConstTensor cellBias(tensorInfo20, cellBiasData);
2513 
2514     std::vector<float> outputGateBiasData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2515     armnn::ConstTensor outputGateBias(tensorInfo20, outputGateBiasData);
2516 
2517     armnn::TensorInfo tensorInfo20x16({numUnits, outputSize}, armnn::DataType::Float32, 0.0f, 0, true);
2518     std::vector<float> recurrentToInputWeightsData = GenerateRandomData<float>(tensorInfo20x16.GetNumElements());
2519     armnn::ConstTensor recurrentToInputWeights(tensorInfo20x16, recurrentToInputWeightsData);
2520 
2521     std::vector<float> recurrentToForgetWeightsData = GenerateRandomData<float>(tensorInfo20x16.GetNumElements());
2522     armnn::ConstTensor recurrentToForgetWeights(tensorInfo20x16, recurrentToForgetWeightsData);
2523 
2524     std::vector<float> recurrentToCellWeightsData = GenerateRandomData<float>(tensorInfo20x16.GetNumElements());
2525     armnn::ConstTensor recurrentToCellWeights(tensorInfo20x16, recurrentToCellWeightsData);
2526 
2527     std::vector<float> recurrentToOutputWeightsData = GenerateRandomData<float>(tensorInfo20x16.GetNumElements());
2528     armnn::ConstTensor recurrentToOutputWeights(tensorInfo20x16, recurrentToOutputWeightsData);
2529 
2530     std::vector<float> cellToInputWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2531     armnn::ConstTensor cellToInputWeights(tensorInfo20, cellToInputWeightsData);
2532 
2533     std::vector<float> cellToForgetWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2534     armnn::ConstTensor cellToForgetWeights(tensorInfo20, cellToForgetWeightsData);
2535 
2536     std::vector<float> cellToOutputWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2537     armnn::ConstTensor cellToOutputWeights(tensorInfo20,  cellToOutputWeightsData);
2538 
2539     armnn::TensorInfo tensorInfo16x20({outputSize, numUnits}, armnn::DataType::Float32, 0.0f, 0, true);
2540     std::vector<float> projectionWeightsData = GenerateRandomData<float>(tensorInfo16x20.GetNumElements());
2541     armnn::ConstTensor projectionWeights(tensorInfo16x20, projectionWeightsData);
2542 
2543     armnn::TensorInfo tensorInfo16({outputSize}, armnn::DataType::Float32, 0.0f, 0, true);
2544     std::vector<float> projectionBiasData(outputSize, 0.f);
2545     armnn::ConstTensor projectionBias(tensorInfo16, projectionBiasData);
2546 
2547     std::vector<float> inputLayerNormWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2548     armnn::ConstTensor inputLayerNormWeights(tensorInfo20, forgetGateBiasData);
2549 
2550     std::vector<float> forgetLayerNormWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2551     armnn::ConstTensor forgetLayerNormWeights(tensorInfo20, forgetGateBiasData);
2552 
2553     std::vector<float> cellLayerNormWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2554     armnn::ConstTensor cellLayerNormWeights(tensorInfo20, forgetGateBiasData);
2555 
2556     std::vector<float> outLayerNormWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2557     armnn::ConstTensor outLayerNormWeights(tensorInfo20, forgetGateBiasData);
2558 
2559     armnn::LstmInputParams params;
2560     params.m_InputToForgetWeights = &inputToForgetWeights;
2561     params.m_InputToCellWeights = &inputToCellWeights;
2562     params.m_InputToOutputWeights = &inputToOutputWeights;
2563     params.m_RecurrentToForgetWeights = &recurrentToForgetWeights;
2564     params.m_RecurrentToCellWeights = &recurrentToCellWeights;
2565     params.m_RecurrentToOutputWeights = &recurrentToOutputWeights;
2566     params.m_ForgetGateBias = &forgetGateBias;
2567     params.m_CellBias = &cellBias;
2568     params.m_OutputGateBias = &outputGateBias;
2569 
2570     // additional params because: descriptor.m_CifgEnabled = false
2571     params.m_InputToInputWeights = &inputToInputWeights;
2572     params.m_RecurrentToInputWeights = &recurrentToInputWeights;
2573     params.m_CellToInputWeights = &cellToInputWeights;
2574     params.m_InputGateBias = &inputGateBias;
2575 
2576     // additional params because: descriptor.m_ProjectionEnabled = true
2577     params.m_ProjectionWeights = &projectionWeights;
2578     params.m_ProjectionBias = &projectionBias;
2579 
2580     // additional params because: descriptor.m_PeepholeEnabled = true
2581     params.m_CellToForgetWeights = &cellToForgetWeights;
2582     params.m_CellToOutputWeights = &cellToOutputWeights;
2583 
2584     // additional params because: despriptor.m_LayerNormEnabled = true
2585     params.m_InputLayerNormWeights = &inputLayerNormWeights;
2586     params.m_ForgetLayerNormWeights = &forgetLayerNormWeights;
2587     params.m_CellLayerNormWeights = &cellLayerNormWeights;
2588     params.m_OutputLayerNormWeights = &outLayerNormWeights;
2589 
2590     armnn::INetworkPtr network = armnn::INetwork::Create();
2591     armnn::IConnectableLayer* const inputLayer   = network->AddInputLayer(0);
2592     armnn::IConnectableLayer* const cellStateIn = network->AddInputLayer(1);
2593     armnn::IConnectableLayer* const outputStateIn = network->AddInputLayer(2);
2594     const std::string layerName("unidirectionalSequenceLstm");
2595     armnn::IConnectableLayer* const unidirectionalSequenceLstmLayer =
2596         network->AddUnidirectionalSequenceLstmLayer(descriptor, params, layerName.c_str());
2597     armnn::IConnectableLayer* const outputLayer  = network->AddOutputLayer(0);
2598 
2599     // connect up
2600     armnn::TensorInfo inputTensorInfo({ batchSize, timeSize, inputSize }, armnn::DataType::Float32);
2601     armnn::TensorInfo cellStateTensorInfo({ batchSize, numUnits}, armnn::DataType::Float32);
2602     armnn::TensorInfo outputStateTensorInfo({ batchSize, outputSize }, armnn::DataType::Float32);
2603     armnn::TensorInfo outputStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
2604     armnn::TensorInfo cellStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
2605     armnn::TensorInfo outputTensorInfo({ batchSize, timeSize, outputSize }, armnn::DataType::Float32);
2606 
2607     inputLayer->GetOutputSlot(0).Connect(unidirectionalSequenceLstmLayer->GetInputSlot(0));
2608     inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
2609 
2610     outputStateIn->GetOutputSlot(0).Connect(unidirectionalSequenceLstmLayer->GetInputSlot(1));
2611     outputStateIn->GetOutputSlot(0).SetTensorInfo(outputStateTensorInfo);
2612 
2613     cellStateIn->GetOutputSlot(0).Connect(unidirectionalSequenceLstmLayer->GetInputSlot(2));
2614     cellStateIn->GetOutputSlot(0).SetTensorInfo(cellStateTensorInfo);
2615 
2616     unidirectionalSequenceLstmLayer->GetOutputSlot(0).SetTensorInfo(outputStateOutTensorInfo);
2617     unidirectionalSequenceLstmLayer->GetOutputSlot(1).SetTensorInfo(cellStateOutTensorInfo);
2618     unidirectionalSequenceLstmLayer->GetOutputSlot(2).Connect(outputLayer->GetInputSlot(0));
2619     unidirectionalSequenceLstmLayer->GetOutputSlot(2).SetTensorInfo(outputTensorInfo);
2620 
2621     armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2622     CHECK(deserializedNetwork);
2623 
2624     VerifyLstmLayer<armnn::UnidirectionalSequenceLstmDescriptor> checker(
2625             layerName,
2626             {inputTensorInfo, outputStateTensorInfo, cellStateTensorInfo},
2627             {outputStateOutTensorInfo, cellStateOutTensorInfo, outputTensorInfo},
2628             descriptor,
2629             params);
2630     deserializedNetwork->ExecuteStrategy(checker);
2631 }
2632 
2633 TEST_CASE("SerializeDeserializeUnidirectionalSequenceLstmCifgPeepholeNoProjectionTimeMajor")
2634 {
2635     armnn::UnidirectionalSequenceLstmDescriptor descriptor;
2636     descriptor.m_ActivationFunc = 4;
2637     descriptor.m_ClippingThresProj = 0.0f;
2638     descriptor.m_ClippingThresCell = 0.0f;
2639     descriptor.m_CifgEnabled = true; // if this is true then we DON'T need to set the OptCifgParams
2640     descriptor.m_ProjectionEnabled = false;
2641     descriptor.m_PeepholeEnabled = true;
2642     descriptor.m_TimeMajor = true;
2643 
2644     const uint32_t batchSize = 1;
2645     const uint32_t timeSize = 2;
2646     const uint32_t inputSize = 2;
2647     const uint32_t numUnits = 4;
2648     const uint32_t outputSize = numUnits;
2649 
2650     armnn::TensorInfo inputWeightsInfo1({numUnits, inputSize}, armnn::DataType::Float32, 0.0f, 0, true);
2651     std::vector<float> inputToForgetWeightsData = GenerateRandomData<float>(inputWeightsInfo1.GetNumElements());
2652     armnn::ConstTensor inputToForgetWeights(inputWeightsInfo1, inputToForgetWeightsData);
2653 
2654     std::vector<float> inputToCellWeightsData = GenerateRandomData<float>(inputWeightsInfo1.GetNumElements());
2655     armnn::ConstTensor inputToCellWeights(inputWeightsInfo1, inputToCellWeightsData);
2656 
2657     std::vector<float> inputToOutputWeightsData = GenerateRandomData<float>(inputWeightsInfo1.GetNumElements());
2658     armnn::ConstTensor inputToOutputWeights(inputWeightsInfo1, inputToOutputWeightsData);
2659 
2660     armnn::TensorInfo inputWeightsInfo2({numUnits, outputSize}, armnn::DataType::Float32, 0.0f, 0, true);
2661     std::vector<float> recurrentToForgetWeightsData = GenerateRandomData<float>(inputWeightsInfo2.GetNumElements());
2662     armnn::ConstTensor recurrentToForgetWeights(inputWeightsInfo2, recurrentToForgetWeightsData);
2663 
2664     std::vector<float> recurrentToCellWeightsData = GenerateRandomData<float>(inputWeightsInfo2.GetNumElements());
2665     armnn::ConstTensor recurrentToCellWeights(inputWeightsInfo2, recurrentToCellWeightsData);
2666 
2667     std::vector<float> recurrentToOutputWeightsData = GenerateRandomData<float>(inputWeightsInfo2.GetNumElements());
2668     armnn::ConstTensor recurrentToOutputWeights(inputWeightsInfo2, recurrentToOutputWeightsData);
2669 
2670     armnn::TensorInfo inputWeightsInfo3({numUnits}, armnn::DataType::Float32, 0.0f, 0, true);
2671     std::vector<float> cellToForgetWeightsData = GenerateRandomData<float>(inputWeightsInfo3.GetNumElements());
2672     armnn::ConstTensor cellToForgetWeights(inputWeightsInfo3, cellToForgetWeightsData);
2673 
2674     std::vector<float> cellToOutputWeightsData = GenerateRandomData<float>(inputWeightsInfo3.GetNumElements());
2675     armnn::ConstTensor cellToOutputWeights(inputWeightsInfo3, cellToOutputWeightsData);
2676 
2677     std::vector<float> forgetGateBiasData(numUnits, 1.0f);
2678     armnn::ConstTensor forgetGateBias(inputWeightsInfo3, forgetGateBiasData);
2679 
2680     std::vector<float> cellBiasData(numUnits, 0.0f);
2681     armnn::ConstTensor cellBias(inputWeightsInfo3, cellBiasData);
2682 
2683     std::vector<float> outputGateBiasData(numUnits, 0.0f);
2684     armnn::ConstTensor outputGateBias(inputWeightsInfo3, outputGateBiasData);
2685 
2686     armnn::LstmInputParams params;
2687     params.m_InputToForgetWeights = &inputToForgetWeights;
2688     params.m_InputToCellWeights = &inputToCellWeights;
2689     params.m_InputToOutputWeights = &inputToOutputWeights;
2690     params.m_RecurrentToForgetWeights = &recurrentToForgetWeights;
2691     params.m_RecurrentToCellWeights = &recurrentToCellWeights;
2692     params.m_RecurrentToOutputWeights = &recurrentToOutputWeights;
2693     params.m_ForgetGateBias = &forgetGateBias;
2694     params.m_CellBias = &cellBias;
2695     params.m_OutputGateBias = &outputGateBias;
2696     params.m_CellToForgetWeights = &cellToForgetWeights;
2697     params.m_CellToOutputWeights = &cellToOutputWeights;
2698 
2699     armnn::INetworkPtr network = armnn::INetwork::Create();
2700     armnn::IConnectableLayer* const inputLayer   = network->AddInputLayer(0);
2701     armnn::IConnectableLayer* const cellStateIn = network->AddInputLayer(1);
2702     armnn::IConnectableLayer* const outputStateIn = network->AddInputLayer(2);
2703     const std::string layerName("UnidirectionalSequenceLstm");
2704     armnn::IConnectableLayer* const unidirectionalSequenceLstmLayer =
2705         network->AddUnidirectionalSequenceLstmLayer(descriptor, params, layerName.c_str());
2706     armnn::IConnectableLayer* const outputLayer  = network->AddOutputLayer(0);
2707 
2708     // connect up
2709     armnn::TensorInfo inputTensorInfo({ timeSize, batchSize, inputSize }, armnn::DataType::Float32);
2710     armnn::TensorInfo cellStateTensorInfo({ batchSize, numUnits}, armnn::DataType::Float32);
2711     armnn::TensorInfo outputStateTensorInfo({ batchSize, outputSize }, armnn::DataType::Float32);
2712     armnn::TensorInfo outputStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
2713     armnn::TensorInfo cellStateOutTensorInfo({batchSize, timeSize, outputSize}, armnn::DataType::Float32);
2714     armnn::TensorInfo outputTensorInfo({ timeSize, batchSize, outputSize }, armnn::DataType::Float32);
2715 
2716     inputLayer->GetOutputSlot(0).Connect(unidirectionalSequenceLstmLayer->GetInputSlot(0));
2717     inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
2718 
2719     outputStateIn->GetOutputSlot(0).Connect(unidirectionalSequenceLstmLayer->GetInputSlot(1));
2720     outputStateIn->GetOutputSlot(0).SetTensorInfo(outputStateTensorInfo);
2721 
2722     cellStateIn->GetOutputSlot(0).Connect(unidirectionalSequenceLstmLayer->GetInputSlot(2));
2723     cellStateIn->GetOutputSlot(0).SetTensorInfo(cellStateTensorInfo);
2724 
2725     unidirectionalSequenceLstmLayer->GetOutputSlot(0).SetTensorInfo(outputStateOutTensorInfo);
2726     unidirectionalSequenceLstmLayer->GetOutputSlot(1).SetTensorInfo(cellStateOutTensorInfo);
2727     unidirectionalSequenceLstmLayer->GetOutputSlot(2).Connect(outputLayer->GetInputSlot(0));
2728     unidirectionalSequenceLstmLayer->GetOutputSlot(2).SetTensorInfo(outputTensorInfo);
2729 
2730     armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2731     CHECK(deserializedNetwork);
2732 
2733     VerifyLstmLayer<armnn::UnidirectionalSequenceLstmDescriptor> checker(
2734         layerName,
2735         {inputTensorInfo, outputStateTensorInfo, cellStateTensorInfo},
2736         {outputStateOutTensorInfo, cellStateOutTensorInfo, outputTensorInfo},
2737         descriptor,
2738         params);
2739     deserializedNetwork->ExecuteStrategy(checker);
2740 }
2741 
2742 }
2743