## ------------------- ## Constants ## ------------------- # Dictionary of known cuda versions and thier download URLS, which do not follow a consistent pattern :( $CUDA_KNOWN_URLS = @{ "10.2" = "http://developer.download.nvidia.com/compute/cuda/10.2/Prod/network_installers/cuda_10.2.89_win10_network.exe"; "11.0" = "http://developer.download.nvidia.com/compute/cuda/11.0.3/network_installers/cuda_11.0.3_win10_network.exe"; "11.1" = "https://developer.download.nvidia.com/compute/cuda/11.1.1/network_installers/cuda_11.1.1_win10_network.exe"; "11.2" = "https://developer.download.nvidia.com/compute/cuda/11.2.2/network_installers/cuda_11.2.2_win10_network.exe"; "11.3" = "https://developer.download.nvidia.com/compute/cuda/11.3.1/network_installers/cuda_11.3.1_win10_network.exe"; "11.4" = "https://developer.download.nvidia.com/compute/cuda/11.4.2/network_installers/cuda_11.4.2_win10_network.exe"; "11.5" = "https://developer.download.nvidia.com/compute/cuda/11.5.0/network_installers/cuda_11.5.0_win10_network.exe"; } # cuda_runtime.h is in nvcc <= 10.2, but cudart >= 11.0 # @todo - make this easier to vary per CUDA version. if (($CUDA_VERSION_FULL -eq "10.2") -or ($CUDA_VERSION_FULL -eq "11.0") -or ($CUDA_VERSION_FULL -eq "11.1") -or ($CUDA_VERSION_FULL -eq "11.2")){ $CUDA_PACKAGES_IN = @( "nvcc"; "visual_studio_integration"; "nvrtc_dev"; "cudart"; # before 11.3, thrust are included by default and no explicit package exists ) } elseif ($CUDA_VERSION_FULL -eq "11.3"){ $CUDA_PACKAGES_IN = @( "nvcc"; "visual_studio_integration"; "cuda_nvrtc"; "cuda_cudart"; "cuda_thrust"; ) } else { # after cuda 11.4 $CUDA_PACKAGES_IN = @( "nvcc"; "visual_studio_integration"; "nvrtc_dev"; "cudart"; "thrust"; ) } ## ------------------- ## Select CUDA version ## ------------------- # Get the cuda version from the environment as env:cuda. $CUDA_VERSION_FULL = $env:cuda # Make sure CUDA_VERSION_FULL is set and valid, otherwise error. # Validate CUDA version, extracting components via regex $cuda_ver_matched = $CUDA_VERSION_FULL -match "^(?[1-9][0-9]*)\.(?[0-9]+)$" if(-not $cuda_ver_matched){ Write-Output "Invalid CUDA version specified, . required. '$CUDA_VERSION_FULL'." exit 1 } $CUDA_MAJOR=$Matches.major $CUDA_MINOR=$Matches.minor ## ------------------------------------------------ ## Select CUDA packages to install from environment ## ------------------------------------------------ $CUDA_PACKAGES = "" # for CUDA >= 11 cudart is a required package. # if([version]$CUDA_VERSION_FULL -ge [version]"11.0") { # if(-not $CUDA_PACKAGES_IN -contains "cudart") { # $CUDA_PACKAGES_IN += 'cudart' # } # } Foreach ($package in $CUDA_PACKAGES_IN) { # Make sure the correct package name is used for nvcc. if($package -eq "nvcc" -and [version]$CUDA_VERSION_FULL -lt [version]"9.1"){ $package="compiler" } elseif($package -eq "compiler" -and [version]$CUDA_VERSION_FULL -ge [version]"9.1") { $package="nvcc" } $CUDA_PACKAGES += " $($package)_$($CUDA_MAJOR).$($CUDA_MINOR)" } echo "$($CUDA_PACKAGES)" ## ----------------- ## Prepare download ## ----------------- # Select the download link if known, otherwise have a guess. $CUDA_REPO_PKG_REMOTE="" if($CUDA_KNOWN_URLS.containsKey($CUDA_VERSION_FULL)){ $CUDA_REPO_PKG_REMOTE=$CUDA_KNOWN_URLS[$CUDA_VERSION_FULL] } else{ # Guess what the url is given the most recent pattern (at the time of writing, 10.1) Write-Output "note: URL for CUDA ${$CUDA_VERSION_FULL} not known, estimating." $CUDA_REPO_PKG_REMOTE="http://developer.download.nvidia.com/compute/cuda/$($CUDA_MAJOR).$($CUDA_MINOR)/Prod/network_installers/cuda_$($CUDA_VERSION_FULL)_win10_network.exe" } $CUDA_REPO_PKG_LOCAL="cuda_$($CUDA_VERSION_FULL)_win10_network.exe" ## ------------ ## Install CUDA ## ------------ # Get CUDA network installer Write-Output "Downloading CUDA Network Installer for $($CUDA_VERSION_FULL) from: $($CUDA_REPO_PKG_REMOTE)" Invoke-WebRequest $CUDA_REPO_PKG_REMOTE -OutFile $CUDA_REPO_PKG_LOCAL | Out-Null if(Test-Path -Path $CUDA_REPO_PKG_LOCAL){ Write-Output "Downloading Complete" } else { Write-Output "Error: Failed to download $($CUDA_REPO_PKG_LOCAL) from $($CUDA_REPO_PKG_REMOTE)" exit 1 } # Invoke silent install of CUDA (via network installer) Write-Output "Installing CUDA $($CUDA_VERSION_FULL). Subpackages $($CUDA_PACKAGES)" Start-Process -Wait -FilePath .\"$($CUDA_REPO_PKG_LOCAL)" -ArgumentList "-s $($CUDA_PACKAGES)" # Check the return status of the CUDA installer. if (!$?) { Write-Output "Error: CUDA installer reported error. $($LASTEXITCODE)" exit 1 } # Store the CUDA_PATH in the environment for the current session, to be forwarded in the action. $CUDA_PATH = "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v$($CUDA_MAJOR).$($CUDA_MINOR)" $CUDA_PATH_VX_Y = "CUDA_PATH_V$($CUDA_MAJOR)_$($CUDA_MINOR)" # Set environmental variables in this session $env:CUDA_PATH = "$($CUDA_PATH)" $env:CUDA_PATH_VX_Y = "$($CUDA_PATH_VX_Y)" Write-Output "CUDA_PATH $($CUDA_PATH)" Write-Output "CUDA_PATH_VX_Y $($CUDA_PATH_VX_Y)" # PATH needs updating elsewhere, anything in here won't persist. # Append $CUDA_PATH/bin to path. # Set CUDA_PATH as an environmental variable # If executing on github actions, emit the appropriate echo statements to update environment variables if (Test-Path "env:GITHUB_ACTIONS") { # Set paths for subsequent steps, using $env:CUDA_PATH echo "Adding CUDA to CUDA_PATH, CUDA_PATH_X_Y and PATH" echo "CUDA_PATH=$env:CUDA_PATH" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append echo "$env:CUDA_PATH_VX_Y=$env:CUDA_PATH" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append echo "$env:CUDA_PATH/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append }