-
Notifications
You must be signed in to change notification settings - Fork 992
Expand file tree
/
Copy pathAdapter.h
More file actions
314 lines (258 loc) · 8.31 KB
/
Adapter.h
File metadata and controls
314 lines (258 loc) · 8.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
// @lint-ignore-every CLANGTIDY facebook-hte-BadMemberName
#include <executorch/backends/vulkan/runtime/vk_api/vk_api.h>
#include <executorch/backends/vulkan/runtime/vk_api/Device.h>
#include <executorch/backends/vulkan/runtime/vk_api/Pipeline.h>
#include <executorch/backends/vulkan/runtime/vk_api/memory/Allocator.h>
#include <array>
namespace vkcompute {
namespace vkapi {
//
// A Vulkan Adapter represents a logical device and all its properties. It
// manages all relevant properties of the underlying physical device, a
// handle to the logical device, and a number of compute queues available to
// the device. It is primarily responsible for managing the VkDevice handle
// which points to the logical device object on the GPU.
//
// This class is primarily used by the Runtime class, which holds one Adapter
// instance for each physical device visible to the VkInstance. Upon
// construction, this class will populate the physical device properties, but
// will not create the logical device until specifically requested via the
// init_device() function.
//
// init_device() will create the logical device and obtain the VkDevice handle
// for it. It will also create a number of compute queues up to the amount
// requested when the Adapter instance was constructed.
//
// Contexts (which represent one thread of execution) will request a compute
// queue from an Adapter. The Adapter will then select a compute queue to
// assign to the Context, attempting to balance load between all available
// queues. This will allow different Contexts (which typically execute on
// separate threads) to run concurrently.
//
#define NUM_QUEUE_MUTEXES 4
class Adapter final {
public:
explicit Adapter(
VkInstance instance,
PhysicalDevice physical_device,
const uint32_t num_queues,
const std::string& cache_data_path);
explicit Adapter(
VkInstance instance,
VkPhysicalDevice physical_device,
VkDevice logical_device,
const uint32_t num_queues,
const std::string& cache_data_path);
Adapter(const Adapter&) = delete;
Adapter& operator=(const Adapter&) = delete;
Adapter(Adapter&&) = delete;
Adapter& operator=(Adapter&&) = delete;
~Adapter();
struct Queue {
uint32_t family_index;
uint32_t queue_index;
VkQueueFlags capabilities;
VkQueue handle;
};
private:
// Use a mutex to manage queue usage info since
// it can be accessed from multiple threads
std::mutex queue_usage_mutex_;
// Physical Device Info
PhysicalDevice physical_device_;
// Queue Management
std::vector<Queue> queues_;
std::vector<uint32_t> queue_usage_;
std::array<std::mutex, NUM_QUEUE_MUTEXES> queue_mutexes_;
// Handles
VkInstance instance_;
DeviceHandle device_;
// Device-level resource caches
ShaderLayoutCache shader_layout_cache_;
ShaderCache shader_cache_;
PipelineLayoutCache pipeline_layout_cache_;
ComputePipelineCache compute_pipeline_cache_;
// Memory Management
SamplerCache sampler_cache_;
Allocator vma_;
// Miscellaneous
bool linear_tiling_3d_enabled_;
bool owns_device_;
public:
// Physical Device metadata
inline VkPhysicalDevice physical_handle() const {
return physical_device_.handle;
}
inline VkDevice device_handle() const {
return device_.handle;
}
inline bool has_unified_memory() const {
return physical_device_.has_unified_memory;
}
inline uint32_t num_compute_queues() const {
return physical_device_.num_compute_queues;
}
inline bool timestamp_compute_and_graphics() const {
return physical_device_.has_timestamps;
}
inline float timestamp_period() const {
return physical_device_.timestamp_period;
}
// Device Identity
inline const std::string& device_name() const {
return physical_device_.device_name;
}
inline vkapi::DeviceType device_type() const {
return physical_device_.device_type;
}
// Queue Management
Queue request_queue();
void return_queue(Queue&);
// Caches
inline ShaderLayoutCache& shader_layout_cache() {
return shader_layout_cache_;
}
inline ShaderCache& shader_cache() {
return shader_cache_;
}
inline PipelineLayoutCache& pipeline_layout_cache() {
return pipeline_layout_cache_;
}
inline ComputePipelineCache& compute_pipeline_cache() {
return compute_pipeline_cache_;
}
// Memory Allocation
inline SamplerCache& sampler_cache() {
return sampler_cache_;
}
inline Allocator& vma() {
return vma_;
}
inline bool linear_tiling_3d_enabled() const {
return linear_tiling_3d_enabled_;
}
// Physical Device Features
inline bool supports_16bit_storage_buffers() {
#ifdef ETVK_FORCE_NO_EXTENSIONS
return false;
#endif
#ifdef VK_KHR_16bit_storage
return physical_device_.shader_16bit_storage.storageBuffer16BitAccess ==
VK_TRUE;
#else
return false;
#endif /* VK_KHR_16bit_storage */
}
inline bool supports_8bit_storage_buffers() {
#ifdef ETVK_FORCE_NO_EXTENSIONS
return false;
#endif
#ifdef VK_KHR_8bit_storage
return physical_device_.shader_8bit_storage.storageBuffer8BitAccess ==
VK_TRUE;
#else
return false;
#endif /* VK_KHR_8bit_storage */
}
inline bool supports_float16_shader_types() {
#ifdef ETVK_FORCE_NO_EXTENSIONS
return false;
#endif
#ifdef VK_KHR_shader_float16_int8
return physical_device_.shader_float16_int8_types.shaderFloat16 == VK_TRUE;
#else
return false;
#endif /* VK_KHR_shader_float16_int8 */
}
inline bool supports_int8_shader_types() {
#ifdef ETVK_FORCE_NO_EXTENSIONS
return false;
#endif
#ifdef VK_KHR_shader_float16_int8
return physical_device_.shader_float16_int8_types.shaderInt8 == VK_TRUE;
#else
return false;
#endif /* VK_KHR_shader_float16_int8 */
}
inline bool supports_int8_dot_product() {
#ifdef ETVK_FORCE_NO_EXTENSIONS
return false;
#endif
#ifdef VK_KHR_shader_integer_dot_product
return physical_device_.shader_int_dot_product_features
.shaderIntegerDotProduct == VK_TRUE;
#else
return false;
#endif /* VK_KHR_shader_integer_dot_product */
}
inline bool supports_nv_cooperative_matrix2() {
#ifdef ETVK_FORCE_NO_EXTENSIONS
return false;
#endif
#ifdef VK_NV_cooperative_matrix2
return physical_device_.cooperative_matrix2_features
.cooperativeMatrixWorkgroupScope == VK_TRUE &&
physical_device_.cooperative_matrix2_features
.cooperativeMatrixFlexibleDimensions == VK_TRUE &&
physical_device_.cooperative_matrix2_features
.cooperativeMatrixTensorAddressing == VK_TRUE;
#else
return false;
#endif /* VK_NV_cooperative_matrix2 */
}
inline bool supports_int16_shader_types() {
#ifdef ETVK_FORCE_NO_EXTENSIONS
return false;
#endif
return physical_device_.supports_int16_shader_types;
}
inline bool supports_int64_shader_types() {
#ifdef ETVK_FORCE_NO_EXTENSIONS
return false;
#endif
return physical_device_.supports_int64_shader_types;
}
inline bool supports_float64_shader_types() {
#ifdef ETVK_FORCE_NO_EXTENSIONS
return false;
#endif
return physical_device_.supports_float64_shader_types;
}
inline bool has_full_float16_buffers_support() {
return supports_16bit_storage_buffers() && supports_float16_shader_types();
}
inline bool has_full_int8_buffers_support() {
return supports_8bit_storage_buffers() && supports_int8_shader_types();
}
inline size_t min_ubo_alignment() const {
return physical_device_.min_ubo_alignment;
}
inline uint32_t max_texture2d_dim() const {
return physical_device_.properties.limits.maxImageDimension2D;
}
inline uint32_t max_texture3d_dim() const {
return physical_device_.properties.limits.maxImageDimension3D;
}
inline uint32_t max_buffer_numel() const {
return physical_device_.properties.limits.maxStorageBufferRange;
}
// Command Buffer Submission
void submit_cmd(
const Queue&,
VkCommandBuffer,
VkFence fence = VK_NULL_HANDLE,
VkSemaphore wait_semaphore = VK_NULL_HANDLE,
VkSemaphore signal_semaphore = VK_NULL_HANDLE);
std::string stringize() const;
friend std::ostream& operator<<(std::ostream&, const Adapter&);
};
} // namespace vkapi
} // namespace vkcompute