ArmNN
 21.05
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
 
bool HasCapability (BackendCapability capabilityClass) const override
 Returns true if backend support the capability false otherwise. 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...
 

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 16 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 94 of file NeonBackend.cpp.

Referenced by NeonBackend::GetId().

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

Referenced by NeonBackend::GetId().

101 {
103 }
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 110 of file NeonBackend.cpp.

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

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

◆ CreateMemoryManager()

IBackendInternal::IMemoryManagerUniquePtr CreateMemoryManager ( ) const
overridevirtual

Reimplemented from IBackendInternal.

Definition at line 48 of file NeonBackend.cpp.

References BaseMemoryManager::Offset.

Referenced by NeonBackend::GetId().

49 {
50  return std::make_unique<NeonMemoryManager>(std::make_unique<arm_compute::Allocator>(),
52 }

◆ CreateWorkloadFactory() [1/4]

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

Implements IBackendInternal.

Definition at line 54 of file NeonBackend.cpp.

Referenced by NeonBackend::GetId().

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

◆ CreateWorkloadFactory() [2/4]

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

Reimplemented from IBackendInternal.

Definition at line 68 of file NeonBackend.cpp.

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

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

◆ CreateWorkloadFactory() [3/4]

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

Reimplemented from IBackendInternal.

Definition at line 61 of file NeonBackend.cpp.

References NeonBackend::CreateBackendSpecificModelContext().

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

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

83 {
84  auto memoryManager = std::make_shared<NeonMemoryManager>(std::make_unique<arm_compute::Allocator>(),
86 
87  tensorHandleFactoryRegistry.RegisterMemoryManager(memoryManager);
88  tensorHandleFactoryRegistry.RegisterFactory(std::make_unique<NeonTensorHandleFactory>(memoryManager));
89 
90  return std::make_unique<NeonWorkloadFactory>(
91  PolymorphicPointerDowncast<NeonMemoryManager>(memoryManager), CreateBackendSpecificModelContext(modelOptions));
92 }
IBackendInternal::IBackendSpecificModelContextPtr CreateBackendSpecificModelContext(const ModelOptions &modelOptions) const override

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

References NeonTensorHandleFactory::GetIdStatic().

Referenced by NeonBackend::GetId().

411 {
412  return std::vector<ITensorHandleFactory::FactoryId>() = { NeonTensorHandleFactory::GetIdStatic() };
413 }
static const FactoryId & GetIdStatic()

◆ GetId()

◆ GetIdStatic()

const BackendId & GetIdStatic ( )
static

Definition at line 42 of file NeonBackend.cpp.

References armnn::NeonBackendId().

Referenced by NeonBackend::GetId().

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

◆ GetLayerSupport() [1/2]

IBackendInternal::ILayerSupportSharedPtr GetLayerSupport ( ) const
overridevirtual

Implements IBackendInternal.

Definition at line 116 of file NeonBackend.cpp.

Referenced by NeonBackend::GetId().

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

References NeonBackend::CreateBackendSpecificModelContext().

126 {
127  static ILayerSupportSharedPtr layerSupport
128  {
129  new NeonLayerSupport(CreateBackendSpecificModelContext(modelOptions))
130  };
131  return layerSupport;
132 }
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 105 of file NeonBackend.cpp.

Referenced by NeonBackend::GetId().

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

◆ HasCapability()

bool HasCapability ( BackendCapability  ) const
overridevirtual

Returns true if backend support the capability false otherwise.

Reimplemented from IBackendInternal.

Definition at line 134 of file NeonBackend.cpp.

References armnn::cpuAccCapabilities.

Referenced by NeonBackend::GetId().

135 {
136  auto search = cpuAccCapabilities.find(capabilityClass);
137  if (search != cpuAccCapabilities.end())
138  {
139  return true;
140  }
141  return false;
142 }
const std::set< armnn::BackendCapability > cpuAccCapabilities
Definition: NeonBackend.hpp:12

◆ OptimizeSubgraphView()

OptimizationViews OptimizeSubgraphView ( const SubgraphView subgraph) const
overridevirtual

Reimplemented from IBackendInternal.

Definition at line 144 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, FullyConnectedLayer::m_Bias, DepthwiseConvolution2dLayer::m_Bias, Convolution2dLayer::m_Bias, Convolution2dDescriptor::m_BiasEnabled, DepthwiseConvolution2dDescriptor::m_BiasEnabled, BatchNormalizationLayer::m_Gamma, BatchNormalizationLayer::m_Mean, BatchNormalizationLayer::m_Variance, DepthwiseConvolution2dLayer::m_Weight, FullyConnectedLayer::m_Weight, Convolution2dLayer::m_Weight, armnn::Multiplication, armnn::NeonAdditionWorkloadValidate(), armnn::NeonBatchNormalizationValidate(), armnn::NeonConvolution2dWorkloadValidate(), armnn::NeonDepthwiseConvolutionWorkloadValidate(), armnn::NeonDivisionWorkloadValidate(), armnn::NeonFullyConnectedWorkloadValidate(), armnn::NeonMultiplicationWorkloadValidate(), armnn::NeonSubtractionWorkloadValidate(), armnn::ReportUntouchedLayers(), and armnn::Subtraction.

Referenced by NeonBackend::GetId().

145 {
146  OptimizationViews optimizationViews;
147 
148  auto it = subgraph.end();
149  std::map<LayerGuid, Layer*> untouched;
150 
151  while (it != subgraph.begin())
152  {
153  --it;
154  Layer& base = **it;
155  untouched.insert({base.GetGuid(), &base});
156  }
157 
158  it = subgraph.end();
159  while (it != subgraph.begin())
160  {
161  --it;
162  Layer& base = **it;
163 
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->m_Bias->GetTensorInfo();
198  }
199 
201  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
202  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
203  baseLayer->GetParameters(),
204  baseLayer->m_Weight->GetTensorInfo(),
205  biases,
206  false,
207  &activationDesc);
208 
209  if (status)
210  {
211  FuseLayerWithWeightsAndBiases<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->m_Bias->GetTensorInfo();
230  }
231 
233  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
234  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
235  baseLayer->GetParameters(),
236  baseLayer->m_Weight->GetTensorInfo(),
237  biases,
238  &activationDesc);
239 
240  if (status)
241  {
242  FuseLayerWithWeightsAndBiases<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 
256  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
257  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
258  baseLayer->m_Weight->GetTensorInfo(),
259  baseLayer->m_Bias->GetTensorInfo(),
260  baseLayer->GetParameters(),
261  &activationDesc);
262 
263  if (status)
264  {
265  FuseLayerWithWeightsAndBiases<FullyConnectedLayer>(optimizationViews,
266  baseLayer,
267  activationLayer,
268  activationDesc,
269  name);
270  untouched.erase(baseLayer->GetGuid());
271  untouched.erase(activationLayer->GetGuid());
272  }
273  }
274  else if (base.GetType() == LayerType::BatchNormalization)
275  {
276  BatchNormalizationLayer* baseLayer =
277  PolymorphicDowncast<BatchNormalizationLayer*>(&base);
278 
280  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
281  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
282  baseLayer->m_Mean->GetTensorInfo(),
283  baseLayer->m_Variance->GetTensorInfo(),
284  baseLayer->m_Beta->GetTensorInfo(),
285  baseLayer->m_Gamma->GetTensorInfo(),
286  baseLayer->GetParameters(),
287  &activationDesc);
288 
289  if (status)
290  {
291  BatchNormalizationLayer* replacementLayer =
292  FuseLayerWithParameters<BatchNormalizationLayer>(
293  optimizationViews,
294  baseLayer,
295  activationLayer,
296  activationDesc,
297  name);
298 
299  replacementLayer->m_Beta = std::move(baseLayer->m_Beta);
300  replacementLayer->m_Gamma = std::move(baseLayer->m_Gamma);
301  replacementLayer->m_Mean = std::move(baseLayer->m_Mean);
302  replacementLayer->m_Variance = std::move(baseLayer->m_Variance);
303  untouched.erase(baseLayer->GetGuid());
304  untouched.erase(activationLayer->GetGuid());
305  }
306  }
307  else if (base.GetType() == LayerType::Addition)
308  {
309  AdditionLayer* baseLayer = PolymorphicDowncast<AdditionLayer*>(&base);
310 
312  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
313  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
314  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
315  &activationDesc);
316 
317  if (status)
318  {
319  FuseLayerWithoutParameters<AdditionLayer>(optimizationViews,
320  baseLayer,
321  activationLayer,
322  activationDesc,
323  name);
324  untouched.erase(baseLayer->GetGuid());
325  untouched.erase(activationLayer->GetGuid());
326  }
327  }
328  else if (base.GetType() == LayerType::Division)
329  {
330  DivisionLayer* baseLayer = PolymorphicDowncast<DivisionLayer*>(&base);
331 
333  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
334  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
335  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
336  &activationDesc);
337 
338  if (status)
339  {
340  FuseLayerWithoutParameters<DivisionLayer>(optimizationViews,
341  baseLayer,
342  activationLayer,
343  activationDesc,
344  name);
345  untouched.erase(baseLayer->GetGuid());
346  untouched.erase(activationLayer->GetGuid());
347  }
348  }
349  else if (base.GetType() == LayerType::Multiplication)
350  {
351  MultiplicationLayer* baseLayer = PolymorphicDowncast<MultiplicationLayer*>(&base);
352 
354  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
355  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
356  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
357  &activationDesc);
358 
359  if (status)
360  {
361  FuseLayerWithoutParameters<MultiplicationLayer>(optimizationViews,
362  baseLayer,
363  activationLayer,
364  activationDesc,
365  name);
366  untouched.erase(baseLayer->GetGuid());
367  untouched.erase(activationLayer->GetGuid());
368  }
369  }
370  else if (base.GetType() == LayerType::Subtraction)
371  {
372  SubtractionLayer* baseLayer = PolymorphicDowncast<SubtractionLayer*>(&base);
373 
375  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
376  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
377  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
378  &activationDesc);
379 
380  if (status)
381  {
382  FuseLayerWithoutParameters<SubtractionLayer>(optimizationViews,
383  baseLayer,
384  activationLayer,
385  activationDesc,
386  name);
387  untouched.erase(baseLayer->GetGuid());
388  untouched.erase(activationLayer->GetGuid());
389  }
390  }
391  }
392  }
393  }
394  }
395  }
396  }
397 
398  if (optimizationViews.GetSubstitutions().empty())
399  {
400  optimizationViews.AddUntouchedSubgraph(SubgraphView(subgraph));
401  }
402  else
403  {
404  ReportUntouchedLayers(optimizationViews, untouched);
405  }
406 
407  return optimizationViews;
408 }
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:30
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 415 of file NeonBackend.cpp.

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

Referenced by NeonBackend::GetId().

416 {
417  auto memoryManager = std::make_shared<NeonMemoryManager>(std::make_unique<arm_compute::Allocator>(),
419 
420  registry.RegisterMemoryManager(memoryManager);
421  registry.RegisterFactory(std::make_unique<NeonTensorHandleFactory>(memoryManager));
422 }

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