Skip to content

Commit e7a0637

Browse files
committed
fix: install real windows cuda cccl headers
Add cuda-cccl_win-64 and normalize nv/target into the CUDA include tree so Windows PyTorch extension builds can resolve cuda_fp16.h.
1 parent 36806e8 commit e7a0637

5 files changed

Lines changed: 79 additions & 20 deletions

File tree

.github/workflows/build-native-windows-wheels.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ jobs:
4646
shell: pwsh
4747
run: |
4848
$cudaEnv = Join-Path $env:RUNNER_TEMP 'cuda-build'
49-
conda create -y -p $cudaEnv -c nvidia/label/cuda-12.8.1 -c nvidia -c conda-forge cuda-nvcc cuda-cudart-dev cuda-cccl libcublas-dev libcusparse-dev libcusolver-dev libcurand-dev libcufft-dev
49+
conda create -y -p $cudaEnv -c nvidia/label/cuda-12.8.1 -c nvidia -c conda-forge cuda-nvcc cuda-cudart-dev cuda-cccl cuda-cccl_win-64 libcublas-dev libcusparse-dev libcusolver-dev libcurand-dev libcufft-dev
5050
$cudaRoot = Join-Path $cudaEnv 'Library'
5151
$nvcc = Join-Path $cudaRoot 'bin\nvcc.exe'
5252
if (-not (Test-Path $nvcc)) {

native-wheels/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,4 @@ Run it from GitHub Actions or with `gh` after the workflow has been committed an
129129
gh workflow run build-native-windows-wheels.yml -f release_tag=native-wheels-torch270-cu128-v1 -f upload_release=true
130130
```
131131

132-
The workflow builds `cp311` and `cp312` wheels on `windows-2022`, installs CUDA Toolkit 12.8 build components plus CUDA dev libraries (`cuBLAS`, `cuSPARSE`, `cuSOLVER`, `cuRAND`, `cuFFT`) into a temporary Conda prefix from the NVIDIA Conda channel, runs the smoke test, and optionally uploads the wheels plus license files to the release tag.
132+
The workflow builds `cp311` and `cp312` wheels on `windows-2022`, installs CUDA Toolkit 12.8 build components plus CUDA dev libraries (`cuBLAS`, `cuSPARSE`, `cuSOLVER`, `cuRAND`, `cuFFT`, and `cuda-cccl_win-64`) into a temporary Conda prefix from the NVIDIA Conda channel, runs the smoke test, and optionally uploads the wheels plus license files to the release tag.

native-wheels/scripts/build-diff-gaussian.ps1

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,42 @@ function Ensure-Directory {
5151
New-Item -ItemType Directory -Force -Path $PathValue | Out-Null
5252
}
5353

54+
function Ensure-CudaCcclHeaders {
55+
param([Parameter(Mandatory = $true)][string]$CudaRoot)
56+
57+
$cudaInclude = Join-Path $CudaRoot 'include'
58+
$cudaNvInclude = Join-Path $cudaInclude 'nv'
59+
$cudaNvTarget = Join-Path $cudaNvInclude 'target'
60+
if (Test-Path $cudaNvTarget) {
61+
Write-Host "[native-wheels] CUDA CCCL nv/target header already available at: $cudaNvTarget"
62+
return
63+
}
64+
65+
$candidateNvIncludes = @(
66+
(Join-Path $CudaRoot 'include\cccl\nv'),
67+
(Join-Path $CudaRoot 'targets\x86_64-windows\include\nv'),
68+
(Join-Path $CudaRoot 'targets\x86_64-win32\include\nv')
69+
)
70+
$sourceNvInclude = $candidateNvIncludes | Where-Object { Test-Path (Join-Path $_ 'target') } | Select-Object -First 1
71+
72+
if (-not $sourceNvInclude) {
73+
$foundNvTarget = Get-ChildItem -Path $CudaRoot -Recurse -File -Filter target -ErrorAction SilentlyContinue |
74+
Where-Object { $_.FullName -match '[\\/]nv[\\/]target$' } |
75+
Select-Object -First 1
76+
if ($foundNvTarget) {
77+
$sourceNvInclude = Split-Path $foundNvTarget.FullName -Parent
78+
}
79+
}
80+
81+
if (-not $sourceNvInclude) {
82+
throw "Could not locate CUDA CCCL nv/target header under $CudaRoot. Install the NVIDIA Conda cuda-cccl_win-64 package or provide a full CUDA Toolkit layout."
83+
}
84+
85+
Ensure-Directory -PathValue $cudaNvInclude
86+
Copy-Item -Path (Join-Path $sourceNvInclude '*') -Destination $cudaNvInclude -Recurse -Force
87+
Write-Host "[native-wheels] Mirrored CUDA CCCL nv headers from $sourceNvInclude to: $cudaNvInclude"
88+
}
89+
5490
$resolvedOutDir = [System.IO.Path]::GetFullPath($OutDir)
5591
$resolvedWorkDir = [System.IO.Path]::GetFullPath($WorkDir)
5692
$venvDir = Join-Path $resolvedWorkDir 'venv'
@@ -79,15 +115,8 @@ $ccclInclude = Join-Path $CudaRoot 'include\cccl'
79115
if (Test-Path $ccclInclude) {
80116
$env:INCLUDE = "$ccclInclude;$env:INCLUDE"
81117
Write-Host "[native-wheels] Added CUDA CCCL include path: $ccclInclude"
82-
83-
$cudaInclude = Join-Path $CudaRoot 'include'
84-
$ccclNvInclude = Join-Path $ccclInclude 'nv'
85-
$cudaNvInclude = Join-Path $cudaInclude 'nv'
86-
if ((Test-Path $ccclNvInclude) -and -not (Test-Path $cudaNvInclude)) {
87-
Copy-Item -Path $ccclNvInclude -Destination $cudaNvInclude -Recurse
88-
Write-Host "[native-wheels] Mirrored CUDA CCCL nv headers to: $cudaNvInclude"
89-
}
90118
}
119+
Ensure-CudaCcclHeaders -CudaRoot $CudaRoot
91120

92121
Invoke-Python -Arguments @('-m', 'venv', $venvDir)
93122
$venvPython = Join-Path $venvDir 'Scripts\python.exe'

native-wheels/scripts/build-nvdiffrast.ps1

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,42 @@ function Ensure-Directory {
5050
New-Item -ItemType Directory -Force -Path $PathValue | Out-Null
5151
}
5252

53+
function Ensure-CudaCcclHeaders {
54+
param([Parameter(Mandatory = $true)][string]$CudaRoot)
55+
56+
$cudaInclude = Join-Path $CudaRoot 'include'
57+
$cudaNvInclude = Join-Path $cudaInclude 'nv'
58+
$cudaNvTarget = Join-Path $cudaNvInclude 'target'
59+
if (Test-Path $cudaNvTarget) {
60+
Write-Host "[native-wheels] CUDA CCCL nv/target header already available at: $cudaNvTarget"
61+
return
62+
}
63+
64+
$candidateNvIncludes = @(
65+
(Join-Path $CudaRoot 'include\cccl\nv'),
66+
(Join-Path $CudaRoot 'targets\x86_64-windows\include\nv'),
67+
(Join-Path $CudaRoot 'targets\x86_64-win32\include\nv')
68+
)
69+
$sourceNvInclude = $candidateNvIncludes | Where-Object { Test-Path (Join-Path $_ 'target') } | Select-Object -First 1
70+
71+
if (-not $sourceNvInclude) {
72+
$foundNvTarget = Get-ChildItem -Path $CudaRoot -Recurse -File -Filter target -ErrorAction SilentlyContinue |
73+
Where-Object { $_.FullName -match '[\\/]nv[\\/]target$' } |
74+
Select-Object -First 1
75+
if ($foundNvTarget) {
76+
$sourceNvInclude = Split-Path $foundNvTarget.FullName -Parent
77+
}
78+
}
79+
80+
if (-not $sourceNvInclude) {
81+
throw "Could not locate CUDA CCCL nv/target header under $CudaRoot. Install the NVIDIA Conda cuda-cccl_win-64 package or provide a full CUDA Toolkit layout."
82+
}
83+
84+
Ensure-Directory -PathValue $cudaNvInclude
85+
Copy-Item -Path (Join-Path $sourceNvInclude '*') -Destination $cudaNvInclude -Recurse -Force
86+
Write-Host "[native-wheels] Mirrored CUDA CCCL nv headers from $sourceNvInclude to: $cudaNvInclude"
87+
}
88+
5389
$resolvedOutDir = [System.IO.Path]::GetFullPath($OutDir)
5490
$resolvedWorkDir = [System.IO.Path]::GetFullPath($WorkDir)
5591
$venvDir = Join-Path $resolvedWorkDir 'venv'
@@ -77,15 +113,8 @@ $ccclInclude = Join-Path $CudaRoot 'include\cccl'
77113
if (Test-Path $ccclInclude) {
78114
$env:INCLUDE = "$ccclInclude;$env:INCLUDE"
79115
Write-Host "[native-wheels] Added CUDA CCCL include path: $ccclInclude"
80-
81-
$cudaInclude = Join-Path $CudaRoot 'include'
82-
$ccclNvInclude = Join-Path $ccclInclude 'nv'
83-
$cudaNvInclude = Join-Path $cudaInclude 'nv'
84-
if ((Test-Path $ccclNvInclude) -and -not (Test-Path $cudaNvInclude)) {
85-
Copy-Item -Path $ccclNvInclude -Destination $cudaNvInclude -Recurse
86-
Write-Host "[native-wheels] Mirrored CUDA CCCL nv headers to: $cudaNvInclude"
87-
}
88116
}
117+
Ensure-CudaCcclHeaders -CudaRoot $CudaRoot
89118

90119
Invoke-Python -Arguments @('-m', 'venv', $venvDir)
91120
$venvPython = Join-Path $venvDir 'Scripts\python.exe'

validate_text_only_setup.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ def validate_native_wheels_tooling() -> None:
156156
require("$ErrorActionPreference = 'Stop'" in build_nvdiffrast, "build-nvdiffrast.ps1 must stop on errors")
157157
require("Invoke-Expression" not in build_nvdiffrast, "build-nvdiffrast.ps1 must not construct commands via Invoke-Expression")
158158
require("include\\cccl" in build_nvdiffrast and "$env:INCLUDE" in build_nvdiffrast, "build-nvdiffrast.ps1 must add Conda CUDA CCCL headers to INCLUDE")
159-
require("Mirrored CUDA CCCL nv headers" in build_nvdiffrast, "build-nvdiffrast.ps1 must mirror Conda CCCL nv headers into CUDA include")
159+
require("Ensure-CudaCcclHeaders" in build_nvdiffrast and "cuda-cccl_win-64" in build_nvdiffrast, "build-nvdiffrast.ps1 must normalize Conda CCCL nv headers into CUDA include")
160160
require("pip wheel" in build_nvdiffrast and "--no-build-isolation" in build_nvdiffrast, "build-nvdiffrast.ps1 must build wheels via pip wheel --no-build-isolation")
161161
require("https://github.com/NVlabs/nvdiffrast.git" in build_nvdiffrast and "v0.4.0" in build_nvdiffrast, "build-nvdiffrast.ps1 must pin nvdiffrast source")
162162

@@ -165,7 +165,7 @@ def validate_native_wheels_tooling() -> None:
165165
require("$ErrorActionPreference = 'Stop'" in build_diff, "build-diff-gaussian.ps1 must stop on errors")
166166
require("Invoke-Expression" not in build_diff, "build-diff-gaussian.ps1 must not construct commands via Invoke-Expression")
167167
require("include\\cccl" in build_diff and "$env:INCLUDE" in build_diff, "build-diff-gaussian.ps1 must add Conda CUDA CCCL headers to INCLUDE")
168-
require("Mirrored CUDA CCCL nv headers" in build_diff, "build-diff-gaussian.ps1 must mirror Conda CCCL nv headers into CUDA include")
168+
require("Ensure-CudaCcclHeaders" in build_diff and "cuda-cccl_win-64" in build_diff, "build-diff-gaussian.ps1 must normalize Conda CCCL nv headers into CUDA include")
169169
require("pip wheel" in build_diff and "--no-build-isolation" in build_diff, "build-diff-gaussian.ps1 must build wheels via pip wheel --no-build-isolation")
170170
require("https://github.com/autonomousvision/mip-splatting.git" in build_diff and "dda02ab5ecf45d6edb8c540d9bb65c7e451345a9" in build_diff, "build-diff-gaussian.ps1 must pin mip-splatting source")
171171
require("submodules/diff-gaussian-rasterization" in build_diff, "build-diff-gaussian.ps1 must build the diff-gaussian subdirectory")
@@ -184,6 +184,7 @@ def validate_native_wheels_tooling() -> None:
184184
require("windows-2022" in workflow, "native wheel workflow must build on Windows")
185185
require("conda-incubator/setup-miniconda@v4" in workflow and "cuda-12.8.1" in workflow, "native wheel workflow must install CUDA Toolkit 12.8 packages from NVIDIA Conda")
186186
require("conda create -y -p $cudaEnv" in workflow, "native wheel workflow must install CUDA packages into an explicit prefix")
187+
require("cuda-cccl_win-64" in workflow, "native wheel workflow must install the real Windows CCCL header package")
187188
require("libcusparse-dev" in workflow and "libcublas-dev" in workflow, "native wheel workflow must install CUDA dev headers required by PyTorch")
188189
require("CUDA_HOME=$cudaRoot" in workflow and "CUDA_PATH=$cudaRoot" in workflow, "native wheel workflow must export CUDA_HOME/CUDA_PATH")
189190
require("ilammy/msvc-dev-cmd@v1" in workflow, "native wheel workflow must prepare MSVC developer shell")

0 commit comments

Comments
 (0)