ArmNN
 23.05
ClBackend Class Reference

#include <ClBackend.hpp>

Inheritance diagram for ClBackend:
IBackendInternal IBackend

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

Constructor & Destructor Documentation

◆ ClBackend() [1/2]

ClBackend ( )
inline

Definition at line 40 of file ClBackend.hpp.

40 : m_CustomAllocator(nullptr) {};

◆ ClBackend() [2/2]

ClBackend ( std::shared_ptr< ICustomAllocator allocator)
inline

Definition at line 41 of file ClBackend.hpp.

42  {
43  std::string err;
44  UseCustomMemoryAllocator(allocator, err);
45  }

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

94  {
95  return gpuAccCapabilities;
96  };

References armnn::gpuAccCapabilities.

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

49 { 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 110 of file ClBackend.hpp.

110 { return 1; }

◆ OptimizeSubgraphView()

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

Reimplemented from IBackendInternal.

Definition at line 276 of file ClBackend.cpp.

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

References armnn::Activation, armnn::Add, armnn::Addition, OptimizationViews::AddUntouchedSubgraph(), armnn::BatchNormalization, SubgraphView::beginIConnectable(), Layer::BeginOutputSlots(), armnn::ClAdditionValidate(), armnn::ClBatchNormalizationValidate(), armnn::ClConvolution2dWorkloadValidate(), armnn::ClDepthwiseConvolutionWorkloadValidate(), armnn::ClDivisionWorkloadValidate(), armnn::ClFullyConnectedWorkloadValidate(), armnn::ClMultiplicationWorkloadValidate(), armnn::ClSubtractionValidate(), armnn::Convolution2d, ClBackend::CreateBackendSpecificModelContext(), armnn::DepthwiseConvolution2d, armnn::Div, armnn::Division, armnn::ElementwiseBinary, SubgraphView::endIConnectable(), Layer::EndOutputSlots(), armnn::FullyConnected, Layer::GetAdditionalInformation(), InputSlot::GetConnectedOutputSlot(), 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::ReportUntouchedLayers(), 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 98 of file ClBackend.hpp.

100  {
101  IgnoreUnused(errMsg);
102  ARMNN_LOG(info) << "Using Custom Allocator for ClBackend";
103 
104  // Set flag to signal the backend to use a custom memory allocator
105  m_CustomAllocator = std::make_shared<ClBackendCustomAllocatorWrapper>(std::move(allocator));
106  m_UsingCustomAllocator = true;
107  return m_UsingCustomAllocator;
108  }

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::ClDivisionWorkloadValidate
arm_compute::Status ClDivisionWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
Definition: ClDivisionWorkload.cpp:18
armnn::LayerType::FullyConnected
@ FullyConnected
armnn::MemorySource::Undefined
@ Undefined
armnn::LayerType::ElementwiseBinary
@ ElementwiseBinary
armnn::MemorySource::Malloc
@ Malloc
armnn::ClBackend::GetIdStatic
static const BackendId & GetIdStatic()
Definition: ClBackend.cpp:45
armnn::LayerType::Subtraction
@ Subtraction
armnn::LayerType::Convolution2d
@ Convolution2d
armnn::IgnoreUnused
void IgnoreUnused(Ts &&...)
Definition: IgnoreUnused.hpp:14
armnn::ClBackend::m_UsingCustomAllocator
bool m_UsingCustomAllocator
Definition: ClBackend.hpp:300
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::gpuAccCapabilities
const BackendCapabilities gpuAccCapabilities("GpuAcc", { {"NonConstWeights", true}, {"AsyncExecution", false}, {"ProtectedContentAllocation", true}, {"ConstantTensorsAsInputs", true}, {"PreImportIOTensors", false}, {"ExternallyManagedMemory", true}, {"MultiAxisPacking", false}, {"SingleAxisPacking", true} })
armnnDeserializer::Pooling2dDescriptor
const armnnSerializer::Pooling2dDescriptor * Pooling2dDescriptor
Definition: Deserializer.hpp:21
armnn::LayerType::Pad
@ Pad
armnn::LayerType::Addition
@ Addition
armnn::ClTensorHandleFactory::GetIdStatic
static const FactoryId & GetIdStatic()
Definition: ClTensorHandleFactory.cpp:93
armnn::LayerType::BatchNormalization
@ BatchNormalization
armnn::LayerType::Reduce
@ Reduce
ARMNN_LOG
#define ARMNN_LOG(severity)
Definition: Logging.hpp:212
armnn::LayerType::Division
@ Division
armnn::ReportUntouchedLayers
void ReportUntouchedLayers(OptimizationViews &optimizationViews, std::map< LayerGuid, Layer * > untouched)
Definition: SubgraphUtils.hpp:52
armnn::optimizations::pad_fold::TryFoldPadIntoLayer2d
bool TryFoldPadIntoLayer2d(const PadDescriptor &padDescriptor, Descriptor &layerDescriptor, const TensorInfo &tensorInfo)
Definition: FoldPadIntoLayer2d.hpp:88
armnn::LayerType::Activation
@ Activation
armnn::BinaryOperation::Sub
@ Sub
armnn::ClMultiplicationWorkloadValidate
arm_compute::Status ClMultiplicationWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
Definition: ClMultiplicationWorkload.cpp:18
armnn::ClBackendId
constexpr const char * ClBackendId()
Definition: ClBackendId.hpp:10
armnn::ClSubtractionValidate
arm_compute::Status ClSubtractionValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
Definition: ClSubtractionWorkload.cpp:46
armnn::IBackendInternal::IBackendSpecificModelContextPtr
std::shared_ptr< IBackendModelContext > IBackendSpecificModelContextPtr
Definition: IBackendInternal.hpp:96
armnn::LayerType::DepthwiseConvolution2d
@ DepthwiseConvolution2d
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::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::BinaryOperation::Mul
@ Mul
armnn::LayerType::Pooling2d
@ Pooling2d
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::Status
Status
Definition: Types.hpp:42
armnn::ClImportTensorHandleFactory::GetIdStatic
static const FactoryId & GetIdStatic()
Definition: ClImportTensorHandleFactory.cpp:93
armnn::IBackendInternal::ILayerSupportSharedPtr
std::shared_ptr< ILayerSupport > ILayerSupportSharedPtr
Definition: IBackendInternal.hpp:94
armnn::ClBackend::CreateBackendSpecificModelContext
IBackendInternal::IBackendSpecificModelContextPtr CreateBackendSpecificModelContext(const ModelOptions &modelOptions) const override
Definition: ClBackend.cpp:247
armnn::BinaryOperation::Add
@ Add
armnn::ClBackend::m_CustomAllocator
std::shared_ptr< ClBackendCustomAllocatorWrapper > m_CustomAllocator
Definition: ClBackend.hpp:299
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:98
armnn::IBackendInternal::IBackendContextPtr
std::unique_ptr< IBackendContext > IBackendContextPtr
Definition: IBackendInternal.hpp:90
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::ClAdditionValidate
arm_compute::Status ClAdditionValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
Definition: ClAdditionWorkload.cpp:45
armnn::MemorySourceFlags
unsigned int MemorySourceFlags
Definition: MemorySources.hpp:15
armnn::LayerType::Multiplication
@ Multiplication
armnn::BinaryOperation::Div
@ Div