diff options
26 files changed, 186 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk index 62a992d434..0e0fa9c89c 100644 --- a/Android.mk +++ b/Android.mk @@ -92,6 +92,7 @@ LOCAL_SRC_FILES := \ src/armnn/layers/ConvertFp32ToFp16Layer.cpp \ src/armnn/layers/DebugLayer.cpp \ src/armnn/layers/DepthwiseConvolution2dLayer.cpp \ + src/armnn/layers/DetectionPostProcessLayer.cpp \ src/armnn/layers/DivisionLayer.cpp \ src/armnn/layers/ElementwiseBaseLayer.cpp \ src/armnn/layers/EqualLayer.cpp \ diff --git a/CMakeLists.txt b/CMakeLists.txt index 339efd0731..6b893f2aef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -191,6 +191,8 @@ list(APPEND armnn_sources src/armnn/layers/DebugLayer.cpp src/armnn/layers/DepthwiseConvolution2dLayer.hpp src/armnn/layers/DepthwiseConvolution2dLayer.cpp + src/armnn/layers/DetectionPostProcessLayer.hpp + src/armnn/layers/DetectionPostProcessLayer.cpp src/armnn/layers/ElementwiseBaseLayer.hpp src/armnn/layers/ElementwiseBaseLayer.cpp src/armnn/layers/EqualLayer.hpp diff --git a/include/armnn/Descriptors.hpp b/include/armnn/Descriptors.hpp index 4497d0da9e..44235c7ada 100644 --- a/include/armnn/Descriptors.hpp +++ b/include/armnn/Descriptors.hpp @@ -327,6 +327,10 @@ struct DepthwiseConvolution2dDescriptor DataLayout m_DataLayout; }; +struct DetectionPostProcessDescriptor +{ +}; + /// A NormalizationDescriptor for the NormalizationLayer. struct NormalizationDescriptor { diff --git a/include/armnn/DescriptorsFwd.hpp b/include/armnn/DescriptorsFwd.hpp index c1d21b5665..f0a4cffab7 100644 --- a/include/armnn/DescriptorsFwd.hpp +++ b/include/armnn/DescriptorsFwd.hpp @@ -13,6 +13,7 @@ struct BatchToSpaceNdDescriptor; struct Convolution2dDescriptor; struct DebugDescriptor; struct DepthwiseConvolution2dDescriptor; +struct DetectionPostProcessDescriptor; struct FakeQuantizationDescriptor; struct FullyConnectedDescriptor; struct L2NormalizationDescriptor; diff --git a/include/armnn/ILayerSupport.hpp b/include/armnn/ILayerSupport.hpp index a603229b96..b5f9e6ac6c 100644 --- a/include/armnn/ILayerSupport.hpp +++ b/include/armnn/ILayerSupport.hpp @@ -77,6 +77,12 @@ public: const Optional<TensorInfo>& biases, Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const = 0; + virtual bool IsDetectionPostProcessSupported( + const TensorInfo& input0, + const TensorInfo& input1, + const DetectionPostProcessDescriptor& descriptor, + Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const = 0; + virtual bool IsDivisionSupported(const TensorInfo& input0, const TensorInfo& input1, const TensorInfo& output, diff --git a/include/armnn/INetwork.hpp b/include/armnn/INetwork.hpp index 05962b95b7..1f7354dd35 100644 --- a/include/armnn/INetwork.hpp +++ b/include/armnn/INetwork.hpp @@ -127,6 +127,13 @@ public: const ConstTensor& biases, const char* name = nullptr) = 0; + /// Adds a Detection PostProcess layer to the network. + /// @param descriptor - Description of the Detection PostProcess layer. + /// @param name - Optional name for the layer. + /// @return - Interface for configuring the layer. + virtual IConnectableLayer* AddDetectionPostProcessLayer( + const DetectionPostProcessDescriptor& descriptor, const char* name = nullptr) =0; + /// Adds a fully connected layer to the network. /// @param fullyConnectedDescriptor - Description of the fully connected layer. /// @param weights - Tensor for the weights data. diff --git a/src/armnn/InternalTypes.cpp b/src/armnn/InternalTypes.cpp index 15f4aa07e2..e4a6ac82d5 100644 --- a/src/armnn/InternalTypes.cpp +++ b/src/armnn/InternalTypes.cpp @@ -24,6 +24,7 @@ char const* GetLayerTypeAsCString(LayerType type) case LayerType::Convolution2d: return "Convolution2d"; case LayerType::Debug: return "Debug"; case LayerType::DepthwiseConvolution2d: return "DepthwiseConvolution2d"; + case LayerType::DetectionPostProcess: return "DetectionPostProcess"; case LayerType::Division: return "Division"; case LayerType::Equal: return "Equal"; case LayerType::FakeQuantization: return "FakeQuantization"; diff --git a/src/armnn/InternalTypes.hpp b/src/armnn/InternalTypes.hpp index 704efdf2b7..a61c7b8147 100644 --- a/src/armnn/InternalTypes.hpp +++ b/src/armnn/InternalTypes.hpp @@ -24,6 +24,7 @@ enum class LayerType Convolution2d, Debug, DepthwiseConvolution2d, + DetectionPostProcess, Division, Equal, FakeQuantization, diff --git a/src/armnn/LayerSupport.cpp b/src/armnn/LayerSupport.cpp index 2eaf780f91..484251ca97 100644 --- a/src/armnn/LayerSupport.cpp +++ b/src/armnn/LayerSupport.cpp @@ -190,6 +190,13 @@ bool IsDepthwiseConvolutionSupported(const BackendId& backend, FORWARD_LAYER_SUPPORT_FUNC(backend, IsDepthwiseConvolutionSupported, input, output, descriptor, weights, biases); } +bool IsDetectionPostProcessSupported(const BackendId& backend, + const TensorInfo& input0, + const TensorInfo& input1, + const DetectionPostProcessDescriptor& descriptor, + char* reasonIfUnsupported, + size_t reasonIfUnsupportedMaxLength); + bool IsDivisionSupported(const BackendId& backend, const TensorInfo& input0, const TensorInfo& input1, diff --git a/src/armnn/LayersFwd.hpp b/src/armnn/LayersFwd.hpp index 27806c5752..497b517f28 100644 --- a/src/armnn/LayersFwd.hpp +++ b/src/armnn/LayersFwd.hpp @@ -16,6 +16,7 @@ #include "layers/Convolution2dLayer.hpp" #include "layers/DebugLayer.hpp" #include "layers/DepthwiseConvolution2dLayer.hpp" +#include "layers/DetectionPostProcessLayer.hpp" #include "layers/DivisionLayer.hpp" #include "layers/EqualLayer.hpp" #include "layers/FakeQuantizationLayer.hpp" @@ -84,6 +85,7 @@ DECLARE_LAYER(ConvertFp32ToFp16) DECLARE_LAYER(Convolution2d) DECLARE_LAYER(Debug) DECLARE_LAYER(DepthwiseConvolution2d) +DECLARE_LAYER(DetectionPostProcess) DECLARE_LAYER(Division) DECLARE_LAYER(Equal) DECLARE_LAYER(FakeQuantization) diff --git a/src/armnn/Network.cpp b/src/armnn/Network.cpp index f9ebad2b08..662a9ccd3c 100644 --- a/src/armnn/Network.cpp +++ b/src/armnn/Network.cpp @@ -594,6 +594,12 @@ IConnectableLayer* Network::AddDepthwiseConvolution2dLayer( return AddDepthwiseConvolution2dLayerImpl(convolution2dDescriptor, weights, &biases, name); } +IConnectableLayer* Network::AddDetectionPostProcessLayer(const armnn::DetectionPostProcessDescriptor& descriptor, + const char* name) +{ + return m_Graph->AddLayer<DetectionPostProcessLayer>(descriptor, name); +} + IConnectableLayer* Network::AddPermuteLayer(const PermuteDescriptor& permuteDescriptor, const char* name) { diff --git a/src/armnn/Network.hpp b/src/armnn/Network.hpp index 7690fafac0..4239ac5ba4 100644 --- a/src/armnn/Network.hpp +++ b/src/armnn/Network.hpp @@ -57,6 +57,10 @@ public: const ConstTensor& biases, const char* name = nullptr) override; + IConnectableLayer* AddDetectionPostProcessLayer( + const DetectionPostProcessDescriptor& descriptor, + const char* name = nullptr) override; + IConnectableLayer* AddFullyConnectedLayer(const FullyConnectedDescriptor& fullyConnectedDescriptor, const ConstTensor& weights, const char* name = nullptr) override; diff --git a/src/armnn/layers/DetectionPostProcessLayer.cpp b/src/armnn/layers/DetectionPostProcessLayer.cpp new file mode 100644 index 0000000000..99aaac7b9f --- /dev/null +++ b/src/armnn/layers/DetectionPostProcessLayer.cpp @@ -0,0 +1,39 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "DetectionPostProcessLayer.hpp" + +#include "LayerCloneBase.hpp" + +#include <armnn/TypesUtils.hpp> +#include <backendsCommon/WorkloadData.hpp> +#include <backendsCommon/WorkloadFactory.hpp> + +namespace armnn +{ + +DetectionPostProcessLayer::DetectionPostProcessLayer(const DetectionPostProcessDescriptor& param, const char* name) + : LayerWithParameters(2, 4, LayerType::DetectionPostProcess, param, name) +{ +} + +std::unique_ptr<IWorkload> DetectionPostProcessLayer::CreateWorkload(const armnn::Graph& graph, + const armnn::IWorkloadFactory& factory) const +{ + DetectionPostProcessQueueDescriptor descriptor; + return factory.CreateDetectionPostProcess(descriptor, PrepInfoAndDesc(descriptor, graph)); +} + +DetectionPostProcessLayer* DetectionPostProcessLayer::Clone(Graph& graph) const +{ + return CloneBase<DetectionPostProcessLayer>(graph, m_Param, GetName()); +} + +void DetectionPostProcessLayer::ValidateTensorShapesFromInputs() +{ + VerifyLayerConnections(2, CHECK_LOCATION()); +} + +} // namespace armnn diff --git a/src/armnn/layers/DetectionPostProcessLayer.hpp b/src/armnn/layers/DetectionPostProcessLayer.hpp new file mode 100644 index 0000000000..b5a1cf17fb --- /dev/null +++ b/src/armnn/layers/DetectionPostProcessLayer.hpp @@ -0,0 +1,43 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include "LayerWithParameters.hpp" + +namespace armnn +{ + +/// This layer represents a detection postprocess operator. +class DetectionPostProcessLayer : public LayerWithParameters<DetectionPostProcessDescriptor> +{ +public: + /// Makes a workload for the DetectionPostProcess type. + /// @param [in] graph The graph where this layer can be found. + /// @param [in] factory The workload factory which will create the workload. + /// @return A pointer to the created workload, or nullptr if not created. + virtual std::unique_ptr<IWorkload> CreateWorkload(const Graph& graph, + const IWorkloadFactory& factory) const override; + + /// Creates a dynamically-allocated copy of this layer. + /// @param [in] graph The graph into which this layer is being cloned. + DetectionPostProcessLayer* Clone(Graph& graph) const override; + + /// Check if the input tensor shape(s) + /// will lead to a valid configuration of @ref DetectionPostProcessLayer. + void ValidateTensorShapesFromInputs() override; + +protected: + /// Constructor to create a DetectionPostProcessLayer. + /// @param [in] param DetectionPostProcessDescriptor to configure the detection postprocess. + /// @param [in] name Optional name for the layer. + DetectionPostProcessLayer(const DetectionPostProcessDescriptor& param, const char* name); + + /// Default destructor + ~DetectionPostProcessLayer() = default; +}; + +} // namespace armnn + diff --git a/src/backends/backendsCommon/LayerSupportBase.cpp b/src/backends/backendsCommon/LayerSupportBase.cpp index 75790dc61a..6358f6f0a8 100644 --- a/src/backends/backendsCommon/LayerSupportBase.cpp +++ b/src/backends/backendsCommon/LayerSupportBase.cpp @@ -116,6 +116,14 @@ bool LayerSupportBase::IsDepthwiseConvolutionSupported(const TensorInfo& input, return DefaultLayerSupport(__func__, __FILE__, __LINE__, reasonIfUnsupported); } +bool LayerSupportBase::IsDetectionPostProcessSupported(const armnn::TensorInfo& input0, + const armnn::TensorInfo& input1, + const armnn::DetectionPostProcessDescriptor& descriptor, + armnn::Optional<std::string&> reasonIfUnsupported) const +{ + return DefaultLayerSupport(__func__, __FILE__, __LINE__, reasonIfUnsupported); +} + bool LayerSupportBase::IsDivisionSupported(const TensorInfo& input0, const TensorInfo& input1, const TensorInfo& output, diff --git a/src/backends/backendsCommon/LayerSupportBase.hpp b/src/backends/backendsCommon/LayerSupportBase.hpp index c3acdcab7f..bf81459582 100644 --- a/src/backends/backendsCommon/LayerSupportBase.hpp +++ b/src/backends/backendsCommon/LayerSupportBase.hpp @@ -68,6 +68,11 @@ public: const Optional<TensorInfo>& biases, Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override; + bool IsDetectionPostProcessSupported(const TensorInfo& input0, + const TensorInfo& input1, + const DetectionPostProcessDescriptor& descriptor, + Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override; + bool IsDivisionSupported(const TensorInfo& input0, const TensorInfo& input1, const TensorInfo& output, diff --git a/src/backends/backendsCommon/WorkloadData.hpp b/src/backends/backendsCommon/WorkloadData.hpp index 2d68c9f7ee..e44eba71af 100644 --- a/src/backends/backendsCommon/WorkloadData.hpp +++ b/src/backends/backendsCommon/WorkloadData.hpp @@ -169,6 +169,11 @@ struct DepthwiseConvolution2dQueueDescriptor : QueueDescriptorWithParameters<Dep void Validate(const WorkloadInfo& workloadInfo) const; }; +struct DetectionPostProcessQueueDescriptor : QueueDescriptorWithParameters<DetectionPostProcessDescriptor> +{ + void Validate(const WorkloadInfo& workloadInfo) const; +}; + // Normalization layer workload data. struct NormalizationQueueDescriptor : QueueDescriptorWithParameters<NormalizationDescriptor> { diff --git a/src/backends/backendsCommon/WorkloadFactory.cpp b/src/backends/backendsCommon/WorkloadFactory.cpp index 38a2402297..cffb54841b 100644 --- a/src/backends/backendsCommon/WorkloadFactory.cpp +++ b/src/backends/backendsCommon/WorkloadFactory.cpp @@ -230,6 +230,18 @@ bool IWorkloadFactory::IsLayerSupported(const BackendId& backendId, reason); break; } + case LayerType::DetectionPostProcess: + { + const TensorInfo& input0 = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + const TensorInfo& input1 = layer.GetInputSlot(1).GetConnection()->GetTensorInfo(); + auto cLayer = boost::polymorphic_downcast<const DetectionPostProcessLayer*>(&layer); + const DetectionPostProcessDescriptor& descriptor = cLayer->GetParameters(); + result = layerSupportObject->IsDetectionPostProcessSupported(input0, + input1, + descriptor, + reason); + break; + } case LayerType::Equal: { const TensorInfo& input0 = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); diff --git a/src/backends/backendsCommon/WorkloadFactory.hpp b/src/backends/backendsCommon/WorkloadFactory.hpp index dd47dd6e05..88833491b2 100644 --- a/src/backends/backendsCommon/WorkloadFactory.hpp +++ b/src/backends/backendsCommon/WorkloadFactory.hpp @@ -79,6 +79,9 @@ public: virtual std::unique_ptr<IWorkload> CreateDepthwiseConvolution2d( const DepthwiseConvolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const = 0; + virtual std::unique_ptr<IWorkload> CreateDetectionPostProcess( + const DetectionPostProcessQueueDescriptor& descriptor, const WorkloadInfo& info) const = 0; + virtual std::unique_ptr<IWorkload> CreateNormalization(const NormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const = 0; diff --git a/src/backends/backendsCommon/test/IsLayerSupportedTestImpl.hpp b/src/backends/backendsCommon/test/IsLayerSupportedTestImpl.hpp index 43c7581b8b..3df71830ca 100644 --- a/src/backends/backendsCommon/test/IsLayerSupportedTestImpl.hpp +++ b/src/backends/backendsCommon/test/IsLayerSupportedTestImpl.hpp @@ -336,6 +336,8 @@ DECLARE_LAYER_POLICY_2_PARAM(Debug) DECLARE_LAYER_POLICY_2_PARAM(DepthwiseConvolution2d) +DECLARE_LAYER_POLICY_2_PARAM(DetectionPostProcess) + DECLARE_LAYER_POLICY_1_PARAM(Equal) DECLARE_LAYER_POLICY_2_PARAM(FakeQuantization) diff --git a/src/backends/cl/ClWorkloadFactory.cpp b/src/backends/cl/ClWorkloadFactory.cpp index 7a53257af1..6cd9c6dfa5 100644 --- a/src/backends/cl/ClWorkloadFactory.cpp +++ b/src/backends/cl/ClWorkloadFactory.cpp @@ -186,6 +186,12 @@ std::unique_ptr<IWorkload> ClWorkloadFactory::CreateDepthwiseConvolution2d( return MakeWorkload<ClDepthwiseConvolutionWorkload>(descriptor, info); } +std::unique_ptr<IWorkload> ClWorkloadFactory::CreateDetectionPostProcess( + const armnn::DetectionPostProcessQueueDescriptor& descriptor, const armnn::WorkloadInfo& info) const +{ + return MakeWorkload<NullWorkload, NullWorkload>(descriptor, info); +} + std::unique_ptr<armnn::IWorkload> ClWorkloadFactory::CreateNormalization(const NormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const { diff --git a/src/backends/cl/ClWorkloadFactory.hpp b/src/backends/cl/ClWorkloadFactory.hpp index 742553743f..5ef7d083da 100644 --- a/src/backends/cl/ClWorkloadFactory.hpp +++ b/src/backends/cl/ClWorkloadFactory.hpp @@ -69,6 +69,9 @@ public: std::unique_ptr<IWorkload> CreateDepthwiseConvolution2d(const DepthwiseConvolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const override; + std::unique_ptr<IWorkload> CreateDetectionPostProcess(const DetectionPostProcessQueueDescriptor& descriptor, + const WorkloadInfo& info) const override; + std::unique_ptr<IWorkload> CreateNormalization(const NormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const override; diff --git a/src/backends/neon/NeonWorkloadFactory.cpp b/src/backends/neon/NeonWorkloadFactory.cpp index e8a00d6b14..76e1dd0118 100644 --- a/src/backends/neon/NeonWorkloadFactory.cpp +++ b/src/backends/neon/NeonWorkloadFactory.cpp @@ -152,6 +152,12 @@ std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateDepthwiseConvolution2d( return std::make_unique<NeonDepthwiseConvolutionWorkload>(descriptor, info); } +std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateDetectionPostProcess( + const armnn::DetectionPostProcessQueueDescriptor& descriptor, const armnn::WorkloadInfo& info) const +{ + return MakeWorkloadHelper<NullWorkload, NullWorkload>(descriptor, info); +} + std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateNormalization( const NormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const { diff --git a/src/backends/neon/NeonWorkloadFactory.hpp b/src/backends/neon/NeonWorkloadFactory.hpp index 52caf7dc32..dd8d9a2d7d 100644 --- a/src/backends/neon/NeonWorkloadFactory.hpp +++ b/src/backends/neon/NeonWorkloadFactory.hpp @@ -70,6 +70,9 @@ public: std::unique_ptr<IWorkload> CreateDepthwiseConvolution2d(const DepthwiseConvolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const override; + std::unique_ptr<IWorkload> CreateDetectionPostProcess(const DetectionPostProcessQueueDescriptor& descriptor, + const WorkloadInfo& info) const override; + std::unique_ptr<IWorkload> CreateNormalization(const NormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const override; diff --git a/src/backends/reference/RefWorkloadFactory.cpp b/src/backends/reference/RefWorkloadFactory.cpp index 75a9efd70f..103abdd1ce 100644 --- a/src/backends/reference/RefWorkloadFactory.cpp +++ b/src/backends/reference/RefWorkloadFactory.cpp @@ -151,6 +151,12 @@ std::unique_ptr<IWorkload> RefWorkloadFactory::CreateDepthwiseConvolution2d( RefDepthwiseConvolution2dUint8Workload>(descriptor, info); } +std::unique_ptr<IWorkload> RefWorkloadFactory::CreateDetectionPostProcess( + const armnn::DetectionPostProcessQueueDescriptor& descriptor, const armnn::WorkloadInfo& info) const +{ + return MakeWorkload<NullWorkload, NullWorkload>(descriptor, info); +} + std::unique_ptr<armnn::IWorkload> RefWorkloadFactory::CreateNormalization( const NormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const { diff --git a/src/backends/reference/RefWorkloadFactory.hpp b/src/backends/reference/RefWorkloadFactory.hpp index 79e73a2610..211f93b2d5 100644 --- a/src/backends/reference/RefWorkloadFactory.hpp +++ b/src/backends/reference/RefWorkloadFactory.hpp @@ -87,6 +87,9 @@ public: std::unique_ptr<IWorkload> CreateDepthwiseConvolution2d(const DepthwiseConvolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const override; + std::unique_ptr<IWorkload> CreateDetectionPostProcess(const DetectionPostProcessQueueDescriptor& descriptor, + const WorkloadInfo& info) const override; + std::unique_ptr<IWorkload> CreateNormalization(const NormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const override; |