diff --git a/LLama/Native/Load/SystemInfo.cs b/LLama/Native/Load/SystemInfo.cs
index 0f48ce44f..c6e63147b 100644
--- a/LLama/Native/Load/SystemInfo.cs
+++ b/LLama/Native/Load/SystemInfo.cs
@@ -44,6 +44,15 @@ public static SystemInfo Get()
#region Vulkan version
private static string? GetVulkanVersion()
{
+ // Prefer asking the Vulkan loader directly. `vulkaninfo` is a separate tool which is not present on every
+ // machine that has a working Vulkan driver (e.g. Windows machines with only an Intel GPU), and spawning it
+ // can be slow or time out (see #930). Without it the Vulkan backend is skipped and only the CPU is offered.
+ string? loaderVersion = GetVulkanVersionFromLoader();
+ if (loaderVersion != null)
+ {
+ return loaderVersion;
+ }
+
// Get Vulkan Summary
string? vulkanSummary = GetVulkanSummary();
// If we have a Vulkan summary
@@ -117,6 +126,57 @@ public static SystemInfo Get()
// Return null if no match is found
return null;
}
+
+ ///
+ /// Query the Vulkan loader in-process with vkEnumerateInstanceVersion (available since Vulkan 1.1).
+ ///
+ /// The loader version as "major.minor.patch", or null if the loader is missing, predates Vulkan 1.1 or the call fails.
+ private static string? GetVulkanVersionFromLoader()
+ {
+ try
+ {
+ int result;
+ uint apiVersion;
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ result = VulkanLoaderWindows.vkEnumerateInstanceVersion(out apiVersion);
+ }
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ {
+ result = VulkanLoaderLinux.vkEnumerateInstanceVersion(out apiVersion);
+ }
+ else
+ {
+ return null;
+ }
+
+ // VK_SUCCESS == 0
+ if (result != 0)
+ {
+ return null;
+ }
+
+ // VK_API_VERSION_MAJOR / MINOR / PATCH (the variant bits above bit 29 are ignored)
+ return $"{(apiVersion >> 22) & 0x7F}.{(apiVersion >> 12) & 0x3FF}.{apiVersion & 0xFFF}";
+ }
+ catch
+ {
+ // DllNotFoundException, EntryPointNotFoundException, etc. Fall back to `vulkaninfo`.
+ return null;
+ }
+ }
+
+ private static class VulkanLoaderWindows
+ {
+ [DllImport("vulkan-1", CallingConvention = CallingConvention.Winapi)]
+ public static extern int vkEnumerateInstanceVersion(out uint pApiVersion);
+ }
+
+ private static class VulkanLoaderLinux
+ {
+ [DllImport("libvulkan.so.1", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int vkEnumerateInstanceVersion(out uint pApiVersion);
+ }
#endregion
#region CUDA version