@@ -2,16 +2,9 @@ name: 'Run benchmarks'
22
33# This action assumes the following prerequisites:
44#
5- # - SYCL is accessible in the system (nightly image provides it within /opt/sycl),
6- # or SYCL is placed in ./toolchain (TODO: change this??). The second option has higher priority.
7- # - /devops has been checked out in ./devops.
8- # - env.GITHUB_TOKEN was properly set, because according to Github, that's
9- # apparently the recommended way to pass a secret into a github action:
10-
11- # https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions#accessing-your-secrets
12- #
13- # - env.RUNNER_TAG set to the runner tag used to run this workflow: Currently,
14- # only specific runners are fully supported.
5+ # - SYCL is placed in dir pointed by 'inputs.sycl_dir', if not, it has to be accessible
6+ # in the system (e.g. nightly image provides it within /opt/sycl, but it might be a little older).
7+ # - /devops dir has been checked out in ./devops.
158
169inputs :
1710 target_devices :
@@ -37,59 +30,132 @@ inputs:
3730 exit_on_failure :
3831 type : string
3932 required : False
33+ # Path to SYCL installation directory
34+ sycl_dir :
35+ type : string
36+ required : False
37+ default : " ./toolchain"
38+ # Only specific runners are supported
39+ runner :
40+ type : string
41+ required : True
4042
4143runs :
4244 # composite actions don't make use of 'name', so copy-paste names as a comment in the first line of each step
4345 using : " composite"
4446 steps :
45- - name : Check specified runner type / target backend
47+ - name : Check inputs and set up environment
4648 shell : bash
4749 env :
50+ # inputs are not directly used, as this allows code injection
4851 TARGET_DEVICE : ${{ inputs.target_devices }}
4952 PRESET : ${{ inputs.preset }}
53+ SYCL_DIR : ${{ inputs.sycl_dir }}
54+ RUNNER_TAG : ${{ inputs.runner }}
55+ # Will append "_<device>_<backend>" to that prefix, as the save name
56+ SAVE_PREFIX : ${{ inputs.save_name }}
5057 run : |
58+ # Check inputs and set up environment
59+
60+ # Ensure runner name has nothing injected
61+ if [ -z "$(printf '%s' "$RUNNER_NAME" | grep -oE '^[a-zA-Z0-9_-]+$')" ]; then
62+ echo "Bad runner name, please ensure runner name is [a-zA-Z0-9_-]."
63+ exit 1
64+ fi
65+
5166 # Check specified runner type / target backend
5267 case "$RUNNER_TAG" in
53- '["PVC_PERF"]' ) ;;
54- '["BMG_PERF"]' ) ;;
68+ '["PVC_PERF"]') MACHINE_TYPE="PVC" ;;
69+ '["BMG_PERF"]') MACHINE_TYPE="BMG" ;;
5570 *)
71+ # Best effort at matching
72+ # TODO: should we drop it and just exit instead?
73+ MACHINE_TYPE="${RUNNER_TAG#[\"}"
74+ MACHINE_TYPE="${MACHINE_TYPE%_PERF=\"]}"
5675 echo "#"
5776 echo "# WARNING: Only specific tuned runners are fully supported."
5877 echo "# This workflow is not guaranteed to work with other runners."
5978 echo "#" ;;
6079 esac
6180
62- # Ensure runner name has nothing injected
63- # TODO: in terms of security, is this overkill?
64- if [ -z "$(printf '%s' "$RUNNER_NAME" | grep -oE '^[a-zA-Z0-9_-]+$')" ]; then
65- echo "Bad runner name, please ensure runner name is [a-zA-Z0-9_-]."
66- exit 1
67- fi
68-
69- # input.target_devices is not directly used, as this allows code injection
7081 case "$TARGET_DEVICE" in
71- level_zero:*) ;;
72- level_zero_v2:*) ;;
82+ level_zero:*) SAVE_SUFFIX="L0" ;;
83+ level_zero_v2:*)
84+ SAVE_SUFFIX="L0v2"
85+ ONEAPI_DEVICE_SELECTOR="level_zero:gpu"
86+ export SYCL_UR_USE_LEVEL_ZERO_V2=1
87+ echo "SYCL_UR_USE_LEVEL_ZERO_V2=$SYCL_UR_USE_LEVEL_ZERO_V2" >> $GITHUB_ENV
88+ ;;
89+ opencl:*) SAVE_SUFFIX="OCL" ;;
7390 *)
91+ SAVE_SUFFIX="${TARGET_DEVICE%%:*}";;
7492 echo "#"
7593 echo "# WARNING: Only level_zero backend is fully supported."
7694 echo "# This workflow is not guaranteed to work with other backends."
7795 echo "#" ;;
7896 esac
79- echo "ONEAPI_DEVICE_SELECTOR=$TARGET_DEVICE" >> $GITHUB_ENV
97+
98+ # Export variables with machine type, save name, device selector, etc.
99+ export ONEAPI_DEVICE_SELECTOR=$TARGET_DEVICE
100+ echo "ONEAPI_DEVICE_SELECTOR=$ONEAPI_DEVICE_SELECTOR" >> $GITHUB_ENV
101+ export SAVE_SUFFIX=$SAVE_SUFFIX
102+ echo "SAVE_SUFFIX=$SAVE_SUFFIX" >> $GITHUB_ENV
103+ export MACHINE_TYPE=$MACHINE_TYPE
104+ echo "MACHINE_TYPE=$MACHINE_TYPE" >> $GITHUB_ENV
105+
106+ export SAVE_NAME="${SAVE_PREFIX}_${MACHINE_TYPE}_${SAVE_SUFFIX}"
107+ echo "SAVE_NAME=$SAVE_NAME" >> $GITHUB_ENV
108+ export SAVE_TIMESTAMP="$(date -u +'%Y%m%d_%H%M%S')" # Timestamps are in UTC time
109+ echo "SAVE_TIMESTAMP=$SAVE_TIMESTAMP" >> $GITHUB_ENV
110+
111+ # By default, the benchmark scripts forceload level_zero
112+ FORCELOAD_ADAPTER="${ONEAPI_DEVICE_SELECTOR%%:*}"
113+ echo "Adapter: $FORCELOAD_ADAPTER"
114+ echo "FORCELOAD_ADAPTER=$FORCELOAD_ADAPTER" >> $GITHUB_ENV
80115
81116 # Make sure specified preset is a known value and is not malicious
82117 python3 ./devops/scripts/benchmarks/presets.py query "$PRESET"
83118 [ "$?" -ne 0 ] && exit 1 # Stop workflow if invalid preset
84119 echo "PRESET=$PRESET" >> $GITHUB_ENV
120+
121+ # Check if SYCL dir exists and has SYCL lib; set CMPLR_ROOT if so
122+ if [ -d "$SYCL_DIR" ] && [ -f "$SYCL_DIR/lib/libsycl.so" ]; then
123+ echo "Using SYCL from: $SYCL_DIR"
124+ export CMPLR_ROOT=$SYCL_DIR
125+ echo "CMPLR_ROOT=$CMPLR_ROOT" >> $GITHUB_ENV
126+ else
127+ echo "WARNING: SYCL directory '$SYCL_DIR' does not exist or is missing libsycl.so"
128+ echo "Checking if SYCL is installed in the system..."
129+ which sycl-ls
130+ sycl-ls
131+ export CMPLR_ROOT="$(dirname $(which sycl-ls))"
132+ echo "Using SYCL from: $CMPLR_ROOT"
133+ echo "CMPLR_ROOT=$CMPLR_ROOT" >> $GITHUB_ENV
134+ fi
85135 - name : Set NUMA node to run benchmarks on
86136 shell : bash
87137 run : |
88138 # Set CPU and GPU affinity for the first NUMA node; second node is used by UMF
89139 NUMA_NODE=0
90140 echo "ZE_AFFINITY_MASK=$NUMA_NODE" >> $GITHUB_ENV
91141 echo "NUMA_NODE=$NUMA_NODE" >> $GITHUB_ENV
142+ - name : Set env var for results branch and repo dir
143+ shell : bash
144+ run : |
145+ # Set env var for results branch and repo dir
146+
147+ # Set BENCHMARK_RESULTS_BRANCH globally for all subsequent steps.
148+ # This has to be done this way because of limits of composite actions.
149+ BENCHMARK_RESULTS_BRANCH="sycl-benchmark-ci-results"
150+ echo "BENCHMARK_RESULTS_BRANCH=$BENCHMARK_RESULTS_BRANCH" >> $GITHUB_ENV
92151
152+ BENCHMARK_RESULTS_REPO_PATH="$(realpath ./llvm-ci-perf-results)"
153+ echo "BENCHMARK_RESULTS_REPO_PATH=$BENCHMARK_RESULTS_REPO_PATH" >> $GITHUB_ENV
154+ - name : Checkout results repo
155+ uses : actions/checkout@v5
156+ with :
157+ ref : ${{ env.BENCHMARK_RESULTS_BRANCH }}
158+ path : ${{ env.BENCHMARK_RESULTS_REPO_PATH }}
93159 # Compute-benchmarks relies on UR static libraries, cmake config files, etc.
94160 # DPC++ doesn't ship with these files. The easiest way of obtaining these
95161 # files is to build from scratch.
@@ -102,10 +168,10 @@ runs:
102168 # modified output the entire sycl build dir as an artifact, in which the
103169 # intermediate files required can be stitched together from the build files.
104170 # However, this is not exactly "clean" or "fun to maintain"...
105- - name : Build Unified Runtime
171+ - name : Clone and build Unified Runtime
106172 shell : bash
107173 run : |
108- # Build Unified Runtime
174+ # Clone and build Unified Runtime
109175 echo "::group::checkout_llvm_ur"
110176
111177 # Sparse-checkout UR at build ref:
@@ -137,13 +203,27 @@ runs:
137203 cd -
138204
139205 echo "::endgroup::"
140- # Linux tools installed during docker creation may not match the self-hosted
141- # kernel version, so we need to install the correct version here.
142- - name : Install perf in version matching the host kernel
206+ - name : Install dependencies
143207 shell : bash
208+ env :
209+ RUNNER_TAG : ${{ inputs.runner }}
144210 run : |
145- # Install perf in version matching the host kernel
146- echo "::group::install_linux_tools"
211+ # Install dependencies
212+
213+ echo "::group::use_compute_runtime_tag_cache"
214+
215+ # Cache the compute_runtime version from dependencies.json, but perform a
216+ # check with L0 version before using it: This value is not guaranteed to
217+ # accurately reflect the current compute_runtime version used, as the
218+ # docker images are built nightly.
219+ export COMPUTE_RUNTIME_TAG_CACHE="$(cat ./devops/dependencies.json | jq -r .linux.compute_runtime.github_tag)"
220+
221+ echo "::endgroup::"
222+ echo "::group::install_perf"
223+
224+ # Install perf in version matching the host kernel.
225+ # Linux tools installed during docker creation may not match the self-hosted
226+ # kernel version, so we need to install the correct version here.
147227 if [ "$RUNNER_TAG" = '["BMG_PERF"]' ]; then
148228 echo "Adding repositories for Ubuntu 25.10 (Questing) on BMG_PERF runner"
149229 echo "deb http://archive.ubuntu.com/ubuntu/ questing main restricted universe multiverse" | sudo tee /etc/apt/sources.list.d/questing.list
@@ -152,30 +232,10 @@ runs:
152232 fi
153233 sudo apt-get update
154234 sudo apt-get install -y linux-tools-$(uname -r)
155- echo "::endgroup::"
156- - name : Set env var for results branch
157- shell : bash
158- run : |
159- # Set env var for results branch
160- # Set BENCHMARK_RESULTS_BRANCH globally for all subsequent steps.
161- # This has to be done this way because of limits of composite actions.
162- BENCHMARK_RESULTS_BRANCH="sycl-benchmark-ci-results"
163- echo "BENCHMARK_RESULTS_BRANCH=$BENCHMARK_RESULTS_BRANCH" >> $GITHUB_ENV
164- - name : Checkout results repo
165- uses : actions/checkout@v5
166- with :
167- ref : ${{ env.BENCHMARK_RESULTS_BRANCH }}
168- path : llvm-ci-perf-results
169- - name : Build and run benchmarks
170- env :
171- # Need to append "_<device>_<backend>" to save name in order to follow
172- # conventions:
173- SAVE_PREFIX : ${{ inputs.save_name }}
174- shell : bash
175- run : |
176- # Build and run benchmarks
177235
236+ echo "::endgroup::"
178237 echo "::group::install_python_deps"
238+
179239 echo "Installing python dependencies..."
180240 # Using --break-system-packages because:
181241 # - venv is not installed
@@ -186,64 +246,37 @@ runs:
186246 pip install --user --break-system-packages -r ./devops/scripts/benchmarks/requirements.txt
187247
188248 echo "::endgroup::"
189- echo "::group::establish_parameters_and_vars"
190-
191- export CMPLR_ROOT=./toolchain
192- # By default, the benchmark scripts forceload level_zero
193- FORCELOAD_ADAPTER="${ONEAPI_DEVICE_SELECTOR%%:*}"
194- echo "Adapter: $FORCELOAD_ADAPTER"
195-
196- case "$ONEAPI_DEVICE_SELECTOR" in
197- level_zero:*) SAVE_SUFFIX="L0" ;;
198- level_zero_v2:*)
199- SAVE_SUFFIX="L0v2"
200- export ONEAPI_DEVICE_SELECTOR="level_zero:gpu" # "level_zero_v2:gpu" not supported anymore
201- export SYCL_UR_USE_LEVEL_ZERO_V2=1
202- ;;
203- opencl:*) SAVE_SUFFIX="OCL" ;;
204- *) SAVE_SUFFIX="${ONEAPI_DEVICE_SELECTOR%%:*}";;
205- esac
206- case "$RUNNER_TAG" in
207- '["PVC_PERF"]') MACHINE_TYPE="PVC" ;;
208- '["BMG_PERF"]') MACHINE_TYPE="BMG" ;;
209- # Best effort at matching
210- *)
211- MACHINE_TYPE="${RUNNER_TAG#[\"}"
212- MACHINE_TYPE="${MACHINE_TYPE%_PERF=\"]}"
213- ;;
214- esac
215- SAVE_NAME="${SAVE_PREFIX}_${MACHINE_TYPE}_${SAVE_SUFFIX}"
216- echo "SAVE_NAME=$SAVE_NAME" >> $GITHUB_ENV
217- SAVE_TIMESTAMP="$(date -u +'%Y%m%d_%H%M%S')" # Timestamps are in UTC time
218-
219- # Cache the compute_runtime version from dependencies.json, but perform a
220- # check with L0 version before using it: This value is not guaranteed to
221- # accurately reflect the current compute_runtime version used, as the
222- # docker images are built nightly.
223- export COMPUTE_RUNTIME_TAG_CACHE="$(cat ./devops/dependencies.json | jq -r .linux.compute_runtime.github_tag)"
224-
225- echo "::endgroup::"
226- echo "::group::sycl_ls"
249+ - name : Run sycl-ls
250+ shell : bash
251+ run : |
252+ # Run sycl-ls
227253 sycl-ls --verbose
228- echo "::endgroup::"
229- echo "::group::run_benchmarks"
254+ - name : Build and run benchmarks
255+ env :
256+ shell : bash
257+ run : |
258+ # Build and run benchmarks
230259
260+ echo "::group::setup_workdir"
231261 WORKDIR="$(realpath ./llvm_test_workdir)"
232262 if [ -n "$WORKDIR" ] && [ -d "$WORKDIR" ] && [[ "$WORKDIR" == *llvm_test_workdir* ]]; then rm -rf "$WORKDIR" ; fi
233263
234264 # Clean up potentially existing, old summary files
235265 [ -f "github_summary_exe.md" ] && rm github_summary_exe.md
236266 [ -f "github_summary_reg.md" ] && rm github_summary_reg.md
237267
268+ echo "::endgroup::"
269+ echo "::group::run_benchmarks"
270+
238271 numactl --cpunodebind "$NUMA_NODE" --membind "$NUMA_NODE" \
239272 ./devops/scripts/benchmarks/main.py "$WORKDIR" \
240- --sycl "$(realpath ./toolchain )" \
273+ --sycl "$(realpath $CMPLR_ROOT )" \
241274 --ur "$(realpath ./ur/install)" \
242275 --adapter "$FORCELOAD_ADAPTER" \
243276 --save "$SAVE_NAME" \
244277 --output-html remote \
245- --results-dir "./llvm-ci-perf-results /" \
246- --output-dir "./llvm-ci-perf-results /" \
278+ --results-dir "$BENCHMARK_RESULTS_REPO_PATH /" \
279+ --output-dir "$BENCHMARK_RESULTS_REPO_PATH /" \
247280 --preset "$PRESET" \
248281 --timestamp-override "$SAVE_TIMESTAMP" \
249282 --detect-version sycl,compute_runtime \
@@ -253,12 +286,13 @@ runs:
253286
254287 echo "::endgroup::"
255288 echo "::group::compare_results"
289+
256290 python3 ./devops/scripts/benchmarks/compare.py to_hist \
257291 --avg-type EWMA \
258292 --cutoff "$(date -u -d '7 days ago' +'%Y%m%d_%H%M%S')" \
259293 --name "$SAVE_NAME" \
260- --compare-file "./llvm-ci-perf-results /results/${SAVE_NAME}_${SAVE_TIMESTAMP}.json" \
261- --results-dir "./llvm-ci-perf-results /results/" \
294+ --compare-file "$BENCHMARK_RESULTS_REPO_PATH /results/${SAVE_NAME}_${SAVE_TIMESTAMP}.json" \
295+ --results-dir "$BENCHMARK_RESULTS_REPO_PATH /results/" \
262296 --regression-filter '^[a-z_]+_sycl .* CPU count' \
263297 --regression-filter-type 'SYCL benchmark (measured using CPU cycle count)' \
264298 --verbose \
@@ -282,18 +316,18 @@ runs:
282316 [ -f "github_summary_exe.md" ] && cat github_summary_exe.md >> $GITHUB_STEP_SUMMARY
283317 [ -f "github_summary_reg.md" ] && cat github_summary_reg.md >> $GITHUB_STEP_SUMMARY
284318
285- cd "./llvm-ci-perf-results "
319+ cd "$BENCHMARK_RESULTS_REPO_PATH "
286320 git add .
287321 for diff in $(git diff HEAD --name-only); do
288322 mkdir -p "../cached_changes/$(dirname $diff)"
289323 cp "$diff" "../cached_changes/$diff"
290324 done
291325 - name : Push benchmarks results
292- if : inputs.upload_results == 'true' && always()
326+ if : always() && inputs.upload_results == 'true'
293327 shell : bash
294328 run : |
295329 # Push benchmarks results
296- cd "./llvm-ci-perf-results "
330+ cd "$BENCHMARK_RESULTS_REPO_PATH "
297331 git config user.name "github-actions[bot]"
298332 git config user.email "github-actions[bot]@users.noreply.github.com"
299333
@@ -329,8 +363,8 @@ runs:
329363 ./devops/scripts/benchmarks/main.py \
330364 "$(realpath ./llvm_test_workdir)" \
331365 --output-html remote \
332- --results-dir "./llvm-ci-perf-results /" \
333- --output-dir "./llvm-ci-perf-results /" \
366+ --results-dir "$BENCHMARK_RESULTS_REPO_PATH /" \
367+ --output-dir "$BENCHMARK_RESULTS_REPO_PATH /" \
334368 --dry-run
335369 cd -
336370 done
0 commit comments