Skip to content

Commit 70ef868

Browse files
authored
Add split build/test callable workflow for validation (#1067)
Every PR test job holds a GPU runner for the full build+test duration (7–16 min), even though 67–86% of that time is CPU-only DXC/LLVM compilation. With one self-hosted runner per GPU SKU, this means builds block GPU-dependent test work unnecessarily. This PR adds two new, standalone workflow files — no existing workflows are modified: build-and-test-split-callable.yaml — A split version of the callable workflow: - Build job: Runs on any available runner of the matching architecture ([self-hosted, Windows, X64] for Intel/NVIDIA/AMD, [self-hosted, ARM64, Windows] for QC). Builds DXC + LLVM, uploads artifacts via tar. - Test job: Runs on the GPU-specific runner (hlsl-${{ inputs.SKU }}). Downloads build artifacts, extracts with --touch to preserve ninja timestamp freshness, then runs tests. - macOS: Unchanged — stays as a single combined job since builds are only ~1 min. validate-split-build-test.yaml — A workflow_dispatch workflow to validate the split callable per-SKU before migrating production workflows. Fixes #1081 Assisted by: Github Copilot
1 parent e1ab5ae commit 70ef868

2 files changed

Lines changed: 430 additions & 0 deletions

File tree

Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
name: HLSL Test (Split Build/Test)
2+
3+
permissions:
4+
contents: read
5+
6+
on:
7+
workflow_dispatch:
8+
inputs:
9+
OffloadTest-branch:
10+
description: 'Test Suite Branch'
11+
required: false
12+
default: 'main'
13+
type: string
14+
LLVM-branch:
15+
description: 'LLVM Branch'
16+
required: false
17+
default: 'main'
18+
type: string
19+
LLVM-fork:
20+
description: 'LLVM fork'
21+
required: false
22+
default: 'llvm'
23+
type: string
24+
DXC-branch:
25+
description: 'DXC Branch'
26+
required: false
27+
default: 'main'
28+
type: string
29+
BuildType:
30+
description: 'Build Type'
31+
required: false
32+
default: 'RelWithDebInfo'
33+
type: choice
34+
options:
35+
- Release
36+
- RelWithDebInfo
37+
- Debug
38+
TestTarget:
39+
required: false
40+
default: 'check-hlsl'
41+
type: string
42+
OS:
43+
required: true
44+
type: choice
45+
options:
46+
- macOS
47+
- windows
48+
SKU:
49+
required: true
50+
type: choice
51+
options:
52+
- macos
53+
- windows-amd
54+
- windows-intel
55+
- windows-nvidia
56+
- windows-qc
57+
LLVM-ExtraCMakeArgs:
58+
description: 'Extra CMake Args for LLVM'
59+
required: false
60+
default: ''
61+
type: string
62+
workflow_call:
63+
inputs:
64+
OffloadTest-branch:
65+
description: 'Test Suite Branch'
66+
required: false
67+
default: 'main'
68+
type: string
69+
LLVM-branch:
70+
description: 'LLVM Branch'
71+
required: false
72+
default: 'main'
73+
type: string
74+
LLVM-fork:
75+
description: 'LLVM Fork'
76+
required: false
77+
default: 'llvm'
78+
type: string
79+
DXC-branch:
80+
description: 'DXC Branch'
81+
required: false
82+
default: 'main'
83+
type: string
84+
OS:
85+
required: true
86+
type: string
87+
SKU:
88+
required: true
89+
type: string
90+
BuildType:
91+
description: 'Build Config'
92+
required: false
93+
default: 'RelWithDebInfo'
94+
type: string
95+
TestTarget:
96+
required: false
97+
default: 'check-hlsl'
98+
type: string
99+
LLVM-ExtraCMakeArgs:
100+
description: 'Extra CMake Args for LLVM'
101+
required: false
102+
default: ''
103+
type: string
104+
105+
# ============================================================================
106+
# Split Build/Test Architecture:
107+
#
108+
# Windows: Build job runs on ANY available runner of the right architecture
109+
# (load-balanced via generic labels), then test job runs on the specific
110+
# GPU runner. This frees GPU runners during the build phase.
111+
#
112+
# macOS: Single combined job (builds are fast ~1 min, split not worth it).
113+
# ============================================================================
114+
115+
jobs:
116+
build:
117+
permissions:
118+
checks: write
119+
# macOS: use the specific macOS runner (single combined job)
120+
# Windows QC (ARM64): use any ARM64 Windows runner
121+
# Windows x64: use any x64 Windows runner (load-balanced across Intel/NVIDIA/AMD)
122+
runs-on: ${{ fromJSON(inputs.OS == 'macOS' && '["self-hosted", "hlsl-macos"]' || inputs.SKU == 'windows-qc' && '["self-hosted", "ARM64", "Windows"]' || '["self-hosted", "Windows", "X64"]') }}
123+
steps:
124+
- name: Checkout DXC
125+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
126+
with:
127+
repository: Microsoft/DirectXShaderCompiler
128+
ref: ${{ inputs.DXC-branch }}
129+
path: DXC
130+
fetch-depth: 1
131+
submodules: true
132+
- name: Checkout LLVM
133+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
134+
with:
135+
repository: ${{ inputs.LLVM-fork }}/llvm-project
136+
ref: ${{ inputs.LLVM-branch }}
137+
path: llvm-project
138+
fetch-depth: 1
139+
- name: Checkout OffloadTest
140+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
141+
with:
142+
repository: llvm/offload-test-suite
143+
ref: ${{ inputs.OffloadTest-branch }}
144+
path: OffloadTest
145+
fetch-depth: 1
146+
- name: Checkout Golden Images
147+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
148+
with:
149+
repository: llvm/offload-golden-images
150+
ref: main
151+
path: golden-images
152+
fetch-depth: 1
153+
- name: Setup Windows x64
154+
if: inputs.OS == 'windows' && runner.arch != 'ARM64'
155+
uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main
156+
with:
157+
arch: amd64
158+
- name: Setup Windows
159+
if: inputs.OS == 'windows' && runner.arch == 'ARM64'
160+
uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main
161+
with:
162+
arch: arm64
163+
- name: Detect Clang
164+
id: Test-Clang
165+
shell: bash
166+
if: contains(inputs.TestTarget, 'clang')
167+
run: echo TEST_CLANG=On >> $GITHUB_OUTPUT
168+
- name: Setup Python
169+
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
170+
with:
171+
pip-install: -r ${{ github.workspace }}/OffloadTest/test/requirements.txt
172+
- name: Build DXC
173+
run: |
174+
cd DXC
175+
mkdir build
176+
cd build
177+
cmake -G Ninja -DCMAKE_BUILD_TYPE=${{ inputs.BuildType }} -DLLVM_ENABLE_ASSERTIONS=On -C ${{ github.workspace }}/DXC/cmake/caches/PredefinedParams.cmake -C ${{ github.workspace }}/OffloadTest/cmake/caches/sccache.cmake -DHLSL_DISABLE_SOURCE_GENERATION=On ${{ github.workspace }}/DXC/
178+
ninja
179+
- name: Build LLVM
180+
run: |
181+
cd llvm-project
182+
mkdir build
183+
cd build
184+
cmake -G Ninja ${{ inputs.LLVM-ExtraCMakeArgs }} -DCMAKE_BUILD_TYPE=${{ inputs.BuildType }} -DLLVM_ENABLE_ASSERTIONS=On -C ${{ github.workspace }}/llvm-project/clang/cmake/caches/HLSL.cmake -C ${{ github.workspace }}/OffloadTest/cmake/caches/sccache.cmake -DDXC_DIR=${{ github.workspace }}/DXC/build/bin -DLLVM_EXTERNAL_OFFLOADTEST_SOURCE_DIR=${{ github.workspace }}/OffloadTest -DLLVM_EXTERNAL_PROJECTS="OffloadTest" -DLLVM_LIT_ARGS="--xunit-xml-output=testresults.xunit.xml -v" -DOFFLOADTEST_TEST_CLANG=${{steps.Test-Clang.outputs.TEST_CLANG || 'Off' }} -DGOLDENIMAGE_DIR=${{ github.workspace }}/golden-images ${{ github.workspace }}/llvm-project/llvm/
185+
ninja hlsl-test-depends
186+
187+
# === macOS: run tests in this job (no split) ===
188+
- name: Dump GPU Info
189+
if: inputs.OS == 'macOS'
190+
run: |
191+
cd llvm-project
192+
cd build
193+
./bin/api-query
194+
- name: Run HLSL Tests
195+
if: inputs.OS == 'macOS'
196+
run: |
197+
cd llvm-project
198+
cd build
199+
ninja check-hlsl-unit
200+
ninja ${{ inputs.TestTarget }}
201+
- name: Publish Test Results
202+
uses: EnricoMi/publish-unit-test-result-action/macos@34d7c956a59aed1bfebf31df77b8de55db9bbaaf # v2.21.0
203+
if: always() && inputs.OS == 'macOS'
204+
with:
205+
comment_mode: off
206+
files: llvm-project/build/**/testresults.xunit.xml
207+
208+
# === Windows: package and upload build artifacts for the test job ===
209+
- name: Package build artifacts
210+
if: inputs.OS == 'windows'
211+
shell: bash
212+
run: |
213+
cd $GITHUB_WORKSPACE
214+
tar cf $RUNNER_TEMP/build-artifacts.tar \
215+
--exclude='*.obj' \
216+
--exclude='*.o' \
217+
--exclude='*.ilk' \
218+
--exclude='*.pdb' \
219+
--exclude='CMakeFiles' \
220+
DXC/build/bin llvm-project/build
221+
- name: Upload build artifacts
222+
if: inputs.OS == 'windows'
223+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
224+
with:
225+
name: build-${{ inputs.SKU }}-${{ inputs.TestTarget }}
226+
path: ${{ runner.temp }}/build-artifacts.tar
227+
retention-days: 1
228+
229+
test:
230+
if: inputs.OS != 'macOS'
231+
needs: build
232+
permissions:
233+
checks: write
234+
runs-on: [self-hosted, "hlsl-${{ inputs.SKU }}"]
235+
steps:
236+
# Checkout all repos: source files are needed for ninja dependency
237+
# tracking and lit test sources.
238+
- name: Checkout DXC
239+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
240+
with:
241+
repository: Microsoft/DirectXShaderCompiler
242+
ref: ${{ inputs.DXC-branch }}
243+
path: DXC
244+
fetch-depth: 1
245+
submodules: true
246+
- name: Checkout LLVM
247+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
248+
with:
249+
repository: ${{ inputs.LLVM-fork }}/llvm-project
250+
ref: ${{ inputs.LLVM-branch }}
251+
path: llvm-project
252+
fetch-depth: 1
253+
- name: Checkout OffloadTest
254+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
255+
with:
256+
repository: llvm/offload-test-suite
257+
ref: ${{ inputs.OffloadTest-branch }}
258+
path: OffloadTest
259+
fetch-depth: 1
260+
- name: Checkout Golden Images
261+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
262+
with:
263+
repository: llvm/offload-golden-images
264+
ref: main
265+
path: golden-images
266+
fetch-depth: 1
267+
268+
# Download and extract build artifacts over the source checkouts.
269+
# --touch ensures extracted files get current timestamps so ninja
270+
# sees build outputs as newer than source files (no rebuild).
271+
- name: Download build artifacts
272+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
273+
with:
274+
name: build-${{ inputs.SKU }}-${{ inputs.TestTarget }}
275+
path: ${{ runner.temp }}
276+
- name: Extract build artifacts
277+
shell: bash
278+
run: |
279+
cd $GITHUB_WORKSPACE
280+
tar xf $RUNNER_TEMP/build-artifacts.tar --touch
281+
282+
- name: Setup Windows x64
283+
if: runner.arch != 'ARM64'
284+
uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main
285+
with:
286+
arch: amd64
287+
- name: Setup Windows
288+
if: runner.arch == 'ARM64'
289+
uses: llvm/actions/setup-windows@89a8cf80982d830faab019237860b344a6390c30 # main
290+
with:
291+
arch: arm64
292+
- name: Setup Python
293+
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
294+
with:
295+
pip-install: -r ${{ github.workspace }}/OffloadTest/test/requirements.txt
296+
297+
- name: Dump GPU Info
298+
run: |
299+
cd llvm-project
300+
cd build
301+
./bin/api-query
302+
- name: Run HLSL Tests
303+
run: |
304+
cd llvm-project
305+
cd build
306+
ninja check-hlsl-unit
307+
ninja ${{ inputs.TestTarget }}
308+
- name: Run dxdiag (Windows only)
309+
if: failure()
310+
shell: powershell
311+
run: |
312+
$fileName = "dxdiag.txt"
313+
$output = Join-Path $env:RUNNER_TEMP $fileName
314+
dxdiag /t $output | Out-Null
315+
Write-Host "DxDiag report saved to $output"
316+
- name: Upload dxdiag artifact
317+
if: failure()
318+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
319+
with:
320+
name: dxdiag-${{ inputs.SKU }}-${{inputs.TestTarget}}.txt
321+
path: ${{ runner.temp }}/dxdiag.txt
322+
#- name: Publish Test Results
323+
# uses: EnricoMi/publish-unit-test-result-action/windows@34d7c956a59aed1bfebf31df77b8de55db9bbaaf # v2.21.0
324+
# if: always() && inputs.OS == 'windows'
325+
# with:
326+
# comment_mode: off
327+
# files: llvm-project/build/**/testresults.xunit.xml

0 commit comments

Comments
 (0)