From 3cd1a387eea12b8f2b128ff94949e6215667d989 Mon Sep 17 00:00:00 2001 From: Jacob Lambert Date: Sat, 9 May 2026 09:32:32 -0700 Subject: [PATCH 1/6] [CI] Split spirv-ci into Build + parallel Test jobs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Today the SPIRV CI is one mega-job (Linux Build & Test) that builds the LLVM/translator/Comgr stack and runs all lit suites sequentially. As we add more test categories (rocm-examples, hip-tests per the SPIRV Automated Testing Status confluence page), one mega-check is too coarse — a failing suite hides the others, can't selectively re-run, and the required-check is all-or-nothing. Split into 4 jobs: Linux Build (required) ├─► Linux Test - SPIRV translator lit (informational, baseline-diff) ├─► Linux Test - LLVM SPIRV codegen (informational) └─► Linux Test - Comgr (informational) Build uploads `build/`, `build-comgr/`, `build-device-libs/` (after strip --strip-unneeded) as a single GHA artifact. Test jobs do a fresh checkout of source trees + download the artifact. Source isn't shipped in the artifact (cleaner: artifact = build outputs, checkout = source). Translator-lit baseline-diff (PR head vs amd-staging) preserved as-is — runs in the translator-lit test job: download artifact, run lit at PR head, swap translator src to amd-staging tip, cmake-reconfigure + ninja-incremental + lit-rerun, post sticky comment with new/fixed/ pre-existing partition. Translator checkout in this job uses fetch-depth: 0 so the baseline `git checkout amd-staging` works. Tests stay informational (per design discussion): promote to required individually as each suite stabilizes. Only Linux Build is required. Pragmatic deviations from TheRock conventions: - GHA artifacts (not S3) for transport — no OIDC/IAM access here yet. Will swap to S3 patterns (post_build_upload.py / fetch_artifacts.py) when this workflow moves into TheRock. Job graph + naming match TheRock so the swap is mechanical. - "Linux" prefix on job names — TheRock uses workflow-file-as-platform convention, but we keep the prefix consistent with the prior rename and our future Windows expansion plans. ACTION REQUIRED on merge: update the amd-staging-psdb ruleset's required-check context from "Linux Build & Test" → "Linux Build". Without it the old rule will dangle (no job named "Linux Build & Test" exists anymore) and PRs would block on a permanently-pending placeholder. --- .github/workflows/spirv-ci.yml | 179 +++++++++++++++++++++++++++++---- 1 file changed, 159 insertions(+), 20 deletions(-) diff --git a/.github/workflows/spirv-ci.yml b/.github/workflows/spirv-ci.yml index 923258dc0..61a87a107 100644 --- a/.github/workflows/spirv-ci.yml +++ b/.github/workflows/spirv-ci.yml @@ -1,9 +1,22 @@ # SPIRV-focused CI for the ROCm LLVM compiler stack. # # Builds LLVM + Clang + LLD with the SPIRV translator in-tree, then builds -# device-libs and Comgr standalone, and runs SPIRV-relevant lit and gtest -# suites. Catches breakage in the compiler / SPIRV translator that would -# fail downstream Comgr testing. +# device-libs and Comgr standalone (one job), and runs SPIRV-relevant lit +# and gtest suites in parallel test jobs that download the build outputs +# as a GHA artifact. Catches breakage in the compiler / SPIRV translator +# that would fail downstream Comgr testing. +# +# Job structure (4 check_runs in the PR rollup): +# - Linux Build (required) +# - Linux Test - SPIRV translator lit (informational, posts baseline-diff comment) +# - Linux Test - LLVM SPIRV codegen (informational) +# - Linux Test - Comgr (informational) +# +# Artifact (`linux-build-tree`) carries `build/`, `build-comgr/`, and +# `build-device-libs/` between Build and the Test jobs. Source trees are +# fresh-checked-out in each test job (cleaner than shipping .git in the +# artifact). GHA artifacts are the interim transport; will swap to S3 +# when this workflow moves into TheRock. # # This is a prototype living in SPIRV-LLVM-Translator. Plan: once stable, # mirror into ROCm/llvm-project amd-staging, then promote to a TheRock @@ -18,15 +31,23 @@ on: permissions: contents: read - pull-requests: write # for the translator lit-failure summary comment + pull-requests: write # for the translator lit baseline-diff comment concurrency: group: ${{ github.workflow }}-${{ github.event.number || github.sha }} cancel-in-progress: true +env: + CONTAINER_IMAGE: ghcr.io/rocm/therock_build_manylinux_x86_64@sha256:702a5133851e6d1daf1207d2c9fbb01c2667914a5b6dc5a01faeb3ce66ea6421 + jobs: - build_and_test: - name: Linux Build & Test + # ===================================================================== + # 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: Linux Build runs-on: azure-linux-scale-rocm timeout-minutes: 120 container: @@ -97,17 +118,69 @@ jobs: - name: Build Comgr run: ninja -C build-comgr amd_comgr - # ---- Tests ------------------------------------------------------------ - # Each suite is its own step so failures are individually identifiable - # in the PR check rollup. Add new suites as new steps below. + # ---- 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 + + - name: Upload build tree artifact + uses: actions/upload-artifact@v4 + with: + name: linux-build-tree + path: | + build + build-comgr + build-device-libs + 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-spirv-translator-lit: + name: Linux 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 + + steps: + - name: Checkout llvm-project (amd-staging) + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + repository: ROCm/llvm-project + ref: amd-staging + path: llvm-project + fetch-depth: 1 + persist-credentials: false + + - name: Checkout SPIRV-LLVM-Translator (PR head) + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + path: llvm-project/llvm/projects/SPIRV-LLVM-Translator + # fetch full history so we can checkout amd-staging tip later for the baseline run + fetch-depth: 0 + persist-credentials: false + + - name: Download build tree artifact + uses: actions/download-artifact@v4 + with: + name: linux-build-tree - name: Test - SPIRV Translator (check-amd-llvm-spirv) [PR head] - # 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 below partitions failures into - # new / fixed / pre-existing so AMD-side regressions stay visible. id: check_spirv_xlator continue-on-error: true run: | @@ -115,14 +188,14 @@ jobs: ninja -C build check-amd-llvm-spirv 2>&1 | tee build/check-amd-llvm-spirv.log - name: Capture PR head translator failures - if: github.event_name == 'pull_request' && always() + 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 translator to amd-staging tip for baseline - if: github.event_name == 'pull_request' && always() + if: always() run: | cd llvm-project/llvm/projects/SPIRV-LLVM-Translator git fetch --depth=1 origin amd-staging @@ -132,7 +205,7 @@ jobs: # Re-run the lit suite with the translator at amd-staging tip so the # comment script can compute the per-PR delta (new vs fixed vs # pre-existing). Incremental rebuild — only translator objects change. - if: github.event_name == 'pull_request' && always() + if: always() id: check_spirv_baseline continue-on-error: true run: | @@ -145,14 +218,14 @@ jobs: - 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: github.event_name == 'pull_request' && always() + 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 - name: Post translator lit summary to PR - if: github.event_name == 'pull_request' && always() + if: always() uses: actions/github-script@v7 with: script: | @@ -217,9 +290,75 @@ jobs: }); } + # ===================================================================== + # Test - LLVM SPIRV codegen lit suite + # ===================================================================== + test-llvm-codegen-spirv: + name: Linux 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 (amd-staging) + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + repository: ROCm/llvm-project + ref: amd-staging + path: llvm-project + fetch-depth: 1 + persist-credentials: false + + - name: Checkout SPIRV-LLVM-Translator (PR head) + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + 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 + - 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: Linux 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 (amd-staging) + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + repository: ROCm/llvm-project + ref: amd-staging + path: llvm-project + fetch-depth: 1 + persist-credentials: false + + - name: Checkout SPIRV-LLVM-Translator (PR head) + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + 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 + - 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 From f9cf123fe916381554cbc5a0b11961990df6cb3e Mon Sep 17 00:00:00 2001 From: Jacob Lambert Date: Sat, 9 May 2026 10:03:50 -0700 Subject: [PATCH 2/6] [CI] Refactor into 2-file workflow_call chain (TheRock conventions) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirrors TheRock's Multi-Arch CI shape: a top-level dispatcher with platform-variant jobs that call reusable per-platform workflows. The Linux variant is byte-isolated so adding Windows later is just a new file + dispatcher entry. Files: - spirv-ci.yml — top-level dispatcher (~25 lines), byte-identical across both this repo and ROCm/llvm-project. Triggers on pull_request + workflow_dispatch. Sole job (linux_release, name Linux::release) calls spirv-ci-linux.yml. - spirv-ci-linux.yml — workflow_call. Holds the build job + 3 test jobs (factored from the prior single spirv-ci.yml). Rendered check_run names in the PR rollup (workflow_call composes the slash hierarchy): - SPIRV Compiler CI / Linux::release / Build - SPIRV Compiler CI / Linux::release / Test SPIRV translator lit - SPIRV Compiler CI / Linux::release / Test LLVM SPIRV codegen - SPIRV Compiler CI / Linux::release / Test Comgr Convention alignment with TheRock (verified against .github/workflows/multi_arch_ci.yml, multi_arch_ci_linux.yml and the rest of the workflow set): - Top-level workflow name Title Case, no branch suffix - Reusable workflow has its own descriptive name - snake_case job IDs, separate display name field - No literal slashes in job names — slashes come from workflow_call - concurrency: only on dispatcher, not on workflow_call - secrets: inherit at the dispatcher → variant call - permissions read-only at workflow level; pull-requests: write escalated only on the translator-lit job that posts the comment - workflow_dispatch alongside pull_request — Multi-Arch's check names don't get the "(pull_request)" suffix even with both triggers, so the disambiguation bug we hit before is sidestepped by the workflow_call structure - Container image pinned with @sha256: ACTION REQUIRED on merge: update the amd-staging-psdb ruleset's required-check context from "Linux Build" → "Linux::release / Build". Without it the dangling rule blocks PRs on a permanently-pending placeholder. --- .github/workflows/spirv-ci-linux.yml | 348 +++++++++++++++++++++++++ .github/workflows/spirv-ci.yml | 372 +-------------------------- 2 files changed, 357 insertions(+), 363 deletions(-) create mode 100644 .github/workflows/spirv-ci-linux.yml diff --git a/.github/workflows/spirv-ci-linux.yml b/.github/workflows/spirv-ci-linux.yml new file mode 100644 index 000000000..0e3f4891c --- /dev/null +++ b/.github/workflows/spirv-ci-linux.yml @@ -0,0 +1,348 @@ +# 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 + +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 amd-staging tip provides the host LLVM/Clang/LLD plus + # the amd/ subprojects (device-libs, comgr). The SPIRV translator PR + # head is overlaid in-tree under llvm/projects/. + - name: Checkout llvm-project (amd-staging) + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + repository: ROCm/llvm-project + ref: amd-staging + path: llvm-project + fetch-depth: 1 + persist-credentials: false + + - name: Checkout SPIRV-LLVM-Translator (PR head) + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + 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 + + - name: Upload build tree artifact + uses: actions/upload-artifact@v4 + with: + name: linux-build-tree + path: | + build + build-comgr + build-device-libs + 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 + pull-requests: write # for the baseline-diff sticky comment + + steps: + - name: Checkout llvm-project (amd-staging) + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + repository: ROCm/llvm-project + ref: amd-staging + path: llvm-project + fetch-depth: 1 + persist-credentials: false + + - name: Checkout SPIRV-LLVM-Translator (PR head) + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + path: llvm-project/llvm/projects/SPIRV-LLVM-Translator + # fetch full history so we can checkout amd-staging tip later for the baseline run + fetch-depth: 0 + persist-credentials: false + + - name: Download build tree artifact + uses: actions/download-artifact@v4 + with: + name: linux-build-tree + + - 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 translator to amd-staging tip for baseline + if: always() + run: | + cd llvm-project/llvm/projects/SPIRV-LLVM-Translator + git fetch --depth=1 origin amd-staging + git checkout FETCH_HEAD + + - name: Test - SPIRV Translator [baseline amd-staging] + # Re-run the lit suite with the translator at amd-staging tip so the + # comment script can compute the per-PR delta (new vs fixed vs + # pre-existing). Incremental rebuild — only translator objects change. + 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 + + - name: Post translator lit summary to PR + if: always() + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const marker = ''; + const read = (p) => { + try { return fs.readFileSync(p, 'utf8').split('\n').filter(Boolean); } + catch { return null; } + }; + const prList = read('build/spirv-fails-pr.txt'); + const baseList = read('build/spirv-fails-baseline.txt'); + const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; + const fmt = (xs) => xs.length ? '```\n' + xs.join('\n') + '\n```' : '_(none)_'; + + let body; + if (!prList) { + body = `${marker}\n⚠️ **SPIRV translator lit suite**: PR run did not produce a result (see [run](${runUrl})).`; + } else if (!baseList) { + body = prList.length === 0 + ? `${marker}\n✅ **SPIRV translator lit suite**: all tests passing on PR head. (Baseline comparison unavailable.)` + : `${marker}\n⚠️ **SPIRV translator lit suite**: ${prList.length} failing on PR head; baseline comparison unavailable (see [run](${runUrl})).\n\n
Failing tests\n\n${fmt(prList)}\n
`; + } else { + const prSet = new Set(prList); + const baseSet = new Set(baseList); + const newFails = prList.filter(t => !baseSet.has(t)); + const fixed = baseList.filter(t => !prSet.has(t)); + const common = prList.filter(t => baseSet.has(t)); + + let headline; + if (newFails.length === 0 && fixed.length === 0 && common.length === 0) { + headline = `✅ **SPIRV translator lit suite**: clean on both PR head and \`amd-staging\` baseline.`; + } else if (newFails.length > 0) { + headline = `🔴 **${newFails.length} new translator lit failure${newFails.length === 1 ? '' : 's'}** introduced by this PR (non-blocking; see [run](${runUrl})).`; + } else if (fixed.length > 0 && common.length === 0) { + headline = `🟢 **SPIRV translator lit suite**: this PR fixes ${fixed.length} test${fixed.length === 1 ? '' : 's'} that fail on \`amd-staging\`. No remaining failures.`; + } else if (fixed.length > 0) { + headline = `🟢 This PR fixes ${fixed.length} translator lit test${fixed.length === 1 ? '' : 's'} (vs \`amd-staging\` baseline). ${common.length} pre-existing failure${common.length === 1 ? '' : 's'} remain.`; + } else { + headline = `⚠️ **${common.length} pre-existing translator lit failure${common.length === 1 ? '' : 's'}** on baseline; not caused by this PR (see [run](${runUrl})).`; + } + + body = `${marker}\n${headline}\n\n` + + ` 0 ? ' open' : ''}>🔴 New failures (${newFails.length}) — likely caused by this PR\n\n${fmt(newFails)}\n\n\n` + + `
🟢 Fixed by this PR (${fixed.length}) — failing on baseline, passing here\n\n${fmt(fixed)}\n
\n\n` + + `
⚠️ Pre-existing on \`amd-staging\` (${common.length})\n\n${fmt(common)}\n
`; + } + + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, repo: context.repo.repo, + issue_number: context.payload.pull_request.number, + }); + const existing = comments.find(c => c.body && c.body.includes(marker)); + if (existing) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, repo: context.repo.repo, + comment_id: existing.id, body, + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, repo: context.repo.repo, + issue_number: context.payload.pull_request.number, body, + }); + } + + # ===================================================================== + # 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 (amd-staging) + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + repository: ROCm/llvm-project + ref: amd-staging + path: llvm-project + fetch-depth: 1 + persist-credentials: false + + - name: Checkout SPIRV-LLVM-Translator (PR head) + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + 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 + + - 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 (amd-staging) + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + repository: ROCm/llvm-project + ref: amd-staging + path: llvm-project + fetch-depth: 1 + persist-credentials: false + + - name: Checkout SPIRV-LLVM-Translator (PR head) + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + 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 + + - 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 diff --git a/.github/workflows/spirv-ci.yml b/.github/workflows/spirv-ci.yml index 61a87a107..6e8e2de6d 100644 --- a/.github/workflows/spirv-ci.yml +++ b/.github/workflows/spirv-ci.yml @@ -1,378 +1,24 @@ -# SPIRV-focused CI for the ROCm LLVM compiler stack. -# -# Builds LLVM + Clang + LLD with the SPIRV translator in-tree, then builds -# device-libs and Comgr standalone (one job), and runs SPIRV-relevant lit -# and gtest suites in parallel test jobs that download the build outputs -# as a GHA artifact. Catches breakage in the compiler / SPIRV translator -# that would fail downstream Comgr testing. -# -# Job structure (4 check_runs in the PR rollup): -# - Linux Build (required) -# - Linux Test - SPIRV translator lit (informational, posts baseline-diff comment) -# - Linux Test - LLVM SPIRV codegen (informational) -# - Linux Test - Comgr (informational) -# -# Artifact (`linux-build-tree`) carries `build/`, `build-comgr/`, and -# `build-device-libs/` between Build and the Test jobs. Source trees are -# fresh-checked-out in each test job (cleaner than shipping .git in the -# artifact). GHA artifacts are the interim transport; will swap to S3 -# when this workflow moves into TheRock. -# -# This is a prototype living in SPIRV-LLVM-Translator. Plan: once stable, -# mirror into ROCm/llvm-project amd-staging, then promote to a TheRock -# stage-based workflow. +# Top-level dispatcher for the SPIRV-focused CI on amd-staging. +# Dispatches to per-platform reusable workflows. Add Windows by adding +# a windows_release job + spirv-ci-windows.yml. -name: SPIRV CI - amd-staging +name: SPIRV Compiler CI on: pull_request: branches: [amd-staging] types: [opened, synchronize, reopened, labeled] + workflow_dispatch: permissions: contents: read - pull-requests: write # for the translator lit baseline-diff comment concurrency: group: ${{ github.workflow }}-${{ github.event.number || github.sha }} cancel-in-progress: true -env: - CONTAINER_IMAGE: ghcr.io/rocm/therock_build_manylinux_x86_64@sha256:702a5133851e6d1daf1207d2c9fbb01c2667914a5b6dc5a01faeb3ce66ea6421 - 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: Linux 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 amd-staging tip provides the host LLVM/Clang/LLD plus - # the amd/ subprojects (device-libs, comgr). The SPIRV translator PR - # head is overlaid in-tree under llvm/projects/. - - name: Checkout llvm-project (amd-staging) - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - repository: ROCm/llvm-project - ref: amd-staging - path: llvm-project - fetch-depth: 1 - persist-credentials: false - - - name: Checkout SPIRV-LLVM-Translator (PR head) - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - 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 - - - name: Upload build tree artifact - uses: actions/upload-artifact@v4 - with: - name: linux-build-tree - path: | - build - build-comgr - build-device-libs - 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-spirv-translator-lit: - name: Linux 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 - - steps: - - name: Checkout llvm-project (amd-staging) - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - repository: ROCm/llvm-project - ref: amd-staging - path: llvm-project - fetch-depth: 1 - persist-credentials: false - - - name: Checkout SPIRV-LLVM-Translator (PR head) - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - path: llvm-project/llvm/projects/SPIRV-LLVM-Translator - # fetch full history so we can checkout amd-staging tip later for the baseline run - fetch-depth: 0 - persist-credentials: false - - - name: Download build tree artifact - uses: actions/download-artifact@v4 - with: - name: linux-build-tree - - - 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 translator to amd-staging tip for baseline - if: always() - run: | - cd llvm-project/llvm/projects/SPIRV-LLVM-Translator - git fetch --depth=1 origin amd-staging - git checkout FETCH_HEAD - - - name: Test - SPIRV Translator [baseline amd-staging] - # Re-run the lit suite with the translator at amd-staging tip so the - # comment script can compute the per-PR delta (new vs fixed vs - # pre-existing). Incremental rebuild — only translator objects change. - 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 - - - name: Post translator lit summary to PR - if: always() - uses: actions/github-script@v7 - with: - script: | - const fs = require('fs'); - const marker = ''; - const read = (p) => { - try { return fs.readFileSync(p, 'utf8').split('\n').filter(Boolean); } - catch { return null; } - }; - const prList = read('build/spirv-fails-pr.txt'); - const baseList = read('build/spirv-fails-baseline.txt'); - const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; - const fmt = (xs) => xs.length ? '```\n' + xs.join('\n') + '\n```' : '_(none)_'; - - let body; - if (!prList) { - body = `${marker}\n⚠️ **SPIRV translator lit suite**: PR run did not produce a result (see [run](${runUrl})).`; - } else if (!baseList) { - body = prList.length === 0 - ? `${marker}\n✅ **SPIRV translator lit suite**: all tests passing on PR head. (Baseline comparison unavailable.)` - : `${marker}\n⚠️ **SPIRV translator lit suite**: ${prList.length} failing on PR head; baseline comparison unavailable (see [run](${runUrl})).\n\n
Failing tests\n\n${fmt(prList)}\n
`; - } else { - const prSet = new Set(prList); - const baseSet = new Set(baseList); - const newFails = prList.filter(t => !baseSet.has(t)); - const fixed = baseList.filter(t => !prSet.has(t)); - const common = prList.filter(t => baseSet.has(t)); - - let headline; - if (newFails.length === 0 && fixed.length === 0 && common.length === 0) { - headline = `✅ **SPIRV translator lit suite**: clean on both PR head and \`amd-staging\` baseline.`; - } else if (newFails.length > 0) { - headline = `🔴 **${newFails.length} new translator lit failure${newFails.length === 1 ? '' : 's'}** introduced by this PR (non-blocking; see [run](${runUrl})).`; - } else if (fixed.length > 0 && common.length === 0) { - headline = `🟢 **SPIRV translator lit suite**: this PR fixes ${fixed.length} test${fixed.length === 1 ? '' : 's'} that fail on \`amd-staging\`. No remaining failures.`; - } else if (fixed.length > 0) { - headline = `🟢 This PR fixes ${fixed.length} translator lit test${fixed.length === 1 ? '' : 's'} (vs \`amd-staging\` baseline). ${common.length} pre-existing failure${common.length === 1 ? '' : 's'} remain.`; - } else { - headline = `⚠️ **${common.length} pre-existing translator lit failure${common.length === 1 ? '' : 's'}** on baseline; not caused by this PR (see [run](${runUrl})).`; - } - - body = `${marker}\n${headline}\n\n` + - ` 0 ? ' open' : ''}>🔴 New failures (${newFails.length}) — likely caused by this PR\n\n${fmt(newFails)}\n\n\n` + - `
🟢 Fixed by this PR (${fixed.length}) — failing on baseline, passing here\n\n${fmt(fixed)}\n
\n\n` + - `
⚠️ Pre-existing on \`amd-staging\` (${common.length})\n\n${fmt(common)}\n
`; - } - - const { data: comments } = await github.rest.issues.listComments({ - owner: context.repo.owner, repo: context.repo.repo, - issue_number: context.payload.pull_request.number, - }); - const existing = comments.find(c => c.body && c.body.includes(marker)); - if (existing) { - await github.rest.issues.updateComment({ - owner: context.repo.owner, repo: context.repo.repo, - comment_id: existing.id, body, - }); - } else { - await github.rest.issues.createComment({ - owner: context.repo.owner, repo: context.repo.repo, - issue_number: context.payload.pull_request.number, body, - }); - } - - # ===================================================================== - # Test - LLVM SPIRV codegen lit suite - # ===================================================================== - test-llvm-codegen-spirv: - name: Linux 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 (amd-staging) - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - repository: ROCm/llvm-project - ref: amd-staging - path: llvm-project - fetch-depth: 1 - persist-credentials: false - - - name: Checkout SPIRV-LLVM-Translator (PR head) - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - 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 - - - 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: Linux 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 (amd-staging) - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - repository: ROCm/llvm-project - ref: amd-staging - path: llvm-project - fetch-depth: 1 - persist-credentials: false - - - name: Checkout SPIRV-LLVM-Translator (PR head) - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - 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 - - - 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 + linux_release: + name: Linux::release + uses: ./.github/workflows/spirv-ci-linux.yml + secrets: inherit From 2f0208a0150b2a36de8396af37f035ec1de5c459 Mon Sep 17 00:00:00 2001 From: Jacob Lambert Date: Sat, 9 May 2026 10:19:00 -0700 Subject: [PATCH 3/6] [CI] Grant pull-requests: write at dispatcher level (fix startup_failure) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous commit moved pull-requests: write to a job-level permission on the test_translator_lit job inside spirv-ci-linux.yml. Per GHA rules, a called workflow's GITHUB_TOKEN permissions are capped by the caller's permissions; if the caller's workflow-level grant is `contents: read` only, the called workflow can't add pull-requests: write — validation fails at startup, no jobs run. Symptom: PR #194 ran with conclusion=startup_failure, no check_runs created, empty PR rollup. Fix: grant pull-requests: write at the dispatcher's workflow-level permissions. The called workflow's job-level grant on test_translator_lit still narrows the actual usage to that single job; this just lifts the caller-side cap. Multi-Arch CI gets away with `contents: read` only because none of its jobs post comments. Ours does, so this grant is required. --- .github/workflows/spirv-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/spirv-ci.yml b/.github/workflows/spirv-ci.yml index 6e8e2de6d..26ebe6c02 100644 --- a/.github/workflows/spirv-ci.yml +++ b/.github/workflows/spirv-ci.yml @@ -12,6 +12,7 @@ on: permissions: contents: read + pull-requests: write # caller cap; the translator-lit test job is the only consumer concurrency: group: ${{ github.workflow }}-${{ github.event.number || github.sha }} From 9229a4edcb05a4b4e7429c9c7312f324d0f409c4 Mon Sep 17 00:00:00 2001 From: Jacob Lambert Date: Sun, 10 May 2026 11:30:35 -0700 Subject: [PATCH 4/6] [CI] Tar build trees for artifact transport (preserve modes + .git) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous commit's first run hit two distinct failures rooted in actions/upload-artifact@v4 defaults: 1. Comgr test job: "/bin/sh: clang-23: Permission denied" — v4 strips executable bits on upload, so binaries come back non-executable. 2. Codegen test job: cmake reconfigure (triggered when ninja sees the freshly-checked-out source as newer than the build tree) failed inside FetchContent's SPIRV-Headers update step with "fatal: not a git repository: '.git'" — v4 also excludes hidden files (the .git dir under build/_deps/) by default. Translator-lit job appeared green but actually hit the same first-lit breakage; continue-on-error: true masked it. Fix: tar the build trees ourselves before upload, untar after download. Tar preserves both file modes and hidden files in one shot, which is simpler than chmodding +x and toggling include-hidden-files separately. --- .github/workflows/spirv-ci-linux.yml | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/.github/workflows/spirv-ci-linux.yml b/.github/workflows/spirv-ci-linux.yml index 0e3f4891c..30b3c0529 100644 --- a/.github/workflows/spirv-ci-linux.yml +++ b/.github/workflows/spirv-ci-linux.yml @@ -95,14 +95,20 @@ jobs: -type f \( -executable -o -name '*.so*' -o -name '*.a' \) \ -exec strip --strip-unneeded {} + 2>/dev/null || true + # Tar the build trees ourselves before upload. actions/upload-artifact@v4 + # otherwise (a) strips executable bits — clang/llvm-as etc. come back as + # non-executable and tests fail with "Permission denied", and (b) skips + # hidden files by default — losing FetchContent's .git dirs (e.g. SPIRV- + # Headers under build/_deps/) which causes cmake reconfigure to fail + # with "fatal: not a git repository: '.git'" on the test side. + - 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: | - build - build-comgr - build-device-libs + path: linux-build-tree.tar retention-days: 1 compression-level: 6 if-no-files-found: error @@ -150,6 +156,9 @@ jobs: with: name: linux-build-tree + - name: Untar build trees + run: tar -xf linux-build-tree.tar + - name: Test - SPIRV Translator (check-amd-llvm-spirv) [PR head] id: check_spirv_xlator continue-on-error: true @@ -293,6 +302,9 @@ jobs: with: name: linux-build-tree + - name: Untar build trees + run: tar -xf linux-build-tree.tar + - name: Test - LLVM SPIRV backend (check-llvm-codegen-spirv) run: ninja -C build check-llvm-codegen-spirv @@ -329,6 +341,9 @@ jobs: with: name: linux-build-tree + - name: Untar build trees + run: tar -xf linux-build-tree.tar + - 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 From 80c5204f71f4f2b3c6b12ba5fac142b2e9280928 Mon Sep 17 00:00:00 2001 From: Jacob Lambert Date: Sun, 10 May 2026 12:14:29 -0700 Subject: [PATCH 5/6] [CI] Test-job wall-time fixes: tar -xmf + shallower translator clone Two wall-time bugs found while diagnosing PR #194's slow codegen test: 1. Untar with `tar -xf` restored mtimes from when the build job produced them. Test-job source checkouts run just before, so freshly-checked-out source files appeared newer than (older) build outputs from the tar, and ninja cascade-rebuilt instead of running the requested test target. Switch to `tar -xmf` (skip mtime restore) so build outputs are newer. Observed ~5-10 min wasted on codegen test job. 2. Translator-lit job's translator checkout used `fetch-depth: 0` (full history) only to enable the later `git checkout amd-staging` for the baseline swap. But `git fetch --depth=1 origin amd-staging` followed by `git checkout FETCH_HEAD` works on a shallow clone too. Switch to `fetch-depth: 1`. ~30-60s save per run. Drive-by: trim verbose comments on the tar/untar steps. --- .github/workflows/spirv-ci-linux.yml | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/.github/workflows/spirv-ci-linux.yml b/.github/workflows/spirv-ci-linux.yml index 30b3c0529..0356ff76c 100644 --- a/.github/workflows/spirv-ci-linux.yml +++ b/.github/workflows/spirv-ci-linux.yml @@ -95,12 +95,8 @@ jobs: -type f \( -executable -o -name '*.so*' -o -name '*.a' \) \ -exec strip --strip-unneeded {} + 2>/dev/null || true - # Tar the build trees ourselves before upload. actions/upload-artifact@v4 - # otherwise (a) strips executable bits — clang/llvm-as etc. come back as - # non-executable and tests fail with "Permission denied", and (b) skips - # hidden files by default — losing FetchContent's .git dirs (e.g. SPIRV- - # Headers under build/_deps/) which causes cmake reconfigure to fail - # with "fatal: not a git repository: '.git'" on the test side. + # 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 @@ -147,8 +143,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: llvm-project/llvm/projects/SPIRV-LLVM-Translator - # fetch full history so we can checkout amd-staging tip later for the baseline run - fetch-depth: 0 + fetch-depth: 1 persist-credentials: false - name: Download build tree artifact @@ -156,8 +151,10 @@ jobs: with: name: linux-build-tree + # -m skips mtime restore so build outputs aren't older than the + # freshly-checked-out source — otherwise ninja cascade-rebuilds. - name: Untar build trees - run: tar -xf linux-build-tree.tar + run: tar -xmf linux-build-tree.tar - name: Test - SPIRV Translator (check-amd-llvm-spirv) [PR head] id: check_spirv_xlator @@ -302,8 +299,10 @@ jobs: with: name: linux-build-tree + # -m skips mtime restore so build outputs aren't older than the + # freshly-checked-out source — otherwise ninja cascade-rebuilds. - name: Untar build trees - run: tar -xf linux-build-tree.tar + run: tar -xmf linux-build-tree.tar - name: Test - LLVM SPIRV backend (check-llvm-codegen-spirv) run: ninja -C build check-llvm-codegen-spirv @@ -341,8 +340,10 @@ jobs: with: name: linux-build-tree + # -m skips mtime restore so build outputs aren't older than the + # freshly-checked-out source — otherwise ninja cascade-rebuilds. - name: Untar build trees - run: tar -xf linux-build-tree.tar + run: tar -xmf linux-build-tree.tar - name: Test - Comgr (check-comgr) # check-comgr depends on test-lit (runs lit suite) and test-unit From d2ea65ef7f5bf86d207d5222516f4f9109429a51 Mon Sep 17 00:00:00 2001 From: Jacob Lambert Date: Sun, 10 May 2026 12:39:02 -0700 Subject: [PATCH 6/6] [CI] Gate translator-lit job on new failures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PR-head and baseline lit steps stay continue-on-error so pre- existing amd-staging breakage doesn't block. The partition comment already surfaces 🔴 New / 🟢 Fixed / ⚠️ Pre-existing buckets. Add a final gate step that exits non-zero when newFails > 0 (PR head FAILs not present in baseline). Real PR-introduced regressions now turn the check red instead of just dropping into a comment. Degrades gracefully — if either capture file is missing (e.g., one of the lit runs failed to produce output) the gate emits a warning and passes rather than blocking on incomplete data. Now that the partition logic has been validated end-to-end on PRs #190/#192 (🔴 New) and #193 (🟢 Fixed), this is a safe step up from informational to blocking. --- .github/workflows/spirv-ci-linux.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.github/workflows/spirv-ci-linux.yml b/.github/workflows/spirv-ci-linux.yml index 0356ff76c..d0ffa55b6 100644 --- a/.github/workflows/spirv-ci-linux.yml +++ b/.github/workflows/spirv-ci-linux.yml @@ -266,6 +266,24 @@ jobs: }); } + # 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 # =====================================================================