From 3003d56d6e4b3293213d5a896701094fc70e3728 Mon Sep 17 00:00:00 2001 From: alinpahontu2912 Date: Wed, 19 Mar 2025 13:02:42 +0100 Subject: [PATCH 1/5] add string normalize method --- src/TorchSharp/Torch.cs | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/TorchSharp/Torch.cs b/src/TorchSharp/Torch.cs index 728fa9ccd..24b71641c 100644 --- a/src/TorchSharp/Torch.cs +++ b/src/TorchSharp/Torch.cs @@ -54,6 +54,27 @@ public static partial class torch static bool nativeBackendCudaLoaded = false; public static string __version__ => libtorchPackageVersion; + private static string NormalizeNuGetVersion(string versionString) + { + if (string.IsNullOrWhiteSpace(versionString)) + throw new ArgumentException($"Invalid NuGet version: {versionString}"); + + string[] parts = versionString.Split('-', '+'); + string[] versionParts = parts[0].Split('.'); + + if (versionParts.Length < 2 || versionParts.Length > 4 || !versionParts.All(IsNumeric)) + throw new ArgumentException($"Invalid NuGet version: {versionString}"); + + string normalizedVersion = versionParts[0] + "." + versionParts[1]; + if (versionParts.Length > 2) normalizedVersion += "." + versionParts[2]; + if (versionParts.Length > 3 && int.Parse(versionParts[3]) != 0) normalizedVersion += "." + versionParts[3]; + + if (parts.Length > 1) + normalizedVersion += "-" + parts[1]; + + return normalizedVersion; + } + private static bool IsNumeric(string str) => int.TryParse(str, out _); internal static bool TryLoadNativeLibraryFromFile(string path, StringBuilder trace) { bool ok; @@ -168,16 +189,17 @@ private static void LoadNativeBackend(bool useCudaBackend, out StringBuilder? tr if (torchsharpLoc!.Contains("torchsharp") && torchsharpLoc.Contains("lib") && Directory.Exists(packagesDir) && Directory.Exists(torchsharpHome)) { - var torchSharpVersion = Path.GetFileName(torchsharpHome); // really GetDirectoryName - + var assembly = typeof(torch).Assembly; + var version = assembly.GetName().Version; + var torchSharpVersion = (version != null) ? version.ToString() : Path.GetFileName(torchsharpHome); if (useCudaBackend) { var consolidatedDir = Path.Combine(torchsharpLoc, $"cuda-{cudaVersion}"); trace.AppendLine($" Trying dynamic load for .NET/F# Interactive by consolidating native {cudaRootPackage}-* binaries to {consolidatedDir}..."); - var cudaOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, $"{cudaRootPackage}-*", libtorchPackageVersion, consolidatedDir, trace); + var cudaOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, $"{cudaRootPackage}-*", NormalizeNuGetVersion(libtorchPackageVersion), consolidatedDir, trace); if (cudaOk) { - cudaOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, "torchsharp", torchSharpVersion, consolidatedDir, trace); + cudaOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, "torchsharp", NormalizeNuGetVersion(torchSharpVersion), consolidatedDir, trace); if (cudaOk) { var consolidated = Path.Combine(consolidatedDir, target); ok = TryLoadNativeLibraryFromFile(consolidated, trace); @@ -193,9 +215,9 @@ private static void LoadNativeBackend(bool useCudaBackend, out StringBuilder? tr trace.AppendLine($" Trying dynamic load for .NET/F# Interactive by consolidating native {cpuRootPackage}-* binaries to {consolidatedDir}..."); - var cpuOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, cpuRootPackage, libtorchPackageVersion, consolidatedDir, trace); + var cpuOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, cpuRootPackage, NormalizeNuGetVersion(libtorchPackageVersion), consolidatedDir, trace); if (cpuOk) { - cpuOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, "torchsharp", torchSharpVersion, consolidatedDir, trace); + cpuOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, "torchsharp", NormalizeNuGetVersion(torchSharpVersion), consolidatedDir, trace); if (cpuOk) { var consolidated = Path.Combine(consolidatedDir, target); ok = TryLoadNativeLibraryFromFile(consolidated, trace); From 2cf5c8856fa08e63f094542cbac0ae995b97e8bb Mon Sep 17 00:00:00 2001 From: Stefan-Alin Pahontu <56953855+alinpahontu2912@users.noreply.github.com> Date: Wed, 26 Mar 2025 10:10:00 +0100 Subject: [PATCH 2/5] remove unnecessary method --- src/TorchSharp/Torch.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/TorchSharp/Torch.cs b/src/TorchSharp/Torch.cs index 24b71641c..77cb47144 100644 --- a/src/TorchSharp/Torch.cs +++ b/src/TorchSharp/Torch.cs @@ -62,7 +62,7 @@ private static string NormalizeNuGetVersion(string versionString) string[] parts = versionString.Split('-', '+'); string[] versionParts = parts[0].Split('.'); - if (versionParts.Length < 2 || versionParts.Length > 4 || !versionParts.All(IsNumeric)) + if (versionParts.Length < 2 || versionParts.Length > 4 || !versionParts.All(v => int.TryParse(v, out _))) throw new ArgumentException($"Invalid NuGet version: {versionString}"); string normalizedVersion = versionParts[0] + "." + versionParts[1]; @@ -74,7 +74,6 @@ private static string NormalizeNuGetVersion(string versionString) return normalizedVersion; } - private static bool IsNumeric(string str) => int.TryParse(str, out _); internal static bool TryLoadNativeLibraryFromFile(string path, StringBuilder trace) { bool ok; From 0c03279429d04b1d3826bb481670a4d2f2b95c73 Mon Sep 17 00:00:00 2001 From: alinpahontu2912 Date: Thu, 27 Mar 2025 12:03:04 +0100 Subject: [PATCH 3/5] improve exception messages, change method visibility and add unit test --- src/TorchSharp/Torch.cs | 6 +++--- test/TorchSharpTest/TestTorchSharp.cs | 13 +++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/TorchSharp/Torch.cs b/src/TorchSharp/Torch.cs index 77cb47144..dfc68fa55 100644 --- a/src/TorchSharp/Torch.cs +++ b/src/TorchSharp/Torch.cs @@ -54,16 +54,16 @@ public static partial class torch static bool nativeBackendCudaLoaded = false; public static string __version__ => libtorchPackageVersion; - private static string NormalizeNuGetVersion(string versionString) + public static string NormalizeNuGetVersion(string versionString) { if (string.IsNullOrWhiteSpace(versionString)) - throw new ArgumentException($"Invalid NuGet version: {versionString}"); + throw new ArgumentException($"Invalid NuGet version: {versionString}. Version string is null, empty or only contains whitespaces"); string[] parts = versionString.Split('-', '+'); string[] versionParts = parts[0].Split('.'); if (versionParts.Length < 2 || versionParts.Length > 4 || !versionParts.All(v => int.TryParse(v, out _))) - throw new ArgumentException($"Invalid NuGet version: {versionString}"); + throw new ArgumentException($"Invalid NuGet version: {versionString}. Please check: https://learn.microsoft.com/en-us/nuget/concepts/package-versioning"); string normalizedVersion = versionParts[0] + "." + versionParts[1]; if (versionParts.Length > 2) normalizedVersion += "." + versionParts[2]; diff --git a/test/TorchSharpTest/TestTorchSharp.cs b/test/TorchSharpTest/TestTorchSharp.cs index 88929cbfe..549b8f131 100644 --- a/test/TorchSharpTest/TestTorchSharp.cs +++ b/test/TorchSharpTest/TestTorchSharp.cs @@ -4,6 +4,8 @@ using System.Collections.Generic; using System.Linq.Expressions; using System.Reflection; +using System.Security.Cryptography; +using Tensorboard; using Xunit; using static TorchSharp.torch; @@ -450,6 +452,17 @@ public void AllowFP16ReductionCuBLAS() Assert.False(torch.backends.cuda.matmul.allow_fp16_reduced_precision_reduction); } + [Fact] + public void CheckVersionStrings() + { + Assert.Equal("2.5.1", torch.NormalizeNuGetVersion("2.5.1.0")); + Assert.Equal("0.105.0", torch.NormalizeNuGetVersion("0.105.0.0")); + Assert.Equal("0.1.0-alpha", torch.NormalizeNuGetVersion("0.1.0-alpha")); + Assert.Equal("0.1.0", torch.NormalizeNuGetVersion("0.1.0")); + Assert.Throws(() => NormalizeNuGetVersion("")); + Assert.Throws(() => NormalizeNuGetVersion("1.2.3.4.5")); + } + // Because some of the tests mess with global state, and are run in parallel, we need to // acquire a lock before testing setting the default RNG see. private static object _lock = new object(); From 94803f1a390f50286ff07c9a8ba05424df0b14c6 Mon Sep 17 00:00:00 2001 From: alinpahontu2912 Date: Tue, 15 Apr 2025 14:00:33 +0300 Subject: [PATCH 4/5] updated standardizing version method calls --- src/TorchSharp/Torch.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/TorchSharp/Torch.cs b/src/TorchSharp/Torch.cs index dfc68fa55..aa930ec3b 100644 --- a/src/TorchSharp/Torch.cs +++ b/src/TorchSharp/Torch.cs @@ -188,17 +188,16 @@ private static void LoadNativeBackend(bool useCudaBackend, out StringBuilder? tr if (torchsharpLoc!.Contains("torchsharp") && torchsharpLoc.Contains("lib") && Directory.Exists(packagesDir) && Directory.Exists(torchsharpHome)) { - var assembly = typeof(torch).Assembly; - var version = assembly.GetName().Version; - var torchSharpVersion = (version != null) ? version.ToString() : Path.GetFileName(torchsharpHome); + var torchSharpVersion = NormalizeNuGetVersion(Path.GetFileName(torchsharpHome)); + var normalizedLibtorchPackageVersion = NormalizeNuGetVersion(libtorchPackageVersion); if (useCudaBackend) { var consolidatedDir = Path.Combine(torchsharpLoc, $"cuda-{cudaVersion}"); trace.AppendLine($" Trying dynamic load for .NET/F# Interactive by consolidating native {cudaRootPackage}-* binaries to {consolidatedDir}..."); - var cudaOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, $"{cudaRootPackage}-*", NormalizeNuGetVersion(libtorchPackageVersion), consolidatedDir, trace); + var cudaOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, $"{cudaRootPackage}-*", normalizedLibtorchPackageVersion, consolidatedDir, trace); if (cudaOk) { - cudaOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, "torchsharp", NormalizeNuGetVersion(torchSharpVersion), consolidatedDir, trace); + cudaOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, "torchsharp", torchSharpVersion, consolidatedDir, trace); if (cudaOk) { var consolidated = Path.Combine(consolidatedDir, target); ok = TryLoadNativeLibraryFromFile(consolidated, trace); @@ -214,9 +213,9 @@ private static void LoadNativeBackend(bool useCudaBackend, out StringBuilder? tr trace.AppendLine($" Trying dynamic load for .NET/F# Interactive by consolidating native {cpuRootPackage}-* binaries to {consolidatedDir}..."); - var cpuOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, cpuRootPackage, NormalizeNuGetVersion(libtorchPackageVersion), consolidatedDir, trace); + var cpuOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, cpuRootPackage, normalizedLibtorchPackageVersion, consolidatedDir, trace); if (cpuOk) { - cpuOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, "torchsharp", NormalizeNuGetVersion(torchSharpVersion), consolidatedDir, trace); + cpuOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, "torchsharp", torchSharpVersion, consolidatedDir, trace); if (cpuOk) { var consolidated = Path.Combine(consolidatedDir, target); ok = TryLoadNativeLibraryFromFile(consolidated, trace); From e71c92cab524832cad0f443da14bca58a164deec Mon Sep 17 00:00:00 2001 From: Stefan-Alin Pahontu <56953855+alinpahontu2912@users.noreply.github.com> Date: Tue, 15 Apr 2025 16:58:38 +0300 Subject: [PATCH 5/5] update releasenotes --- RELEASENOTES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 3f040e54a..3e9c01a83 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -8,6 +8,7 @@ __Bug Fixes__: #1426 Sequential.eval() does not put model into eval mode
`torch.optim.lr_scheduler.LinearLR` `end_factor` default has been corrected, is now 1.0.
Update package version of SixLabors.ImageSharp to avoid security vulnerability
+Updated dll dependencies loading to avoid using hardcoded version strings
__API Changes__: