xref: /aosp_15_r20/external/armnn/src/armnnTestUtils/MockBackend.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1*89c4ff92SAndroid Build Coastguard Worker //
2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved.
3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
4*89c4ff92SAndroid Build Coastguard Worker //
5*89c4ff92SAndroid Build Coastguard Worker 
6*89c4ff92SAndroid Build Coastguard Worker #include <armnn/BackendRegistry.hpp>
7*89c4ff92SAndroid Build Coastguard Worker #include <armnn/backends/MemCopyWorkload.hpp>
8*89c4ff92SAndroid Build Coastguard Worker #include <armnnTestUtils/MockBackend.hpp>
9*89c4ff92SAndroid Build Coastguard Worker #include <armnnTestUtils/MockTensorHandle.hpp>
10*89c4ff92SAndroid Build Coastguard Worker #include <backendsCommon/DefaultAllocator.hpp>
11*89c4ff92SAndroid Build Coastguard Worker #include <backendsCommon/test/MockBackendId.hpp>
12*89c4ff92SAndroid Build Coastguard Worker #include <SubgraphViewSelector.hpp>
13*89c4ff92SAndroid Build Coastguard Worker 
14*89c4ff92SAndroid Build Coastguard Worker #include "Layer.hpp"
15*89c4ff92SAndroid Build Coastguard Worker 
16*89c4ff92SAndroid Build Coastguard Worker namespace armnn
17*89c4ff92SAndroid Build Coastguard Worker {
18*89c4ff92SAndroid Build Coastguard Worker 
GetIdStatic()19*89c4ff92SAndroid Build Coastguard Worker const BackendId& MockBackend::GetIdStatic()
20*89c4ff92SAndroid Build Coastguard Worker {
21*89c4ff92SAndroid Build Coastguard Worker     static const BackendId s_Id{MockBackendId()};
22*89c4ff92SAndroid Build Coastguard Worker     return s_Id;
23*89c4ff92SAndroid Build Coastguard Worker }
24*89c4ff92SAndroid Build Coastguard Worker 
25*89c4ff92SAndroid Build Coastguard Worker namespace
26*89c4ff92SAndroid Build Coastguard Worker {
27*89c4ff92SAndroid Build Coastguard Worker static const BackendId s_Id{ MockBackendId() };
28*89c4ff92SAndroid Build Coastguard Worker }
29*89c4ff92SAndroid Build Coastguard Worker 
MockWorkloadFactory(const std::shared_ptr<MockMemoryManager> & memoryManager)30*89c4ff92SAndroid Build Coastguard Worker MockWorkloadFactory::MockWorkloadFactory(const std::shared_ptr<MockMemoryManager>& memoryManager)
31*89c4ff92SAndroid Build Coastguard Worker     : m_MemoryManager(memoryManager)
32*89c4ff92SAndroid Build Coastguard Worker {}
33*89c4ff92SAndroid Build Coastguard Worker 
MockWorkloadFactory()34*89c4ff92SAndroid Build Coastguard Worker MockWorkloadFactory::MockWorkloadFactory()
35*89c4ff92SAndroid Build Coastguard Worker     : m_MemoryManager(new MockMemoryManager())
36*89c4ff92SAndroid Build Coastguard Worker {}
37*89c4ff92SAndroid Build Coastguard Worker 
GetBackendId() const38*89c4ff92SAndroid Build Coastguard Worker const BackendId& MockWorkloadFactory::GetBackendId() const
39*89c4ff92SAndroid Build Coastguard Worker {
40*89c4ff92SAndroid Build Coastguard Worker     return s_Id;
41*89c4ff92SAndroid Build Coastguard Worker }
42*89c4ff92SAndroid Build Coastguard Worker 
CreateWorkload(LayerType type,const QueueDescriptor & descriptor,const WorkloadInfo & info) const43*89c4ff92SAndroid Build Coastguard Worker std::unique_ptr<IWorkload> MockWorkloadFactory::CreateWorkload(LayerType type,
44*89c4ff92SAndroid Build Coastguard Worker                                                                const QueueDescriptor& descriptor,
45*89c4ff92SAndroid Build Coastguard Worker                                                                const WorkloadInfo& info) const
46*89c4ff92SAndroid Build Coastguard Worker {
47*89c4ff92SAndroid Build Coastguard Worker     switch (type)
48*89c4ff92SAndroid Build Coastguard Worker     {
49*89c4ff92SAndroid Build Coastguard Worker         case LayerType::MemCopy: {
50*89c4ff92SAndroid Build Coastguard Worker             auto memCopyQueueDescriptor = PolymorphicDowncast<const MemCopyQueueDescriptor*>(&descriptor);
51*89c4ff92SAndroid Build Coastguard Worker             if (descriptor.m_Inputs.empty())
52*89c4ff92SAndroid Build Coastguard Worker             {
53*89c4ff92SAndroid Build Coastguard Worker                 throw InvalidArgumentException("MockWorkloadFactory: CreateMemCopy() expected an input tensor.");
54*89c4ff92SAndroid Build Coastguard Worker             }
55*89c4ff92SAndroid Build Coastguard Worker             return std::make_unique<CopyMemGenericWorkload>(*memCopyQueueDescriptor, info);
56*89c4ff92SAndroid Build Coastguard Worker         }
57*89c4ff92SAndroid Build Coastguard Worker         default:
58*89c4ff92SAndroid Build Coastguard Worker             return nullptr;
59*89c4ff92SAndroid Build Coastguard Worker     }
60*89c4ff92SAndroid Build Coastguard Worker }
61*89c4ff92SAndroid Build Coastguard Worker 
IsLayerSupported(const armnn::Layer * layer)62*89c4ff92SAndroid Build Coastguard Worker bool IsLayerSupported(const armnn::Layer* layer)
63*89c4ff92SAndroid Build Coastguard Worker {
64*89c4ff92SAndroid Build Coastguard Worker     ARMNN_ASSERT(layer != nullptr);
65*89c4ff92SAndroid Build Coastguard Worker 
66*89c4ff92SAndroid Build Coastguard Worker     armnn::LayerType layerType = layer->GetType();
67*89c4ff92SAndroid Build Coastguard Worker     switch (layerType)
68*89c4ff92SAndroid Build Coastguard Worker     {
69*89c4ff92SAndroid Build Coastguard Worker         case armnn::LayerType::Input:
70*89c4ff92SAndroid Build Coastguard Worker         case armnn::LayerType::Output:
71*89c4ff92SAndroid Build Coastguard Worker         case armnn::LayerType::Constant:
72*89c4ff92SAndroid Build Coastguard Worker         case armnn::LayerType::Addition:
73*89c4ff92SAndroid Build Coastguard Worker         case armnn::LayerType::Convolution2d:
74*89c4ff92SAndroid Build Coastguard Worker         case armnn::LayerType::ElementwiseBinary:
75*89c4ff92SAndroid Build Coastguard Worker             // Layer supported
76*89c4ff92SAndroid Build Coastguard Worker             return true;
77*89c4ff92SAndroid Build Coastguard Worker         default:
78*89c4ff92SAndroid Build Coastguard Worker             // Layer unsupported
79*89c4ff92SAndroid Build Coastguard Worker             return false;
80*89c4ff92SAndroid Build Coastguard Worker     }
81*89c4ff92SAndroid Build Coastguard Worker }
82*89c4ff92SAndroid Build Coastguard Worker 
IsLayerSupported(const armnn::Layer & layer)83*89c4ff92SAndroid Build Coastguard Worker bool IsLayerSupported(const armnn::Layer& layer)
84*89c4ff92SAndroid Build Coastguard Worker {
85*89c4ff92SAndroid Build Coastguard Worker     return IsLayerSupported(&layer);
86*89c4ff92SAndroid Build Coastguard Worker }
87*89c4ff92SAndroid Build Coastguard Worker 
IsLayerOptimizable(const armnn::Layer * layer)88*89c4ff92SAndroid Build Coastguard Worker bool IsLayerOptimizable(const armnn::Layer* layer)
89*89c4ff92SAndroid Build Coastguard Worker {
90*89c4ff92SAndroid Build Coastguard Worker     ARMNN_ASSERT(layer != nullptr);
91*89c4ff92SAndroid Build Coastguard Worker 
92*89c4ff92SAndroid Build Coastguard Worker     // A Layer is not optimizable if its name contains "unoptimizable"
93*89c4ff92SAndroid Build Coastguard Worker     const std::string layerName(layer->GetName());
94*89c4ff92SAndroid Build Coastguard Worker     bool optimizable = layerName.find("unoptimizable") == std::string::npos;
95*89c4ff92SAndroid Build Coastguard Worker 
96*89c4ff92SAndroid Build Coastguard Worker     return optimizable;
97*89c4ff92SAndroid Build Coastguard Worker }
98*89c4ff92SAndroid Build Coastguard Worker 
IsLayerOptimizable(const armnn::Layer & layer)99*89c4ff92SAndroid Build Coastguard Worker bool IsLayerOptimizable(const armnn::Layer& layer)
100*89c4ff92SAndroid Build Coastguard Worker {
101*89c4ff92SAndroid Build Coastguard Worker     return IsLayerOptimizable(&layer);
102*89c4ff92SAndroid Build Coastguard Worker }
103*89c4ff92SAndroid Build Coastguard Worker 
104*89c4ff92SAndroid Build Coastguard Worker } // Anonymous namespace
105*89c4ff92SAndroid Build Coastguard Worker 
106*89c4ff92SAndroid Build Coastguard Worker namespace armnn
107*89c4ff92SAndroid Build Coastguard Worker {
108*89c4ff92SAndroid Build Coastguard Worker 
MockBackendInitialiser()109*89c4ff92SAndroid Build Coastguard Worker MockBackendInitialiser::MockBackendInitialiser()
110*89c4ff92SAndroid Build Coastguard Worker {
111*89c4ff92SAndroid Build Coastguard Worker     BackendRegistryInstance().Register(MockBackend::GetIdStatic(),
112*89c4ff92SAndroid Build Coastguard Worker                                        []()
113*89c4ff92SAndroid Build Coastguard Worker                                        {
114*89c4ff92SAndroid Build Coastguard Worker                                            return IBackendInternalUniquePtr(new MockBackend);
115*89c4ff92SAndroid Build Coastguard Worker                                        });
116*89c4ff92SAndroid Build Coastguard Worker }
117*89c4ff92SAndroid Build Coastguard Worker 
~MockBackendInitialiser()118*89c4ff92SAndroid Build Coastguard Worker MockBackendInitialiser::~MockBackendInitialiser()
119*89c4ff92SAndroid Build Coastguard Worker {
120*89c4ff92SAndroid Build Coastguard Worker     try
121*89c4ff92SAndroid Build Coastguard Worker     {
122*89c4ff92SAndroid Build Coastguard Worker         BackendRegistryInstance().Deregister(MockBackend::GetIdStatic());
123*89c4ff92SAndroid Build Coastguard Worker     }
124*89c4ff92SAndroid Build Coastguard Worker     catch (...)
125*89c4ff92SAndroid Build Coastguard Worker     {
126*89c4ff92SAndroid Build Coastguard Worker         std::cerr << "could not deregister mock backend" << std::endl;
127*89c4ff92SAndroid Build Coastguard Worker     }
128*89c4ff92SAndroid Build Coastguard Worker }
129*89c4ff92SAndroid Build Coastguard Worker 
CreateWorkloadFactory(const IBackendInternal::IMemoryManagerSharedPtr &) const130*89c4ff92SAndroid Build Coastguard Worker IBackendInternal::IWorkloadFactoryPtr MockBackend::CreateWorkloadFactory(
131*89c4ff92SAndroid Build Coastguard Worker     const IBackendInternal::IMemoryManagerSharedPtr& /*memoryManager*/) const
132*89c4ff92SAndroid Build Coastguard Worker {
133*89c4ff92SAndroid Build Coastguard Worker     return IWorkloadFactoryPtr{};
134*89c4ff92SAndroid Build Coastguard Worker }
135*89c4ff92SAndroid Build Coastguard Worker 
CreateBackendContext(const IRuntime::CreationOptions &) const136*89c4ff92SAndroid Build Coastguard Worker IBackendInternal::IBackendContextPtr MockBackend::CreateBackendContext(const IRuntime::CreationOptions&) const
137*89c4ff92SAndroid Build Coastguard Worker {
138*89c4ff92SAndroid Build Coastguard Worker     return IBackendContextPtr{};
139*89c4ff92SAndroid Build Coastguard Worker }
140*89c4ff92SAndroid Build Coastguard Worker 
CreateBackendProfilingContext(const IRuntime::CreationOptions & options,IBackendProfilingPtr & backendProfiling)141*89c4ff92SAndroid Build Coastguard Worker IBackendInternal::IBackendProfilingContextPtr MockBackend::CreateBackendProfilingContext(
142*89c4ff92SAndroid Build Coastguard Worker     const IRuntime::CreationOptions& options, IBackendProfilingPtr& backendProfiling)
143*89c4ff92SAndroid Build Coastguard Worker {
144*89c4ff92SAndroid Build Coastguard Worker     IgnoreUnused(options);
145*89c4ff92SAndroid Build Coastguard Worker     std::shared_ptr<armnn::MockBackendProfilingContext> context =
146*89c4ff92SAndroid Build Coastguard Worker         std::make_shared<MockBackendProfilingContext>(backendProfiling);
147*89c4ff92SAndroid Build Coastguard Worker     MockBackendProfilingService::Instance().SetProfilingContextPtr(context);
148*89c4ff92SAndroid Build Coastguard Worker     return context;
149*89c4ff92SAndroid Build Coastguard Worker }
150*89c4ff92SAndroid Build Coastguard Worker 
CreateMemoryManager() const151*89c4ff92SAndroid Build Coastguard Worker IBackendInternal::IMemoryManagerUniquePtr MockBackend::CreateMemoryManager() const
152*89c4ff92SAndroid Build Coastguard Worker {
153*89c4ff92SAndroid Build Coastguard Worker     return IMemoryManagerUniquePtr{};
154*89c4ff92SAndroid Build Coastguard Worker }
155*89c4ff92SAndroid Build Coastguard Worker 
GetLayerSupport() const156*89c4ff92SAndroid Build Coastguard Worker IBackendInternal::ILayerSupportSharedPtr MockBackend::GetLayerSupport() const
157*89c4ff92SAndroid Build Coastguard Worker {
158*89c4ff92SAndroid Build Coastguard Worker     static ILayerSupportSharedPtr layerSupport{new MockLayerSupport};
159*89c4ff92SAndroid Build Coastguard Worker     return layerSupport;
160*89c4ff92SAndroid Build Coastguard Worker }
161*89c4ff92SAndroid Build Coastguard Worker 
OptimizeSubgraphView(const SubgraphView & subgraph) const162*89c4ff92SAndroid Build Coastguard Worker OptimizationViews MockBackend::OptimizeSubgraphView(const SubgraphView& subgraph) const
163*89c4ff92SAndroid Build Coastguard Worker {
164*89c4ff92SAndroid Build Coastguard Worker     // Prepare the optimization views
165*89c4ff92SAndroid Build Coastguard Worker     OptimizationViews optimizationViews;
166*89c4ff92SAndroid Build Coastguard Worker 
167*89c4ff92SAndroid Build Coastguard Worker     // Get the layers of the input sub-graph
168*89c4ff92SAndroid Build Coastguard Worker     const SubgraphView::IConnectableLayers& subgraphLayers = subgraph.GetIConnectableLayers();
169*89c4ff92SAndroid Build Coastguard Worker 
170*89c4ff92SAndroid Build Coastguard Worker     // Parse the layers
171*89c4ff92SAndroid Build Coastguard Worker     SubgraphView::IConnectableLayers supportedLayers;
172*89c4ff92SAndroid Build Coastguard Worker     SubgraphView::IConnectableLayers unsupportedLayers;
173*89c4ff92SAndroid Build Coastguard Worker     SubgraphView::IConnectableLayers untouchedLayers;
174*89c4ff92SAndroid Build Coastguard Worker     std::for_each(subgraphLayers.begin(),
175*89c4ff92SAndroid Build Coastguard Worker                   subgraphLayers.end(),
176*89c4ff92SAndroid Build Coastguard Worker                   [&](IConnectableLayer* layer)
177*89c4ff92SAndroid Build Coastguard Worker                   {
178*89c4ff92SAndroid Build Coastguard Worker                       bool supported = IsLayerSupported(PolymorphicDowncast<Layer*>(layer));
179*89c4ff92SAndroid Build Coastguard Worker                       if (supported)
180*89c4ff92SAndroid Build Coastguard Worker                       {
181*89c4ff92SAndroid Build Coastguard Worker                           // Layer supported, check if it's optimizable
182*89c4ff92SAndroid Build Coastguard Worker                           bool optimizable = IsLayerOptimizable(PolymorphicDowncast<Layer*>(layer));
183*89c4ff92SAndroid Build Coastguard Worker                           if (optimizable)
184*89c4ff92SAndroid Build Coastguard Worker                           {
185*89c4ff92SAndroid Build Coastguard Worker                               // Layer fully supported
186*89c4ff92SAndroid Build Coastguard Worker                               supportedLayers.push_back(layer);
187*89c4ff92SAndroid Build Coastguard Worker                           }
188*89c4ff92SAndroid Build Coastguard Worker                           else
189*89c4ff92SAndroid Build Coastguard Worker                           {
190*89c4ff92SAndroid Build Coastguard Worker                               // Layer supported but not optimizable
191*89c4ff92SAndroid Build Coastguard Worker                               untouchedLayers.push_back(layer);
192*89c4ff92SAndroid Build Coastguard Worker                           }
193*89c4ff92SAndroid Build Coastguard Worker                       }
194*89c4ff92SAndroid Build Coastguard Worker                       else
195*89c4ff92SAndroid Build Coastguard Worker                       {
196*89c4ff92SAndroid Build Coastguard Worker                           // Layer unsupported
197*89c4ff92SAndroid Build Coastguard Worker                           unsupportedLayers.push_back(layer);
198*89c4ff92SAndroid Build Coastguard Worker                       }
199*89c4ff92SAndroid Build Coastguard Worker                   });
200*89c4ff92SAndroid Build Coastguard Worker 
201*89c4ff92SAndroid Build Coastguard Worker     // Check if there are supported layers
202*89c4ff92SAndroid Build Coastguard Worker     if (!supportedLayers.empty())
203*89c4ff92SAndroid Build Coastguard Worker     {
204*89c4ff92SAndroid Build Coastguard Worker         // Select the layers that are neither inputs or outputs, but that are optimizable
205*89c4ff92SAndroid Build Coastguard Worker         auto supportedSubgraphSelector = [](const Layer& layer)
206*89c4ff92SAndroid Build Coastguard Worker         {
207*89c4ff92SAndroid Build Coastguard Worker             return layer.GetType() != LayerType::Input &&
208*89c4ff92SAndroid Build Coastguard Worker                 layer.GetType() != LayerType::Output &&
209*89c4ff92SAndroid Build Coastguard Worker                 IsLayerSupported(layer) &&
210*89c4ff92SAndroid Build Coastguard Worker                 IsLayerOptimizable(layer);
211*89c4ff92SAndroid Build Coastguard Worker         };
212*89c4ff92SAndroid Build Coastguard Worker 
213*89c4ff92SAndroid Build Coastguard Worker         // Apply the subgraph selector to the supported layers to group them into sub-graphs were appropriate
214*89c4ff92SAndroid Build Coastguard Worker         SubgraphView mutableSubgraph(subgraph);
215*89c4ff92SAndroid Build Coastguard Worker         SubgraphViewSelector::Subgraphs supportedSubgraphs =
216*89c4ff92SAndroid Build Coastguard Worker                          SubgraphViewSelector::SelectSubgraphs(mutableSubgraph, supportedSubgraphSelector);
217*89c4ff92SAndroid Build Coastguard Worker 
218*89c4ff92SAndroid Build Coastguard Worker         // Create a substitution pair for each supported sub-graph
219*89c4ff92SAndroid Build Coastguard Worker         std::for_each(supportedSubgraphs.begin(),
220*89c4ff92SAndroid Build Coastguard Worker                       supportedSubgraphs.end(),
221*89c4ff92SAndroid Build Coastguard Worker                       [&optimizationViews](const SubgraphView::SubgraphViewPtr& supportedSubgraph)
222*89c4ff92SAndroid Build Coastguard Worker                       {
223*89c4ff92SAndroid Build Coastguard Worker                           ARMNN_ASSERT(supportedSubgraph != nullptr);
224*89c4ff92SAndroid Build Coastguard Worker 
225*89c4ff92SAndroid Build Coastguard Worker                           CompiledBlobPtr blobPtr;
226*89c4ff92SAndroid Build Coastguard Worker                           BackendId backend = MockBackendId();
227*89c4ff92SAndroid Build Coastguard Worker 
228*89c4ff92SAndroid Build Coastguard Worker                           IConnectableLayer* preCompiledLayer =
229*89c4ff92SAndroid Build Coastguard Worker                                                optimizationViews.GetINetwork()->AddPrecompiledLayer(
230*89c4ff92SAndroid Build Coastguard Worker                                                    PreCompiledDescriptor(supportedSubgraph->GetNumInputSlots(),
231*89c4ff92SAndroid Build Coastguard Worker                                                                          supportedSubgraph->GetNumOutputSlots()),
232*89c4ff92SAndroid Build Coastguard Worker                                                    std::move(blobPtr),
233*89c4ff92SAndroid Build Coastguard Worker                                                    backend,
234*89c4ff92SAndroid Build Coastguard Worker                                                    nullptr);
235*89c4ff92SAndroid Build Coastguard Worker 
236*89c4ff92SAndroid Build Coastguard Worker                           SubgraphView substitutionSubgraph(*supportedSubgraph);
237*89c4ff92SAndroid Build Coastguard Worker                           SubgraphView replacementSubgraph(preCompiledLayer);
238*89c4ff92SAndroid Build Coastguard Worker 
239*89c4ff92SAndroid Build Coastguard Worker                           optimizationViews.AddSubstitution({ substitutionSubgraph, replacementSubgraph });
240*89c4ff92SAndroid Build Coastguard Worker                       });
241*89c4ff92SAndroid Build Coastguard Worker     }
242*89c4ff92SAndroid Build Coastguard Worker 
243*89c4ff92SAndroid Build Coastguard Worker     // Check if there are unsupported layers
244*89c4ff92SAndroid Build Coastguard Worker     if (!unsupportedLayers.empty())
245*89c4ff92SAndroid Build Coastguard Worker     {
246*89c4ff92SAndroid Build Coastguard Worker         // Select the layers that are neither inputs or outputs, and are not optimizable
247*89c4ff92SAndroid Build Coastguard Worker         auto unsupportedSubgraphSelector = [](const Layer& layer)
248*89c4ff92SAndroid Build Coastguard Worker         {
249*89c4ff92SAndroid Build Coastguard Worker             return layer.GetType() != LayerType::Input &&
250*89c4ff92SAndroid Build Coastguard Worker                 layer.GetType() != LayerType::Output &&
251*89c4ff92SAndroid Build Coastguard Worker                 !IsLayerSupported(layer);
252*89c4ff92SAndroid Build Coastguard Worker         };
253*89c4ff92SAndroid Build Coastguard Worker 
254*89c4ff92SAndroid Build Coastguard Worker         // Apply the subgraph selector to the unsupported layers to group them into sub-graphs were appropriate
255*89c4ff92SAndroid Build Coastguard Worker         SubgraphView mutableSubgraph(subgraph);
256*89c4ff92SAndroid Build Coastguard Worker         SubgraphViewSelector::Subgraphs unsupportedSubgraphs =
257*89c4ff92SAndroid Build Coastguard Worker                          SubgraphViewSelector::SelectSubgraphs(mutableSubgraph, unsupportedSubgraphSelector);
258*89c4ff92SAndroid Build Coastguard Worker 
259*89c4ff92SAndroid Build Coastguard Worker         // Add each unsupported sub-graph to the list of failed sub-graphs in the optimizization views
260*89c4ff92SAndroid Build Coastguard Worker         std::for_each(unsupportedSubgraphs.begin(),
261*89c4ff92SAndroid Build Coastguard Worker                       unsupportedSubgraphs.end(),
262*89c4ff92SAndroid Build Coastguard Worker                       [&optimizationViews](const SubgraphView::SubgraphViewPtr& unsupportedSubgraph)
263*89c4ff92SAndroid Build Coastguard Worker                       {
264*89c4ff92SAndroid Build Coastguard Worker                           ARMNN_ASSERT(unsupportedSubgraph != nullptr);
265*89c4ff92SAndroid Build Coastguard Worker 
266*89c4ff92SAndroid Build Coastguard Worker                           optimizationViews.AddFailedSubgraph(SubgraphView(*unsupportedSubgraph));
267*89c4ff92SAndroid Build Coastguard Worker                       });
268*89c4ff92SAndroid Build Coastguard Worker     }
269*89c4ff92SAndroid Build Coastguard Worker 
270*89c4ff92SAndroid Build Coastguard Worker     // Check if there are untouched layers
271*89c4ff92SAndroid Build Coastguard Worker     if (!untouchedLayers.empty())
272*89c4ff92SAndroid Build Coastguard Worker     {
273*89c4ff92SAndroid Build Coastguard Worker         // Select the layers that are neither inputs or outputs, that are supported but that and are not optimizable
274*89c4ff92SAndroid Build Coastguard Worker         auto untouchedSubgraphSelector = [](const Layer& layer)
275*89c4ff92SAndroid Build Coastguard Worker         {
276*89c4ff92SAndroid Build Coastguard Worker             return layer.GetType() != LayerType::Input &&
277*89c4ff92SAndroid Build Coastguard Worker                 layer.GetType() != LayerType::Output &&
278*89c4ff92SAndroid Build Coastguard Worker                 IsLayerSupported(layer) &&
279*89c4ff92SAndroid Build Coastguard Worker                 !IsLayerOptimizable(layer);
280*89c4ff92SAndroid Build Coastguard Worker         };
281*89c4ff92SAndroid Build Coastguard Worker 
282*89c4ff92SAndroid Build Coastguard Worker         // Apply the subgraph selector to the untouched layers to group them into sub-graphs were appropriate
283*89c4ff92SAndroid Build Coastguard Worker         SubgraphView mutableSubgraph(subgraph);
284*89c4ff92SAndroid Build Coastguard Worker         SubgraphViewSelector::Subgraphs untouchedSubgraphs =
285*89c4ff92SAndroid Build Coastguard Worker                          SubgraphViewSelector::SelectSubgraphs(mutableSubgraph, untouchedSubgraphSelector);
286*89c4ff92SAndroid Build Coastguard Worker 
287*89c4ff92SAndroid Build Coastguard Worker         // Add each untouched sub-graph to the list of untouched sub-graphs in the optimizization views
288*89c4ff92SAndroid Build Coastguard Worker         std::for_each(untouchedSubgraphs.begin(),
289*89c4ff92SAndroid Build Coastguard Worker                       untouchedSubgraphs.end(),
290*89c4ff92SAndroid Build Coastguard Worker                       [&optimizationViews](const SubgraphView::SubgraphViewPtr& untouchedSubgraph)
291*89c4ff92SAndroid Build Coastguard Worker                       {
292*89c4ff92SAndroid Build Coastguard Worker                           ARMNN_ASSERT(untouchedSubgraph != nullptr);
293*89c4ff92SAndroid Build Coastguard Worker 
294*89c4ff92SAndroid Build Coastguard Worker                           optimizationViews.AddUntouchedSubgraph(SubgraphView(*untouchedSubgraph));
295*89c4ff92SAndroid Build Coastguard Worker                       });
296*89c4ff92SAndroid Build Coastguard Worker     }
297*89c4ff92SAndroid Build Coastguard Worker 
298*89c4ff92SAndroid Build Coastguard Worker     return optimizationViews;
299*89c4ff92SAndroid Build Coastguard Worker }
300*89c4ff92SAndroid Build Coastguard Worker 
GetDefaultAllocator() const301*89c4ff92SAndroid Build Coastguard Worker std::unique_ptr<ICustomAllocator> MockBackend::GetDefaultAllocator() const
302*89c4ff92SAndroid Build Coastguard Worker {
303*89c4ff92SAndroid Build Coastguard Worker     return std::make_unique<DefaultAllocator>();
304*89c4ff92SAndroid Build Coastguard Worker }
305*89c4ff92SAndroid Build Coastguard Worker 
306*89c4ff92SAndroid Build Coastguard Worker }    // namespace armnn
307