IVGCVSW-6589 AddReduceLayer to PyArmNN

  * AddReduceLayer to PyArmNN armnn_network.i
  * AddReduceDescriptor to PyArmNN armnn_descriptors.i
  * Add layer to test_network.py
  * Add descriptor unit tests to test_descriptors.py

Signed-off-by: Ryan OShea <ryan.oshea3@arm.com>
Change-Id: I2a8706052baf8f9c0038a5ea327d73b8f3ea1961
diff --git a/python/pyarmnn/src/pyarmnn/__init__.py b/python/pyarmnn/src/pyarmnn/__init__.py
index b71fc36..5f95cb0 100644
--- a/python/pyarmnn/src/pyarmnn/__init__.py
+++ b/python/pyarmnn/src/pyarmnn/__init__.py
@@ -97,6 +97,8 @@
 from ._generated.pyarmnn import OutputShapeRounding_Ceiling, OutputShapeRounding_Floor, \
     PaddingMethod_Exclude, PaddingMethod_IgnoreValue, PoolingAlgorithm_Average, PoolingAlgorithm_L2, \
     PoolingAlgorithm_Max, Pooling2dDescriptor
+from ._generated.pyarmnn import ReduceDescriptor, ReduceOperation_Prod, ReduceOperation_Max, ReduceOperation_Mean, \
+    ReduceOperation_Min, ReduceOperation_Sum
 from ._generated.pyarmnn import ResizeMethod_Bilinear, ResizeMethod_NearestNeighbor, ResizeDescriptor, \
     ReshapeDescriptor, SliceDescriptor, SpaceToBatchNdDescriptor, SpaceToDepthDescriptor, StandInDescriptor, \
     StackDescriptor, StridedSliceDescriptor, SoftmaxDescriptor, TransposeConvolution2dDescriptor, \
diff --git a/python/pyarmnn/src/pyarmnn/swig/modules/armnn_descriptors.i b/python/pyarmnn/src/pyarmnn/swig/modules/armnn_descriptors.i
index d20796a..7330023 100644
--- a/python/pyarmnn/src/pyarmnn/swig/modules/armnn_descriptors.i
+++ b/python/pyarmnn/src/pyarmnn/swig/modules/armnn_descriptors.i
@@ -745,6 +745,28 @@
 
 %feature("docstring",
     "
+    A ReduceDescriptor for the REDUCE operators.
+
+    Contains:
+        m_KeepDims(bool): If true then output shape has no change.
+        m_vAxis (list of int): The indices of the dimensions to reduce.
+        m_ReduceOperation (int): Specifies the reduction operation to execute ('ReduceOperation_Sum',
+                                             'ReduceOperation_Max', 'ReduceOperation_Mean', 'ReduceOperation_Min',
+                                             'ReduceOperation_Prod'). Default: 0 ('ReduceOperation_Sum').
+        ") ReduceDescriptor;
+struct ReduceDescriptor
+{
+    ReduceDescriptor();
+
+    bool m_KeepDims;
+    std::vector<uint32_t> m_vAxis;
+    ReduceOperation m_ReduceOperation;
+
+    bool operator ==(const ReduceDescriptor& rhs) const;
+};
+
+%feature("docstring",
+    "
     A descriptor for the Reshape layer. See `INetwork.AddReshapeLayer()`.
 
     Contains:
diff --git a/python/pyarmnn/src/pyarmnn/swig/modules/armnn_network.i b/python/pyarmnn/src/pyarmnn/swig/modules/armnn_network.i
index 789e428..643f99f 100644
--- a/python/pyarmnn/src/pyarmnn/swig/modules/armnn_network.i
+++ b/python/pyarmnn/src/pyarmnn/swig/modules/armnn_network.i
@@ -856,6 +856,19 @@
         ") AddRankLayer;
     armnn::IConnectableLayer* AddRankLayer(const char* name = nullptr);
 
+    %feature("docstring",
+        "
+        Adds a Reduce layer to the network.
+
+        Args:
+            reduceDescriptor (ReduceDescriptor): Parameters for the reduce operation.
+            name (str): Optional name for the layer.
+
+        Returns:
+            IConnectableLayer: Interface for configuring the layer.
+        ") AddReduceLayer;
+    armnn::IConnectableLayer* AddReduceLayer(const armnn::ReduceDescriptor& reduceDescriptor,
+                                             const char* name = nullptr);
 
     %feature("docstring",
         "
diff --git a/python/pyarmnn/test/test_descriptors.py b/python/pyarmnn/test/test_descriptors.py
index 80c5359..262b8fc 100644
--- a/python/pyarmnn/test/test_descriptors.py
+++ b/python/pyarmnn/test/test_descriptors.py
@@ -288,6 +288,11 @@
     # check the empty Targetshape
     assert desc.m_TargetShape.GetNumDimensions() == 0
 
+def test_reduce_descriptor_default_values():
+    desc = ann.ReduceDescriptor()
+    assert desc.m_KeepDims == False
+    assert desc.m_vAxis == []
+    assert desc.m_ReduceOperation == ann.ReduceOperation_Sum
 
 def test_slice_descriptor_default_values():
     desc = ann.SliceDescriptor()
@@ -517,6 +522,7 @@
                                        'InstanceNormalizationDescriptor',
                                        'BatchToSpaceNdDescriptor',
                                        'FakeQuantizationDescriptor',
+                                       'ReduceDescriptor',
                                        'ResizeDescriptor',
                                        'ReshapeDescriptor',
                                        'SpaceToBatchNdDescriptor',
@@ -565,6 +571,7 @@
                                        'InstanceNormalizationDescriptor',
                                        'BatchToSpaceNdDescriptor',
                                        'FakeQuantizationDescriptor',
+                                       'ReduceDescriptor',
                                        'ResizeDescriptor',
                                        'ReshapeDescriptor',
                                        'SpaceToBatchNdDescriptor',
diff --git a/python/pyarmnn/test/test_network.py b/python/pyarmnn/test/test_network.py
index e33470e..e56621a 100644
--- a/python/pyarmnn/test/test_network.py
+++ b/python/pyarmnn/test/test_network.py
@@ -229,6 +229,7 @@
     'AddQuantizeLayer',
     'AddQuantizedLstmLayer',
     'AddRankLayer',
+    'AddReduceLayer',
     'AddReshapeLayer',
     'AddResizeLayer',
     'AddShapeLayer',