Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[vulkan] Fix stale GPU lifetime management tests for Vulkan. #8601

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/runtime/vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@ WEAK int halide_vulkan_device_free(void *user_context, halide_buffer_t *halide_b
halide_buffer->device_interface = nullptr;

#ifdef DEBUG_RUNTIME
debug(user_context) << "Vulkan: Released memory for device region ("
<< "user_context: " << user_context << ", "
<< "buffer: " << halide_buffer << ", "
<< "size_in_bytes: " << (uint64_t)device_region->size << ")\n";

uint64_t t_after = halide_current_time_ns(user_context);
debug(user_context) << " Time: " << (t_after - t_before) / 1.0e6 << " ms\n";
#endif
Expand Down Expand Up @@ -348,6 +353,11 @@ WEAK int halide_vulkan_device_malloc(void *user_context, halide_buffer_t *buf) {
}

#ifdef DEBUG_RUNTIME
debug(user_context) << "Vulkan: Reserved memory for device region ("
<< "user_context: " << user_context << ", "
<< "buffer: " << buf << ", "
<< "size_in_bytes: " << (uint64_t)size << ")\n";

uint64_t t_after = halide_current_time_ns(user_context);
debug(user_context) << " Time: " << (t_after - t_before) / 1.0e6 << " ms\n";
#endif
Expand Down
50 changes: 43 additions & 7 deletions src/runtime/vulkan_resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ struct VulkanSharedMemoryAllocation {

// Entry point metadata for shader modules
struct VulkanShaderBinding {
const char *entry_point_name = nullptr;
char *entry_point_name = nullptr;
VulkanDispatchData dispatch_data = {};
VkDescriptorPool descriptor_pool = VK_NULL_HANDLE;
VkDescriptorSet descriptor_set = VK_NULL_HANDLE;
Expand Down Expand Up @@ -1182,7 +1182,7 @@ VulkanShaderBinding *vk_decode_shader_bindings(void *user_context, VulkanMemoryA
halide_debug_assert(user_context, (idx + 8) < module_entries); // should be at least 8 entries

// [0] Length of entry point name (padded to nearest word size)
uint32_t entry_point_name_length = module_ptr[idx++];
uint32_t entry_point_name_length = module_ptr[idx++]; // length is number of uint32_t entries

// [*] Entry point string data (padded with null chars)
const char *entry_point_name = (const char *)(module_ptr + idx); // NOTE: module owns string data
Expand Down Expand Up @@ -1304,7 +1304,13 @@ VulkanShaderBinding *vk_decode_shader_bindings(void *user_context, VulkanMemoryA
}
debug(user_context) << "]\n";
#endif
shader_bindings[n].entry_point_name = entry_point_name; // NOTE: module owns string data
shader_bindings[n].entry_point_name = (char *)vk_host_malloc(user_context, entry_point_name_length * sizeof(uint32_t), 0, alloc_scope, allocator->callbacks());
if (shader_bindings[n].entry_point_name == nullptr) {
error(user_context) << "Vulkan: Failed to allocate entry_point_name! Out of memory!\n";
return nullptr;
}

memcpy(shader_bindings[n].entry_point_name, entry_point_name, entry_point_name_length * sizeof(uint32_t));
shader_bindings[n].uniform_buffer_count = uniform_buffer_count;
shader_bindings[n].storage_buffer_count = storage_buffer_count;
shader_bindings[n].specialization_constants_count = specialization_constants_count;
Expand Down Expand Up @@ -1611,10 +1617,11 @@ void vk_destroy_compiled_shader_module(VulkanCompiledShaderModule *shader_module

if (shader_module->descriptor_set_layouts) {
for (uint32_t n = 0; n < shader_module->shader_count; n++) {
debug(user_context) << " destroying descriptor set layout [" << n << "] " << shader_module->shader_bindings[n].entry_point_name << "\n";
debug(user_context) << " destroying descriptor set layout [" << n << "] " << shader_module->descriptor_set_layouts[n] << "\n";
vk_destroy_descriptor_set_layout(user_context, allocator, shader_module->descriptor_set_layouts[n]);
shader_module->descriptor_set_layouts[n] = VK_NULL_HANDLE;
}
debug(user_context) << " destroying descriptor set layout " << (void *)shader_module->descriptor_set_layouts << "\n";
vk_host_free(user_context, shader_module->descriptor_set_layouts, allocator->callbacks());
shader_module->descriptor_set_layouts = nullptr;
}
Expand All @@ -1625,24 +1632,45 @@ void vk_destroy_compiled_shader_module(VulkanCompiledShaderModule *shader_module
}

if (shader_module->shader_bindings) {
#ifdef DEBUG_RUNTIME
debug(user_context)
<< " destroying shader bindings ("
<< "shader_module: " << shader_module << ", "
<< "shader_bindings: " << shader_module->shader_bindings << ")\n";
#endif
for (uint32_t n = 0; n < shader_module->shader_count; n++) {
#ifdef DEBUG_RUNTIME
debug(user_context) << " destroying shader binding [" << n << "] ";
if (shader_module->shader_bindings[n].entry_point_name) {
debug(user_context) << shader_module->shader_bindings[n].entry_point_name << "\n";
vk_host_free(user_context, shader_module->shader_bindings[n].entry_point_name, allocator->callbacks());
shader_module->shader_bindings[n].entry_point_name = nullptr;
} else {
debug(user_context) << "<unknown entry point>\n";
}
#endif
if (shader_module->shader_bindings[n].args_region) {
debug(user_context) << " destroying shader binding args regions [" << n << "]\n";
vk_destroy_scalar_uniform_buffer(user_context, allocator, shader_module->shader_bindings[n].args_region);
shader_module->shader_bindings[n].args_region = nullptr;
}
if (shader_module->shader_bindings[n].descriptor_pool) {
debug(user_context) << " destroying shader binding descriptor pool [" << n << "]\n";
vk_destroy_descriptor_pool(user_context, allocator, shader_module->shader_bindings[n].descriptor_pool);
shader_module->shader_bindings[n].descriptor_pool = VK_NULL_HANDLE;
}
if (shader_module->shader_bindings[n].specialization_constants) {
debug(user_context) << " destroying shader binding specialization constants [" << n << "]\n";
vk_host_free(user_context, shader_module->shader_bindings[n].specialization_constants, allocator->callbacks());
shader_module->shader_bindings[n].specialization_constants = nullptr;
}
if (shader_module->shader_bindings[n].shared_memory_allocations) {
debug(user_context) << " destroying shader binding shared memory allocations [" << n << "]\n";
vk_host_free(user_context, shader_module->shader_bindings[n].shared_memory_allocations, allocator->callbacks());
shader_module->shader_bindings[n].shared_memory_allocations = nullptr;
}
if (shader_module->shader_bindings[n].compute_pipeline) {
debug(user_context) << " destroying shader binding compute pipeline [" << n << "]\n";
vk_destroy_compute_pipeline(user_context, allocator, shader_module->shader_bindings[n].compute_pipeline);
shader_module->shader_bindings[n].compute_pipeline = VK_NULL_HANDLE;
}
Expand All @@ -1651,13 +1679,14 @@ void vk_destroy_compiled_shader_module(VulkanCompiledShaderModule *shader_module
shader_module->shader_bindings = nullptr;
}
if (shader_module->shader_module) {
debug(user_context) << " . destroying shader module " << (void *)shader_module->shader_module << "\n";
debug(user_context) << " destroying shader module " << (void *)shader_module->shader_module << "\n";
vkDestroyShaderModule(allocator->current_device(), shader_module->shader_module, allocator->callbacks());
shader_module->shader_module = VK_NULL_HANDLE;
}
shader_module->shader_count = 0;
vk_host_free(user_context, shader_module, allocator->callbacks());
shader_module = nullptr;
debug(user_context) << " Destroyed compiled shader module: " << (void *)shader_module << "\n";
}

void vk_destroy_compilation_cache_entry(VulkanCompilationCacheEntry *cache_entry) {
Expand All @@ -1674,15 +1703,22 @@ void vk_destroy_compilation_cache_entry(VulkanCompilationCacheEntry *cache_entry
return;
}

debug(user_context)
<< " Destroying " << cache_entry->module_count << " shader modules for cache entry (cache_entry: " << cache_entry << ")\n";

for (uint32_t m = 0; m < cache_entry->module_count; m++) {
VulkanCompiledShaderModule *shader_module = cache_entry->compiled_modules[m];
vk_destroy_compiled_shader_module(shader_module, allocator);
debug(user_context)
<< " destroying compiled_module[" << m << "]: " << cache_entry->compiled_modules[m] << "\n";

VulkanCompiledShaderModule *compiled_module = cache_entry->compiled_modules[m];
vk_destroy_compiled_shader_module(compiled_module, allocator);
}

cache_entry->module_count = 0;
cache_entry->allocator = nullptr;
vk_host_free(user_context, cache_entry, allocator->callbacks());
cache_entry = nullptr;
debug(user_context) << "Vulkan: Destroyed compilation cache entry (cache_entry: " << cache_entry << ")\n";
}

int vk_destroy_shader_modules(void *user_context, VulkanMemoryAllocator *allocator) {
Expand Down
4 changes: 2 additions & 2 deletions test/common/gpu_object_lifetime_tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ class GpuObjectLifetimeTracker {
{"vk_create_pipeline_layout", "vk_destroy_pipeline_layout"},
{"vk_create_compute_pipeline", "vk_destroy_compute_pipeline"},
{"vk_create_descriptor_pool", "vk_destroy_descriptor_pool"},
{"Vulkan: Allocated memory for device region", "Vulkan: Deallocated memory for device region"},
{"Vulkan: Created buffer", "Vulkan: Destroyed buffer"},
{"Vulkan: Reserved memory for device region", "Vulkan: Released memory for device region"},
{"vkCreateBuffer: Created buffer for device region", "vkDestroyBuffer: Destroyed buffer for device region"},

// WebGPU objects
{"wgpuCreateInstance", "wgpuInstanceRelease", true},
Expand Down
Loading