Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
355 changes: 355 additions & 0 deletions .github/workflows/spirv-ci-linux-amd-staging.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,355 @@
# Linux variant of the SPIRV CI: builds LLVM/Clang/translator/Comgr in
# one job and runs SPIRV-relevant test suites in parallel test jobs that
# consume a GHA artifact uploaded by the build job.

name: SPIRV Compiler CI - Linux - amd-staging

on:
workflow_call:

jobs:
# =====================================================================
# Build LLVM + Clang + amd-llvm-spirv + device-libs + Comgr.
# Strip binaries and upload the build trees as a single artifact for
# the test jobs to consume.
# =====================================================================
build:
name: Build
runs-on: azure-linux-scale-rocm
timeout-minutes: 120
container:
image: ghcr.io/rocm/therock_build_manylinux_x86_64@sha256:702a5133851e6d1daf1207d2c9fbb01c2667914a5b6dc5a01faeb3ce66ea6421
steps:
# ---- Checkout ---------------------------------------------------------
# llvm-project at PR head (this repo) provides LLVM/Clang/LLD + amd/
# subprojects (device-libs, comgr). The SPIRV translator is pinned to
# amd-staging and overlaid in-tree under llvm/projects/.
- name: Checkout llvm-project (PR head)
# On pull_request events: PR head from the (possibly fork) head repo.
# On workflow_dispatch: the branch the dispatch was on.
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
ref: ${{ github.event.pull_request.head.sha || github.sha }}
path: llvm-project
fetch-depth: 1
persist-credentials: false

- name: Checkout SPIRV-LLVM-Translator (amd-staging)
# Pinned to amd-staging because llvm-project PRs don't change
# the translator. Without an explicit repository/ref, checkout
# defaults to the workflow's own repo (llvm-project) and clobbers
# the translator path with llvm-project content.
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: ROCm/SPIRV-LLVM-Translator
ref: amd-staging
path: llvm-project/llvm/projects/SPIRV-LLVM-Translator
fetch-depth: 1
persist-credentials: false

# ---- Build LLVM + Clang + LLD + in-tree SPIRV translator --------------
- name: Configure LLVM
run: |
cmake -G Ninja -S llvm-project/llvm -B build \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_ASSERTIONS=ON \
-DLLVM_ENABLE_PROJECTS="clang;lld" \
-DLLVM_TARGETS_TO_BUILD="AMDGPU;X86;SPIRV" \
-DLLVM_INCLUDE_TESTS=ON \
-DLLVM_INSTALL_GTEST=ON \
-DLLVM_LIT_ARGS="-sv --no-progress-bar"

- name: Build LLVM + Clang + amd-llvm-spirv + test deps
# *-test-depends pull in all tools needed for lit (FileCheck, not,
# llc, llvm-*, clang, opt, etc.) and stay current with upstream.
run: ninja -C build llvm-test-depends clang-test-depends amd-llvm-spirv

# ---- Build device-libs (standalone, against built LLVM) --------------
- name: Configure device-libs
run: |
cmake -G Ninja -S llvm-project/amd/device-libs -B build-device-libs \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH=$PWD/build \
-DLLVM_DIR=$PWD/build/lib/cmake/llvm

- name: Build device-libs
run: ninja -C build-device-libs

# ---- Build Comgr (standalone, against built LLVM + device-libs) ------
- name: Configure Comgr
# LLVM_EXTERNAL_SPIRV_LLVM_TRANSLATOR_SOURCE_DIR points Comgr at
# the in-tree translator headers so COMGR_SPIRV_TRANSLATOR_AVAILABLE
# turns ON (otherwise translator-dependent lit tests are UNSUPPORTED).
run: |
cmake -G Ninja -S llvm-project/amd/comgr -B build-comgr \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH="$PWD/build;$PWD/build-device-libs" \
-DLLVM_DIR=$PWD/build/lib/cmake/llvm \
-DLLVM_EXTERNAL_SPIRV_LLVM_TRANSLATOR_SOURCE_DIR=$PWD/llvm-project/llvm/projects/SPIRV-LLVM-Translator \
-DBUILD_TESTING=ON

- name: Build Comgr
run: ninja -C build-comgr amd_comgr

# ---- Strip + upload artifact -----------------------------------------
# Strip binaries to keep the artifact under GHA's 10GB cap and shorten
# upload/download time. Tests don't need debug symbols. `--strip-unneeded`
# preserves dynamic symbols needed at link/load time.
- name: Strip binaries
run: |
find build build-comgr build-device-libs \
-type f \( -executable -o -name '*.so*' -o -name '*.a' \) \
-exec strip --strip-unneeded {} + 2>/dev/null || true

# Tar before upload: actions/upload-artifact@v4 strips +x bits and
# excludes hidden files (loses FetchContent .git dirs).
- name: Tar build trees
run: tar -cf linux-build-tree.tar build build-comgr build-device-libs

- name: Upload build tree artifact
uses: actions/upload-artifact@v4
with:
name: linux-build-tree
path: linux-build-tree.tar
retention-days: 1
compression-level: 6
if-no-files-found: error

# =====================================================================
# Test - SPIRV translator lit (with PR-head vs amd-staging baseline diff)
# =====================================================================
# Non-blocking: upstream Khronos breaks ~1 translator lit test per week
# (spirv-val drift, LLVM IR changes vs DebugInfo tests, DCE). Their fixes
# typically land within a day; our daily upstream-merge cron pulls them
# in. Blocking here would gate unrelated PRs during those windows. The
# baseline run partitions failures into new / fixed / pre-existing so
# AMD-side regressions stay visible.
test_translator_lit:
name: Test SPIRV translator lit
needs: build
runs-on: azure-linux-scale-rocm
timeout-minutes: 30
container:
image: ghcr.io/rocm/therock_build_manylinux_x86_64@sha256:702a5133851e6d1daf1207d2c9fbb01c2667914a5b6dc5a01faeb3ce66ea6421
permissions:
contents: read

steps:
- name: Checkout llvm-project (PR head)
# On pull_request events: PR head from the (possibly fork) head repo.
# On workflow_dispatch: the branch the dispatch was on.
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
ref: ${{ github.event.pull_request.head.sha || github.sha }}
path: llvm-project
fetch-depth: 1
persist-credentials: false

- name: Checkout SPIRV-LLVM-Translator (amd-staging)
# Pinned to amd-staging because llvm-project PRs don't change
# the translator. Without an explicit repository/ref, checkout
# defaults to the workflow's own repo (llvm-project) and clobbers
# the translator path with llvm-project content.
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: ROCm/SPIRV-LLVM-Translator
ref: amd-staging
path: llvm-project/llvm/projects/SPIRV-LLVM-Translator
fetch-depth: 1
persist-credentials: false

- name: Download build tree artifact
uses: actions/download-artifact@v4
with:
name: linux-build-tree

# touch build.ninja so it's newer than CMakeCache.txt — without it
# tar -m's per-file mtimes can trigger a cmake regen + cascade rebuild.
- name: Untar build trees
run: |
tar -xmf linux-build-tree.tar
touch build/build.ninja build-comgr/build.ninja build-device-libs/build.ninja

- name: Test - SPIRV Translator (check-amd-llvm-spirv) [PR head]
id: check_spirv_xlator
continue-on-error: true
run: |
set -o pipefail
ninja -C build check-amd-llvm-spirv 2>&1 | tee build/check-amd-llvm-spirv.log

- name: Capture PR head translator failures
if: always()
run: |
grep -oE '^FAIL: LLVM_SPIRV :: \S+' build/check-amd-llvm-spirv.log \
| sort -u > build/spirv-fails-pr.txt || true
echo "PR head failures:"; cat build/spirv-fails-pr.txt

- name: Switch llvm-project to amd-staging tip for baseline
# PRs on llvm-project change llvm/clang/lld, not the translator, so the
# baseline-diff swap target is llvm-project. Use explicit upstream URL
# because `origin` may be a fork on PR runs.
if: always()
run: |
cd llvm-project
git fetch --depth=1 https://github.com/ROCm/llvm-project.git amd-staging
git checkout FETCH_HEAD

- name: Test - SPIRV Translator [baseline amd-staging]
# Re-run the lit suite with llvm-project at amd-staging tip to compute
# the per-PR delta vs PR-head failures. Incremental rebuild — only
# changed LLVM libs are recompiled and the translator is relinked.
if: always()
id: check_spirv_baseline
continue-on-error: true
run: |
set -o pipefail
# Re-configure to pick up any CMakeLists / file-list changes in the swap
cmake -G Ninja -S llvm-project/llvm -B build
ninja -C build check-amd-llvm-spirv 2>&1 \
| tee build/check-amd-llvm-spirv-baseline.log

- name: Capture baseline translator failures
# Split from the lit step so a non-zero ninja exit (lit failures +
# set -o pipefail under bash -e) doesn't skip this grep.
if: always()
run: |
grep -oE '^FAIL: LLVM_SPIRV :: \S+' build/check-amd-llvm-spirv-baseline.log \
| sort -u > build/spirv-fails-baseline.txt || true
echo "Baseline failures:"; cat build/spirv-fails-baseline.txt

# Fail the job on real regressions (PR head FAILs that aren't on
# amd-staging baseline). Pre-existing baseline failures don't block.
- name: Gate - new translator lit failures
if: always()
run: |
if [ ! -f build/spirv-fails-pr.txt ] || [ ! -f build/spirv-fails-baseline.txt ]; then
echo "::warning::Could not compute new-failure delta (missing pr.txt or baseline.txt); not gating."
exit 0
fi
new=$(comm -23 build/spirv-fails-pr.txt build/spirv-fails-baseline.txt)
if [ -n "$new" ]; then
count=$(printf '%s\n' "$new" | wc -l)
echo "::error::$count new translator lit failure(s) introduced by this PR:"
printf '%s\n' "$new" | sed 's/^/::error:: /'
exit 1
fi
echo "No new translator lit failures vs amd-staging baseline."

# =====================================================================
# Test - LLVM SPIRV codegen lit suite
# =====================================================================
test_codegen:
name: Test LLVM SPIRV codegen
needs: build
runs-on: azure-linux-scale-rocm
timeout-minutes: 15
container:
image: ghcr.io/rocm/therock_build_manylinux_x86_64@sha256:702a5133851e6d1daf1207d2c9fbb01c2667914a5b6dc5a01faeb3ce66ea6421

steps:
- name: Checkout llvm-project (PR head)
# On pull_request events: PR head from the (possibly fork) head repo.
# On workflow_dispatch: the branch the dispatch was on.
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
ref: ${{ github.event.pull_request.head.sha || github.sha }}
path: llvm-project
fetch-depth: 1
persist-credentials: false

- name: Checkout SPIRV-LLVM-Translator (amd-staging)
# Pinned to amd-staging because llvm-project PRs don't change
# the translator. Without an explicit repository/ref, checkout
# defaults to the workflow's own repo (llvm-project) and clobbers
# the translator path with llvm-project content.
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: ROCm/SPIRV-LLVM-Translator
ref: amd-staging
path: llvm-project/llvm/projects/SPIRV-LLVM-Translator
fetch-depth: 1
persist-credentials: false

- name: Download build tree artifact
uses: actions/download-artifact@v4
with:
name: linux-build-tree

# touch build.ninja so it's newer than CMakeCache.txt — without it
# tar -m's per-file mtimes can trigger a cmake regen + cascade rebuild.
- name: Untar build trees
run: |
tar -xmf linux-build-tree.tar
touch build/build.ninja build-comgr/build.ninja build-device-libs/build.ninja

- name: Test - LLVM SPIRV backend (check-llvm-codegen-spirv)
run: ninja -C build check-llvm-codegen-spirv

# =====================================================================
# Test - Comgr (lit + gtest + ctest)
# =====================================================================
test_comgr:
name: Test Comgr
needs: build
runs-on: azure-linux-scale-rocm
timeout-minutes: 30
container:
image: ghcr.io/rocm/therock_build_manylinux_x86_64@sha256:702a5133851e6d1daf1207d2c9fbb01c2667914a5b6dc5a01faeb3ce66ea6421

steps:
- name: Checkout llvm-project (PR head)
# On pull_request events: PR head from the (possibly fork) head repo.
# On workflow_dispatch: the branch the dispatch was on.
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
ref: ${{ github.event.pull_request.head.sha || github.sha }}
path: llvm-project
fetch-depth: 1
persist-credentials: false

- name: Checkout SPIRV-LLVM-Translator (amd-staging)
# Pinned to amd-staging because llvm-project PRs don't change
# the translator. Without an explicit repository/ref, checkout
# defaults to the workflow's own repo (llvm-project) and clobbers
# the translator path with llvm-project content.
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: ROCm/SPIRV-LLVM-Translator
ref: amd-staging
path: llvm-project/llvm/projects/SPIRV-LLVM-Translator
fetch-depth: 1
persist-credentials: false

- name: Download build tree artifact
uses: actions/download-artifact@v4
with:
name: linux-build-tree

# touch build.ninja so it's newer than CMakeCache.txt — without it
# tar -m's per-file mtimes can trigger a cmake regen + cascade rebuild.
- name: Untar build trees
run: |
tar -xmf linux-build-tree.tar
touch build/build.ninja build-comgr/build.ninja build-device-libs/build.ninja

- name: Test - Comgr (check-comgr)
# check-comgr depends on test-lit (runs lit suite) and test-unit
# (runs gtest binaries via its COMMAND block), then runs ctest for
# the legacy C tests. Single target = all three test layers.
id: check_comgr
run: ninja -C build-comgr check-comgr

- name: Show failed Comgr ctest output
# check-comgr invokes ctest without --output-on-failure, so failures
# show "***Failed" with no stderr. Re-run any failed cases verbosely
# and redirect comgr's internal log buffer to stderr so clang errors
# from inside amd_comgr_do_action() surface (otherwise comgr just
# returns AMD_COMGR_STATUS_ERROR with no detail).
if: failure() && steps.check_comgr.conclusion == 'failure'
env:
AMD_COMGR_REDIRECT_LOGS: stderr
run: ctest --test-dir build-comgr --output-on-failure --rerun-failed
Loading
Loading