ArmNN
 21.08
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::Optimizations GetOptimizations () const override
 
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
 
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...
 
- Public Member Functions inherited from IBackendInternal
 ~IBackendInternal () override=default
 Allow backends created by the factory function to be destroyed through IBackendInternal. More...
 
virtual ISubGraphConverterPtr CreateSubGraphConverter (const std::shared_ptr< SubGraph > &subGraph) const
 
virtual SubGraphUniquePtr OptimizeSubGraph (const SubGraph &subGraph, bool &optimizationAttempted) const
 
virtual 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 >
 
using GraphUniquePtr = std::unique_ptr< Graph >
 
using SubgraphViewUniquePtr = std::unique_ptr< SubgraphView >
 
using supported = std::unique_ptr< ISubGraphConverter >
 
using instead = std::unique_ptr< SubGraph >
 
- Protected Member Functions inherited from IBackendInternal
 IBackendInternal ()=default
 Creation must be done through a specific backend interface. More...
 
- Protected Member Functions inherited from IBackend
 IBackend ()
 
virtual ~IBackend ()
 

Detailed Description

Definition at line 32 of file ClBackend.hpp.

Constructor & Destructor Documentation

◆ ClBackend() [1/2]

ClBackend ( )
inline

Definition at line 35 of file ClBackend.hpp.

35 : m_CustomAllocator(nullptr) {};
std::shared_ptr< ClBackendCustomAllocatorWrapper > m_CustomAllocator
Definition: ClBackend.hpp:291

◆ ClBackend() [2/2]

ClBackend ( std::shared_ptr< ICustomAllocator allocator)
inline

Definition at line 36 of file ClBackend.hpp.

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

37  {
38  std::string err;
39  UseCustomMemoryAllocator(allocator, err);
40  }
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:92

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

Referenced by ClBackend::GetId().

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

Referenced by ClBackend::GetId().

191 {
193 }
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 200 of file ClBackend.cpp.

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

202 {
203  return IBackendSpecificModelContextPtr{new ClBackendModelContext{modelOptions}};
204 }
std::shared_ptr< IBackendModelContext > IBackendSpecificModelContextPtr

◆ CreateMemoryManager()

IBackendInternal::IMemoryManagerUniquePtr CreateMemoryManager ( ) const
overridevirtual

Reimplemented from IBackendInternal.

Definition at line 50 of file ClBackend.cpp.

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

Referenced by ClBackend::GetId().

51 {
53  {
54  return std::make_unique<ClMemoryManager>(m_CustomAllocator);
55  }
56  return std::make_unique<ClMemoryManager>(std::make_unique<arm_compute::CLBufferAllocator>());
57 }
std::shared_ptr< ClBackendCustomAllocatorWrapper > m_CustomAllocator
Definition: ClBackend.hpp:291
bool m_UsingCustomAllocator
Definition: ClBackend.hpp:292

◆ CreateWorkloadFactory() [1/5]

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

Implements IBackendInternal.

Definition at line 59 of file ClBackend.cpp.

Referenced by ClBackend::GetId().

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

◆ CreateWorkloadFactory() [2/5]

IBackendInternal::IWorkloadFactoryPtr CreateWorkloadFactory ( TensorHandleFactoryRegistry registry) const
overridevirtual

Reimplemented from IBackendInternal.

Definition at line 73 of file ClBackend.cpp.

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

75 {
76  std::shared_ptr<ClMemoryManager> memoryManager;
78  {
79  memoryManager = std::make_shared<ClMemoryManager>(m_CustomAllocator);
80  }
81  else
82  {
83  memoryManager = std::make_shared<ClMemoryManager>(std::make_unique<arm_compute::CLBufferAllocator>());
84  }
85 
86  registry.RegisterMemoryManager(memoryManager);
87  registry.RegisterFactory(std::make_unique<ClTensorHandleFactory>(memoryManager));
88  registry.RegisterFactory(std::make_unique<ClImportTensorHandleFactory>(
89  static_cast<MemorySourceFlags>(MemorySource::Malloc), static_cast<MemorySourceFlags>(MemorySource::Malloc)));
90 
91  return std::make_unique<ClWorkloadFactory>(
92  PolymorphicPointerDowncast<ClMemoryManager>(memoryManager));
93 }
std::shared_ptr< ClBackendCustomAllocatorWrapper > m_CustomAllocator
Definition: ClBackend.hpp:291
bool m_UsingCustomAllocator
Definition: ClBackend.hpp:292

◆ CreateWorkloadFactory() [3/5]

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

Reimplemented from IBackendInternal.

Definition at line 66 of file ClBackend.cpp.

References ClBackend::CreateBackendSpecificModelContext().

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

◆ CreateWorkloadFactory() [4/5]

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

Reimplemented from IBackendInternal.

Definition at line 95 of file ClBackend.cpp.

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

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

◆ CreateWorkloadFactory() [5/5]

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

Reimplemented from IBackendInternal.

Definition at line 117 of file ClBackend.cpp.

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

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

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

References armnn::gpuAccCapabilities.

88  {
89  return gpuAccCapabilities;
90  };
const BackendCapabilities gpuAccCapabilities("GpuAcc", { {"NonConstWeights", false}, {"AsyncExecution", false}, {"ProtectedContentAllocation", true} })

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

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

Referenced by ClBackend::GetId().

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

◆ GetId()

◆ GetIdStatic()

const BackendId & GetIdStatic ( )
static

Definition at line 44 of file ClBackend.cpp.

References armnn::ClBackendId().

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

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

◆ GetLayerSupport() [1/2]

IBackendInternal::ILayerSupportSharedPtr GetLayerSupport ( ) const
overridevirtual

Implements IBackendInternal.

Definition at line 206 of file ClBackend.cpp.

Referenced by ClBackend::GetId().

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

References ClBackend::CreateBackendSpecificModelContext().

216 {
217  static ILayerSupportSharedPtr layerSupport
218  {
219  new ClLayerSupport(CreateBackendSpecificModelContext(modelOptions))
220  };
221  return layerSupport;
222 }
IBackendInternal::IBackendSpecificModelContextPtr CreateBackendSpecificModelContext(const ModelOptions &modelOptions) const override
Definition: ClBackend.cpp:200
std::shared_ptr< ILayerSupport > ILayerSupportSharedPtr

◆ GetOptimizations()

IBackendInternal::Optimizations GetOptimizations ( ) const
overridevirtual

Reimplemented from IBackendInternal.

Definition at line 195 of file ClBackend.cpp.

Referenced by ClBackend::GetId().

196 {
197  return Optimizations{};
198 }
std::vector< OptimizationPtr > Optimizations

◆ OptimizeSubgraphView()

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

Reimplemented from IBackendInternal.

Definition at line 224 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().

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

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

Referenced by ClBackend::GetId().

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

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

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

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

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

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

Referenced by ClBackend::ClBackend().

94  {
95  IgnoreUnused(errMsg);
96  ARMNN_LOG(info) << "Using Custom Allocator for ClBackend";
97 
98  // Set flag to signal the backend to use a custom memory allocator
99  m_CustomAllocator = std::make_shared<ClBackendCustomAllocatorWrapper>(std::move(allocator));
100  m_UsingCustomAllocator = true;
101  return m_UsingCustomAllocator;
102  }
#define ARMNN_LOG(severity)
Definition: Logging.hpp:202
std::shared_ptr< ClBackendCustomAllocatorWrapper > m_CustomAllocator
Definition: ClBackend.hpp:291
void IgnoreUnused(Ts &&...)
bool m_UsingCustomAllocator
Definition: ClBackend.hpp:292

Member Data Documentation

◆ m_CustomAllocator

◆ m_UsingCustomAllocator


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