ArmNN
 21.08
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::Optimizations GetOptimizations () const override
 
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...
 
- Public Member Functions inherited from IBackendInternal
 ~IBackendInternal () override=default
 Allow backends created by the factory function to be destroyed through IBackendInternal. More...
 
virtual ISubGraphConverterPtr CreateSubGraphConverter (const std::shared_ptr< SubGraph > &subGraph) const
 
virtual SubGraphUniquePtr OptimizeSubGraph (const SubGraph &subGraph, bool &optimizationAttempted) const
 
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...
 

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 OptimizationPtr = std::unique_ptr< Optimization >
 
using Optimizations = std::vector< OptimizationPtr >
 
using ILayerSupportSharedPtr = std::shared_ptr< ILayerSupport >
 
using IBackendSpecificModelContextPtr = std::shared_ptr< IBackendModelContext >
 
using IMemoryManagerUniquePtr = std::unique_ptr< IMemoryManager >
 
using IMemoryManagerSharedPtr = std::shared_ptr< IMemoryManager >
 
using GraphUniquePtr = std::unique_ptr< Graph >
 
using SubgraphViewUniquePtr = std::unique_ptr< SubgraphView >
 
using supported = std::unique_ptr< ISubGraphConverter >
 
using instead = std::unique_ptr< SubGraph >
 
- 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 20 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 95 of file NeonBackend.cpp.

Referenced by NeonBackend::GetId().

96 {
97  return IBackendContextPtr{};
98 }
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 100 of file NeonBackend.cpp.

Referenced by NeonBackend::GetId().

102 {
104 }
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 111 of file NeonBackend.cpp.

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

113 {
114  return IBackendSpecificModelContextPtr{new NeonBackendModelContext{modelOptions}};
115 }
std::shared_ptr< IBackendModelContext > IBackendSpecificModelContextPtr

◆ CreateMemoryManager()

IBackendInternal::IMemoryManagerUniquePtr CreateMemoryManager ( ) const
overridevirtual

Reimplemented from IBackendInternal.

Definition at line 49 of file NeonBackend.cpp.

References BaseMemoryManager::Offset.

Referenced by NeonBackend::GetId().

50 {
51  return std::make_unique<NeonMemoryManager>(std::make_unique<arm_compute::Allocator>(),
53 }

◆ CreateWorkloadFactory() [1/4]

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

Implements IBackendInternal.

Definition at line 55 of file NeonBackend.cpp.

Referenced by NeonBackend::GetId().

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

◆ CreateWorkloadFactory() [2/4]

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

Reimplemented from IBackendInternal.

Definition at line 69 of file NeonBackend.cpp.

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

71 {
72  auto memoryManager = std::make_shared<NeonMemoryManager>(std::make_unique<arm_compute::Allocator>(),
74 
75  tensorHandleFactoryRegistry.RegisterMemoryManager(memoryManager);
76  tensorHandleFactoryRegistry.RegisterFactory(std::make_unique<NeonTensorHandleFactory>(memoryManager));
77 
78  return std::make_unique<NeonWorkloadFactory>(
79  PolymorphicPointerDowncast<NeonMemoryManager>(memoryManager));
80 }

◆ CreateWorkloadFactory() [3/4]

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

Reimplemented from IBackendInternal.

Definition at line 62 of file NeonBackend.cpp.

References NeonBackend::CreateBackendSpecificModelContext().

64 {
65  return std::make_unique<NeonWorkloadFactory>(
66  PolymorphicPointerDowncast<NeonMemoryManager>(memoryManager), CreateBackendSpecificModelContext(modelOptions));
67 }
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 82 of file NeonBackend.cpp.

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

84 {
85  auto memoryManager = std::make_shared<NeonMemoryManager>(std::make_unique<arm_compute::Allocator>(),
87 
88  tensorHandleFactoryRegistry.RegisterMemoryManager(memoryManager);
89  tensorHandleFactoryRegistry.RegisterFactory(std::make_unique<NeonTensorHandleFactory>(memoryManager));
90 
91  return std::make_unique<NeonWorkloadFactory>(
92  PolymorphicPointerDowncast<NeonMemoryManager>(memoryManager), CreateBackendSpecificModelContext(modelOptions));
93 }
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 59 of file NeonBackend.hpp.

References armnn::cpuAccCapabilities.

60  {
61  return cpuAccCapabilities;
62  };
const BackendCapabilities cpuAccCapabilities("GpuAcc", { {"NonConstWeights", false}, {"AsyncExecution", false} })

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

References NeonTensorHandleFactory::GetIdStatic().

Referenced by NeonBackend::GetId().

422 {
423  return std::vector<ITensorHandleFactory::FactoryId>() = { NeonTensorHandleFactory::GetIdStatic() };
424 }
static const FactoryId & GetIdStatic()

◆ GetId()

◆ GetIdStatic()

const BackendId & GetIdStatic ( )
static

Definition at line 43 of file NeonBackend.cpp.

References armnn::NeonBackendId().

Referenced by NeonBackend::GetId().

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

◆ GetLayerSupport() [1/2]

IBackendInternal::ILayerSupportSharedPtr GetLayerSupport ( ) const
overridevirtual

Implements IBackendInternal.

Definition at line 117 of file NeonBackend.cpp.

Referenced by NeonBackend::GetId().

118 {
119  static ILayerSupportSharedPtr layerSupport
120  {
122  };
123  return layerSupport;
124 }
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 126 of file NeonBackend.cpp.

References NeonBackend::CreateBackendSpecificModelContext().

127 {
128  static ILayerSupportSharedPtr layerSupport
129  {
130  new NeonLayerSupport(CreateBackendSpecificModelContext(modelOptions))
131  };
132  return layerSupport;
133 }
IBackendInternal::IBackendSpecificModelContextPtr CreateBackendSpecificModelContext(const ModelOptions &modelOptions) const override
std::shared_ptr< ILayerSupport > ILayerSupportSharedPtr

◆ GetOptimizations()

IBackendInternal::Optimizations GetOptimizations ( ) const
overridevirtual

Reimplemented from IBackendInternal.

Definition at line 106 of file NeonBackend.cpp.

Referenced by NeonBackend::GetId().

107 {
108  return Optimizations{};
109 }
std::vector< OptimizationPtr > Optimizations

◆ OptimizeSubgraphView()

OptimizationViews OptimizeSubgraphView ( const SubgraphView subgraph) const
overridevirtual

Reimplemented from IBackendInternal.

Definition at line 135 of file NeonBackend.cpp.

References armnn::Activation, armnn::Addition, OptimizationViews::AddUntouchedSubgraph(), armnn::BatchNormalization, SubgraphView::begin(), Layer::BeginOutputSlots(), armnn::Convolution2d, armnn::DepthwiseConvolution2d, armnn::Division, SubgraphView::end(), 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, 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().

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

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

Referenced by NeonBackend::GetId().

427 {
428  auto memoryManager = std::make_shared<NeonMemoryManager>(std::make_unique<arm_compute::Allocator>(),
430 
431  registry.RegisterMemoryManager(memoryManager);
432  registry.RegisterFactory(std::make_unique<NeonTensorHandleFactory>(memoryManager));
433 }

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