Compute Library
 21.02
NEDeviceBackend.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2021 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
25 
36 
46 
48 
49 namespace arm_compute
50 {
51 namespace graph
52 {
53 namespace backends
54 {
55 /** Register Neon backend */
56 static detail::BackendRegistrar<NEDeviceBackend> NEDeviceBackend_registrar(Target::NEON);
57 
59  : _allocator()
60 {
61 }
62 
64 {
65  //Nothing to do
66 }
67 
69 {
70  //Nothing to do
71  ARM_COMPUTE_UNUSED(ctx);
72 }
73 
75 {
76  // Set number of threads
77  if(ctx.config().num_threads >= 0)
78  {
80  }
81 
82  // Create function level memory manager
83  if(ctx.memory_management_ctx(Target::NEON) == nullptr)
84  {
85  MemoryManagerContext mm_ctx;
86  mm_ctx.target = Target::NEON;
89  mm_ctx.cross_group = std::make_shared<MemoryGroup>(mm_ctx.cross_mm);
90  mm_ctx.allocator = &_allocator;
91 
92  ctx.insert_memory_management_ctx(std::move(mm_ctx));
93  }
94 
95  // Create function level weights manager
96  if(ctx.weights_management_ctx(Target::NEON) == nullptr)
97  {
98  WeightsManagerContext wm_ctx;
99  wm_ctx.target = Target::NEON;
100  wm_ctx.wm = create_weights_manager();
101 
102  ctx.insert_weights_management_ctx(std::move(wm_ctx));
103  }
104 }
105 
107 {
108  return true;
109 }
110 
112 {
113  return &_allocator;
114 }
115 
116 std::unique_ptr<ITensorHandle> NEDeviceBackend::create_tensor(const Tensor &tensor)
117 {
118  // Get tensor descriptor
119  const TensorDescriptor &tensor_desc = tensor.desc();
120  ARM_COMPUTE_ERROR_ON(tensor_desc.target != Target::NEON);
121 
122  // Create backend tensor handle
123  TensorInfo info(tensor_desc.shape, 1, tensor_desc.data_type, tensor_desc.quant_info);
124  info.set_data_layout(tensor_desc.layout);
125 
126  return std::make_unique<NETensorHandle>(info);
127 }
128 
129 std::unique_ptr<ITensorHandle> NEDeviceBackend::create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent)
130 {
131  if(parent == nullptr)
132  {
133  return nullptr;
134  }
135 
136  return std::make_unique<NESubTensorHandle>(parent, shape, coords, extend_parent);
137 }
138 
139 std::unique_ptr<arm_compute::IFunction> NEDeviceBackend::configure_node(INode &node, GraphContext &ctx)
140 {
141  ARM_COMPUTE_LOG_GRAPH_VERBOSE("Configuring Neon node with ID : " << node.id() << std::endl);
143 
144  // Configure node
145  return NEFunctionFactory::create(&node, ctx);
146 }
147 
149 {
150  ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating Neon node with ID : " << node.id() << std::endl);
152 
153  return NENodeValidator::validate(&node);
154 }
155 
156 std::shared_ptr<arm_compute::IMemoryManager> NEDeviceBackend::create_memory_manager(MemoryManagerAffinity affinity)
157 {
158  std::shared_ptr<ILifetimeManager> lifetime_mgr = nullptr;
159  if(affinity == MemoryManagerAffinity::Buffer)
160  {
161  lifetime_mgr = std::make_shared<BlobLifetimeManager>();
162  }
163  else
164  {
165  lifetime_mgr = std::make_shared<OffsetLifetimeManager>();
166  }
167  auto pool_mgr = std::make_shared<PoolManager>();
168  auto mm = std::make_shared<MemoryManagerOnDemand>(lifetime_mgr, pool_mgr);
169 
170  return mm;
171 }
172 
173 std::shared_ptr<arm_compute::IWeightsManager> NEDeviceBackend::create_weights_manager()
174 {
175  auto weights_mgr = std::make_shared<IWeightsManager>();
176  return weights_mgr;
177 }
178 } // namespace backends
179 } // namespace graph
180 } // namespace arm_compute
std::shared_ptr< arm_compute::IMemoryManager > create_memory_manager(MemoryManagerAffinity affinity) override
Create a backend memory manager given its affinity.
Neon capable target device.
Shape of a tensor.
Definition: TensorShape.h:39
IAllocator * backend_allocator() override
Gets a backend memory allocator.
virtual void set_num_threads(unsigned int num_threads)=0
Sets the number of threads the scheduler will use to run the kernels.
Target assigned_target() const
Returns assigned target for this node.
Definition: INode.cpp:198
bool insert_weights_management_ctx(WeightsManagerContext &&weights_ctx)
Inserts a weights manager context.
std::shared_ptr< arm_compute::IMemoryGroup > cross_group
Cross-function memory group.
Definition: GraphContext.h:45
Status validate_node(INode &node) override
Validate a node.
bool insert_memory_management_ctx(MemoryManagerContext &&memory_ctx)
Inserts a memory manager context.
void initialize_backend() override
Initializes the backend.
std::unique_ptr< ITensorHandle > create_tensor(const Tensor &tensor) override
Create a backend Tensor.
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Definition: Error.h:466
Status class.
Definition: Error.h:52
WeightsManagerContext * weights_management_ctx(Target target)
Gets a weights manager context for a given target.
static Status validate(INode *node)
Validate a node.
std::shared_ptr< arm_compute::IWeightsManager > create_weights_manager() override
Create a backend weights manager.
Copyright (c) 2017-2021 Arm Limited.
bool is_backend_supported() override
Checks if an instantiated backend is actually supported.
TensorDescriptor & desc()
TensorInfo metadata accessor.
Definition: Tensor.cpp:40
QuantizationInfo quant_info
Quantization info.
Node interface.
Definition: INode.h:45
ITensorInfo & set_data_layout(const DataLayout &data_layout) override
Set the data layout of the tensor.
Definition: TensorInfo.cpp:386
#define ARM_COMPUTE_UNUSED(...)
To avoid unused variables warnings.
Definition: Error.h:152
Coordinates of an item.
Definition: Coordinates.h:37
std::unique_ptr< arm_compute::IFunction > configure_node(INode &node, GraphContext &ctx) override
Configure a backend Node.
NodeID id() const
Returns node&#39;s ID.
Definition: INode.cpp:102
static std::unique_ptr< arm_compute::IFunction > create(INode *node, GraphContext &ctx)
Create a backend execution function depending on the node type.
Tensor handle interface object.
Definition: ITensorHandle.h:38
std::unique_ptr< ITensorHandle > create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent) override
Create a backend Sub-Tensor.
std::shared_ptr< arm_compute::IMemoryManager > intra_mm
Intra-function memory manager.
Definition: GraphContext.h:43
ScaleKernelInfo info(interpolation_policy, default_border_mode, PixelValue(), sampling_policy, false)
const GraphConfig & config() const
Graph configuration accessor.
std::shared_ptr< arm_compute::IMemoryManager > cross_mm
Cross-function memory manager.
Definition: GraphContext.h:44
Contains structs required for weights management.
Definition: GraphContext.h:50
#define ARM_COMPUTE_LOG_GRAPH_VERBOSE(x)
Definition: Logger.h:50
Contains structs required for memory management.
Definition: GraphContext.h:40
Allocator interface.
Definition: IAllocator.h:35
int num_threads
Number of threads to use (thread capable backends), if 0 the backend will auto-initialize, if -1 the backend will stay as it is.
Definition: Types.h:88
void release_backend_context(GraphContext &ctx) override
Release the backend specific resources associated to a given graph context.
Store the tensor&#39;s metadata.
Definition: TensorInfo.h:45
IAllocator * allocator
Backend allocator to use.
Definition: GraphContext.h:46
void setup_backend_context(GraphContext &ctx) override
Setups the given graph context.
MemoryManagerContext * memory_management_ctx(Target target)
Gets a memory manager context for a given target.
MemoryManagerAffinity
Backend Memory Manager affinity.
Definition: Types.h:194
std::shared_ptr< arm_compute::IWeightsManager > wm
Weights manager.
Definition: GraphContext.h:53
Tensor object.
Definition: Tensor.h:41
static IScheduler & get()
Access the scheduler singleton.
Definition: Scheduler.cpp:94