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
7 changes: 6 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,12 @@
<TargetPlatform Condition="'$(TargetPlatform)' == ''">$(TargetOS)-$(TargetArchitecture)</TargetPlatform>

<TargetRuntimeID Condition="'$(TargetOS)' == 'windows'">win-x64</TargetRuntimeID>
<TargetRuntimeID Condition="'$(TargetPlatform)' == 'windows-arm64'">win-arm64</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="'$(TargetPlatform)' == 'windows-arm64'">win-arm64</TargetRuntimeID>
<TargetRuntimeID Condition="'$(TargetOS)' == 'linux'">linux-x64</TargetRuntimeID>
<TargetRuntimeID Condition="'$(TargetOS)' == 'mac'">osx-$(TargetArchitecture)</TargetRuntimeID>

Expand Down Expand Up @@ -141,14 +143,17 @@
<LibTorchCpuLocalNameSuffix>cpu</LibTorchCpuLocalNameSuffix>
<LibTorchCudaLocalNameSuffix>cu$(CudaVersionNoDot)</LibTorchCudaLocalNameSuffix>
<LibTorchArchiveCoreName Condition="'$(TargetOS)' == 'windows'">libtorch-win-shared-with-deps$(LibTorchDebug)</LibTorchArchiveCoreName>
<LibTorchArchiveCoreName Condition="'$(TargetPlatform)' == 'windows-arm64'">libtorch-win-arm64-shared-with-deps$(LibTorchDebug)</LibTorchArchiveCoreName>
<LibTorchArchiveCoreName Condition="'$(TargetOS)' == 'linux'">libtorch-shared-with-deps</LibTorchArchiveCoreName>
<LibTorchArchiveCoreName Condition="'$(TargetOS)' == 'mac'">libtorch-macos-x86_64</LibTorchArchiveCoreName>
<LibTorchArchiveCoreName Condition="'$(TargetPlatform)' == 'mac-arm64'">libtorch-macos-arm64</LibTorchArchiveCoreName>
<LibTorchCpuArchiveBase>$(LibTorchArchiveCoreName)-$(LibTorchVersion)$(LibTorchCpuArchiveNameSuffix)</LibTorchCpuArchiveBase>
<LibTorchCudaArchiveBase>$(LibTorchArchiveCoreName)-$(LibTorchVersion)$(LibTorchCudaArchiveNameSuffix)</LibTorchCudaArchiveBase>
<LibTorchCpuLocalBase>$(LibTorchArchiveCoreName)-$(LibTorchVersion)$(LibTorchCpuLocalNameSuffix)</LibTorchCpuLocalBase>
<LibTorchCudaLocalBase>$(LibTorchArchiveCoreName)-$(LibTorchVersion)$(LibTorchCudaLocalNameSuffix)</LibTorchCudaLocalBase>
<LibTorchCmakePath>$(IntermediateOutputRootPath)libtorch-cpu\$(LibTorchCpuLocalBase)\libtorch\share\cmake\Torch</LibTorchCmakePath>
<LibTorchCmakePath Condition="'$(TargetPlatform)' != 'windows-arm64'">$(IntermediateOutputRootPath)libtorch-cpu\$(LibTorchCpuLocalBase)\libtorch\share\cmake\Torch</LibTorchCmakePath>
<!-- Windows ARM64 archive has a different layout: share/cmake/Torch instead of libtorch/share/cmake/Torch -->
<LibTorchCmakePath Condition="'$(TargetPlatform)' == 'windows-arm64'">$(IntermediateOutputRootPath)libtorch-cpu\$(LibTorchCpuLocalBase)\share\cmake\Torch</LibTorchCmakePath>
</PropertyGroup>

<!-- Language configuration -->
Expand Down
10 changes: 10 additions & 0 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@
<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="armpl_lp64" />
<NativeAssemblyReference Include="c10" />
<NativeAssemblyReference Include="torch" />
<NativeAssemblyReference Include="torch_cpu" />
<NativeAssemblyReference Include="torch_global_deps" />
<NativeAssemblyReference Include="uv" />
</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
118 changes: 118 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
################################################################################
Expand Down Expand Up @@ -285,13 +294,72 @@ 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
################################################################################
condition: and(ne(variables['system.pullrequest.isfork'], true), eq(variables['build.sourcebranchname'], '${{ parameters.SourceBranchName }}'))
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:
Expand Down Expand Up @@ -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
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 @@ -7,6 +7,7 @@
<ItemGroup>
<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-arm64/libtorch-cpu-win-arm64.nupkgproj" />
<ProjectReference Include="../libtorch-cpu-win-x64/libtorch-cpu-win-x64.nupkgproj" />
</ItemGroup>

Expand Down
2 changes: 2 additions & 0 deletions pkg/pack.proj
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
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-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
30 changes: 10 additions & 20 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=amd64_arm64&&shift&goto Arg_Loop)

if /i [%1] == [--libtorchpath] ( set LIBTORCH_PATH=%2&&shift&goto Arg_Loop)

Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion 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 All @@ -40,7 +41,7 @@ GOTO :DONE
echo "Usage..."
echo "gen-buildsys-win.bat <VSVersion> <Target Architecture>"
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
Expand Down
11 changes: 10 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,7 @@
<CopyToPackageSemaphore>$(MainPackageFolder)\.copied.SkipTests.$(SkipTests).IncludeLibTorchCpuPackages.$(IncludeLibTorchCpuPackages)</CopyToPackageSemaphore>
</PropertyGroup>

<ItemGroup Condition="'$(TargetOS)' == 'windows'">
<ItemGroup Condition="'$(TargetOS)' == 'windows' and '$(NativeTargetArchitecture)' != 'arm64'">
<File Include="libtorch\lib\c10.dll" />
<File Include="libtorch\lib\libiomp5md.dll" />
<File Include="libtorch\lib\libiompstubs5md.dll" />
Expand All @@ -39,6 +39,15 @@
<File Include="libtorch\lib\torch_global_deps.dll" />
<File Include="libtorch\lib\uv.dll" />
</ItemGroup>
<!-- Windows ARM64 archive has a different layout (lib/ instead of libtorch/lib/) and uses ARM Performance Libraries instead of Intel OpenMP -->
<ItemGroup Condition="'$(TargetOS)' == 'windows' and '$(NativeTargetArchitecture)' == 'arm64'">
<File Include="lib\armpl_lp64.dll" />
<File Include="lib\c10.dll" />
<File Include="lib\torch.dll" />
<File Include="lib\torch_cpu.dll" />
<File Include="lib\torch_global_deps.dll" />
<File Include="lib\uv.dll" />
</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
3 changes: 2 additions & 1 deletion src/TorchSharp/Torch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down