aboutsummaryrefslogtreecommitdiff
path: root/src/armnn
diff options
context:
space:
mode:
authorMatthew Sloyan <matthew.sloyan@arm.com>2021-10-18 13:07:49 +0100
committerMatthew Sloyan <matthew.sloyan@arm.com>2021-10-20 16:03:04 +0100
commit5d7b0a314b3e354a6cbcf15f5dd78b50f1e02774 (patch)
tree3d844c4575193ffddfe3a17c51cb808c9f16ddb0 /src/armnn
parent73010788725f8f07efb6df20711ece712ee213ea (diff)
downloadarmnn-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.cpp11
-rw-r--r--src/armnn/Graph.cpp11
-rw-r--r--src/armnn/Network.cpp22
-rw-r--r--src/armnn/Network.hpp2
-rw-r--r--src/armnn/layers/Convolution3dLayer.cpp52
-rw-r--r--src/armnn/layers/Convolution3dLayer.hpp10
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