IVGCVSW-1880: Add no-op factory implementations of CreatePad

* Added PadDescriptor and PadQueueDescriptor
* Factory method CreatePad on all backends returning null workloads

Change-Id: Ifeb50f9249ea31edfc3586d49b008ea1b5c59ae2
diff --git a/include/armnn/Descriptors.hpp b/include/armnn/Descriptors.hpp
index 5f9df6b..8940e0b 100644
--- a/include/armnn/Descriptors.hpp
+++ b/include/armnn/Descriptors.hpp
@@ -347,4 +347,14 @@
     bool m_KeepDims;
 };
 
+struct PadDescriptor
+{
+    PadDescriptor(const std::vector<std::pair<unsigned int, unsigned int>>& padList);
+
+    // first is number of values to add before the tensor in the dimension,
+    // second is the number of values to add after the tensor in the dimension
+    // the number of pairs should match the number of dimensions in the input tensor.
+    std::vector<std::pair<unsigned int, unsigned int>> m_PadList;
+};
+
 }
diff --git a/src/armnn/backends/ClWorkloadFactory.cpp b/src/armnn/backends/ClWorkloadFactory.cpp
index 217c637..c35f044 100644
--- a/src/armnn/backends/ClWorkloadFactory.cpp
+++ b/src/armnn/backends/ClWorkloadFactory.cpp
@@ -258,6 +258,12 @@
     return MakeWorkload<NullWorkload, NullWorkload>(descriptor, info);
 }
 
+std::unique_ptr<IWorkload> ClWorkloadFactory::CreatePad(const PadQueueDescriptor& descriptor,
+                                                        const WorkloadInfo& info) const
+{
+    return MakeWorkload<NullWorkload, NullWorkload>(descriptor, info);
+}
+
 void ClWorkloadFactory::Finalize()
 {
     m_MemoryManager.Finalize();
@@ -461,6 +467,12 @@
     return nullptr;
 }
 
+std::unique_ptr<IWorkload> ClWorkloadFactory::CreatePad(const PadQueueDescriptor& descriptor,
+                                                        const WorkloadInfo& info) const
+{
+    return nullptr;
+}
+
 void ClWorkloadFactory::Finalize()
 {
 }
diff --git a/src/armnn/backends/ClWorkloadFactory.hpp b/src/armnn/backends/ClWorkloadFactory.hpp
index 4403310..892d564 100644
--- a/src/armnn/backends/ClWorkloadFactory.hpp
+++ b/src/armnn/backends/ClWorkloadFactory.hpp
@@ -117,6 +117,9 @@
     virtual std::unique_ptr<IWorkload> CreateMean(const MeanQueueDescriptor& descriptor,
                                                   const WorkloadInfo& Info) const override;
 
+    virtual std::unique_ptr<IWorkload> CreatePad(const PadQueueDescriptor& descriptor,
+                                                 const WorkloadInfo& info) const override;
+
     virtual void Finalize() override;
 
     virtual void Release() override;
diff --git a/src/armnn/backends/NeonWorkloadFactory.cpp b/src/armnn/backends/NeonWorkloadFactory.cpp
index ccbec9a..80ce0b9 100644
--- a/src/armnn/backends/NeonWorkloadFactory.cpp
+++ b/src/armnn/backends/NeonWorkloadFactory.cpp
@@ -250,6 +250,12 @@
     return MakeWorkload<NullWorkload, NullWorkload>(descriptor, info);
 }
 
+std::unique_ptr<IWorkload> NeonWorkloadFactory::CreatePad(const PadQueueDescriptor& descriptor,
+                                                          const WorkloadInfo& info) const
+{
+    return MakeWorkload<NullWorkload, NullWorkload>(descriptor, info);
+}
+
 void NeonWorkloadFactory::Finalize()
 {
     m_MemoryManager.Finalize();
@@ -453,6 +459,12 @@
     return nullptr;
 }
 
+std::unique_ptr<IWorkload> NeonWorkloadFactory::CreatePad(const PadQueueDescriptor& descriptor,
+                                                          const WorkloadInfo& info) const
+{
+    return nullptr;
+}
+
 void NeonWorkloadFactory::Finalize()
 {}
 
diff --git a/src/armnn/backends/NeonWorkloadFactory.hpp b/src/armnn/backends/NeonWorkloadFactory.hpp
index 5410c22..a981855 100644
--- a/src/armnn/backends/NeonWorkloadFactory.hpp
+++ b/src/armnn/backends/NeonWorkloadFactory.hpp
@@ -117,6 +117,9 @@
     virtual std::unique_ptr<IWorkload> CreateMean(const MeanQueueDescriptor& descriptor,
                                                   const WorkloadInfo& Info) const override;
 
+    virtual std::unique_ptr<IWorkload> CreatePad(const PadQueueDescriptor& descriptor,
+                                                 const WorkloadInfo& info) const override;
+
     virtual void Finalize() override;
 
     virtual void Release() override;
diff --git a/src/armnn/backends/RefWorkloadFactory.cpp b/src/armnn/backends/RefWorkloadFactory.cpp
index 318f47c..93b4d94 100644
--- a/src/armnn/backends/RefWorkloadFactory.cpp
+++ b/src/armnn/backends/RefWorkloadFactory.cpp
@@ -239,4 +239,11 @@
     return MakeWorkload<NullWorkload, NullWorkload>(descriptor, info);
 }
 
+std::unique_ptr<IWorkload> RefWorkloadFactory::CreatePad(const PadQueueDescriptor& descriptor,
+                                                 const WorkloadInfo& info) const
+{
+    return MakeWorkload<NullWorkload, NullWorkload>(descriptor, info);
+}
+
+
 } // namespace armnn
diff --git a/src/armnn/backends/RefWorkloadFactory.hpp b/src/armnn/backends/RefWorkloadFactory.hpp
index 5e694d6..6b13377 100644
--- a/src/armnn/backends/RefWorkloadFactory.hpp
+++ b/src/armnn/backends/RefWorkloadFactory.hpp
@@ -132,6 +132,9 @@
 
     virtual std::unique_ptr<IWorkload> CreateMean(const MeanQueueDescriptor& descriptor,
                                                   const WorkloadInfo& Info) const override;
+
+    virtual std::unique_ptr<IWorkload> CreatePad(const PadQueueDescriptor& descriptor,
+                                                 const WorkloadInfo& info) const override;
 private:
 
     template <typename F32Workload, typename U8Workload, typename QueueDescriptorType>
diff --git a/src/armnn/backends/WorkloadData.cpp b/src/armnn/backends/WorkloadData.cpp
index 25144a4..c5c607d 100644
--- a/src/armnn/backends/WorkloadData.cpp
+++ b/src/armnn/backends/WorkloadData.cpp
@@ -850,4 +850,22 @@
     }
 }
 
+void PadQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
+{
+    ValidateSingleInput(workloadInfo, "PadQueueDescriptor");
+    ValidateSingleOutput(workloadInfo, "PadQueueDescriptor");
+
+    const TensorInfo& input = workloadInfo.m_InputTensorInfos[0];
+    const TensorInfo& output = workloadInfo.m_OutputTensorInfos[1];
+    // input and output should have the same number of dimensions
+    ValidateTensorNumDimensions(output, "PadQueueDescriptor", input.GetNumDimensions(), "output");
+    // there should be entry in the pad list for each dimension in the input tensor
+    if (m_Parameters.m_PadList.size() != input.GetNumDimensions()) {
+        throw InvalidArgumentException("Pad List should contain the same number of entries as there"
+                                       " are dimensions in the input tensor that is " +
+                                       to_string(input.GetNumDimensions()) + " entries " +
+                                       " not " + to_string(m_Parameters.m_PadList.size()) + " entries.");
+    }
+}
+
 } //namespace armnn
diff --git a/src/armnn/backends/WorkloadData.hpp b/src/armnn/backends/WorkloadData.hpp
index a36f0ad..b5b0402 100644
--- a/src/armnn/backends/WorkloadData.hpp
+++ b/src/armnn/backends/WorkloadData.hpp
@@ -202,6 +202,12 @@
     void Validate(const WorkloadInfo& workloadInfo) const;
 };
 
+// Pad layer workload data
+struct PadQueueDescriptor : QueueDescriptorWithParameters<PadDescriptor>
+{
+    void Validate(const WorkloadInfo& workloadInfo) const;
+};
+
 // Batch norm layer workload data.
 struct BatchNormalizationQueueDescriptor : QueueDescriptorWithParameters<BatchNormalizationDescriptor>
 {
diff --git a/src/armnn/backends/WorkloadFactory.hpp b/src/armnn/backends/WorkloadFactory.hpp
index 3cd04f9..fbc6134 100644
--- a/src/armnn/backends/WorkloadFactory.hpp
+++ b/src/armnn/backends/WorkloadFactory.hpp
@@ -129,6 +129,9 @@
 
     virtual std::unique_ptr<IWorkload> CreateMean(const MeanQueueDescriptor& descriptor,
                                                   const WorkloadInfo& Info) const = 0;
+
+    virtual std::unique_ptr<IWorkload> CreatePad(const PadQueueDescriptor& descriptor,
+                                                 const WorkloadInfo& Info) const = 0;
 };
 
 } //namespace armnn