diff --git a/Directory.Build.props b/Directory.Build.props
index e8e44ee50..014fd9495 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -55,10 +55,12 @@
$(TargetOS)-$(TargetArchitecture)
win-x64
+ win-arm64
linux-x64
osx-arm64
win-x64
+ win-arm64
linux-x64
osx-$(TargetArchitecture)
@@ -141,6 +143,7 @@
cpu
cu$(CudaVersionNoDot)
libtorch-win-shared-with-deps$(LibTorchDebug)
+ libtorch-win-arm64-shared-with-deps$(LibTorchDebug)
libtorch-shared-with-deps
libtorch-macos-x86_64
libtorch-macos-arm64
@@ -148,7 +151,9 @@
$(LibTorchArchiveCoreName)-$(LibTorchVersion)$(LibTorchCudaArchiveNameSuffix)
$(LibTorchArchiveCoreName)-$(LibTorchVersion)$(LibTorchCpuLocalNameSuffix)
$(LibTorchArchiveCoreName)-$(LibTorchVersion)$(LibTorchCudaLocalNameSuffix)
- $(IntermediateOutputRootPath)libtorch-cpu\$(LibTorchCpuLocalBase)\libtorch\share\cmake\Torch
+ $(IntermediateOutputRootPath)libtorch-cpu\$(LibTorchCpuLocalBase)\libtorch\share\cmake\Torch
+
+ $(IntermediateOutputRootPath)libtorch-cpu\$(LibTorchCpuLocalBase)\share\cmake\Torch
diff --git a/Directory.Build.targets b/Directory.Build.targets
index 4ab3c814c..cc6bb3d4e 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -18,6 +18,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 3a6a17a96..df20611ac 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -89,6 +89,15 @@ jobs:
pool:
vmImage: 'macos-latest'
+- template: /build/ci/job-template.yml
+ parameters:
+ prepScript: echo "no prep needed"
+ name: Windows_arm64
+ buildScript: dotnet build /p:SkipCuda=true /p:TargetArchitecture=arm64 /p:SkipNetFxBuild=true -c
+ testScript: echo "Cannot run ARM64 tests on x64 Azure Pipelines agent"
+ pool:
+ vmImage: 'windows-latest'
+
################################################################################
# {Build} --> combine --> package to build native bits on multiple OS's
################################################################################
@@ -285,6 +294,64 @@ jobs:
- publish: $(Build.SourcesDirectory)/bin/obj/packprep/$(BuildConfig)
artifact: MacAssets_arm64
+################################################################################
+- job: Windows_arm64_Native_Build_For_Packages
+################################################################################
+ condition: and(ne(variables['system.pullrequest.isfork'], true), eq(variables['build.sourcebranchname'], '${{ parameters.SourceBranchName }}'))
+ variables:
+ BuildConfig: Release
+ OfficialBuildId: $(BUILD.BUILDNUMBER)
+ DOTNET_CLI_TELEMETRY_OPTOUT: 1
+ DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
+ DOTNET_MULTILEVEL_LOOKUP: 0
+ pool:
+ vmImage: 'windows-latest'
+ steps:
+ # Initial cleanup
+ - script: |
+ rmdir /s /q .git 2>nul
+ dotnet nuget locals all --clear
+ dir
+ displayName: Initial cleanup
+ continueOnError: true
+
+ - task: UseDotNet@2
+ displayName: 'Use .NET Core sdk'
+ inputs:
+ packageType: sdk
+ version: 8.0.x
+ installationPath: $(Agent.ToolsDirectory)/dotnet
+
+ # Download ARM64 LibTorch and clean immediately
+ - script: |
+ dotnet build -c $(BuildConfig) src/Redist/libtorch-cpu/libtorch-cpu.proj /p:UpdateSHA=true /p:SkipTests=true /p:TargetOS=windows /p:TargetArchitecture=arm64 /t:Build /p:IncludeLibTorchCpuPackages=true
+ del /s /q *.zip 2>nul
+ del /s /q *.tar.gz 2>nul
+ displayName: Download ARM64 libtorch native binaries and cleanup
+ condition: eq('${{ parameters.BuildLibTorchPackages }}', true)
+
+ # Cross-compile LibTorchSharp for ARM64 on x64 host
+ - script: dotnet build -c $(BuildConfig) src/TorchSharp/TorchSharp.csproj /p:SkipCuda=true /p:SkipTests=true /p:TargetArchitecture=arm64
+ condition: eq('${{ parameters.BuildLibTorchPackages }}', true)
+ displayName: Build TorchSharp win-arm64
+
+ - script: dotnet build -c $(BuildConfig) src/TorchVision/TorchVision.csproj /p:SkipCuda=true /p:SkipTests=true /p:TargetArchitecture=arm64
+ displayName: Build TorchVision
+
+ - script: dotnet build -c $(BuildConfig) src/TorchAudio/TorchAudio.csproj /p:SkipCuda=true /p:SkipTests=true /p:TargetArchitecture=arm64
+ displayName: Build TorchAudio
+
+ # Clean up unnecessary files before publishing
+ - script: |
+ del /s /q $(Build.SourcesDirectory)\bin\*.pdb 2>nul
+ del /s /q $(Build.SourcesDirectory)\bin\*.xml 2>nul
+ del /s /q $(Build.SourcesDirectory)\bin\obj\packprep\$(BuildConfig)\*.lib 2>nul
+ displayName: Clean up unnecessary files
+ continueOnError: true
+
+ - publish: $(Build.SourcesDirectory)/bin/obj/packprep/$(BuildConfig)
+ artifact: WindowsAssets_arm64
+
################################################################################
- job: Build_TorchSharp_And_libtorch_cpu_Packages
################################################################################
@@ -292,6 +359,7 @@ jobs:
dependsOn:
- Linux_Native_Build_For_Packages
- Windows_Native_Build_For_Packages
+ - Windows_arm64_Native_Build_For_Packages
- MacOS_arm64_Native_Build_For_Packages
timeoutInMinutes: 90
variables:
@@ -496,6 +564,56 @@ jobs:
displayName: Clean WindowsAssets immediately
continueOnError: true
+ # Process Windows ARM64 assets
+ - task: DownloadPipelineArtifact@2
+ displayName: Download Windows ARM64 TorchSharp assets
+ inputs:
+ artifact: WindowsAssets_arm64
+ patterns: |
+ TorchSharp/**
+ path: $(Pipeline.Workspace)/WindowsAssets_arm64
+ retryCountOnTaskFailure: 3
+
+ - task: DownloadPipelineArtifact@2
+ displayName: Download Windows ARM64 TorchAudio assets
+ inputs:
+ artifact: WindowsAssets_arm64
+ patterns: |
+ TorchAudio/**
+ path: $(Pipeline.Workspace)/WindowsAssets_arm64
+ retryCountOnTaskFailure: 3
+
+ - task: DownloadPipelineArtifact@2
+ displayName: Download Windows ARM64 TorchVision assets
+ inputs:
+ artifact: WindowsAssets_arm64
+ patterns: |
+ TorchVision/**
+ path: $(Pipeline.Workspace)/WindowsAssets_arm64
+ retryCountOnTaskFailure: 3
+
+ - task: DownloadPipelineArtifact@2
+ displayName: Download Windows ARM64 libtorch-cpu assets
+ condition: eq('${{ parameters.BuildLibTorchPackages }}', true)
+ inputs:
+ artifact: WindowsAssets_arm64
+ patterns: |
+ libtorch-cpu-win-arm64/**
+ path: $(Pipeline.Workspace)/WindowsAssets_arm64
+ retryCountOnTaskFailure: 3
+ continueOnError: true
+
+ - task: CopyFiles@2
+ displayName: Copy Windows ARM64 native assets (batch)
+ inputs:
+ sourceFolder: $(Pipeline.Workspace)/WindowsAssets_arm64
+ targetFolder: $(Build.SourcesDirectory)/bin/obj/packprep/$(BuildConfig)
+ cleanTargetFolder: false
+
+ - script: rmdir /s /q $(Pipeline.Workspace)\WindowsAssets_arm64
+ displayName: Clean WindowsAssets_arm64 immediately
+ continueOnError: true
+
# Restore and pack
- script: dotnet restore pkg/pack.proj /p:Configuration=Release --nologo
displayName: Restore package projects
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..d8ce731a6
--- /dev/null
+++ b/pkg/libtorch-cpu-win-arm64/libtorch-cpu-win-arm64.nupkgproj
@@ -0,0 +1,16 @@
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pkg/libtorch-cpu/libtorch-cpu.nupkgproj b/pkg/libtorch-cpu/libtorch-cpu.nupkgproj
index 97c3ffe67..c35a3d5fc 100644
--- a/pkg/libtorch-cpu/libtorch-cpu.nupkgproj
+++ b/pkg/libtorch-cpu/libtorch-cpu.nupkgproj
@@ -7,6 +7,7 @@
+
diff --git a/pkg/pack.proj b/pkg/pack.proj
index 3c9db2f98..55474fdc6 100644
--- a/pkg/pack.proj
+++ b/pkg/pack.proj
@@ -24,6 +24,8 @@
Condition="'$(IncludeTorchSharpPackage)' == 'true' AND !Exists('$(PackagePreparationPath)\TorchSharp\runtimes\linux-x64\native\libLibTorchSharp.so')" />
+
diff --git a/src/Native/build.cmd b/src/Native/build.cmd
index c0c26c600..ef2b1bd84 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=amd64_arm64&&shift&goto Arg_Loop)
if /i [%1] == [--libtorchpath] ( set LIBTORCH_PATH=%2&&shift&goto Arg_Loop)
@@ -66,50 +67,39 @@ exit /b 1
:: Setup vars for VS2026
set __PlatformToolset=v145
set __VSVersion=18 2026
-if NOT "%__BuildArch%" == "arm64" (
- :: Set the environment for the native build
- call "%VS180COMNTOOLS%..\..\VC\Auxiliary\Build\vcvarsall.bat" %__VCBuildArch%
-)
+:: Set the environment for the native build (including cross-compilation for ARM64)
+call "%VS180COMNTOOLS%..\..\VC\Auxiliary\Build\vcvarsall.bat" %__VCBuildArch%
goto :SetupDirs
:VS2022
:: Setup vars for VS2022
set __PlatformToolset=v143
set __VSVersion=17 2022
-if NOT "%__BuildArch%" == "arm64" (
- :: Set the environment for the native build
- call "%VS170COMNTOOLS%..\..\VC\Auxiliary\Build\vcvarsall.bat" %__VCBuildArch%
-)
+:: Set the environment for the native build (including cross-compilation for ARM64)
+call "%VS170COMNTOOLS%..\..\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 (including cross-compilation for ARM64)
+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 (including cross-compilation for ARM64)
+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%
-)
+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..c4a76bd4f 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
@@ -40,7 +41,7 @@ GOTO :DONE
echo "Usage..."
echo "gen-buildsys-win.bat "
echo "Specify the VSVersion to be used - VS2015, VS2017 or VS2019"
- echo "Specify the Target Architecture - x86, or x64."
+ echo "Specify the Target Architecture - x86, x64, or ARM64."
EXIT /B 1
:DONE
diff --git a/src/Redist/libtorch-cpu/libtorch-cpu.proj b/src/Redist/libtorch-cpu/libtorch-cpu.proj
index adc8ba013..c082675ee 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)
-
+
@@ -39,6 +39,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/Redist/libtorch-cpu/libtorch-win-arm64-shared-with-deps-2.10.0%2Bcpu.zip.sha b/src/Redist/libtorch-cpu/libtorch-win-arm64-shared-with-deps-2.10.0%2Bcpu.zip.sha
new file mode 100644
index 000000000..f50bc08ff
--- /dev/null
+++ b/src/Redist/libtorch-cpu/libtorch-win-arm64-shared-with-deps-2.10.0%2Bcpu.zip.sha
@@ -0,0 +1 @@
+38d666a9030ba098d1ac5dabfd995cf3d113a12d512252080978b0cc206af205
\ No newline at end of file
diff --git a/src/TorchSharp/Torch.cs b/src/TorchSharp/Torch.cs
index dd7a07689..c7e6dd608 100644
--- a/src/TorchSharp/Torch.cs
+++ b/src/TorchSharp/Torch.cs
@@ -38,7 +38,8 @@ public static partial class torch
RuntimeInformation.OSArchitecture == Architecture.Arm64;
static string nativeRid =>
- RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? $"win-x64" :
+ RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
+ ? (RuntimeInformation.OSArchitecture == Architecture.Arm64 ? "win-arm64" : "win-x64") :
RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? $"linux-x64" :
isAppleSilicon ? "osx-arm64" :
"any";