aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/armnn/Graph.hpp33
-rw-r--r--src/armnn/test/optimizations/FoldPadTests.cpp61
-rw-r--r--src/armnn/test/optimizations/Fp32NetworkToBf16ConverterTests.cpp34
3 files changed, 81 insertions, 47 deletions
diff --git a/src/armnn/Graph.hpp b/src/armnn/Graph.hpp
index 4623461302..482d9277e8 100644
--- a/src/armnn/Graph.hpp
+++ b/src/armnn/Graph.hpp
@@ -246,6 +246,15 @@ private:
}
return it;
}
+ Iterator ForwardToEndOfInputsAndConstants(Iterator it) const
+ {
+ while ((it != m_Layers.end()) &&
+ ((*it)->GetType() == LayerType::Input || (*it)->GetType() == LayerType::Constant))
+ {
+ ++it;
+ }
+ return it;
+ }
Iterator RewindToBeginOfOutputs(Iterator it) const
{
@@ -335,7 +344,7 @@ protected:
Graph* m_Graph;
};
-/// Input/Output layers specialize this template.
+/// Input/Output/Constant layers specialize this template.
template <typename LayerT>
class Graph::LayerInGraph final : public LayerInGraphBase<LayerT>
{
@@ -352,12 +361,32 @@ public:
LayerInGraph(Graph& graph, Iterator insertBefore, Args&&... args)
: LayerInGraphBase<LayerT>(graph,
// Make sure it's inserted after all inputs and before all outputs.
- graph.ForwardToEndOfInputs(graph.RewindToBeginOfOutputs(insertBefore)),
+ graph.ForwardToEndOfInputsAndConstants(graph.RewindToBeginOfOutputs(insertBefore)),
std::forward<Args>(args)...)
{
}
};
+template <>
+class Graph::LayerInGraph<ConstantLayer> final : public LayerInGraphBase<ConstantLayer>
+{
+public:
+ template <typename... Args>
+ LayerInGraph(Graph& graph, Args&&... args)
+ : LayerInGraphBase<ConstantLayer>(graph,
+ // Always add to the back of the inputs.
+ std::next(graph.begin(), IteratorDifference(graph.GetNumInputs())),
+ std::forward<Args>(args)...)
+ {}
+ template <typename... Args>
+ LayerInGraph(Graph& graph, Iterator, Args&&... args)
+ // Ignore Iterator argument. Always add to the back of the inputs.
+ : LayerInGraph(graph, std::forward<Args>(args)...)
+ {}
+ ~LayerInGraph() override
+ {}
+};
+
/// Inputs add/remove their binding id to m_InputIds in the graph.
template <>
class Graph::LayerInGraph<InputLayer> final : public LayerInGraphBase<InputLayer>
diff --git a/src/armnn/test/optimizations/FoldPadTests.cpp b/src/armnn/test/optimizations/FoldPadTests.cpp
index 14c211f9bf..4d7defcabe 100644
--- a/src/armnn/test/optimizations/FoldPadTests.cpp
+++ b/src/armnn/test/optimizations/FoldPadTests.cpp
@@ -25,6 +25,7 @@ TEST_CASE("FoldPadLayerIntoConvolution2dLayer")
TensorInfo inputInfo(4, inputShape, DataType::Float32);
TensorInfo paddedInfo(4, paddedShape, DataType::Float32);
+ TensorInfo weightsInfo(4, weightsShape, DataType::Float32, 1.0f, 0, true);
TensorInfo outputInfo(4, outputShape, DataType::Float32);
Layer* input = graph.AddLayer<InputLayer>(0, "input");
@@ -45,16 +46,13 @@ TEST_CASE("FoldPadLayerIntoConvolution2dLayer")
convolution2dDescriptor.m_DataLayout = DataLayout::NHWC;
std::vector<float> weightsVector(18);
- ConstTensor weights(TensorInfo(4, weightsShape, DataType::Float32, 0.0f, 0, true), weightsVector);
+ ConstTensor weights(weightsInfo, 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);
Layer* output = graph.AddLayer<OutputLayer>(0, "output");
@@ -75,12 +73,11 @@ TEST_CASE("FoldPadLayerIntoConvolution2dLayer")
(conv2dLayerParams.m_BiasEnabled == false) && (conv2dLayerParams.m_DataLayout == DataLayout::NHWC);
};
- CHECK(CheckSequence(graph.cbegin(), graph.cend(),
- &IsLayerOfType<InputLayer>,
- &IsLayerOfType<PadLayer>,
- &IsLayerOfType<ConstantLayer>,
- checkSimpleConv2d,
- &IsLayerOfType<OutputLayer>));
+ CHECK(CheckSequence(graph.cbegin(), graph.cend(), &IsLayerOfType<InputLayer>,
+ &IsLayerOfType<ConstantLayer>,
+ &IsLayerOfType<PadLayer>,
+ checkSimpleConv2d,
+ &IsLayerOfType<OutputLayer>));
armnn::Optimizer::Pass(graph, armnn::MakeOptimizations(FoldPadIntoConvolution2d()));
@@ -94,11 +91,10 @@ TEST_CASE("FoldPadLayerIntoConvolution2dLayer")
(conv2dLayerParams.m_BiasEnabled == false) && (conv2dLayerParams.m_DataLayout == DataLayout::NHWC);
};
- CHECK(CheckSequence(graph.cbegin(), graph.cend(),
- &IsLayerOfType<InputLayer>,
- checkPadFoldedIntoConv2d,
- &IsLayerOfType<ConstantLayer>,
- &IsLayerOfType<OutputLayer>));
+ CHECK(CheckSequence(graph.cbegin(), graph.cend(), &IsLayerOfType<InputLayer>,
+ &IsLayerOfType<ConstantLayer>,
+ checkPadFoldedIntoConv2d,
+ &IsLayerOfType<OutputLayer>));
}
TEST_CASE("FoldPadLayerIntoDepthwiseConvolution2dLayer")
@@ -111,6 +107,7 @@ TEST_CASE("FoldPadLayerIntoDepthwiseConvolution2dLayer")
TensorInfo inputInfo(4, inputShape, DataType::Float32);
TensorInfo paddedInfo(4, paddedShape, DataType::Float32);
+ TensorInfo weightsInfo(4, weightsShape, DataType::Float32, 1.0f, 0, true);
TensorInfo outputInfo(4, outputShape, DataType::Float32);
Layer* input = graph.AddLayer<InputLayer>(0, "input");
@@ -131,15 +128,15 @@ TEST_CASE("FoldPadLayerIntoDepthwiseConvolution2dLayer")
depthwiseConvolution2dDescriptor.m_DataLayout = DataLayout::NHWC;
std::vector<float> weightsVector(18);
- ConstTensor weights(TensorInfo(4, weightsShape, DataType::Float32, 0.0f, 0, true), weightsVector);
+ ConstTensor weights(weightsInfo, weightsVector);
- auto* depthwiseConv2dLayer = graph.AddLayer<DepthwiseConvolution2dLayer>(depthwiseConvolution2dDescriptor,
- "depthwiseConv2d");
auto* weightsLayer = graph.AddLayer<ConstantLayer>("weights");
+ weightsLayer->GetOutputSlot().SetTensorInfo(weightsInfo);
+ weightsLayer->m_LayerOutput = std::make_shared<ScopedTensorHandle>(weights);
- weightsLayer->GetOutputSlot().SetTensorInfo(weights.GetInfo());
+ auto* depthwiseConv2dLayer = graph.AddLayer<DepthwiseConvolution2dLayer>(depthwiseConvolution2dDescriptor,
+ "depthwiseConv2d");
depthwiseConv2dLayer->GetOutputSlot().SetTensorInfo(outputInfo);
- depthwiseConv2dLayer->m_Weight = std::make_shared<ScopedTensorHandle>(weights);
Layer* output = graph.AddLayer<OutputLayer>(0, "output");
@@ -160,12 +157,11 @@ TEST_CASE("FoldPadLayerIntoDepthwiseConvolution2dLayer")
(depthwiseConv2dLayerParams.m_DataLayout == DataLayout::NHWC);
};
- CHECK(CheckSequence(graph.cbegin(), graph.cend(),
- &IsLayerOfType<InputLayer>,
- &IsLayerOfType<PadLayer>,
- checkSimpleDepthwiseConv2d,
- &IsLayerOfType<ConstantLayer>,
- &IsLayerOfType<OutputLayer>));
+ CHECK(CheckSequence(graph.cbegin(), graph.cend(), &IsLayerOfType<InputLayer>,
+ &IsLayerOfType<ConstantLayer>,
+ &IsLayerOfType<PadLayer>,
+ checkSimpleDepthwiseConv2d,
+ &IsLayerOfType<OutputLayer>));
armnn::Optimizer::Pass(graph, MakeOptimizations(FoldPadIntoDepthwiseConvolution2d()));
@@ -181,11 +177,10 @@ TEST_CASE("FoldPadLayerIntoDepthwiseConvolution2dLayer")
(depthwiseConv2dLayerParams.m_DataLayout == DataLayout::NHWC);
};
- CHECK(CheckSequence(graph.cbegin(), graph.cend(),
- &IsLayerOfType<InputLayer>,
- checkPadFoldedIntoDepthwiseConv2d,
- &IsLayerOfType<ConstantLayer>,
- &IsLayerOfType<OutputLayer>));
+ CHECK(CheckSequence(graph.cbegin(), graph.cend(), &IsLayerOfType<InputLayer>,
+ &IsLayerOfType<ConstantLayer>,
+ checkPadFoldedIntoDepthwiseConv2d,
+ &IsLayerOfType<OutputLayer>));
}
TEST_CASE("FoldPadLayerIntoPooling2dLayer")
@@ -631,10 +626,10 @@ TEST_CASE("FoldPadLayerIntoConv2dLayer_ExecuteInferenceWithAndWithoutOptimizatio
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42};
- TensorInfo weightsInfo(4, weightsShape, DataType::Float32, 0.0f, 0, true);
+ TensorInfo weightsInfo(4, weightsShape, DataType::Float32, 1.0f, 0, true);
ConstTensor weights(weightsInfo, weightsData);
std::vector<float> biasVector = {5, 6, 7, 8};
- TensorInfo biasInfo({4}, DataType::Float32, 0.0f, 0, true);
+ TensorInfo biasInfo({4}, DataType::Float32, 1.0f, 0, true);
ConstTensor bias(biasInfo, biasVector);
IConnectableLayer* conv2dLayer = network->AddConvolution2dLayer(convDescriptor, "Conv2D");
diff --git a/src/armnn/test/optimizations/Fp32NetworkToBf16ConverterTests.cpp b/src/armnn/test/optimizations/Fp32NetworkToBf16ConverterTests.cpp
index d3a6932a48..66893ce1f5 100644
--- a/src/armnn/test/optimizations/Fp32NetworkToBf16ConverterTests.cpp
+++ b/src/armnn/test/optimizations/Fp32NetworkToBf16ConverterTests.cpp
@@ -92,18 +92,23 @@ TEST_CASE("Fp32NetworkToBf16OptimizationConv2DTest")
conv->GetOutputSlot().Connect(output->GetInputSlot(0));
CHECK(CheckSequence(graph.cbegin(), graph.cend(), &IsLayerOfType<armnn::InputLayer>,
- &IsLayerOfType<armnn::Convolution2dLayer>, &IsLayerOfType<armnn::ConstantLayer>,
- &IsLayerOfType<armnn::ConstantLayer>, &IsLayerOfType<armnn::OutputLayer>));
+ &IsLayerOfType<armnn::ConstantLayer>,
+ &IsLayerOfType<armnn::ConstantLayer>,
+ &IsLayerOfType<armnn::Convolution2dLayer>,
+ &IsLayerOfType<armnn::OutputLayer>));
// Run the optimizer
armnn::Optimizer::Pass(graph, armnn::MakeOptimizations(RedirectMembersToConstantInputs(),
Fp32NetworkToBf16Converter()));
+ CHECK(7 == graph.GetNumLayers());
CHECK(CheckSequence(graph.cbegin(), graph.cend(), &IsLayerOfType<armnn::InputLayer>,
- &IsLayerOfType<armnn::ConvertFp32ToBf16Layer>,
- &IsLayerOfType<armnn::ConstantLayer>, &IsLayerOfType<armnn::ConvertFp32ToBf16Layer>,
- &IsLayerOfType<armnn::ConstantLayer>, &IsLayerOfType<armnn::Convolution2dLayer>,
- &IsLayerOfType<armnn::OutputLayer>));
+ &IsLayerOfType<armnn::ConstantLayer>,
+ &IsLayerOfType<armnn::ConstantLayer>,
+ &IsLayerOfType<armnn::ConvertFp32ToBf16Layer>,
+ &IsLayerOfType<armnn::ConvertFp32ToBf16Layer>,
+ &IsLayerOfType<armnn::Convolution2dLayer>,
+ &IsLayerOfType<armnn::OutputLayer>));
armnn::TensorInfo inputTensor = conv->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo();
armnn::TensorInfo weightTensor = conv->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo();
@@ -179,17 +184,23 @@ TEST_CASE("Fp32NetworkToBf16OptimizationFullyConnectedTest")
fc->GetOutputSlot().Connect(output->GetInputSlot(0));
CHECK(CheckSequence(graph.cbegin(), graph.cend(), &IsLayerOfType<armnn::InputLayer>,
- &IsLayerOfType<armnn::FullyConnectedLayer>, &IsLayerOfType<armnn::ConstantLayer>,
- &IsLayerOfType<armnn::ConstantLayer>, &IsLayerOfType<armnn::OutputLayer>));
+ &IsLayerOfType<armnn::ConstantLayer>,
+ &IsLayerOfType<armnn::ConstantLayer>,
+ &IsLayerOfType<armnn::FullyConnectedLayer>,
+ &IsLayerOfType<armnn::OutputLayer>));
// Run the optimizer
armnn::Optimizer::Pass(graph, armnn::MakeOptimizations(RedirectMembersToConstantInputs(),
Fp32NetworkToBf16Converter()));
+ CHECK(7 == graph.GetNumLayers());
CHECK(CheckSequence(graph.cbegin(), graph.cend(), &IsLayerOfType<armnn::InputLayer>,
- &IsLayerOfType<armnn::ConvertFp32ToBf16Layer>, &IsLayerOfType<armnn::ConstantLayer>,
- &IsLayerOfType<armnn::ConvertFp32ToBf16Layer>, &IsLayerOfType<armnn::ConstantLayer>,
- &IsLayerOfType<armnn::FullyConnectedLayer>, &IsLayerOfType<armnn::OutputLayer>));
+ &IsLayerOfType<armnn::ConstantLayer>,
+ &IsLayerOfType<armnn::ConstantLayer>,
+ &IsLayerOfType<armnn::ConvertFp32ToBf16Layer>,
+ &IsLayerOfType<armnn::ConvertFp32ToBf16Layer>,
+ &IsLayerOfType<armnn::FullyConnectedLayer>,
+ &IsLayerOfType<armnn::OutputLayer>));
armnn::TensorInfo inputTensor = fc->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo();
armnn::TensorInfo weightTensor = fc->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo();
@@ -215,5 +226,4 @@ TEST_CASE("Fp32NetworkToBf16OptimizationFullyConnectedTest")
CHECK(data[7] == armnn::BFloat16(-9.131327E-10f)); // 0xB07B
}
-
} \ No newline at end of file