Commit 0cbadca
authored
Windows AMI: mirror cuDNN bin\x64 → bin\ flatten step from pytorch/pytorch (#8027)
## Summary
Mirror in `Install-CUDA-Tools.ps1` the flatten step that
`pytorch/pytorch:.ci/pytorch/windows/internal/cuda_install.bat` already
performs, so AMIs baked with the cuDNN cuda13 archive layout end up with
`cudnn64_9.dll` (and friends) directly in:
```
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v13.x\bin\
```
instead of nested under `bin\x64\`.
## Why
Nightly Windows wheel builds on the `windows.12xlarge` runner pool
started shipping with **zero cuDNN DLLs bundled**. Example: [run
25155048920
(`wheel-py3_13-cuda13_0-build`)](https://github.com/pytorch/pytorch/actions/runs/25155048920/job/73734676020)
— the wheel-bundling step logs:
```
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v13.0\bin\cudnn*64_*.dll*
The system cannot find the file specified.
0 file(s) copied.
```
### Root cause
NVIDIA's cuDNN archive layout differs between cuda12 and cuda13:
| archive | DLL location |
|---|---|
| `cudnn-windows-x86_64-9.10.2.21_cuda12-archive` | `bin\cudnn64_9.dll`
(flat) |
| `cudnn-windows-x86_64-9.19.0.56_cuda13-archive` |
`bin\x64\cudnn64_9.dll` (nested) |
| `cudnn-windows-x86_64-9.20.0.48_cuda13-archive` |
`bin\x64\cudnn64_9.dll` (nested) |
`Install-Cudnn` in `Install-CUDA-Tools.ps1` does:
```powershell
Copy-Item -Force -Verbose -Recurse "$tmpCudnnExtracted\$cudnn_subfolder\bin\*" "$expectedInstallLocation\bin"
```
A recursive copy of `bin\*` from a tree containing `bin\x64\<dll>`
produces `…\v13.0\bin\x64\<dll>` — DLLs nested rather than flat in
`bin\`. Confirmed in the [most recent AMI bake
log](https://github.com/pytorch/test-infra/actions/runs/24685806739/job/72194746118):
```
[2802] Source: …\cudnn-windows-x86_64-9.20.0.48_cuda13-archive\bin\x64\cudnn64_9.dll
[2803] Destination: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v13.0\bin\x64\cudnn64_9.dll ❌ nested
```
The header lands at the right place (`include\cudnn.h`), so
`cuda_install.bat`'s "already installed" check (which only looks at
`cudnn_version.h`) passes and skips the reinstall — i.e. the .bat-side
flatten step never runs. The wheel-bundling step then globs
`bin\cudnn*64_*.dll*` non-recursively → 0 files.
### Why this didn't surface before
For any cuda13 archive (9.12, 9.19, 9.20) the AMI installer has always
produced the nested layout. The bug stayed hidden because while the
AMI-baked cuDNN version differed from the version pinned in
`.ci/pytorch/`, `cuda_install.bat`'s reinstall path ran on every build —
and it [explicitly
flattens](https://github.com/pytorch/pytorch/blob/main/.ci/pytorch/windows/internal/cuda_install.bat)
`bin\x64\*.* → bin\` before bundling:
```bat
xcopy /Y /S "...\cudnn\%CUDNN_FOLDER%\bin\*.*" "...\v%CUDA_VERSION_STR%\bin\"
:: Newer cuDNN archives place DLLs under bin\x64\. Flatten them into bin\
:: so they are found via PATH (which only includes bin\, not bin\x64\).
if exist "...\cudnn\%CUDNN_FOLDER%\bin\x64\*.*" (
xcopy /Y "...\cudnn\%CUDNN_FOLDER%\bin\x64\*.*" "...\v%CUDA_VERSION_STR%\bin\"
)
```
The AMI's broken layout was overwritten before any wheel was built. The
bug only surfaces once the AMI version equals the .ci-expected version
(so the .bat check returns "already installed" and skips the reinstall)
— which happened with
[#7972](#7972), bumping the
AMI to cuDNN 9.20.0 to match the pin in pytorch/pytorch.
## Change
Literal mirror in PowerShell of the flatten step the .bat already does:
```powershell
Copy-Item -Force -Verbose -Recurse "$tmpCudnnExtracted\$cudnn_subfolder\bin\*" "$expectedInstallLocation\bin"
# Newer cuDNN archives place DLLs under bin\x64\. Flatten them into bin\
# so they are found via PATH (which only includes bin\, not bin\x64\).
# Mirrors the same step in pytorch/pytorch:.ci/pytorch/windows/internal/cuda_install.bat.
$cudnnBinX64 = "$tmpCudnnExtracted\$cudnn_subfolder\bin\x64"
if (Test-Path -Path $cudnnBinX64 -PathType Container) {
Copy-Item -Force -Verbose "$cudnnBinX64\*.*" "$expectedInstallLocation\bin"
}
```
Net diff: +7 lines, no other behavior change.
## Compatibility with `cuda_install.bat`
- **AMI version matches expected version**: `.bat` skips reinstall;
wheel-bundling now finds DLLs flat in `bin\` thanks to this fix. ✅
- **AMI version mismatches expected version**: `.bat` runs `del /Q
bin\cudnn*.dll` (cleanly removes the flat AMI DLLs), then downloads +
reinstalls + flattens itself. ✅
## Test plan
- [ ] Re-bake the Windows AMI for CUDA 13.0 / 13.2.
- [ ] On the freshly-baked image, confirm `dir "C:\Program Files\NVIDIA
GPU Computing Toolkit\CUDA\v13.0\bin\cudnn*.dll"` lists `cudnn64_9.dll`,
`cudnn_adv64_9.dll`, `cudnn_cnn64_9.dll`, `cudnn_engines_*64_9.dll`,
`cudnn_graph64_9.dll`, `cudnn_heuristic64_9.dll`, `cudnn_ops64_9.dll`
directly under `bin\`.
- [ ] Re-run a `windows-binary-wheel` job on the `windows.12xlarge` pool
and confirm the wheel-bundling step copies non-zero cuDNN DLLs.
- [ ] Confirm the produced wheel returns `True` from
`torch.backends.cudnn.is_available()`.
cc @pytorch/dev-infra1 parent ec8cb08 commit 0cbadca
1 file changed
Lines changed: 7 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
106 | 106 | | |
107 | 107 | | |
108 | 108 | | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
109 | 116 | | |
110 | 117 | | |
111 | 118 | | |
| |||
0 commit comments