MLCE-360 'ReduceLayer InferOutputShape Issue'

* Updated ParseReduce() function in TfLiteParser to read correct axis data
* Remove unused m_TargetWidth and m_TargetHight from ReduceDescriptor
* Updated the ArmNN Serializer Schema

Signed-off-by: Sadik Armagan <sadik.armagan@arm.com>
Change-Id: I98b6e00ccba1d8ea8c845cb1ae28840e42339629
diff --git a/include/armnn/Descriptors.hpp b/include/armnn/Descriptors.hpp
index d6e37e5..a8e68aa 100644
--- a/include/armnn/Descriptors.hpp
+++ b/include/armnn/Descriptors.hpp
@@ -1290,26 +1290,18 @@
 struct ReduceDescriptor
 {
     ReduceDescriptor()
-        : m_TargetHeight(0)
-        , m_TargetWidth(0)
-        , m_KeepDims(false)
+        : m_KeepDims(false)
         , m_vAxis()
         , m_ReduceOperation(ReduceOperation::Sum)
     {}
 
     bool operator ==(const ReduceDescriptor& rhs) const
     {
-        return m_TargetHeight         == rhs.m_TargetHeight &&
-               m_TargetWidth          == rhs.m_TargetWidth &&
-               m_KeepDims             == rhs.m_KeepDims &&
+        return m_KeepDims             == rhs.m_KeepDims &&
                m_vAxis                == rhs.m_vAxis &&
                m_ReduceOperation      == rhs.m_ReduceOperation;
     }
 
-    /// Target height value.
-    uint32_t m_TargetHeight;
-    /// Target width value.
-    uint32_t m_TargetWidth;
     /// if true then output shape has no change.
     bool m_KeepDims;
     /// The indices of the dimensions to reduce.
diff --git a/src/armnnDeserializer/Deserializer.cpp b/src/armnnDeserializer/Deserializer.cpp
index e98ff15..cbc4758 100644
--- a/src/armnnDeserializer/Deserializer.cpp
+++ b/src/armnnDeserializer/Deserializer.cpp
@@ -2118,8 +2118,6 @@
     auto flatBufferAxis = fbDescriptor->axis();
 
     armnn::ReduceDescriptor descriptor;
-    descriptor.m_TargetHeight = fbDescriptor->targetHeight();
-    descriptor.m_TargetWidth  = fbDescriptor->targetWidth();
     descriptor.m_KeepDims     = fbDescriptor->keepDims();
     descriptor.m_vAxis = std::vector<unsigned int>(flatBufferAxis->begin(), flatBufferAxis->end());
     descriptor.m_ReduceOperation = ToReduceOperation(fbDescriptor->reduceOperation());
diff --git a/src/armnnSerializer/ArmnnSchema.fbs b/src/armnnSerializer/ArmnnSchema.fbs
index aa539b1..9dbf6aa 100644
--- a/src/armnnSerializer/ArmnnSchema.fbs
+++ b/src/armnnSerializer/ArmnnSchema.fbs
@@ -895,8 +895,6 @@
 }
 
 table ReduceDescriptor {
-    targetHeight:uint;
-    targetWidth:uint;
     keepDims:bool = false;
     axis:[uint];
     reduceOperation:ReduceOperation = Sum;
diff --git a/src/armnnSerializer/ArmnnSchema_generated.h b/src/armnnSerializer/ArmnnSchema_generated.h
index 32548b2..cb9e686 100644
--- a/src/armnnSerializer/ArmnnSchema_generated.h
+++ b/src/armnnSerializer/ArmnnSchema_generated.h
@@ -9207,18 +9207,10 @@
 struct ReduceDescriptor FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
   typedef ReduceDescriptorBuilder Builder;
   enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
-    VT_TARGETHEIGHT = 4,
-    VT_TARGETWIDTH = 6,
-    VT_KEEPDIMS = 8,
-    VT_AXIS = 10,
-    VT_REDUCEOPERATION = 12
+    VT_KEEPDIMS = 4,
+    VT_AXIS = 6,
+    VT_REDUCEOPERATION = 8
   };
-  uint32_t targetHeight() const {
-    return GetField<uint32_t>(VT_TARGETHEIGHT, 0);
-  }
-  uint32_t targetWidth() const {
-    return GetField<uint32_t>(VT_TARGETWIDTH, 0);
-  }
   bool keepDims() const {
     return GetField<uint8_t>(VT_KEEPDIMS, 0) != 0;
   }
@@ -9230,8 +9222,6 @@
   }
   bool Verify(flatbuffers::Verifier &verifier) const {
     return VerifyTableStart(verifier) &&
-           VerifyField<uint32_t>(verifier, VT_TARGETHEIGHT) &&
-           VerifyField<uint32_t>(verifier, VT_TARGETWIDTH) &&
            VerifyField<uint8_t>(verifier, VT_KEEPDIMS) &&
            VerifyOffset(verifier, VT_AXIS) &&
            verifier.VerifyVector(axis()) &&
@@ -9244,12 +9234,6 @@
   typedef ReduceDescriptor Table;
   flatbuffers::FlatBufferBuilder &fbb_;
   flatbuffers::uoffset_t start_;
-  void add_targetHeight(uint32_t targetHeight) {
-    fbb_.AddElement<uint32_t>(ReduceDescriptor::VT_TARGETHEIGHT, targetHeight, 0);
-  }
-  void add_targetWidth(uint32_t targetWidth) {
-    fbb_.AddElement<uint32_t>(ReduceDescriptor::VT_TARGETWIDTH, targetWidth, 0);
-  }
   void add_keepDims(bool keepDims) {
     fbb_.AddElement<uint8_t>(ReduceDescriptor::VT_KEEPDIMS, static_cast<uint8_t>(keepDims), 0);
   }
@@ -9273,15 +9257,11 @@
 
 inline flatbuffers::Offset<ReduceDescriptor> CreateReduceDescriptor(
     flatbuffers::FlatBufferBuilder &_fbb,
-    uint32_t targetHeight = 0,
-    uint32_t targetWidth = 0,
     bool keepDims = false,
     flatbuffers::Offset<flatbuffers::Vector<uint32_t>> axis = 0,
     armnnSerializer::ReduceOperation reduceOperation = armnnSerializer::ReduceOperation_Sum) {
   ReduceDescriptorBuilder builder_(_fbb);
   builder_.add_axis(axis);
-  builder_.add_targetWidth(targetWidth);
-  builder_.add_targetHeight(targetHeight);
   builder_.add_reduceOperation(reduceOperation);
   builder_.add_keepDims(keepDims);
   return builder_.Finish();
@@ -9289,16 +9269,12 @@
 
 inline flatbuffers::Offset<ReduceDescriptor> CreateReduceDescriptorDirect(
     flatbuffers::FlatBufferBuilder &_fbb,
-    uint32_t targetHeight = 0,
-    uint32_t targetWidth = 0,
     bool keepDims = false,
     const std::vector<uint32_t> *axis = nullptr,
     armnnSerializer::ReduceOperation reduceOperation = armnnSerializer::ReduceOperation_Sum) {
   auto axis__ = axis ? _fbb.CreateVector<uint32_t>(*axis) : 0;
   return armnnSerializer::CreateReduceDescriptor(
       _fbb,
-      targetHeight,
-      targetWidth,
       keepDims,
       axis__,
       reduceOperation);
diff --git a/src/armnnSerializer/Serializer.cpp b/src/armnnSerializer/Serializer.cpp
index a2217a3..28afac7 100644
--- a/src/armnnSerializer/Serializer.cpp
+++ b/src/armnnSerializer/Serializer.cpp
@@ -911,8 +911,6 @@
 {
     auto fbReduceBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reduce);
     auto fbDescriptor = CreateReduceDescriptor(m_flatBufferBuilder,
-                                               reduceDescriptor.m_TargetHeight,
-                                               reduceDescriptor.m_TargetWidth,
                                                reduceDescriptor.m_KeepDims,
                                                m_flatBufferBuilder.CreateVector(reduceDescriptor.m_vAxis),
                                                GetFlatBufferReduceOperation(reduceDescriptor.m_ReduceOperation));
diff --git a/src/armnnTfLiteParser/TfLiteParser.cpp b/src/armnnTfLiteParser/TfLiteParser.cpp
index 8ce1667..ab32ef7 100644
--- a/src/armnnTfLiteParser/TfLiteParser.cpp
+++ b/src/armnnTfLiteParser/TfLiteParser.cpp
@@ -3091,19 +3091,24 @@
 
     armnn::TensorInfo inputTensorInfo0 = ToTensorInfo(inputs[0]);
     armnn::TensorInfo inputTensorInfo1 = ToTensorInfo(inputs[1]);
-    TensorShape input0Shape = inputTensorInfo0.GetShape();
 
     ReduceDescriptor desc;
-
     BufferRawPtr axisBufferPtr = GetBuffer(m_Model, inputs[1]->buffer);
     // Get const axis value from model and set it to descriptor.
     if (axisBufferPtr != nullptr)
     {
-        for (uint32_t i = 0; i < inputTensorInfo1.GetNumElements(); ++i)
-        {
-            desc.m_vAxis.push_back(armnnUtils::GetUnsignedAxis(inputTensorInfo0.GetNumDimensions(),
-                                                               axisBufferPtr->data.data()[i]));
-        }
+        std::vector<int32_t> axisData(inputTensorInfo1.GetNumElements());
+        ::memcpy(axisData.data(), axisBufferPtr->data.data(), inputTensorInfo1.GetNumBytes());
+
+        // Convert the axis to unsigned int and remove duplicates.
+        auto rank = static_cast<int32_t>(inputTensorInfo0.GetNumDimensions());
+        std::set<unsigned int> uniqueAxis;
+        std::transform(axisData.begin(),
+                       axisData.end(),
+                       std::inserter(uniqueAxis, uniqueAxis.begin()),
+                       [rank](int i)->unsigned int{
+                               return static_cast<uint32_t>(((i + rank) % rank)); });
+        desc.m_vAxis.assign(uniqueAxis.begin(), uniqueAxis.end());
     }
     else
     {
@@ -3113,8 +3118,6 @@
         }
     }
 
-    desc.m_TargetHeight    = input0Shape[1];
-    desc.m_TargetWidth     = input0Shape[2];
     desc.m_KeepDims        = options->keep_dims;
     desc.m_ReduceOperation = reduceOperation;
 
diff --git a/src/armnnTfLiteParser/test/Reduce.cpp b/src/armnnTfLiteParser/test/Reduce.cpp
index 622d54e..c2a22f0 100644
--- a/src/armnnTfLiteParser/test/Reduce.cpp
+++ b/src/armnnTfLiteParser/test/Reduce.cpp
@@ -90,7 +90,7 @@
 
 struct SimpleReduceMaxFixture : public ReduceMaxFixture
 {
-    SimpleReduceMaxFixture() : ReduceMaxFixture("[ 1, 1, 2, 3 ]", "[ 1, 1, 1, 3 ]", "[ 1 ]", "[ 2 ]") {}
+    SimpleReduceMaxFixture() : ReduceMaxFixture("[ 1, 1, 2, 3 ]", "[ 1, 1, 1, 3 ]", "[ 1 ]", "[  2,0,0,0 ]") {}
 };
 
 BOOST_FIXTURE_TEST_CASE(ParseReduceMax, SimpleReduceMaxFixture)
@@ -179,7 +179,7 @@
 
 struct SimpleReduceMinFixture : public ReduceMinFixture
 {
-    SimpleReduceMinFixture() : ReduceMinFixture("[ 1, 1, 2, 3 ]", "[ 1, 1, 1, 3 ]", "[ 1 ]", "[ 2 ]") {}
+    SimpleReduceMinFixture() : ReduceMinFixture("[ 1, 1, 2, 3 ]", "[ 1, 1, 1, 3 ]", "[ 1 ]", "[ 2, 0, 0, 0 ]") {}
 };
 
 BOOST_FIXTURE_TEST_CASE(ParseReduceMin, SimpleReduceMinFixture)
diff --git a/src/armnnTfLiteParser/test/Sum.cpp b/src/armnnTfLiteParser/test/Sum.cpp
index 22b19ae..177bcd5 100644
--- a/src/armnnTfLiteParser/test/Sum.cpp
+++ b/src/armnnTfLiteParser/test/Sum.cpp
@@ -90,7 +90,7 @@
 
 struct SimpleSumFixture : public SumFixture
 {
-    SimpleSumFixture() : SumFixture("[ 1, 3, 2, 4 ]", "[ 1, 1, 1, 4 ]", "[ 2 ]", "[ 1, 2 ]") {}
+    SimpleSumFixture() : SumFixture("[ 1, 3, 2, 4 ]", "[ 1, 1, 1, 4 ]", "[ 2 ]", "[ 1, 0, 0, 0,  2, 0, 0, 0 ]") {}
 };
 
 BOOST_FIXTURE_TEST_CASE(ParseSum, SimpleSumFixture)