IVGCVSW-6806 Fixed issue with missing TensorInfos in UnidirectionalSequenceLSTM

 * Corrected TensorInfo order for IsUnidirectionalSequenceLstmSupported
    * outputStateOut TensorInfo is not optional.
    * cellStateOut TensorInfo is not optional.
    * TensorInfo Order matches other QLSTM/LSTM layers.

!armnn:7455

Signed-off-by: Mike Kelly <mike.kelly@arm.com>
Change-Id: I5b0e0fa4b6e1c3da6689d9aefc9b959172c2e7d4
diff --git a/ConversionUtils_1_2.hpp b/ConversionUtils_1_2.hpp
index 1bcd9f2..0ff50cf 100644
--- a/ConversionUtils_1_2.hpp
+++ b/ConversionUtils_1_2.hpp
@@ -3455,6 +3455,18 @@
     // Outputs
     const TensorInfo& outputInfo         = GetTensorInfoForOperand(*output);
 
+    unsigned int batchSize               = inputInfo.GetShape()[0];
+    unsigned int outputSize              = outputInfo.GetShape()[2];
+    unsigned int numUnits                = cellStateInInfo.GetShape()[1];
+
+    armnn::DataType dataType             = inputInfo.GetDataType();
+    float qScale                         = inputInfo.GetQuantizationScale();
+    int qOffset                          = inputInfo.GetQuantizationOffset();
+
+    armnn::TensorInfo cellStateOutInfo({batchSize, numUnits}, cellStateInInfo.GetDataType(),
+                                       cellStateInInfo.GetQuantizationScale(), cellStateInInfo.GetQuantizationOffset());
+    armnn::TensorInfo outputStateOutInfo({batchSize, outputSize}, dataType, qScale, qOffset);
+
     // Basic parameters
     LstmInputParamsInfo paramsInfo;
     paramsInfo.m_InputToForgetWeights     = &(params.m_InputToForgetWeights->GetInfo());
@@ -3505,9 +3517,6 @@
         paramsInfo.m_OutputLayerNormWeights = &(params.m_OutputLayerNormWeights->GetInfo());
     }
 
-    auto hiddenStateOutInfo = EmptyOptional();
-    auto cellStateOutInfo   = EmptyOptional();
-
     bool isSupported = false;
     auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported)
     {
@@ -3518,9 +3527,9 @@
                                    inputInfo,
                                    outputStateInInfo,
                                    cellStateInInfo,
-                                   outputInfo,
-                                   hiddenStateOutInfo,
+                                   outputStateOutInfo,
                                    cellStateOutInfo,
+                                   outputInfo,
                                    desc,
                                    paramsInfo);
     };
@@ -3552,12 +3561,12 @@
 
     if (!isDynamic)
     {
-        return (SetupAndTrackLayerOutputSlot<HalPolicy>(operation, 0, *layer, 0, model, data));
+        return (SetupAndTrackLayerOutputSlot<HalPolicy>(operation, 0, *layer, 2, model, data));
     }
     else
     {
-        return (SetupAndTrackLayerOutputSlot<HalPolicy>(
-                    operation, 0, *layer, 0, model, data, nullptr, validateFunc, ActivationFn::kActivationNone, true));
+        return (SetupAndTrackLayerOutputSlot<HalPolicy>(operation, 0, *layer, 2, model, data, nullptr,
+                                                        validateFunc, ActivationFn::kActivationNone, true));
     }
 }
 
diff --git a/test/UnidirectionalSequenceLstm.hpp b/test/UnidirectionalSequenceLstm.hpp
index d03f8ab..75b7a8d 100644
--- a/test/UnidirectionalSequenceLstm.hpp
+++ b/test/UnidirectionalSequenceLstm.hpp
@@ -138,10 +138,10 @@
                                         const std::vector<float>& outputLayerNormWeightsValue,
                                         const hidl_vec<uint32_t>& outputDimensions,
                                         const std::vector<float>& outputValue,
-                                        const hidl_vec<uint32_t>&,
-                                        const std::vector<float>&,
-                                        const hidl_vec<uint32_t>&,
-                                        const std::vector<float>&,
+                                        const hidl_vec<uint32_t>&, // outputStateOutDimensions,
+                                        const std::vector<float>&, // outputStateOutValue,
+                                        const hidl_vec<uint32_t>&, // cellStateOutDimensions,
+                                        const std::vector<float>&, // cellStateOutValue,
                                         armnn::Compute compute,
                                         float epsilonValue = 0)
 {
@@ -519,12 +519,12 @@
     // 1: The hidden state (out): A 2-D tensor of ANEURALNETWORKS_TENSOR_FLOAT32/16, of shape
     //    [batch_size, output_size]. This output is optional and can be omitted. If this output
     //    is present then output #2 must be present as well.
-    hidl_vec<uint32_t> hiddenStateOutDimensions{0};
-    std::vector<float> hiddenStateOutValue;
+    hidl_vec<uint32_t> hiddenStateOutDimensions{batchSize, outputSize};
+    std::vector<float> hiddenStateOutValue(batchSize * outputSize, 0.f);
     // 2: The cell state (out): A 2-D tensor of ANEURALNETWORKS_TENSOR_FLOAT32/16, of shape
     //    [batch_size, num_units]. This output is optional and can be omitted.
-    hidl_vec<uint32_t> cellStateOutDimensions{0};
-    std::vector<float> cellStateOutValue;
+    hidl_vec<uint32_t> cellStateOutDimensions{batchSize, numUnits};
+    std::vector<float> cellStateOutValue(batchSize * numUnits, 0.f);
 
     UnidirectionalSequenceLstmTestImpl<HalPolicy>(inputDimensions, inputValue,
                                                   inputToInputWeightsDimensions, inputToInputWeightsValue,
@@ -724,12 +724,12 @@
     // 1: The hidden state (out): A 2-D tensor of ANEURALNETWORKS_TENSOR_FLOAT32/16, of shape
     //    [batch_size, output_size]. This output is optional and can be omitted. If this output
     //    is present then output #2 must be present as well.
-    hidl_vec<uint32_t> hiddenStateOutDimensions{0};
-    std::vector<float> hiddenStateOutValue;
+    hidl_vec<uint32_t> hiddenStateOutDimensions{batchSize, outputSize};
+    std::vector<float> hiddenStateOutValue(batchSize * outputSize, 0.f);
     // 2: The cell state (out): A 2-D tensor of ANEURALNETWORKS_TENSOR_FLOAT32/16, of shape
     //    [batch_size, num_units]. This output is optional and can be omitted.
-    hidl_vec<uint32_t> cellStateOutDimensions{0};
-    std::vector<float> cellStateOutValue;
+    hidl_vec<uint32_t> cellStateOutDimensions{batchSize, numUnits};
+    std::vector<float> cellStateOutValue(batchSize * numUnits, 0.f);
 
     UnidirectionalSequenceLstmTestImpl<HalPolicy>(inputDimensions, inputValue,
                                                   inputToInputWeightsDimensions, inputToInputWeightsValue,
@@ -964,12 +964,12 @@
     // 1: The hidden state (out): A 2-D tensor of ANEURALNETWORKS_TENSOR_FLOAT32/16, of shape
     //    [batch_size, output_size]. This output is optional and can be omitted. If this output
     //    is present then output #2 must be present as well.
-    hidl_vec<uint32_t> hiddenStateOutDimensions{0};
-    std::vector<float> hiddenStateOutValue;
+    hidl_vec<uint32_t> hiddenStateOutDimensions{batchSize, outputSize};
+    std::vector<float> hiddenStateOutValue(batchSize * outputSize, 0.f);
     // 2: The cell state (out): A 2-D tensor of ANEURALNETWORKS_TENSOR_FLOAT32/16, of shape
     //    [batch_size, num_units]. This output is optional and can be omitted.
-    hidl_vec<uint32_t> cellStateOutDimensions{0};
-    std::vector<float> cellStateOutValue;
+    hidl_vec<uint32_t> cellStateOutDimensions{batchSize, numUnits};
+    std::vector<float> cellStateOutValue(batchSize * numUnits, 0.f);
 
     UnidirectionalSequenceLstmTestImpl<HalPolicy>(inputDimensions, inputValue,
                                                   inputToInputWeightsDimensions, inputToInputWeightsValue,
@@ -1179,12 +1179,12 @@
     // 1: The hidden state (out): A 2-D tensor of ANEURALNETWORKS_TENSOR_FLOAT32/16, of shape
     //    [batch_size, output_size]. This output is optional and can be omitted. If this output
     //    is present then output #2 must be present as well.
-    hidl_vec<uint32_t> hiddenStateOutDimensions{0};
-    std::vector<float> hiddenStateOutValue;
+    hidl_vec<uint32_t> hiddenStateOutDimensions{batchSize, outputSize};
+    std::vector<float> hiddenStateOutValue(batchSize * outputSize, 0.f);
     // 2: The cell state (out): A 2-D tensor of ANEURALNETWORKS_TENSOR_FLOAT32/16, of shape
     //    [batch_size, num_units]. This output is optional and can be omitted.
-    hidl_vec<uint32_t> cellStateOutDimensions{0};
-    std::vector<float> cellStateOutValue;
+    hidl_vec<uint32_t> cellStateOutDimensions{batchSize, numUnits};
+    std::vector<float> cellStateOutValue(batchSize * numUnits, 0.f);
 
     UnidirectionalSequenceLstmTestImpl<HalPolicy>(inputDimensions, inputValue,
                                                   inputToInputWeightsDimensions, inputToInputWeightsValue,
@@ -1376,12 +1376,12 @@
     // 1: The hidden state (out): A 2-D tensor of ANEURALNETWORKS_TENSOR_FLOAT32/16, of shape
     //    [batch_size, output_size]. This output is optional and can be omitted. If this output
     //    is present then output #2 must be present as well.
-    hidl_vec<uint32_t> hiddenStateOutDimensions{0};
-    std::vector<float> hiddenStateOutValue;
+    hidl_vec<uint32_t> hiddenStateOutDimensions{batchSize, outputSize};
+    std::vector<float> hiddenStateOutValue(batchSize * outputSize, 0.f);
     // 2: The cell state (out): A 2-D tensor of ANEURALNETWORKS_TENSOR_FLOAT32/16, of shape
     //    [batch_size, num_units]. This output is optional and can be omitted.
-    hidl_vec<uint32_t> cellStateOutDimensions{0};
-    std::vector<float> cellStateOutValue;
+    hidl_vec<uint32_t> cellStateOutDimensions{batchSize, numUnits};
+    std::vector<float> cellStateOutValue(batchSize * numUnits, 0.f);
 
     UnidirectionalSequenceLstmTestImpl<HalPolicy>(inputDimensions, inputValue,
                                                   inputToInputWeightsDimensions, inputToInputWeightsValue,