diff --git a/Directory.Build.props b/Directory.Build.props
index ff94123a3..8ba341083 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -52,14 +52,13 @@
mac
linux
+
$(TargetOS)-$(TargetArchitecture)
- win-x64
+ win-arm64
+ win-x64
linux-x64
osx-arm64
-
- win-x64
- linux-x64
osx-$(TargetArchitecture)
@@ -95,8 +94,8 @@
- true
- false
+ true
+ false
false
@@ -141,6 +140,7 @@
cpu
cu$(CudaVersionNoDot)
libtorch-win-shared-with-deps$(LibTorchDebug)
+ libtorch-win-arm64-shared-with-deps$(LibTorchDebug)
libtorch-cxx11-abi-shared-with-deps
libtorch-macos-x86_64
libtorch-macos-arm64
diff --git a/Directory.Build.targets b/Directory.Build.targets
index 70c79f166..dc72e290c 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -1,7 +1,12 @@
-
+
+
+
+
+
+
-
+
@@ -20,6 +25,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -116,5 +135,5 @@
-
+
\ No newline at end of file
diff --git a/pkg/TorchAudio/TorchAudio.nupkgproj b/pkg/TorchAudio/TorchAudio.nupkgproj
index 7ac14ee82..1ca16a71b 100644
--- a/pkg/TorchAudio/TorchAudio.nupkgproj
+++ b/pkg/TorchAudio/TorchAudio.nupkgproj
@@ -8,7 +8,7 @@
-
+
diff --git a/pkg/TorchVision/TorchVision.nupkgproj b/pkg/TorchVision/TorchVision.nupkgproj
index f389e9b84..813fd1959 100644
--- a/pkg/TorchVision/TorchVision.nupkgproj
+++ b/pkg/TorchVision/TorchVision.nupkgproj
@@ -8,7 +8,7 @@
-
+
diff --git a/pkg/libtorch-cpu-win-arm64/libtorch-cpu-win-arm64.nupkgproj b/pkg/libtorch-cpu-win-arm64/libtorch-cpu-win-arm64.nupkgproj
new file mode 100644
index 000000000..766c20d0d
--- /dev/null
+++ b/pkg/libtorch-cpu-win-arm64/libtorch-cpu-win-arm64.nupkgproj
@@ -0,0 +1,16 @@
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pkg/libtorch-cpu/libtorch-cpu.nupkgproj b/pkg/libtorch-cpu/libtorch-cpu.nupkgproj
index 97c3ffe67..97296c6c8 100644
--- a/pkg/libtorch-cpu/libtorch-cpu.nupkgproj
+++ b/pkg/libtorch-cpu/libtorch-cpu.nupkgproj
@@ -8,6 +8,7 @@
+
diff --git a/pkg/pack.proj b/pkg/pack.proj
index 3c9db2f98..d5f0f86f3 100644
--- a/pkg/pack.proj
+++ b/pkg/pack.proj
@@ -22,8 +22,10 @@
-
+
+
diff --git a/src/Examples.Utils/Examples.Utils.csproj b/src/Examples.Utils/Examples.Utils.csproj
index a542b181d..620d5b487 100644
--- a/src/Examples.Utils/Examples.Utils.csproj
+++ b/src/Examples.Utils/Examples.Utils.csproj
@@ -17,7 +17,7 @@
-
+
diff --git a/src/Native/build.cmd b/src/Native/build.cmd
index c805b2608..ee5d19838 100644
--- a/src/Native/build.cmd
+++ b/src/Native/build.cmd
@@ -23,6 +23,7 @@ if /i [%1] == [Debug] ( set CMAKE_BUILD_TYPE=Debug&&shift&goto Arg_Loop)
if /i [%1] == [x86] ( set __BuildArch=x86&&set __VCBuildArch=x86&&shift&goto Arg_Loop)
if /i [%1] == [x64] ( set __BuildArch=x64&&set __VCBuildArch=x86_amd64&&shift&goto Arg_Loop)
if /i [%1] == [amd64] ( set __BuildArch=x64&&set __VCBuildArch=x86_amd64&&shift&goto Arg_Loop)
+if /i [%1] == [arm64] ( set __BuildArch=arm64&&set __VCBuildArch=x86_arm64&&shift&goto Arg_Loop)
if /i [%1] == [--libtorchpath] ( set LIBTORCH_PATH=%2&&shift&goto Arg_Loop)
@@ -64,40 +65,32 @@ exit /b 1
:: Setup vars for VS2022
set __PlatformToolset=v143
set __VSVersion=17 2022
-if NOT "%__BuildArch%" == "arm64" (
- :: Set the environment for the native build
- call "%VS160COMNTOOLS%..\..\VC\Auxiliary\Build\vcvarsall.bat" %__VCBuildArch%
-)
+:: Set the environment for the native build
+call "%VS160COMNTOOLS%..\..\VC\Auxiliary\Build\vcvarsall.bat" %__VCBuildArch%
goto :SetupDirs
:VS2019
:: Setup vars for VS2019
set __PlatformToolset=v142
set __VSVersion=16 2019
-if NOT "%__BuildArch%" == "arm64" (
- :: Set the environment for the native build
- call "%VS160COMNTOOLS%..\..\VC\Auxiliary\Build\vcvarsall.bat" %__VCBuildArch%
-)
+:: Set the environment for the native build
+call "%VS160COMNTOOLS%..\..\VC\Auxiliary\Build\vcvarsall.bat" %__VCBuildArch%
goto :SetupDirs
:VS2017
:: Setup vars for VS2017
set __PlatformToolset=v141
set __VSVersion=15 2017
-if NOT "%__BuildArch%" == "arm64" (
- :: Set the environment for the native build
- call "%VS150COMNTOOLS%..\..\VC\Auxiliary\Build\vcvarsall.bat" %__VCBuildArch%
-)
+:: Set the environment for the native build
+call "%VS150COMNTOOLS%..\..\VC\Auxiliary\Build\vcvarsall.bat" %__VCBuildArch%
goto :SetupDirs
:VS2015
:: Setup vars for VS2015build
set __PlatformToolset=v140
set __VSVersion=14 2015
-if NOT "%__BuildArch%" == "arm64" (
- :: Set the environment for the native build
- call "%VS140COMNTOOLS%..\..\VC\vcvarsall.bat" %__VCBuildArch%
-)
+:: Set the environment for the native build
+call "%VS140COMNTOOLS%..\..\VC\vcvarsall.bat" %__VCBuildArch%
:SetupDirs
:: Setup to cmake the native components
diff --git a/src/Native/gen-buildsys-win.bat b/src/Native/gen-buildsys-win.bat
index b3870c171..e8ec2fd39 100644
--- a/src/Native/gen-buildsys-win.bat
+++ b/src/Native/gen-buildsys-win.bat
@@ -30,6 +30,7 @@ popd
:: Set the target architecture to a format cmake understands.
if /i "%3" == "x64" (set __ExtraCmakeParams=%__ExtraCmakeParams% -A x64)
if /i "%3" == "x86" (set __ExtraCmakeParams=%__ExtraCmakeParams% -A Win32)
+if /i "%3" == "arm64" (set __ExtraCmakeParams=%__ExtraCmakeParams% -A ARM64)
echo "%CMakePath%" "-DCMAKE_BUILD_TYPE=%CMAKE_BUILD_TYPE%" "-DCMAKE_INSTALL_PREFIX=%__CMakeBinDir%" "-DLIBTORCH_PATH=%LIBTORCH_PATH%" -G "Visual Studio %__VSString%" %__ExtraCmakeParams% -B. -H%1
"%CMakePath%" "-DCMAKE_BUILD_TYPE=%CMAKE_BUILD_TYPE%" "-DCMAKE_INSTALL_PREFIX=%__CMakeBinDir%" "-DLIBTORCH_PATH=%LIBTORCH_PATH%" -G "Visual Studio %__VSString%" %__ExtraCmakeParams% -B. -H%1
diff --git a/src/Redist/libtorch-cpu/libtorch-cpu.proj b/src/Redist/libtorch-cpu/libtorch-cpu.proj
index 9c538dbe8..16705c006 100644
--- a/src/Redist/libtorch-cpu/libtorch-cpu.proj
+++ b/src/Redist/libtorch-cpu/libtorch-cpu.proj
@@ -30,7 +30,7 @@
$(MainPackageFolder)\.copied.SkipTests.$(SkipTests).IncludeLibTorchCpuPackages.$(IncludeLibTorchCpuPackages)
-
+
@@ -41,6 +41,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Redist/libtorch-cpu/libtorch-win-arm64-shared-with-deps-2.7.1%2Bcpu.zip.sha b/src/Redist/libtorch-cpu/libtorch-win-arm64-shared-with-deps-2.7.1%2Bcpu.zip.sha
new file mode 100644
index 000000000..2a96235c2
--- /dev/null
+++ b/src/Redist/libtorch-cpu/libtorch-win-arm64-shared-with-deps-2.7.1%2Bcpu.zip.sha
@@ -0,0 +1 @@
+F9DD47C792C900601F08265DDC0186036E01503ADA7895F0C7C90F8AF64FBC4B
diff --git a/src/Redist/libtorch-cpu/libtorch-win-arm64-shared-with-deps-debug-2.7.1%2Bcpu.zip.sha b/src/Redist/libtorch-cpu/libtorch-win-arm64-shared-with-deps-debug-2.7.1%2Bcpu.zip.sha
new file mode 100644
index 000000000..f35825d9a
--- /dev/null
+++ b/src/Redist/libtorch-cpu/libtorch-win-arm64-shared-with-deps-debug-2.7.1%2Bcpu.zip.sha
@@ -0,0 +1 @@
+DFDD2BECA32B1B3D4894EFA801DC60570849F0ED47A318734BA798A5C4D6513B
diff --git a/src/TorchSharp/Torch.cs b/src/TorchSharp/Torch.cs
index c59196bfe..cfb4770d8 100644
--- a/src/TorchSharp/Torch.cs
+++ b/src/TorchSharp/Torch.cs
@@ -36,13 +36,13 @@ public static partial class torch
RuntimeInformation.OSArchitecture == Architecture.Arm64;
static string nativeRid =>
- RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? $"win-x64" :
+ RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ($"win-{(RuntimeInformation.OSArchitecture == Architecture.Arm64 ? "arm64" : "x64")}") :
RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? $"linux-x64" :
isAppleSilicon ? "osx-arm64" :
"any";
static string nativeGlob =>
- RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @".*\.dll" :
+ RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @".*\.dll$" :
RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? @".*\.dylib\.*" :
// must match
// lib.so
@@ -127,7 +127,8 @@ private static void LoadNativeBackend(bool useCudaBackend, out StringBuilder? tr
if (useCudaBackend) {
var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
- if (isWindows) {
+ // CUDA is not supported on Windows ARM64. Only attempt to load CUDA components on Windows x64.
+ if (isWindows && RuntimeInformation.OSArchitecture == Architecture.X64) {
trace.AppendLine($" Try loading Windows cuda native components");
// Preloading these DLLs on windows seems to iron out problems where one native DLL
// requests a load of another through dynamic linking techniques.
@@ -151,9 +152,49 @@ private static void LoadNativeBackend(bool useCudaBackend, out StringBuilder? tr
ok = TryLoadNativeLibraryByName("torch_cuda", typeof(torch).Assembly, trace);
ok = TryLoadNativeLibraryByName("LibTorchSharp", typeof(torch).Assembly, trace);
+
+ // On Windows, also attempt direct absolute-path loads from the assembly directory
+ if (!ok && isWindows) {
+ var asmDir = Path.GetDirectoryName(typeof(torch).Assembly.Location)!;
+ var torchCudaPath = Path.Combine(asmDir, "torch_cuda.dll");
+ var libTorchSharpPath = Path.Combine(asmDir, "LibTorchSharp.dll");
+ trace.AppendLine($" Attempting absolute-path load of native components from {asmDir}...");
+ ok = TryLoadNativeLibraryFromFile(torchCudaPath, trace);
+ if (ok) ok = TryLoadNativeLibraryFromFile(libTorchSharpPath, trace);
+ }
} else {
- ok = TryLoadNativeLibraryByName("torch_cpu", typeof(torch).Assembly, trace);
- ok = TryLoadNativeLibraryByName("LibTorchSharp", typeof(torch).Assembly, trace);
+ var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
+ if (isWindows) {
+ // Preload dependency chain explicitly on Windows: torch_global_deps -> c10 -> uv -> torch -> torch_cpu -> LibTorchSharp
+ trace.AppendLine($" Try loading Windows CPU native dependency chain: torch_global_deps -> c10 -> uv -> torch -> torch_cpu -> LibTorchSharp");
+ ok = TryLoadNativeLibraryByName("torch_global_deps", typeof(torch).Assembly, trace);
+ if (ok) ok = TryLoadNativeLibraryByName("c10", typeof(torch).Assembly, trace);
+ if (ok) ok = TryLoadNativeLibraryByName("uv", typeof(torch).Assembly, trace);
+ if (ok) ok = TryLoadNativeLibraryByName("torch", typeof(torch).Assembly, trace);
+ if (ok) ok = TryLoadNativeLibraryByName("torch_cpu", typeof(torch).Assembly, trace);
+ if (ok) ok = TryLoadNativeLibraryByName("LibTorchSharp", typeof(torch).Assembly, trace);
+ } else {
+ ok = TryLoadNativeLibraryByName("torch_cpu", typeof(torch).Assembly, trace);
+ if (ok) ok = TryLoadNativeLibraryByName("LibTorchSharp", typeof(torch).Assembly, trace);
+ }
+
+ // On Windows, also attempt direct absolute-path loads from the assembly directory
+ if (!ok && isWindows) {
+ var asmDir = Path.GetDirectoryName(typeof(torch).Assembly.Location)!;
+ var torchGlobalDepsPath = Path.Combine(asmDir, "torch_global_deps.dll");
+ var c10Path = Path.Combine(asmDir, "c10.dll");
+ var uvPath = Path.Combine(asmDir, "uv.dll");
+ var torchPath = Path.Combine(asmDir, "torch.dll");
+ var torchCpuPath = Path.Combine(asmDir, "torch_cpu.dll");
+ var libTorchSharpPath = Path.Combine(asmDir, "LibTorchSharp.dll");
+ trace.AppendLine($" Attempting absolute-path load of native components from {asmDir}...");
+ ok = TryLoadNativeLibraryFromFile(torchGlobalDepsPath, trace);
+ if (ok) ok = TryLoadNativeLibraryFromFile(c10Path, trace);
+ if (ok) ok = TryLoadNativeLibraryFromFile(uvPath, trace);
+ if (ok) ok = TryLoadNativeLibraryFromFile(torchPath, trace);
+ if (ok) ok = TryLoadNativeLibraryFromFile(torchCpuPath, trace);
+ if (ok) ok = TryLoadNativeLibraryFromFile(libTorchSharpPath, trace);
+ }
}
trace.AppendLine($" Result from regular native load of LibTorchSharp is {ok}");