IVGCVSW-3221 Refactor Mean ref workload and tests

 * Renamed RefMeanFloat32Workload and RefMeanUint8Workload
   to RefMeanWorkload, updated references to reflect this
   change.
 * Refactored RefFloorWorkload to use Decoders/Encoders,
   to support the use of multiple data types.
 * Deleted reference Unit8 Mean tests as they were
   duplicates of the Float32 tests. Refactored these tests
   to support multiple data types and updated references.
 * Adjusted the values used in the tests' input tensors so
   that they are more like floating point numbers
   e.g. change 1.0f to 1.5f.
 * Replace size_t with unsigned int in Mean ref workload,
   for better compatibility with the Encoder/Decoder,
   removed some unnecessary casts after this.
 * Added ValidateTensorDataTypesMatch() function to
   WorkloadData.cpp, added CreateIncorrectDimensionsErrorMsg
   function to RefLayerSupport.cpp.
 * Added passing and failing tests for ref IsMeanSupported.

Signed-off-by: James Conroy <james.conroy@arm.com>
Change-Id: Id3d44463d1385255c727a497d4026d21a49e7eb2
diff --git a/src/backends/reference/RefLayerSupport.cpp b/src/backends/reference/RefLayerSupport.cpp
index cf1814e..402bd66 100644
--- a/src/backends/reference/RefLayerSupport.cpp
+++ b/src/backends/reference/RefLayerSupport.cpp
@@ -47,6 +47,21 @@
 
 } // anonymous namespace
 
+namespace
+{
+
+std::string CreateIncorrectDimensionsErrorMsg(unsigned int expected,
+                                              unsigned int actual,
+                                              std::string& layerStr,
+                                              std::string& tensorName)
+{
+    std::string errorMsg = "Reference " + layerStr + ": Expected " + std::to_string(expected) + " dimensions but got" +
+                           " " + std::to_string(actual) + " dimensions instead, for the '" + tensorName + "' tensor.";
+
+    return errorMsg;
+}
+
+} // anonymous namespace
 
 namespace
 {
@@ -177,6 +192,15 @@
         }
     }
 };
+
+struct TensorNumDimensionsAreCorrect : public Rule
+{
+    TensorNumDimensionsAreCorrect(const TensorInfo& info, unsigned int expectedNumDimensions)
+    {
+        m_Res = info.GetNumDimensions() == expectedNumDimensions;
+    }
+};
+
 } // namespace
 
 
@@ -874,12 +898,58 @@
                                       const MeanDescriptor& descriptor,
                                       Optional<std::string&> reasonIfUnsupported) const
 {
-    ignore_unused(output);
-    ignore_unused(descriptor);
-    return IsSupportedForDataTypeRef(reasonIfUnsupported,
-                                     input.GetDataType(),
-                                     &TrueFunc<>,
-                                     &TrueFunc<>);
+    bool supported = true;
+    std::string meanLayerStr = "Mean";
+    std::string outputTensorStr = "output";
+
+    std::array<DataType,2> supportedTypes =
+    {
+        DataType::Float32,
+        DataType::QuantisedAsymm8
+    };
+
+    supported &= CheckSupportRule(TypeAnyOf(input, supportedTypes), reasonIfUnsupported,
+                                  "Reference Mean: input type not supported.");
+
+    supported &= CheckSupportRule(TypesAreEqual(input, output), reasonIfUnsupported,
+                                  "Reference Mean: input and output types are mismatched");
+
+    if (descriptor.m_KeepDims)
+    {
+        supported &= CheckSupportRule(TensorNumDimensionsAreCorrect(output, input.GetNumDimensions()),
+                                      reasonIfUnsupported,
+                                      CreateIncorrectDimensionsErrorMsg(input.GetNumDimensions(),
+                                                                        output.GetNumDimensions(),
+                                                                        meanLayerStr, outputTensorStr).data());
+    }
+    else if (descriptor.m_Axis.empty())
+    {
+        supported &= CheckSupportRule(TensorNumDimensionsAreCorrect(output, 1),
+                                      reasonIfUnsupported,
+                                      CreateIncorrectDimensionsErrorMsg(1, output.GetNumDimensions(),
+                                                                        meanLayerStr, outputTensorStr).data());
+    }
+    else
+    {
+        auto outputDim = input.GetNumDimensions() - boost::numeric_cast<unsigned int>(descriptor.m_Axis.size());
+
+        if (outputDim > 0)
+        {
+            supported &= CheckSupportRule(TensorNumDimensionsAreCorrect(output, outputDim),
+                                          reasonIfUnsupported,
+                                          CreateIncorrectDimensionsErrorMsg(outputDim, output.GetNumDimensions(),
+                                                                            meanLayerStr, outputTensorStr).data());
+        }
+        else
+        {
+            supported &= CheckSupportRule(TensorNumDimensionsAreCorrect(output, 1),
+                                          reasonIfUnsupported,
+                                          CreateIncorrectDimensionsErrorMsg(1, output.GetNumDimensions(),
+                                                                            meanLayerStr, outputTensorStr).data());
+        }
+    }
+
+    return supported;
 }
 
 bool RefLayerSupport::IsMergerSupported(const std::vector<const TensorInfo*> inputs,