Commit cf02415e for whisper.cpp
commit cf02415e29e9daa30c5387209fd45e5299af9bca
Author: losewayy <1134285612@qq.com>
Date: Thu Oct 15 16:37:35 2026 +0800
vulkan : fix concurrent first device init (llama/29766)
* vulkan : fix concurrent first device init
* tests : load models in parallel in test-thread-safety
Loading them serially never exercised concurrent first backend init, so the crash reported in #29764 was invisible to this test.
* vulkan : create fence before retaining device in buffer context
diff --git a/ggml/src/ggml-vulkan/ggml-vulkan.cpp b/ggml/src/ggml-vulkan/ggml-vulkan.cpp
index 42057114..436bfe3b 100644
--- a/ggml/src/ggml-vulkan/ggml-vulkan.cpp
+++ b/ggml/src/ggml-vulkan/ggml-vulkan.cpp
@@ -3990,10 +3990,12 @@ void ggml_vk_load_shaders(vk_device& device, vk_pipeline requested) {
vk_device ggml_vk_get_device(size_t idx) {
VK_LOG_DEBUG("ggml_vk_get_device(" << idx << ")");
+ static std::mutex mutex;
+ std::lock_guard<std::mutex> lock(mutex);
+
if (vk_instance.devices[idx] == nullptr) {
VK_LOG_DEBUG("Initializing new vk_device");
vk_device device = std::make_shared<vk_device_struct>();
- vk_instance.devices[idx] = device;
device->memory_logger = std::unique_ptr<vk_memory_logger>(new vk_memory_logger());
@@ -4891,14 +4893,14 @@ vk_device ggml_vk_get_device(size_t idx) {
device->async_use_transfer_queue = false;
}
+ device->fence = device->device.createFence({});
+
device->buffer_type = {
/* .iface = */ ggml_backend_vk_buffer_type_interface,
/* .device = */ ggml_backend_reg_dev_get(ggml_backend_vk_reg(), idx),
/* .context = */ new ggml_backend_vk_buffer_type_context{ device->name, device },
};
- device->fence = device->device.createFence({});
-
device->idx = idx;
device->serialize_submissions = getenv("GGML_VK_SERIALIZE_SUBMISSIONS") != nullptr;
@@ -4920,6 +4922,9 @@ vk_device ggml_vk_get_device(size_t idx) {
device->mmvq_mode = 1;
}
+ // publish the device only when it is fully built
+ vk_instance.devices[idx] = device;
+
return device;
}
@@ -16463,6 +16468,11 @@ void vk_queue_handle_unsynchronized::submit(vk::ArrayProxy<const vk::SubmitInfo>
}
vk_device_struct::~vk_device_struct() {
+ // the build failed before the device was created, nothing to destroy
+ if (device == VK_NULL_HANDLE) {
+ return;
+ }
+
VK_LOG_DEBUG("destroy device " << name);
device.destroyFence(fence);