diff --git a/discover/gpu_info_vulkan.c b/discover/gpu_info_vulkan.c index b520c8436..a85754a29 100644 --- a/discover/gpu_info_vulkan.c +++ b/discover/gpu_info_vulkan.c @@ -203,6 +203,16 @@ void vk_check_vram(vk_handle_t rh, int i, mem_info_t *resp) { snprintf(&resp->gpu_id[0], GPU_ID_LEN, "%d", i); resp->gpu_name[GPU_NAME_LEN - 1] = '\0'; strncpy(&resp->gpu_name[0], properties.deviceName, GPU_NAME_LEN - 1); + resp->gpu_name[GPU_NAME_LEN - 1] = '\0'; + const uint8_t *uuid = properties.pipelineCacheUUID; + snprintf(&resp->gpu_id[0], GPU_ID_LEN, + "GPU-%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", + uuid[0], uuid[1], uuid[2], uuid[3], + uuid[4], uuid[5], + uuid[6], uuid[7], + uuid[8], uuid[9], + uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15] + ); resp->total = (uint64_t) device_memory_total_size; resp->free = (uint64_t) device_memory_heap_budget; resp->major = VK_API_VERSION_MAJOR(properties.apiVersion); diff --git a/llama/patches/0023-vulkan-get-GPU-ID-ollama-v0.11.5.patch b/llama/patches/0023-vulkan-get-GPU-ID-ollama-v0.11.5.patch new file mode 100644 index 000000000..f5b8f428d --- /dev/null +++ b/llama/patches/0023-vulkan-get-GPU-ID-ollama-v0.11.5.patch @@ -0,0 +1,115 @@ +From e0ba120c913a2931010a31e0fdf160697a15b9f1 Mon Sep 17 00:00:00 2001 +From: Xiaodong Ye +Date: Mon, 18 Aug 2025 12:48:07 +0800 +Subject: [PATCH] vulkan: get GPU ID (ollama v0.11.5) + +Signed-off-by: Xiaodong Ye +--- + discover/gpu_info_vulkan.c | 9 +++++ + .../ggml/ggml/src/ggml-vulkan/ggml-vulkan.cpp | 35 +++++++++++++++++++ + 2 files changed, 44 insertions(+) + +diff --git a/discover/gpu_info_vulkan.c b/discover/gpu_info_vulkan.c +index 6d67353d..afac97dd 100644 +--- a/discover/gpu_info_vulkan.c ++++ b/discover/gpu_info_vulkan.c +@@ -171,6 +171,15 @@ void vk_check_vram(vk_handle_t rh, int i, mem_info_t *resp) { + snprintf(&resp->gpu_id[0], GPU_ID_LEN, "%d", i); + strncpy(&resp->gpu_name[0], properties.deviceName, GPU_NAME_LEN - 1); + resp->gpu_name[GPU_NAME_LEN - 1] = '\0'; ++ const uint8_t *uuid = properties.pipelineCacheUUID; ++ snprintf(&resp->gpu_id[0], GPU_ID_LEN, ++ "GPU-%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", ++ uuid[0], uuid[1], uuid[2], uuid[3], ++ uuid[4], uuid[5], ++ uuid[6], uuid[7], ++ uuid[8], uuid[9], ++ uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15] ++ ); + resp->total = (uint64_t) device_memory_total_size; + resp->free = (uint64_t) device_memory_heap_budget; + resp->major = VK_API_VERSION_MAJOR(properties.apiVersion); +diff --git a/ml/backend/ggml/ggml/src/ggml-vulkan/ggml-vulkan.cpp b/ml/backend/ggml/ggml/src/ggml-vulkan/ggml-vulkan.cpp +index 4070e248..1c8c15d5 100644 +--- a/ml/backend/ggml/ggml/src/ggml-vulkan/ggml-vulkan.cpp ++++ b/ml/backend/ggml/ggml/src/ggml-vulkan/ggml-vulkan.cpp +@@ -10194,6 +10194,27 @@ static void ggml_vk_get_device_description(int device, char * description, size_ + snprintf(description, description_size, "%s", props.deviceName.data()); + } + ++static std::string ggml_vk_get_device_id(int device) { ++ ggml_vk_instance_init(); ++ ++ std::vector devices = vk_instance.instance.enumeratePhysicalDevices(); ++ ++ vk::PhysicalDeviceProperties props; ++ devices[device].getProperties(&props); ++ ++ const auto& uuid = props.pipelineCacheUUID; ++ char id[64]; ++ snprintf(id, sizeof(id), ++ "GPU-%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", ++ uuid[0], uuid[1], uuid[2], uuid[3], ++ uuid[4], uuid[5], ++ uuid[6], uuid[7], ++ uuid[8], uuid[9], ++ uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15] ++ ); ++ return std::string(id); ++} ++ + // backend interface + + #define UNUSED GGML_UNUSED +@@ -10790,6 +10811,12 @@ void ggml_backend_vk_get_device_description(int device, char * description, size + ggml_vk_get_device_description(dev_idx, description, description_size); + } + ++std::string ggml_backend_vk_get_device_id(int device) { ++ GGML_ASSERT(device < (int) vk_instance.device_indices.size()); ++ int dev_idx = vk_instance.device_indices[device]; ++ return ggml_vk_get_device_id(dev_idx); ++} ++ + void ggml_backend_vk_get_device_memory(int device, size_t * free, size_t * total) { + GGML_ASSERT(device < (int) vk_instance.device_indices.size()); + +@@ -10812,6 +10839,7 @@ struct ggml_backend_vk_device_context { + size_t device; + std::string name; + std::string description; ++ std::string id; + }; + + static const char * ggml_backend_vk_device_get_name(ggml_backend_dev_t dev) { +@@ -10824,6 +10852,11 @@ static const char * ggml_backend_vk_device_get_description(ggml_backend_dev_t de + return ctx->description.c_str(); + } + ++static const char * ggml_backend_vk_device_get_id(ggml_backend_dev_t dev) { ++ ggml_backend_vk_device_context * ctx = (ggml_backend_vk_device_context *)dev->context; ++ return ctx->id.c_str(); ++} ++ + static void ggml_backend_vk_device_get_memory(ggml_backend_dev_t device, size_t * free, size_t * total) { + ggml_backend_vk_device_context * ctx = (ggml_backend_vk_device_context *)device->context; + ggml_backend_vk_get_device_memory(ctx->device, free, total); +@@ -10847,6 +10880,7 @@ static enum ggml_backend_dev_type ggml_backend_vk_device_get_type(ggml_backend_d + static void ggml_backend_vk_device_get_props(ggml_backend_dev_t dev, struct ggml_backend_dev_props * props) { + props->name = ggml_backend_vk_device_get_name(dev); + props->description = ggml_backend_vk_device_get_description(dev); ++ props->id = ggml_backend_vk_device_get_id(dev); + props->type = ggml_backend_vk_device_get_type(dev); + ggml_backend_vk_device_get_memory(dev, &props->memory_free, &props->memory_total); + props->caps = { +@@ -11265,6 +11299,7 @@ static ggml_backend_dev_t ggml_backend_vk_reg_get_device(ggml_backend_reg_t reg, + ctx->device = i; + ctx->name = GGML_VK_NAME + std::to_string(i); + ctx->description = desc; ++ ctx->id = ggml_backend_vk_get_device_id(i); + devices.push_back(new ggml_backend_device { + /* .iface = */ ggml_backend_vk_device_i, + /* .reg = */ reg, +-- +2.25.1 + diff --git a/ml/backend/ggml/ggml/src/ggml-vulkan/ggml-vulkan.cpp b/ml/backend/ggml/ggml/src/ggml-vulkan/ggml-vulkan.cpp index 4070e248b..1c8c15d52 100644 --- a/ml/backend/ggml/ggml/src/ggml-vulkan/ggml-vulkan.cpp +++ b/ml/backend/ggml/ggml/src/ggml-vulkan/ggml-vulkan.cpp @@ -10194,6 +10194,27 @@ static void ggml_vk_get_device_description(int device, char * description, size_ snprintf(description, description_size, "%s", props.deviceName.data()); } +static std::string ggml_vk_get_device_id(int device) { + ggml_vk_instance_init(); + + std::vector devices = vk_instance.instance.enumeratePhysicalDevices(); + + vk::PhysicalDeviceProperties props; + devices[device].getProperties(&props); + + const auto& uuid = props.pipelineCacheUUID; + char id[64]; + snprintf(id, sizeof(id), + "GPU-%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", + uuid[0], uuid[1], uuid[2], uuid[3], + uuid[4], uuid[5], + uuid[6], uuid[7], + uuid[8], uuid[9], + uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15] + ); + return std::string(id); +} + // backend interface #define UNUSED GGML_UNUSED @@ -10790,6 +10811,12 @@ void ggml_backend_vk_get_device_description(int device, char * description, size ggml_vk_get_device_description(dev_idx, description, description_size); } +std::string ggml_backend_vk_get_device_id(int device) { + GGML_ASSERT(device < (int) vk_instance.device_indices.size()); + int dev_idx = vk_instance.device_indices[device]; + return ggml_vk_get_device_id(dev_idx); +} + void ggml_backend_vk_get_device_memory(int device, size_t * free, size_t * total) { GGML_ASSERT(device < (int) vk_instance.device_indices.size()); @@ -10812,6 +10839,7 @@ struct ggml_backend_vk_device_context { size_t device; std::string name; std::string description; + std::string id; }; static const char * ggml_backend_vk_device_get_name(ggml_backend_dev_t dev) { @@ -10824,6 +10852,11 @@ static const char * ggml_backend_vk_device_get_description(ggml_backend_dev_t de return ctx->description.c_str(); } +static const char * ggml_backend_vk_device_get_id(ggml_backend_dev_t dev) { + ggml_backend_vk_device_context * ctx = (ggml_backend_vk_device_context *)dev->context; + return ctx->id.c_str(); +} + static void ggml_backend_vk_device_get_memory(ggml_backend_dev_t device, size_t * free, size_t * total) { ggml_backend_vk_device_context * ctx = (ggml_backend_vk_device_context *)device->context; ggml_backend_vk_get_device_memory(ctx->device, free, total); @@ -10847,6 +10880,7 @@ static enum ggml_backend_dev_type ggml_backend_vk_device_get_type(ggml_backend_d static void ggml_backend_vk_device_get_props(ggml_backend_dev_t dev, struct ggml_backend_dev_props * props) { props->name = ggml_backend_vk_device_get_name(dev); props->description = ggml_backend_vk_device_get_description(dev); + props->id = ggml_backend_vk_device_get_id(dev); props->type = ggml_backend_vk_device_get_type(dev); ggml_backend_vk_device_get_memory(dev, &props->memory_free, &props->memory_total); props->caps = { @@ -11265,6 +11299,7 @@ static ggml_backend_dev_t ggml_backend_vk_reg_get_device(ggml_backend_reg_t reg, ctx->device = i; ctx->name = GGML_VK_NAME + std::to_string(i); ctx->description = desc; + ctx->id = ggml_backend_vk_get_device_id(i); devices.push_back(new ggml_backend_device { /* .iface = */ ggml_backend_vk_device_i, /* .reg = */ reg,