ArmNN
 22.02
OptimizationViewsTests.cpp File Reference
#include <CommonTestUtils.hpp>
#include "MockBackend.hpp"
#include <Graph.hpp>
#include <Network.hpp>
#include <SubgraphViewSelector.hpp>
#include <armnn/backends/OptimizationViews.hpp>
#include <armnn/backends/SubgraphView.hpp>
#include <armnn/utility/PolymorphicDowncast.hpp>
#include <doctest/doctest.h>

Go to the source code of this file.

Functions

void CheckLayers (Graph &graph)
 
 TEST_SUITE ("OptimizationViewsTestSuite")
 

Function Documentation

◆ CheckLayers()

void CheckLayers ( Graph graph)

Definition at line 22 of file OptimizationViewsTests.cpp.

References armnn::Input, armnn::Output, and armnn::PreCompiled.

Referenced by IDeserializer::GetNetworkOutputBindingInfo(), and TEST_SUITE().

23 {
24  unsigned int m_inputLayerCount = 0, m_outputLayerCount = 0, m_addLayerCount = 0;
25  for(auto layer : graph)
26  {
27  switch(layer->GetType())
28  {
29  case LayerType::Input:
30  ++m_inputLayerCount;
31  CHECK((layer->GetName() == std::string("inLayer0") ||
32  layer->GetName() == std::string("inLayer1")));
33  break;
34  // The Addition layer should become a PreCompiled Layer after Optimisation
35  case LayerType::PreCompiled:
36  ++m_addLayerCount;
37  CHECK(std::string(layer->GetName()) == "pre-compiled");
38  break;
39  case LayerType::Output:
40  ++m_outputLayerCount;
41  CHECK(std::string(layer->GetName()) == "outLayer");
42  break;
43  default:
44  //Fail for anything else
45  CHECK(false);
46  }
47  }
48  CHECK(m_inputLayerCount == 2);
49  CHECK(m_outputLayerCount == 1);
50  CHECK(m_addLayerCount == 1);
51 }

◆ TEST_SUITE()

TEST_SUITE ( "OptimizationViewsTestSuite"  )

Definition at line 53 of file OptimizationViewsTests.cpp.

References OptimizationViews::AddFailedSubgraph(), Graph::AddLayer(), OptimizationViews::AddSubstitution(), OptimizationViews::AddUntouchedSubgraph(), CheckLayers(), IOutputSlot::Connect(), OutputSlot::Connect(), armnn::CpuRef, IRuntime::Create(), INetwork::Create(), CreateInputsFrom(), CreateOutputsFrom(), CreateSubgraphViewFrom(), armnn::Float32, armnn::GetGraphForTesting(), MockBackend::GetIdStatic(), OptimizationViews::GetINetwork(), IConnectableLayer::GetInputSlot(), Layer::GetInputSlot(), IConnectableLayer::GetOutputSlot(), Layer::GetOutputSlot(), armnn::Optimize(), IOutputSlot::SetTensorInfo(), Graph::SubstituteSubgraph(), and OptimizationViews::Validate().

54 {
55 TEST_CASE("OptimizedViewsSubgraphLayerCount")
56 {
57  OptimizationViews view;
58  // Construct a graph with 3 layers
59  Graph baseGraph;
60 
61  Layer* const inputLayer = baseGraph.AddLayer<InputLayer>(0, "input");
62 
63  Convolution2dDescriptor convDescriptor;
64  PreCompiledDescriptor substitutionLayerDescriptor(1, 1);
65  Layer* const convLayer1 = baseGraph.AddLayer<Convolution2dLayer>(convDescriptor, "conv1");
66  Layer* const convLayer2 = baseGraph.AddLayer<Convolution2dLayer>(convDescriptor, "conv2");
67  Layer* const substitutableCompiledLayer =
68  baseGraph.AddLayer<PreCompiledLayer>(substitutionLayerDescriptor, "pre-compiled");
69 
70  Layer* const outputLayer = baseGraph.AddLayer<OutputLayer>(0, "output");
71 
72  inputLayer->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(0));
73  convLayer1->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(0));
74  convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
75 
76  // Subgraph for a failed layer
79  CreateOutputsFrom({convLayer1}),
80  {convLayer1});
81  // Subgraph for an untouched layer
82  SubgraphViewSelector::SubgraphViewPtr untouchedSubgraph =
84  CreateOutputsFrom({convLayer2}),
85  {convLayer2});
86  // Subgraph for a substitutable layer
87  SubgraphViewSelector::SubgraphViewPtr substitutableSubgraph =
89  CreateOutputsFrom({convLayer2}),
90  {substitutableCompiledLayer});
91  // Create a Graph containing a layer to substitute in
92  Graph substitutableGraph;
93  Layer* const substitutionpreCompiledLayer =
94  substitutableGraph.AddLayer<PreCompiledLayer>(substitutionLayerDescriptor, "pre-compiled");
95 
96  // Subgraph for a substitution layer
97  SubgraphViewSelector::SubgraphViewPtr substitutionSubgraph =
98  CreateSubgraphViewFrom(CreateInputsFrom({substitutionpreCompiledLayer}),
99  CreateOutputsFrom({substitutionpreCompiledLayer}),
100  {substitutionpreCompiledLayer});
101 
102  // Sub in the graph
103  baseGraph.SubstituteSubgraph(*substitutableSubgraph, *substitutionSubgraph);
104 
105  view.AddFailedSubgraph(SubgraphView(*failedSubgraph));
106  view.AddUntouchedSubgraph(SubgraphView(*untouchedSubgraph));
107 
110  CreateOutputsFrom({convLayer2}),
111  {substitutionpreCompiledLayer});
112  view.AddSubstitution({*baseSubgraph, *substitutionSubgraph});
113 
114  // Construct original subgraph to compare against
115  SubgraphViewSelector::SubgraphViewPtr originalSubgraph =
117  CreateOutputsFrom({convLayer2}),
118  {convLayer1, convLayer2, substitutionpreCompiledLayer});
119 
120  CHECK(view.Validate(*originalSubgraph));
121 }
122 
123 
124 TEST_CASE("OptimizedViewsSubgraphLayerCountUsingGetINetwork")
125 {
126  OptimizationViews view;
127 
128  IConnectableLayer* const inputLayer = view.GetINetwork()->AddInputLayer(0, "input");
129 
130  DepthwiseConvolution2dDescriptor convDescriptor;
131  PreCompiledDescriptor substitutionLayerDescriptor(1, 1);
132  CompiledBlobPtr blobPtr;
133  BackendId backend = Compute::CpuRef;
134 
135  Layer* convLayer1 = PolymorphicDowncast<Layer*>(
136  view.GetINetwork()->AddDepthwiseConvolution2dLayer(convDescriptor,
137  ConstTensor(),
139  "conv1"));
140 
141  Layer* convLayer2 = PolymorphicDowncast<Layer*>(
142  view.GetINetwork()->AddDepthwiseConvolution2dLayer(convDescriptor,
143  ConstTensor(),
145  "conv2"));
146 
147  IConnectableLayer* const outputLayer = view.GetINetwork()->AddOutputLayer(0, "output");
148 
149  inputLayer->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(0));
150  convLayer1->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(0));
151  convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
152 
153  // Subgraph for a failed layer
155  CreateOutputsFrom({convLayer1}),
156  {convLayer1});
157  // Subgraph for an untouched layer
159  CreateOutputsFrom({convLayer2}),
160  {convLayer2});
161 
162  // Create a Network containing a layer to substitute in
163  NetworkImpl net;
164  Layer* substitutionpreCompiledLayer = PolymorphicDowncast<Layer*>(
165  net.AddPrecompiledLayer(substitutionLayerDescriptor, std::move(blobPtr), backend));
166 
167  // Subgraph for a substitution layer
168  SubgraphViewSelector::SubgraphViewPtr substitutionSubgraph =
169  CreateSubgraphViewFrom(CreateInputsFrom({substitutionpreCompiledLayer}),
170  CreateOutputsFrom({substitutionpreCompiledLayer}),
171  {substitutionpreCompiledLayer});
172 
173  view.AddFailedSubgraph(SubgraphView(*failedSubgraph));
174  view.AddUntouchedSubgraph(SubgraphView(*untouchedSubgraph));
175 
177  CreateOutputsFrom({convLayer2}),
178  {substitutionpreCompiledLayer});
179  view.AddSubstitution({*baseSubgraph, *substitutionSubgraph});
180 
181  // Construct original subgraph to compare against
182  SubgraphViewSelector::SubgraphViewPtr originalSubgraph =
184  CreateOutputsFrom({convLayer2}),
185  {convLayer1, convLayer2, substitutionpreCompiledLayer});
186 
187  CHECK(view.Validate(*originalSubgraph));
188 }
189 
190 TEST_CASE("OptimizedViewsSubgraphLayerCountFailValidate")
191 {
192  OptimizationViews view;
193  // Construct a graph with 3 layers
194  Graph baseGraph;
195 
196  Layer* const inputLayer = baseGraph.AddLayer<InputLayer>(0, "input");
197 
198  Convolution2dDescriptor convDescriptor;
199  PreCompiledDescriptor substitutionLayerDescriptor(1, 1);
200  Layer* const convLayer1 = baseGraph.AddLayer<Convolution2dLayer>(convDescriptor, "conv1");
201  Layer* const convLayer2 = baseGraph.AddLayer<Convolution2dLayer>(convDescriptor, "conv2");
202  Layer* const substitutableCompiledLayer =
203  baseGraph.AddLayer<PreCompiledLayer>(substitutionLayerDescriptor, "pre-compiled");
204 
205  Layer* const outputLayer = baseGraph.AddLayer<OutputLayer>(0, "output");
206 
207  inputLayer->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(0));
208  convLayer1->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(0));
209  convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
210 
211  // Subgraph for an untouched layer
212  SubgraphViewSelector::SubgraphViewPtr untouchedSubgraph =
214  CreateOutputsFrom({convLayer2}),
215  {convLayer2});
216  // Subgraph for a substitutable layer
217  SubgraphViewSelector::SubgraphViewPtr substitutableSubgraph =
219  CreateOutputsFrom({convLayer2}),
220  {substitutableCompiledLayer});
221  // Create a Graph containing a layer to substitute in
222  Graph substitutableGraph;
223  Layer* const substitutionpreCompiledLayer =
224  substitutableGraph.AddLayer<PreCompiledLayer>(substitutionLayerDescriptor, "pre-compiled");
225 
226  // Subgraph for a substitution layer
227  SubgraphViewSelector::SubgraphViewPtr substitutionSubgraph =
228  CreateSubgraphViewFrom(CreateInputsFrom({substitutionpreCompiledLayer}),
229  CreateOutputsFrom({substitutionpreCompiledLayer}),
230  {substitutionpreCompiledLayer});
231 
232  // Sub in the graph
233  baseGraph.SubstituteSubgraph(*substitutableSubgraph, *substitutionSubgraph);
234 
235  view.AddUntouchedSubgraph(SubgraphView(*untouchedSubgraph));
236 
239  CreateOutputsFrom({convLayer2}),
240  {substitutionpreCompiledLayer});
241  view.AddSubstitution({*baseSubgraph, *substitutionSubgraph});
242 
243  // Construct original subgraph to compare against
244  SubgraphViewSelector::SubgraphViewPtr originalSubgraph =
246  CreateOutputsFrom({convLayer2}),
247  {convLayer1, convLayer2, substitutionpreCompiledLayer});
248 
249  // Validate should fail as convLayer1 is not counted
250  CHECK(!view.Validate(*originalSubgraph));
251 }
252 
253 TEST_CASE("OptimizeViewsValidateDeviceMockBackend")
254 {
255  // build up the structure of the network
257 
258  armnn::IConnectableLayer* input = net->AddInputLayer(0, "inLayer0");
259  armnn::IConnectableLayer* input1 = net->AddInputLayer(1, "inLayer1");
260 
261  armnn::IConnectableLayer* addition = net->AddAdditionLayer("addLayer");
262 
263  armnn::IConnectableLayer* output = net->AddOutputLayer(0, "outLayer");
264 
265  input->GetOutputSlot(0).Connect(addition->GetInputSlot(0));
266  input1->GetOutputSlot(0).Connect(addition->GetInputSlot(1));
267  addition->GetOutputSlot(0).Connect(output->GetInputSlot(0));
268 
272 
273  armnn::MockBackendInitialiser initialiser;
276 
277  std::vector<armnn::BackendId> backends = { MockBackend().GetIdStatic() };
278  armnn::IOptimizedNetworkPtr optNet = armnn::Optimize(*net, backends, runtime->GetDeviceSpec());
279  CHECK(optNet);
280 
281  // Check the optimised graph
282  armnn::Graph& graph = GetGraphForTesting(optNet.get());
283  CheckLayers(graph);
284 }
285 
286 }
static IRuntimePtr Create(const CreationOptions &options)
Definition: Runtime.cpp:40
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
Definition: INetwork.hpp:66
LayerT * AddLayer(Args &&... args)
Adds a new layer, of type LayerType, to the graph constructed with the arguments passed.
Definition: Graph.hpp:420
A Convolution2dDescriptor for the Convolution2dLayer.
int Connect(InputSlot &destination)
Definition: Layer.cpp:86
std::unique_ptr< IRuntime, void(*)(IRuntime *runtime)> IRuntimePtr
Definition: IRuntime.hpp:31
void CheckLayers(Graph &graph)
void AddSubstitution(SubstitutionPair &&substitution)
Private implementation of INetwork.
Definition: Network.hpp:31
virtual void SetTensorInfo(const TensorInfo &tensorInfo)=0
std::unique_ptr< void, CompiledBlobDeleter > CompiledBlobPtr
Definition: INetwork.hpp:245
The SubgraphView class represents a subgraph of a Graph.
const InputSlot & GetInputSlot(unsigned int index) const override
Get a const input slot handle by slot index.
Definition: Layer.hpp:321
A layer user-provided data can be bound to (e.g. inputs, outputs).
Definition: OutputLayer.hpp:13
IOptimizedNetworkPtr Optimize(const INetwork &network, const std::vector< BackendId > &backendPreferences, const IDeviceSpec &deviceSpec, const OptimizerOptions &options=OptimizerOptions(), Optional< std::vector< std::string > &> messages=EmptyOptional())
Create an optimized version of the network.
Definition: Network.cpp:1680
SubgraphView::InputSlots CreateInputsFrom(const std::vector< Layer *> &layers)
static const BackendId & GetIdStatic()
Definition: MockBackend.cpp:18
A tensor defined by a TensorInfo (shape and data type) and an immutable backing store.
Definition: Tensor.hpp:327
void AddFailedSubgraph(SubgraphView &&subgraph)
std::unique_ptr< IOptimizedNetwork, void(*)(IOptimizedNetwork *network)> IOptimizedNetworkPtr
Definition: INetwork.hpp:242
bool Validate(const SubgraphView &originalSubgraph) const
void AddUntouchedSubgraph(SubgraphView &&subgraph)
void SubstituteSubgraph(SubgraphView &subgraph, IConnectableLayer *substituteLayer)
Substitutes the given sub-graph with either a new layer or a new sub-graph.
Definition: Graph.cpp:433
Graph & GetGraphForTesting(IOptimizedNetwork *optNet)
Definition: TestUtils.cpp:47
std::unique_ptr< SubgraphView > SubgraphViewPtr
SubgraphView::SubgraphViewPtr CreateSubgraphViewFrom(SubgraphView::InputSlots &&inputs, SubgraphView::OutputSlots &&outputs, SubgraphView::Layers &&layers)
SubgraphView::OutputSlots CreateOutputsFrom(const std::vector< Layer *> &layers)
A layer user-provided data can be bound to (e.g. inputs, outputs).
Definition: InputLayer.hpp:13
virtual const IInputSlot & GetInputSlot(unsigned int index) const =0
Get a const input slot handle by slot index.
const OutputSlot & GetOutputSlot(unsigned int index=0) const override
Get the const output slot handle by slot index.
Definition: Layer.hpp:323
virtual const IOutputSlot & GetOutputSlot(unsigned int index) const =0
Get the const output slot handle by slot index.
This layer represents a convolution 2d operation.
std::unique_ptr< INetwork, void(*)(INetwork *network)> INetworkPtr
Definition: INetwork.hpp:241
virtual int Connect(IInputSlot &destination)=0
A PreCompiledDescriptor for the PreCompiledLayer.
static INetworkPtr Create(NetworkOptions networkOptions={})
Definition: Network.cpp:492
A DepthwiseConvolution2dDescriptor for the DepthwiseConvolution2dLayer.