Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,16 @@
<TargetOS Condition="'$(TargetOS)' == '' AND $([MSBuild]::IsOSPlatform('osx'))">mac</TargetOS>
<TargetOS Condition="'$(TargetOS)' == '' AND '$(OS)' != 'Windows_NT'">linux</TargetOS>


<TargetPlatform Condition="'$(TargetPlatform)' == ''">$(TargetOS)-$(TargetArchitecture)</TargetPlatform>

<TargetRuntimeID Condition="'$(TargetOS)' == 'windows'">win-x64</TargetRuntimeID>
<TargetRuntimeID Condition="'$(TargetOS)' == 'windows' and '$(TargetArchitecture)' == 'arm64'">win-arm64</TargetRuntimeID>
<TargetRuntimeID Condition="'$(TargetOS)' == 'windows' and '$(TargetArchitecture)' != 'arm64'">win-x64</TargetRuntimeID>
<TargetRuntimeID Condition="'$(TargetOS)' == 'linux'">linux-x64</TargetRuntimeID>
<TargetRuntimeID Condition="'$(TargetPlatform)' == 'mac-arm64'">osx-arm64</TargetRuntimeID>

<TargetRuntimeID Condition="'$(TargetOS)' == 'windows'">win-x64</TargetRuntimeID>
<TargetRuntimeID Condition="'$(TargetOS)' == 'linux'">linux-x64</TargetRuntimeID>
<TargetRuntimeID Condition="'$(TargetOS)' == 'mac'">osx-$(TargetArchitecture)</TargetRuntimeID>

<!-- on windows separate debug binaries of LibTorch are available-->
<!-- on windows separate debug binaries of LibTorch are available -->
<LibTorchDebug Condition="('$(NativeConfiguration)' == 'Debug') AND '$(TargetOS)' == 'windows'">-debug</LibTorchDebug>

<NativeOutputPath>$(BaseOutputPath)$(NativeTargetArchitecture).$(NativeConfiguration)\Native\</NativeOutputPath>
Expand Down Expand Up @@ -95,8 +94,8 @@

<PropertyGroup>
<!-- turned on/off manually in separate CI jobs -->
<SkipCuda Condition="'$(TargetOS)' == 'mac'">true</SkipCuda>
<SkipCuda Condition="'$(TargetOS)' != 'mac'">false</SkipCuda>
<SkipCuda Condition="'$(TargetOS)' == 'mac' or ('$(TargetOS)' == 'windows' and '$(TargetArchitecture)' == 'arm64')">true</SkipCuda>
<SkipCuda Condition="'$(SkipCuda)' == ''">false</SkipCuda>
<SkipTests>false</SkipTests>

<!-- By default only TorchSharp and no libtorch-cpu or libtorch-cuda packages are built. The CI file controls these via 'BuildLibTorchPackages' -->
Expand Down Expand Up @@ -141,7 +140,8 @@
<LibTorchCpuLocalNameSuffix>cpu</LibTorchCpuLocalNameSuffix>
<LibTorchCudaLocalNameSuffix>cu$(CudaVersionNoDot)</LibTorchCudaLocalNameSuffix>
<LibTorchArchiveCoreName Condition="'$(TargetOS)' == 'windows'">libtorch-win-shared-with-deps$(LibTorchDebug)</LibTorchArchiveCoreName>
<LibTorchArchiveCoreName Condition="'$(TargetOS)' == 'linux'">libtorch-shared-with-deps</LibTorchArchiveCoreName>
<LibTorchArchiveCoreName Condition="'$(TargetOS)' == 'windows' and '$(TargetArchitecture)' == 'arm64'">libtorch-win-arm64-shared-with-deps$(LibTorchDebug)</LibTorchArchiveCoreName>
<LibTorchArchiveCoreName Condition="'$(TargetOS)' == 'linux'">libtorch-cxx11-abi-shared-with-deps</LibTorchArchiveCoreName>
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The LibTorchArchiveCoreName for Linux has been changed to "libtorch-cxx11-abi-shared-with-deps", but there is no corresponding SHA file for the 2.10.0 version (libtorch-cxx11-abi-shared-with-deps-2.10.0%2Bcpu.zip.sha). The repository contains "libtorch-shared-with-deps-2.10.0%2Bcpu.zip.sha" but not the cxx11-abi variant for 2.10.0. This will cause the build to fail when trying to validate the downloaded archive. Either:

  1. The SHA file needs to be added to this PR, or
  2. This change to the Linux archive name should be removed if it was unintentional

This appears to be an unrelated change that was accidentally included in the Windows ARM64 support PR.

Suggested change
<LibTorchArchiveCoreName Condition="'$(TargetOS)' == 'linux'">libtorch-cxx11-abi-shared-with-deps</LibTorchArchiveCoreName>
<LibTorchArchiveCoreName Condition="'$(TargetOS)' == 'linux'">libtorch-shared-with-deps</LibTorchArchiveCoreName>

Copilot uses AI. Check for mistakes.
<LibTorchArchiveCoreName Condition="'$(TargetOS)' == 'mac'">libtorch-macos-x86_64</LibTorchArchiveCoreName>
<LibTorchArchiveCoreName Condition="'$(TargetPlatform)' == 'mac-arm64'">libtorch-macos-arm64</LibTorchArchiveCoreName>
<LibTorchCpuArchiveBase>$(LibTorchArchiveCoreName)-$(LibTorchVersion)$(LibTorchCpuArchiveNameSuffix)</LibTorchCpuArchiveBase>
Expand Down
25 changes: 22 additions & 3 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
<Project>

<!-- Ensure NativeOutputPath is populated for consumer projects (examples/tests) on Windows ARM64 by staging redist first -->
<Target Name="EnsureNativeRedistStaged" BeforeTargets="PrepareForRun" Condition="'$(OS)' == 'Windows_NT' and '$(NativeTargetArchitecture)' == 'arm64' and '$(SkipNative)' != 'true'">
<Message Importance="High" Text="Ensuring Windows ARM64 native redist is staged to $(NativeOutputPath)" />
<MSBuild Projects="$(RepoRoot)src\Redist\libtorch-cpu\libtorch-cpu.proj" Targets="Build" Properties="Configuration=$(NativeConfiguration);TargetOS=windows;TargetArchitecture=arm64" />
</Target>

<!-- We copy over the LibTorch native binaries in order to run tests. This can probably be automated better. -->
<!-- These lists are duplicated in redist/... with file splitting added for package prep -->
<!-- These lists are duplicated in redist/... with file splitting added for package prep -->

<ItemGroup Condition="'$(TestUsesLibTorch)' == 'true' and '$(SkipNative)' != 'true' ">
<NativeAssemblyReference Include="LibTorchSharp" />
Expand All @@ -18,6 +23,20 @@
<NativeAssemblyReference Include="uv" />
</ItemGroup>

<!-- Windows ARM64 CPU libtorch binary list used for examples and testing -->
<ItemGroup Condition="'$(NativeTargetArchitecture)' == 'arm64' and '$(OS)' == 'Windows_NT' and '$(TestUsesLibTorch)' == 'true' and ('$(TestCuda)' != 'true' or '$(SkipCuda)' == 'true') and '$(SkipNative)' != 'true' ">
<NativeAssemblyReference Include="aoti_custom_ops" />
<NativeAssemblyReference Include="backend_with_compiler" />
<NativeAssemblyReference Include="c10" />
<NativeAssemblyReference Include="torchbind_test" />
<NativeAssemblyReference Include="torch" />
<NativeAssemblyReference Include="torch_cpu" />
<NativeAssemblyReference Include="torch_global_deps" />
<NativeAssemblyReference Include="uv" />
<NativeAssemblyReference Include="jitbackend_test" />
<NativeAssemblyReference Include="armpl_lp64" />
</ItemGroup>

<!-- Windows CUDA 12.1 libtorch binary list used for examples and testing -->
<ItemGroup Condition="'$(NativeTargetArchitecture)' == 'x64' and '$(OS)' == 'Windows_NT' and '$(TestUsesLibTorch)' == 'true' and ('$(TestCuda)' == 'true' and '$(SkipCuda)' != 'true') and '$(SkipNative)' != 'true' ">
<NativeAssemblyReference Include="c10" Variant="cuda\" />
Expand Down Expand Up @@ -113,5 +132,5 @@
</Copy>

</Target>

</Project>
2 changes: 1 addition & 1 deletion pkg/TorchAudio/TorchAudio.nupkgproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<ItemGroup>
<ProjectReference Include="..\TorchSharp\TorchSharp.nupkgproj" />
</ItemGroup>

<ItemGroup>
<Content Include="..\common\NormalPackage.props" Pack="true" PackagePath="buildTransitive\net8.0\$(MSBuildProjectName).props" />
<Content Include="..\common\NormalPackage.targets" Pack="true" PackagePath="buildTransitive\net8.0\$(MSBuildProjectName).targets" />
Expand Down
2 changes: 1 addition & 1 deletion pkg/TorchVision/TorchVision.nupkgproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<ItemGroup>
<ProjectReference Include="..\TorchSharp\TorchSharp.nupkgproj" />
</ItemGroup>

<ItemGroup>
<Content Include="..\common\NormalPackage.props" Pack="true" PackagePath="buildTransitive\net8.0\$(MSBuildProjectName).props" />
<Content Include="..\common\NormalPackage.targets" Pack="true" PackagePath="buildTransitive\net8.0\$(MSBuildProjectName).targets" />
Expand Down
16 changes: 16 additions & 0 deletions pkg/libtorch-cpu-win-arm64/libtorch-cpu-win-arm64.nupkgproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk" DefaultTargets="Pack">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
</ItemGroup>

<ItemGroup>
<Content Include="..\common\CpuHeadPackage.props" Pack="true" PackagePath="buildTransitive\netstandard2.0\$(MSBuildProjectName).props" />
<Content Include="..\common\CpuHeadPackage.targets" Pack="true" PackagePath="buildTransitive\netstandard2.0\$(MSBuildProjectName).targets" />
<Content Include="..\empty.txt" Pack="true" PackagePath="lib\netstandard2.0\_._" />
<Content Include="$(RepoRoot)\THIRD-PARTY-NOTICES.txt" Pack="true" PackagePath="LICENSE-LIBTORCH.txt" />
</ItemGroup>
</Project>
1 change: 1 addition & 0 deletions pkg/libtorch-cpu/libtorch-cpu.nupkgproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<ProjectReference Include="../libtorch-cpu-linux-x64/libtorch-cpu-linux-x64.nupkgproj" />
<ProjectReference Include="../libtorch-cpu-osx-arm64/libtorch-cpu-osx-arm64.nupkgproj" />
<ProjectReference Include="../libtorch-cpu-win-x64/libtorch-cpu-win-x64.nupkgproj" />
<ProjectReference Include="../libtorch-cpu-win-arm64/libtorch-cpu-win-arm64.nupkgproj" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
Expand Down
6 changes: 4 additions & 2 deletions pkg/pack.proj
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
<Target Name="Pack" DependsOnTargets="Restore">
<Warning Text="Packages will be incomplete and unusable on linux platforms. To get a complete package you need the LibTorchSharp.so binaries for other platforms and copy them into '$(PackagePreparationPath)' to make complete packages. This is automated by Azure Pipelines."
Condition="'$(IncludeTorchSharpPackage)' == 'true' AND !Exists('$(PackagePreparationPath)\TorchSharp\runtimes\linux-x64\native\libLibTorchSharp.so')" />
<Warning Text="Packages will be incomplete and unusable on win-x64 platform. To get a complete package you need the LibTorchSharp.dll binaries for other platforms and copy them into '$(PackagePreparationPath)' to make complete packages. This is automated by Azure Pipelines."
Condition="'$(IncludeTorchSharpPackage)' == 'true' AND !Exists('$(PackagePreparationPath)\TorchSharp\runtimes\win-x64\native\LibTorchSharp.dll')" />
<Warning Text="Packages will be incomplete and unusable on win-x64 platform. To get a complete package you need the LibTorchSharp.dll binaries for other platforms and copy them into '$(PackagePreparationPath)' to make complete packages. This is automated by Azure Pipelines."
Condition="'$(IncludeTorchSharpPackage)' == 'true' AND !Exists('$(PackagePreparationPath)\TorchSharp\runtimes\win-x64\native\LibTorchSharp.dll')" />
<Warning Text="Packages will be incomplete and unusable on win-arm64 platform. To get a complete package you need the LibTorchSharp.dll binaries for other platforms and copy them into '$(PackagePreparationPath)' to make complete packages. This is automated by Azure Pipelines."
Condition="'$(IncludeTorchSharpPackage)' == 'true' AND !Exists('$(PackagePreparationPath)\TorchSharp\runtimes\win-arm64\native\LibTorchSharp.dll')" />

<MSBuild Projects="%(PackProject.Identity)" Targets="Pack" />

Expand Down
19 changes: 7 additions & 12 deletions src/Native/build.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -86,30 +87,24 @@ goto :SetupDirs
:: 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
Expand Down
1 change: 1 addition & 0 deletions src/Native/gen-buildsys-win.bat
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 15 additions & 1 deletion src/Redist/libtorch-cpu/libtorch-cpu.proj
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
<CopyToPackageSemaphore>$(MainPackageFolder)\.copied.SkipTests.$(SkipTests).IncludeLibTorchCpuPackages.$(IncludeLibTorchCpuPackages)</CopyToPackageSemaphore>
</PropertyGroup>

<ItemGroup Condition="'$(TargetOS)' == 'windows'">
<ItemGroup Condition="'$(TargetOS)' == 'windows' and '$(NativeTargetArchitecture)' != 'arm64'">
<File Include="libtorch\lib\asmjit.dll" />
<File Include="libtorch\lib\c10.dll" />
<File Include="libtorch\lib\libiomp5md.dll" />
<File Include="libtorch\lib\libiompstubs5md.dll" />
Expand All @@ -39,6 +40,19 @@
<File Include="libtorch\lib\torch_global_deps.dll" />
<File Include="libtorch\lib\uv.dll" />
</ItemGroup>
<!-- Windows ARM64 has a smaller set of DLLs and different deps names -->
<ItemGroup Condition="'$(TargetOS)' == 'windows' and '$(NativeTargetArchitecture)' == 'arm64'">
<File Include="lib\aoti_custom_ops.dll"/>
<File Include="lib\backend_with_compiler.dll"/>
<File Include="lib\c10.dll"/>
<File Include="lib\jitbackend_test.dll"/>
<File Include="lib\torchbind_test.dll"/>
<File Include="lib\torch.dll"/>
<File Include="lib\torch_cpu.dll"/>
<File Include="lib\torch_global_deps.dll"/>
<File Include="lib\uv.dll"/>
<File Include="lib\armpl_lp64.dll"/>
Comment on lines +45 to +54
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Windows ARM64 file paths use "lib" instead of "libtorch\lib" which is inconsistent with the x64 Windows paths (lines 34-41) and other platforms. This inconsistency suggests these files may be in a different directory structure in the ARM64 libtorch distribution. Please verify that the ARM64 libtorch archive actually has files directly in a "lib" folder rather than "libtorch\lib". If the directory structure is indeed different, this is correct. Otherwise, these paths should be updated to match the pattern used for other platforms.

Suggested change
<File Include="lib\aoti_custom_ops.dll"/>
<File Include="lib\backend_with_compiler.dll"/>
<File Include="lib\c10.dll"/>
<File Include="lib\jitbackend_test.dll"/>
<File Include="lib\torchbind_test.dll"/>
<File Include="lib\torch.dll"/>
<File Include="lib\torch_cpu.dll"/>
<File Include="lib\torch_global_deps.dll"/>
<File Include="lib\uv.dll"/>
<File Include="lib\armpl_lp64.dll"/>
<File Include="libtorch\lib\aoti_custom_ops.dll"/>
<File Include="libtorch\lib\backend_with_compiler.dll"/>
<File Include="libtorch\lib\c10.dll"/>
<File Include="libtorch\lib\jitbackend_test.dll"/>
<File Include="libtorch\lib\torchbind_test.dll"/>
<File Include="libtorch\lib\torch.dll"/>
<File Include="libtorch\lib\torch_cpu.dll"/>
<File Include="libtorch\lib\torch_global_deps.dll"/>
<File Include="libtorch\lib\uv.dll"/>
<File Include="libtorch\lib\armpl_lp64.dll"/>

Copilot uses AI. Check for mistakes.
</ItemGroup>
<ItemGroup Condition="'$(NativeTargetArchitecture)' == 'arm64' and '$(TargetOS)' == 'mac'">
<File Include="libtorch\lib\libc10.dylib" />
<File Include="libtorch\lib\libshm.dylib" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
38D666A9030BA098D1AC5DABFD995CF3D113A12D512252080978B0CC206AF205
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
F9DD47C792C900601F08265DDC0186036E01503ADA7895F0C7C90F8AF64FBC4B
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
A6B6C3D9FF25113F8E48F6C7A5DD14EFCA5BCA6DE300DE0BD003FCC309439F2C
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DFDD2BECA32B1B3D4894EFA801DC60570849F0ED47A318734BA798A5C4D6513B
51 changes: 46 additions & 5 deletions src/TorchSharp/Torch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,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$" :
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex pattern change adds a "$" end-of-string anchor to the Windows DLL pattern. However, at line 320 in the same file, this pattern is already wrapped with "^" and "$" anchors: var nativeRegExp = new Regex("^" + nativeGlob + "$");. This means the final regex will be ^.*\.dll$$ with a double dollar sign, which is incorrect and will fail to match DLL files. The "$" should be removed from the nativeGlob definition since it's already added when the regex is constructed.

Suggested change
RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @".*\.dll$" :
RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @".*\.dll" :

Copilot uses AI. Check for mistakes.
RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? @".*\.dylib\.*" :
// must match
// lib.so
Expand Down Expand Up @@ -129,7 +129,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.
Expand All @@ -152,9 +153,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);
Copy link

Copilot AI Aug 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable isWindows is redeclared here when it's already available from line 129. Consider reusing the existing variable to avoid duplication.

Copilot uses AI. Check for mistakes.
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);
}
Comment on lines +167 to +180
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new Windows CPU dependency loading chain is more explicit (torch_global_deps -> c10 -> uv -> torch -> torch_cpu -> LibTorchSharp) compared to the previous simpler approach that only loaded torch_cpu and LibTorchSharp. While this may be necessary for Windows ARM64, applying it to all Windows platforms (including x64) could be a breaking change. Consider:

  1. Whether this change is actually needed for Windows x64 or only for ARM64
  2. If this is needed for all Windows, testing on x64 to ensure backward compatibility
  3. Whether the order of dependencies is correct for all scenarios

If this change is specifically for ARM64 dependencies, consider adding a condition to only use this explicit chain for ARM64, or add a comment explaining why this is now needed for all Windows platforms.

Copilot uses AI. Check for mistakes.

// 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);
}
Comment on lines +182 to +198
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The absolute-path fallback loading for Windows CPU mode loads files even if earlier named-based loads succeeded (the check is if (!ok && isWindows)). However, this fallback will only execute if the previous named-based loads failed. The logic constructs paths for all dependency DLLs and attempts to load them in order. If any single load fails, the entire chain fails (the pattern if (ok) ok = ... means subsequent loads only happen if previous ones succeeded).

Consider whether this is the desired behavior, or if it should continue attempting to load remaining DLLs even if one fails, similar to how the named-based approach uses ok = ... without checking previous success for each individual library.

Copilot uses AI. Check for mistakes.
}

trace.AppendLine($" Result from regular native load of LibTorchSharp is {ok}");
Expand Down
Loading