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