Skip to content

fix(build): PTX fallback when target GPU arch exceeds nvcc codegen #15

fix(build): PTX fallback when target GPU arch exceeds nvcc codegen

fix(build): PTX fallback when target GPU arch exceeds nvcc codegen #15

Workflow file for this run

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