diff options
author | Matthew Sloyan <matthew.sloyan@arm.com> | 2021-10-18 13:07:49 +0100 |
---|---|---|
committer | Matthew Sloyan <matthew.sloyan@arm.com> | 2021-10-20 16:03:04 +0100 |
commit | 5d7b0a314b3e354a6cbcf15f5dd78b50f1e02774 (patch) | |
tree | 3d844c4575193ffddfe3a17c51cb808c9f16ddb0 /src/armnn | |
parent | 73010788725f8f07efb6df20711ece712ee213ea (diff) | |
download | armnn-5d7b0a314b3e354a6cbcf15f5dd78b50f1e02774.tar.gz |
Add ConstTensorsAsInput support for Conv3d
* Constant weights and biases are now stored as Constant layers.
* Updated Serializer, Deserializer and unit tests to reflect this.
* Updated TfLiteParser.
* Updated Ref backend to handle constant weights and
bias as inputs rather than reading from member variables.
* Added Conv3d EndToEnd test.
* Added NCDHW DataLayout and unit tests.
Signed-off-by: Matthew Sloyan <matthew.sloyan@arm.com>
Change-Id: I10cdd354ca5f1c748730f92ffdb36bf810f83c8e
Diffstat (limited to 'src/armnn')
-rw-r--r-- | src/armnn/Descriptors.cpp | 11 | ||||
-rw-r--r-- | src/armnn/Graph.cpp | 11 | ||||
-rw-r--r-- | src/armnn/Network.cpp | 22 | ||||
-rw-r--r-- | src/armnn/Network.hpp | 2 | ||||
-rw-r--r-- | src/armnn/layers/Convolution3dLayer.cpp | 52 | ||||
-rw-r--r-- | src/armnn/layers/Convolution3dLayer.hpp | 10 |
6 files changed, 29 insertions, 79 deletions
diff --git a/src/armnn/Descriptors.cpp b/src/armnn/Descriptors.cpp index ab68097247..ef55ee7bb5 100644 --- a/src/armnn/Descriptors.cpp +++ b/src/armnn/Descriptors.cpp @@ -441,4 +441,15 @@ uint32_t FullyConnectedDescriptor::GetNumInputs() const return numInputs; } +uint32_t Convolution3dDescriptor::GetNumInputs() const +{ + // Return 2 otherwise check if bias is enabled + unsigned int numInputs = 2; + if (m_BiasEnabled) + { + numInputs = 3; + } + return numInputs; +} + } diff --git a/src/armnn/Graph.cpp b/src/armnn/Graph.cpp index 30639b12e8..0591bea99a 100644 --- a/src/armnn/Graph.cpp +++ b/src/armnn/Graph.cpp @@ -588,7 +588,7 @@ void Graph::InferTensorInfos() } /// Throws exception due to a layer input not being connected to an output slot. -/// Verifies weights and bias are set for FullyConnected layers on input slots 1 +/// Verifies weights and bias are set for layers on input slots 1 /// and 2 respectively. Method checks if bias is enabled before ensuring it is set. /// /// @param layer constant pointer to a Layer object @@ -600,7 +600,8 @@ void Graph::ConstructErrorMessageForUnconnectedInputs(Layer* const layer, std::ostringstream message; bool noWeightsAndBias = false; - if (layer->GetType() == armnn::LayerType::FullyConnected && slotIndex > 0) + if ((layer->GetType() == armnn::LayerType::FullyConnected || + layer->GetType() == armnn::LayerType::Convolution3d) && slotIndex > 0) { // If weights are not set and is bias enabled, also check if bias is set if (slotIndex == 1 && layer->GetNumInputSlots() == 3) @@ -608,7 +609,7 @@ void Graph::ConstructErrorMessageForUnconnectedInputs(Layer* const layer, const IOutputSlot* biasSource = layer->GetInputSlot(2).GetConnectedOutputSlot(); if (biasSource == NULL) { - message << "FullyConnected layer weights and bias not set: "; + message << layer->GetName() << " layer weights and bias not set: "; noWeightsAndBias = true; } } @@ -618,11 +619,11 @@ void Graph::ConstructErrorMessageForUnconnectedInputs(Layer* const layer, { if (slotIndex == 1) { - message << "FullyConnected layer weights not set: "; + message << layer->GetName() << " layer weights not set: "; } else { - message << "FullyConnected layer bias not set: "; + message << layer->GetName() << " layer bias not set: "; } } } diff --git a/src/armnn/Network.cpp b/src/armnn/Network.cpp index 99d7b96ec2..b516d519d5 100644 --- a/src/armnn/Network.cpp +++ b/src/armnn/Network.cpp @@ -114,11 +114,9 @@ IConnectableLayer* INetwork::AddConvolution2dLayer(const Convolution2dDescriptor IConnectableLayer* INetwork::AddConvolution3dLayer(const Convolution3dDescriptor& convolution3dDescriptor, - const ConstTensor& weights, - const Optional<ConstTensor>& biases, const char* name) { - return pNetworkImpl->AddConvolution3dLayer(convolution3dDescriptor, weights, biases, name); + return pNetworkImpl->AddConvolution3dLayer(convolution3dDescriptor, name); } @@ -1934,25 +1932,9 @@ IConnectableLayer* NetworkImpl::AddConvolution2dLayer(const Convolution2dDescrip } IConnectableLayer* NetworkImpl::AddConvolution3dLayer(const Convolution3dDescriptor& convolution3dDescriptor, - const ConstTensor& weights, - const Optional<ConstTensor>& biases, const char* name) { - if (convolution3dDescriptor.m_BiasEnabled && !biases.has_value()) - { - throw InvalidArgumentException("AddConvolution2dLayer: biases cannot be empty"); - } - - const auto layer = m_Graph->AddLayer<Convolution3dLayer>(convolution3dDescriptor, name); - - layer->m_Weight = std::make_shared<ScopedTensorHandle>(weights); - - if (convolution3dDescriptor.m_BiasEnabled) - { - layer->m_Bias = std::make_shared<ScopedTensorHandle>(biases.value()); - } - - return layer; + return m_Graph->AddLayer<Convolution3dLayer>(convolution3dDescriptor, name); } IConnectableLayer* NetworkImpl::AddDepthToSpaceLayer(const DepthToSpaceDescriptor& depthToSpaceDescriptor, diff --git a/src/armnn/Network.hpp b/src/armnn/Network.hpp index eb1d39d2f6..818a765296 100644 --- a/src/armnn/Network.hpp +++ b/src/armnn/Network.hpp @@ -87,8 +87,6 @@ public: const char* name = nullptr); IConnectableLayer* AddConvolution3dLayer(const Convolution3dDescriptor& convolution3dDescriptor, - const ConstTensor& weights, - const Optional<ConstTensor>& biases, const char* name = nullptr); IConnectableLayer* AddConstantLayer(const ConstTensor& input, const char* name = nullptr); diff --git a/src/armnn/layers/Convolution3dLayer.cpp b/src/armnn/layers/Convolution3dLayer.cpp index 0e38c0b129..1c2d1b9872 100644 --- a/src/armnn/layers/Convolution3dLayer.cpp +++ b/src/armnn/layers/Convolution3dLayer.cpp @@ -16,7 +16,7 @@ namespace armnn { Convolution3dLayer::Convolution3dLayer(const Convolution3dDescriptor& param, const char* name) - : LayerWithParameters(1, 1, LayerType::Convolution3d, param, name) + : LayerWithParameters(param.GetNumInputs(), 1, LayerType::Convolution3d, param, name) { } @@ -25,12 +25,11 @@ void Convolution3dLayer::SerializeLayerParameters(ParameterStringifyFunction& fn const std::vector<TensorShape>& inputShapes = { GetInputSlot(0).GetConnection()->GetTensorInfo().GetShape(), - m_Weight->GetTensorInfo().GetShape() + GetInputSlot(1).GetConnection()->GetTensorInfo().GetShape(), }; // Conv3d Filter Layout: [D,H,W,I,O] const TensorShape filterShape = inputShapes[1]; - DataLayoutIndexed dataLayoutIndex(m_Param.m_DataLayout); unsigned int filterDepth = filterShape[0]; unsigned int filterHeight = filterShape[1]; unsigned int filterWidth = filterShape[2]; @@ -48,18 +47,7 @@ void Convolution3dLayer::SerializeLayerParameters(ParameterStringifyFunction& fn std::unique_ptr<IWorkload> Convolution3dLayer::CreateWorkload(const IWorkloadFactory& factory) const { - // At this level constant data should not be released. - ARMNN_ASSERT_MSG(m_Weight != nullptr, "Convolution3dLayer: Weights data should not be null."); - Convolution3dQueueDescriptor descriptor; - descriptor.m_Weight = m_Weight.get(); - - if (m_Param.m_BiasEnabled) - { - ARMNN_ASSERT_MSG(m_Bias != nullptr, "Convolution3dLayer: Bias data should not be null."); - descriptor.m_Bias = m_Bias.get(); - } - SetAdditionalInfo(descriptor); return factory.CreateConvolution3d(descriptor, PrepInfoAndDesc(descriptor)); @@ -68,14 +56,6 @@ std::unique_ptr<IWorkload> Convolution3dLayer::CreateWorkload(const IWorkloadFac Convolution3dLayer* Convolution3dLayer::Clone(Graph& graph) const { auto layer = CloneBase<Convolution3dLayer>(graph, m_Param, GetName()); - - layer->m_Weight = m_Weight ? m_Weight : nullptr; - - if (layer->m_Param.m_BiasEnabled) - { - layer->m_Bias = m_Bias ? m_Bias : nullptr; - } - return std::move(layer); } @@ -117,36 +97,33 @@ std::vector<TensorShape> Convolution3dLayer::InferOutputShapes(const std::vector unsigned int outChannels = filterShape[4]; unsigned int outBatchSize = inBatchSize; - TensorShape tensorShape = TensorShape( { outBatchSize, outDepth, outHeight, outWidth, outChannels } ); + TensorShape tensorShape = m_Param.m_DataLayout == armnn::DataLayout::NDHWC ? + TensorShape( { outBatchSize, outDepth, outHeight, outWidth, outChannels } ) : + TensorShape( { outBatchSize, outChannels, outDepth, outHeight, outWidth }); return std::vector<TensorShape>({ tensorShape }); } void Convolution3dLayer::ValidateTensorShapesFromInputs() { - VerifyLayerConnections(1, CHECK_LOCATION()); + VerifyLayerConnections(m_Param.GetNumInputs(), CHECK_LOCATION()); const TensorShape& outputShape = GetOutputSlot(0).GetTensorInfo().GetShape(); VerifyShapeInferenceType(outputShape, m_ShapeInferenceMethod); - // check if we m_Weight data is not nullptr - ARMNN_ASSERT_MSG(m_Weight != nullptr, "Convolution3dLayer: Weights data should not be null."); + ARMNN_ASSERT_MSG(GetInputSlot(1).GetConnection(), + "Convolution3dLayer: Weights should be connected to input slot 1."); auto inferredShapes = InferOutputShapes({ GetInputSlot(0).GetConnection()->GetTensorInfo().GetShape(), - m_Weight->GetTensorInfo().GetShape() }); + GetInputSlot(1).GetConnection()->GetTensorInfo().GetShape() }); ARMNN_ASSERT(inferredShapes.size() == 1); ValidateAndCopyShape(outputShape, inferredShapes[0], m_ShapeInferenceMethod, "Convolution3dLayer"); } -Layer::ConstantTensors Convolution3dLayer::GetConstantTensorsByRef() -{ - return {m_Weight, m_Bias}; -} - ARMNN_NO_DEPRECATE_WARN_BEGIN void Convolution3dLayer::Accept(ILayerVisitor& visitor) const { @@ -157,16 +134,7 @@ ARMNN_NO_DEPRECATE_WARN_END void Convolution3dLayer::ExecuteStrategy(IStrategy& strategy) const { - ManagedConstTensorHandle managedWeight(m_Weight); - std::vector<armnn::ConstTensor> constTensors { { managedWeight.GetTensorInfo(), managedWeight.Map() } }; - - ManagedConstTensorHandle managedBias(m_Bias); - if (GetParameters().m_BiasEnabled) - { - constTensors.emplace_back(ConstTensor(managedBias.GetTensorInfo(), managedBias.Map())); - } - - strategy.ExecuteStrategy(this, GetParameters(), constTensors, GetName()); + strategy.ExecuteStrategy(this, GetParameters(), {}, GetName()); } } // namespace armnn diff --git a/src/armnn/layers/Convolution3dLayer.hpp b/src/armnn/layers/Convolution3dLayer.hpp index bef5715098..7cbd6428dc 100644 --- a/src/armnn/layers/Convolution3dLayer.hpp +++ b/src/armnn/layers/Convolution3dLayer.hpp @@ -16,12 +16,6 @@ class ScopedTensorHandle; class Convolution3dLayer : public LayerWithParameters<Convolution3dDescriptor> { public: - - /// A unique pointer to store Weight values. - std::shared_ptr<ConstTensorHandle> m_Weight; - /// A unique pointer to store Bias values. - std::shared_ptr<ConstTensorHandle> m_Bias; - /// Makes a workload for the Convolution3d type. /// @param [in] graph The graph where this layer can be found. /// @param [in] factory The workload factory which will create the workload. @@ -59,10 +53,6 @@ protected: /// Default destructor ~Convolution3dLayer() = default; - - /// Retrieve the handles to the constant values stored by the layer. - /// @return A vector of the constant tensors stored by this layer. - ConstantTensors GetConstantTensorsByRef() override; }; } // namespace |