1 /*
2 * Copyright (c) 2018-2020 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 */
24 #include "arm_compute/graph/backends/GLES/GCDeviceBackend.h"
25
26 #include "arm_compute/graph/Graph.h"
27 #include "arm_compute/graph/GraphContext.h"
28 #include "arm_compute/graph/INode.h"
29 #include "arm_compute/graph/Logger.h"
30 #include "arm_compute/graph/Tensor.h"
31 #include "arm_compute/graph/backends/BackendRegistrar.h"
32 #include "arm_compute/graph/backends/GLES/GCFunctionFactory.h"
33 #include "arm_compute/graph/backends/GLES/GCNodeValidator.h"
34 #include "arm_compute/graph/backends/GLES/GCTensorHandle.h"
35
36 #include "arm_compute/core/TensorInfo.h"
37 #include "arm_compute/runtime/BlobLifetimeManager.h"
38 #include "arm_compute/runtime/GLES_COMPUTE/GCBufferAllocator.h"
39 #include "arm_compute/runtime/GLES_COMPUTE/GCScheduler.h"
40 #include "arm_compute/runtime/MemoryGroup.h"
41 #include "arm_compute/runtime/MemoryManagerOnDemand.h"
42 #include "arm_compute/runtime/PoolManager.h"
43
44 #include "support/ToolchainSupport.h"
45
46 namespace arm_compute
47 {
48 namespace graph
49 {
50 namespace backends
51 {
52 /** Register GLES backend */
53 static detail::BackendRegistrar<GCDeviceBackend> GCDeviceBackend_registrar(Target::GC);
54
GCDeviceBackend()55 GCDeviceBackend::GCDeviceBackend()
56 : _initialized(false), _allocator()
57 {
58 }
59
initialize_backend()60 void GCDeviceBackend::initialize_backend()
61 {
62 // Setup Scheduler
63 GCScheduler::get().default_init();
64 }
65
release_backend_context(GraphContext & ctx)66 void GCDeviceBackend::release_backend_context(GraphContext &ctx)
67 {
68 //Nothing to do
69 ARM_COMPUTE_UNUSED(ctx);
70 }
71
setup_backend_context(GraphContext & ctx)72 void GCDeviceBackend::setup_backend_context(GraphContext &ctx)
73 {
74 // Force backend initialization
75 if(!_initialized)
76 {
77 initialize_backend();
78 _initialized = true;
79 }
80
81 // Setup a management backend
82 if(ctx.memory_management_ctx(Target::GC) == nullptr)
83 {
84 MemoryManagerContext mm_ctx;
85 mm_ctx.target = Target::GC;
86 mm_ctx.intra_mm = create_memory_manager(MemoryManagerAffinity::Buffer);
87 mm_ctx.cross_mm = create_memory_manager(MemoryManagerAffinity::Buffer);
88 mm_ctx.cross_group = std::make_shared<MemoryGroup>(mm_ctx.cross_mm);
89 mm_ctx.allocator = &_allocator;
90
91 ctx.insert_memory_management_ctx(std::move(mm_ctx));
92 }
93 }
94
is_backend_supported()95 bool GCDeviceBackend::is_backend_supported()
96 {
97 return arm_compute::opengles31_is_available();
98 }
99
backend_allocator()100 IAllocator *GCDeviceBackend::backend_allocator()
101 {
102 return &_allocator;
103 }
104
create_tensor(const Tensor & tensor)105 std::unique_ptr<ITensorHandle> GCDeviceBackend::create_tensor(const Tensor &tensor)
106 {
107 // Get tensor descriptor
108 const TensorDescriptor &tensor_desc = tensor.desc();
109 ARM_COMPUTE_ERROR_ON(tensor_desc.target != Target::GC);
110
111 // Create backend tensor handle
112 TensorInfo info(tensor_desc.shape, 1, tensor_desc.data_type, tensor_desc.quant_info);
113 info.set_data_layout(tensor_desc.layout);
114
115 return support::cpp14::make_unique<GCTensorHandle>(info);
116 }
117
create_subtensor(ITensorHandle * parent,TensorShape shape,Coordinates coords,bool extend_parent)118 std::unique_ptr<ITensorHandle> GCDeviceBackend::create_subtensor(ITensorHandle *parent, TensorShape shape, Coordinates coords, bool extend_parent)
119 {
120 ARM_COMPUTE_UNUSED(parent, shape, coords, extend_parent);
121 ARM_COMPUTE_ERROR("GLES backend has no sub-tensor support!");
122 return nullptr;
123 }
124
configure_node(INode & node,GraphContext & ctx)125 std::unique_ptr<arm_compute::IFunction> GCDeviceBackend::configure_node(INode &node, GraphContext &ctx)
126 {
127 ARM_COMPUTE_LOG_GRAPH_VERBOSE("Configuring GC node with ID : " << node.id() << std::endl);
128 ARM_COMPUTE_ERROR_ON(node.assigned_target() != Target::GC);
129
130 // Configure node
131 return GCFunctionFactory::create(&node, ctx);
132 }
133
validate_node(INode & node)134 arm_compute::Status GCDeviceBackend::validate_node(INode &node)
135 {
136 ARM_COMPUTE_LOG_GRAPH_VERBOSE("Validating GC node with ID : " << node.id() << std::endl);
137 ARM_COMPUTE_ERROR_ON(node.assigned_target() != Target::GC);
138
139 return GCNodeValidator::validate(&node);
140 }
141
create_memory_manager(MemoryManagerAffinity affinity)142 std::shared_ptr<arm_compute::IMemoryManager> GCDeviceBackend::create_memory_manager(MemoryManagerAffinity affinity)
143 {
144 if(affinity == MemoryManagerAffinity::Offset)
145 {
146 ARM_COMPUTE_LOG_GRAPH_WARNING("GC Backend does not support offset affinity memory management!");
147 return nullptr;
148 }
149
150 auto lifetime_mgr = std::make_shared<BlobLifetimeManager>();
151 auto pool_mgr = std::make_shared<PoolManager>();
152 auto mm = std::make_shared<MemoryManagerOnDemand>(lifetime_mgr, pool_mgr);
153
154 return mm;
155 }
156
create_weights_manager()157 std::shared_ptr<arm_compute::IWeightsManager> GCDeviceBackend::create_weights_manager()
158 {
159 return nullptr;
160 }
161 } // namespace backends
162 } // namespace graph
163 } // namespace arm_compute
164