ArmNN
 21.11
OptimizationViewsTests.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 
7 #include "CommonTestUtils.hpp"
8 #include "MockBackend.hpp"
9 
12 #include <Graph.hpp>
13 #include <Network.hpp>
14 #include <SubgraphView.hpp>
15 #include <SubgraphViewSelector.hpp>
16 
17 #include <doctest/doctest.h>
18 
19 using namespace armnn;
20 
21 void CheckLayers(Graph& graph)
22 {
23  unsigned int m_inputLayerCount = 0, m_outputLayerCount = 0, m_addLayerCount = 0;
24  for(auto layer : graph)
25  {
26  switch(layer->GetType())
27  {
28  case LayerType::Input:
29  ++m_inputLayerCount;
30  CHECK((layer->GetName() == std::string("inLayer0") ||
31  layer->GetName() == std::string("inLayer1")));
32  break;
33  // The Addition layer should become a PreCompiled Layer after Optimisation
35  ++m_addLayerCount;
36  CHECK(std::string(layer->GetName()) == "pre-compiled");
37  break;
38  case LayerType::Output:
39  ++m_outputLayerCount;
40  CHECK(std::string(layer->GetName()) == "outLayer");
41  break;
42  default:
43  //Fail for anything else
44  CHECK(false);
45  }
46  }
47  CHECK(m_inputLayerCount == 2);
48  CHECK(m_outputLayerCount == 1);
49  CHECK(m_addLayerCount == 1);
50 }
51 
52 TEST_SUITE("OptimizationViewsTestSuite")
53 {
54 TEST_CASE("OptimizedViewsSubgraphLayerCount")
55 {
56  OptimizationViews view;
57  // Construct a graph with 3 layers
58  Graph& baseGraph = view.GetGraph();
59 
60  Layer* const inputLayer = baseGraph.AddLayer<InputLayer>(0, "input");
61 
62  Convolution2dDescriptor convDescriptor;
63  PreCompiledDescriptor substitutionLayerDescriptor(1, 1);
64  Layer* const convLayer1 = baseGraph.AddLayer<Convolution2dLayer>(convDescriptor, "conv1");
65  Layer* const convLayer2 = baseGraph.AddLayer<Convolution2dLayer>(convDescriptor, "conv2");
66  Layer* const substitutableCompiledLayer =
67  baseGraph.AddLayer<PreCompiledLayer>(substitutionLayerDescriptor, "pre-compiled");
68 
69  Layer* const outputLayer = baseGraph.AddLayer<OutputLayer>(0, "output");
70 
71  inputLayer->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(0));
72  convLayer1->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(0));
73  convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
74 
75  // Subgraph for a failed layer
78  CreateOutputsFrom({convLayer1}),
79  {convLayer1});
80  // Subgraph for an untouched layer
81  SubgraphViewSelector::SubgraphViewPtr untouchedSubgraph =
83  CreateOutputsFrom({convLayer2}),
84  {convLayer2});
85  // Subgraph for a substitutable layer
86  SubgraphViewSelector::SubgraphViewPtr substitutableSubgraph =
88  CreateOutputsFrom({convLayer2}),
89  {substitutableCompiledLayer});
90  // Create a Graph containing a layer to substitute in
91  Graph substitutableGraph;
92  Layer* const substitutionpreCompiledLayer =
93  substitutableGraph.AddLayer<PreCompiledLayer>(substitutionLayerDescriptor, "pre-compiled");
94 
95  // Subgraph for a substitution layer
96  SubgraphViewSelector::SubgraphViewPtr substitutionSubgraph =
97  CreateSubgraphViewFrom(CreateInputsFrom({substitutionpreCompiledLayer}),
98  CreateOutputsFrom({substitutionpreCompiledLayer}),
99  {substitutionpreCompiledLayer});
100 
101  // Sub in the graph
102  baseGraph.SubstituteSubgraph(*substitutableSubgraph, *substitutionSubgraph);
103 
104  view.AddFailedSubgraph(SubgraphView(*failedSubgraph));
105  view.AddUntouchedSubgraph(SubgraphView(*untouchedSubgraph));
106 
109  CreateOutputsFrom({convLayer2}),
110  {substitutionpreCompiledLayer});
111  view.AddSubstitution({*baseSubgraph, *substitutionSubgraph});
112 
113  // Construct original subgraph to compare against
114  SubgraphViewSelector::SubgraphViewPtr originalSubgraph =
116  CreateOutputsFrom({convLayer2}),
117  {convLayer1, convLayer2, substitutionpreCompiledLayer});
118 
119  CHECK(view.Validate(*originalSubgraph));
120 }
121 
122 TEST_CASE("OptimizedViewsSubgraphLayerCountFailValidate")
123 {
124  OptimizationViews view;
125  // Construct a graph with 3 layers
126  Graph& baseGraph = view.GetGraph();
127 
128  Layer* const inputLayer = baseGraph.AddLayer<InputLayer>(0, "input");
129 
130  Convolution2dDescriptor convDescriptor;
131  PreCompiledDescriptor substitutionLayerDescriptor(1, 1);
132  Layer* const convLayer1 = baseGraph.AddLayer<Convolution2dLayer>(convDescriptor, "conv1");
133  Layer* const convLayer2 = baseGraph.AddLayer<Convolution2dLayer>(convDescriptor, "conv2");
134  Layer* const substitutableCompiledLayer =
135  baseGraph.AddLayer<PreCompiledLayer>(substitutionLayerDescriptor, "pre-compiled");
136 
137  Layer* const outputLayer = baseGraph.AddLayer<OutputLayer>(0, "output");
138 
139  inputLayer->GetOutputSlot(0).Connect(convLayer1->GetInputSlot(0));
140  convLayer1->GetOutputSlot(0).Connect(convLayer2->GetInputSlot(0));
141  convLayer2->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
142 
143  // Subgraph for an untouched layer
144  SubgraphViewSelector::SubgraphViewPtr untouchedSubgraph =
146  CreateOutputsFrom({convLayer2}),
147  {convLayer2});
148  // Subgraph for a substitutable layer
149  SubgraphViewSelector::SubgraphViewPtr substitutableSubgraph =
151  CreateOutputsFrom({convLayer2}),
152  {substitutableCompiledLayer});
153  // Create a Graph containing a layer to substitute in
154  Graph substitutableGraph;
155  Layer* const substitutionpreCompiledLayer =
156  substitutableGraph.AddLayer<PreCompiledLayer>(substitutionLayerDescriptor, "pre-compiled");
157 
158  // Subgraph for a substitution layer
159  SubgraphViewSelector::SubgraphViewPtr substitutionSubgraph =
160  CreateSubgraphViewFrom(CreateInputsFrom({substitutionpreCompiledLayer}),
161  CreateOutputsFrom({substitutionpreCompiledLayer}),
162  {substitutionpreCompiledLayer});
163 
164  // Sub in the graph
165  baseGraph.SubstituteSubgraph(*substitutableSubgraph, *substitutionSubgraph);
166 
167  view.AddUntouchedSubgraph(SubgraphView(*untouchedSubgraph));
168 
171  CreateOutputsFrom({convLayer2}),
172  {substitutionpreCompiledLayer});
173  view.AddSubstitution({*baseSubgraph, *substitutionSubgraph});
174 
175  // Construct original subgraph to compare against
176  SubgraphViewSelector::SubgraphViewPtr originalSubgraph =
178  CreateOutputsFrom({convLayer2}),
179  {convLayer1, convLayer2, substitutionpreCompiledLayer});
180 
181  // Validate should fail as convLayer1 is not counted
182  CHECK(!view.Validate(*originalSubgraph));
183 }
184 
185 TEST_CASE("OptimizeViewsValidateDeviceMockBackend")
186 {
187  // build up the structure of the network
189 
190  armnn::IConnectableLayer* input = net->AddInputLayer(0, "inLayer0");
191  armnn::IConnectableLayer* input1 = net->AddInputLayer(1, "inLayer1");
192 
193  armnn::IConnectableLayer* addition = net->AddAdditionLayer("addLayer");
194 
195  armnn::IConnectableLayer* output = net->AddOutputLayer(0, "outLayer");
196 
197  input->GetOutputSlot(0).Connect(addition->GetInputSlot(0));
198  input1->GetOutputSlot(0).Connect(addition->GetInputSlot(1));
199  addition->GetOutputSlot(0).Connect(output->GetInputSlot(0));
200 
204 
205  armnn::MockBackendInitialiser initialiser;
208 
209  std::vector<armnn::BackendId> backends = { MockBackend().GetIdStatic() };
210  armnn::IOptimizedNetworkPtr optNet = armnn::Optimize(*net, backends, runtime->GetDeviceSpec());
211  CHECK(optNet);
212 
213  // Check the optimised graph
214  armnn::Graph& graph = GetGraphForTesting(optNet.get());
215  CheckLayers(graph);
216 }
217 
218 }
TEST_SUITE("TestConstTensorLayerVisitor")
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:61
LayerT * AddLayer(Args &&... args)
Adds a new layer, of type LayerType, to the graph constructed with the arguments passed.
Definition: Graph.hpp:417
A Convolution2dDescriptor for the Convolution2dLayer.
int Connect(InputSlot &destination)
Definition: Layer.cpp:83
std::unique_ptr< IRuntime, void(*)(IRuntime *runtime)> IRuntimePtr
Definition: IRuntime.hpp:31
void CheckLayers(Graph &graph)
void AddSubstitution(SubstitutionPair &&substitution)
Copyright (c) 2021 ARM Limited and Contributors.
virtual void SetTensorInfo(const TensorInfo &tensorInfo)=0
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:316
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:1605
SubgraphView::InputSlots CreateInputsFrom(const std::vector< Layer *> &layers)
static const BackendId & GetIdStatic()
Definition: MockBackend.cpp:89
void AddFailedSubgraph(SubgraphView &&subgraph)
std::unique_ptr< IOptimizedNetwork, void(*)(IOptimizedNetwork *network)> IOptimizedNetworkPtr
Definition: INetwork.hpp:198
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:434
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:318
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:197
virtual int Connect(IInputSlot &destination)=0
A PreCompiledDescriptor for the PreCompiledLayer.
static INetworkPtr Create(NetworkOptions networkOptions={})
Definition: Network.cpp:478