ArmNN
 22.11
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 ModelOptions &modelOptions) 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
 
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 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...
 
virtual ExecutionData CreateExecutionData (WorkingMemDescriptor &workingMemDescriptor) const
 Returns ExecutionData for the backend. More...
 
virtual void UpdateExecutionData (ExecutionData &executionData, WorkingMemDescriptor &workingMemDescriptor) const
 Update the ExecutionData for a layer. 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< arm::pipe::IBackendProfilingContext >
 This is the bridge between backend and backend profiling we'll keep it in the backend namespace. More...
 
using IBackendProfilingPtr = std::unique_ptr< arm::pipe::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< arm::pipe::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 65 of file NeonBackend.hpp.

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

66  {
67  return cpuAccCapabilities;
68  };
const BackendCapabilities cpuAccCapabilities("CpuAcc", { {"NonConstWeights", false}, {"AsyncExecution", false}, {"ProtectedContentAllocation", false}, {"ConstantTensorsAsInputs", true}, {"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 455 of file NeonBackend.cpp.

Referenced by NeonBackend::GetCapabilities().

456 {
457  return std::make_unique<DefaultAllocator>();
458 }

◆ 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 436 of file NeonBackend.cpp.

References NeonTensorHandleFactory::GetIdStatic().

Referenced by NeonBackend::GetId().

437 {
438  return std::vector<ITensorHandleFactory::FactoryId>() = { NeonTensorHandleFactory::GetIdStatic() };
439 }
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 ModelOptions modelOptions 
) 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, Convolution2dDescriptor::m_BiasEnabled, DepthwiseConvolution2dDescriptor::m_BiasEnabled, BatchNormalizationLayer::m_Gamma, BatchNormalizationLayer::m_Mean, BatchNormalizationLayer::m_Variance, 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().

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

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

Referenced by NeonBackend::GetId().

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

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