xref: /aosp_15_r20/external/ComputeLibrary/src/dynamic_fusion/sketch/gpu/GpuWorkloadSketchImpl.h (revision c217d954acce2dbc11938adb493fc0abd69584f3)
1 /*
2  * Copyright (c) 2022-2023 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 #ifndef SRC_DYNAMIC_FUSION_SKETCH_GPU_GPUWORKLOADSKETCHIMPL
25 #define SRC_DYNAMIC_FUSION_SKETCH_GPU_GPUWORKLOADSKETCHIMPL
26 
27 #include "arm_compute/dynamic_fusion/sketch/MemoryDescriptor.h"
28 #include "arm_compute/dynamic_fusion/sketch/gpu/GpuWorkloadSketch.h"
29 #include "src/dynamic_fusion/sketch/gpu/GpuComponentServices.h"
30 #include "src/dynamic_fusion/sketch/gpu/GpuKernelComponentGraph.h"
31 #include "src/dynamic_fusion/sketch/gpu/GpuOperatorGroup.h"
32 
33 #include <memory>
34 #include <vector>
35 
36 namespace arm_compute
37 {
38 namespace experimental
39 {
40 namespace dynamic_fusion
41 {
42 /** Internal implementation of @ref GpuWorkloadSketch */
43 class GpuWorkloadSketch::Implementation
44 {
45 public:
46     /** Constructor
47      *
48      * @param[in] context global workload creation context
49      */
Implementation(Context * context)50     explicit Implementation(
51         Context *context)
52         : _context{ context },
53           _comp_services{},
54           _component_graph{ &_comp_services },
55           _operator_group{},
56           _managed_tensor_info_list{ std::vector<std::unique_ptr<TensorInfo>>() },
57           _mem_map{}
58     {
59     }
60     /** Prevent instances of this class from being copy constructed */
61     Implementation(const Implementation &impl) = delete;
62     /** Prevent instances of this class from being copied */
63     Implementation &operator=(const Implementation &impl) = delete;
64     /** Allow instances of this class to be move constructed */
65     Implementation(Implementation &&impl) = default;
66     /** Allow instances of this class to be moved */
67     Implementation &operator=(Implementation &&impl) = default;
68     /** Get workload context */
context()69     const Context *context() const
70     {
71         return _context;
72     }
73     /** Get component graph */
component_graph()74     const GpuKernelComponentGraph &component_graph() const
75     {
76         return _component_graph;
77     }
78     /** Get component graph */
component_graph()79     GpuKernelComponentGraph &component_graph()
80     {
81         return _component_graph;
82     }
83     /** Get operator group */
operator_group()84     const GpuOperatorGroup &operator_group() const
85     {
86         return _operator_group;
87     }
88     /** Get operator group */
operator_group()89     GpuOperatorGroup &operator_group()
90     {
91         return _operator_group;
92     }
allocate_new_tensor_id()93     ITensorInfo::Id allocate_new_tensor_id()
94     {
95         return ++_next_id;
96     }
97     /** Generate @ref GpuWorkloadSourceCode from the workload sketch
98      * @note The sketch must be valid. Any error encountered during the building of the code will be thrown.
99      *
100      * @return GpuWorkloadSourceCode  The generated workload code
101      */
generate_source_code()102     GpuWorkloadSourceCode generate_source_code() const
103     {
104         return component_graph().fuse(_mem_map).write_workload_code();
105     }
106     /** Create a virtual (see @ref MemoryType) tensor info and save it
107      *
108      * @return ITensorInfo*  The created virtual tensor info object pointer
109      */
create_virtual_tensor()110     ITensorInfo *create_virtual_tensor()
111     {
112         auto uptr = std::make_unique<TensorInfo>();
113         uptr->set_id(-allocate_new_tensor_id()); // virtual tensors must have negative id
114         register_memory_descriptor(*uptr, MemoryDescriptor{ MemoryType::Virtual });
115         _managed_tensor_info_list.emplace_back(std::move(uptr));
116         return _managed_tensor_info_list.back().get();
117     }
118     /** Create an auxiliary (see @ref MemoryType) tensor info and save it
119      *
120      * @return ITensorInfo*  The created auxiliary tensor info object pointer
121      */
122 
123     /** Create an auxiliary (see @ref MemoryType) tensor info and save it
124      *
125      * @param[in] tensor_info @ref ITensorInfo to copy from
126      *
127      * @return ITensorInfo*  The created auxiliary tensor info object pointer
128      */
create_auxiliary_tensor(const ITensorInfo & tensor_info)129     ITensorInfo *create_auxiliary_tensor(const ITensorInfo &tensor_info)
130     {
131         auto uptr = std::make_unique<TensorInfo>(tensor_info);
132         uptr->set_id(allocate_new_tensor_id());
133         register_memory_descriptor(*uptr, MemoryDescriptor{ MemoryType::Auxiliary, AuxMemoryInfo{ uptr->total_size() } });
134         _managed_tensor_info_list.emplace_back(std::move(uptr));
135         return _managed_tensor_info_list.back().get();
136     }
137     /** Register memory descriptor of a tensor info
138      *
139      * @param[in] info     @ref ITensorInfo to be registered
140      * @param[in] mem_desc @ref MemoryDescriptor to be registered with @p info
141      */
register_memory_descriptor(const ITensorInfo & info,const MemoryDescriptor & mem_desc)142     void register_memory_descriptor(const ITensorInfo &info, const MemoryDescriptor &mem_desc)
143     {
144         _mem_map[info.id()] = mem_desc;
145     }
146 
147 private:
148     Context                                 *_context;
149     GpuComponentServices                     _comp_services;
150     GpuKernelComponentGraph                  _component_graph;
151     GpuOperatorGroup                         _operator_group;
152     ITensorInfo::Id                          _next_id{ ITensorInfo::invalid_tensor_id };
153     std::vector<std::unique_ptr<TensorInfo>> _managed_tensor_info_list;
154     MemoryDescriptorMap                      _mem_map;
155 };
156 } // namespace dynamic_fusion
157 } // namespace experimental
158 } // namespace arm_compute
159 #endif /* SRC_DYNAMIC_FUSION_SKETCH_GPU_GPUWORKLOADSKETCHIMPL */
160