Skip to content

Commit

Permalink
vulkan: select only one device for single gpu with multiple drivers
Browse files Browse the repository at this point in the history
  • Loading branch information
Adriankhl committed Jun 6, 2024
1 parent 243b5ef commit 5d9d14d
Showing 1 changed file with 42 additions and 31 deletions.
73 changes: 42 additions & 31 deletions ggml-vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include <algorithm>
#include <cmath>
#include <iostream>
#include <limits>
#include <tuple>
#include <vector>
#include <sstream>
Expand Down Expand Up @@ -1707,52 +1706,64 @@ void ggml_vk_instance_init() {
} else {
// There can be two physical devices corresponding to the same GPU if there are 2 different drivers
// This can cause error when splitting layers aross the devices, need to keep only 1
std::cout << "Device " << i << " and device " << *old_device << " have the same device id" << std::endl;
#ifdef GGML_VULKAN_DEBUG
std::cerr << "Device " << i << " and device " << *old_device << " have the same device id" << std::endl;
#endif

vk::PhysicalDeviceProperties2 old_prop;
vk::PhysicalDeviceDriverProperties old_driver;
old_prop.pNext = &old_driver;
devices[*old_device].getProperties2(&old_prop);
std::string old_driver_name {old_driver.driverName.data()};

vk::PhysicalDeviceProperties2 new_prop;
vk::PhysicalDeviceDriverProperties new_driver;
new_prop.pNext = &new_driver;
devices[i].getProperties2(&new_prop);
std::string new_driver_name {new_driver.driverName.data()};

// Check https://vulkan.gpuinfo.org/displaycoreproperty.php?name=driverName&core=1.2 for a list of driver names
// Smaller number -> higher priority
std::map<std::string, int> driver_priorities {};
driver_priorities["NVIDIA"] = 1;
driver_priorities["nvk"] = 2;
driver_priorities["radv"] = 3;
driver_priorities["AMD open-source driver"] = 4;
driver_priorities["AMD proprietary driver"] = 5;
driver_priorities["Intel open-source Mesa driver"] = 6;
driver_priorities["Intel Corporation"] = 7;

// Select the driver based on the priority map
// Keep the old one if the names are not there
std::map<vk::DriverId, int> driver_priorities {};
int old_priority = std::numeric_limits<int>::max();
if (driver_priorities.count(old_driver_name)) {
old_priority = driver_priorities[old_driver_name];
}
int new_priority = std::numeric_limits<int>::max();
if (driver_priorities.count(new_driver_name)) {
new_priority = driver_priorities[new_driver_name];

// Check https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkDriverId.html for the list of driver id
// Smaller number -> higher priority
switch (old_prop.properties.vendorID) {
case VK_VENDOR_ID_AMD:
driver_priorities[static_cast<vk::DriverId>(VkDriverId::VK_DRIVER_ID_MESA_RADV)] = 1;
driver_priorities[static_cast<vk::DriverId>(VkDriverId::VK_DRIVER_ID_AMD_OPEN_SOURCE)] = 2;
driver_priorities[static_cast<vk::DriverId>(VkDriverId::VK_DRIVER_ID_AMD_PROPRIETARY)] = 3;
break;
case VK_VENDOR_ID_INTEL:
driver_priorities[static_cast<vk::DriverId>(VkDriverId::VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA)] = 1;
driver_priorities[static_cast<vk::DriverId>(VkDriverId::VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS)] = 2;
break;
case VK_VENDOR_ID_NVIDIA:
driver_priorities[static_cast<vk::DriverId>(VkDriverId::VK_DRIVER_ID_NVIDIA_PROPRIETARY)] = 1;
driver_priorities[static_cast<vk::DriverId>(VkDriverId::VK_DRIVER_ID_MESA_NVK)] = 2;
break;
}

if (driver_priorities.count(old_driver.driverID)) {
old_priority = driver_priorities[old_driver.driverID];
}
if (driver_priorities.count(new_driver.driverID)) {
new_priority = driver_priorities[new_driver.driverID];
}

if (new_priority < old_priority) {
auto r = std::remove(vk_instance.device_indices.begin(), vk_instance.device_indices.end(), *old_device);
vk_instance.device_indices.erase(r, vk_instance.device_indices.end());
vk_instance.device_indices.push_back(i);
std::cout << "Prioritize device " << i << " driver " << new_driver_name << " over device " << *old_device << " driver " << old_driver_name << std::endl;
std::cout << "Remove device " << *old_device << std::endl;
} else {
std::cout << "Prioritize device " << *old_device << " driver " << old_driver_name << " over device " << i << " driver " << new_driver_name << std::endl;
std::cout << "Keep device " << *old_device << std::endl;
}
auto r = std::remove(vk_instance.device_indices.begin(), vk_instance.device_indices.end(), *old_device);
vk_instance.device_indices.erase(r, vk_instance.device_indices.end());
vk_instance.device_indices.push_back(i);

#ifdef GGML_VULKAN_DEBUG
std::cerr << "Prioritize device " << i << " driver " << new_driver.driverName << " over device " << *old_device << " driver " << old_driver.driverName << std::endl;
#endif
}
#ifdef GGML_VULKAN_DEBUG
else {
std::cerr << "Prioritize device " << *old_device << " driver " << old_driver.driverName << " over device " << i << " driver " << new_driver.driverName << std::endl;

}
#endif
}
}
}
Expand Down

0 comments on commit 5d9d14d

Please sign in to comment.