diff --git a/actions/setup_cuda/README.md b/actions/setup_cuda/README.md index a4060f7..c1ec6d7 100644 --- a/actions/setup_cuda/README.md +++ b/actions/setup_cuda/README.md @@ -1,39 +1,42 @@ # setup_cuda -A reusable action to install NVIDIA CUDA Toolkit on Linux runners using the runfile installer. +A reusable action to install NVIDIA CUDA Toolkit on Linux and Windows runners using official installers. -This action provides a consistent way to install CUDA Toolkit across different Linux runners, including both standard -Ubuntu and ARM-based Ubuntu runners. The installation uses NVIDIA's official runfile installers and sets up all -necessary environment variables for C/C++ compilation. +This action provides a consistent way to install CUDA Toolkit across different runners, including Linux (x86_64, ARM64) +and Windows (x86_64). The installation uses NVIDIA's official installers and sets up all necessary environment +variables for C/C++ compilation. ## 🛠️ Prep Work -This action is designed for Linux runners only and requires: -- Ubuntu-based runner (standard x86_64 or ARM64/aarch64) -- Sufficient disk space (CUDA Toolkit requires ~3-4 GB) -- `sudo` access (required for installation) +This action supports the following runners: +- **Linux**: Ubuntu-based runners (x86_64 or ARM64/aarch64) - requires `sudo` access +- **Windows**: Windows Server runners (x86_64) +- **macOS**: Skips gracefully (CUDA not supported on macOS) + +Requirements: +- Sufficient disk space (CUDA Toolkit requires ~3-4 GB for local installer, ~100MB for network installer) > [!NOTE] > This action installs the CUDA Toolkit only (compiler, libraries, headers) and does not install GPU drivers, > as they are not needed for compilation and are not available in standard GitHub Actions runners. > [!TIP] -> To find the correct CUDA version and driver version combination, visit the -> [NVIDIA CUDA Toolkit Downloads](https://developer.nvidia.com/cuda-downloads) page and select your desired version. -> The driver version is part of the runfile name. +> To find the correct CUDA version and driver version combination: +> - **For Linux**: Visit [NVIDIA CUDA Toolkit Downloads](https://developer.nvidia.com/cuda-downloads), select Linux, and note the driver version in the runfile name +> - **For Windows**: Only the CUDA version is needed ## 🚀 Basic Usage See [action.yml](action.yml) -### CUDA 12.4.1 +### Linux - CUDA 13.1.0 ```yaml steps: - - name: Setup CUDA 12.4.1 + - name: Setup CUDA 13.1.0 uses: LizardByte/actions/actions/setup_cuda@master with: - cuda-version: '12.4.1' - driver-version: '550.54.15' + cuda-version: '13.1.0' + driver-version: '590.44.01' # Required for Linux - name: Verify CUDA Version run: nvcc --version ``` @@ -44,23 +47,32 @@ steps: - name: Setup CUDA uses: LizardByte/actions/actions/setup_cuda@master with: - cuda-version: '12.6.2' - driver-version: '560.35.03' + cuda-version: '13.1.0' + driver-version: '590.44.01' install-path: '/opt/cuda' ``` ## 📥 Inputs -| Name | Description | Default | Required | -|----------------|-------------------------------------------------------------------------|-------------------|----------| -| cuda-version | The version of CUDA Toolkit to install (e.g., '12.6.2', '11.8.0') | | `true` | -| driver-version | The driver version in the runfile name (e.g., '560.35.03', '520.61.05') | | `true` | -| install-path | Installation path for CUDA Toolkit | `/usr/local/cuda` | `false` | +| Name | Description | Default | Required | +|----------------|------------------------------------------------------------------------|-------------------|----------| +| cuda-version | The version of CUDA Toolkit to install (e.g., '13.1.0', '12.4.1') | | `true` | +| driver-version | The driver version in the runfile name (Linux only, e.g., '590.44.01') | | `false`* | +| install-path | Installation path for CUDA Toolkit (Linux only) | `/usr/local/cuda` | `false` | + +**Required for Linux, not used for Windows (uses network installer).* > [!NOTE] -> The `driver-version` is the version number included in NVIDIA's runfile name. For example, for the file -> `cuda_12.4.1_550.54.15_linux.run`, the cuda-version is `12.4.1` and the driver-version is `550.54.15`. -> You can find these on the [NVIDIA CUDA Downloads](https://developer.nvidia.com/cuda-downloads) page. +> **Linux**: The `driver-version` is required and must match the driver version in NVIDIA's runfile name. +> - Example: `cuda_13.1.0_590.44.01_linux.run` → driver-version: `590.44.01` +> +> **Windows**: The `driver-version` is not used. Windows uses the network installer which doesn't require specifying a driver version. +> - Network installer: `cuda_13.1.0_windows_network.exe` +> +> **macOS**: The action skips gracefully with a success message (CUDA is not supported on macOS). + +> [!TIP] +> Find driver versions on the [NVIDIA CUDA Downloads](https://developer.nvidia.com/cuda-downloads) page by selecting Linux and viewing the runfile name. ## 📤 Outputs @@ -72,24 +84,34 @@ steps: ## 📝 Notes -### Supported CUDA Versions +### Supported Platforms & Installers -This action can install **any** CUDA Toolkit version available from NVIDIA, as long as you provide the correct -`cuda-version` and `driver-version` combination. There is no hardcoded list of supported versions. +This action can install **any** CUDA Toolkit version available from NVIDIA. + +| Platform | Installer Type | Driver Version | +|----------------|-------------------|----------------| +| Linux x86_64 | Local runfile | ✅ Required | +| Linux ARM64 | Local runfile | ✅ Required | +| Windows x86_64 | Network installer | ❌ Not needed | +| macOS | N/A (skips) | ❌ Not needed | > [!TIP] -> To find the driver version for any CUDA version: -> 1. Visit [NVIDIA CUDA Toolkit Archive](https://developer.nvidia.com/cuda-toolkit-archive) -> 2. Select your desired CUDA version -> 3. Choose "Linux" → "x86_64" (or "sbsa" for ARM) → "Ubuntu" → "runfile (local)" -> 4. The download link will show the full runfile name, which includes the driver version +> **For Linux**: Find the driver version by visiting [NVIDIA CUDA Toolkit Archive](https://developer.nvidia.com/cuda-toolkit-archive): +> 1. Select your desired CUDA version +> 2. Choose "Linux" → "x86_64" (or "sbsa" for ARM) → "Ubuntu" → "runfile (local)" +> 3. The download link shows the full runfile name with driver version > -> For example: `cuda_12.4.1_550.54.15_linux.run` means driver version is `550.54.15` +> Example: `cuda_13.1.0_590.44.01_linux.run` means driver version is `590.44.01` + +> [!TIP] +> **For Windows**: Only specify the `cuda-version`. The network installer automatically handles driver components. > [!NOTE] -> The action automatically detects your architecture and downloads the appropriate installer: -> - **x86_64**: Downloads `cuda_X.Y.Z_DDD.DD.DD_linux.run` -> - **aarch64**: Downloads `cuda_X.Y.Z_DDD.DD.DD_linux_sbsa.run` (Server Base System Architecture) +> The action automatically detects your platform and downloads the appropriate installer: +> - **Linux x86_64**: `cuda_X.Y.Z_DDD.DD.DD_linux.run` +> - **Linux aarch64**: `cuda_X.Y.Z_DDD.DD.DD_linux_sbsa.run` (Server Base System Architecture) +> - **Windows**: `cuda_X.Y.Z_windows_network.exe` (network installer) +> - **macOS**: Skips with success message ### Environment Variables @@ -100,20 +122,31 @@ This action automatically sets up the following environment variables for subseq - `CUDA_ROOT` - Same as CUDA_PATH (for compatibility) - `CMAKE_CUDA_COMPILER` - Path to nvcc compiler - `PATH` - Updated to include `${CUDA_PATH}/bin` -- `LD_LIBRARY_PATH` - Updated to include `${CUDA_PATH}/lib64` -- `LIBRARY_PATH` - Updated to include `${CUDA_PATH}/lib64` -- `CPATH` - Updated to include `${CUDA_PATH}/include` +- `LD_LIBRARY_PATH` - Updated to include `${CUDA_PATH}/lib64` (Linux only) +- `LIBRARY_PATH` - Updated to include `${CUDA_PATH}/lib64` (Linux only) +- `CPATH` - Updated to include `${CUDA_PATH}/include` (Linux only) These variables make it easy to compile CUDA code with various build systems (Make, CMake, etc.). ### Installation Details -- **Installation Method**: Official NVIDIA runfile installer +**Linux:** +- **Installation Method**: Official NVIDIA runfile installer (local) - **Components Installed**: CUDA Toolkit only (compiler, libraries, headers) -- **Components NOT Installed**: GPU drivers, OpenGL libraries (not needed for compilation) +- **Components NOT Installed**: GPU drivers, OpenGL libraries - **Installation Size**: ~3-4 GB depending on version - **Installation Time**: ~2-5 minutes depending on runner speed +**Windows:** +- **Installation Method**: Official NVIDIA network installer +- **Components Installed**: CUDA Toolkit only (compiler, libraries, headers) +- **Components NOT Installed**: GPU drivers, Visual Studio integration +- **Download Size**: ~2-100 MB (components downloaded during installation) +- **Installation Time**: ~5-10 minutes (downloads components as needed) + +**macOS:** +- Skips gracefully with success message (CUDA not supported) + ### CMake Integration The action sets `CMAKE_CUDA_COMPILER` automatically, so CMake will find the correct nvcc compiler. @@ -125,7 +158,11 @@ The action sets `CMAKE_CUDA_COMPILER` automatically, so CMake will find the corr ## ⚠️ Limitations -- **Linux Only**: This action only supports Linux runners (Ubuntu-based) - **No GPU Execution**: GitHub Actions runners don't have GPUs, so you can compile CUDA code but not run it - **No Driver Installation**: GPU drivers are not installed (not needed for compilation) -- **Architecture Support**: Only x86_64 and ARM64/aarch64 architectures are supported +- **Platform Support**: + - ✅ Linux x86_64 and ARM64/aarch64 (full support) + - ✅ Windows x86_64 (full support via network installer) + - ⚠️ macOS (skips gracefully - CUDA not supported on macOS) +- **Linux Requirements**: Requires `sudo` access for installation +- **Windows**: Install path not customizable (uses NVIDIA default location) diff --git a/actions/setup_cuda/action.yml b/actions/setup_cuda/action.yml index 98967a2..5b7788e 100644 --- a/actions/setup_cuda/action.yml +++ b/actions/setup_cuda/action.yml @@ -14,10 +14,12 @@ inputs: driver-version: description: > The driver version included in the CUDA installer (e.g., '560.35.03', '520.61.05'). + Required for Linux, not used for Windows (uses network installer). This can be found on NVIDIA's CUDA Toolkit download page. - required: true + required: false + default: "" install-path: - description: "Installation path for CUDA Toolkit" + description: "Installation path for CUDA Toolkit (Linux only, Windows uses default location)" required: false default: "/usr/local/cuda" diff --git a/actions/setup_cuda/ci-matrix.json b/actions/setup_cuda/ci-matrix.json index fb07261..6a63c92 100644 --- a/actions/setup_cuda/ci-matrix.json +++ b/actions/setup_cuda/ci-matrix.json @@ -12,5 +12,11 @@ "cuda-version": "13.1.0", "driver-version": "590.44.01" } + }, + { + "runs-on": "windows-latest", + "with": { + "cuda-version": "13.1.0" + } } ] diff --git a/actions/setup_cuda/post-ci.sh b/actions/setup_cuda/post-ci.sh index 6db9d8d..26e79bc 100644 --- a/actions/setup_cuda/post-ci.sh +++ b/actions/setup_cuda/post-ci.sh @@ -43,13 +43,111 @@ else exit 1 fi +# Check for lib directory (Windows uses lib, Linux uses lib64) if [[ -d "${CUDA_PATH}/lib64" ]]; then echo "✓ ${CUDA_PATH}/lib64 exists" +elif [[ -d "${CUDA_PATH}/lib" ]]; then + echo "✓ ${CUDA_PATH}/lib exists" else - echo "✗ ${CUDA_PATH}/lib64 not found" + echo "✗ ${CUDA_PATH}/lib or lib64 not found" exit 1 fi +# Detect platform (prefer GitHub's RUNNER_OS when available) +RUNNER_OS_NORMALIZED="${RUNNER_OS:-}" +if [[ -z "${RUNNER_OS_NORMALIZED}" ]]; then + case "$(uname -s 2>/dev/null || echo unknown)" in + MINGW*|MSYS*|CYGWIN*) RUNNER_OS_NORMALIZED="Windows" ;; + Darwin*) RUNNER_OS_NORMALIZED="macOS" ;; + Linux*) RUNNER_OS_NORMALIZED="Linux" ;; + *) RUNNER_OS_NORMALIZED="unknown" ;; + esac +fi + +# On Windows, nvcc needs the MSVC host compiler (cl.exe). GitHub runners sometimes +# don't have it on PATH inside bash. We'll try to enable it, and if we can't, +# we'll skip the compilation test (but still validate the CUDA install). +maybe_enable_msvc_windows() { + [[ "${RUNNER_OS_NORMALIZED}" == "Windows" ]] || return 0 + + if command -v cl.exe &>/dev/null; then + return 0 + fi + + echo "" + echo "MSVC host compiler (cl.exe) not found in PATH. Attempting to enable Visual Studio environment..." + + # Try to locate VS installation via vswhere.exe + # Note: Windows env vars may include parentheses, so use printenv instead of ${ProgramFiles(x86)} + local programfiles_x86 + programfiles_x86="$(printenv 'ProgramFiles(x86)' 2>/dev/null || true)" + local vswhere_winpath="${programfiles_x86}\\Microsoft Visual Studio\\Installer\\vswhere.exe" + local vswhere="" + + # Convert to MSYS path if needed (Git-Bash provides cygpath) + if command -v cygpath &>/dev/null; then + vswhere="$(cygpath -u "$vswhere_winpath" 2>/dev/null || true)" + fi + + # Fallback common path if cygpath isn't available + if [[ -z "${vswhere}" ]]; then + vswhere="/c/Program Files (x86)/Microsoft Visual Studio/Installer/vswhere.exe" + fi + + if [[ ! -f "${vswhere}" ]]; then + echo "⚠ vswhere.exe not found; cannot auto-enable MSVC environment." + return 0 + fi + + local vs_install + vs_install="$(${vswhere} -latest -products '*' -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath 2>/dev/null || true)" + + if [[ -z "${vs_install}" ]]; then + echo "⚠ Visual Studio with C++ build tools not found via vswhere.exe." + return 0 + fi + + # Prefer VsDevCmd.bat (sets a complete dev environment) + local vsdevcmd + vsdevcmd="${vs_install}\\Common7\\Tools\\VsDevCmd.bat" + local vcvars64 + vcvars64="${vs_install}\\VC\\Auxiliary\\Build\\vcvars64.bat" + + local bat_to_call="" + if [[ -f "${vsdevcmd}" ]]; then + bat_to_call="${vsdevcmd}" + elif [[ -f "${vcvars64}" ]]; then + bat_to_call="${vcvars64}" + else + echo "⚠ Could not find VsDevCmd.bat or vcvars64.bat under: ${vs_install}" + return 0 + fi + + # Export the environment from cmd.exe into this bash process. + # We parse `set` output lines as KEY=VALUE. + local env_dump + env_dump="$(cmd.exe /c "call \"${bat_to_call}\" -arch=amd64 -host_arch=amd64 >nul 2>&1 && set" 2>nul | tr -d '\r' || true)" + + if [[ -z "${env_dump}" ]]; then + echo "⚠ Failed to capture Visual Studio environment." + return 0 + fi + + while IFS='=' read -r key val; do + # Skip malformed lines + [[ -z "${key}" ]] && continue + export "${key}=${val}" + done <<< "${env_dump}" + + if command -v cl.exe &>/dev/null; then + echo "✓ MSVC environment enabled (cl.exe now found)" + else + echo "⚠ MSVC environment attempted but cl.exe still not found" + fi +} + +maybe_enable_msvc_windows + # Try to compile a simple CUDA program echo "" echo "Testing CUDA compilation..." @@ -68,24 +166,42 @@ int main() { } EOF -if nvcc -o test_cuda test_cuda.cu; then - echo "✓ CUDA compilation successful" - if ./test_cuda; then - echo "✓ CUDA program execution successful" +# On Windows, nvcc requires MSVC's cl.exe. If it's not available, skip this test. +if [[ "${RUNNER_OS_NORMALIZED}" == "Windows" ]] && ! command -v cl.exe &>/dev/null; then + echo "⚠ Skipping CUDA compilation test on Windows because cl.exe was not found in PATH." + echo " (CUDA toolkit is installed, but MSVC Build Tools are required to compile with nvcc.)" + rm -f test_cuda.cu +else + # Compile only: GitHub runners typically don't have a GPU, so execution is unreliable. + if [[ "${RUNNER_OS_NORMALIZED}" == "Windows" ]]; then + # Object-only compile to validate nvcc + host compiler integration + if nvcc -c test_cuda.cu -o test_cuda.obj; then + echo "✓ CUDA compilation successful" + else + echo "✗ CUDA compilation failed" + rm -f test_cuda.cu test_cuda.obj + exit 1 + fi + rm -f test_cuda.cu test_cuda.obj else - echo "✗ CUDA program execution failed" + if nvcc -o test_cuda test_cuda.cu; then + echo "✓ CUDA compilation successful" + if ./test_cuda; then + echo "✓ CUDA program execution successful" + else + echo "✗ CUDA program execution failed" + rm -f test_cuda test_cuda.cu + exit 1 + fi + else + echo "✗ CUDA compilation failed" + rm -f test_cuda.cu + exit 1 + fi rm -f test_cuda test_cuda.cu - exit 1 fi -else - echo "✗ CUDA compilation failed" - rm -f test_cuda.cu - exit 1 fi -# Clean up test files -rm -f test_cuda test_cuda.cu - # Test CMake integration echo "" echo "Testing CMake CUDA support..." diff --git a/actions/setup_cuda/pre-ci.sh b/actions/setup_cuda/pre-ci.sh index f133095..307d920 100644 --- a/actions/setup_cuda/pre-ci.sh +++ b/actions/setup_cuda/pre-ci.sh @@ -5,6 +5,26 @@ set -euo pipefail echo "Pre-CI: Freeing up disk space for CUDA installation..." echo "" +# Detect OS +OS_TYPE=$(uname -s) + +# Skip on macOS +if [[ "$OS_TYPE" == "Darwin" ]]; then + echo "macOS detected - skipping cleanup (CUDA not supported on macOS)" + echo "Pre-CI setup complete!" + exit 0 +fi + +# Skip on Windows +if [[ "$OS_TYPE" == MINGW* ]] || [[ "$OS_TYPE" == MSYS* ]] || [[ "$OS_TYPE" == CYGWIN* ]]; then + echo "Windows detected - skipping cleanup (Windows runners have sufficient space)" + echo "Pre-CI setup complete!" + exit 0 +fi + +echo "Linux detected - running cleanup script..." +echo "" + # Determine which branch/ref to use for downloading the cleanup script # If we're running in the LizardByte/actions repository itself, use the current commit SHA # Otherwise, use master branch diff --git a/actions/setup_cuda/setup_cuda.sh b/actions/setup_cuda/setup_cuda.sh index 8dd9f18..ae74841 100644 --- a/actions/setup_cuda/setup_cuda.sh +++ b/actions/setup_cuda/setup_cuda.sh @@ -10,10 +10,37 @@ BLUE='\033[0;34m' CYAN='\033[0;36m' RESET='\033[0m' +# OS type constants +readonly OS_LINUX="linux" +readonly OS_WINDOWS="windows" +readonly OS_MACOS="macos" + # Default values CUDA_VERSION="" DRIVER_VERSION="" -INSTALL_PATH="/usr/local/cuda" +INSTALL_PATH="" +OS_TYPE="" + +# Detect OS +detect_os() { + case "$(uname -s)" in + Linux*) + echo "$OS_LINUX" + ;; + Darwin*) + echo "$OS_MACOS" + ;; + MINGW*|MSYS*|CYGWIN*) + echo "$OS_WINDOWS" + ;; + *) + echo -e "${RED}Error: Unsupported OS: $(uname -s)${RESET}" >&2 + exit 1 + ;; + esac + + return 0 +} # Function to detect architecture detect_architecture() { @@ -36,17 +63,21 @@ detect_architecture() { return 0 } -# Function to get the runfile name for a specific version and architecture -get_runfile_name() { +# Function to get the installer name for a specific version and architecture +get_installer_name() { local version="$1" local driver_version="$2" local arch="$3" + local os_type="$4" - # NVIDIA naming convention for runfiles - # For x86_64: cuda___linux.run - # For aarch64: cuda___linux_sbsa.run + # NVIDIA naming convention for installers + # Linux x86_64: cuda___linux.run + # Linux aarch64: cuda___linux_sbsa.run + # Windows: cuda__windows_network.exe (network installer, no driver version) - if [[ "$arch" == "x86_64" ]]; then + if [[ "$os_type" == "$OS_WINDOWS" ]]; then + echo "cuda_${version}_windows_network.exe" + elif [[ "$arch" == "x86_64" ]]; then echo "cuda_${version}_${driver_version}_linux.run" elif [[ "$arch" == "aarch64" ]]; then echo "cuda_${version}_${driver_version}_linux_sbsa.run" @@ -61,10 +92,15 @@ get_runfile_name() { # Function to get download URL get_download_url() { local version="$1" - local runfile="$2" + local installer="$2" + local os_type="$3" - # NVIDIA's standard URL pattern - echo "https://developer.download.nvidia.com/compute/cuda/${version}/local_installers/${runfile}" + # NVIDIA's URL pattern differs for Windows network installer + if [[ "$os_type" == "$OS_WINDOWS" ]]; then + echo "https://developer.download.nvidia.com/compute/cuda/${version}/network_installers/${installer}" + else + echo "https://developer.download.nvidia.com/compute/cuda/${version}/local_installers/${installer}" + fi return 0 } @@ -74,27 +110,31 @@ install_cuda() { local version="$1" local driver_version="$2" local install_path="$3" + local os_type="$4" local arch - local runfile + local installer local download_url arch=$(detect_architecture) echo -e "${BLUE}Detected architecture: ${CYAN}${arch}${RESET}" + echo -e "${BLUE}Operating system: ${CYAN}${os_type}${RESET}" - runfile=$(get_runfile_name "$version" "$driver_version" "$arch") - download_url=$(get_download_url "$version" "$runfile") + installer=$(get_installer_name "$version" "$driver_version" "$arch" "$os_type") + download_url=$(get_download_url "$version" "$installer" "$os_type") - echo -e "${BLUE}Installing CUDA Toolkit ${CYAN}${version}${BLUE} for ${CYAN}${arch}${RESET}" - echo -e "${CYAN}Driver version: ${driver_version}${RESET}" + echo -e "${BLUE}Installing CUDA Toolkit ${CYAN}${version}${BLUE} for ${CYAN}${os_type}/${arch}${RESET}" + if [[ "$os_type" != "$OS_WINDOWS" ]]; then + echo -e "${CYAN}Driver version: ${driver_version}${RESET}" + fi echo -e "${CYAN}Download URL: ${download_url}${RESET}" - # Download the runfile + # Download the installer echo -e "${BLUE}Downloading CUDA installer...${RESET}" local tmp_dir tmp_dir=$(mktemp -d) - local runfile_path="${tmp_dir}/${runfile}" + local installer_path="${tmp_dir}/${installer}" - if ! curl -fsSL -o "$runfile_path" "$download_url"; then + if ! curl -fsSL -o "$installer_path" "$download_url"; then echo -e "${RED}Error: Failed to download CUDA installer${RESET}" >&2 echo -e "${YELLOW}URL: ${download_url}${RESET}" >&2 rm -rf "$tmp_dir" @@ -103,22 +143,36 @@ install_cuda() { echo -e "${GREEN}Download complete${RESET}" - # Make the runfile executable - chmod +x "$runfile_path" - - # Install CUDA toolkit (without driver, since we don't have GPU in CI) - echo -e "${BLUE}Installing CUDA Toolkit to ${CYAN}${install_path}${RESET}" - echo -e "${YELLOW}Note: Installing toolkit only (no driver)${RESET}" + if [[ "$os_type" == "$OS_WINDOWS" ]]; then + # Windows installation using network installer + echo -e "${BLUE}Installing CUDA Toolkit (network installer)${RESET}" + echo -e "${YELLOW}Note: Installing toolkit only (no driver, no visual studio integration)${RESET}" - # Run the installer silently - # --silent: silent installation - # --toolkit: install toolkit only - # --toolkitpath: specify installation path - # --no-opengl-libs: don't install OpenGL libraries (not needed for compilation) - if ! sudo "$runfile_path" --silent --toolkit --toolkitpath="$install_path" --no-opengl-libs; then - echo -e "${RED}Error: CUDA installation failed${RESET}" >&2 - rm -rf "$tmp_dir" - exit 1 + # Run the network installer silently + # -s: silent mode + if ! "$installer_path" -s; then + echo -e "${RED}Error: CUDA installation failed${RESET}" >&2 + rm -rf "$tmp_dir" + exit 1 + fi + else + # Linux installation + # Make the runfile executable + chmod +x "$installer_path" + + echo -e "${BLUE}Installing CUDA Toolkit to ${CYAN}${install_path}${RESET}" + echo -e "${YELLOW}Note: Installing toolkit only (no driver)${RESET}" + + # Run the installer silently + # --silent: silent installation + # --toolkit: install toolkit only + # --toolkitpath: specify installation path + # --no-opengl-libs: don't install OpenGL libraries (not needed for compilation) + if ! sudo "$installer_path" --silent --toolkit --toolkitpath="$install_path" --no-opengl-libs; then + echo -e "${RED}Error: CUDA installation failed${RESET}" >&2 + rm -rf "$tmp_dir" + exit 1 + fi fi echo -e "${GREEN}CUDA Toolkit installation complete${RESET}" @@ -127,9 +181,22 @@ install_cuda() { rm -rf "$tmp_dir" # Verify installation - if [[ -f "${install_path}/bin/nvcc" ]]; then - echo -e "${GREEN}CUDA compiler (nvcc) found at ${install_path}/bin/nvcc${RESET}" - "${install_path}/bin/nvcc" --version + local nvcc_path + if [[ "$os_type" == "$OS_WINDOWS" ]]; then + # Windows: CUDA installs to C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v + # Find the nvcc.exe + nvcc_path=$(find "/c/Program Files/NVIDIA GPU Computing Toolkit/CUDA" -name "nvcc.exe" 2>/dev/null | head -1 || true) + if [[ -z "$nvcc_path" ]]; then + # Try Program Files (x86) + nvcc_path=$(find "/c/Program Files (x86)/NVIDIA GPU Computing Toolkit/CUDA" -name "nvcc.exe" 2>/dev/null | head -1 || true) + fi + else + nvcc_path="${install_path}/bin/nvcc" + fi + + if [[ -f "$nvcc_path" ]]; then + echo -e "${GREEN}CUDA compiler (nvcc) found at ${nvcc_path}${RESET}" + "$nvcc_path" --version || true else echo -e "${RED}Error: CUDA compiler not found after installation${RESET}" >&2 exit 1 @@ -142,43 +209,105 @@ install_cuda() { setup_environment() { local install_path="$1" local version="$2" + local os_type="$3" echo -e "${BLUE}Setting up environment variables...${RESET}" - # Add CUDA to PATH - echo "${install_path}/bin" >> "${GITHUB_PATH}" - - # Set environment variables for GitHub Actions - if [[ -n "${GITHUB_ENV:-}" ]]; then - { - echo "CUDA_PATH=${install_path}" - echo "CUDA_HOME=${install_path}" - echo "CUDA_ROOT=${install_path}" - echo "LD_LIBRARY_PATH=${install_path}/lib64:\${LD_LIBRARY_PATH:-}" - echo "LIBRARY_PATH=${install_path}/lib64:\${LIBRARY_PATH:-}" - echo "CPATH=${install_path}/include:\${CPATH:-}" - echo "CMAKE_CUDA_COMPILER=${install_path}/bin/nvcc" - } >> "${GITHUB_ENV}" - fi + if [[ "$os_type" == "$OS_WINDOWS" ]]; then + # Windows: Find CUDA installation + local cuda_base="/c/Program Files/NVIDIA GPU Computing Toolkit/CUDA" + if [[ ! -d "$cuda_base" ]]; then + cuda_base="/c/Program Files (x86)/NVIDIA GPU Computing Toolkit/CUDA" + fi - # Set outputs for GitHub Actions - if [[ -n "${GITHUB_OUTPUT:-}" ]]; then - { - echo "cuda-version=${version}" - echo "cuda-path=${install_path}" - echo "nvcc-path=${install_path}/bin/nvcc" - } >> "${GITHUB_OUTPUT}" - fi + # Find the version directory + local cuda_version_dir + cuda_version_dir=$(find "$cuda_base" -maxdepth 1 -type d -name "v*" | sort -V | tail -1) - echo -e "${GREEN}Environment variables configured:${RESET}" - echo -e " ${CYAN}CUDA_PATH=${install_path}${RESET}" - echo -e " ${CYAN}CUDA_HOME=${install_path}${RESET}" - echo -e " ${CYAN}CUDA_ROOT=${install_path}${RESET}" - echo -e " ${CYAN}CMAKE_CUDA_COMPILER=${install_path}/bin/nvcc${RESET}" - echo -e " ${CYAN}PATH includes ${install_path}/bin${RESET}" - echo -e " ${CYAN}LD_LIBRARY_PATH includes ${install_path}/lib64${RESET}" - echo -e " ${CYAN}LIBRARY_PATH includes ${install_path}/lib64${RESET}" - echo -e " ${CYAN}CPATH includes ${install_path}/include${RESET}" + if [[ -z "$cuda_version_dir" ]]; then + echo -e "${RED}Error: Could not find CUDA installation directory${RESET}" >&2 + exit 1 + fi + + local nvcc_path="${cuda_version_dir}/bin/nvcc.exe" + + # Convert paths to Windows format for outputs + local win_cuda_path + local win_nvcc_path + if command -v cygpath &>/dev/null; then + win_cuda_path=$(cygpath -w "$cuda_version_dir") + win_nvcc_path=$(cygpath -w "$nvcc_path") + else + # Fallback: convert /c/path to C:\path + win_cuda_path=$(echo "$cuda_version_dir" | sed 's|^/\([a-z]\)/|\U\1:/|' | sed 's|/|\\|g') + win_nvcc_path=$(echo "$nvcc_path" | sed 's|^/\([a-z]\)/|\U\1:/|' | sed 's|/|\\|g') + fi + + # Add CUDA to PATH (use Unix-style for bash) + echo "${cuda_version_dir}/bin" >> "${GITHUB_PATH}" + + # Set environment variables for GitHub Actions (use Windows-style paths) + if [[ -n "${GITHUB_ENV:-}" ]]; then + { + echo "CUDA_PATH=${win_cuda_path}" + echo "CUDA_HOME=${win_cuda_path}" + echo "CUDA_ROOT=${win_cuda_path}" + echo "CUDA_PATH_V${version//./_}=${win_cuda_path}" + echo "CMAKE_CUDA_COMPILER=${win_nvcc_path}" + } >> "${GITHUB_ENV}" + fi + + # Set outputs for GitHub Actions (use Windows-style paths) + if [[ -n "${GITHUB_OUTPUT:-}" ]]; then + { + echo "cuda-version=${version}" + echo "cuda-path=${win_cuda_path}" + echo "nvcc-path=${win_nvcc_path}" + } >> "${GITHUB_OUTPUT}" + fi + + echo -e "${GREEN}Environment variables configured:${RESET}" + echo -e " ${CYAN}CUDA_PATH=${win_cuda_path}${RESET}" + echo -e " ${CYAN}CUDA_HOME=${win_cuda_path}${RESET}" + echo -e " ${CYAN}CMAKE_CUDA_COMPILER=${win_nvcc_path}${RESET}" + echo -e " ${CYAN}PATH includes ${cuda_version_dir}/bin${RESET}" + else + # Linux: Use provided install path + # Add CUDA to PATH + echo "${install_path}/bin" >> "${GITHUB_PATH}" + + # Set environment variables for GitHub Actions + if [[ -n "${GITHUB_ENV:-}" ]]; then + { + echo "CUDA_PATH=${install_path}" + echo "CUDA_HOME=${install_path}" + echo "CUDA_ROOT=${install_path}" + echo "LD_LIBRARY_PATH=${install_path}/lib64:\${LD_LIBRARY_PATH:-}" + echo "LIBRARY_PATH=${install_path}/lib64:\${LIBRARY_PATH:-}" + echo "CPATH=${install_path}/include:\${CPATH:-}" + echo "CMAKE_CUDA_COMPILER=${install_path}/bin/nvcc" + } >> "${GITHUB_ENV}" + fi + + # Set outputs for GitHub Actions + if [[ -n "${GITHUB_OUTPUT:-}" ]]; then + { + echo "cuda-version=${version}" + echo "cuda-path=${install_path}" + echo "nvcc-path=${install_path}/bin/nvcc" + } >> "${GITHUB_OUTPUT}" + fi + + echo -e "${GREEN}Environment variables configured:${RESET}" + echo -e " ${CYAN}CUDA_PATH=${install_path}${RESET}" + echo -e " ${CYAN}CUDA_HOME=${install_path}${RESET}" + echo -e " ${CYAN}CUDA_ROOT=${install_path}${RESET}" + echo -e " ${CYAN}CMAKE_CUDA_COMPILER=${install_path}/bin/nvcc${RESET}" + echo -e " ${CYAN}PATH includes ${install_path}/bin${RESET}" + echo -e " ${CYAN}LD_LIBRARY_PATH includes ${install_path}/lib64${RESET}" + echo -e " ${CYAN}LIBRARY_PATH includes ${install_path}/lib64${RESET}" + echo -e " ${CYAN}CPATH includes ${install_path}/include${RESET}" + fi return 0 } @@ -212,31 +341,52 @@ if [[ -z "$CUDA_VERSION" ]]; then exit 1 fi -if [[ -z "$DRIVER_VERSION" ]]; then - echo -e "${RED}Error: --driver-version is required${RESET}" >&2 +# Detect OS +OS_TYPE=$(detect_os) + +# Skip on macOS +if [[ "$OS_TYPE" == "$OS_MACOS" ]]; then + echo -e "${YELLOW}macOS detected - CUDA Toolkit installation not supported on macOS${RESET}" + echo -e "${YELLOW}Skipping CUDA installation...${RESET}" + echo "" + echo -e "${GREEN}=== CUDA Toolkit Setup Skipped (macOS) ===${RESET}" + exit 0 +fi + +# Validate driver-version is provided for Linux (not needed for Windows network installer) +if [[ "$OS_TYPE" == "$OS_LINUX" ]] && [[ -z "$DRIVER_VERSION" ]]; then + echo -e "${RED}Error: --driver-version is required for Linux${RESET}" >&2 echo -e "${YELLOW}Example: --driver-version=550.54.15${RESET}" >&2 echo -e "${YELLOW}Find the correct driver version at: https://developer.nvidia.com/cuda-downloads${RESET}" >&2 exit 1 fi +# Set default install path if not provided +if [[ -z "$INSTALL_PATH" ]]; then + if [[ "$OS_TYPE" == "$OS_WINDOWS" ]]; then + # Windows default is handled by the installer itself + INSTALL_PATH="C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v${CUDA_VERSION}" + else + # Linux default + INSTALL_PATH="/usr/local/cuda" + fi +fi + # Main execution echo -e "${BLUE}=== CUDA Toolkit Setup ===${RESET}" +echo -e "${CYAN}Operating System: ${OS_TYPE}${RESET}" echo -e "${CYAN}CUDA Version: ${CUDA_VERSION}${RESET}" -echo -e "${CYAN}Driver Version: ${DRIVER_VERSION}${RESET}" +if [[ "$OS_TYPE" == "$OS_LINUX" ]]; then + echo -e "${CYAN}Driver Version: ${DRIVER_VERSION}${RESET}" +fi echo -e "${CYAN}Install Path: ${INSTALL_PATH}${RESET}" echo "" -# Check if running on Linux -if [[ "$(uname -s)" != "Linux" ]]; then - echo -e "${RED}Error: This action only supports Linux runners${RESET}" >&2 - exit 1 -fi - # Install CUDA -install_cuda "$CUDA_VERSION" "$DRIVER_VERSION" "$INSTALL_PATH" +install_cuda "$CUDA_VERSION" "$DRIVER_VERSION" "$INSTALL_PATH" "$OS_TYPE" # Setup environment -setup_environment "$INSTALL_PATH" "$CUDA_VERSION" +setup_environment "$INSTALL_PATH" "$CUDA_VERSION" "$OS_TYPE" echo "" echo -e "${GREEN}=== CUDA Toolkit Setup Complete ===${RESET}"