From 207ef9a6b8b3ea0afe9a095639f67b5dedd095d7 Mon Sep 17 00:00:00 2001 From: Nattapat Chaimanowong Date: Fri, 2 Nov 2018 10:57:25 +0000 Subject: IVGCVSW-2093 Add SpaceToBatchNd layer and corresponding no-op factory implementations Change-Id: Ibd457f3a2d4342c4d6335bd3c471282a14ab6b14 --- src/backends/ILayerSupport.cpp | 8 ++++++ src/backends/WorkloadData.cpp | 40 ++++++++++++++++++++++++++ src/backends/WorkloadData.hpp | 5 ++++ src/backends/WorkloadFactory.cpp | 11 +++++++ src/backends/WorkloadFactory.hpp | 3 ++ src/backends/cl/ClWorkloadFactory.cpp | 12 ++++++++ src/backends/cl/ClWorkloadFactory.hpp | 3 ++ src/backends/neon/NeonWorkloadFactory.cpp | 12 ++++++++ src/backends/neon/NeonWorkloadFactory.hpp | 3 ++ src/backends/reference/RefWorkloadFactory.cpp | 6 ++++ src/backends/reference/RefWorkloadFactory.hpp | 3 ++ src/backends/test/IsLayerSupportedTestImpl.hpp | 2 ++ 12 files changed, 108 insertions(+) (limited to 'src/backends') diff --git a/src/backends/ILayerSupport.cpp b/src/backends/ILayerSupport.cpp index 34168c55b8..ebfff5d429 100644 --- a/src/backends/ILayerSupport.cpp +++ b/src/backends/ILayerSupport.cpp @@ -256,6 +256,14 @@ bool ILayerSupport::IsSoftmaxSupported(const TensorInfo& input, return DefaultLayerSupport(__func__, __FILE__, __LINE__, reasonIfUnsupported); } +bool ILayerSupport::IsSpaceToBatchNdSupported(const TensorInfo& input, + const TensorInfo& output, + const SpaceToBatchNdDescriptor& descriptor, + Optional reasonIfUnsupported) const +{ + return DefaultLayerSupport(__func__, __FILE__, __LINE__, reasonIfUnsupported); +} + bool ILayerSupport::IsSplitterSupported(const TensorInfo& input, const ViewsDescriptor& descriptor, Optional reasonIfUnsupported) const diff --git a/src/backends/WorkloadData.cpp b/src/backends/WorkloadData.cpp index ef31fbd1fb..495d4ecde9 100644 --- a/src/backends/WorkloadData.cpp +++ b/src/backends/WorkloadData.cpp @@ -741,6 +741,46 @@ void ReshapeQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const } } +void SpaceToBatchNdQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const +{ + ValidateSingleInput(workloadInfo, "SpaceToBatchNdQueueDescriptor"); + ValidateSingleOutput(workloadInfo, "SpaceToBatchNdQueueDescriptor"); + + ValidateTensorNumDimensions(workloadInfo.m_InputTensorInfos[0], "SpaceToBatchNdQueueDescriptor", 4, "input"); + ValidateTensorNumDimensions(workloadInfo.m_OutputTensorInfos[0], "SpaceToBatchNdQueueDescriptor", 4, "output"); + + if (workloadInfo.m_InputTensorInfos[0].GetNumElements() != workloadInfo.m_OutputTensorInfos[0].GetNumElements()) + { + throw InvalidArgumentException("SpaceToBatchNdQueueDescriptor: Input tensor has " + + to_string(workloadInfo.m_InputTensorInfos[0].GetNumElements()) + " but output tensor has " + + to_string(workloadInfo.m_OutputTensorInfos[0].GetNumElements()) + " elements."); + } + + if (m_Parameters.m_BlockShape.size() != 2) + { + throw InvalidArgumentException("Block Shape must contains 2 spatial dimensions"); + } + + if (m_Parameters.m_BlockShape.size() != m_Parameters.m_PadList.size()) + { + throw InvalidArgumentException("Pad List must contains the same number of dimensions as Block Shape."); + } + + const TensorShape inputShape = workloadInfo.m_InputTensorInfos[0].GetShape(); + + std::pair heightPad = m_Parameters.m_PadList[0]; + std::pair widthPad = m_Parameters.m_PadList[1]; + + if ((inputShape[m_Parameters.m_DataLayout.GetHeightIndex()] + heightPad.first + heightPad.second) + % m_Parameters.m_BlockShape[0] != 0 || + (inputShape[m_Parameters.m_DataLayout.GetWidthIndex()] + widthPad.first + widthPad.second) + % m_Parameters.m_BlockShape[1] != 0) + { + throw InvalidArgumentException( + "Input shape after padding must be divisible by Block Shape in all spatial dimensions"); + } +} + void FloorQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const { ValidateSingleInput(workloadInfo, "FloorQueueDescriptor"); diff --git a/src/backends/WorkloadData.hpp b/src/backends/WorkloadData.hpp index 40e89f76e4..867d9f2159 100644 --- a/src/backends/WorkloadData.hpp +++ b/src/backends/WorkloadData.hpp @@ -271,6 +271,11 @@ struct ReshapeQueueDescriptor : QueueDescriptorWithParameters void Validate(const WorkloadInfo& workloadInfo) const; }; +struct SpaceToBatchNdQueueDescriptor : QueueDescriptorWithParameters +{ + void Validate(const WorkloadInfo& workloadInfo) const; +}; + struct FloorQueueDescriptor : QueueDescriptor { void Validate(const WorkloadInfo& workloadInfo) const; diff --git a/src/backends/WorkloadFactory.cpp b/src/backends/WorkloadFactory.cpp index 2e7a24f732..e9c2ab7a5d 100644 --- a/src/backends/WorkloadFactory.cpp +++ b/src/backends/WorkloadFactory.cpp @@ -542,6 +542,17 @@ bool IWorkloadFactory::IsLayerSupported(const BackendId& backendId, reason); break; } + case LayerType::SpaceToBatchNd: + { + auto cLayer = boost::polymorphic_downcast(&layer); + const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo(); + result = layerSupportObject->IsSpaceToBatchNdSupported(OverrideDataType(input, dataType), + OverrideDataType(output, dataType), + cLayer->GetParameters(), + reason); + break; + } case LayerType::Splitter: { auto cLayer = boost::polymorphic_downcast(&layer); diff --git a/src/backends/WorkloadFactory.hpp b/src/backends/WorkloadFactory.hpp index 2f422ab4f6..96906cb7f5 100644 --- a/src/backends/WorkloadFactory.hpp +++ b/src/backends/WorkloadFactory.hpp @@ -116,6 +116,9 @@ public: virtual std::unique_ptr CreateReshape(const ReshapeQueueDescriptor& descriptor, const WorkloadInfo& info) const = 0; + virtual std::unique_ptr CreateSpaceToBatchNd(const SpaceToBatchNdQueueDescriptor& descriptor, + const WorkloadInfo& info) const = 0; + virtual std::unique_ptr CreateFloor(const FloorQueueDescriptor& descriptor, const WorkloadInfo& info) const = 0; diff --git a/src/backends/cl/ClWorkloadFactory.cpp b/src/backends/cl/ClWorkloadFactory.cpp index 08ee9e922d..ae9d471f13 100644 --- a/src/backends/cl/ClWorkloadFactory.cpp +++ b/src/backends/cl/ClWorkloadFactory.cpp @@ -274,6 +274,12 @@ std::unique_ptr ClWorkloadFactory::CreateReshape(const ReshapeQueueDe return MakeWorkload(descriptor, info); } +std::unique_ptr ClWorkloadFactory::CreateSpaceToBatchNd(const SpaceToBatchNdQueueDescriptor& descriptor, + const WorkloadInfo& info) const +{ + return nullptr; +} + std::unique_ptr ClWorkloadFactory::CreateFloor(const FloorQueueDescriptor& descriptor, const WorkloadInfo& info) const { @@ -477,6 +483,12 @@ std::unique_ptr ClWorkloadFactory::CreateReshape(const ReshapeQueueDe return nullptr; } +std::unique_ptr ClWorkloadFactory::CreateSpaceToBatchNd(const SpaceToBatchNdQueueDescriptor& descriptor, + const WorkloadInfo& info) const +{ + return nullptr; +} + std::unique_ptr ClWorkloadFactory::CreateFloor(const FloorQueueDescriptor& descriptor, const WorkloadInfo& info) const { diff --git a/src/backends/cl/ClWorkloadFactory.hpp b/src/backends/cl/ClWorkloadFactory.hpp index ba7cf6931f..bd4ab50be0 100644 --- a/src/backends/cl/ClWorkloadFactory.hpp +++ b/src/backends/cl/ClWorkloadFactory.hpp @@ -99,6 +99,9 @@ public: virtual std::unique_ptr CreateReshape(const ReshapeQueueDescriptor& descriptor, const WorkloadInfo& info) const override; + virtual std::unique_ptr CreateSpaceToBatchNd(const SpaceToBatchNdQueueDescriptor& descriptor, + const WorkloadInfo& info) const override; + virtual std::unique_ptr CreateFloor(const FloorQueueDescriptor& descriptor, const WorkloadInfo& info) const override; diff --git a/src/backends/neon/NeonWorkloadFactory.cpp b/src/backends/neon/NeonWorkloadFactory.cpp index c16d383554..81d088b5aa 100644 --- a/src/backends/neon/NeonWorkloadFactory.cpp +++ b/src/backends/neon/NeonWorkloadFactory.cpp @@ -238,6 +238,12 @@ std::unique_ptr NeonWorkloadFactory::CreateReshape(const ReshapeQueue return std::make_unique(descriptor, info); } +std::unique_ptr NeonWorkloadFactory::CreateSpaceToBatchNd(const SpaceToBatchNdQueueDescriptor& descriptor, + const WorkloadInfo& info) const +{ + return nullptr; +} + std::unique_ptr NeonWorkloadFactory::CreateFloor(const FloorQueueDescriptor& descriptor, const WorkloadInfo& info) const { @@ -441,6 +447,12 @@ std::unique_ptr NeonWorkloadFactory::CreateReshape(const ReshapeQueue return nullptr; } +std::unique_ptr NeonWorkloadFactory::CreateSpaceToBatchNd(const SpaceToBatchNdQueueDescriptor& descriptor, + const WorkloadInfo& info) const +{ + return nullptr; +} + std::unique_ptr NeonWorkloadFactory::CreateFloor(const FloorQueueDescriptor& descriptor, const WorkloadInfo& info) const { diff --git a/src/backends/neon/NeonWorkloadFactory.hpp b/src/backends/neon/NeonWorkloadFactory.hpp index 030e982a20..da83693a35 100644 --- a/src/backends/neon/NeonWorkloadFactory.hpp +++ b/src/backends/neon/NeonWorkloadFactory.hpp @@ -100,6 +100,9 @@ public: virtual std::unique_ptr CreateReshape(const ReshapeQueueDescriptor& descriptor, const WorkloadInfo& info) const override; + virtual std::unique_ptr CreateSpaceToBatchNd(const SpaceToBatchNdQueueDescriptor& descriptor, + const WorkloadInfo& info) const override; + virtual std::unique_ptr CreateFloor(const FloorQueueDescriptor& descriptor, const WorkloadInfo& info) const override; diff --git a/src/backends/reference/RefWorkloadFactory.cpp b/src/backends/reference/RefWorkloadFactory.cpp index 864ffdbf4f..3af81567e5 100644 --- a/src/backends/reference/RefWorkloadFactory.cpp +++ b/src/backends/reference/RefWorkloadFactory.cpp @@ -214,6 +214,12 @@ std::unique_ptr RefWorkloadFactory::CreateReshape(const ReshapeQueueD return MakeWorkload(descriptor, info); } +std::unique_ptr RefWorkloadFactory::CreateSpaceToBatchNd(const SpaceToBatchNdQueueDescriptor& descriptor, + const WorkloadInfo& info) const +{ + return MakeWorkload(descriptor, info); +} + std::unique_ptr RefWorkloadFactory::CreateFloor(const FloorQueueDescriptor& descriptor, const WorkloadInfo& info) const { diff --git a/src/backends/reference/RefWorkloadFactory.hpp b/src/backends/reference/RefWorkloadFactory.hpp index be0dafc159..2e51ec37cc 100644 --- a/src/backends/reference/RefWorkloadFactory.hpp +++ b/src/backends/reference/RefWorkloadFactory.hpp @@ -117,6 +117,9 @@ public: virtual std::unique_ptr CreateReshape(const ReshapeQueueDescriptor& descriptor, const WorkloadInfo& info) const override; + virtual std::unique_ptr CreateSpaceToBatchNd(const SpaceToBatchNdQueueDescriptor& descriptor, + const WorkloadInfo& info) const override; + virtual std::unique_ptr CreateFloor(const FloorQueueDescriptor& descriptor, const WorkloadInfo& info) const override; diff --git a/src/backends/test/IsLayerSupportedTestImpl.hpp b/src/backends/test/IsLayerSupportedTestImpl.hpp index 1bcf56dc61..722d82d8ab 100644 --- a/src/backends/test/IsLayerSupportedTestImpl.hpp +++ b/src/backends/test/IsLayerSupportedTestImpl.hpp @@ -352,6 +352,8 @@ DECLARE_LAYER_POLICY_2_PARAM(Reshape) DECLARE_LAYER_POLICY_2_PARAM(Softmax) +DECLARE_LAYER_POLICY_2_PARAM(SpaceToBatchNd) + DECLARE_LAYER_POLICY_2_PARAM(Splitter) DECLARE_LAYER_POLICY_1_PARAM(Subtraction) -- cgit v1.2.1