Skip to content

Commit 243b5ef

Browse files
committed
vulkan: select only one device for single gpu with multiple drivers
1 parent b864b50 commit 243b5ef

File tree

1 file changed

+63
-1
lines changed

1 file changed

+63
-1
lines changed

ggml-vulkan.cpp

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
#include "ggml-vulkan.h"
2+
#include <limits>
3+
#include <map>
4+
#include <ostream>
5+
#include <string>
6+
#include <vulkan/vulkan_core.h>
27

38
#ifdef GGML_VULKAN_RUN_TESTS
49
#include <chrono>
@@ -1691,7 +1696,64 @@ void ggml_vk_instance_init() {
16911696
vk::PhysicalDeviceProperties props = devices[i].getProperties();
16921697

16931698
if (props.deviceType == vk::PhysicalDeviceType::eDiscreteGpu) {
1694-
vk_instance.device_indices.push_back(i);
1699+
// Check if there are two physical devices corresponding to the same GPU
1700+
auto old_device = std::find_if(
1701+
vk_instance.device_indices.begin(),
1702+
vk_instance.device_indices.end(),
1703+
[&devices, &props](const size_t k){ return devices[k].getProperties().deviceID == props.deviceID; }
1704+
);
1705+
if (old_device == vk_instance.device_indices.end()) {
1706+
vk_instance.device_indices.push_back(i);
1707+
} else {
1708+
// There can be two physical devices corresponding to the same GPU if there are 2 different drivers
1709+
// This can cause error when splitting layers aross the devices, need to keep only 1
1710+
std::cout << "Device " << i << " and device " << *old_device << " have the same device id" << std::endl;
1711+
1712+
vk::PhysicalDeviceProperties2 old_prop;
1713+
vk::PhysicalDeviceDriverProperties old_driver;
1714+
old_prop.pNext = &old_driver;
1715+
devices[*old_device].getProperties2(&old_prop);
1716+
std::string old_driver_name {old_driver.driverName.data()};
1717+
1718+
vk::PhysicalDeviceProperties2 new_prop;
1719+
vk::PhysicalDeviceDriverProperties new_driver;
1720+
new_prop.pNext = &new_driver;
1721+
devices[i].getProperties2(&new_prop);
1722+
std::string new_driver_name {new_driver.driverName.data()};
1723+
1724+
// Check https://vulkan.gpuinfo.org/displaycoreproperty.php?name=driverName&core=1.2 for a list of driver names
1725+
// Smaller number -> higher priority
1726+
std::map<std::string, int> driver_priorities {};
1727+
driver_priorities["NVIDIA"] = 1;
1728+
driver_priorities["nvk"] = 2;
1729+
driver_priorities["radv"] = 3;
1730+
driver_priorities["AMD open-source driver"] = 4;
1731+
driver_priorities["AMD proprietary driver"] = 5;
1732+
driver_priorities["Intel open-source Mesa driver"] = 6;
1733+
driver_priorities["Intel Corporation"] = 7;
1734+
1735+
// Select the driver based on the priority map
1736+
// Keep the old one if the names are not there
1737+
int old_priority = std::numeric_limits<int>::max();
1738+
if (driver_priorities.count(old_driver_name)) {
1739+
old_priority = driver_priorities[old_driver_name];
1740+
}
1741+
int new_priority = std::numeric_limits<int>::max();
1742+
if (driver_priorities.count(new_driver_name)) {
1743+
new_priority = driver_priorities[new_driver_name];
1744+
}
1745+
1746+
if (new_priority < old_priority) {
1747+
auto r = std::remove(vk_instance.device_indices.begin(), vk_instance.device_indices.end(), *old_device);
1748+
vk_instance.device_indices.erase(r, vk_instance.device_indices.end());
1749+
vk_instance.device_indices.push_back(i);
1750+
std::cout << "Prioritize device " << i << " driver " << new_driver_name << " over device " << *old_device << " driver " << old_driver_name << std::endl;
1751+
std::cout << "Remove device " << *old_device << std::endl;
1752+
} else {
1753+
std::cout << "Prioritize device " << *old_device << " driver " << old_driver_name << " over device " << i << " driver " << new_driver_name << std::endl;
1754+
std::cout << "Keep device " << *old_device << std::endl;
1755+
}
1756+
}
16951757
}
16961758
}
16971759

0 commit comments

Comments
 (0)