Skip to content

Commit bb9054d

Browse files
committed
vulkan: guard against multiple initialization
This trades a late heap-use-after-free for an early abort, which feels more correct. Signed-off-by: Jared Van Bortel <[email protected]>
1 parent 00a5a66 commit bb9054d

File tree

3 files changed

+19
-0
lines changed

3 files changed

+19
-0
lines changed

ggml-vulkan.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5219,6 +5219,11 @@ GGML_CALL static bool ggml_backend_buffer_is_vk(ggml_backend_buffer_t buffer) {
52195219
return buffer->iface.get_name == ggml_backend_vk_buffer_get_name;
52205220
}
52215221

5222+
size_t ggml_backend_vk_idx(ggml_backend_t backend) {
5223+
ggml_backend_vk_context * ctx = (ggml_backend_vk_context *)backend->context;
5224+
return ctx->idx;
5225+
}
5226+
52225227
GGML_CALL static void ggml_backend_vk_buffer_free_buffer(ggml_backend_buffer_t buffer) {
52235228
#ifdef GGML_VULKAN_DEBUG
52245229
std::cerr << "ggml_backend_vk_buffer_free_buffer()" << std::endl;

ggml-vulkan.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ GGML_API GGML_CALL void ggml_vk_device_destroy(ggml_vk_device
2525
GGML_API GGML_CALL ggml_backend_t ggml_backend_vk_init(size_t dev_num);
2626

2727
GGML_API GGML_CALL bool ggml_backend_is_vk(ggml_backend_t backend);
28+
GGML_API GGML_CALL size_t ggml_backend_vk_idx(ggml_backend_t backend);
2829
GGML_API GGML_CALL int ggml_backend_vk_get_device_count(void);
2930
GGML_API GGML_CALL void ggml_backend_vk_get_device_description(int device, char * description, size_t description_size);
3031
GGML_API GGML_CALL void ggml_backend_vk_get_device_memory(int device, size_t * free, size_t * total);

llama.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2240,12 +2240,21 @@ struct llama_model {
22402240
}
22412241
};
22422242

2243+
#ifdef GGML_USE_VULKAN
2244+
static bool vulkan_backend_initialized[GGML_VK_MAX_DEVICES] = {};
2245+
#endif
2246+
22432247
struct llama_context {
22442248
llama_context(const llama_model & model) : model(model), t_start_us(model.t_start_us), t_load_us(model.t_load_us) {}
22452249
~llama_context() {
22462250
ggml_backend_sched_free(sched);
22472251

22482252
for (ggml_backend_t backend : backends) {
2253+
#ifdef GGML_USE_VULKAN
2254+
if (ggml_backend_is_vk(backend)) {
2255+
vulkan_backend_initialized[ggml_backend_vk_idx(backend)] = false;
2256+
}
2257+
#endif
22492258
ggml_backend_free(backend);
22502259
}
22512260

@@ -15489,6 +15498,8 @@ struct llama_context * llama_new_context_with_model(
1548915498
return nullptr;
1549015499
}
1549115500
if (model->split_mode == LLAMA_SPLIT_MODE_NONE) {
15501+
GGML_ASSERT(!vulkan_backend_initialized[model->main_gpu]);
15502+
vulkan_backend_initialized[model->main_gpu] = true;
1549215503
ggml_backend_t backend = ggml_backend_vk_init(model->main_gpu);
1549315504
if (backend == nullptr) {
1549415505
LLAMA_LOG_ERROR("%s: failed to initialize Vulkan backend\n", __func__);
@@ -15498,6 +15509,8 @@ struct llama_context * llama_new_context_with_model(
1549815509
ctx->backends.push_back(backend);
1549915510
} else {
1550015511
for (int device = 0; device < ggml_backend_vk_get_device_count(); ++device) {
15512+
GGML_ASSERT(!vulkan_backend_initialized[device]);
15513+
vulkan_backend_initialized[device] = true;
1550115514
ggml_backend_t backend = ggml_backend_vk_init(device);
1550215515
if (backend == nullptr) {
1550315516
LLAMA_LOG_ERROR("%s: failed to initialize Vulkan%d backend\n", __func__, device);

0 commit comments

Comments
 (0)