fix(build): PTX fallback when target GPU arch exceeds nvcc codegen #15
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: arch-matrix | |
| # Verifies the README-documented CUDA arch matrix stays buildable | |
| # under the SYCL build (XCHPLOT2_BUILD_CUDA=ON, the default when | |
| # nvcc is present). Each job sets CMAKE_CUDA_ARCHITECTURES to one | |
| # of the documented targets and runs cmake configure + builds the | |
| # CUDA TUs. No accelerator needed. | |
| # | |
| # Arch coverage mirrors the README "Common values" line: | |
| # 61 GTX 10-series (Pascal) — needs CUDA 12.x (12.9 last) | |
| # 75 Turing | |
| # 86 RTX 30-series (Ampere) | |
| # 89 RTX 40-series (Ada) — also the default | |
| # 120 RTX 50-series (Blackwell) — needs CUDA 12.8+ | |
| on: | |
| pull_request: | |
| paths-ignore: | |
| # Docs & metadata | |
| - '**.md' | |
| - 'docs/**' | |
| - 'LICENSE*' | |
| - '.gitignore' | |
| - '.gitattributes' | |
| - '.editorconfig' | |
| - '.markdownlint*' | |
| - '.github/dependabot.yml' | |
| - '.github/ISSUE_TEMPLATE/**' | |
| - '.github/PULL_REQUEST_TEMPLATE*' | |
| # Runtime scripts not exercised by the arch matrix (it runs | |
| # cmake configure + builds pos2_gpu_cuda_obj only). | |
| - 'scripts/test/**' | |
| - 'scripts/test-multi-gpu.sh' | |
| - 'scripts/build-container.sh' | |
| - 'scripts/install-container-deps.sh' | |
| # Containerfile / compose are install-matrix-only — arch | |
| # matrix uses a stock nvidia/cuda image and never touches them. | |
| - 'Containerfile' | |
| - 'compose.yaml' | |
| # Sibling CI workflows. | |
| - '.github/workflows/ci.yml' | |
| - '.github/workflows/install-matrix.yml' | |
| push: | |
| branches: [main] | |
| paths-ignore: | |
| - '**.md' | |
| - 'docs/**' | |
| - 'LICENSE*' | |
| - '.gitignore' | |
| - '.gitattributes' | |
| - '.editorconfig' | |
| - '.markdownlint*' | |
| - '.github/dependabot.yml' | |
| - '.github/ISSUE_TEMPLATE/**' | |
| - '.github/PULL_REQUEST_TEMPLATE*' | |
| - 'scripts/test/**' | |
| - 'scripts/test-multi-gpu.sh' | |
| - 'scripts/build-container.sh' | |
| - 'scripts/install-container-deps.sh' | |
| - 'Containerfile' | |
| - 'compose.yaml' | |
| - '.github/workflows/ci.yml' | |
| - '.github/workflows/install-matrix.yml' | |
| permissions: | |
| contents: read | |
| jobs: | |
| build: | |
| name: arch / sm_${{ matrix.arch }} | |
| runs-on: ubuntu-latest | |
| container: | |
| image: ${{ matrix.image }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - arch: 61 | |
| image: nvidia/cuda:12.9.1-devel-ubuntu24.04 | |
| - arch: 75 | |
| image: nvidia/cuda:13.0.1-devel-ubuntu24.04 | |
| - arch: 86 | |
| image: nvidia/cuda:13.0.1-devel-ubuntu24.04 | |
| - arch: 89 | |
| image: nvidia/cuda:13.0.1-devel-ubuntu24.04 | |
| - arch: 120 | |
| image: nvidia/cuda:12.9.1-devel-ubuntu24.04 | |
| steps: | |
| - name: Bootstrap apt + sudo stub (container runs as root) | |
| run: | | |
| apt-get update | |
| DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ | |
| ca-certificates curl git | |
| # scripts/install-deps.sh calls `sudo` throughout; we're | |
| # already root in the container, so wire `sudo` to exec the | |
| # rest of the args directly. Cheaper than `apt install sudo` | |
| # which pulls a chunk of policy / pam state we don't need. | |
| cat > /usr/local/bin/sudo <<'EOF' | |
| #!/bin/sh | |
| exec "$@" | |
| EOF | |
| chmod +x /usr/local/bin/sudo | |
| - name: Install rustup (with retries) — keygen-rs sub-build needs cargo | |
| run: | | |
| # curl with --retry: GitHub Actions has seen transient connect | |
| # failures to sh.rustup.rs. 5 attempts at 10s spacing covers | |
| # short outages without padding cold-cache jobs. | |
| # Done BEFORE install-deps.sh so that script's own rustup | |
| # branch (which has no retries) gets skipped via its | |
| # `command -v cargo` probe. | |
| curl --proto '=https' --tlsv1.2 -sSfL \ | |
| --retry 5 --retry-delay 10 --retry-all-errors \ | |
| https://sh.rustup.rs \ | |
| | sh -s -- -y --default-toolchain stable --profile minimal | |
| echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" | |
| - uses: actions/checkout@v5 | |
| - name: Cache /opt/adaptivecpp | |
| id: cache-adaptivecpp | |
| uses: actions/cache@v4 | |
| with: | |
| path: /opt/adaptivecpp | |
| # Key components — invalidate the cache when any of these change: | |
| # matrix.image LLVM version in the base image differs | |
| # between CUDA 12.9 and 13.0 → ABI-relevant | |
| # for AdaptiveCpp's built-against-LLVM bits | |
| # install-deps.sh ACPP_REF default + apt package list live | |
| # here; any edit means rebuild | |
| # Restore is best-effort; install-deps.sh detects an existing | |
| # /opt/adaptivecpp and skips its build, so a partial / stale | |
| # cache that lands the dir but is corrupt would only show as | |
| # a downstream link error — at which point bumping | |
| # install-deps.sh's hash naturally re-keys the cache. | |
| key: acpp-${{ matrix.image }}-${{ hashFiles('scripts/install-deps.sh') }} | |
| - name: Run scripts/install-deps.sh (LLVM/lld + AdaptiveCpp at /opt/adaptivecpp) | |
| run: | | |
| # cargo is already on PATH from the rustup step above, so | |
| # install-deps.sh's `if ! command -v cargo` guard skips its | |
| # own rustup install entirely. | |
| # Distro-aware bootstrap: apt-installs build-essential, cmake, | |
| # llvm-18 / clang-18 / lld-18, boost, then builds AdaptiveCpp | |
| # v25.10.0 from source at /opt/adaptivecpp. ~15-20 min cold, | |
| # ~2 min on a cache hit (the apt-installed LLVM bits still | |
| # need to land but the AdaptiveCpp build itself is skipped | |
| # because the dir already exists from cache restore). | |
| # --gpu nvidia tells it to skip the AMD-only ROCm headers | |
| # path (we're inside a nvidia/cuda image already). | |
| export PATH="$HOME/.cargo/bin:$PATH" | |
| if [ "${{ steps.cache-adaptivecpp.outputs.cache-hit }}" = "true" ]; then | |
| echo "[ci] AdaptiveCpp restored from cache; install-deps.sh" | |
| echo "[ci] will detect it at /opt/adaptivecpp and skip the build." | |
| fi | |
| bash scripts/install-deps.sh --gpu nvidia | |
| - name: cmake configure + build CUDA TUs (arch=${{ matrix.arch }}) | |
| run: | | |
| export PATH="$HOME/.cargo/bin:$PATH" | |
| # XCHPLOT2_BUILD_CUDA=ON exercises the CUDA path even though | |
| # we're not building the full SYCL binary here; the arch | |
| # matrix is about confirming nvcc accepts the target. | |
| # AdaptiveCpp is already installed at /opt/adaptivecpp by | |
| # install-deps.sh — CMake's probe picks it up automatically. | |
| cmake -B build -S . \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DXCHPLOT2_BUILD_CUDA=ON \ | |
| -DCMAKE_CUDA_ARCHITECTURES=${{ matrix.arch }} | |
| cmake --build build -j --target pos2_gpu_cuda_obj |