• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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