ArmNN
 22.02
NeonBackend Class Reference

#include <NeonBackend.hpp>

Inheritance diagram for NeonBackend:
IBackendInternal IBackend

Public Member Functions

 NeonBackend ()=default
 
 ~NeonBackend ()=default
 
const BackendIdGetId () const override
 
IBackendInternal::IMemoryManagerUniquePtr CreateMemoryManager () const override
 
IWorkloadFactoryPtr CreateWorkloadFactory (const IBackendInternal::IMemoryManagerSharedPtr &memoryManager=nullptr) const override
 
IWorkloadFactoryPtr CreateWorkloadFactory (class TensorHandleFactoryRegistry &tensorHandleFactoryRegistry) const override
 
IWorkloadFactoryPtr CreateWorkloadFactory (const IMemoryManagerSharedPtr &memoryManager, const ModelOptions &modelOptions) const override
 
IWorkloadFactoryPtr CreateWorkloadFactory (class TensorHandleFactoryRegistry &tensorHandleFactoryRegistry, const ModelOptions &modelOptions) const override
 
IBackendInternal::IBackendContextPtr CreateBackendContext (const IRuntime::CreationOptions &) const override
 Create the runtime context of the backend. More...
 
IBackendInternal::IBackendProfilingContextPtr CreateBackendProfilingContext (const IRuntime::CreationOptions &, IBackendProfilingPtr &backendProfiling) override
 Create context specifically used for profiling interaction from backends. More...
 
IBackendInternal::ILayerSupportSharedPtr GetLayerSupport () const override
 
IBackendInternal::ILayerSupportSharedPtr GetLayerSupport (const ModelOptions &modelOptions) const override
 
OptimizationViews OptimizeSubgraphView (const SubgraphView &subgraph) const override
 
std::vector< ITensorHandleFactory::FactoryIdGetHandleFactoryPreferences () const override
 (Optional) Returns a vector of supported TensorHandleFactory ids in preference order. More...
 
void RegisterTensorHandleFactories (class TensorHandleFactoryRegistry &registry) override
 (Optional) Register TensorHandleFactories Either this method or CreateMemoryManager() and IWorkloadFactory::CreateTensor()/IWorkloadFactory::CreateSubtensor() methods must be implemented. More...
 
IBackendInternal::IBackendSpecificModelContextPtr CreateBackendSpecificModelContext (const ModelOptions &modelOptions) const override
 
BackendCapabilities GetCapabilities () const override
 Returns a BackendCapability if the backend lists the capability The BackendCapability must then be inspected to check whether or not that BackendCapability is supported Otherwise returns an EmptyOptional if the BackendCapability is unlisted. More...
 
std::unique_ptr< ICustomAllocatorGetDefaultAllocator () const override
 Returns the default memory allocator for the backend. More...
 
- Public Member Functions inherited from IBackendInternal
 ~IBackendInternal () override=default
 Allow backends created by the factory function to be destroyed through IBackendInternal. More...
 
virtual IWorkloadFactoryPtr CreateWorkloadFactory (class TensorHandleFactoryRegistry &tensorHandleFactoryRegistry, const ModelOptions &modelOptions, MemorySourceFlags inputFlags, MemorySourceFlags outputFlags) const
 
virtual OptimizationViews OptimizeSubgraphView (const SubgraphView &subgraph, const ModelOptions &modelOptions) const
 
bool SupportsTensorAllocatorAPI () const
 
ITensorHandleFactory::FactoryId GetBackwardCompatibleFavoriteHandleFactory ()
 
virtual void RegisterTensorHandleFactories (class TensorHandleFactoryRegistry &registry, MemorySourceFlags inputFlags, MemorySourceFlags outputFlags)
 (Optional) Register TensorHandleFactories Either this method or CreateMemoryManager() and IWorkloadFactory::CreateTensor()/IWorkloadFactory::CreateSubtensor() methods must be implemented. More...
 
virtual bool HasCapability (BackendCapability) const
 Returns true if backend support the capability false otherwise. More...
 
virtual bool UseCustomMemoryAllocator (std::shared_ptr< ICustomAllocator > allocator, armnn::Optional< std::string &> errMsg)
 Signals the backend to use a custom memory allocator provided by the user. More...
 
virtual unsigned int GetNumberOfCacheFiles () const
 Returns the number of files cached if backend supports caching. More...
 

Static Public Member Functions

static const BackendIdGetIdStatic ()
 
- Static Public Member Functions inherited from IBackendInternal
static constexpr BackendVersion GetApiVersion ()
 Returns the version of the Backend API. More...
 

Additional Inherited Members

- Public Types inherited from IBackendInternal
using IWorkloadFactoryPtr = std::unique_ptr< IWorkloadFactory >
 
using IBackendContextPtr = std::unique_ptr< IBackendContext >
 
using IBackendProfilingContextPtr = std::shared_ptr< armnn::profiling::IBackendProfilingContext >
 This is the bridge between backend and backend profiling we'll keep it in the backend namespace. More...
 
using IBackendProfilingPtr = std::unique_ptr< armnn::profiling::IBackendProfiling >
 
using ILayerSupportSharedPtr = std::shared_ptr< ILayerSupport >
 
using IBackendSpecificModelContextPtr = std::shared_ptr< IBackendModelContext >
 
using IMemoryManagerUniquePtr = std::unique_ptr< IMemoryManager >
 
using IMemoryManagerSharedPtr = std::shared_ptr< IMemoryManager >
 
- Protected Member Functions inherited from IBackendInternal
 IBackendInternal ()=default
 Creation must be done through a specific backend interface. More...
 
- Protected Member Functions inherited from IBackend
 IBackend ()
 
virtual ~IBackend ()
 

Detailed Description

Definition at line 26 of file NeonBackend.hpp.

Constructor & Destructor Documentation

◆ NeonBackend()

NeonBackend ( )
default

◆ ~NeonBackend()

~NeonBackend ( )
default

Member Function Documentation

◆ CreateBackendContext()

IBackendInternal::IBackendContextPtr CreateBackendContext ( const IRuntime::CreationOptions ) const
overridevirtual

Create the runtime context of the backend.

Implementations may return a default-constructed IBackendContextPtr if no context is needed at runtime. Implementations must throw BackendUnavailableException if the backend cannot be used (for example, necessary accelerator hardware is not present). The default implementation always returns a default-constructed pointer.

Reimplemented from IBackendInternal.

Definition at line 107 of file NeonBackend.cpp.

Referenced by NeonBackend::GetId().

108 {
109  return IBackendContextPtr{};
110 }
std::unique_ptr< IBackendContext > IBackendContextPtr

◆ CreateBackendProfilingContext()

IBackendInternal::IBackendProfilingContextPtr CreateBackendProfilingContext ( const IRuntime::CreationOptions creationOptions,
IBackendProfilingPtr backendProfiling 
)
overridevirtual

Create context specifically used for profiling interaction from backends.

Reimplemented from IBackendInternal.

Definition at line 112 of file NeonBackend.cpp.

Referenced by NeonBackend::GetId().

114 {
116 }
std::shared_ptr< armnn::profiling::IBackendProfilingContext > IBackendProfilingContextPtr
This is the bridge between backend and backend profiling we&#39;ll keep it in the backend namespace...

◆ CreateBackendSpecificModelContext()

IBackendInternal::IBackendSpecificModelContextPtr CreateBackendSpecificModelContext ( const ModelOptions modelOptions) const
overridevirtual

Reimplemented from IBackendInternal.

Definition at line 118 of file NeonBackend.cpp.

Referenced by NeonBackend::CreateWorkloadFactory(), NeonBackend::GetId(), and NeonBackend::GetLayerSupport().

120 {
121  return IBackendSpecificModelContextPtr{new NeonBackendModelContext{modelOptions}};
122 }
std::shared_ptr< IBackendModelContext > IBackendSpecificModelContextPtr

◆ CreateMemoryManager()

IBackendInternal::IMemoryManagerUniquePtr CreateMemoryManager ( ) const
overridevirtual

Reimplemented from IBackendInternal.

Definition at line 50 of file NeonBackend.cpp.

References BaseMemoryManager::Offset.

Referenced by NeonBackend::GetId().

51 {
52  return std::make_unique<NeonMemoryManager>(std::make_unique<arm_compute::Allocator>(),
54 }

◆ CreateWorkloadFactory() [1/4]

IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory ( const IBackendInternal::IMemoryManagerSharedPtr memoryManager = nullptr) const
overridevirtual

Implements IBackendInternal.

Definition at line 56 of file NeonBackend.cpp.

Referenced by NeonBackend::GetId().

58 {
59  return std::make_unique<NeonWorkloadFactory>(
60  PolymorphicPointerDowncast<NeonMemoryManager>(memoryManager));
61 }

◆ CreateWorkloadFactory() [2/4]

IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory ( class TensorHandleFactoryRegistry tensorHandleFactoryRegistry) const
overridevirtual

Reimplemented from IBackendInternal.

Definition at line 70 of file NeonBackend.cpp.

References BaseMemoryManager::Offset, TensorHandleFactoryRegistry::RegisterCopyAndImportFactoryPair(), TensorHandleFactoryRegistry::RegisterFactory(), and TensorHandleFactoryRegistry::RegisterMemoryManager().

72 {
73  auto memoryManager = std::make_shared<NeonMemoryManager>(std::make_unique<arm_compute::Allocator>(),
75 
76  tensorHandleFactoryRegistry.RegisterMemoryManager(memoryManager);
77 
78  auto factory = std::make_unique<NeonTensorHandleFactory>(memoryManager);
79  // Register copy and import factory pair
80  tensorHandleFactoryRegistry.RegisterCopyAndImportFactoryPair(factory->GetId(), factory->GetId());
81  // Register the factory
82  tensorHandleFactoryRegistry.RegisterFactory(std::move(factory));
83 
84 
85  return std::make_unique<NeonWorkloadFactory>(
86  PolymorphicPointerDowncast<NeonMemoryManager>(memoryManager));
87 }

◆ CreateWorkloadFactory() [3/4]

IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory ( const IMemoryManagerSharedPtr memoryManager,
const ModelOptions modelOptions 
) const
overridevirtual

Reimplemented from IBackendInternal.

Definition at line 63 of file NeonBackend.cpp.

References NeonBackend::CreateBackendSpecificModelContext().

65 {
66  return std::make_unique<NeonWorkloadFactory>(
67  PolymorphicPointerDowncast<NeonMemoryManager>(memoryManager), CreateBackendSpecificModelContext(modelOptions));
68 }
IBackendInternal::IBackendSpecificModelContextPtr CreateBackendSpecificModelContext(const ModelOptions &modelOptions) const override

◆ CreateWorkloadFactory() [4/4]

IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory ( class TensorHandleFactoryRegistry tensorHandleFactoryRegistry,
const ModelOptions modelOptions 
) const
overridevirtual

Reimplemented from IBackendInternal.

Definition at line 89 of file NeonBackend.cpp.

References NeonBackend::CreateBackendSpecificModelContext(), BaseMemoryManager::Offset, TensorHandleFactoryRegistry::RegisterCopyAndImportFactoryPair(), TensorHandleFactoryRegistry::RegisterFactory(), and TensorHandleFactoryRegistry::RegisterMemoryManager().

91 {
92  auto memoryManager = std::make_shared<NeonMemoryManager>(std::make_unique<arm_compute::Allocator>(),
94 
95  tensorHandleFactoryRegistry.RegisterMemoryManager(memoryManager);
96 
97  auto factory = std::make_unique<NeonTensorHandleFactory>(memoryManager);
98  // Register copy and import factory pair
99  tensorHandleFactoryRegistry.RegisterCopyAndImportFactoryPair(factory->GetId(), factory->GetId());
100  // Register the factory
101  tensorHandleFactoryRegistry.RegisterFactory(std::move(factory));
102 
103  return std::make_unique<NeonWorkloadFactory>(
104  PolymorphicPointerDowncast<NeonMemoryManager>(memoryManager), CreateBackendSpecificModelContext(modelOptions));
105 }
IBackendInternal::IBackendSpecificModelContextPtr CreateBackendSpecificModelContext(const ModelOptions &modelOptions) const override

◆ GetCapabilities()

BackendCapabilities GetCapabilities ( ) const
inlineoverridevirtual

Returns a BackendCapability if the backend lists the capability The BackendCapability must then be inspected to check whether or not that BackendCapability is supported Otherwise returns an EmptyOptional if the BackendCapability is unlisted.

Reimplemented from IBackendInternal.

Definition at line 64 of file NeonBackend.hpp.

References armnn::cpuAccCapabilities, and NeonBackend::GetDefaultAllocator().

65  {
66  return cpuAccCapabilities;
67  };
const BackendCapabilities cpuAccCapabilities("CpuAcc", { {"NonConstWeights", false}, {"AsyncExecution", false}, {"ProtectedContentAllocation", false}, {"ConstantTensorsAsInputs", false}, {"PreImportIOTensors", false}, {"ExternallyManagedMemory", true}, {"MultiAxisPacking", false}, {"SingleAxisPacking", true} })

◆ GetDefaultAllocator()

std::unique_ptr< ICustomAllocator > GetDefaultAllocator ( ) const
overridevirtual

Returns the default memory allocator for the backend.

Returns
- Returns unique pointer to the Default Allocator of the Backend

Reimplemented from IBackendInternal.

Definition at line 452 of file NeonBackend.cpp.

Referenced by NeonBackend::GetCapabilities().

453 {
454  return std::make_unique<DefaultAllocator>();
455 }

◆ GetHandleFactoryPreferences()

std::vector< ITensorHandleFactory::FactoryId > GetHandleFactoryPreferences ( ) const
overridevirtual

(Optional) Returns a vector of supported TensorHandleFactory ids in preference order.

Reimplemented from IBackendInternal.

Definition at line 433 of file NeonBackend.cpp.

References NeonTensorHandleFactory::GetIdStatic().

Referenced by NeonBackend::GetId().

434 {
435  return std::vector<ITensorHandleFactory::FactoryId>() = { NeonTensorHandleFactory::GetIdStatic() };
436 }
static const FactoryId & GetIdStatic()

◆ GetId()

◆ GetIdStatic()

const BackendId & GetIdStatic ( )
static

Definition at line 44 of file NeonBackend.cpp.

References armnn::NeonBackendId().

Referenced by NeonBackend::GetId().

45 {
46  static const BackendId s_Id{NeonBackendId()};
47  return s_Id;
48 }
constexpr const char * NeonBackendId()

◆ GetLayerSupport() [1/2]

IBackendInternal::ILayerSupportSharedPtr GetLayerSupport ( ) const
overridevirtual

Implements IBackendInternal.

Definition at line 124 of file NeonBackend.cpp.

Referenced by NeonBackend::GetId().

125 {
126  static ILayerSupportSharedPtr layerSupport
127  {
129  };
130  return layerSupport;
131 }
std::shared_ptr< IBackendModelContext > IBackendSpecificModelContextPtr
std::shared_ptr< ILayerSupport > ILayerSupportSharedPtr

◆ GetLayerSupport() [2/2]

IBackendInternal::ILayerSupportSharedPtr GetLayerSupport ( const ModelOptions modelOptions) const
overridevirtual

Reimplemented from IBackendInternal.

Definition at line 133 of file NeonBackend.cpp.

References NeonBackend::CreateBackendSpecificModelContext().

134 {
135  static ILayerSupportSharedPtr layerSupport
136  {
137  new NeonLayerSupport(CreateBackendSpecificModelContext(modelOptions))
138  };
139  return layerSupport;
140 }
IBackendInternal::IBackendSpecificModelContextPtr CreateBackendSpecificModelContext(const ModelOptions &modelOptions) const override
std::shared_ptr< ILayerSupport > ILayerSupportSharedPtr

◆ OptimizeSubgraphView()

OptimizationViews OptimizeSubgraphView ( const SubgraphView subgraph) const
overridevirtual

Reimplemented from IBackendInternal.

Definition at line 142 of file NeonBackend.cpp.

References armnn::Activation, armnn::Addition, OptimizationViews::AddUntouchedSubgraph(), armnn::BatchNormalization, SubgraphView::beginIConnectable(), Layer::BeginOutputSlots(), armnn::Convolution2d, armnn::DepthwiseConvolution2d, armnn::Division, SubgraphView::endIConnectable(), Layer::EndOutputSlots(), armnn::FullyConnected, Layer::GetAdditionalInformation(), InputSlot::GetConnectedOutputSlot(), Layer::GetGuid(), Layer::GetInputSlot(), Layer::GetName(), LayerWithParameters< Parameters >::GetParameters(), OptimizationViews::GetSubstitutions(), OutputSlot::GetTensorInfo(), Layer::GetType(), BatchNormalizationLayer::m_Beta, DepthwiseConvolution2dLayer::m_Bias, Convolution2dLayer::m_Bias, FullyConnectedLayer::m_Bias, FullyConnectedDescriptor::m_BiasEnabled, Convolution2dDescriptor::m_BiasEnabled, DepthwiseConvolution2dDescriptor::m_BiasEnabled, BatchNormalizationLayer::m_Gamma, BatchNormalizationLayer::m_Mean, BatchNormalizationLayer::m_Variance, DepthwiseConvolution2dLayer::m_Weight, Convolution2dLayer::m_Weight, FullyConnectedLayer::m_Weight, armnn::Multiplication, armnn::NeonAdditionWorkloadValidate(), armnn::NeonBatchNormalizationValidate(), armnn::NeonConvolution2dWorkloadValidate(), armnn::NeonDepthwiseConvolutionWorkloadValidate(), armnn::NeonDivisionWorkloadValidate(), armnn::NeonFullyConnectedWorkloadValidate(), armnn::NeonMultiplicationWorkloadValidate(), armnn::NeonSubtractionWorkloadValidate(), armnn::Reduce, armnn::ReportUntouchedLayers(), and armnn::Subtraction.

Referenced by NeonBackend::GetId().

143 {
144  OptimizationViews optimizationViews;
145 
146  auto it = subgraph.endIConnectable();
147  std::map<LayerGuid, Layer*> untouched;
148 
149  while (it != subgraph.beginIConnectable())
150  {
151  --it;
152  Layer& base = *(PolymorphicDowncast<Layer*>(*it));
153  untouched.insert({base.GetGuid(), &base});
154  }
155 
156  it = subgraph.endIConnectable();
157  while (it != subgraph.beginIConnectable())
158  {
159  --it;
160  Layer& base = *(PolymorphicDowncast<Layer*>(*it));
161 
162  // Fuse activation into previous layer if supported by backend
163  if ((base.GetType() == LayerType::DepthwiseConvolution2d || base.GetType() == LayerType::Convolution2d
164  || base.GetType() == LayerType::BatchNormalization || base.GetType() == LayerType::FullyConnected
165  || base.GetType() == LayerType::Addition || base.GetType() == LayerType::Multiplication
166  || base.GetType() == LayerType::Subtraction || base.GetType() == LayerType::Division)
167  && (base.GetAdditionalInformation<ActivationDescriptor>() == nullptr))
168  {
169  for (auto output = base.BeginOutputSlots(); output != base.EndOutputSlots(); ++output)
170  {
171  if (output->GetNumConnections() == 1)
172  {
173  for (auto&& childInput : output->GetConnections())
174  {
175  if ((childInput->GetOwningLayer().GetType() == LayerType::Activation) &&
176  (checkDataTypeInputandOutput(childInput->GetOwningLayer())))
177  {
178  Layer& child = childInput->GetOwningLayer();
179 
180  auto* activationLayer = PolymorphicDowncast<ActivationLayer*>(&child);
181 
182  const std::string name = std::string("fused-") + child.GetName() + std::string("-into-") +
183  base.GetName();
184 
185  // Get params from activation layer
186  ActivationDescriptor activationDesc = activationLayer->GetParameters();
187 
188  if (base.GetType() == LayerType::Convolution2d)
189  {
190  Convolution2dLayer* baseLayer = PolymorphicDowncast<Convolution2dLayer*>(&base);
191 
192  Optional<TensorInfo> biases;
193 
194  if (baseLayer->GetParameters().m_BiasEnabled)
195  {
196  biases = baseLayer->m_Bias->GetTensorInfo();
197  }
198 
200  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
201  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
202  baseLayer->GetParameters(),
203  baseLayer->m_Weight->GetTensorInfo(),
204  biases,
205  false,
206  &activationDesc);
207 
208  if (status)
209  {
210  FuseConvolution2dLayer<Convolution2dLayer>(optimizationViews,
211  baseLayer,
212  activationLayer,
213  activationDesc,
214  name);
215  untouched.erase(baseLayer->GetGuid());
216  untouched.erase(activationLayer->GetGuid());
217  }
218  }
219  else if (base.GetType() == LayerType::DepthwiseConvolution2d)
220  {
221  DepthwiseConvolution2dLayer* baseLayer =
222  PolymorphicDowncast<DepthwiseConvolution2dLayer*>(&base);
223 
224  Optional<TensorInfo> biases;
225 
226  if (baseLayer->GetParameters().m_BiasEnabled)
227  {
228  biases = baseLayer->m_Bias->GetTensorInfo();
229  }
230 
232  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
233  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
234  baseLayer->GetParameters(),
235  baseLayer->m_Weight->GetTensorInfo(),
236  biases,
237  &activationDesc);
238 
239  if (status)
240  {
241  FuseDepthwiseConvolution2dLayer<DepthwiseConvolution2dLayer>(optimizationViews,
242  baseLayer,
243  activationLayer,
244  activationDesc,
245  name);
246  untouched.erase(baseLayer->GetGuid());
247  untouched.erase(activationLayer->GetGuid());
248  }
249  }
250  else if (base.GetType() == LayerType::FullyConnected)
251  {
252  FullyConnectedLayer* baseLayer = PolymorphicDowncast<FullyConnectedLayer*>(&base);
253  Optional<TensorInfo> biases;
254 
255  if (baseLayer->GetParameters().m_BiasEnabled)
256  {
257  biases = baseLayer->m_Bias->GetTensorInfo();
258  }
259 
261  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
262  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
263  baseLayer->m_Weight->GetTensorInfo(),
264  biases,
265  baseLayer->GetParameters(),
266  &activationDesc);
267 
268  if (status)
269  {
270  FuseFullyConnectedLayer<FullyConnectedLayer>(optimizationViews,
271  baseLayer,
272  activationLayer,
273  activationDesc,
274  name);
275  untouched.erase(baseLayer->GetGuid());
276  untouched.erase(activationLayer->GetGuid());
277  }
278  }
279  else if (base.GetType() == LayerType::BatchNormalization)
280  {
281  BatchNormalizationLayer* baseLayer =
282  PolymorphicDowncast<BatchNormalizationLayer*>(&base);
283 
285  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
286  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
287  baseLayer->m_Mean->GetTensorInfo(),
288  baseLayer->m_Variance->GetTensorInfo(),
289  baseLayer->m_Beta->GetTensorInfo(),
290  baseLayer->m_Gamma->GetTensorInfo(),
291  baseLayer->GetParameters(),
292  &activationDesc);
293 
294  if (status)
295  {
296  BatchNormalizationLayer* replacementLayer =
297  FuseBatchNormalizationLayer<BatchNormalizationLayer>(optimizationViews,
298  baseLayer,
299  activationLayer,
300  activationDesc,
301  name);
302 
303  replacementLayer->m_Beta = std::move(baseLayer->m_Beta);
304  replacementLayer->m_Gamma = std::move(baseLayer->m_Gamma);
305  replacementLayer->m_Mean = std::move(baseLayer->m_Mean);
306  replacementLayer->m_Variance = std::move(baseLayer->m_Variance);
307  untouched.erase(baseLayer->GetGuid());
308  untouched.erase(activationLayer->GetGuid());
309  }
310  }
311  else if (base.GetType() == LayerType::Addition)
312  {
313  AdditionLayer* baseLayer = PolymorphicDowncast<AdditionLayer*>(&base);
314 
316  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
317  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
318  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
319  &activationDesc);
320 
321  if (status)
322  {
323  FuseAdditionLayer<AdditionLayer>(optimizationViews,
324  baseLayer,
325  activationLayer,
326  activationDesc,
327  name);
328  untouched.erase(baseLayer->GetGuid());
329  untouched.erase(activationLayer->GetGuid());
330  }
331  }
332  else if (base.GetType() == LayerType::Division)
333  {
334  DivisionLayer* baseLayer = PolymorphicDowncast<DivisionLayer*>(&base);
335 
337  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
338  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
339  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
340  &activationDesc);
341 
342  if (status)
343  {
344  FuseDivisionLayer<DivisionLayer>(optimizationViews,
345  baseLayer,
346  activationLayer,
347  activationDesc,
348  name);
349  untouched.erase(baseLayer->GetGuid());
350  untouched.erase(activationLayer->GetGuid());
351  }
352  }
353  else if (base.GetType() == LayerType::Multiplication)
354  {
355  MultiplicationLayer* baseLayer = PolymorphicDowncast<MultiplicationLayer*>(&base);
356 
358  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
359  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
360  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
361  &activationDesc);
362 
363  if (status)
364  {
365  FuseMultiplicationLayer<MultiplicationLayer>(optimizationViews,
366  baseLayer,
367  activationLayer,
368  activationDesc,
369  name);
370  untouched.erase(baseLayer->GetGuid());
371  untouched.erase(activationLayer->GetGuid());
372  }
373  }
374  else if (base.GetType() == LayerType::Subtraction)
375  {
376  SubtractionLayer* baseLayer = PolymorphicDowncast<SubtractionLayer*>(&base);
377 
379  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
380  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
381  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
382  &activationDesc);
383 
384  if (status)
385  {
386  FuseSubtractionLayer<SubtractionLayer>(optimizationViews,
387  baseLayer,
388  activationLayer,
389  activationDesc,
390  name);
391  untouched.erase(baseLayer->GetGuid());
392  untouched.erase(activationLayer->GetGuid());
393  }
394  }
395  }
396  }
397  }
398  }
399  }
400 
401  // Separate reduce layer with multiple axes into multiple reduce layers with 1 axis.
402  if (base.GetType() == LayerType::Reduce)
403  {
404  ReduceLayer* baseLayer = PolymorphicDowncast<ReduceLayer*>(&base);
405  ReduceDescriptor reduceDescriptor = baseLayer->GetParameters();
406 
407  if (!reduceDescriptor.m_vAxis.empty() && reduceDescriptor.m_vAxis.size() > 1)
408  {
409  // Add new layers to the graph and connect them.
410  std::vector<IConnectableLayer*> layers = ChainReduceLayers<ReduceLayer>(optimizationViews,
411  baseLayer,
412  reduceDescriptor);
413 
414  // Replace existing baselayer with new subgraph.
415  ReplaceLayers<ReduceLayer>(optimizationViews, baseLayer, layers);
416  untouched.erase(baseLayer->GetGuid());
417  }
418  }
419  }
420 
421  if (optimizationViews.GetSubstitutions().empty())
422  {
423  optimizationViews.AddUntouchedSubgraph(SubgraphView(subgraph));
424  }
425  else
426  {
427  ReportUntouchedLayers(optimizationViews, untouched);
428  }
429 
430  return optimizationViews;
431 }
arm_compute::Status NeonBatchNormalizationValidate(const TensorInfo &input, const TensorInfo &output, const TensorInfo &mean, const TensorInfo &var, const TensorInfo &beta, const TensorInfo &gamma, const BatchNormalizationDescriptor &descriptor, const ActivationDescriptor *activationDescriptor)
void ReportUntouchedLayers(OptimizationViews &optimizationViews, std::map< LayerGuid, Layer *> untouched)
arm_compute::Status NeonDepthwiseConvolutionWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const DepthwiseConvolution2dDescriptor &descriptor, const TensorInfo &weights, const Optional< TensorInfo > &biases, const ActivationDescriptor *activationDescriptor)
arm_compute::Status NeonFullyConnectedWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const TensorInfo &weights, const Optional< TensorInfo > &biases, const FullyConnectedDescriptor &descriptor, const ActivationDescriptor *activationDescriptor)
arm_compute::Status NeonAdditionWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
arm_compute::Status NeonSubtractionWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
Status
enumeration
Definition: Types.hpp:29
arm_compute::Status NeonConvolution2dWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const Convolution2dDescriptor &descriptor, const TensorInfo &weights, const Optional< TensorInfo > &biases, bool isFastMathEnabled, const ActivationDescriptor *activationDescriptor)
arm_compute::Status NeonDivisionWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
arm_compute::Status NeonMultiplicationWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)

◆ RegisterTensorHandleFactories()

void RegisterTensorHandleFactories ( class TensorHandleFactoryRegistry )
overridevirtual

(Optional) Register TensorHandleFactories Either this method or CreateMemoryManager() and IWorkloadFactory::CreateTensor()/IWorkloadFactory::CreateSubtensor() methods must be implemented.

Reimplemented from IBackendInternal.

Definition at line 438 of file NeonBackend.cpp.

References BaseMemoryManager::Offset, TensorHandleFactoryRegistry::RegisterCopyAndImportFactoryPair(), TensorHandleFactoryRegistry::RegisterFactory(), and TensorHandleFactoryRegistry::RegisterMemoryManager().

Referenced by NeonBackend::GetId().

439 {
440  auto memoryManager = std::make_shared<NeonMemoryManager>(std::make_unique<arm_compute::Allocator>(),
442 
443  registry.RegisterMemoryManager(memoryManager);
444 
445  auto factory = std::make_unique<NeonTensorHandleFactory>(memoryManager);
446  // Register copy and import factory pair
447  registry.RegisterCopyAndImportFactoryPair(factory->GetId(), factory->GetId());
448  // Register the factory
449  registry.RegisterFactory(std::move(factory));
450 }

The documentation for this class was generated from the following files: