ArmNN
 21.11
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 bool HasCapability (BackendCapability) const
 Returns true if backend support the capability false otherwise. 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< 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 >
 
- 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) {};
std::shared_ptr< ClBackendCustomAllocatorWrapper > m_CustomAllocator
Definition: ClBackend.hpp:299

◆ ClBackend() [2/2]

ClBackend ( std::shared_ptr< ICustomAllocator allocator)
inline

Definition at line 41 of file ClBackend.hpp.

References ClBackend::GetIdStatic(), ClBackend::UseCustomMemoryAllocator(), and ClBackend::~ClBackend().

42  {
43  std::string err;
44  UseCustomMemoryAllocator(allocator, err);
45  }
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

◆ ~ClBackend()

~ClBackend ( )
default

Referenced by ClBackend::ClBackend().

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

Referenced by ClBackend::GetId().

186 {
187  return IBackendContextPtr{new ClBackendContext{options}};
188 }
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 190 of file ClBackend.cpp.

Referenced by ClBackend::GetId().

192 {
194 }
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 196 of file ClBackend.cpp.

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

198 {
199  return IBackendSpecificModelContextPtr{new ClBackendModelContext{modelOptions}};
200 }
std::shared_ptr< IBackendModelContext > IBackendSpecificModelContextPtr

◆ CreateMemoryManager()

IBackendInternal::IMemoryManagerUniquePtr CreateMemoryManager ( ) const
overridevirtual

Reimplemented from IBackendInternal.

Definition at line 51 of file ClBackend.cpp.

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

Referenced by ClBackend::GetId().

52 {
54  {
55  return std::make_unique<ClMemoryManager>(m_CustomAllocator);
56  }
57  return std::make_unique<ClMemoryManager>(std::make_unique<arm_compute::CLBufferAllocator>());
58 }
std::shared_ptr< ClBackendCustomAllocatorWrapper > m_CustomAllocator
Definition: ClBackend.hpp:299
bool m_UsingCustomAllocator
Definition: ClBackend.hpp:300

◆ CreateWorkloadFactory() [1/5]

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

Implements IBackendInternal.

Definition at line 60 of file ClBackend.cpp.

Referenced by ClBackend::GetId().

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

◆ CreateWorkloadFactory() [2/5]

IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory ( TensorHandleFactoryRegistry registry) const
overridevirtual

Reimplemented from IBackendInternal.

Definition at line 74 of file ClBackend.cpp.

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

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  registry.RegisterMemoryManager(memoryManager);
88  registry.RegisterFactory(std::make_unique<ClTensorHandleFactory>(memoryManager));
89  registry.RegisterFactory(std::make_unique<ClImportTensorHandleFactory>(
90  static_cast<MemorySourceFlags>(MemorySource::Malloc), static_cast<MemorySourceFlags>(MemorySource::Malloc)));
91 
92  return std::make_unique<ClWorkloadFactory>(
93  PolymorphicPointerDowncast<ClMemoryManager>(memoryManager));
94 }
std::shared_ptr< ClBackendCustomAllocatorWrapper > m_CustomAllocator
Definition: ClBackend.hpp:299
bool m_UsingCustomAllocator
Definition: ClBackend.hpp:300

◆ CreateWorkloadFactory() [3/5]

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

Reimplemented from IBackendInternal.

Definition at line 67 of file ClBackend.cpp.

References ClBackend::CreateBackendSpecificModelContext().

69 {
70  return std::make_unique<ClWorkloadFactory>(
71  PolymorphicPointerDowncast<ClMemoryManager>(memoryManager), CreateBackendSpecificModelContext(modelOptions));
72 }
IBackendInternal::IBackendSpecificModelContextPtr CreateBackendSpecificModelContext(const ModelOptions &modelOptions) const override
Definition: ClBackend.cpp:196

◆ CreateWorkloadFactory() [4/5]

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

Reimplemented from IBackendInternal.

Definition at line 96 of file ClBackend.cpp.

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

98 {
99  std::shared_ptr<ClMemoryManager> memoryManager;
101  {
102  memoryManager = std::make_shared<ClMemoryManager>(m_CustomAllocator);
103  }
104  else
105  {
106  memoryManager = std::make_shared<ClMemoryManager>(std::make_unique<arm_compute::CLBufferAllocator>());
107  }
108 
109  registry.RegisterMemoryManager(memoryManager);
110  registry.RegisterFactory(std::make_unique<ClTensorHandleFactory>(memoryManager));
111  registry.RegisterFactory(std::make_unique<ClImportTensorHandleFactory>(
112  static_cast<MemorySourceFlags>(MemorySource::Malloc), static_cast<MemorySourceFlags>(MemorySource::Malloc)));
113 
114  return std::make_unique<ClWorkloadFactory>(
115  PolymorphicPointerDowncast<ClMemoryManager>(memoryManager), CreateBackendSpecificModelContext(modelOptions));
116 }
std::shared_ptr< ClBackendCustomAllocatorWrapper > m_CustomAllocator
Definition: ClBackend.hpp:299
IBackendInternal::IBackendSpecificModelContextPtr CreateBackendSpecificModelContext(const ModelOptions &modelOptions) const override
Definition: ClBackend.cpp:196
bool m_UsingCustomAllocator
Definition: ClBackend.hpp:300

◆ CreateWorkloadFactory() [5/5]

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

Reimplemented from IBackendInternal.

Definition at line 118 of file ClBackend.cpp.

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

123 {
124  std::shared_ptr<ClMemoryManager> memoryManager;
126  {
127  memoryManager = std::make_shared<ClMemoryManager>(m_CustomAllocator);
128  }
129  else
130  {
131  memoryManager = std::make_shared<ClMemoryManager>(std::make_unique<arm_compute::CLBufferAllocator>());
132  }
133 
134  registry.RegisterMemoryManager(memoryManager);
135  registry.RegisterFactory(std::make_unique<ClTensorHandleFactory>(memoryManager));
136  registry.RegisterFactory(std::make_unique<ClImportTensorHandleFactory>(inputFlags, outputFlags));
137 
138  return std::make_unique<ClWorkloadFactory>(
139  PolymorphicPointerDowncast<ClMemoryManager>(memoryManager), CreateBackendSpecificModelContext(modelOptions));
140 }
std::shared_ptr< ClBackendCustomAllocatorWrapper > m_CustomAllocator
Definition: ClBackend.hpp:299
IBackendInternal::IBackendSpecificModelContextPtr CreateBackendSpecificModelContext(const ModelOptions &modelOptions) const override
Definition: ClBackend.cpp:196
bool m_UsingCustomAllocator
Definition: ClBackend.hpp:300

◆ 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.

References armnn::gpuAccCapabilities.

94  {
95  return gpuAccCapabilities;
96  };
const BackendCapabilities gpuAccCapabilities("GpuAcc", { {"NonConstWeights", false}, {"AsyncExecution", false}, {"ProtectedContentAllocation", true}, {"ConstantTensorsAsInputs", false}, {"PreImportIOTensors", false}, {"ExternallyManagedMemory", true}, {"MultiAxisPacking", false}, {"SingleAxisPacking", true} })

◆ GetDefaultAllocator()

std::unique_ptr< ICustomAllocator > GetDefaultAllocator ( ) const
overridevirtual

Returns the default memory allocator for the backend.

Returns
- Returns unique pointer to the Default Allocator of the Backend

Reimplemented from IBackendInternal.

Definition at line 220 of file ClBackend.cpp.

Referenced by ClBackend::GetId().

221 {
222  return std::make_unique<ClBackendDefaultAllocator>();
223 }

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

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

Referenced by ClBackend::GetId().

143 {
144  return std::vector<ITensorHandleFactory::FactoryId> {ClTensorHandleFactory::GetIdStatic(),
146 }
static const FactoryId & GetIdStatic()

◆ GetId()

◆ GetIdStatic()

const BackendId & GetIdStatic ( )
static

Definition at line 45 of file ClBackend.cpp.

References armnn::ClBackendId().

Referenced by ClBackend::ClBackend(), and ClBackend::GetId().

46 {
47  static const BackendId s_Id{ClBackendId()};
48  return s_Id;
49 }
constexpr const char * ClBackendId()
Definition: ClBackendId.hpp:10

◆ GetLayerSupport() [1/2]

IBackendInternal::ILayerSupportSharedPtr GetLayerSupport ( ) const
overridevirtual

Implements IBackendInternal.

Definition at line 202 of file ClBackend.cpp.

Referenced by ClBackend::GetId().

203 {
204  static ILayerSupportSharedPtr layerSupport
205  {
207  };
208  return layerSupport;
209 }
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 211 of file ClBackend.cpp.

References ClBackend::CreateBackendSpecificModelContext().

212 {
213  static ILayerSupportSharedPtr layerSupport
214  {
215  new ClLayerSupport(CreateBackendSpecificModelContext(modelOptions))
216  };
217  return layerSupport;
218 }
IBackendInternal::IBackendSpecificModelContextPtr CreateBackendSpecificModelContext(const ModelOptions &modelOptions) const override
Definition: ClBackend.cpp:196
std::shared_ptr< ILayerSupport > ILayerSupportSharedPtr

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

References armnn::Activation, 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::Convolution2d, ClBackend::CreateBackendSpecificModelContext(), 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(), ClBackendModelContext::IsFastMathEnabled(), BatchNormalizationLayer::m_Beta, DepthwiseConvolution2dLayer::m_Bias, Convolution2dLayer::m_Bias, FullyConnectedLayer::m_Bias, Convolution2dDescriptor::m_BiasEnabled, DepthwiseConvolution2dDescriptor::m_BiasEnabled, BatchNormalizationLayer::m_Gamma, BatchNormalizationLayer::m_Mean, BatchNormalizationLayer::m_Variance, DepthwiseConvolution2dLayer::m_Weight, FullyConnectedLayer::m_Weight, Convolution2dLayer::m_Weight, armnn::Multiplication, armnn::Reduce, armnn::ReportUntouchedLayers(), and armnn::Subtraction.

Referenced by ClBackend::GetId().

227 {
228  OptimizationViews optimizationViews;
229 
230  auto it = subgraph.end();
231  bool isFastMathEnabled = false;
232  std::map<LayerGuid, Layer*> untouched;
233 
234  while (it != subgraph.begin())
235  {
236  --it;
237  Layer& base = **it;
238  untouched.insert({base.GetGuid(), &base});
239  }
240 
241  it = subgraph.end();
242 #if defined(ARMCOMPUTECL_ENABLED)
244 
245  if (modelContextPtr)
246  {
247  auto clModelOptions = dynamic_cast<ClBackendModelContext*>(modelContextPtr.get());
248  if (clModelOptions)
249  {
250  isFastMathEnabled = clModelOptions->IsFastMathEnabled();
251  }
252  }
253 #endif
254  while (it != subgraph.begin())
255  {
256  --it;
257  Layer& base = **it;
258 
259  // Fuse activation into previous layer if supported by backend
260  if ((base.GetType() == LayerType::DepthwiseConvolution2d || base.GetType() == LayerType::Convolution2d
261  || base.GetType() == LayerType::BatchNormalization || base.GetType() == LayerType::FullyConnected
262  || base.GetType() == LayerType::Addition || base.GetType() == LayerType::Multiplication
263  || base.GetType() == LayerType::Subtraction || base.GetType() == LayerType::Division)
264  && (base.GetAdditionalInformation<ActivationDescriptor>() == nullptr))
265  {
266  for (auto output = base.BeginOutputSlots(); output != base.EndOutputSlots(); ++output)
267  {
268  if (output->GetNumConnections() == 1)
269  {
270  for (auto&& childInput : output->GetConnections())
271  {
272  if ((childInput->GetOwningLayer().GetType() == LayerType::Activation) &&
273  (checkDataTypeInputandOutput(childInput->GetOwningLayer())))
274  {
275  Layer& child = childInput->GetOwningLayer();
276 
277  auto* activationLayer = PolymorphicDowncast<ActivationLayer*>(&child);
278 
279  const std::string name = std::string("fused-") + child.GetName() + std::string("-into-") +
280  base.GetName();
281 
282  // Get params from activation layer
283  ActivationDescriptor activationDesc = activationLayer->GetParameters();
284 
285  if (base.GetType() == LayerType::Convolution2d)
286  {
287  Convolution2dLayer* baseLayer = PolymorphicDowncast<Convolution2dLayer*>(&base);
288 
289  Optional<TensorInfo> biases;
290 
291  if (baseLayer->GetParameters().m_BiasEnabled)
292  {
293  biases = baseLayer->m_Bias->GetTensorInfo();
294  }
295 
297  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
298  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
299  baseLayer->GetParameters(),
300  baseLayer->m_Weight->GetTensorInfo(),
301  biases,
302  isFastMathEnabled,
303  &activationDesc);
304 
305  if (status)
306  {
307  FuseLayerWithWeightsAndBiases<Convolution2dLayer>(optimizationViews,
308  baseLayer,
309  activationLayer,
310  activationDesc,
311  name);
312  untouched.erase(baseLayer->GetGuid());
313  untouched.erase(activationLayer->GetGuid());
314  }
315  }
316  else if (base.GetType() == LayerType::DepthwiseConvolution2d)
317  {
318  DepthwiseConvolution2dLayer* baseLayer =
319  PolymorphicDowncast<DepthwiseConvolution2dLayer*>(&base);
320 
321  Optional<TensorInfo> biases;
322 
323  if (baseLayer->GetParameters().m_BiasEnabled)
324  {
325  biases = baseLayer->m_Bias->GetTensorInfo();
326  }
327 
329  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
330  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
331  baseLayer->GetParameters(),
332  baseLayer->m_Weight->GetTensorInfo(),
333  biases,
334  &activationDesc);
335 
336  if (status)
337  {
338  FuseLayerWithWeightsAndBiases<DepthwiseConvolution2dLayer>(optimizationViews,
339  baseLayer,
340  activationLayer,
341  activationDesc,
342  name);
343  untouched.erase(baseLayer->GetGuid());
344  untouched.erase(activationLayer->GetGuid());
345  }
346  }
347  else if (base.GetType() == LayerType::FullyConnected)
348  {
349  FullyConnectedLayer* baseLayer = PolymorphicDowncast<FullyConnectedLayer*>(&base);
350 
352  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
353  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
354  baseLayer->m_Weight->GetTensorInfo(),
355  baseLayer->m_Bias->GetTensorInfo(),
356  baseLayer->GetParameters(),
357  &activationDesc);
358 
359  if (status)
360  {
361  FuseLayerWithWeightsAndBiases<FullyConnectedLayer>(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::BatchNormalization)
371  {
372  BatchNormalizationLayer* baseLayer =
373  PolymorphicDowncast<BatchNormalizationLayer*>(&base);
374 
376  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
377  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
378  baseLayer->m_Mean->GetTensorInfo(),
379  baseLayer->m_Variance->GetTensorInfo(),
380  baseLayer->m_Beta->GetTensorInfo(),
381  baseLayer->m_Gamma->GetTensorInfo(),
382  baseLayer->GetParameters(),
383  &activationDesc);
384 
385  if (status)
386  {
387  BatchNormalizationLayer* replacementLayer =
388  FuseLayerWithParameters<BatchNormalizationLayer>(optimizationViews,
389  baseLayer,
390  activationLayer,
391  activationDesc,
392  name);
393 
394  replacementLayer->m_Beta = std::move(baseLayer->m_Beta);
395  replacementLayer->m_Gamma = std::move(baseLayer->m_Gamma);
396  replacementLayer->m_Mean = std::move(baseLayer->m_Mean);
397  replacementLayer->m_Variance = std::move(baseLayer->m_Variance);
398  untouched.erase(baseLayer->GetGuid());
399  untouched.erase(activationLayer->GetGuid());
400  }
401  }
402  else if (base.GetType() == LayerType::Addition)
403  {
404  AdditionLayer* baseLayer = PolymorphicDowncast<AdditionLayer*>(&base);
405 
407  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
408  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
409  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
410  &activationDesc);
411 
412  if (status)
413  {
414  FuseLayerWithoutParameters<AdditionLayer>(optimizationViews,
415  baseLayer,
416  activationLayer,
417  activationDesc,
418  name);
419  untouched.erase(baseLayer->GetGuid());
420  untouched.erase(activationLayer->GetGuid());
421  }
422  }
423  else if (base.GetType() == LayerType::Division)
424  {
425  DivisionLayer* baseLayer = PolymorphicDowncast<DivisionLayer*>(&base);
426 
428  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
429  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
430  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
431  &activationDesc);
432 
433  if (status)
434  {
435  FuseLayerWithoutParameters<DivisionLayer>(optimizationViews,
436  baseLayer,
437  activationLayer,
438  activationDesc,
439  name);
440  untouched.erase(baseLayer->GetGuid());
441  untouched.erase(activationLayer->GetGuid());
442  }
443  }
444  else if (base.GetType() == LayerType::Multiplication)
445  {
446  MultiplicationLayer* baseLayer = PolymorphicDowncast<MultiplicationLayer*>(&base);
447 
449  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
450  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
451  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
452  &activationDesc);
453 
454  if (status)
455  {
456  FuseLayerWithoutParameters<MultiplicationLayer>(optimizationViews,
457  baseLayer,
458  activationLayer,
459  activationDesc,
460  name);
461  untouched.erase(baseLayer->GetGuid());
462  untouched.erase(activationLayer->GetGuid());
463  }
464  }
465  else if (base.GetType() == LayerType::Subtraction)
466  {
467  SubtractionLayer* baseLayer = PolymorphicDowncast<SubtractionLayer*>(&base);
468 
470  baseLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
471  baseLayer->GetInputSlot(1).GetConnectedOutputSlot()->GetTensorInfo(),
472  activationLayer->GetInputSlot(0).GetConnectedOutputSlot()->GetTensorInfo(),
473  &activationDesc);
474 
475  if (status)
476  {
477  FuseLayerWithoutParameters<SubtractionLayer>(optimizationViews,
478  baseLayer,
479  activationLayer,
480  activationDesc,
481  name);
482  untouched.erase(baseLayer->GetGuid());
483  untouched.erase(activationLayer->GetGuid());
484  }
485  }
486  }
487  }
488  }
489  }
490  }
491 
492  // Separate reduce layer with multiple axes into multiple reduce layers with 1 axis.
493  if (base.GetType() == LayerType::Reduce)
494  {
495  ReduceLayer* baseLayer = PolymorphicDowncast<ReduceLayer*>(&base);
496  ReduceDescriptor reduceDescriptor = baseLayer->GetParameters();
497 
498  if (!reduceDescriptor.m_vAxis.empty() && reduceDescriptor.m_vAxis.size() > 1)
499  {
500  // Add new layers to the graph and connect them.
501  std::vector<Layer*> layers = ChainReduceLayers<ReduceLayer>(optimizationViews,
502  baseLayer,
503  reduceDescriptor);
504 
505  // Replace existing baselayer with new subgraph.
506  ReplaceLayers<ReduceLayer>(optimizationViews, baseLayer, layers);
507  untouched.erase(baseLayer->GetGuid());
508  }
509  }
510  }
511 
512  if (optimizationViews.GetSubstitutions().empty())
513  {
514  optimizationViews.AddUntouchedSubgraph(SubgraphView(subgraph));
515  }
516  else
517  {
518  ReportUntouchedLayers(optimizationViews, untouched);
519  }
520 
521  return optimizationViews;
522 }
arm_compute::Status ClAdditionValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
arm_compute::Status ClFullyConnectedWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const TensorInfo &weights, const TensorInfo &biases, const FullyConnectedDescriptor &descriptor, const ActivationDescriptor *activationDescriptor)
arm_compute::Status ClDivisionWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
void ReportUntouchedLayers(OptimizationViews &optimizationViews, std::map< LayerGuid, Layer *> untouched)
arm_compute::Status ClSubtractionValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
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)
IBackendInternal::IBackendSpecificModelContextPtr CreateBackendSpecificModelContext(const ModelOptions &modelOptions) const override
Definition: ClBackend.cpp:196
std::shared_ptr< IBackendModelContext > IBackendSpecificModelContextPtr
arm_compute::Status ClMultiplicationWorkloadValidate(const TensorInfo &input0, const TensorInfo &input1, const TensorInfo &output, const ActivationDescriptor *activationDescriptor)
Status
enumeration
Definition: Types.hpp:29
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)
arm_compute::Status ClDepthwiseConvolutionWorkloadValidate(const TensorInfo &input, const TensorInfo &output, const DepthwiseConvolution2dDescriptor &descriptor, const TensorInfo &weights, const Optional< TensorInfo > &biases, const ActivationDescriptor *activationDescriptor)

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

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

Referenced by ClBackend::GetId().

149 {
150  std::shared_ptr<ClMemoryManager> memoryManager;
152  {
153  memoryManager = std::make_shared<ClMemoryManager>(m_CustomAllocator);
154  }
155  else
156  {
157  memoryManager = std::make_shared<ClMemoryManager>(std::make_unique<arm_compute::CLBufferAllocator>());
158  }
159 
160  registry.RegisterMemoryManager(memoryManager);
161  registry.RegisterFactory(std::make_unique<ClTensorHandleFactory>(memoryManager));
162  registry.RegisterFactory(std::make_unique<ClImportTensorHandleFactory>(
163  static_cast<MemorySourceFlags>(MemorySource::Malloc), static_cast<MemorySourceFlags>(MemorySource::Malloc)));
164 }
std::shared_ptr< ClBackendCustomAllocatorWrapper > m_CustomAllocator
Definition: ClBackend.hpp:299
bool m_UsingCustomAllocator
Definition: ClBackend.hpp:300

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

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

169 {
170  std::shared_ptr<ClMemoryManager> memoryManager;
172  {
173  memoryManager = std::make_shared<ClMemoryManager>(m_CustomAllocator);
174  }
175  else
176  {
177  memoryManager = std::make_shared<ClMemoryManager>(std::make_unique<arm_compute::CLBufferAllocator>());
178  }
179 
180  registry.RegisterMemoryManager(memoryManager);
181  registry.RegisterFactory(std::make_unique<ClTensorHandleFactory>(memoryManager));
182  registry.RegisterFactory(std::make_unique<ClImportTensorHandleFactory>(inputFlags, outputFlags));
183 }
std::shared_ptr< ClBackendCustomAllocatorWrapper > m_CustomAllocator
Definition: ClBackend.hpp:299
bool m_UsingCustomAllocator
Definition: ClBackend.hpp:300

◆ 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.

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

Referenced by ClBackend::ClBackend().

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  }
#define ARMNN_LOG(severity)
Definition: Logging.hpp:202
std::shared_ptr< ClBackendCustomAllocatorWrapper > m_CustomAllocator
Definition: ClBackend.hpp:299
void IgnoreUnused(Ts &&...)
bool m_UsingCustomAllocator
Definition: ClBackend.hpp:300

Member Data Documentation

◆ m_CustomAllocator

◆ m_UsingCustomAllocator


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