From e46659669b753411421a6a552b32b9f1d27b8b2e Mon Sep 17 00:00:00 2001 From: Jim Flynn Date: Mon, 31 Jan 2022 16:08:53 +0000 Subject: IVGCVSW-6639 Add GetParameters to IConnectableLayer Change-Id: Id55a460ecb510f5b30235b03f54390f2c8188fc2 Signed-off-by: Jim Flynn --- delegate/src/MultiLayerFacade.hpp | 5 +++ include/armnn/Descriptors.hpp | 8 +++++ include/armnn/INetwork.hpp | 7 +++++ src/armnn/Layer.cpp | 3 ++ src/armnn/Layer.hpp | 6 ++++ src/armnn/layers/LayerWithParameters.hpp | 2 +- src/armnn/test/NetworkTests.cpp | 53 ++++++++++++++++++++++++++++++++ 7 files changed, 83 insertions(+), 1 deletion(-) diff --git a/delegate/src/MultiLayerFacade.hpp b/delegate/src/MultiLayerFacade.hpp index fa23980c26..ccd011a669 100644 --- a/delegate/src/MultiLayerFacade.hpp +++ b/delegate/src/MultiLayerFacade.hpp @@ -129,9 +129,14 @@ public: return m_FirstLayer->GetType(); } + virtual const armnn::BaseDescriptor& GetParameters() const override { return m_NullDescriptor; } + private: armnn::IConnectableLayer* m_FirstLayer; armnn::IConnectableLayer* m_LastLayer; + + // to satisfy the GetParameters method need to hand back a NullDescriptor + armnn::NullDescriptor m_NullDescriptor; }; } // namespace armnnDelegate diff --git a/include/armnn/Descriptors.hpp b/include/armnn/Descriptors.hpp index b37db540da..280c18e78c 100644 --- a/include/armnn/Descriptors.hpp +++ b/include/armnn/Descriptors.hpp @@ -21,9 +21,17 @@ namespace armnn /// Base class for all descriptors. struct BaseDescriptor { + virtual bool IsNull() const { return false; } virtual ~BaseDescriptor() = default; }; +/// Null Descriptor used as a return value from the IConnectableLayer GetParameters method +/// by layers which do not have a descriptor +struct NullDescriptor : BaseDescriptor +{ + bool IsNull() const override { return true; } +}; + /// An ActivationDescriptor for the ActivationLayer. struct ActivationDescriptor : BaseDescriptor { diff --git a/include/armnn/INetwork.hpp b/include/armnn/INetwork.hpp index a48ee25f72..073f119ef4 100644 --- a/include/armnn/INetwork.hpp +++ b/include/armnn/INetwork.hpp @@ -112,6 +112,13 @@ public: /// Returns the armnn::LayerType of this layer virtual LayerType GetType() const = 0; + /// If the layer has a descriptor return it. + /// The base descriptor can then be cast to the correct descriptor class. + /// If the layer has no associated descriptor a struct of type NullDescriptor will be returned. + /// Note: NullDescriptors can be detected because they return true when + /// the BaseDescriptor IsNull function is invoked. + virtual const BaseDescriptor& GetParameters() const = 0; + protected: /// Objects are not deletable via the handle ~IConnectableLayer() {} diff --git a/src/armnn/Layer.cpp b/src/armnn/Layer.cpp index 98fc14b56e..88bc6d56e1 100644 --- a/src/armnn/Layer.cpp +++ b/src/armnn/Layer.cpp @@ -17,6 +17,9 @@ namespace armnn { +// Instantiate the static member variable +NullDescriptor Layer::m_NullDescriptor; + void InputSlot::Insert(Layer& layer) { ARMNN_ASSERT(layer.GetNumOutputSlots() == 1); diff --git a/src/armnn/Layer.hpp b/src/armnn/Layer.hpp index f2ea6cb26d..ecfa1d9a5b 100644 --- a/src/armnn/Layer.hpp +++ b/src/armnn/Layer.hpp @@ -351,6 +351,8 @@ public: m_AdditionalInfoObject = additionalInfo; } + virtual const BaseDescriptor& GetParameters() const override { return m_NullDescriptor; } + protected: // Graph needs access to the virtual destructor. friend class Graph; @@ -427,6 +429,10 @@ private: std::list m_RelatedLayerNames; + /// returned by layers which have no parameters associated with them. + /// has to be a member as it is returned as a const reference + /// declared static so that there is only ever one of them in memory + static NullDescriptor m_NullDescriptor; }; // A layer user-provided data can be bound to (e.g. inputs, outputs). diff --git a/src/armnn/layers/LayerWithParameters.hpp b/src/armnn/layers/LayerWithParameters.hpp index 952eff66ff..2ac16c5f5f 100644 --- a/src/armnn/layers/LayerWithParameters.hpp +++ b/src/armnn/layers/LayerWithParameters.hpp @@ -15,7 +15,7 @@ class LayerWithParameters : public Layer public: using DescriptorType = Parameters; - const Parameters& GetParameters() const { return m_Param; } + const Parameters& GetParameters() const override { return m_Param; } /// Helper to serialize the layer parameters to string /// (currently used in DotSerializer and company). diff --git a/src/armnn/test/NetworkTests.cpp b/src/armnn/test/NetworkTests.cpp index d4edf5da97..66dbb4ee16 100644 --- a/src/armnn/test/NetworkTests.cpp +++ b/src/armnn/test/NetworkTests.cpp @@ -600,4 +600,57 @@ TEST_CASE("StandInLayerSingleInputMultipleOutputsNetworkTest") CHECK(standIn->GetOutputSlot(1).GetConnection(0) == &output1->GetInputSlot(0)); } +TEST_CASE("ObtainConv2DDescriptorFromIConnectableLayer") +{ + armnn::NetworkImpl net; + + unsigned int dims[] = { 10,1,1,1 }; + std::vector convWeightsData(10); + armnn::ConstTensor weights(armnn::TensorInfo(4, dims, armnn::DataType::Float32, 0.0f, 0, true), convWeightsData); + + armnn::Convolution2dDescriptor convDesc2d; + convDesc2d.m_PadLeft = 2; + convDesc2d.m_PadRight = 3; + convDesc2d.m_PadTop = 4; + convDesc2d.m_PadBottom = 5; + convDesc2d.m_StrideX = 2; + convDesc2d.m_StrideY = 1; + convDesc2d.m_DilationX = 3; + convDesc2d.m_DilationY = 3; + convDesc2d.m_BiasEnabled = false; + convDesc2d.m_DataLayout = armnn::DataLayout::NCHW; + armnn::IConnectableLayer* const convLayer = net.AddConvolution2dLayer(convDesc2d, + weights, + armnn::EmptyOptional(), + "conv layer"); + CHECK(convLayer); + + const armnn::BaseDescriptor& descriptor = convLayer->GetParameters(); + CHECK(descriptor.IsNull() == false); + const armnn::Convolution2dDescriptor& originalDescriptor = + static_cast(descriptor); + CHECK(originalDescriptor.m_PadLeft == 2); + CHECK(originalDescriptor.m_PadRight == 3); + CHECK(originalDescriptor.m_PadTop == 4); + CHECK(originalDescriptor.m_PadBottom == 5); + CHECK(originalDescriptor.m_StrideX == 2); + CHECK(originalDescriptor.m_StrideY == 1); + CHECK(originalDescriptor.m_DilationX == 3); + CHECK(originalDescriptor.m_DilationY == 3); + CHECK(originalDescriptor.m_BiasEnabled == false); + CHECK(originalDescriptor.m_DataLayout == armnn::DataLayout::NCHW); +} + +TEST_CASE("CheckNullDescriptor") +{ + armnn::NetworkImpl net; + armnn::IConnectableLayer* const addLayer = net.AddAdditionLayer(); + + CHECK(addLayer); + + const armnn::BaseDescriptor& descriptor = addLayer->GetParameters(); + // additional layer has no descriptor so a NullDescriptor will be returned + CHECK(descriptor.IsNull() == true); +} + } -- cgit v1.2.1