ArmNN
 21.11
CompatibilityTests.cpp File Reference
#include <cl/ClBackend.hpp>
#include <neon/NeonBackend.hpp>
#include <reference/RefBackend.hpp>
#include <armnn/BackendHelper.hpp>
#include <Network.hpp>
#include <doctest/doctest.h>
#include <vector>
#include <string>

Go to the source code of this file.

Functions

 TEST_SUITE ("BackendsCompatibility")
 
 TEST_SUITE ("BackendCapability")
 

Function Documentation

◆ TEST_SUITE() [1/2]

TEST_SUITE ( "BackendsCompatibility"  )

Definition at line 26 of file CompatibilityTests.cpp.

References Graph::AddCompatibilityLayers(), Graph::AddLayer(), OutputSlot::Connect(), Graph::ForEachLayer(), Layer::GetInputSlot(), Layer::GetOutputSlot(), Layer::GetType(), armnn::MemCopy, armnn::MemImport, armnn::SelectTensorHandleStrategy(), Layer::SetBackendId(), and Graph::TopologicalSort().

27 {
28 // Partially disabled Test Suite
29 TEST_CASE("Neon_Cl_DirectCompatibility_Test")
30 {
31  auto neonBackend = std::make_unique<NeonBackend>();
32  auto clBackend = std::make_unique<ClBackend>();
33 
35  neonBackend->RegisterTensorHandleFactories(registry);
36  clBackend->RegisterTensorHandleFactories(registry);
37 
38  const BackendId& neonBackendId = neonBackend->GetId();
39  const BackendId& clBackendId = clBackend->GetId();
40 
41  BackendsMap backends;
42  backends[neonBackendId] = std::move(neonBackend);
43  backends[clBackendId] = std::move(clBackend);
44 
45  armnn::Graph graph;
46 
47  armnn::InputLayer* const inputLayer = graph.AddLayer<armnn::InputLayer>(0, "input");
48 
49  inputLayer->SetBackendId(neonBackendId);
50 
52  armnn::SoftmaxLayer* const softmaxLayer1 = graph.AddLayer<armnn::SoftmaxLayer>(smDesc, "softmax1");
53  softmaxLayer1->SetBackendId(clBackendId);
54 
55  armnn::SoftmaxLayer* const softmaxLayer2 = graph.AddLayer<armnn::SoftmaxLayer>(smDesc, "softmax2");
56  softmaxLayer2->SetBackendId(neonBackendId);
57 
58  armnn::SoftmaxLayer* const softmaxLayer3 = graph.AddLayer<armnn::SoftmaxLayer>(smDesc, "softmax3");
59  softmaxLayer3->SetBackendId(clBackendId);
60 
61  armnn::SoftmaxLayer* const softmaxLayer4 = graph.AddLayer<armnn::SoftmaxLayer>(smDesc, "softmax4");
62  softmaxLayer4->SetBackendId(neonBackendId);
63 
64  armnn::OutputLayer* const outputLayer = graph.AddLayer<armnn::OutputLayer>(0, "output");
65  outputLayer->SetBackendId(clBackendId);
66 
67  inputLayer->GetOutputSlot(0).Connect(softmaxLayer1->GetInputSlot(0));
68  softmaxLayer1->GetOutputSlot(0).Connect(softmaxLayer2->GetInputSlot(0));
69  softmaxLayer2->GetOutputSlot(0).Connect(softmaxLayer3->GetInputSlot(0));
70  softmaxLayer3->GetOutputSlot(0).Connect(softmaxLayer4->GetInputSlot(0));
71  softmaxLayer4->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
72 
73  graph.TopologicalSort();
74 
75  std::vector<std::string> errors;
76  auto result = SelectTensorHandleStrategy(graph, backends, registry, true, errors);
77 
78  CHECK(result.m_Error == false);
79  CHECK(result.m_Warning == false);
80 
81  // OutputSlot& inputLayerOut = inputLayer->GetOutputSlot(0);
82  // OutputSlot& softmaxLayer1Out = softmaxLayer1->GetOutputSlot(0);
83  // OutputSlot& softmaxLayer2Out = softmaxLayer2->GetOutputSlot(0);
84  // OutputSlot& softmaxLayer3Out = softmaxLayer3->GetOutputSlot(0);
85  // OutputSlot& softmaxLayer4Out = softmaxLayer4->GetOutputSlot(0);
86 
87  // // Check that the correct factory was selected
88  // CHECK(inputLayerOut.GetTensorHandleFactoryId() == "Arm/Cl/TensorHandleFactory");
89  // CHECK(softmaxLayer1Out.GetTensorHandleFactoryId() == "Arm/Cl/TensorHandleFactory");
90  // CHECK(softmaxLayer2Out.GetTensorHandleFactoryId() == "Arm/Cl/TensorHandleFactory");
91  // CHECK(softmaxLayer3Out.GetTensorHandleFactoryId() == "Arm/Cl/TensorHandleFactory");
92  // CHECK(softmaxLayer4Out.GetTensorHandleFactoryId() == "Arm/Cl/TensorHandleFactory");
93 
94  // // Check that the correct strategy was selected
95  // CHECK((inputLayerOut.GetEdgeStrategyForConnection(0) == EdgeStrategy::DirectCompatibility));
96  // CHECK((softmaxLayer1Out.GetEdgeStrategyForConnection(0) == EdgeStrategy::DirectCompatibility));
97  // CHECK((softmaxLayer2Out.GetEdgeStrategyForConnection(0) == EdgeStrategy::DirectCompatibility));
98  // CHECK((softmaxLayer3Out.GetEdgeStrategyForConnection(0) == EdgeStrategy::DirectCompatibility));
99  // CHECK((softmaxLayer4Out.GetEdgeStrategyForConnection(0) == EdgeStrategy::DirectCompatibility));
100 
101  graph.AddCompatibilityLayers(backends, registry);
102 
103  // Test for copy layers
104  int copyCount= 0;
105  graph.ForEachLayer([&copyCount](Layer* layer)
106  {
107  if (layer->GetType() == LayerType::MemCopy)
108  {
109  copyCount++;
110  }
111  });
112  // CHECK(copyCount == 0);
113 
114  // Test for import layers
115  int importCount= 0;
116  graph.ForEachLayer([&importCount](Layer *layer)
117  {
118  if (layer->GetType() == LayerType::MemImport)
119  {
120  importCount++;
121  }
122  });
123  // CHECK(importCount == 0);
124 }
125 
126 }
LayerT * AddLayer(Args &&... args)
Adds a new layer, of type LayerType, to the graph constructed with the arguments passed.
Definition: Graph.hpp:417
int Connect(InputSlot &destination)
Definition: Layer.cpp:83
void SetBackendId(const BackendId &id)
Definition: Layer.hpp:270
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
void ForEachLayer(Func func) const
Definition: Graph.hpp:40
This layer represents a softmax operation.
LayerType GetType() const override
Returns the armnn::LayerType of this layer.
Definition: Layer.hpp:265
A layer user-provided data can be bound to (e.g. inputs, outputs).
Definition: InputLayer.hpp:13
const OutputSlot & GetOutputSlot(unsigned int index=0) const override
Get the const output slot handle by slot index.
Definition: Layer.hpp:318
OptimizationResult SelectTensorHandleStrategy(Graph &optGraph, BackendsMap &backends, TensorHandleFactoryRegistry &registry, bool importEnabled, Optional< std::vector< std::string > &> errMessages)
Definition: Network.cpp:1536
Graph & TopologicalSort()
Sorts layers in topological order and return this.
Definition: Graph.hpp:180
A SoftmaxDescriptor for the SoftmaxLayer.
void AddCompatibilityLayers(std::map< BackendId, std::unique_ptr< class IBackendInternal >> &backends, TensorHandleFactoryRegistry &registry)
Modifies the graph in-place, removing edges connecting layers using different compute devices...
Definition: Graph.cpp:302
std::map< BackendId, std::unique_ptr< class IBackendInternal > > BackendsMap
Definition: Network.hpp:279

◆ TEST_SUITE() [2/2]

TEST_SUITE ( "BackendCapability"  )

Definition at line 129 of file CompatibilityTests.cpp.

References armnn::HasCapability().

130 {
131 
132 namespace
133 {
134 
135 #if defined(ARMNNREF_ENABLED) || defined(ARMCOMPUTENEON_ENABLED) || defined(ARMCOMPUTECL_ENABLED)
136 void CapabilityTestHelper(BackendCapabilities &capabilities,
137  std::vector<std::pair<std::string, bool>> capabilityVector)
138 {
139  for (auto pair : capabilityVector)
140  {
141  CHECK_MESSAGE(armnn::HasCapability(pair.first, capabilities),
142  pair.first << " capability was not been found");
143  CHECK_MESSAGE(armnn::HasCapability(BackendOptions::BackendOption{pair.first, pair.second}, capabilities),
144  pair.first << " capability set incorrectly");
145  }
146 }
147 #endif
148 
149 #if defined(ARMNNREF_ENABLED)
150 
151 TEST_CASE("Ref_Backends_Unknown_Capability_Test")
152 {
153  auto refBackend = std::make_unique<RefBackend>();
154  auto refCapabilities = refBackend->GetCapabilities();
155 
156  armnn::BackendOptions::BackendOption AsyncExecutionFalse{"AsyncExecution", false};
157  CHECK(!armnn::HasCapability(AsyncExecutionFalse, refCapabilities));
158 
159  armnn::BackendOptions::BackendOption AsyncExecutionInt{"AsyncExecution", 50};
160  CHECK(!armnn::HasCapability(AsyncExecutionFalse, refCapabilities));
161 
162  armnn::BackendOptions::BackendOption AsyncExecutionFloat{"AsyncExecution", 0.0f};
163  CHECK(!armnn::HasCapability(AsyncExecutionFloat, refCapabilities));
164 
165  armnn::BackendOptions::BackendOption AsyncExecutionString{"AsyncExecution", "true"};
166  CHECK(!armnn::HasCapability(AsyncExecutionString, refCapabilities));
167 
168  CHECK(!armnn::HasCapability("Telekinesis", refCapabilities));
169  armnn::BackendOptions::BackendOption unknownCapability{"Telekinesis", true};
170  CHECK(!armnn::HasCapability(unknownCapability, refCapabilities));
171 }
172 
173 TEST_CASE ("Ref_Backends_Capability_Test")
174 {
175  auto refBackend = std::make_unique<RefBackend>();
176  auto refCapabilities = refBackend->GetCapabilities();
177 
178  CapabilityTestHelper(refCapabilities,
179  {{"NonConstWeights", true},
180  {"AsyncExecution", true},
181  {"ProtectedContentAllocation", false},
182  {"ConstantTensorsAsInputs", true},
183  {"PreImportIOTensors", true},
184  {"ExternallyManagedMemory", true},
185  {"MultiAxisPacking", false}});
186 }
187 
188 #endif
189 
190 #if defined(ARMCOMPUTENEON_ENABLED)
191 
192 TEST_CASE ("Neon_Backends_Capability_Test")
193 {
194  auto neonBackend = std::make_unique<NeonBackend>();
195  auto neonCapabilities = neonBackend->GetCapabilities();
196 
197  CapabilityTestHelper(neonCapabilities,
198  {{"NonConstWeights", false},
199  {"AsyncExecution", false},
200  {"ProtectedContentAllocation", false},
201  {"ConstantTensorsAsInputs", false},
202  {"PreImportIOTensors", false},
203  {"ExternallyManagedMemory", true},
204  {"MultiAxisPacking", false}});
205 }
206 
207 #endif
208 
209 #if defined(ARMCOMPUTECL_ENABLED)
210 
211 TEST_CASE ("Cl_Backends_Capability_Test")
212 {
213  auto clBackend = std::make_unique<ClBackend>();
214  auto clCapabilities = clBackend->GetCapabilities();
215 
216  CapabilityTestHelper(clCapabilities,
217  {{"NonConstWeights", false},
218  {"AsyncExecution", false},
219  {"ProtectedContentAllocation", true},
220  {"ConstantTensorsAsInputs", false},
221  {"PreImportIOTensors", false},
222  {"ExternallyManagedMemory", true},
223  {"MultiAxisPacking", false}});
224 }
225 
226 #endif
227 }
228 }
bool HasCapability(const std::string &name, const BackendCapabilities &capabilities)
Convenience function to check if a capability exists in a BackendCapabilites struct.
Struct for the users to pass backend specific options.