ArmNN
 24.02
ClBackend Class Reference

#include <ClBackend.hpp>

Inheritance diagram for ClBackend:
[legend]
Collaboration diagram for ClBackend:
[legend]

Classes

class  ClBackendCustomAllocatorMemoryRegion
 
class  ClBackendCustomAllocatorWrapper
 

Public Member Functions

 ClBackend ()
 
 ClBackend (std::shared_ptr< ICustomAllocator > allocator)
 
 ~ClBackend ()=default
 
const BackendIdGetId () const override
 
IBackendInternal::IMemoryManagerUniquePtr CreateMemoryManager () const override
 
IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory (const IBackendInternal::IMemoryManagerSharedPtr &memoryManager=nullptr) const override
 
IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory (TensorHandleFactoryRegistry &registry) const override
 
IWorkloadFactoryPtr CreateWorkloadFactory (const IMemoryManagerSharedPtr &memoryManager, const ModelOptions &modelOptions) const override
 
IWorkloadFactoryPtr CreateWorkloadFactory (class TensorHandleFactoryRegistry &tensorHandleFactoryRegistry, const ModelOptions &modelOptions) const override
 
IWorkloadFactoryPtr CreateWorkloadFactory (class TensorHandleFactoryRegistry &tensorHandleFactoryRegistry, const ModelOptions &modelOptions, MemorySourceFlags inputFlags, MemorySourceFlags outputFlags) const override
 
std::vector< ITensorHandleFactory::FactoryIdGetHandleFactoryPreferences () const override
 (Optional) Returns a vector of supported TensorHandleFactory ids in preference order. More...
 
void RegisterTensorHandleFactories (TensorHandleFactoryRegistry &registry) override
 (Optional) Register TensorHandleFactories Either this method or CreateMemoryManager() and IWorkloadFactory::CreateTensor() IWorkloadFactory::CreateSubtensor() methods must be implemented. More...
 
void RegisterTensorHandleFactories (TensorHandleFactoryRegistry &registry, MemorySourceFlags inputFlags, MemorySourceFlags outputFlags) override
 (Optional) Register TensorHandleFactories Either this method or CreateMemoryManager() and IWorkloadFactory::CreateTensor() IWorkloadFactory::CreateSubtensor() methods must be implemented. More...
 
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
 
IBackendInternal::IBackendSpecificModelContextPtr CreateBackendSpecificModelContext (const ModelOptions &modelOptions) const override
 
std::unique_ptr< ICustomAllocatorGetDefaultAllocator () const override
 Returns the default memory allocator for the backend. More...
 
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...
 
virtual bool UseCustomMemoryAllocator (std::shared_ptr< ICustomAllocator > allocator, armnn::Optional< std::string & > errMsg) override
 Signals the backend to use a custom memory allocator provided by the user. More...
 
virtual unsigned int GetNumberOfCacheFiles () const override
 Returns the number of files cached if backend supports caching. More...
 
- Public Member Functions inherited from IBackendInternal
 ~IBackendInternal () override=default
 Allow backends created by the factory function to be destroyed through IBackendInternal. More...
 
virtual OptimizationViews OptimizeSubgraphView (const SubgraphView &subgraph) const
 
bool SupportsTensorAllocatorAPI () const
 
ITensorHandleFactory::FactoryId GetBackwardCompatibleFavoriteHandleFactory ()
 
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...
 

Public Attributes

std::shared_ptr< ClBackendCustomAllocatorWrapperm_CustomAllocator
 
bool m_UsingCustomAllocator = false
 

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 24 of file ClBackend.hpp.

Constructor & Destructor Documentation

◆ ClBackend() [1/2]

ClBackend ( )
inline

Definition at line 27 of file ClBackend.hpp.

27 : m_CustomAllocator(nullptr) {};

◆ ClBackend() [2/2]

ClBackend ( std::shared_ptr< ICustomAllocator allocator)
inline

Definition at line 28 of file ClBackend.hpp.

29  {
30  std::string err;
31  UseCustomMemoryAllocator(allocator, err);
32  }

References ClBackend::UseCustomMemoryAllocator().

◆ ~ClBackend()

~ClBackend ( )
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 236 of file ClBackend.cpp.

237 {
238  return IBackendContextPtr{new ClBackendContext{options}};
239 }

◆ 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 241 of file ClBackend.cpp.

243 {
245 }

◆ CreateBackendSpecificModelContext()

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

Reimplemented from IBackendInternal.

Definition at line 247 of file ClBackend.cpp.

249 {
250  return IBackendSpecificModelContextPtr{new ClBackendModelContext{modelOptions}};
251 }

Referenced by ClBackend::CreateWorkloadFactory(), ClBackend::GetLayerSupport(), and ClBackend::OptimizeSubgraphView().

◆ CreateMemoryManager()

IBackendInternal::IMemoryManagerUniquePtr CreateMemoryManager ( ) const
overridevirtual

Reimplemented from IBackendInternal.

Definition at line 51 of file ClBackend.cpp.

52 {
54  {
55  return std::make_unique<ClMemoryManager>(m_CustomAllocator);
56  }
57  return std::make_unique<ClMemoryManager>(std::make_unique<arm_compute::CLBufferAllocator>());
58 }

References ClBackend::m_CustomAllocator, and ClBackend::m_UsingCustomAllocator.

◆ CreateWorkloadFactory() [1/5]

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

Reimplemented from IBackendInternal.

Definition at line 102 of file ClBackend.cpp.

104 {
105  std::shared_ptr<ClMemoryManager> memoryManager;
107  {
108  memoryManager = std::make_shared<ClMemoryManager>(m_CustomAllocator);
109  }
110  else
111  {
112  memoryManager = std::make_shared<ClMemoryManager>(std::make_unique<arm_compute::CLBufferAllocator>());
113  }
114 
115  std::unique_ptr<ITensorHandleFactory> factory = std::make_unique<ClTensorHandleFactory>(memoryManager);
116  std::unique_ptr<ITensorHandleFactory> importFactory = std::make_unique<ClImportTensorHandleFactory>(
118 
119  registry.RegisterCopyAndImportFactoryPair(factory->GetId(), importFactory->GetId());
120  registry.RegisterCopyAndImportFactoryPair(importFactory->GetId(), factory->GetId());
121 
122  registry.RegisterMemoryManager(memoryManager);
123  registry.RegisterFactory(std::move(factory));
124  registry.RegisterFactory(std::move(importFactory));
125 
126  return std::make_unique<ClWorkloadFactory>(
127  PolymorphicPointerDowncast<ClMemoryManager>(memoryManager), CreateBackendSpecificModelContext(modelOptions));
128 }

References ClBackend::CreateBackendSpecificModelContext(), ClBackend::m_CustomAllocator, ClBackend::m_UsingCustomAllocator, armnn::Malloc, TensorHandleFactoryRegistry::RegisterCopyAndImportFactoryPair(), TensorHandleFactoryRegistry::RegisterFactory(), and TensorHandleFactoryRegistry::RegisterMemoryManager().

◆ CreateWorkloadFactory() [2/5]

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

Reimplemented from IBackendInternal.

Definition at line 130 of file ClBackend.cpp.

135 {
136  // To allow force import if inputFlags/outputFlags are Undefined, set it as Malloc
137  if (inputFlags == static_cast<MemorySourceFlags>(MemorySource::Undefined))
138  {
139  inputFlags = static_cast<MemorySourceFlags>(MemorySource::Malloc);
140  }
141  if (outputFlags == static_cast<MemorySourceFlags>(MemorySource::Undefined))
142  {
143  outputFlags = static_cast<MemorySourceFlags>(MemorySource::Malloc);
144  }
145  std::shared_ptr<ClMemoryManager> memoryManager;
147  {
148  memoryManager = std::make_shared<ClMemoryManager>(m_CustomAllocator);
149  }
150  else
151  {
152  memoryManager = std::make_shared<ClMemoryManager>(std::make_unique<arm_compute::CLBufferAllocator>());
153  }
154 
155  std::unique_ptr<ITensorHandleFactory> factory = std::make_unique<ClTensorHandleFactory>(memoryManager);
156  std::unique_ptr<ITensorHandleFactory> importFactory = std::make_unique<ClImportTensorHandleFactory>(
157  inputFlags, outputFlags);
158 
159  registry.RegisterCopyAndImportFactoryPair(factory->GetId(), importFactory->GetId());
160  registry.RegisterCopyAndImportFactoryPair(importFactory->GetId(), factory->GetId());
161 
162  registry.RegisterMemoryManager(memoryManager);
163  registry.RegisterFactory(std::move(factory));
164  registry.RegisterFactory(std::move(importFactory));
165 
166  return std::make_unique<ClWorkloadFactory>(
167  PolymorphicPointerDowncast<ClMemoryManager>(memoryManager), CreateBackendSpecificModelContext(modelOptions));
168 }

References ClBackend::CreateBackendSpecificModelContext(), ClBackend::m_CustomAllocator, ClBackend::m_UsingCustomAllocator, armnn::Malloc, TensorHandleFactoryRegistry::RegisterCopyAndImportFactoryPair(), TensorHandleFactoryRegistry::RegisterFactory(), TensorHandleFactoryRegistry::RegisterMemoryManager(), and armnn::Undefined.

◆ CreateWorkloadFactory() [3/5]

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

Implements IBackendInternal.

Definition at line 60 of file ClBackend.cpp.

62 {
63  return std::make_unique<ClWorkloadFactory>(
64  PolymorphicPointerDowncast<ClMemoryManager>(memoryManager));
65 }

◆ CreateWorkloadFactory() [4/5]

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

Reimplemented from IBackendInternal.

Definition at line 67 of file ClBackend.cpp.

69 {
70  return std::make_unique<ClWorkloadFactory>(
71  PolymorphicPointerDowncast<ClMemoryManager>(memoryManager), CreateBackendSpecificModelContext(modelOptions));
72 }

References ClBackend::CreateBackendSpecificModelContext().

◆ CreateWorkloadFactory() [5/5]

IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory ( TensorHandleFactoryRegistry registry) const
overridevirtual

Reimplemented from IBackendInternal.

Definition at line 74 of file ClBackend.cpp.

76 {
77  std::shared_ptr<ClMemoryManager> memoryManager;
79  {
80  memoryManager = std::make_shared<ClMemoryManager>(m_CustomAllocator);
81  }
82  else
83  {
84  memoryManager = std::make_shared<ClMemoryManager>(std::make_unique<arm_compute::CLBufferAllocator>());
85  }
86 
87  std::unique_ptr<ITensorHandleFactory> factory = std::make_unique<ClTensorHandleFactory>(memoryManager);
88  std::unique_ptr<ITensorHandleFactory> importFactory = std::make_unique<ClImportTensorHandleFactory>(
90 
91  registry.RegisterCopyAndImportFactoryPair(factory->GetId(), importFactory->GetId());
92  registry.RegisterCopyAndImportFactoryPair(importFactory->GetId(), factory->GetId());
93 
94  registry.RegisterMemoryManager(memoryManager);
95  registry.RegisterFactory(std::move(factory));
96  registry.RegisterFactory(std::move(importFactory));
97 
98  return std::make_unique<ClWorkloadFactory>(
99  PolymorphicPointerDowncast<ClMemoryManager>(memoryManager));
100 }

References ClBackend::m_CustomAllocator, ClBackend::m_UsingCustomAllocator, armnn::Malloc, TensorHandleFactoryRegistry::RegisterCopyAndImportFactoryPair(), TensorHandleFactoryRegistry::RegisterFactory(), and TensorHandleFactoryRegistry::RegisterMemoryManager().

◆ GetCapabilities()

BackendCapabilities GetCapabilities ( ) const
overridevirtual

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 276 of file ClBackend.cpp.

277 {
278  // add new capabilities here..
279  return BackendCapabilities ("GpuAcc",
280  {
281  {"NonConstWeights", true},
282  {"AsyncExecution", false},
283  {"ProtectedContentAllocation", true},
284  {"ConstantTensorsAsInputs", true},
285  {"PreImportIOTensors", false},
286  {"ExternallyManagedMemory", true},
287  {"MultiAxisPacking", false},
288  {"SingleAxisPacking", true},
289  {"HasFp16", arm_compute::CLKernelLibrary::get().fp16_supported()}
290  });
291 }

◆ 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 271 of file ClBackend.cpp.

272 {
273  return std::make_unique<ClBackendDefaultAllocator>();
274 }

◆ 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 170 of file ClBackend.cpp.

171 {
172  return std::vector<ITensorHandleFactory::FactoryId> {ClTensorHandleFactory::GetIdStatic(),
174 }

References ClTensorHandleFactory::GetIdStatic(), and ClImportTensorHandleFactory::GetIdStatic().

◆ GetId()

const BackendId& GetId ( ) const
inlineoverridevirtual

Implements IBackend.

Definition at line 36 of file ClBackend.hpp.

36 { return GetIdStatic(); }

References ClBackend::GetIdStatic().

◆ GetIdStatic()

const BackendId & GetIdStatic ( )
static

Definition at line 45 of file ClBackend.cpp.

46 {
47  static const BackendId s_Id{ClBackendId()};
48  return s_Id;
49 }

References armnn::ClBackendId().

Referenced by ClBackend::GetId().

◆ GetLayerSupport() [1/2]

IBackendInternal::ILayerSupportSharedPtr GetLayerSupport ( ) const
overridevirtual

Implements IBackendInternal.

Definition at line 253 of file ClBackend.cpp.

254 {
255  static ILayerSupportSharedPtr layerSupport
256  {
258  };
259  return layerSupport;
260 }

◆ GetLayerSupport() [2/2]

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

Reimplemented from IBackendInternal.

Definition at line 262 of file ClBackend.cpp.

263 {
264  static ILayerSupportSharedPtr layerSupport
265  {
266  new ClLayerSupport(CreateBackendSpecificModelContext(modelOptions))
267  };
268  return layerSupport;
269 }

References ClBackend::CreateBackendSpecificModelContext().

◆ GetNumberOfCacheFiles()

virtual unsigned int GetNumberOfCacheFiles ( ) const
inlineoverridevirtual

Returns the number of files cached if backend supports caching.

Returns
- Returns 0 if backend does not support caching otherwise number of files cached

Reimplemented from IBackendInternal.

Definition at line 94 of file ClBackend.hpp.

94 { return 1; }

◆ OptimizeSubgraphView()

OptimizationViews OptimizeSubgraphView ( const SubgraphView subgraph,
const ModelOptions modelOptions 
) const
overridevirtual

Reimplemented from IBackendInternal.

Definition at line 293 of file ClBackend.cpp.

295 {
296  OptimizationViews optimizationViews(modelOptions);
297 
298  auto it = subgraph.end();
299  bool isFastMathEnabled = false;
300  std::map<LayerGuid, Layer*> untouched;
301 
302  while (it != subgraph.begin())
303  {
304  --it;
305  Layer& base = *(PolymorphicDowncast<Layer*>(*it));
306  untouched.insert({base.GetGuid(), &base});
307  }
308 
309  it = subgraph.end();
310 #if defined(ARMCOMPUTECL_ENABLED)
312 
313  if (modelContextPtr)
314  {
315  auto clModelOptions = dynamic_cast<ClBackendModelContext*>(modelContextPtr.get());
316  if (clModelOptions)
317  {
318  isFastMathEnabled = clModelOptions->IsFastMathEnabled();
319  }
320  }
321 #endif
322  while (it != subgraph.begin())
323  {
324  --it;
325  Layer& base = *(PolymorphicDowncast<Layer*>(*it));
326 
327  // Fuse activation into previous layer if supported by backend
328  if ((base.GetType() == LayerType::DepthwiseConvolution2d || base.GetType() == LayerType::Convolution2d
329  || base.GetType() == LayerType::BatchNormalization || base.GetType() == LayerType::FullyConnected
330  || base.GetType() == LayerType::Addition || base.GetType() == LayerType::Multiplication
331  || base.GetType() == LayerType::Subtraction || base.GetType() == LayerType::Division
332  || base.GetType() == LayerType::ElementwiseBinary)
333  && (base.GetAdditionalInformation<ActivationDescriptor>() == nullptr))
334  {
335  for (auto output = base.BeginOutputSlots(); output != base.EndOutputSlots(); ++output)
336  {
337  if (output->GetNumConnections() == 1)
338  {
339  for (auto&& childInput : output->GetConnections())
340  {
341  if ((childInput->GetOwningLayer().GetType() == LayerType::Activation) &&
342  (checkDataTypeInputandOutput(childInput->GetOwningLayer())))
343  {
344  Layer& child = childInput->GetOwningLayer();
345 
346  auto* activationLayer = PolymorphicDowncast<ActivationLayer*>(&child);
347 
348  const std::string name = std::string("fused-") + child.GetName() + std::string("-into-") +
349  base.GetName();
350 
351  // Get params from activation layer
352  ActivationDescriptor activationDesc = activationLayer->GetParameters();
353 
354  if (base.GetType() == LayerType::Convolution2d)
355  {
356  Convolution2dLayer* baseLayer = PolymorphicDowncast<Convolution2dLayer*>(&base);
357 
358  Optional<TensorInfo> biases;
359 
360  if (baseLayer->GetParameters().m_BiasEnabled)
361  {
362  biases = baseLayer->GetInputSlot(2).GetConnectedOutputSlot()->GetTensorInfo();
363  }
364 
366  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
367  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
368  baseLayer->GetParameters(),
369  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
370  biases,
371  isFastMathEnabled,
372  &activationDesc);
373 
374  if (status)
375  {
376  FuseConvolution2dLayer<Convolution2dLayer>(optimizationViews,
377  baseLayer,
378  activationLayer,
379  activationDesc,
380  name);
381  untouched.erase(baseLayer->GetGuid());
382  untouched.erase(activationLayer->GetGuid());
383  }
384  }
385  else if (base.GetType() == LayerType::DepthwiseConvolution2d)
386  {
387  DepthwiseConvolution2dLayer* baseLayer =
388  PolymorphicDowncast<DepthwiseConvolution2dLayer*>(&base);
389 
390  Optional<TensorInfo> biases;
391 
392  if (baseLayer->GetParameters().m_BiasEnabled)
393  {
394  biases = baseLayer->GetInputSlot(2).GetConnectedOutputSlot()->GetTensorInfo();
395  }
396 
398  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
399  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
400  baseLayer->GetParameters(),
401  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
402  biases,
403  &activationDesc);
404 
405  if (status)
406  {
407  FuseDepthwiseConvolution2dLayer<DepthwiseConvolution2dLayer>(optimizationViews,
408  baseLayer,
409  activationLayer,
410  activationDesc,
411  name);
412  untouched.erase(baseLayer->GetGuid());
413  untouched.erase(activationLayer->GetGuid());
414  }
415  }
416  else if (base.GetType() == LayerType::FullyConnected)
417  {
418  FullyConnectedLayer* baseLayer = PolymorphicDowncast<FullyConnectedLayer*>(&base);
419  FullyConnectedDescriptor descriptor = baseLayer->GetParameters();
420 
421  // As bias is optional only try to get TensorInfo from input if bias is enabled.
422  Optional<TensorInfo> biases;
423  if (descriptor.m_BiasEnabled)
424  {
425  biases = baseLayer->GetInputSlot(2).GetConnectedOutputSlot()->GetTensorInfo();
426  }
427 
429  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
430  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
431  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
432  biases,
433  baseLayer->GetParameters(),
434  &activationDesc);
435 
436  if (status)
437  {
438  FuseFullyConnectedLayer<FullyConnectedLayer>(optimizationViews,
439  baseLayer,
440  activationLayer,
441  activationDesc,
442  name);
443  untouched.erase(baseLayer->GetGuid());
444  untouched.erase(activationLayer->GetGuid());
445  }
446  }
447  else if (base.GetType() == LayerType::BatchNormalization)
448  {
449  BatchNormalizationLayer* baseLayer =
450  PolymorphicDowncast<BatchNormalizationLayer*>(&base);
451 
453  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
454  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
455  baseLayer->m_Mean->GetTensorInfo(),
456  baseLayer->m_Variance->GetTensorInfo(),
457  baseLayer->m_Beta->GetTensorInfo(),
458  baseLayer->m_Gamma->GetTensorInfo(),
459  baseLayer->GetParameters(),
460  &activationDesc);
461 
462  if (status)
463  {
464  BatchNormalizationLayer* replacementLayer =
465  FuseBatchNormalizationLayer<BatchNormalizationLayer>(optimizationViews,
466  baseLayer,
467  activationLayer,
468  activationDesc,
469  name);
470 
471  replacementLayer->m_Beta = std::move(baseLayer->m_Beta);
472  replacementLayer->m_Gamma = std::move(baseLayer->m_Gamma);
473  replacementLayer->m_Mean = std::move(baseLayer->m_Mean);
474  replacementLayer->m_Variance = std::move(baseLayer->m_Variance);
475 
476  untouched.erase(baseLayer->GetGuid());
477  untouched.erase(activationLayer->GetGuid());
478  }
479  }
480  else if (base.GetType() == LayerType::Addition)
481  {
482  AdditionLayer* baseLayer = PolymorphicDowncast<AdditionLayer*>(&base);
483 
485  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
486  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
487  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
488  &activationDesc);
489 
490  if (status)
491  {
492  FuseAdditionLayer<AdditionLayer>(optimizationViews,
493  baseLayer,
494  activationLayer,
495  activationDesc,
496  name);
497 
498  untouched.erase(baseLayer->GetGuid());
499  untouched.erase(activationLayer->GetGuid());
500  }
501  }
502  else if (base.GetType() == LayerType::Division)
503  {
504  DivisionLayer* baseLayer = PolymorphicDowncast<DivisionLayer*>(&base);
505 
507  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
508  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
509  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
510  &activationDesc);
511 
512  if (status)
513  {
514  FuseDivisionLayer<DivisionLayer>(optimizationViews,
515  baseLayer,
516  activationLayer,
517  activationDesc,
518  name);
519  untouched.erase(baseLayer->GetGuid());
520  untouched.erase(activationLayer->GetGuid());
521  }
522  }
523  else if (base.GetType() == LayerType::Multiplication)
524  {
525  MultiplicationLayer* baseLayer = PolymorphicDowncast<MultiplicationLayer*>(&base);
526 
528  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
529  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
530  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
531  &activationDesc);
532 
533  if (status)
534  {
535  FuseMultiplicationLayer<MultiplicationLayer>(optimizationViews,
536  baseLayer,
537  activationLayer,
538  activationDesc,
539  name);
540  untouched.erase(baseLayer->GetGuid());
541  untouched.erase(activationLayer->GetGuid());
542  }
543  }
544  else if (base.GetType() == LayerType::Subtraction)
545  {
546  SubtractionLayer* baseLayer = PolymorphicDowncast<SubtractionLayer*>(&base);
547 
549  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
550  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
551  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
552  &activationDesc);
553 
554  if (status)
555  {
556  FuseSubtractionLayer<SubtractionLayer>(optimizationViews,
557  baseLayer,
558  activationLayer,
559  activationDesc,
560  name);
561  untouched.erase(baseLayer->GetGuid());
562  untouched.erase(activationLayer->GetGuid());
563  }
564  }
565  else if (base.GetType() == LayerType::ElementwiseBinary)
566  {
567  ElementwiseBinaryLayer* baseLayer = PolymorphicDowncast<ElementwiseBinaryLayer*>(&base);
568 
569  if (baseLayer->GetParameters().m_Operation == BinaryOperation::Add)
570  {
572  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
573  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
574  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
575  &activationDesc);
576 
577  if (status)
578  {
579  FuseElementwiseBinaryLayer<ElementwiseBinaryLayer>(optimizationViews,
580  baseLayer,
581  activationLayer,
582  activationDesc,
584  name);
585  untouched.erase(baseLayer->GetGuid());
586  untouched.erase(activationLayer->GetGuid());
587  }
588  }
589  else if (baseLayer->GetParameters().m_Operation == BinaryOperation::Div)
590  {
592  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
593  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
594  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
595  &activationDesc);
596 
597  if (status)
598  {
599  FuseElementwiseBinaryLayer<ElementwiseBinaryLayer>(optimizationViews,
600  baseLayer,
601  activationLayer,
602  activationDesc,
604  name);
605  untouched.erase(baseLayer->GetGuid());
606  untouched.erase(activationLayer->GetGuid());
607  }
608  }
609  else if (baseLayer->GetParameters().m_Operation == BinaryOperation::Mul)
610  {
612  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
613  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
614  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
615  &activationDesc);
616 
617  if (status)
618  {
619  FuseElementwiseBinaryLayer<ElementwiseBinaryLayer>(optimizationViews,
620  baseLayer,
621  activationLayer,
622  activationDesc,
624  name);
625  untouched.erase(baseLayer->GetGuid());
626  untouched.erase(activationLayer->GetGuid());
627  }
628  }
629  else if (baseLayer->GetParameters().m_Operation == BinaryOperation::Sub)
630  {
632  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
633  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
634  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
635  &activationDesc);
636 
637  if (status)
638  {
639  FuseElementwiseBinaryLayer<ElementwiseBinaryLayer>(optimizationViews,
640  baseLayer,
641  activationLayer,
642  activationDesc,
644  name);
645  untouched.erase(baseLayer->GetGuid());
646  untouched.erase(activationLayer->GetGuid());
647  }
648  }
649  // No fusion available for other BinaryOperations
650  }
651  }
652  }
653  }
654  }
655  }
656 
657  // Separate reduce layer with multiple axes into multiple reduce layers with 1 axis.
658  if (base.GetType() == LayerType::Reduce)
659  {
660  ReduceLayer* baseLayer = PolymorphicDowncast<ReduceLayer*>(&base);
661  ReduceDescriptor reduceDescriptor = baseLayer->GetParameters();
662 
663  if (!reduceDescriptor.m_vAxis.empty() && reduceDescriptor.m_vAxis.size() > 1)
664  {
665  // Add new layers to the graph and connect them.
666  std::vector<IConnectableLayer*> layers = ChainReduceLayers<ReduceLayer>(optimizationViews,
667  baseLayer,
668  reduceDescriptor);
669 
670  // Replace existing baselayer with new subgraph.
671  ReplaceLayers<ReduceLayer>(optimizationViews, baseLayer, layers);
672  untouched.erase(baseLayer->GetGuid());
673  }
674  }
675 
676  // Remove Reshape where possible
677  if (base.GetType() == LayerType::Reshape)
678  {
679  ReshapeLayer* baseLayer = PolymorphicDowncast<ReshapeLayer*>(&base);
680 
681  // Cannot remove a Reshape if it's connected to any layer that has an NCHW layout
682  if (ConnectedToLayerWithNCHW(baseLayer))
683  {
684  continue;
685  }
686  RemoveReshapeLayer(baseLayer, untouched, optimizationViews);
687  }
688 
689  // Special case to fuse padding into average pooling 2d for quantized datatype.
690  // Required to be done as a backend specific optimization as Neon does not support this special case.
691  if (base.GetType() == LayerType::Pooling2d)
692  {
693  Pooling2dLayer* baseLayer = PolymorphicDowncast<Pooling2dLayer*>(&base);
694  Pooling2dDescriptor poolingDescriptor = baseLayer->GetParameters();
695 
696  if (baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetOwningLayer().GetType() == LayerType::Pad)
697  {
698  PadLayer* padLayer = PolymorphicDowncast<PadLayer*>(
699  &baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetOwningLayer());
700  if (padLayer->GetOutputSlot(0).GetNumConnections() == 1 &&
701  optimizations::pad_fold::TryFoldPadIntoLayer2d(padLayer->GetParameters(),
702  poolingDescriptor,
703  padLayer->GetOutputSlot().GetTensorInfo(),
704  true))
705  {
706  FoldPadIntoAveragePool2d<Pooling2dLayer>(optimizationViews, baseLayer,
707  poolingDescriptor, padLayer);
708  untouched.erase(baseLayer->GetGuid());
709  untouched.erase(padLayer->GetGuid());
710  }
711  }
712  }
713  }
714 
715  if (optimizationViews.GetSubstitutions().empty() && optimizationViews.GetDeletedSubgraphs().empty())
716  {
717  optimizationViews.AddUntouchedSubgraph(SubgraphView(subgraph));
718  }
719  else
720  {
721  ReportUntouchedLayers(optimizationViews, untouched);
722  }
723 
724  return optimizationViews;
725 }

References armnn::Activation, armnn::Add, armnn::Addition, OptimizationViews::AddUntouchedSubgraph(), armnn::BatchNormalization, SubgraphView::begin(), Layer::BeginOutputSlots(), armnn::ClAdditionValidate(), armnn::ClBatchNormalizationValidate(), armnn::ClConvolution2dWorkloadValidate(), armnn::ClDepthwiseConvolutionWorkloadValidate(), armnn::ClDivisionWorkloadValidate(), armnn::ClFullyConnectedWorkloadValidate(), armnn::ClMultiplicationWorkloadValidate(), armnn::ClSubtractionValidate(), armnn::ConnectedToLayerWithNCHW(), armnn::Convolution2d, ClBackend::CreateBackendSpecificModelContext(), armnn::DepthwiseConvolution2d, armnn::Div, armnn::Division, armnn::ElementwiseBinary, SubgraphView::end(), Layer::EndOutputSlots(), armnn::FullyConnected, Layer::GetAdditionalInformation(), InputSlot::GetConnectedOutputSlot(), OptimizationViews::GetDeletedSubgraphs(), Layer::GetGuid(), Layer::GetInputSlot(), Layer::GetName(), OutputSlot::GetNumConnections(), Layer::GetOutputSlot(), OutputSlot::GetOwningLayer(), LayerWithParameters< Parameters >::GetParameters(), OptimizationViews::GetSubstitutions(), OutputSlot::GetTensorInfo(), Layer::GetType(), ClBackendModelContext::IsFastMathEnabled(), BatchNormalizationLayer::m_Beta, FullyConnectedDescriptor::m_BiasEnabled, Convolution2dDescriptor::m_BiasEnabled, DepthwiseConvolution2dDescriptor::m_BiasEnabled, BatchNormalizationLayer::m_Gamma, BatchNormalizationLayer::m_Mean, ElementwiseBinaryDescriptor::m_Operation, BatchNormalizationLayer::m_Variance, ReduceDescriptor::m_vAxis, armnn::Mul, armnn::Multiplication, armnn::Pad, armnn::Pooling2d, armnn::Reduce, armnn::RemoveReshapeLayer(), armnn::ReportUntouchedLayers(), armnn::Reshape, armnn::Sub, armnn::Subtraction, and armnn::optimizations::pad_fold::TryFoldPadIntoLayer2d().

◆ RegisterTensorHandleFactories() [1/2]

void RegisterTensorHandleFactories ( 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 176 of file ClBackend.cpp.

177 {
178  std::shared_ptr<ClMemoryManager> memoryManager;
180  {
181  memoryManager = std::make_shared<ClMemoryManager>(m_CustomAllocator);
182  }
183  else
184  {
185  memoryManager = std::make_shared<ClMemoryManager>(std::make_unique<arm_compute::CLBufferAllocator>());
186  }
187 
188  std::unique_ptr<ITensorHandleFactory> factory = std::make_unique<ClTensorHandleFactory>(memoryManager);
189  std::unique_ptr<ITensorHandleFactory> importFactory = std::make_unique<ClImportTensorHandleFactory>(
191 
192  registry.RegisterCopyAndImportFactoryPair(factory->GetId(), importFactory->GetId());
193  registry.RegisterCopyAndImportFactoryPair(importFactory->GetId(), factory->GetId());
194 
195  registry.RegisterMemoryManager(memoryManager);
196  registry.RegisterFactory(std::move(factory));
197  registry.RegisterFactory(std::move(importFactory));
198 
199 }

References ClBackend::m_CustomAllocator, ClBackend::m_UsingCustomAllocator, armnn::Malloc, TensorHandleFactoryRegistry::RegisterCopyAndImportFactoryPair(), TensorHandleFactoryRegistry::RegisterFactory(), and TensorHandleFactoryRegistry::RegisterMemoryManager().

◆ RegisterTensorHandleFactories() [2/2]

void RegisterTensorHandleFactories ( TensorHandleFactoryRegistry registry,
MemorySourceFlags  inputFlags,
MemorySourceFlags  outputFlags 
)
overridevirtual

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

Reimplemented from IBackendInternal.

Definition at line 201 of file ClBackend.cpp.

204 {
205  // To allow force import if inputFlags/outputFlags are Undefined, set it as Malloc
206  if (inputFlags == static_cast<MemorySourceFlags>(MemorySource::Undefined))
207  {
208  inputFlags = static_cast<MemorySourceFlags>(MemorySource::Malloc);
209  }
210  if (outputFlags == static_cast<MemorySourceFlags>(MemorySource::Undefined))
211  {
212  outputFlags = static_cast<MemorySourceFlags>(MemorySource::Malloc);
213  }
214  std::shared_ptr<ClMemoryManager> memoryManager;
216  {
217  memoryManager = std::make_shared<ClMemoryManager>(m_CustomAllocator);
218  }
219  else
220  {
221  memoryManager = std::make_shared<ClMemoryManager>(std::make_unique<arm_compute::CLBufferAllocator>());
222  }
223 
224  std::unique_ptr<ITensorHandleFactory> factory = std::make_unique<ClTensorHandleFactory>(memoryManager);
225  std::unique_ptr<ITensorHandleFactory> importFactory = std::make_unique<ClImportTensorHandleFactory>(
226  inputFlags, outputFlags);
227 
228  registry.RegisterCopyAndImportFactoryPair(factory->GetId(), importFactory->GetId());
229  registry.RegisterCopyAndImportFactoryPair(importFactory->GetId(), factory->GetId());
230 
231  registry.RegisterMemoryManager(memoryManager);
232  registry.RegisterFactory(std::move(factory));
233  registry.RegisterFactory(std::move(importFactory));
234 }

References ClBackend::m_CustomAllocator, ClBackend::m_UsingCustomAllocator, armnn::Malloc, TensorHandleFactoryRegistry::RegisterCopyAndImportFactoryPair(), TensorHandleFactoryRegistry::RegisterFactory(), TensorHandleFactoryRegistry::RegisterMemoryManager(), and armnn::Undefined.

◆ UseCustomMemoryAllocator()

virtual bool UseCustomMemoryAllocator ( std::shared_ptr< ICustomAllocator allocator,
armnn::Optional< std::string & >  errMsg 
)
inlineoverridevirtual

Signals the backend to use a custom memory allocator provided by the user.

Parameters
allocator- a pointer to the provided ICustomAllocator to use with this backend
errMsg- Optional string variable to return error messages
Returns
- Returns true if switching to custom allocator was successful

Reimplemented from IBackendInternal.

Definition at line 82 of file ClBackend.hpp.

84  {
85  IgnoreUnused(errMsg);
86  ARMNN_LOG(info) << "Using Custom Allocator for ClBackend";
87 
88  // Set flag to signal the backend to use a custom memory allocator
89  m_CustomAllocator = std::make_shared<ClBackendCustomAllocatorWrapper>(std::move(allocator));
92  }

References ARMNN_LOG, armnn::IgnoreUnused(), armnn::info, ClBackend::m_CustomAllocator, and ClBackend::m_UsingCustomAllocator.

Referenced by ClBackend::ClBackend().

Member Data Documentation

◆ m_CustomAllocator

◆ m_UsingCustomAllocator


The documentation for this class was generated from the following files:
armnn::MemorySource::Malloc
@ Malloc
armnn::BinaryOperation::Mul
@ Mul
armnn::BinaryOperation::Add
@ Add
armnn::ClBackend::m_UsingCustomAllocator
bool m_UsingCustomAllocator
Definition: ClBackend.hpp:284
armnn::LayerType::BatchNormalization
@ BatchNormalization
armnn::ClSubtractionValidate
arm_compute::Status ClSubtractionValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
Definition: ClSubtractionWorkload.cpp:46
armnn::ClTensorHandleFactory::GetIdStatic
static const FactoryId & GetIdStatic()
Definition: ClTensorHandleFactory.cpp:93
armnn::ClMultiplicationWorkloadValidate
arm_compute::Status ClMultiplicationWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
Definition: ClMultiplicationWorkload.cpp:18
armnn::BackendCapabilities
BackendOptions BackendCapabilities
Definition: BackendOptions.hpp:19
armnn::BinaryOperation::Sub
@ Sub
armnn::MemorySourceFlags
unsigned int MemorySourceFlags
Definition: MemorySources.hpp:15
armnn::ClFullyConnectedWorkloadValidate
arm_compute::Status ClFullyConnectedWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const TensorInfo &weights, const Optional< TensorInfo > &biases, const FullyConnectedDescriptor &descriptor, const ActivationDescriptor *activationDescriptor)
Definition: ClFullyConnectedWorkload.cpp:19
armnn::ClConvolution2dWorkloadValidate
arm_compute::Status ClConvolution2dWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const Convolution2dDescriptor &descriptor, const TensorInfo &weights, const Optional< TensorInfo > &biases, bool isFastMathEnabled, const ActivationDescriptor *activationDescriptor)
Definition: ClConvolution2dWorkload.cpp:23
armnn::LayerType::Reduce
@ Reduce
armnn::IBackendInternal::IBackendContextPtr
std::unique_ptr< IBackendContext > IBackendContextPtr
Definition: IBackendInternal.hpp:90
armnn::LayerType::ElementwiseBinary
@ ElementwiseBinary
armnn::ClBackend::UseCustomMemoryAllocator
virtual bool UseCustomMemoryAllocator(std::shared_ptr< ICustomAllocator > allocator, armnn::Optional< std::string & > errMsg) override
Signals the backend to use a custom memory allocator provided by the user.
Definition: ClBackend.hpp:82
ARMNN_LOG
#define ARMNN_LOG(severity)
Definition: Logging.hpp:212
armnn::ClImportTensorHandleFactory::GetIdStatic
static const FactoryId & GetIdStatic()
Definition: ClImportTensorHandleFactory.cpp:93
armnn::ClAdditionValidate
arm_compute::Status ClAdditionValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
Definition: ClAdditionWorkload.cpp:45
armnn::optimizations::pad_fold::TryFoldPadIntoLayer2d
bool TryFoldPadIntoLayer2d(const PadDescriptor &padDescriptor, Descriptor &layerDescriptor, const TensorInfo &tensorInfo)
Definition: FoldPadIntoLayer2d.hpp:88
armnn::LayerType::Subtraction
@ Subtraction
armnn::RemoveReshapeLayer
void RemoveReshapeLayer(ReshapeLayer *baseLayer, std::map< LayerGuid, Layer * > &untouched, OptimizationViews &optimizationViews)
Definition: SubgraphUtils.hpp:293
armnn::MemorySource::Undefined
@ Undefined
armnn::LayerType::Multiplication
@ Multiplication
armnn::ClBackend::m_CustomAllocator
std::shared_ptr< ClBackendCustomAllocatorWrapper > m_CustomAllocator
Definition: ClBackend.hpp:283
armnn::LayerType::Addition
@ Addition
armnn::LayerType::Pooling2d
@ Pooling2d
armnn::LayerType::Division
@ Division
armnn::IBackendInternal::IBackendProfilingContextPtr
std::shared_ptr< arm::pipe::IBackendProfilingContext > IBackendProfilingContextPtr
This is the bridge between backend and backend profiling we'll keep it in the backend namespace.
Definition: IBackendInternal.hpp:92
armnn::LayerType::FullyConnected
@ FullyConnected
armnn::LayerType::DepthwiseConvolution2d
@ DepthwiseConvolution2d
armnn::Status
Status
Definition: Types.hpp:42
armnn::LayerType::Reshape
@ Reshape
armnn::ClBatchNormalizationValidate
arm_compute::Status ClBatchNormalizationValidate(const TensorInfo &input, const TensorInfo &output, const TensorInfo &mean, const TensorInfo &var, const TensorInfo &beta, const TensorInfo &gamma, const BatchNormalizationDescriptor &descriptor, const ActivationDescriptor *activationDescriptor)
Definition: ClBatchNormalizationFloatWorkload.cpp:19
armnn::IgnoreUnused
void IgnoreUnused(Ts &&...)
Definition: IgnoreUnused.hpp:14
armnn::ClDivisionWorkloadValidate
arm_compute::Status ClDivisionWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
Definition: ClDivisionWorkload.cpp:18
armnn::ClBackend::GetIdStatic
static const BackendId & GetIdStatic()
Definition: ClBackend.cpp:45
armnn::LayerType::Pad
@ Pad
armnn::ClBackend::CreateBackendSpecificModelContext
IBackendInternal::IBackendSpecificModelContextPtr CreateBackendSpecificModelContext(const ModelOptions &modelOptions) const override
Definition: ClBackend.cpp:247
armnn::ClBackendId
constexpr const char * ClBackendId()
Definition: ClBackendId.hpp:10
armnn::IBackendInternal::ILayerSupportSharedPtr
std::shared_ptr< ILayerSupport > ILayerSupportSharedPtr
Definition: IBackendInternal.hpp:94
armnn::ReportUntouchedLayers
void ReportUntouchedLayers(OptimizationViews &optimizationViews, std::map< LayerGuid, Layer * > untouched)
Definition: SubgraphUtils.hpp:220
armnn::ConnectedToLayerWithNCHW
bool ConnectedToLayerWithNCHW(Layer *baseLayer)
Checks if the Layer is connected to any Layer that has an NCHW layout.
Definition: SubgraphUtils.hpp:250
armnn::BinaryOperation::Div
@ Div
armnn::LayerType::Convolution2d
@ Convolution2d
armnn::LayerType::Activation
@ Activation
armnn::ClDepthwiseConvolutionWorkloadValidate
arm_compute::Status ClDepthwiseConvolutionWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const DepthwiseConvolution2dDescriptor &descriptor, const TensorInfo &weights, const Optional< TensorInfo > &biases, const ActivationDescriptor *activationDescriptor)
Definition: ClDepthwiseConvolutionWorkload.cpp:26
armnn::IBackendInternal::IBackendSpecificModelContextPtr
std::shared_ptr< IBackendModelContext > IBackendSpecificModelContextPtr
Definition: IBackendInternal.hpp:96
armnnDeserializer::Pooling2dDescriptor
const armnnSerializer::Pooling2dDescriptor * Pooling2dDescriptor
Definition: Deserializer.hpp:21