From c31ebbdf18242646277b954399355b7af13d0031 Mon Sep 17 00:00:00 2001 From: Martin Evans Date: Thu, 1 Aug 2024 13:32:21 +0100 Subject: [PATCH 1/3] Better handling of the vulkaninfo process, in case it hangs. --- LLama/Extensions/ProcessExtensions.cs | 57 +++++++++++++++++++++++++++ LLama/Native/Load/SystemInfo.cs | 38 +++++++----------- 2 files changed, 72 insertions(+), 23 deletions(-) create mode 100644 LLama/Extensions/ProcessExtensions.cs diff --git a/LLama/Extensions/ProcessExtensions.cs b/LLama/Extensions/ProcessExtensions.cs new file mode 100644 index 000000000..144a19e02 --- /dev/null +++ b/LLama/Extensions/ProcessExtensions.cs @@ -0,0 +1,57 @@ +using System.Diagnostics; +using System.Text; +using System; + +namespace LLama.Extensions; + +internal static class ProcessExtensions +{ + public static void SafeKill(this Process process, bool entireProcessTree = true) + { + if (process.HasExited) + return; + + // There's a race here! If the process closed between the above check + // and the below `Kill` call then an `InvalidOperationException` will + // be thrown! Catch it and move on. + + try + { + process.Kill(entireProcessTree); + process.WaitForExit(55); + } + catch (InvalidOperationException) + { + } + } + + /// + /// Run a process for a certain amount of time and then terminate it + /// + /// + /// + /// return code, standard output, standard error, flag indicating if process exited or was terminated + public static (int ret, string stdOut, string stdErr, bool ok) SafeRun(this Process process, TimeSpan timeout) + { + var stdOut = new StringBuilder(); + process.OutputDataReceived += (s, e) => + { + stdOut.Append(e.Data); + }; + + var stdErr = new StringBuilder(); + process.ErrorDataReceived += (s, e) => + { + stdErr.Append(e.Data); + }; + + process.Start(); + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + + var ok = process.WaitForExit((int)timeout.TotalMilliseconds); + process.SafeKill(); + + return (process.ExitCode, stdOut.ToString(), stdErr.ToString(), ok); + } +} \ No newline at end of file diff --git a/LLama/Native/Load/SystemInfo.cs b/LLama/Native/Load/SystemInfo.cs index d5516ef37..b746283ad 100644 --- a/LLama/Native/Load/SystemInfo.cs +++ b/LLama/Native/Load/SystemInfo.cs @@ -12,7 +12,7 @@ namespace LLama.Native /// /// /// - public record class SystemInfo(OSPlatform OSPlatform, int CudaMajorVersion, string? VulkanVersion) + public record SystemInfo(OSPlatform OSPlatform, int CudaMajorVersion, string? VulkanVersion) { /// /// Get the system information of the current machine. @@ -71,36 +71,28 @@ public static SystemInfo Get() // Note: on Linux, this requires `vulkan-tools` to be installed. (`sudo apt install vulkan-tools`) try { - // Set up the process start info - ProcessStartInfo start = new() - { - FileName = "vulkaninfo", - Arguments = "--summary", - RedirectStandardOutput = true, - UseShellExecute = false, - CreateNoWindow = true - }; - - // Start the process + // Start a process to read vulkan info Process process = new() { - StartInfo = start + StartInfo = new() + { + FileName = "vulkaninfo", + Arguments = "--summary", + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true + } }; - process.Start(); - - // Read the output to a string - string output = process.StandardOutput.ReadToEnd(); - - // Wait for the process to exit - process.WaitForExit(); + var (exitCode, output, error, ok) = process.SafeRun(TimeSpan.FromSeconds(1)); + + if (!ok) + return null; // Return the output return output; } - catch (Exception e) + catch { - //Console.WriteLine(e); - // Return null if we failed to get the Vulkan version return null; } From 4c9b78d013366035d63707aa830628292e4b675b Mon Sep 17 00:00:00 2001 From: Martin Evans Date: Thu, 1 Aug 2024 13:36:05 +0100 Subject: [PATCH 2/3] Redirecting stderr --- LLama/Native/Load/SystemInfo.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/LLama/Native/Load/SystemInfo.cs b/LLama/Native/Load/SystemInfo.cs index b746283ad..f736ddf40 100644 --- a/LLama/Native/Load/SystemInfo.cs +++ b/LLama/Native/Load/SystemInfo.cs @@ -79,6 +79,7 @@ public static SystemInfo Get() FileName = "vulkaninfo", Arguments = "--summary", RedirectStandardOutput = true, + RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true } From 7fa80832c40584e664cc3d0aad3b8c1877e013fb Mon Sep 17 00:00:00 2001 From: Martin Evans Date: Thu, 1 Aug 2024 13:45:59 +0100 Subject: [PATCH 3/3] Fixed missing parameter in netstd2.1 --- LLama/Extensions/ProcessExtensions.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/LLama/Extensions/ProcessExtensions.cs b/LLama/Extensions/ProcessExtensions.cs index 144a19e02..6e6ea5d40 100644 --- a/LLama/Extensions/ProcessExtensions.cs +++ b/LLama/Extensions/ProcessExtensions.cs @@ -17,7 +17,11 @@ public static void SafeKill(this Process process, bool entireProcessTree = true) try { +#if NET5_0_OR_GREATER process.Kill(entireProcessTree); +#else + process.Kill(); +#endif process.WaitForExit(55); } catch (InvalidOperationException)