aboutsummaryrefslogtreecommitdiff
path: root/src/armnn
diff options
context:
space:
mode:
Diffstat (limited to 'src/armnn')
-rw-r--r--src/armnn/BackendHelper.cpp25
-rw-r--r--src/armnn/Descriptors.cpp41
-rw-r--r--src/armnn/Graph.cpp14
-rw-r--r--src/armnn/Layer.cpp37
-rw-r--r--src/armnn/LoadedNetwork.cpp7
-rw-r--r--src/armnn/Network.cpp83
-rw-r--r--src/armnn/Network.hpp8
-rw-r--r--src/armnn/NetworkUtils.cpp9
-rw-r--r--src/armnn/Tensor.cpp4
-rw-r--r--src/armnn/layers/Convolution2dLayer.cpp51
-rw-r--r--src/armnn/layers/Convolution2dLayer.hpp6
-rw-r--r--src/armnn/optimizations/FoldPadIntoLayer2d.hpp58
-rw-r--r--src/armnn/optimizations/FuseBatchNorm.hpp68
-rw-r--r--src/armnn/optimizations/RedirectMembersToConstantInputs.hpp1
-rw-r--r--src/armnn/test/ConstTensorLayerVisitor.cpp48
-rw-r--r--src/armnn/test/ConstTensorLayerVisitor.hpp20
-rw-r--r--src/armnn/test/NetworkTests.cpp21
-rw-r--r--src/armnn/test/OptimizerTests.cpp62
-rw-r--r--src/armnn/test/ShapeInferenceTests.cpp15
-rw-r--r--src/armnn/test/SubgraphViewTests.cpp72
-rw-r--r--src/armnn/test/optimizations/FoldPadTests.cpp27
-rw-r--r--src/armnn/test/optimizations/FuseActivationTests.cpp5
-rw-r--r--src/armnn/test/optimizations/FuseBatchNormTests.cpp106
23 files changed, 415 insertions, 373 deletions
diff --git a/src/armnn/BackendHelper.cpp b/src/armnn/BackendHelper.cpp
index 03f32ac191..9f97c26a75 100644
--- a/src/armnn/BackendHelper.cpp
+++ b/src/armnn/BackendHelper.cpp
@@ -373,6 +373,31 @@ bool LayerSupportHandle::IsConvolution2dSupported(const TensorInfo& input,
TensorInfo biasesVal = biases.has_value() ? biases.value() : TensorInfo();
TensorInfos infos{input, output, weights, biasesVal};
+ Optional<const BackendOptions::BackendOption> capability ;
+ if(!m_BackendId.IsUndefined())
+ {
+ capability = GetCapability("ConstantTensorsAsInputs", m_BackendId);
+ if(!capability.has_value() || capability.value().GetValue().AsBool() == false)
+ {
+ if(!weights.IsConstant())
+ {
+ return false;
+ }
+ if (descriptor.m_BiasEnabled && !biases.has_value())
+ {
+ return false;
+ }
+
+
+ // At the first stage we will only print a warning. this is to give
+ // backend developers a chance to adopt and read weights from input slots.
+ ARMNN_LOG(warning) << "The backend makes use of a deprecated interface to read constant tensors. "
+ "If you are a backend developer please find more information in our "
+ "doxygen documentation on github https://github.com/ARM-software/armnn "
+ "under the keyword 'ConstTensorsAsInputs'.";
+ }
+ }
+
return m_LayerSupport->IsLayerSupported(LayerType::Convolution2d,
infos,
descriptor,
diff --git a/src/armnn/Descriptors.cpp b/src/armnn/Descriptors.cpp
index d67d4404e0..4eb875e03d 100644
--- a/src/armnn/Descriptors.cpp
+++ b/src/armnn/Descriptors.cpp
@@ -425,16 +425,10 @@ int StridedSliceDescriptor::GetStopForAxis(const TensorShape& inputShape,
}
-uint32_t FullyConnectedDescriptor::GetNumViews() const
+uint32_t GetNumInputs(bool biasEnabled)
{
- return GetNumInputs();
-}
-
-uint32_t FullyConnectedDescriptor::GetNumInputs() const
-{
- // Return 2 otherwise check if bias is enabled
unsigned int numInputs = 2;
- if (m_BiasEnabled)
+ if (biasEnabled)
{
numInputs = 3;
}
@@ -443,24 +437,27 @@ uint32_t FullyConnectedDescriptor::GetNumInputs() const
uint32_t Convolution3dDescriptor::GetNumInputs() const
{
- // Return 2 otherwise check if bias is enabled
- unsigned int numInputs = 2;
- if (m_BiasEnabled)
- {
- numInputs = 3;
- }
- return numInputs;
+ return armnn::GetNumInputs(m_BiasEnabled);
+}
+
+uint32_t Convolution2dDescriptor::GetNumInputs() const
+{
+ return armnn::GetNumInputs(m_BiasEnabled);
+}
+
+uint32_t FullyConnectedDescriptor::GetNumInputs() const
+{
+ return armnn::GetNumInputs(m_BiasEnabled);
+}
+
+uint32_t FullyConnectedDescriptor::GetNumViews() const
+{
+ return armnn::GetNumInputs(m_BiasEnabled);
}
uint32_t DepthwiseConvolution2dDescriptor::GetNumInputs() const
{
- // Return 2 otherwise check if bias is enabled
- unsigned int numInputs = 2;
- if (m_BiasEnabled)
- {
- numInputs = 3;
- }
- return numInputs;
+ return armnn::GetNumInputs(m_BiasEnabled);
}
}
diff --git a/src/armnn/Graph.cpp b/src/armnn/Graph.cpp
index c1cec482b6..8500e529b0 100644
--- a/src/armnn/Graph.cpp
+++ b/src/armnn/Graph.cpp
@@ -603,16 +603,19 @@ void Graph::ConstructErrorMessageForUnconnectedInputs(Layer* const layer,
bool noWeightsAndBias = false;
if ((layer->GetType() == armnn::LayerType::FullyConnected ||
+ layer->GetType() == armnn::LayerType::Convolution2d ||
layer->GetType() == armnn::LayerType::Convolution3d ||
layer->GetType() == armnn::LayerType::DepthwiseConvolution2d) && slotIndex > 0)
{
+ message << std::endl;
+
// If weights are not set and is bias enabled, also check if bias is set
if (slotIndex == 1 && layer->GetNumInputSlots() == 3)
{
const IOutputSlot* biasSource = layer->GetInputSlot(2).GetConnectedOutputSlot();
if (biasSource == NULL)
{
- message << layer->GetName() << " layer weights and bias not set: ";
+ message << "Weights and bias layers not set." << std::endl;
noWeightsAndBias = true;
}
}
@@ -622,11 +625,11 @@ void Graph::ConstructErrorMessageForUnconnectedInputs(Layer* const layer,
{
if (slotIndex == 1)
{
- message << layer->GetName() << " layer weights not set: ";
+ message << "Weights layer not set." << std::endl;
}
else
{
- message << layer->GetName() << " layer bias not set: ";
+ message << "Bias layer not set." << std::endl;
}
}
}
@@ -634,9 +637,10 @@ void Graph::ConstructErrorMessageForUnconnectedInputs(Layer* const layer,
std::string slotString = noWeightsAndBias ? "1 & 2" : std::to_string(slotIndex);
message << "Input slot(s) "
<< slotString
- << " not connected to an output slot on "
+ << " for "
<< GetLayerTypeAsCString(layer->GetType())
- << " layer "
+ << " not connected to an output slot. " << std::endl
+ << "Layer name: "
<< std::quoted(layer->GetName());
throw LayerValidationException(message.str());
}
diff --git a/src/armnn/Layer.cpp b/src/armnn/Layer.cpp
index a31119b395..3241b5024e 100644
--- a/src/armnn/Layer.cpp
+++ b/src/armnn/Layer.cpp
@@ -23,16 +23,23 @@ namespace armnn
// Instantiate the static member variable
NullDescriptor Layer::m_NullDescriptor;
-template <typename LayerT>
-void AssertMultipleInputSlots(Layer& layer)
+void AssertNumberOfInputSlots(Layer& layer)
{
- if(PolymorphicDowncast<const LayerT*>(&(layer.GetParameters()))->m_BiasEnabled)
+ switch (layer.GetType())
{
- ARMNN_ASSERT(layer.GetNumInputSlots() == 3);
- }
- else
- {
- ARMNN_ASSERT(layer.GetNumInputSlots() == 2);
+ case LayerType::Convolution2d:
+ case LayerType::DepthwiseConvolution2d:
+ case LayerType::FullyConnected:
+ {
+ ARMNN_ASSERT(layer.GetNumInputSlots() == 2 ||
+ layer.GetNumInputSlots() == 3);
+ break;
+ }
+ default:
+ {
+ ARMNN_ASSERT(layer.GetNumInputSlots() == 1);
+ break;
+ }
}
}
@@ -47,19 +54,7 @@ void InputSlot::Insert(Layer& layer)
// Disconnects parent from this.
prevSlot->Disconnect(*this);
- switch (layer.GetType())
- {
- case LayerType::DepthwiseConvolution2d:
- {
- AssertMultipleInputSlots<DepthwiseConvolution2dDescriptor>(layer);
- break;
- }
- default:
- {
- ARMNN_ASSERT(layer.GetNumInputSlots() == 1);
- break;
- }
- }
+ AssertNumberOfInputSlots(layer);
// Connects inserted layer to parent.
int idx = prevSlot->Connect(layer.GetInputSlot(0));
diff --git a/src/armnn/LoadedNetwork.cpp b/src/armnn/LoadedNetwork.cpp
index a88fa5ab9c..228927db57 100644
--- a/src/armnn/LoadedNetwork.cpp
+++ b/src/armnn/LoadedNetwork.cpp
@@ -330,10 +330,10 @@ LoadedNetwork::LoadedNetwork(std::unique_ptr<IOptimizedNetwork> net,
if (layer->GetType() == LayerType::Constant)
{
+ // Place the Constant Workloads into a queue so that they can be executed first
ConstWorkloads.push_back(m_WorkloadQueue.back().get());
}
}
-
// release the constant data in the layer..
layer->ReleaseConstantData();
break;
@@ -513,10 +513,7 @@ LoadedNetwork::LoadedNetwork(std::unique_ptr<IOptimizedNetwork> net,
AllocateAndExecuteConstantWorkloadsAsync();
}
}
-
- // If synchronous, execute all constant layer workloads as the FoldPad optimization
- // may have created a new conv2d layer prior to the input constant layers which will
- // cause a failure if constant workloads are not executed
+ // If synchronous, execute all constant layer workloads
if (!networkProperties.m_AsyncEnabled)
{
for (auto workload: ConstWorkloads)
diff --git a/src/armnn/Network.cpp b/src/armnn/Network.cpp
index d2ebd4cde6..479e57fc56 100644
--- a/src/armnn/Network.cpp
+++ b/src/armnn/Network.cpp
@@ -83,35 +83,23 @@ IConnectableLayer* INetwork::AddConcatLayer(const ConcatDescriptor& concatDescri
IConnectableLayer* INetwork::AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
- const ConstTensor& weights,
- const Optional<ConstTensor>& biases,
const char* name)
{
- return pNetworkImpl->AddConvolution2dLayer(convolution2dDescriptor, weights, biases, name);
+ return pNetworkImpl->AddConvolution2dLayer(convolution2dDescriptor, name);
}
-
-IConnectableLayer* INetwork::AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
- const ConstTensor& weights,
- const char* name)
-{
- Optional<ConstTensor> biases;
- return pNetworkImpl->AddConvolution2dLayer(convolution2dDescriptor, weights, biases, name);
-}
-
-
+ARMNN_NO_DEPRECATE_WARN_BEGIN
IConnectableLayer* INetwork::AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
- const ConstTensor& weights,
- const ConstTensor& biases,
- const char* name )
+ const ConstTensor& weights,
+ const Optional<ConstTensor>& biases,
+ const char* name)
{
-
return pNetworkImpl->AddConvolution2dLayer(convolution2dDescriptor,
weights,
armnn::Optional<ConstTensor>(biases),
name);
}
-
+ARMNN_NO_DEPRECATE_WARN_END
IConnectableLayer* INetwork::AddConvolution3dLayer(const Convolution3dDescriptor& convolution3dDescriptor,
const char* name)
@@ -2012,25 +2000,33 @@ IConnectableLayer* NetworkImpl::AddConcatLayer(const ConcatDescriptor& concatDes
return m_Graph->AddLayer<ConcatLayer>(concatDescriptor, name);
}
-IConnectableLayer* NetworkImpl::AddConvolution2dLayerImpl(const Convolution2dDescriptor& convolution2dDescriptor,
- const ConstTensor& weights,
- const Optional<ConstTensor>& biases,
- const char* name)
+IConnectableLayer* NetworkImpl::AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
+ const char* name)
{
- if (convolution2dDescriptor.m_BiasEnabled && !biases.has_value())
- {
- throw InvalidArgumentException("AddConvolution2dLayer: biases cannot be empty");
- }
-
- const auto layer = m_Graph->AddLayer<Convolution2dLayer>(convolution2dDescriptor, name);
+ return m_Graph->AddLayer<Convolution2dLayer>(convolution2dDescriptor, name);
+}
+IConnectableLayer* NetworkImpl::AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
+ const ConstTensor& weights,
+ const Optional<ConstTensor>& biases,
+ const char* name)
+{
+ auto layer = m_Graph->AddLayer<Convolution2dLayer>(convolution2dDescriptor, name);
+ // Add a constant layer for weights
+ ConstantLayer* weightsLayer = m_Graph->AddLayer<ConstantLayer>("Weights");
+ weightsLayer->m_LayerOutput = std::make_shared<ScopedTensorHandle>(weights);
layer->m_Weight = std::make_shared<ScopedTensorHandle>(weights);
-
- if (convolution2dDescriptor.m_BiasEnabled)
+ weightsLayer->GetOutputSlot(0).SetTensorInfo(weightsLayer->m_LayerOutput->GetTensorInfo());
+ weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1));
+ // Add a constant layer for biases
+ if (biases.has_value() && convolution2dDescriptor.m_BiasEnabled)
{
+ ConstantLayer* biasLayer = m_Graph->AddLayer<ConstantLayer>("Bias");
+ biasLayer->m_LayerOutput = std::make_shared<ScopedTensorHandle>(biases.value());
layer->m_Bias = std::make_shared<ScopedTensorHandle>(biases.value());
+ biasLayer->GetOutputSlot(0).SetTensorInfo(biasLayer->m_LayerOutput->GetTensorInfo());
+ biasLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(2));
}
-
return layer;
}
@@ -2044,31 +2040,6 @@ IConnectableLayer* NetworkImpl::AddConvertFp32ToFp16Layer(const char* name)
return m_Graph->AddLayer<ConvertFp32ToFp16Layer>(name);
}
-IConnectableLayer* NetworkImpl::AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
- const ConstTensor& weights,
- const Optional<ConstTensor>& biases,
- const char* name)
-{
- return AddConvolution2dLayerImpl(convolution2dDescriptor, weights, biases, name);
-}
-
-IConnectableLayer* NetworkImpl::AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
- const ConstTensor& weights,
- const char* name)
-{
- Optional<ConstTensor> biases;
- return AddConvolution2dLayerImpl(convolution2dDescriptor, weights, biases, name);
-}
-
-IConnectableLayer* NetworkImpl::AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
- const ConstTensor& weights,
- const ConstTensor& biases,
- const char* name)
-{
- Optional<ConstTensor> optionalBiases(biases);
- return AddConvolution2dLayerImpl(convolution2dDescriptor, weights, optionalBiases, name);
-}
-
IConnectableLayer* NetworkImpl::AddConvolution3dLayer(const Convolution3dDescriptor& convolution3dDescriptor,
const char* name)
{
diff --git a/src/armnn/Network.hpp b/src/armnn/Network.hpp
index c5ed8de50d..c2be600d05 100644
--- a/src/armnn/Network.hpp
+++ b/src/armnn/Network.hpp
@@ -71,6 +71,10 @@ public:
const char* name = nullptr);
IConnectableLayer* AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
+ const char* name = nullptr);
+
+ ARMNN_DEPRECATED_MSG_REMOVAL_DATE("This AddConvolution2dLayer overload is deprecated", "22.11")
+ IConnectableLayer* AddConvolution2dLayer(const Convolution2dDescriptor& convolution2dDescriptor,
const ConstTensor& weights,
const Optional<ConstTensor>& biases,
const char* name = nullptr);
@@ -256,10 +260,6 @@ public:
void ExecuteStrategy(IStrategy& strategy) const;
private:
- IConnectableLayer* AddConvolution2dLayerImpl(const Convolution2dDescriptor& convolution2dDescriptor,
- const ConstTensor& weights,
- const Optional<ConstTensor>& biases,
- const char* name);
bool GetShapeInferenceMethod();
NetworkOptions m_NetworkOptions;
diff --git a/src/armnn/NetworkUtils.cpp b/src/armnn/NetworkUtils.cpp
index 666ce3d069..7597798fa4 100644
--- a/src/armnn/NetworkUtils.cpp
+++ b/src/armnn/NetworkUtils.cpp
@@ -98,6 +98,15 @@ std::vector<ConvertFp32ToBf16Layer*> InsertConvertFp32ToBf16LayersBefore(Graph&
for (auto&& inputSlot = layer.BeginInputSlots(); inputSlot != layer.EndInputSlots(); ++inputSlot)
{
bool allowInsert = true;
+
+ if ((layer.GetType() == LayerType::Convolution2d ||
+ layer.GetType() == LayerType::FullyConnected ||
+ layer.GetType() == LayerType::DepthwiseConvolution2d)
+ && inputSlot->GetSlotIndex() == 2)
+ {
+ // Refrain from reducing bias to Bf16
+ continue;
+ }
if (expectCorrectInputType)
{
// Only insert ConvertFp32ToBf16Layer before FP32 input slots
diff --git a/src/armnn/Tensor.cpp b/src/armnn/Tensor.cpp
index 6a4dbf8dae..ab4ecc9194 100644
--- a/src/armnn/Tensor.cpp
+++ b/src/armnn/Tensor.cpp
@@ -362,9 +362,7 @@ TensorInfo::TensorInfo(unsigned int numDimensions,
float quantizationScale,
int32_t quantizationOffset,
bool isConstant)
- : m_Shape(numDimensions, dimensionSizes)
- , m_DataType(dataType)
- , m_IsConstant(isConstant)
+ : m_Shape(numDimensions, dimensionSizes), m_DataType(dataType), m_IsConstant(isConstant)
{
SetQuantizationScale(quantizationScale);
SetQuantizationOffset(quantizationOffset);
diff --git a/src/armnn/layers/Convolution2dLayer.cpp b/src/armnn/layers/Convolution2dLayer.cpp
index ef5db8e9b9..7b3382bf93 100644
--- a/src/armnn/layers/Convolution2dLayer.cpp
+++ b/src/armnn/layers/Convolution2dLayer.cpp
@@ -21,7 +21,7 @@ namespace armnn
{
Convolution2dLayer::Convolution2dLayer(const Convolution2dDescriptor& param, const char* name)
- : LayerWithParameters(1, 1, LayerType::Convolution2d, param, name)
+ : LayerWithParameters(param.GetNumInputs(), 1, LayerType::Convolution2d, param, name)
{
}
@@ -32,7 +32,7 @@ void Convolution2dLayer::SerializeLayerParameters(ParameterStringifyFunction& fn
const std::vector<TensorShape>& inputShapes =
{
GetInputSlot(0).GetConnection()->GetTensorInfo().GetShape(),
- m_Weight->GetTensorInfo().GetShape()
+ GetInputSlot(1).GetConnection()->GetTensorInfo().GetShape()
};
const TensorShape filterShape = inputShapes[1];
DataLayoutIndexed dataLayoutIndex(m_Param.m_DataLayout);
@@ -49,15 +49,14 @@ void Convolution2dLayer::SerializeLayerParameters(ParameterStringifyFunction& fn
std::unique_ptr<IWorkload> Convolution2dLayer::CreateWorkload(const IWorkloadFactory& factory) const
{
// on this level constant data should not be released..
- ARMNN_ASSERT_MSG(m_Weight != nullptr, "Convolution2dLayer: Weights data should not be null.");
ARMNN_SCOPED_PROFILING_EVENT(Compute::Undefined, "Convolution2dLayer_CreateWorkload");
Convolution2dQueueDescriptor descriptor;
-
- descriptor.m_Weight = m_Weight.get();
-
- if (m_Param.m_BiasEnabled)
+ if (m_Weight)
+ {
+ descriptor.m_Weight = m_Weight.get();
+ }
+ if (m_Param.m_BiasEnabled && m_Bias)
{
- ARMNN_ASSERT_MSG(m_Bias != nullptr, "Convolution2dLayer: Bias data should not be null.");
descriptor.m_Bias = m_Bias.get();
}
@@ -120,18 +119,18 @@ std::vector<TensorShape> Convolution2dLayer::InferOutputShapes(const std::vector
void Convolution2dLayer::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, "Convolution2dLayer: Weights data should not be null.");
+ ARMNN_ASSERT_MSG(GetInputSlot(1).GetConnection(),
+ "Convolution2dLayer: Weights should be connected to input slot 1.");
- auto inferredShapes = InferOutputShapes({
- GetInputSlot(0).GetConnection()->GetTensorInfo().GetShape(),
- m_Weight->GetTensorInfo().GetShape() });
+ std::vector<TensorShape> inferredShapes = InferOutputShapes({
+ GetInputSlot(0).GetConnection()->GetTensorInfo().GetShape(),
+ GetInputSlot(1).GetConnection()->GetTensorInfo().GetShape() });
ARMNN_ASSERT(inferredShapes.size() == 1);
@@ -147,33 +146,13 @@ Layer::ConstantTensors Convolution2dLayer::GetConstantTensorsByRef()
ARMNN_NO_DEPRECATE_WARN_BEGIN
void Convolution2dLayer::Accept(ILayerVisitor& visitor) const
{
- ManagedConstTensorHandle managedWeight(m_Weight);
- ConstTensor weightsTensor(managedWeight.GetTensorInfo(), managedWeight.Map());
-
- Optional<ConstTensor> optionalBiasTensor = EmptyOptional();
- ManagedConstTensorHandle managedBias(m_Bias);
- if (GetParameters().m_BiasEnabled)
- {
- ConstTensor biasTensor(managedBias.GetTensorInfo(), managedBias.Map());
- optionalBiasTensor = Optional<ConstTensor>(biasTensor);
- }
-
- visitor.VisitConvolution2dLayer(this, GetParameters(), weightsTensor, optionalBiasTensor, GetName());
+ visitor.VisitConvolution2dLayer(this, GetParameters(), GetName());
}
ARMNN_NO_DEPRECATE_WARN_END
void Convolution2dLayer::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/Convolution2dLayer.hpp b/src/armnn/layers/Convolution2dLayer.hpp
index 844747831c..6bb86da18e 100644
--- a/src/armnn/layers/Convolution2dLayer.hpp
+++ b/src/armnn/layers/Convolution2dLayer.hpp
@@ -17,8 +17,10 @@ class Convolution2dLayer : public LayerWithParameters<Convolution2dDescriptor>
public:
/// A unique pointer to store Weight values.
+ /// @Note: Deprecated. Removal date is 22.11. Weights are stored in ConstantLayers now.
std::shared_ptr<ConstTensorHandle> m_Weight;
/// A unique pointer to store Bias values.
+ /// @Note: Deprecated. Removal date is 22.11. Bias are stored in ConstantLayers now.
std::shared_ptr<ConstTensorHandle> m_Bias;
/// Makes a workload for the Convolution2d type.
@@ -59,8 +61,8 @@ protected:
/// Default destructor
~Convolution2dLayer() = default;
- /// Retrieve the handles to the constant values stored by the layer.
- /// @return A vector of the constant tensors stored by this layer.
+ /// @Note Deprecated. GetConstantTensorsByRef is deprecated. m_Weights and m_Bias
+ /// should be connected to layer as Constant Layers instead."
ConstantTensors GetConstantTensorsByRef() override;
};
diff --git a/src/armnn/optimizations/FoldPadIntoLayer2d.hpp b/src/armnn/optimizations/FoldPadIntoLayer2d.hpp
index bbaabb815e..eb6bc90afd 100644
--- a/src/armnn/optimizations/FoldPadIntoLayer2d.hpp
+++ b/src/armnn/optimizations/FoldPadIntoLayer2d.hpp
@@ -146,8 +146,22 @@ Layer2dT* FoldPadIntoLayer2dImpl(Graph& graph, InputSlot& connection)
const std::string name = std::string("folded-") + padLayer.GetName() + "-into-" + layer2d.GetName();
auto& newLayer2d = *graph.InsertNewLayer<Layer2dT>(padLayer.GetInputSlot(0), newLayer2dDescriptor, name.c_str());
- // Reconnect the pad layer with its original parent.
newLayer2d.GetOutputSlot().MoveAllConnections(parentSlot);
+ // Start at 1 to connect only weights and bias
+ for (unsigned int i = 1; i < layer2d.GetNumInputSlots(); ++i)
+ {
+ if (layer2d.GetInputSlot(i).GetConnectedOutputSlot() != nullptr)
+ {
+ Layer& tgtLayer = layer2d.GetInputSlot(i).GetConnectedOutputSlot()->GetOwningLayer();
+ // Ensure we are definitely connecting the necessary constant layers
+ if (tgtLayer.GetType() == armnn::LayerType::Constant)
+ {
+ // Remove old connection and connect to new layer2d
+ tgtLayer.GetOutputSlot(0).Disconnect(layer2d.GetInputSlot(i));
+ tgtLayer.GetOutputSlot(0).Connect(newLayer2d.GetInputSlot(i));
+ }
+ }
+ }
// Moves connections in old layer2d layer output to new layer.
// Old layer2d layer will be removed as it's left unconnected.
@@ -168,14 +182,19 @@ public:
{
const auto conv2dLayer = PolymorphicDowncast<Convolution2dLayer*>(&connection.GetOwningLayer());
// Copy weights and bias to the new convolution layer
- ARMNN_ASSERT_MSG(conv2dLayer->m_Weight != nullptr,
- "FoldPadIntoConvolution2d: Weights data should not be null.");
+ ARMNN_ASSERT_MSG(newConv2dLayer->GetInputSlot(1).GetConnection() != nullptr,
+ "FoldPadIntoConvolution2d: New convolution layer is missing connection to weights layer");
+
+ // Deprecated 22.11
newConv2dLayer->m_Weight = std::move(conv2dLayer->m_Weight);
if (conv2dLayer->GetParameters().m_BiasEnabled)
{
- ARMNN_ASSERT_MSG(conv2dLayer->m_Bias != nullptr,
- "FoldPadIntoConvolution2d: Bias data should not be null if bias is enabled.");
+ ARMNN_ASSERT_MSG(newConv2dLayer->GetInputSlot(2).GetConnection() != nullptr,
+ "FoldPadIntoConvolution2d: New convolution layer is missing "
+ "connection to bias layer.");
+
+ // Deprecated 22.11
newConv2dLayer->m_Bias = std::move(conv2dLayer->m_Bias);
}
}
@@ -191,26 +210,25 @@ class FoldPadIntoDepthwiseConvolution2dImpl
public:
void Run(Graph& graph, InputSlot& connection) const
{
- const auto newLayer2d = FoldPadIntoLayer2dImpl<DepthwiseConvolution2dLayer>(graph, connection);
+ const auto newConv2dLayer = FoldPadIntoLayer2dImpl<DepthwiseConvolution2dLayer>(graph, connection);
- if (newLayer2d != nullptr)
+ if (newConv2dLayer != nullptr)
{
- const auto layer2d = PolymorphicDowncast<DepthwiseConvolution2dLayer*>(&connection.GetOwningLayer());
+ const auto conv2dLayer = PolymorphicDowncast<DepthwiseConvolution2dLayer*>(&connection.GetOwningLayer());
+ // Copy weights and bias to the new convolution layer
+ ARMNN_ASSERT_MSG(newConv2dLayer->GetInputSlot(1).GetConnection() != nullptr,
+ "FoldPadIntoDepthwiseConvolution2d: New convolution layer is missing connection to weights layer");
- // Move weights and bias layer connections to the new convolution layer
- ARMNN_ASSERT_MSG(layer2d->GetInputSlot(1).GetConnection() != nullptr,
- "FoldPadIntoDepthwiseConvolution2d: Weights data should not be null.");
- Layer& weightLayer = layer2d->GetInputSlot(1).GetConnectedOutputSlot()->GetOwningLayer();
- weightLayer.GetOutputSlot(0).Disconnect(layer2d->GetInputSlot(1));
- weightLayer.GetOutputSlot(0).Connect(newLayer2d->GetInputSlot(1));
+ // Deprecated 22.11
+ newConv2dLayer->m_Weight = std::move(conv2dLayer->m_Weight);
- if (layer2d->GetParameters().m_BiasEnabled)
+ if (conv2dLayer->GetParameters().m_BiasEnabled)
{
- ARMNN_ASSERT_MSG(layer2d->GetInputSlot(2).GetConnection() != nullptr,
- "FoldPadIntoDepthwiseConvolution2d: Bias data should not be null if bias is enabled.");
- Layer& biasLayer = layer2d->GetInputSlot(2).GetConnectedOutputSlot()->GetOwningLayer();
- biasLayer.GetOutputSlot(0).Disconnect(layer2d->GetInputSlot(2));
- biasLayer.GetOutputSlot(0).Connect(newLayer2d->GetInputSlot(2));
+ ARMNN_ASSERT_MSG(newConv2dLayer->GetInputSlot(2).GetConnection() != nullptr,
+ "FoldPadIntoConvolution2d: New convolution layer is missing "
+ "connection to bias layer.");
+ // Deprecated 22.11
+ newConv2dLayer->m_Bias = std::move(conv2dLayer->m_Bias);
}
}
}
diff --git a/src/armnn/optimizations/FuseBatchNorm.hpp b/src/armnn/optimizations/FuseBatchNorm.hpp
index 6a50fc4a0c..bca0c7d00a 100644
--- a/src/armnn/optimizations/FuseBatchNorm.hpp
+++ b/src/armnn/optimizations/FuseBatchNorm.hpp
@@ -14,8 +14,8 @@ namespace armnn
namespace optimizations
{
-template <typename ConvLayer, armnn::DataType ArmnnType,
- typename T = armnn::ResolveType<ArmnnType>>
+template<typename ConvLayer, armnn::DataType ArmnnType,
+ typename T = armnn::ResolveType<ArmnnType>>
class FuseBatchNorm
{
public:
@@ -26,7 +26,7 @@ public:
/// combined with the parameters of the child BatchNorm layer.
void Run(Graph& graph, InputSlot& connection) const
{
- Layer& base = connection.GetConnectedOutputSlot()->GetOwningLayer();
+ Layer& base = connection.GetConnectedOutputSlot()->GetOwningLayer();
Layer& child = connection.GetOwningLayer();
bool depthwise = (base.GetType() == LayerType::DepthwiseConvolution2d);
@@ -37,7 +37,7 @@ public:
if (base.GetDataType() == ArmnnType && child.GetDataType() == ArmnnType)
{
OutputSlot* parentOut = base.GetInputSlot(0).GetConnectedOutputSlot();
- auto convLayer = PolymorphicDowncast<ConvLayer*>(&base);
+ auto convLayer = PolymorphicDowncast<ConvLayer*>(&base);
auto batchNormLayer = PolymorphicDowncast<BatchNormalizationLayer*>(&child);
// Read convolution and batch norm parameters
@@ -50,25 +50,16 @@ public:
ConstTensor meanTensor(batchNormLayer->m_Mean->GetTensorInfo(), batchNormLayer->m_Mean->Map(true));
ConstTensor varTensor(batchNormLayer->m_Variance->GetTensorInfo(), batchNormLayer->m_Variance->Map(true));
- auto convDescriptor = convLayer->GetParameters();
+ auto convDescriptor = convLayer->GetParameters();
ConstTensor weightsTensor;
- if (convLayer->GetNumInputSlots() > 1)
- {
- ARMNN_ASSERT_MSG(convLayer->GetInputSlots()[1].GetConnection() != nullptr,
- "FuseBatchNorm: Weight data should not be null.");
- InputSlot & oldSlotWeights = const_cast<InputSlot&>(convLayer->GetInputSlots()[1]);
- OutputSlot & constantSlotWeights = const_cast<OutputSlot&>(*oldSlotWeights.GetConnectedOutputSlot());
- ConstantLayer* weightLayer = PolymorphicDowncast<ConstantLayer*>(
- &constantSlotWeights.GetOwningLayer());
- weightsTensor = ConstTensor(weightLayer->m_LayerOutput->GetTensorInfo(),
- weightLayer->m_LayerOutput->Map(true));
- }
- else
- {
- ARMNN_ASSERT_MSG(convLayer->m_Weight != nullptr,
- "FuseBatchNorm: Bias data should not be null if bias is enabled.");
- weightsTensor = ConstTensor(convLayer->m_Weight->GetTensorInfo(), convLayer->m_Weight->Map(true));
- }
+ ARMNN_ASSERT_MSG(convLayer->GetInputSlots()[1].GetConnection() != nullptr,
+ "FuseBatchNorm: Weight data should not be null.");
+
+ ConstantLayer* weightLayer = PolymorphicDowncast<ConstantLayer*>(
+ &base.GetInputSlot(1).GetConnectedOutputSlot()->GetOwningLayer());
+
+ weightsTensor = ConstTensor(weightLayer->m_LayerOutput->GetTensorInfo(),
+ weightLayer->m_LayerOutput->Map(true));
armnnUtils::DataLayoutIndexed dataLayout(convDescriptor.m_DataLayout);
auto weightsShape = weightsTensor.GetInfo().GetShape();
@@ -76,9 +67,9 @@ public:
const unsigned int depthMultiplier = depthwise ? weightsShape[3] / inputChannels : 1;
const unsigned int outputChannels = depthwise ? weightsShape[3] : weightsShape[0];
const unsigned int weightsHeight = depthwise ? weightsShape[1] :
- weightsShape[dataLayout.GetHeightIndex()];
+ weightsShape[dataLayout.GetHeightIndex()];
const unsigned int weightsWidth = depthwise ? weightsShape[2] :
- weightsShape[dataLayout.GetWidthIndex()];
+ weightsShape[dataLayout.GetWidthIndex()];
const auto* weightsBuffer = static_cast<const T*>(weightsTensor.GetMemoryArea());
const auto* betaBuffer = static_cast<const T*>(betaTensor.GetMemoryArea());
@@ -99,7 +90,7 @@ public:
{
for (unsigned int cOut = 0; cOut < outputChannels; ++cOut)
{
- T mult = gammaVector[cOut] / static_cast<T>(sqrtf (varianceVector[cOut] + epsilon));
+ T mult = gammaVector[cOut] / static_cast<T>(sqrtf(varianceVector[cOut] + epsilon));
for (unsigned int h = 0; h < weightsHeight; ++h)
{
@@ -140,23 +131,14 @@ public:
if (biasWasEnabledBeforeOpt)
{
ConstTensor biasTensor;
- if (convLayer->GetNumInputSlots() > 1)
- {
- ARMNN_ASSERT_MSG(convLayer->GetInputSlots()[2].GetConnection() != nullptr,
- "FuseBatchNorm: Bias data should not be null if bias is enabled.");
- InputSlot & oldSlotBias = const_cast<InputSlot&>(convLayer->GetInputSlots()[2]);
- OutputSlot & constantSlotBias = const_cast<OutputSlot&>(*oldSlotBias.GetConnectedOutputSlot());
- ConstantLayer* biasLayer = PolymorphicDowncast<ConstantLayer*>(
- &constantSlotBias.GetOwningLayer());
- biasTensor = ConstTensor(biasLayer->m_LayerOutput->GetTensorInfo(),
- biasLayer->m_LayerOutput->Map(true));
- }
- else
- {
- ARMNN_ASSERT_MSG(convLayer->m_Bias != nullptr,
- "FuseBatchNorm: Bias data should not be null if bias is enabled.");
- biasTensor = ConstTensor(convLayer->m_Bias->GetTensorInfo(), convLayer->m_Bias->Map(true));
- }
+ ARMNN_ASSERT_MSG(convLayer->GetInputSlots()[2].GetConnection() != nullptr,
+ "FuseBatchNorm: Bias data should not be null if bias is enabled.");
+
+ ConstantLayer* biasLayer = PolymorphicDowncast<ConstantLayer*>(
+ &base.GetInputSlot(2).GetConnectedOutputSlot()->GetOwningLayer());
+
+ biasTensor = ConstTensor(biasLayer->m_LayerOutput->GetTensorInfo(),
+ biasLayer->m_LayerOutput->Map(true));
const auto* biasBuffer = static_cast<const T*>(biasTensor.GetMemoryArea());
std::vector<T> biasVector(biasBuffer, biasBuffer + biasTensor.GetNumElements());
@@ -192,8 +174,6 @@ public:
// This optimization will always have 3 input slots on the Conv2d base layer
if (newConv2dLayer.GetNumInputSlots() > 1)
{
- ConstantLayer* weightLayer = PolymorphicDowncast<ConstantLayer*>(
- &base.GetInputSlot(1).GetConnectedOutputSlot()->GetOwningLayer());
// Remove old connection and connect to new layer2d
weightLayer->GetOutputSlot(0).Disconnect(base.GetInputSlot(1));
weightLayer->GetOutputSlot(0).Connect(newConv2dLayer.GetInputSlot(1));
diff --git a/src/armnn/optimizations/RedirectMembersToConstantInputs.hpp b/src/armnn/optimizations/RedirectMembersToConstantInputs.hpp
index cb97a0fe32..483377452e 100644
--- a/src/armnn/optimizations/RedirectMembersToConstantInputs.hpp
+++ b/src/armnn/optimizations/RedirectMembersToConstantInputs.hpp
@@ -29,6 +29,7 @@ public:
case LayerType::BatchNormalization:
break;
case LayerType::Convolution2d:
+ RedirectWeightsAndBiases<Convolution2dLayer>(&layer);
break;
case LayerType::DepthwiseConvolution2d:
RedirectWeightsAndBiases<DepthwiseConvolution2dLayer>(&layer);
diff --git a/src/armnn/test/ConstTensorLayerVisitor.cpp b/src/armnn/test/ConstTensorLayerVisitor.cpp
index af0581ce4c..701327b120 100644
--- a/src/armnn/test/ConstTensorLayerVisitor.cpp
+++ b/src/armnn/test/ConstTensorLayerVisitor.cpp
@@ -119,16 +119,22 @@ TEST_CASE("CheckConvolution2dLayer")
descriptor.m_StrideX = 2;
descriptor.m_StrideY = 3;
descriptor.m_DataLayout = DataLayout::NHWC;
+ descriptor.m_BiasEnabled = false;
std::vector<float> data = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
std::vector<unsigned int> dimensions = {1, 1, 3, 3};
ConstTensor weights(TensorInfo(4, dimensions.data(), DataType::Float32, 0.0f, 0, true), data);
- TestConvolution2dLayerVisitor visitor(descriptor, weights, EmptyOptional());
+ TestConstantLayerVisitor weightsVisitor(weights);
+ TestConvolution2dLayerVisitor visitor(descriptor);
NetworkImpl net;
- IConnectableLayer* const layer = net.AddConvolution2dLayer(descriptor, weights, EmptyOptional());
+ IConnectableLayer* const weightsLayer = net.AddConstantLayer(weights);
+ IConnectableLayer* const layer = net.AddConvolution2dLayer(descriptor);
+ weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1));
+
+ weightsLayer->ExecuteStrategy(weightsVisitor);
layer->ExecuteStrategy(visitor);
}
@@ -148,11 +154,17 @@ TEST_CASE("CheckNamedConvolution2dLayer")
std::vector<unsigned int> dimensions = {1, 1, 3, 3};
ConstTensor weights(TensorInfo(4, dimensions.data(), DataType::Float32, 0.0f, 0, true), data);
- TestConvolution2dLayerVisitor visitor(descriptor, weights, EmptyOptional(), layerName);
+ TestConstantLayerVisitor weightsVisitor(weights);
+ TestConvolution2dLayerVisitor visitor(descriptor, layerName);
NetworkImpl net;
- IConnectableLayer* const layer = net.AddConvolution2dLayer(descriptor, weights, EmptyOptional(), layerName);
+ IConnectableLayer* const weightsLayer = net.AddConstantLayer(weights);
+ IConnectableLayer* const layer = net.AddConvolution2dLayer(descriptor, layerName);
+
+ weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1));
+
+ weightsLayer->ExecuteStrategy(weightsVisitor);
layer->ExecuteStrategy(visitor);
}
@@ -175,13 +187,21 @@ TEST_CASE("CheckConvolution2dLayerWithBiases")
std::vector<float> biasData = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
std::vector<unsigned int> biasDimensions = {1, 1, 3, 3};
ConstTensor biases(TensorInfo(4, biasDimensions.data(), DataType::Float32, 0.0f, 0, true), biasData);
- Optional<ConstTensor> optionalBiases(biases);
- TestConvolution2dLayerVisitor visitor(descriptor, weights, optionalBiases);
+ TestConstantLayerVisitor weightsVisitor(weights);
+ TestConstantLayerVisitor biasVisitor(biases);
+ TestConvolution2dLayerVisitor visitor(descriptor);
NetworkImpl net;
+ IConnectableLayer* const weightsLayer = net.AddConstantLayer(weights);
+ IConnectableLayer* const biasLayer = net.AddConstantLayer(biases);
+ IConnectableLayer* const layer = net.AddConvolution2dLayer(descriptor);
- IConnectableLayer* const layer = net.AddConvolution2dLayer(descriptor, weights, optionalBiases);
+ weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1));
+ biasLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(2));
+
+ biasLayer->ExecuteStrategy(biasVisitor);
+ weightsLayer->ExecuteStrategy(weightsVisitor);
layer->ExecuteStrategy(visitor);
}
@@ -205,13 +225,21 @@ TEST_CASE("CheckNamedConvolution2dLayerWithBiases")
std::vector<float> biasData = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
std::vector<unsigned int> biasDimensions = {1, 1, 3, 3};
ConstTensor biases(TensorInfo(4, biasDimensions.data(), DataType::Float32, 0.0f, 0, true), biasData);
- Optional<ConstTensor> optionalBiases(biases);
- TestConvolution2dLayerVisitor visitor(descriptor, weights, optionalBiases, layerName);
+ TestConstantLayerVisitor weightsVisitor(weights);
+ TestConstantLayerVisitor biasVisitor(biases);
+ TestConvolution2dLayerVisitor visitor(descriptor, layerName);
NetworkImpl net;
+ IConnectableLayer* const weightsLayer = net.AddConstantLayer(weights);
+ IConnectableLayer* const biasLayer = net.AddConstantLayer(biases);
+ IConnectableLayer* const layer = net.AddConvolution2dLayer(descriptor, layerName);
- IConnectableLayer* const layer = net.AddConvolution2dLayer(descriptor, weights, optionalBiases, layerName);
+ weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1));
+ biasLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(2));
+
+ biasLayer->ExecuteStrategy(biasVisitor);
+ weightsLayer->ExecuteStrategy(weightsVisitor);
layer->ExecuteStrategy(visitor);
}
diff --git a/src/armnn/test/ConstTensorLayerVisitor.hpp b/src/armnn/test/ConstTensorLayerVisitor.hpp
index 00d17b4ae8..1f1b3f5262 100644
--- a/src/armnn/test/ConstTensorLayerVisitor.hpp
+++ b/src/armnn/test/ConstTensorLayerVisitor.hpp
@@ -21,22 +21,18 @@ class TestConvolution2dLayerVisitor : public TestLayerVisitor
{
public:
explicit TestConvolution2dLayerVisitor(const Convolution2dDescriptor& convolution2dDescriptor,
- const ConstTensor& weights,
- const Optional<ConstTensor>& biases,
const char* name = nullptr)
: TestLayerVisitor(name)
, m_Descriptor(convolution2dDescriptor)
- , m_Weights(weights)
- , m_Biases(biases)
{}
virtual ~TestConvolution2dLayerVisitor() {}
void ExecuteStrategy(const armnn::IConnectableLayer* layer,
- const armnn::BaseDescriptor& descriptor,
- const std::vector<armnn::ConstTensor>& constants,
- const char* name,
- const armnn::LayerBindingId id = 0) override
+ const armnn::BaseDescriptor& descriptor,
+ const std::vector<armnn::ConstTensor>& constants,
+ const char* name,
+ const armnn::LayerBindingId id = 0) override
{
armnn::IgnoreUnused(descriptor, constants, id);
switch (layer->GetType())
@@ -46,12 +42,6 @@ public:
CheckLayerPointer(layer);
CheckLayerName(name);
CheckDescriptor(static_cast<const armnn::Convolution2dDescriptor&>(descriptor));
- CheckConstTensors(m_Weights, constants[0]);
- if (m_Biases.has_value())
- {
- CHECK(constants.size() == 2);
- CheckConstTensors(m_Biases.value(), constants[1]);
- }
break;
}
default:
@@ -66,8 +56,6 @@ protected:
private:
Convolution2dDescriptor m_Descriptor;
- ConstTensor m_Weights;
- Optional<ConstTensor> m_Biases;
};
class TestDepthwiseConvolution2dLayerVisitor : public TestLayerVisitor
diff --git a/src/armnn/test/NetworkTests.cpp b/src/armnn/test/NetworkTests.cpp
index c64c0a0d40..7756f40623 100644
--- a/src/armnn/test/NetworkTests.cpp
+++ b/src/armnn/test/NetworkTests.cpp
@@ -77,18 +77,18 @@ TEST_CASE("NetworkModification")
armnn::ConstTensor weights(armnn::TensorInfo(4, dims, armnn::DataType::Float32, 0.0f, 0, true), convWeightsData);
armnn::Convolution2dDescriptor convDesc2d;
- armnn::IConnectableLayer* const convLayer = net.AddConvolution2dLayer(convDesc2d,
- weights,
- armnn::EmptyOptional(),
- "conv layer");
+ armnn::IConnectableLayer* const weightsLayer = net.AddConstantLayer(weights, "conv const weights");
+ armnn::IConnectableLayer* const convLayer = net.AddConvolution2dLayer(convDesc2d, "conv layer");
CHECK(convLayer);
+ CHECK(weightsLayer);
inputLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(0));
+ weightsLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(1));
armnn::FullyConnectedDescriptor fullyConnectedDesc;
// Constant layer that now holds weights data for FullyConnected
- armnn::IConnectableLayer* const constantWeightsLayer = net.AddConstantLayer(weights, "const weights");
+ armnn::IConnectableLayer* const constantWeightsLayer = net.AddConstantLayer(weights, "fc const weights");
armnn::IConnectableLayer* const fullyConnectedLayer = net.AddFullyConnectedLayer(fullyConnectedDesc,
"fully connected");
CHECK(constantWeightsLayer);
@@ -155,12 +155,13 @@ TEST_CASE("NetworkModification")
multiplicationLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
//Tests that all layers are present in the graph.
- CHECK(net.GetGraph().GetNumLayers() == 12);
+ CHECK(net.GetGraph().GetNumLayers() == 13);
//Tests that the vertices exist and have correct names.
CHECK(GraphHasNamedLayer(net.GetGraph(), "input layer"));
CHECK(GraphHasNamedLayer(net.GetGraph(), "conv layer"));
- CHECK(GraphHasNamedLayer(net.GetGraph(), "const weights"));
+ CHECK(GraphHasNamedLayer(net.GetGraph(), "conv const weights"));
+ CHECK(GraphHasNamedLayer(net.GetGraph(), "fc const weights"));
CHECK(GraphHasNamedLayer(net.GetGraph(), "fully connected"));
CHECK(GraphHasNamedLayer(net.GetGraph(), "pooling2d"));
CHECK(GraphHasNamedLayer(net.GetGraph(), "activation"));
@@ -239,8 +240,8 @@ TEST_CASE("NetworkModification")
CHECK(AreAllLayerInputSlotsConnected(*outputLayer));
// Checks connectivity.
- checkOneOutputToOneInputConnection(inputLayer, convLayer, 0);
- checkOneOutputToTwoInputConnectionForTwoDifferentLayers(convLayer, constantWeightsLayer, fullyConnectedLayer, 1, 0);
+ checkOneOutputToTwoInputConnectionForTwoDifferentLayers(inputLayer, weightsLayer, convLayer, 0, 0);
+ checkOneOutputToTwoInputConnectionForTwoDifferentLayers(convLayer, constantWeightsLayer, fullyConnectedLayer, 2, 0);
checkOneOutputToOneInputConnection(fullyConnectedLayer, poolingLayer, 2, 1);
checkOneOutputToOneInputConnection(poolingLayer, activationLayer);
checkOneOutputToOneInputConnection(activationLayer, normalizationLayer);
@@ -619,10 +620,12 @@ TEST_CASE("ObtainConv2DDescriptorFromIConnectableLayer")
convDesc2d.m_DilationY = 3;
convDesc2d.m_BiasEnabled = false;
convDesc2d.m_DataLayout = armnn::DataLayout::NCHW;
+ ARMNN_NO_DEPRECATE_WARN_BEGIN
armnn::IConnectableLayer* const convLayer = net.AddConvolution2dLayer(convDesc2d,
weights,
armnn::EmptyOptional(),
"conv layer");
+ ARMNN_NO_DEPRECATE_WARN_END
CHECK(convLayer);
const armnn::BaseDescriptor& descriptor = convLayer->GetParameters();
diff --git a/src/armnn/test/OptimizerTests.cpp b/src/armnn/test/OptimizerTests.cpp
index 6a13dc6456..3dd55279c6 100644
--- a/src/armnn/test/OptimizerTests.cpp
+++ b/src/armnn/test/OptimizerTests.cpp
@@ -441,6 +441,11 @@ void CreateConvolution2dGraph(Graph &graph, const unsigned int* inputShape,
Layer* input = graph.AddLayer<InputLayer>(0, "input");
input->GetOutputSlot().SetTensorInfo(inputInfo);
+ ConstantLayer* weightsLayer = nullptr;
+ weightsLayer = graph.AddLayer<ConstantLayer>("Weights");
+ weightsLayer->m_LayerOutput = std::make_shared<ScopedTensorHandle>(weights);
+ weightsLayer->GetOutputSlot(0).SetTensorInfo(weightsLayer->m_LayerOutput->GetTensorInfo());
+
Convolution2dLayer* layer = graph.AddLayer<Convolution2dLayer>(desc, "conv2d");
layer->m_Weight = std::make_unique<armnn::ScopedTensorHandle>(weights);
layer->GetOutputSlot().SetTensorInfo(outputInfo);
@@ -448,6 +453,7 @@ void CreateConvolution2dGraph(Graph &graph, const unsigned int* inputShape,
Layer* output = graph.AddLayer<OutputLayer>(0, "output");
input->GetOutputSlot().Connect(layer->GetInputSlot(0));
layer->GetOutputSlot().Connect(output->GetInputSlot(0));
+ weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1));
}
TEST_CASE("Conv2dValidateTensorShapesFromInputs")
@@ -875,40 +881,70 @@ TEST_CASE("OptimizeForExclusiveConnectionsFuseTest")
ConstTensor mean(TensorInfo(1, outputChannelSize, DataType::Float32, 0.0f, 0, true), meanVector);
ConstTensor variance(TensorInfo(1, outputChannelSize, DataType::Float32, 0.0f, 0, true), varianceVector);
+ ConstantLayer* biasLayer = nullptr;
+
// Define the network
Graph graph;
auto input = graph.AddLayer<InputLayer>(0, "input");
+ auto weightsLayer = graph.AddLayer<ConstantLayer>("Weights");
auto conv = graph.AddLayer<Convolution2dLayer>(convolution2dDescriptor, "convolution");
auto batchNorm = graph.AddLayer<BatchNormalizationLayer>(batchNormDescriptor, "batchNorm");
auto output = graph.AddLayer<OutputLayer>(0, "output");
// Set layer information
input->GetOutputSlot().SetTensorInfo(inputInfo);
+
+ weightsLayer->m_LayerOutput = std::make_shared<ScopedTensorHandle>(weights);
+ weightsLayer->GetOutputSlot(0).SetTensorInfo(weightsLayer->m_LayerOutput->GetTensorInfo());
conv->GetOutputSlot().SetTensorInfo(outputInfo);
+
batchNorm->GetOutputSlot().SetTensorInfo(outputInfo);
- conv->m_Weight = std::make_unique<ScopedTensorHandle>(weights);
batchNorm->m_Beta = std::make_unique<ScopedTensorHandle>(beta);
batchNorm->m_Gamma = std::make_unique<ScopedTensorHandle>(gamma);
batchNorm->m_Mean = std::make_unique<ScopedTensorHandle>(mean);
batchNorm->m_Variance = std::make_unique<ScopedTensorHandle>(variance);
+
if (convolution2dDescriptor.m_BiasEnabled)
{
std::vector<float> biasVector = { 11 };
ConstTensor bias(TensorInfo(1, outputChannelSize, DataType::Float32, 0.0f, 0, true), biasVector);
- conv->m_Bias = std::make_unique<ScopedTensorHandle>(bias);
+ biasLayer =graph.AddLayer<ConstantLayer>("Bias");
+ biasLayer->m_LayerOutput = std::make_shared<ScopedTensorHandle>(bias);
+ biasLayer->GetOutputSlot(0).SetTensorInfo(biasLayer->m_LayerOutput->GetTensorInfo());
+ biasLayer->GetOutputSlot(0).Connect(conv->GetInputSlot(2));
+ conv->m_Bias = biasLayer->m_LayerOutput;
}
// Connect layers
input->GetOutputSlot(0).Connect(conv->GetInputSlot(0));
+ weightsLayer->GetOutputSlot(0).Connect(conv->GetInputSlot(1));
conv->GetOutputSlot(0).Connect(batchNorm->GetInputSlot(0));
batchNorm->GetOutputSlot(0).Connect(output->GetInputSlot(0));
- CHECK(4 == graph.GetNumLayers());
- CHECK(CheckSequence(graph.cbegin(), graph.cend(),
- &IsLayerOfType<InputLayer>,
- &IsLayerOfType<Convolution2dLayer>,
- &IsLayerOfType<BatchNormalizationLayer>,
- &IsLayerOfType<OutputLayer>));
+ // Temporary workaround to ensure the descriptor weights are populated
+ conv->m_Weight = weightsLayer->m_LayerOutput;
+
+ if (convolution2dDescriptor.m_BiasEnabled)
+ {
+ CHECK(6 == graph.GetNumLayers());
+ CHECK(CheckSequence(graph.cbegin(), graph.cend(),
+ &IsLayerOfType<InputLayer>,
+ &IsLayerOfType<ConstantLayer>,
+ &IsLayerOfType<ConstantLayer>,
+ &IsLayerOfType<Convolution2dLayer>,
+ &IsLayerOfType<BatchNormalizationLayer>,
+ &IsLayerOfType<OutputLayer>));
+ }
+ else
+ {
+ CHECK(5 == graph.GetNumLayers());
+ CHECK(CheckSequence(graph.cbegin(), graph.cend(),
+ &IsLayerOfType<InputLayer>,
+ &IsLayerOfType<ConstantLayer>,
+ &IsLayerOfType<Convolution2dLayer>,
+ &IsLayerOfType<BatchNormalizationLayer>,
+ &IsLayerOfType<OutputLayer>));
+ }
// Optimize graph
armnn::Optimizer::Pass(graph, MakeOptimizations(FuseBatchNormIntoConvolution2DFloat32()));
@@ -918,11 +954,13 @@ TEST_CASE("OptimizeForExclusiveConnectionsFuseTest")
(layer->GetNameStr() == "fused-batchNorm-into-convolution");
};
- CHECK(3 == graph.GetNumLayers());
+ CHECK(5 == graph.GetNumLayers());
CHECK(CheckSequence(graph.cbegin(), graph.cend(),
- &IsLayerOfType<InputLayer>,
- checkFusedConv2d,
- &IsLayerOfType<OutputLayer>));
+ &IsLayerOfType<InputLayer>,
+ &IsLayerOfType<ConstantLayer>,
+ &IsLayerOfType<ConstantLayer>,
+ checkFusedConv2d,
+ &IsLayerOfType<OutputLayer>));
}
// Tests that OptimizeForExclusiveConnections works, not fusing when not needed, using BatchNorm fusing as example
diff --git a/src/armnn/test/ShapeInferenceTests.cpp b/src/armnn/test/ShapeInferenceTests.cpp
index d45c9900c0..a3800ade09 100644
--- a/src/armnn/test/ShapeInferenceTests.cpp
+++ b/src/armnn/test/ShapeInferenceTests.cpp
@@ -275,8 +275,6 @@ TEST_CASE("Convolution2dTest")
{
const TensorShape inputShape{1, 1, 10, 10};
- Graph graph;
-
Convolution2dDescriptor descriptor;
descriptor.m_PadLeft = 0;
@@ -288,16 +286,9 @@ TEST_CASE("Convolution2dTest")
descriptor.m_DilationX = 3;
descriptor.m_DilationY = 3;
- auto layer = BuildGraph<Convolution2dLayer>(&graph,
- {inputShape},
- descriptor,
- "conv2d");
-
- const float Datum = 0.0f;
- ConstTensor weights({{1, 1, 3, 3}, DataType::Float32, 0.0f, 0, true}, &Datum);
- layer->m_Weight = std::make_unique<ScopedTensorHandle>(weights);
-
- RunShapeInferenceTest<Convolution2dLayer>(layer, {{ 1, 1, 4, 4 }});
+ CreateGraphAndRunTest<Convolution2dLayer>({ inputShape, { 1, 1, 3, 3 } },
+ { { 1, 1, 4, 4 } }, descriptor,
+ "convd");
}
TEST_CASE("DebugLayerTest")
diff --git a/src/armnn/test/SubgraphViewTests.cpp b/src/armnn/test/SubgraphViewTests.cpp
index 048c4f51fd..d7465c8361 100644
--- a/src/armnn/test/SubgraphViewTests.cpp
+++ b/src/armnn/test/SubgraphViewTests.cpp
@@ -42,28 +42,44 @@ bool AreAnySubgraphLayersPresentInGraph(const SubgraphView::IConnectableLayers &
//
// this helper only works if all layers where the inputs connect to are not selected
//
-SubgraphView::InputSlots CreateInputsFrom(const std::vector<Layer*>& layers)
+SubgraphView::InputSlots CreateInputsFrom(const std::vector<Layer*>& layers,
+ std::vector<int> ignoreSlots = {})
{
SubgraphView::InputSlots result;
for (auto&& layer : layers)
{
for (auto&& it = layer->BeginInputSlots(); it != layer->EndInputSlots(); ++it)
{
- result.push_back(&(*it));
+ if (std::find(ignoreSlots.begin(), ignoreSlots.end(), it->GetSlotIndex()) != ignoreSlots.end())
+ {
+ continue;
+ }
+ else
+ {
+ result.push_back(&(*it));
+ }
}
}
return result;
}
/// Duplication for IConnectableLayer
-SubgraphView::IInputSlots CreateIInputsFrom(const std::vector<armnn::IConnectableLayer*>& layers)
+SubgraphView::IInputSlots CreateIInputsFrom(const std::vector<armnn::IConnectableLayer*>& layers,
+ std::vector<int> ignoreSlots = {})
{
SubgraphView::IInputSlots result;
- for (auto&& layer : layers)
+ for (auto&& layer: layers)
{
- for (unsigned int i = 0 ; i < layer->GetNumInputSlots(); ++i)
+ for (unsigned int i = 0; i < layer->GetNumInputSlots(); ++i)
{
- result.push_back(&(layer->GetInputSlot(i)));
+ if (std::find(ignoreSlots.begin(), ignoreSlots.end(), i) != ignoreSlots.end())
+ {
+ continue;
+ }
+ else
+ {
+ result.push_back(&(layer->GetInputSlot(i)));
+ }
}
}
return result;
@@ -241,7 +257,7 @@ TEST_CASE("SubgraphViewSlots")
// Construct sub-graph
SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom({},
- CreateIInputsFrom({convLayer1}),
+ CreateIInputsFrom({convLayer1}, {1, 2}),
CreateIOutputsFrom({convLayer2}));
// Test that both old and new are initialized
@@ -327,17 +343,20 @@ TEST_CASE("SingleInputSingleOutput")
Convolution2dDescriptor convDescriptor;
Layer* const convLayer1 = graph.AddLayer<Convolution2dLayer>(convDescriptor, "conv1");
Layer* const convLayer2 = graph.AddLayer<Convolution2dLayer>(convDescriptor, "conv2");
-
+ Layer* const weightsLayer1 = graph.AddLayer<ConstantLayer>("weights1");
+ Layer* const weightsLayer2 = graph.AddLayer<ConstantLayer>("weights2");
Layer* const outputLayer = graph.AddLayer<OutputLayer>(0, "output");
inputLayer->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(0));
+ weightsLayer1->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(1));
convLayer1->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(0));
+ weightsLayer2->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(1));
convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
// Construct sub-graph
SubgraphViewSelector::SubgraphViewPtr subgraph =
CreateSubgraphViewFrom({},
- CreateIInputsFrom({convLayer1}),
+ CreateIInputsFrom({convLayer1}, {1}),
CreateIOutputsFrom({convLayer2}));
// Save sub-graph connections for comparison after substitution
@@ -377,7 +396,7 @@ TEST_CASE("SingleInputSingleOutputAddPrecompiledLayerSubstituteSubgraph1")
convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
// Construct sub-graph
- SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(CreateInputsFrom({convLayer1}),
+ SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(CreateInputsFrom({convLayer1}, {1}),
CreateOutputsFrom({convLayer2}),
{});
@@ -421,7 +440,7 @@ TEST_CASE("SingleInputSingleOutputAddPrecompiledLayerSubstituteSubgraph2")
convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
// Construct sub-graph
- SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(CreateInputsFrom({convLayer1}),
+ SubgraphViewSelector::SubgraphViewPtr subgraph = CreateSubgraphViewFrom(CreateInputsFrom({convLayer1}, {1}),
CreateOutputsFrom({convLayer2}),
{});
@@ -467,7 +486,7 @@ TEST_CASE("SingleInputSingleOutputSubstituteGraph")
// Construct sub-graph
SubgraphViewSelector::SubgraphViewPtr subgraph =
- CreateSubgraphViewFrom(CreateInputsFrom({convLayer1}),
+ CreateSubgraphViewFrom(CreateInputsFrom({convLayer1}, {1}),
CreateOutputsFrom({convLayer2}),
{});
@@ -519,7 +538,7 @@ TEST_CASE("MultiInputSingleOutput")
concatLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
// Construct sub-graph
- auto subgraph = CreateSubgraphViewFrom(CreateInputsFrom({convLayer1, convLayer2}),
+ auto subgraph = CreateSubgraphViewFrom(CreateInputsFrom({convLayer1, convLayer2}, {1}),
CreateOutputsFrom({concatLayer}),
{});
@@ -621,7 +640,7 @@ TEST_CASE("MultiInputMultiOutput")
// Construct sub-graph
SubgraphViewSelector::SubgraphViewPtr subgraph =
- CreateSubgraphViewFrom(CreateInputsFrom({convLayer1, convLayer2}),
+ CreateSubgraphViewFrom(CreateInputsFrom({convLayer1, convLayer2}, {1}),
CreateOutputsFrom({convLayer1, convLayer2}),
{});
@@ -942,7 +961,8 @@ TEST_CASE("MultipleSimpleSubgraphs")
// This test case represents the scenario when we have two distinct subgraphs
// in a simple linear network. The selected nodes are the M* and the
// non-selected ones are the X*
- //
+ // W2 ->->
+ // |
// X1 -> M1 -> M2 -> X2 -> M3 -> X3
//
// The expected results is two subgraphs, one with {M1, M2} and another one
@@ -952,12 +972,17 @@ TEST_CASE("MultipleSimpleSubgraphs")
// the graph is constructed in reverse order
auto x3 = graph.AddLayer<OutputLayer>(0, "output");
+
auto m3 = graph.InsertNewLayer<ActivationLayer>(x3->GetInputSlot(0),
ActivationDescriptor{},
"m3");
+
auto x2 = graph.InsertNewLayer<Convolution2dLayer>(m3->GetInputSlot(0),
- Convolution2dDescriptor{},
- "x2");
+ Convolution2dDescriptor{},
+ "x2");
+
+ auto w2 = graph.InsertNewLayer<ConstantLayer>(x2->GetInputSlot(1), "w2");
+
auto m2 = graph.InsertNewLayer<ActivationLayer>(x2->GetInputSlot(0),
ActivationDescriptor{},
"m2");
@@ -966,6 +991,7 @@ TEST_CASE("MultipleSimpleSubgraphs")
"m1");
graph.InsertNewLayer<InputLayer>(m1->GetInputSlot(0), 0, "x1");
+ IgnoreUnused(w2);
// All selected 'M*' layers will be of Activation type
SubgraphViewSelector::Subgraphs subgraphs =
SubgraphViewSelector::SelectSubgraphs(
@@ -1636,10 +1662,17 @@ TEST_CASE("SingleSubgraph")
Layer* const convLayer2 = graph.AddLayer<Convolution2dLayer>(convDescriptor, "conv2");
convLayer2->SetBackendId(Compute::GpuAcc);
+ Layer* const weights1 = graph.AddLayer<ConstantLayer>("weights1");
+ weights1->SetBackendId(Compute::GpuAcc);
+ Layer* const weights2 = graph.AddLayer<ConstantLayer>("weights2");
+ weights2->SetBackendId(Compute::GpuAcc);
+
Layer* const outputLayer = graph.AddLayer<OutputLayer>(0, "output");
inputLayer->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(0));
+ weights1->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(1));
convLayer1->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(0));
+ weights2->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(1));
convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
// GpuAcc sub graph selector
@@ -1702,6 +1735,9 @@ TEST_CASE("MultipleSubgraphs")
Layer* const convLayer1 = graph.AddLayer<Convolution2dLayer>(convDescriptor, "conv1");
Layer* const convLayer2 = graph.AddLayer<Convolution2dLayer>(convDescriptor, "conv2");
+ Layer* const weights1 = graph.AddLayer<ConstantLayer>("weights1");
+ Layer* const weights2 = graph.AddLayer<ConstantLayer>("weights2");
+
OriginsDescriptor concatDescriptor(2);
Layer* const pConcatLayer = graph.AddLayer<ConcatLayer>(concatDescriptor, "concat");
pConcatLayer->SetBackendId(Compute::CpuAcc);
@@ -1711,7 +1747,9 @@ TEST_CASE("MultipleSubgraphs")
inputLayer->GetOutputSlot(0).Connect(splitterLayer->GetInputSlot(0));
splitterLayer->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(0));
splitterLayer->GetOutputSlot(1).Connect(convLayer2->GetInputSlot(0));
+ weights1->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(1));
convLayer1->GetOutputSlot(0).Connect(pConcatLayer->GetInputSlot(0));
+ weights2->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(1));
convLayer2->GetOutputSlot(0).Connect(pConcatLayer->GetInputSlot(1));
pConcatLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
diff --git a/src/armnn/test/optimizations/FoldPadTests.cpp b/src/armnn/test/optimizations/FoldPadTests.cpp
index 9919c6d0e6..027b10377d 100644
--- a/src/armnn/test/optimizations/FoldPadTests.cpp
+++ b/src/armnn/test/optimizations/FoldPadTests.cpp
@@ -47,6 +47,12 @@ TEST_CASE("FoldPadLayerIntoConvolution2dLayer")
std::vector<float> weightsVector(18);
ConstTensor weights(TensorInfo(4, weightsShape, DataType::Float32, 0.0f, 0, true), weightsVector);
+ ConstantLayer* weightsLayer = graph.AddLayer<ConstantLayer>("Weights");
+ weightsLayer->m_LayerOutput = std::make_shared<ScopedTensorHandle>(weights);
+
+ TensorInfo weightsInfo = weightsLayer->m_LayerOutput->GetTensorInfo();
+ weightsLayer->GetOutputSlot(0).SetTensorInfo(weightsInfo);
+
Convolution2dLayer* conv2dLayer = graph.AddLayer<Convolution2dLayer>(convolution2dDescriptor, "conv2d");
conv2dLayer->m_Weight = std::make_unique<ScopedTensorHandle>(weights);
conv2dLayer->GetOutputSlot().SetTensorInfo(outputInfo);
@@ -56,6 +62,7 @@ TEST_CASE("FoldPadLayerIntoConvolution2dLayer")
// Connect up layers - input -> pad -> conv2d -> output
input->GetOutputSlot().Connect(padLayer->GetInputSlot(0));
padLayer->GetOutputSlot().Connect(conv2dLayer->GetInputSlot(0));
+ weightsLayer->GetOutputSlot().Connect(conv2dLayer->GetInputSlot(1));
conv2dLayer->GetOutputSlot().Connect(output->GetInputSlot(0));
auto checkSimpleConv2d = [](const Layer* const layer)->bool {
@@ -69,10 +76,11 @@ TEST_CASE("FoldPadLayerIntoConvolution2dLayer")
};
CHECK(CheckSequence(graph.cbegin(), graph.cend(),
- &IsLayerOfType<InputLayer>,
- &IsLayerOfType<PadLayer>,
- checkSimpleConv2d,
- &IsLayerOfType<OutputLayer>));
+ &IsLayerOfType<InputLayer>,
+ &IsLayerOfType<PadLayer>,
+ &IsLayerOfType<ConstantLayer>,
+ checkSimpleConv2d,
+ &IsLayerOfType<OutputLayer>));
armnn::Optimizer::Pass(graph, armnn::MakeOptimizations(FoldPadIntoConvolution2d()));
@@ -87,9 +95,10 @@ TEST_CASE("FoldPadLayerIntoConvolution2dLayer")
};
CHECK(CheckSequence(graph.cbegin(), graph.cend(),
- &IsLayerOfType<InputLayer>,
- checkPadFoldedIntoConv2d,
- &IsLayerOfType<OutputLayer>));
+ &IsLayerOfType<InputLayer>,
+ checkPadFoldedIntoConv2d,
+ &IsLayerOfType<ConstantLayer>,
+ &IsLayerOfType<OutputLayer>));
}
TEST_CASE("FoldPadLayerIntoDepthwiseConvolution2dLayer")
@@ -628,12 +637,12 @@ TEST_CASE("FoldPadLayerIntoConv2dLayer_ExecuteInferenceWithAndWithoutOptimizatio
TensorInfo biasInfo({4}, DataType::Float32, 0.0f, 0, true);
ConstTensor bias(biasInfo, biasVector);
Optional<ConstTensor> optionalBias = Optional<ConstTensor>(bias);
-
+ ARMNN_NO_DEPRECATE_WARN_BEGIN
IConnectableLayer* conv2dLayer = network->AddConvolution2dLayer(convDescriptor,
weights,
optionalBias,
"Conv2D");
-
+ ARMNN_NO_DEPRECATE_WARN_END
TensorInfo outputInfo(4, outputShape, DataType::Float32);
conv2dLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
diff --git a/src/armnn/test/optimizations/FuseActivationTests.cpp b/src/armnn/test/optimizations/FuseActivationTests.cpp
index e5f54208f0..0cca86f93b 100644
--- a/src/armnn/test/optimizations/FuseActivationTests.cpp
+++ b/src/armnn/test/optimizations/FuseActivationTests.cpp
@@ -42,7 +42,7 @@ struct Convolution2dTest
{
using LayerType = Convolution2dLayer;
static const bool isElementWise = false;
- static const bool isConstTensorAsInputSupported = false;
+ static const bool isConstTensorAsInputSupported = true;
static TensorShape GetInputShape() { return TensorShape( {1, 4, 4, 3}); } // NHWCin
static TensorShape GetOutputShape() { return TensorShape( {1, 3, 3, 4}); } // NHWCout
@@ -69,8 +69,9 @@ struct Convolution2dTest
TensorInfo weightsInfo(GetWeightsShape(), ArmnnType, scale, offset, true);
ConstTensor weights(weightsInfo, weightsVector);
Optional<ConstTensor> optionalBias;
-
+ ARMNN_NO_DEPRECATE_WARN_BEGIN
return network->AddConvolution2dLayer(descriptor, weights, optionalBias, name);
+ ARMNN_NO_DEPRECATE_WARN_END
}
static std::vector<IConnectableLayer*> AddConstantLayers(INetwork* network,
diff --git a/src/armnn/test/optimizations/FuseBatchNormTests.cpp b/src/armnn/test/optimizations/FuseBatchNormTests.cpp
index b28bb17773..4a94f7889b 100644
--- a/src/armnn/test/optimizations/FuseBatchNormTests.cpp
+++ b/src/armnn/test/optimizations/FuseBatchNormTests.cpp
@@ -24,7 +24,6 @@ class Conv2dTest
public:
using ConvDescriptorType = armnn::Convolution2dDescriptor;
using ConvLayerType = armnn::Convolution2dLayer;
- static const bool isConstTensorAsInputSupported = false;
static IConnectableLayer *AddConvolution(INetwork *network,
const Convolution2dDescriptor &descriptor,
@@ -32,7 +31,9 @@ public:
const Optional<ConstTensor> &biases,
const char *name)
{
+ ARMNN_NO_DEPRECATE_WARN_BEGIN
return network->AddConvolution2dLayer(descriptor, weights, biases, name);
+ ARMNN_NO_DEPRECATE_WARN_END
}
static std::vector<IConnectableLayer*> AddConstantLayers(INetwork *network,
@@ -54,13 +55,12 @@ class DepthwiseConv2dTest
public:
using ConvDescriptorType = armnn::DepthwiseConvolution2dDescriptor;
using ConvLayerType = armnn::DepthwiseConvolution2dLayer;
- static const bool isConstTensorAsInputSupported = true;
- static IConnectableLayer *AddConvolution(INetwork *network,
- const DepthwiseConvolution2dDescriptor &descriptor,
- const ConstTensor &weights,
- const Optional<ConstTensor> &biases,
- const char *name)
+ static IConnectableLayer* AddConvolution(INetwork* network,
+ const DepthwiseConvolution2dDescriptor& descriptor,
+ const ConstTensor& weights,
+ const Optional<ConstTensor>& biases,
+ const char* name)
{
IgnoreUnused(weights);
IgnoreUnused(biases);
@@ -183,19 +183,15 @@ INetworkPtr CreateNetwork(bool depthwise, bool preventFusing)
output2Layer = network->AddOutputLayer(1);
}
- // If ConstTensorAsInputs is supported weights and bias are stored as constant layers.
- if (Conv2dTest::isConstTensorAsInputSupported)
- {
- std::vector<IConnectableLayer*> constantLayers = Conv2dTest::AddConstantLayers(network.get(),
- convolution2dDescriptor,
- weights,
- Optional<ConstTensor>());
+ std::vector<IConnectableLayer*> constantLayers = Conv2dTest::AddConstantLayers(network.get(),
+ convolution2dDescriptor,
+ weights,
+ Optional<ConstTensor>());
- // Connect constant layers to receiverLayer.
- for (unsigned int i = 0; i < constantLayers.size(); ++i)
- {
- constantLayers[i]->GetOutputSlot(0).Connect(convLayer->GetInputSlot(i + 1));
- }
+ // Connect constant layers to receiverLayer.
+ for (unsigned int i = 0; i < constantLayers.size(); ++i)
+ {
+ constantLayers[i]->GetOutputSlot(0).Connect(convLayer->GetInputSlot(i + 1));
}
// Set layer information
@@ -241,26 +237,14 @@ void FuseBatchNormIntoConvTest(bool depthwise, float tolerance, armnn::Compute b
(layer->GetNameStr() == "fused-batchNorm-into-convolution");
};
- if (Conv2dTest::isConstTensorAsInputSupported)
- {
- CHECK(5 == graphFused.GetNumLayers());
- CHECK(CheckSequence(graphFused.cbegin(),
- graphFused.cend(),
- &IsLayerOfType<InputLayer>,
- &IsLayerOfType<ConstantLayer>,
- &IsLayerOfType<ConstantLayer>,
- checkFusedConv2d,
- &IsLayerOfType<OutputLayer>));
- }
- else
- {
- CHECK(3 == graphFused.GetNumLayers());
- CHECK(CheckSequence(graphFused.cbegin(),
- graphFused.cend(),
- &IsLayerOfType<InputLayer>,
- checkFusedConv2d,
- &IsLayerOfType<OutputLayer>));
- }
+ CHECK(5 == graphFused.GetNumLayers());
+ CHECK(CheckSequence(graphFused.cbegin(),
+ graphFused.cend(),
+ &IsLayerOfType<InputLayer>,
+ &IsLayerOfType<ConstantLayer>,
+ &IsLayerOfType<ConstantLayer>,
+ checkFusedConv2d,
+ &IsLayerOfType<OutputLayer>));
// Load network into runtime
NetworkId networkIdentifier;
@@ -278,10 +262,10 @@ void FuseBatchNormIntoConvTest(bool depthwise, float tolerance, armnn::Compute b
TensorInfo inputTensorInfo = run->GetInputTensorInfo(networkIdentifier, 0);
inputTensorInfo.SetConstant(true);
- InputTensors inputTensorsFused {
+ InputTensors inputTensorsFused {
{0, ConstTensor(inputTensorInfo, inputDataFused.data())}};
OutputTensors outputTensorsFused{
- {0, Tensor(run->GetOutputTensorInfo(networkIdentifier, 0), outputDataFused.data())}};
+ {0, Tensor(run->GetOutputTensorInfo(networkIdentifier, 0), outputDataFused.data())}};
// Execute network
run->EnqueueWorkload(networkIdentifier, inputTensorsFused, outputTensorsFused);
@@ -294,33 +278,19 @@ void FuseBatchNormIntoConvTest(bool depthwise, float tolerance, armnn::Compute b
IRuntimePtr runNotFused = IRuntime::Create(IRuntime::CreationOptions()); // default options
// Optimise ArmNN network
- IOptimizedNetworkPtr optNetNotFused = Optimize(*networkNotFused, {backendId}, runNotFused->GetDeviceSpec());
+ IOptimizedNetworkPtr optNetNotFused = Optimize(*networkNotFused, { backendId }, runNotFused->GetDeviceSpec());
Graph& graphNotFused = GetGraphForTesting(optNetNotFused.get());
- if (Conv2dTest::isConstTensorAsInputSupported)
- {
- CHECK(6 == graphNotFused.GetNumLayers());
- CHECK(CheckSequence(graphNotFused.cbegin(),
- graphNotFused.cend(),
- &IsLayerOfType<armnn::InputLayer>,
- &IsLayerOfType<armnn::ConstantLayer>,
- &IsLayerOfType<ConvLayerType>,
- &IsLayerOfType<armnn::BatchNormalizationLayer>,
- &IsLayerOfType<armnn::OutputLayer>,
- &IsLayerOfType<armnn::OutputLayer>));
- }
- else
- {
- CHECK(5 == graphNotFused.GetNumLayers());
- CHECK(CheckSequence(graphNotFused.cbegin(),
- graphNotFused.cend(),
- &IsLayerOfType<armnn::InputLayer>,
- &IsLayerOfType<ConvLayerType>,
- &IsLayerOfType<armnn::BatchNormalizationLayer>,
- &IsLayerOfType<armnn::OutputLayer>,
- &IsLayerOfType<armnn::OutputLayer>));
- }
+ CHECK(6 == graphNotFused.GetNumLayers());
+ CHECK(CheckSequence(graphNotFused.cbegin(),
+ graphNotFused.cend(),
+ &IsLayerOfType<armnn::InputLayer>,
+ &IsLayerOfType<armnn::ConstantLayer>,
+ &IsLayerOfType<ConvLayerType>,
+ &IsLayerOfType<armnn::BatchNormalizationLayer>,
+ &IsLayerOfType<armnn::OutputLayer>,
+ &IsLayerOfType<armnn::OutputLayer>));
// Load network into runtime
NetworkId networkIdentifierNotFused;
@@ -341,10 +311,10 @@ void FuseBatchNormIntoConvTest(bool depthwise, float tolerance, armnn::Compute b
TensorInfo inputTensorInfo2 = runNotFused->GetInputTensorInfo(networkIdentifierNotFused, 0);
inputTensorInfo2.SetConstant(true);
InputTensors inputTensorsNotFused{
- {0, ConstTensor(inputTensorInfo2, inputDataNotFused.data())}};
+ { 0, ConstTensor(inputTensorInfo2, inputDataNotFused.data()) } };
OutputTensors outputTensorsNotFused{
- {0, Tensor(runNotFused->GetOutputTensorInfo(networkIdentifierNotFused, 0), outputDataNotFused.data())},
- {1, Tensor(runNotFused->GetOutputTensorInfo(networkIdentifierNotFused, 1), outputData2NotFused.data())}};
+ { 0, Tensor(runNotFused->GetOutputTensorInfo(networkIdentifierNotFused, 0), outputDataNotFused.data()) },
+ { 1, Tensor(runNotFused->GetOutputTensorInfo(networkIdentifierNotFused, 1), outputData2NotFused.data()) } };
// Execute network
runNotFused->EnqueueWorkload(networkIdentifierNotFused, inputTensorsNotFused, outputTensorsNotFused);