IVGCVSW-3249 Extend the BatchToSpace workload to support QSymm16

 * Add reference supportedness validation checks.
 * Call unit tests with QSymm16 data type.

Change-Id: Ie6621ca7072dfc69278198c53e09b090275a7fff
Signed-off-by: Francis Murtagh <francis.murtagh@arm.com>
diff --git a/src/armnn/test/CreateWorkload.hpp b/src/armnn/test/CreateWorkload.hpp
index 00257ea..0048646 100644
--- a/src/armnn/test/CreateWorkload.hpp
+++ b/src/armnn/test/CreateWorkload.hpp
@@ -926,7 +926,7 @@
     Layer* const output = graph.AddLayer<OutputLayer>(0, "output");
 
     // Connects up.
-    armnn::TensorInfo tensorInfo({1, 1}, DataType);
+    armnn::TensorInfo tensorInfo({1, 1, 1, 1}, DataType);
 
     Connect(input, layer, tensorInfo);
     Connect(layer, output, tensorInfo);
diff --git a/src/backends/backendsCommon/WorkloadData.cpp b/src/backends/backendsCommon/WorkloadData.cpp
index cd40097..1d0be5d 100644
--- a/src/backends/backendsCommon/WorkloadData.cpp
+++ b/src/backends/backendsCommon/WorkloadData.cpp
@@ -1431,8 +1431,26 @@
 
 void BatchToSpaceNdQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
 {
-    ValidateNumInputs(workloadInfo, "BatchToSpaceNdQueueDescriptor", 1);
-    ValidateNumOutputs(workloadInfo, "BatchToSpaceNdQueueDescriptor", 1);
+    const std::string batchToSpaceNdQueueDescriptorStr = "BatchToSpaceNdQueueDescriptor";
+
+    ValidateNumInputs(workloadInfo, batchToSpaceNdQueueDescriptorStr, 1);
+    ValidateNumOutputs(workloadInfo, batchToSpaceNdQueueDescriptorStr, 1);
+
+    const TensorInfo& input  = workloadInfo.m_InputTensorInfos[0];
+    const TensorInfo& output = workloadInfo.m_OutputTensorInfos[0];
+
+    std::vector<DataType> supportedTypes =
+    {
+            DataType::Float32,
+            DataType::QuantisedAsymm8,
+            DataType::QuantisedSymm16
+    };
+
+    ValidateDataTypes(workloadInfo.m_InputTensorInfos[0],
+                      supportedTypes,
+                      batchToSpaceNdQueueDescriptorStr);
+
+    ValidateTensorDataTypesMatch(input, output, batchToSpaceNdQueueDescriptorStr, "input", "output");
 }
 
 void StridedSliceQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
diff --git a/src/backends/backendsCommon/test/LayerTests.hpp b/src/backends/backendsCommon/test/LayerTests.hpp
index d54d41e..10bc00f 100644
--- a/src/backends/backendsCommon/test/LayerTests.hpp
+++ b/src/backends/backendsCommon/test/LayerTests.hpp
@@ -3324,7 +3324,7 @@
 
     outputTensorInfo.SetQuantizationScale(scale);
     outputTensorInfo.SetQuantizationOffset(offset);
-;
+
     auto input = MakeTensor<T, InputDim>(inputTensorInfo, ConvertToDataType<ArmnnType>(inputData, inputTensorInfo));
 
     LayerTestResult<T, OutputDim> result(outputTensorInfo);
diff --git a/src/backends/reference/RefLayerSupport.cpp b/src/backends/reference/RefLayerSupport.cpp
index 4e9a678..1f37420 100644
--- a/src/backends/reference/RefLayerSupport.cpp
+++ b/src/backends/reference/RefLayerSupport.cpp
@@ -359,14 +359,45 @@
                                                 Optional<std::string&> reasonIfUnsupported) const
 {
     ignore_unused(descriptor);
-    return (IsSupportedForDataTypeRef(reasonIfUnsupported,
-                                      input.GetDataType(),
-                                      &TrueFunc<>,
-                                      &TrueFunc<>) &&
-            IsSupportedForDataTypeRef(reasonIfUnsupported,
-                                      output.GetDataType(),
-                                      &TrueFunc<>,
-                                      &TrueFunc<>));
+
+    bool supported = true;
+
+    std::string batchToSpaceNdLayerStr = "batchToSpaceNd";
+    std::string inputTensorStr = "input";
+    std::string outputTensorStr = "output";
+
+    // Define supported types.
+    std::array<DataType,3> supportedTypes =
+    {
+            DataType::Float32,
+            DataType::QuantisedAsymm8,
+            DataType::QuantisedSymm16
+    };
+
+    supported &= CheckSupportRule(TypeAnyOf(input, supportedTypes), reasonIfUnsupported,
+                                  "Reference BatchToSpaceNd: input type not supported.");
+
+    supported &= CheckSupportRule(TypeAnyOf(output, supportedTypes), reasonIfUnsupported,
+                                  "Reference BatchToSpaceNd: output type not supported.");
+
+    supported &= CheckSupportRule(TypesAreEqual(input, output), reasonIfUnsupported,
+                                  "Reference BatchToSpaceNd: input and output types mismatched.");
+
+    supported &= CheckSupportRule(TensorNumDimensionsAreCorrect(output, 4),
+                                  reasonIfUnsupported,
+                                  CreateIncorrectDimensionsErrorMsg(4,
+                                                                    output.GetNumDimensions(),
+                                                                    batchToSpaceNdLayerStr,
+                                                                    outputTensorStr).data());
+
+    supported &= CheckSupportRule(TensorNumDimensionsAreCorrect(input, 4),
+                                  reasonIfUnsupported,
+                                  CreateIncorrectDimensionsErrorMsg(4,
+                                                                    input.GetNumDimensions(),
+                                                                    batchToSpaceNdLayerStr,
+                                                                    inputTensorStr).data());
+
+    return supported;
 }
 
 bool RefLayerSupport::IsConcatSupported(const std::vector<const TensorInfo*> inputs,
diff --git a/src/backends/reference/test/RefCreateWorkloadTests.cpp b/src/backends/reference/test/RefCreateWorkloadTests.cpp
index 67b1d94..68df349 100644
--- a/src/backends/reference/test/RefCreateWorkloadTests.cpp
+++ b/src/backends/reference/test/RefCreateWorkloadTests.cpp
@@ -339,7 +339,7 @@
     RefCreateFullyConnectedWorkloadTest<RefFullyConnectedWorkload, armnn::DataType::QuantisedAsymm8>();
 }
 
-BOOST_AUTO_TEST_CASE(CreateFullyConnectedWorkloadQuantisedAsymm16)
+BOOST_AUTO_TEST_CASE(CreateFullyConnectedWorkloadQuantisedSymm16)
 {
     RefCreateFullyConnectedWorkloadTest<RefFullyConnectedWorkload, armnn::DataType::QuantisedSymm16>();
 }
@@ -700,8 +700,8 @@
     auto workload = CreateBatchToSpaceNdWorkloadTest<BatchToSpaceNdWorkloadType, DataType>(factory, graph);
 
     CheckInputOutput(std::move(workload),
-                     TensorInfo({ 1, 1 }, DataType),
-                     TensorInfo({ 1, 1 }, DataType));
+                     TensorInfo({ 1, 1, 1, 1 }, DataType),
+                     TensorInfo({ 1, 1, 1, 1 }, DataType));
 }
 
 BOOST_AUTO_TEST_CASE(CreateBatchToSpaceNdFloat32)
@@ -714,6 +714,11 @@
     RefCreateBatchToSpaceNdTest<RefBatchToSpaceNdWorkload, armnn::DataType::QuantisedAsymm8>();
 }
 
+BOOST_AUTO_TEST_CASE(CreateBatchToSpaceNdQSymm16)
+{
+    RefCreateBatchToSpaceNdTest<RefBatchToSpaceNdWorkload, armnn::DataType::QuantisedSymm16>();
+}
+
 template <typename L2NormalizationWorkloadType, armnn::DataType DataType>
 static void RefCreateL2NormalizationTest(DataLayout dataLayout)
 {
diff --git a/src/backends/reference/test/RefLayerTests.cpp b/src/backends/reference/test/RefLayerTests.cpp
index f933bfe..b997a14 100644
--- a/src/backends/reference/test/RefLayerTests.cpp
+++ b/src/backends/reference/test/RefLayerTests.cpp
@@ -828,6 +828,14 @@
 ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNhwcUint6,  BatchToSpaceNdNhwcTest6<armnn::DataType::QuantisedAsymm8>)
 ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNhwcUint7,  BatchToSpaceNdNhwcTest7<armnn::DataType::QuantisedAsymm8>)
 
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNhwcQsymm16_1,  BatchToSpaceNdNhwcTest1<armnn::DataType::QuantisedSymm16>)
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNhwcQsymm16_2,  BatchToSpaceNdNhwcTest2<armnn::DataType::QuantisedSymm16>)
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNhwcQsymm16_3,  BatchToSpaceNdNhwcTest3<armnn::DataType::QuantisedSymm16>)
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNhwcQsymm16_4,  BatchToSpaceNdNhwcTest4<armnn::DataType::QuantisedSymm16>)
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNhwcQsymm16_5,  BatchToSpaceNdNhwcTest5<armnn::DataType::QuantisedSymm16>)
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNhwcQsymm16_6,  BatchToSpaceNdNhwcTest6<armnn::DataType::QuantisedSymm16>)
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNhwcQsymm16_7,  BatchToSpaceNdNhwcTest7<armnn::DataType::QuantisedSymm16>)
+
 ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwFloat1, BatchToSpaceNdNchwTest1<armnn::DataType::Float32>)
 ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwFloat2, BatchToSpaceNdNchwTest2<armnn::DataType::Float32>)
 ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwFloat3, BatchToSpaceNdNchwTest3<armnn::DataType::Float32>)
@@ -844,6 +852,15 @@
 ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwUint6,  BatchToSpaceNdNchwTest6<armnn::DataType::QuantisedAsymm8>)
 ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwUint7,  BatchToSpaceNdNchwTest7<armnn::DataType::QuantisedAsymm8>)
 
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwQsymm16_1,  BatchToSpaceNdNchwTest1<armnn::DataType::QuantisedSymm16>)
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwQsymm16_2,  BatchToSpaceNdNchwTest2<armnn::DataType::QuantisedSymm16>)
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwQsymm16_3,  BatchToSpaceNdNchwTest3<armnn::DataType::QuantisedSymm16>)
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwQsymm16_4,  BatchToSpaceNdNchwTest4<armnn::DataType::QuantisedSymm16>)
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwQsymm16_5,  BatchToSpaceNdNchwTest5<armnn::DataType::QuantisedSymm16>)
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwQsymm16_6,  BatchToSpaceNdNchwTest6<armnn::DataType::QuantisedSymm16>)
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwQsymm16_7,  BatchToSpaceNdNchwTest7<armnn::DataType::QuantisedSymm16>)
+
+
 // SpaceToDepth
 ARMNN_AUTO_TEST_CASE(SpaceToDepthNCHWAsymmQ8, SpaceToDepthNCHWAsymmQ8Test)
 ARMNN_AUTO_TEST_CASE(SpaceToDepthNHWCAsymmQ8, SpaceToDepthNHWCAsymmQ8Test)