Line data Source code
1 : // SPDX-License-Identifier: Apache-2.0
2 : #pragma once
3 :
4 : #include <set>
5 : #include <unordered_map>
6 :
7 : #include "kompute/Core.hpp"
8 :
9 : #include "kompute/Sequence.hpp"
10 : #include "logger/Logger.hpp"
11 :
12 : #define KP_DEFAULT_SESSION "DEFAULT"
13 :
14 : namespace kp {
15 :
16 : /**
17 : Base orchestrator which creates and manages device and child components
18 : */
19 : class Manager
20 : {
21 : public:
22 : /**
23 : Base constructor and default used which creates the base resources
24 : including choosing the device 0 by default.
25 : */
26 : Manager();
27 :
28 : /**
29 : * Similar to base constructor but allows for further configuration to use
30 : * when creating the Vulkan resources.
31 : *
32 : * @param physicalDeviceIndex The index of the physical device to use
33 : * @param familyQueueIndices (Optional) List of queue indices to add for
34 : * explicit allocation
35 : * @param desiredExtensions The desired extensions to load from
36 : * physicalDevice
37 : */
38 : Manager(uint32_t physicalDeviceIndex,
39 : const std::vector<uint32_t>& familyQueueIndices = {},
40 : const std::vector<std::string>& desiredExtensions = {});
41 :
42 : /**
43 : * Manager constructor which allows your own vulkan application to integrate
44 : * with the kompute use.
45 : *
46 : * @param instance Vulkan compute instance to base this application
47 : * @param physicalDevice Vulkan physical device to use for application
48 : * @param device Vulkan logical device to use for all base resources
49 : * @param physicalDeviceIndex Index for vulkan physical device used
50 : */
51 : Manager(std::shared_ptr<vk::Instance> instance,
52 : std::shared_ptr<vk::PhysicalDevice> physicalDevice,
53 : std::shared_ptr<vk::Device> device);
54 :
55 : /**
56 : * Manager destructor which would ensure all owned resources are destroyed
57 : * unless explicitly stated that resources should not be destroyed or freed.
58 : */
59 : ~Manager();
60 :
61 : /**
62 : * Create a managed sequence that will be destroyed by this manager
63 : * if it hasn't been destroyed by its reference count going to zero.
64 : *
65 : * @param queueIndex The queue to use from the available queues
66 : * @param nrOfTimestamps The maximum number of timestamps to allocate.
67 : * If zero (default), disables latching of timestamps.
68 : * @returns Shared pointer with initialised sequence
69 : */
70 : std::shared_ptr<Sequence> sequence(uint32_t queueIndex = 0,
71 : uint32_t totalTimestamps = 0);
72 :
73 : /**
74 : * Create a managed tensor that will be destroyed by this manager
75 : * if it hasn't been destroyed by its reference count going to zero.
76 : *
77 : * @param data The data to initialize the tensor with
78 : * @param tensorType The type of tensor to initialize
79 : * @returns Shared pointer with initialised tensor
80 : */
81 : template<typename T>
82 97 : std::shared_ptr<TensorT<T>> tensorT(
83 : const std::vector<T>& data,
84 : Tensor::TensorTypes tensorType = Tensor::TensorTypes::eDevice)
85 : {
86 194 : KP_LOG_DEBUG("Kompute Manager tensor creation triggered");
87 :
88 195 : std::shared_ptr<TensorT<T>> tensor{ new kp::TensorT<T>(
89 97 : this->mPhysicalDevice, this->mDevice, data, tensorType) };
90 :
91 96 : if (this->mManageResources) {
92 96 : this->mManagedTensors.push_back(tensor);
93 : }
94 :
95 96 : return tensor;
96 0 : }
97 :
98 88 : std::shared_ptr<TensorT<float>> tensor(
99 : const std::vector<float>& data,
100 : Tensor::TensorTypes tensorType = Tensor::TensorTypes::eDevice)
101 : {
102 88 : return this->tensorT<float>(data, tensorType);
103 : }
104 :
105 : std::shared_ptr<Tensor> tensor(
106 : void* data,
107 : uint32_t elementTotalCount,
108 : uint32_t elementMemorySize,
109 : const Tensor::TensorDataTypes& dataType,
110 : Tensor::TensorTypes tensorType = Tensor::TensorTypes::eDevice)
111 : {
112 : std::shared_ptr<Tensor> tensor{ new kp::Tensor(this->mPhysicalDevice,
113 : this->mDevice,
114 : data,
115 : elementTotalCount,
116 : elementMemorySize,
117 : dataType,
118 : tensorType) };
119 :
120 : if (this->mManageResources) {
121 : this->mManagedTensors.push_back(tensor);
122 : }
123 :
124 : return tensor;
125 : }
126 :
127 : /**
128 : * Default non-template function that can be used to create algorithm
129 : * objects which provides default types to the push and spec constants as
130 : * floats.
131 : *
132 : * @param tensors (optional) The tensors to initialise the algorithm with
133 : * @param spirv (optional) The SPIRV bytes for the algorithm to dispatch
134 : * @param workgroup (optional) kp::Workgroup for algorithm to use, and
135 : * defaults to (tensor[0].size(), 1, 1)
136 : * @param specializationConstants (optional) float vector to use for
137 : * specialization constants, and defaults to an empty constant
138 : * @param pushConstants (optional) float vector to use for push constants,
139 : * and defaults to an empty constant
140 : * @returns Shared pointer with initialised algorithm
141 : */
142 33 : std::shared_ptr<Algorithm> algorithm(
143 : const std::vector<std::shared_ptr<Tensor>>& tensors = {},
144 : const std::vector<uint32_t>& spirv = {},
145 : const Workgroup& workgroup = {},
146 : const std::vector<float>& specializationConstants = {},
147 : const std::vector<float>& pushConstants = {})
148 : {
149 : return this->algorithm<>(
150 33 : tensors, spirv, workgroup, specializationConstants, pushConstants);
151 : }
152 :
153 : /**
154 : * Create a managed algorithm that will be destroyed by this manager
155 : * if it hasn't been destroyed by its reference count going to zero.
156 : *
157 : * @param tensors (optional) The tensors to initialise the algorithm with
158 : * @param spirv (optional) The SPIRV bytes for the algorithm to dispatch
159 : * @param workgroup (optional) kp::Workgroup for algorithm to use, and
160 : * defaults to (tensor[0].size(), 1, 1)
161 : * @param specializationConstants (optional) templatable vector parameter to
162 : * use for specialization constants, and defaults to an empty constant
163 : * @param pushConstants (optional) templatable vector parameter to use for
164 : * push constants, and defaults to an empty constant
165 : * @returns Shared pointer with initialised algorithm
166 : */
167 : template<typename S = float, typename P = float>
168 37 : std::shared_ptr<Algorithm> algorithm(
169 : const std::vector<std::shared_ptr<Tensor>>& tensors,
170 : const std::vector<uint32_t>& spirv,
171 : const Workgroup& workgroup,
172 : const std::vector<S>& specializationConstants,
173 : const std::vector<P>& pushConstants)
174 : {
175 :
176 74 : KP_LOG_DEBUG("Kompute Manager algorithm creation triggered");
177 :
178 37 : std::shared_ptr<Algorithm> algorithm{ new kp::Algorithm(
179 37 : this->mDevice,
180 : tensors,
181 : spirv,
182 : workgroup,
183 : specializationConstants,
184 : pushConstants) };
185 :
186 37 : if (this->mManageResources) {
187 37 : this->mManagedAlgorithms.push_back(algorithm);
188 : }
189 :
190 37 : return algorithm;
191 0 : }
192 :
193 : /**
194 : * Destroy the GPU resources and all managed resources by manager.
195 : **/
196 : void destroy();
197 : /**
198 : * Run a pseudo-garbage collection to release all the managed resources
199 : * that have been already freed due to these reaching to zero ref count.
200 : **/
201 : void clear();
202 :
203 : /**
204 : * Information about the current device.
205 : *
206 : * @return vk::PhysicalDeviceProperties containing information about the
207 : *device
208 : **/
209 : vk::PhysicalDeviceProperties getDeviceProperties() const;
210 :
211 : /**
212 : * List the devices available in the current vulkan instance.
213 : *
214 : * @return vector of physical devices containing their respective properties
215 : **/
216 : std::vector<vk::PhysicalDevice> listDevices() const;
217 :
218 : /**
219 : * The current Vulkan instance.
220 : *
221 : * @return a shared pointer to the current Vulkan instance held by this
222 : *object
223 : **/
224 : std::shared_ptr<vk::Instance> getVkInstance() const;
225 :
226 : private:
227 : // -------------- OPTIONALLY OWNED RESOURCES
228 : std::shared_ptr<vk::Instance> mInstance = nullptr;
229 : bool mFreeInstance = false;
230 : std::shared_ptr<vk::PhysicalDevice> mPhysicalDevice = nullptr;
231 : std::shared_ptr<vk::Device> mDevice = nullptr;
232 : bool mFreeDevice = false;
233 :
234 : // -------------- ALWAYS OWNED RESOURCES
235 : std::vector<std::weak_ptr<Tensor>> mManagedTensors;
236 : std::vector<std::weak_ptr<Sequence>> mManagedSequences;
237 : std::vector<std::weak_ptr<Algorithm>> mManagedAlgorithms;
238 :
239 : std::vector<uint32_t> mComputeQueueFamilyIndices;
240 : std::vector<std::shared_ptr<vk::Queue>> mComputeQueues;
241 :
242 : bool mManageResources = false;
243 :
244 : #ifndef KOMPUTE_DISABLE_VK_DEBUG_LAYERS
245 : vk::DebugReportCallbackEXT mDebugReportCallback;
246 : vk::DispatchLoaderDynamic mDebugDispatcher;
247 : #endif
248 :
249 : // Create functions
250 : void createInstance();
251 : void createDevice(const std::vector<uint32_t>& familyQueueIndices = {},
252 : uint32_t hysicalDeviceIndex = 0,
253 : const std::vector<std::string>& desiredExtensions = {});
254 : };
255 :
256 : } // End namespace kp
|