IVGCVSW-4262 Use ACL Permute and Reshape Validate function in Neon and CL

!android-nn-driver:2465

Signed-off-by: Kevin May <kevin.may@arm.com>
Change-Id: Ibabb73c0ae0df2e530a68398f75c76e6b80c0701
diff --git a/include/armnn/ILayerSupport.hpp b/include/armnn/ILayerSupport.hpp
index 33f86de..f796a2d 100644
--- a/include/armnn/ILayerSupport.hpp
+++ b/include/armnn/ILayerSupport.hpp
@@ -242,6 +242,7 @@
                                           Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const = 0;
 
     virtual bool IsReshapeSupported(const TensorInfo& input,
+                                    const TensorInfo& output,
                                     const ReshapeDescriptor& descriptor,
                                     Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const = 0;
 
diff --git a/src/armnn/LayerSupport.cpp b/src/armnn/LayerSupport.cpp
index d730205..38cac92 100644
--- a/src/armnn/LayerSupport.cpp
+++ b/src/armnn/LayerSupport.cpp
@@ -510,11 +510,12 @@
 
 bool IsReshapeSupported(const BackendId& backend,
                         const TensorInfo& input,
+                        const TensorInfo& output,
                         const ReshapeDescriptor& descriptor,
                         char* reasonIfUnsupported,
                         size_t reasonIfUnsupportedMaxLength)
 {
-    FORWARD_LAYER_SUPPORT_FUNC(backend, IsReshapeSupported, input, descriptor);
+    FORWARD_LAYER_SUPPORT_FUNC(backend, IsReshapeSupported, input, output, descriptor);
 }
 
 bool IsResizeSupported(const BackendId& backend,
diff --git a/src/backends/backendsCommon/LayerSupportBase.cpp b/src/backends/backendsCommon/LayerSupportBase.cpp
index ee8dc5f..ecbf5e4 100644
--- a/src/backends/backendsCommon/LayerSupportBase.cpp
+++ b/src/backends/backendsCommon/LayerSupportBase.cpp
@@ -372,6 +372,7 @@
 }
 
 bool LayerSupportBase::IsReshapeSupported(const TensorInfo& input,
+                                          const TensorInfo& output,
                                           const ReshapeDescriptor& descriptor,
                                           Optional<std::string&> reasonIfUnsupported) const
 {
diff --git a/src/backends/backendsCommon/LayerSupportBase.hpp b/src/backends/backendsCommon/LayerSupportBase.hpp
index 0d5a2af..60021b2 100644
--- a/src/backends/backendsCommon/LayerSupportBase.hpp
+++ b/src/backends/backendsCommon/LayerSupportBase.hpp
@@ -227,6 +227,7 @@
                                   Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override;
 
     bool IsReshapeSupported(const TensorInfo& input,
+                            const TensorInfo& output,
                             const ReshapeDescriptor& descriptor,
                             Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override;
 
diff --git a/src/backends/backendsCommon/WorkloadFactory.cpp b/src/backends/backendsCommon/WorkloadFactory.cpp
index ffef5b4..cda822c 100644
--- a/src/backends/backendsCommon/WorkloadFactory.cpp
+++ b/src/backends/backendsCommon/WorkloadFactory.cpp
@@ -712,7 +712,9 @@
         {
             auto cLayer = boost::polymorphic_downcast<const ReshapeLayer*>(&layer);
             const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo();
+            const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo();
             result = layerSupportObject->IsReshapeSupported(OverrideDataType(input, dataType),
+                                                            OverrideDataType(output, dataType),
                                                             cLayer->GetParameters(),
                                                             reason);
             break;
diff --git a/src/backends/cl/ClLayerSupport.cpp b/src/backends/cl/ClLayerSupport.cpp
index 2bbd77a..8803e77 100644
--- a/src/backends/cl/ClLayerSupport.cpp
+++ b/src/backends/cl/ClLayerSupport.cpp
@@ -40,6 +40,7 @@
 #include "workloads/ClPermuteWorkload.hpp"
 #include "workloads/ClPooling2dWorkload.hpp"
 #include "workloads/ClPreluWorkload.hpp"
+#include "workloads/ClReshapeWorkload.hpp"
 #include "workloads/ClResizeWorkload.hpp"
 #include "workloads/ClQuantizedLstmWorkload.hpp"
 #include "workloads/ClQuantizeWorkload.hpp"
@@ -508,9 +509,7 @@
                                         const PermuteDescriptor& descriptor,
                                         Optional<std::string&> reasonIfUnsupported) const
 {
-    ignore_unused(input);
-    ignore_unused(output);
-    FORWARD_WORKLOAD_VALIDATE_FUNC(ClPermuteWorkloadValidate, reasonIfUnsupported, descriptor);
+    FORWARD_WORKLOAD_VALIDATE_FUNC(ClPermuteWorkloadValidate, reasonIfUnsupported, input, output, descriptor);
 }
 
 bool ClLayerSupport::IsPooling2dSupported(const TensorInfo& input,
@@ -558,13 +557,12 @@
 }
 
 bool ClLayerSupport::IsReshapeSupported(const TensorInfo& input,
+                                        const TensorInfo& output,
                                         const ReshapeDescriptor& descriptor,
                                         Optional<std::string&> reasonIfUnsupported) const
 {
-    ignore_unused(input);
     ignore_unused(descriptor);
-    ignore_unused(reasonIfUnsupported);
-    return true;
+    FORWARD_WORKLOAD_VALIDATE_FUNC(ClReshapeWorkloadValidate, reasonIfUnsupported, input, output);
 }
 
 bool ClLayerSupport::IsResizeSupported(const TensorInfo& input,
diff --git a/src/backends/cl/ClLayerSupport.hpp b/src/backends/cl/ClLayerSupport.hpp
index 69c2280..491e793 100644
--- a/src/backends/cl/ClLayerSupport.hpp
+++ b/src/backends/cl/ClLayerSupport.hpp
@@ -184,6 +184,7 @@
                              Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override;
 
     bool IsReshapeSupported(const TensorInfo& input,
+                            const TensorInfo& output,
                             const ReshapeDescriptor& descriptor,
                             Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override;
 
diff --git a/src/backends/cl/workloads/ClPermuteWorkload.cpp b/src/backends/cl/workloads/ClPermuteWorkload.cpp
index bec80e5..41bce1d 100644
--- a/src/backends/cl/workloads/ClPermuteWorkload.cpp
+++ b/src/backends/cl/workloads/ClPermuteWorkload.cpp
@@ -14,16 +14,16 @@
 namespace armnn
 {
 
-arm_compute::Status ClPermuteWorkloadValidate(const PermuteDescriptor& descriptor)
+arm_compute::Status ClPermuteWorkloadValidate(const TensorInfo& input,
+                                              const TensorInfo& output,
+                                              const PermuteDescriptor& descriptor)
 {
-    const armnn::PermutationVector& perm = descriptor.m_DimMappings;
+    const arm_compute::TensorInfo aclInputInfo = armcomputetensorutils::BuildArmComputeTensorInfo(input);
+    const arm_compute::TensorInfo aclOutputInfo = armcomputetensorutils::BuildArmComputeTensorInfo(output);
+    const armnn::PermutationVector& mappings = descriptor.m_DimMappings;
 
-    ARM_COMPUTE_RETURN_ERROR_ON_MSG(!perm.IsEqual({ 0U, 3U, 1U, 2U })
-                                    && !perm.IsEqual({ 0U, 2U, 3U, 1U })
-                                    && !perm.IsEqual({ 3U, 2U, 0U, 1U }),
-    "Only [0, 3, 1, 2], [0, 2, 3, 1] and [3, 2, 0, 1] permutations are supported");
-
-    return arm_compute::Status{};
+    return arm_compute::CLPermute::validate(&aclInputInfo, &aclOutputInfo,
+                                            armcomputetensorutils::BuildArmComputePermutationVector(mappings));
 }
 
 ClPermuteWorkload::ClPermuteWorkload(const PermuteQueueDescriptor& descriptor,
diff --git a/src/backends/cl/workloads/ClPermuteWorkload.hpp b/src/backends/cl/workloads/ClPermuteWorkload.hpp
index 58aa7ea..8b5f4c6 100644
--- a/src/backends/cl/workloads/ClPermuteWorkload.hpp
+++ b/src/backends/cl/workloads/ClPermuteWorkload.hpp
@@ -16,7 +16,9 @@
 namespace armnn
 {
 
-arm_compute::Status ClPermuteWorkloadValidate(const PermuteDescriptor& descriptor);
+arm_compute::Status ClPermuteWorkloadValidate(const TensorInfo& input,
+                                              const TensorInfo& output,
+                                              const PermuteDescriptor& descriptor);
 
 class ClPermuteWorkload : public BaseWorkload<PermuteQueueDescriptor>
 {
diff --git a/src/backends/cl/workloads/ClReshapeWorkload.cpp b/src/backends/cl/workloads/ClReshapeWorkload.cpp
index db1702a..d752290 100644
--- a/src/backends/cl/workloads/ClReshapeWorkload.cpp
+++ b/src/backends/cl/workloads/ClReshapeWorkload.cpp
@@ -12,6 +12,15 @@
 namespace armnn
 {
 
+arm_compute::Status ClReshapeWorkloadValidate(const TensorInfo& input,
+                                              const TensorInfo& output)
+{
+    const arm_compute::TensorInfo aclInputInfo = armcomputetensorutils::BuildArmComputeTensorInfo(input);
+    const arm_compute::TensorInfo aclOutputInfo = armcomputetensorutils::BuildArmComputeTensorInfo(output);
+
+    return arm_compute::CLReshapeLayer::validate(&aclInputInfo, &aclOutputInfo);
+}
+
 ClReshapeWorkload::ClReshapeWorkload(const ReshapeQueueDescriptor& descriptor, const WorkloadInfo& info)
     : BaseWorkload<ReshapeQueueDescriptor>(descriptor, info)
 {
diff --git a/src/backends/cl/workloads/ClReshapeWorkload.hpp b/src/backends/cl/workloads/ClReshapeWorkload.hpp
index a7b464e..62f5fcc 100644
--- a/src/backends/cl/workloads/ClReshapeWorkload.hpp
+++ b/src/backends/cl/workloads/ClReshapeWorkload.hpp
@@ -12,6 +12,9 @@
 namespace armnn
 {
 
+arm_compute::Status ClReshapeWorkloadValidate(const TensorInfo& input,
+                                              const TensorInfo& output);
+
 class ClReshapeWorkload : public BaseWorkload<ReshapeQueueDescriptor>
 {
 public:
diff --git a/src/backends/neon/NeonLayerSupport.cpp b/src/backends/neon/NeonLayerSupport.cpp
index 80695fb..b2b165e 100644
--- a/src/backends/neon/NeonLayerSupport.cpp
+++ b/src/backends/neon/NeonLayerSupport.cpp
@@ -40,6 +40,7 @@
 #include "workloads/NeonPreluWorkload.hpp"
 #include "workloads/NeonQuantizeWorkload.hpp"
 #include "workloads/NeonQuantizedLstmWorkload.hpp"
+#include "workloads/NeonReshapeWorkload.hpp"
 #include "workloads/NeonResizeWorkload.hpp"
 #include "workloads/NeonSoftmaxBaseWorkload.hpp"
 #include "workloads/NeonSpaceToDepthWorkload.hpp"
@@ -499,14 +500,15 @@
 }
 
 bool NeonLayerSupport::IsReshapeSupported(const TensorInfo& input,
+                                          const TensorInfo& output,
                                           const ReshapeDescriptor& descriptor,
                                           Optional<std::string&> reasonIfUnsupported) const
 {
     ignore_unused(descriptor);
-    return IsSupportedForDataTypeNeon(reasonIfUnsupported,
-                                      input.GetDataType(),
-                                      &TrueFunc<>,
-                                      &TrueFunc<>);
+    FORWARD_WORKLOAD_VALIDATE_FUNC(NeonReshapeWorkloadValidate,
+                                   reasonIfUnsupported,
+                                   input,
+                                   output);
 }
 
 bool NeonLayerSupport::IsResizeSupported(const TensorInfo& input,
diff --git a/src/backends/neon/NeonLayerSupport.hpp b/src/backends/neon/NeonLayerSupport.hpp
index 7ba90e4..58181d3 100644
--- a/src/backends/neon/NeonLayerSupport.hpp
+++ b/src/backends/neon/NeonLayerSupport.hpp
@@ -174,6 +174,7 @@
                                   Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override;
 
     bool IsReshapeSupported(const TensorInfo& input,
+                            const TensorInfo& output,
                             const ReshapeDescriptor& descriptor,
                             Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override;
 
diff --git a/src/backends/neon/workloads/NeonReshapeWorkload.cpp b/src/backends/neon/workloads/NeonReshapeWorkload.cpp
index 7f2056c..659bb94 100644
--- a/src/backends/neon/workloads/NeonReshapeWorkload.cpp
+++ b/src/backends/neon/workloads/NeonReshapeWorkload.cpp
@@ -14,6 +14,15 @@
 namespace armnn
 {
 
+arm_compute::Status NeonReshapeWorkloadValidate(const TensorInfo& input,
+                                                const TensorInfo& output)
+{
+    const arm_compute::TensorInfo aclInputInfo = armcomputetensorutils::BuildArmComputeTensorInfo(input);
+    const arm_compute::TensorInfo aclOutputInfo = armcomputetensorutils::BuildArmComputeTensorInfo(output);
+
+    return arm_compute::NEReshapeLayer::validate(&aclInputInfo, &aclOutputInfo);
+}
+
 NeonReshapeWorkload::NeonReshapeWorkload(const ReshapeQueueDescriptor& descriptor,
                                          const WorkloadInfo& info)
     : BaseWorkload<ReshapeQueueDescriptor>(descriptor, info)
diff --git a/src/backends/neon/workloads/NeonReshapeWorkload.hpp b/src/backends/neon/workloads/NeonReshapeWorkload.hpp
index 2202463..186a02b 100644
--- a/src/backends/neon/workloads/NeonReshapeWorkload.hpp
+++ b/src/backends/neon/workloads/NeonReshapeWorkload.hpp
@@ -6,7 +6,10 @@
 #pragma once
 
 #include <backendsCommon/Workload.hpp>
+#include <backendsCommon/WorkloadData.hpp>
+#include <neon/workloads/NeonWorkloadUtils.hpp>
 
+#include <armnn/TypesUtils.hpp>
 #include <arm_compute/runtime/IFunction.h>
 
 #include <memory>
@@ -14,6 +17,8 @@
 namespace armnn
 {
 
+arm_compute::Status NeonReshapeWorkloadValidate(const TensorInfo& input, const TensorInfo& output);
+
 class NeonReshapeWorkload : public BaseWorkload<ReshapeQueueDescriptor>
 {
 public:
diff --git a/src/backends/reference/RefLayerSupport.cpp b/src/backends/reference/RefLayerSupport.cpp
index 22d7914..b776540 100644
--- a/src/backends/reference/RefLayerSupport.cpp
+++ b/src/backends/reference/RefLayerSupport.cpp
@@ -1228,9 +1228,11 @@
 }
 
 bool RefLayerSupport::IsReshapeSupported(const TensorInfo& input,
+                                         const TensorInfo& output,
                                          const ReshapeDescriptor& descriptor,
                                          Optional<std::string&> reasonIfUnsupported) const
 {
+    ignore_unused(output);
     ignore_unused(descriptor);
     // Define supported output types.
     std::array<DataType,4> supportedOutputTypes =
diff --git a/src/backends/reference/RefLayerSupport.hpp b/src/backends/reference/RefLayerSupport.hpp
index f8bbeb7..b37ab8b 100644
--- a/src/backends/reference/RefLayerSupport.hpp
+++ b/src/backends/reference/RefLayerSupport.hpp
@@ -199,6 +199,7 @@
                              Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override;
 
     bool IsReshapeSupported(const TensorInfo& input,
+                            const TensorInfo& output,
                             const ReshapeDescriptor& descriptor,
                             Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override;