Skip to content

Commit 5d1a966

Browse files
add string normalize method (#1461)
* add string normalize method * remove unnecessary method * improve exception messages, change method visibility and add unit test * updated standardizing version method calls * update releasenotes
1 parent 20b8206 commit 5d1a966

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

RELEASENOTES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ __Bug Fixes__:
88
#1426 Sequential.eval() does not put model into eval mode<br/>
99
`torch.optim.lr_scheduler.LinearLR` `end_factor` default has been corrected, is now 1.0.<br/>
1010
Update package version of SixLabors.ImageSharp to avoid security vulnerability<br/>
11+
Updated dll dependencies loading to avoid using hardcoded version strings<br/>
1112

1213
__API Changes__:
1314

src/TorchSharp/Torch.cs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,26 @@ public static partial class torch
5454
static bool nativeBackendCudaLoaded = false;
5555

5656
public static string __version__ => libtorchPackageVersion;
57+
public static string NormalizeNuGetVersion(string versionString)
58+
{
59+
if (string.IsNullOrWhiteSpace(versionString))
60+
throw new ArgumentException($"Invalid NuGet version: {versionString}. Version string is null, empty or only contains whitespaces");
61+
62+
string[] parts = versionString.Split('-', '+');
63+
string[] versionParts = parts[0].Split('.');
64+
65+
if (versionParts.Length < 2 || versionParts.Length > 4 || !versionParts.All(v => int.TryParse(v, out _)))
66+
throw new ArgumentException($"Invalid NuGet version: {versionString}. Please check: https://learn.microsoft.com/en-us/nuget/concepts/package-versioning");
67+
68+
string normalizedVersion = versionParts[0] + "." + versionParts[1];
69+
if (versionParts.Length > 2) normalizedVersion += "." + versionParts[2];
70+
if (versionParts.Length > 3 && int.Parse(versionParts[3]) != 0) normalizedVersion += "." + versionParts[3];
71+
72+
if (parts.Length > 1)
73+
normalizedVersion += "-" + parts[1];
74+
75+
return normalizedVersion;
76+
}
5777

5878
internal static bool TryLoadNativeLibraryFromFile(string path, StringBuilder trace) {
5979
bool ok;
@@ -168,14 +188,14 @@ private static void LoadNativeBackend(bool useCudaBackend, out StringBuilder? tr
168188

169189
if (torchsharpLoc!.Contains("torchsharp") && torchsharpLoc.Contains("lib") && Directory.Exists(packagesDir) && Directory.Exists(torchsharpHome)) {
170190

171-
var torchSharpVersion = Path.GetFileName(torchsharpHome); // really GetDirectoryName
172-
191+
var torchSharpVersion = NormalizeNuGetVersion(Path.GetFileName(torchsharpHome));
192+
var normalizedLibtorchPackageVersion = NormalizeNuGetVersion(libtorchPackageVersion);
173193
if (useCudaBackend) {
174194
var consolidatedDir = Path.Combine(torchsharpLoc, $"cuda-{cudaVersion}");
175195

176196
trace.AppendLine($" Trying dynamic load for .NET/F# Interactive by consolidating native {cudaRootPackage}-* binaries to {consolidatedDir}...");
177197

178-
var cudaOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, $"{cudaRootPackage}-*", libtorchPackageVersion, consolidatedDir, trace);
198+
var cudaOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, $"{cudaRootPackage}-*", normalizedLibtorchPackageVersion, consolidatedDir, trace);
179199
if (cudaOk) {
180200
cudaOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, "torchsharp", torchSharpVersion, consolidatedDir, trace);
181201
if (cudaOk) {
@@ -193,7 +213,7 @@ private static void LoadNativeBackend(bool useCudaBackend, out StringBuilder? tr
193213

194214
trace.AppendLine($" Trying dynamic load for .NET/F# Interactive by consolidating native {cpuRootPackage}-* binaries to {consolidatedDir}...");
195215

196-
var cpuOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, cpuRootPackage, libtorchPackageVersion, consolidatedDir, trace);
216+
var cpuOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, cpuRootPackage, normalizedLibtorchPackageVersion, consolidatedDir, trace);
197217
if (cpuOk) {
198218
cpuOk = CopyNativeComponentsIntoSingleDirectory(packagesDir, "torchsharp", torchSharpVersion, consolidatedDir, trace);
199219
if (cpuOk) {

test/TorchSharpTest/TestTorchSharp.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
using System.Collections.Generic;
55
using System.Linq.Expressions;
66
using System.Reflection;
7+
using System.Security.Cryptography;
8+
using Tensorboard;
79
using Xunit;
810

911
using static TorchSharp.torch;
@@ -450,6 +452,17 @@ public void AllowFP16ReductionCuBLAS()
450452
Assert.False(torch.backends.cuda.matmul.allow_fp16_reduced_precision_reduction);
451453
}
452454

455+
[Fact]
456+
public void CheckVersionStrings()
457+
{
458+
Assert.Equal("2.5.1", torch.NormalizeNuGetVersion("2.5.1.0"));
459+
Assert.Equal("0.105.0", torch.NormalizeNuGetVersion("0.105.0.0"));
460+
Assert.Equal("0.1.0-alpha", torch.NormalizeNuGetVersion("0.1.0-alpha"));
461+
Assert.Equal("0.1.0", torch.NormalizeNuGetVersion("0.1.0"));
462+
Assert.Throws<ArgumentException>(() => NormalizeNuGetVersion(""));
463+
Assert.Throws<ArgumentException>(() => NormalizeNuGetVersion("1.2.3.4.5"));
464+
}
465+
453466
// Because some of the tests mess with global state, and are run in parallel, we need to
454467
// acquire a lock before testing setting the default RNG see.
455468
private static object _lock = new object();

0 commit comments

Comments
 (0)