Skip to content

Commit 93456e0

Browse files
committed
Amend config loading to python, split aggregate workflow
1 parent efef394 commit 93456e0

File tree

4 files changed

+127
-131
lines changed

4 files changed

+127
-131
lines changed

.github/workflows/sycl-benchmark-aggregate.yml

Lines changed: 10 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,16 @@ on:
1111
inputs:
1212
cutoff_timestamp:
1313
description: |
14-
Timestamp indicating the age limit of data used in average calculation:
15-
Any benchmark results created before this timestamp is excluded from
16-
being aggregated.
17-
18-
Any valid date string supported by GNU coreutils is valid here:
19-
https://www.gnu.org/software/coreutils/manual/html_node/Date-input-formats.html
14+
Timestamp (YYYYMMDD_HHMMSS) indicating the age limit of data used in
15+
average calculation: Any benchmark results created before this
16+
timestamp is excluded from being aggregated.
2017
type: string
21-
required: false
18+
required: true
2219
workflow_call:
2320
inputs:
2421
cutoff_timestamp:
2522
type: string
26-
required: false
23+
required: true
2724

2825
permissions:
2926
contents: read
@@ -35,74 +32,12 @@ jobs:
3532
steps:
3633
- uses: actions/checkout@v4
3734
with:
38-
path: llvm
3935
sparse-checkout: |
4036
devops/scripts/benchmarking
4137
devops/benchmarking
42-
- name: Load benchmarking configuration
43-
run: |
44-
CONFIG_FILE="$PWD/llvm/devops/benchmarking/benchmark-ci.conf"
45-
46-
# Load default values from configuration file
47-
. "$PWD/llvm/devops/scripts/benchmarking/utils.sh"
48-
# utils.sh contains functions to sanitize config file settings
49-
load_config_constants "$CONFIG_FILE"
50-
echo "PERF_RES_GIT_REPO=$PERF_RES_GIT_REPO" >> $GITHUB_ENV
51-
echo "PERF_RES_BRANCH=$PERF_RES_BRANCH" >> $GITHUB_ENV
52-
echo "PERF_RES_PATH=$PERF_RES_PATH" >> $GITHUB_ENV
53-
54-
# Determine a "cutoff timestamp" used by the aggregator script
55-
#
56-
# This timestamp controls which historical results are used to compute
57-
# measures of central tendency: Any files timestamped *before* this time
58-
# will be *excluded* from the central tendency calculation.
59-
60-
echo "TIMESTAMP_FORMAT=$TIMESTAMP_FORMAT" >> $GITHUB_ENV
61-
if [ -z '${{ inputs.cutoff_timestamp }}' ]; then
62-
# No time given, use default time period from config file:
63-
echo "CUTOFF_TIMESTAMP=$(date --date="$AVERAGE_CUTOFF_RANGE" +"$TIMESTAMP_FORMAT")" >> $GITHUB_ENV
64-
else
65-
# If the provided time is a valid GNU coreutils date string, convert
66-
# the time to our format:
67-
_converted_timestamp="$(date --date '${{ inputs.cutoff_timestamp }}' +"$TIMESTAMP_FORMAT" 2> /dev/null)"
68-
if [ -n "$_converted_timestamp" ]; then
69-
echo "CUTOFF_TIMESTAMP=$_converted_timestamp" >> $GITHUB_ENV
70-
else
71-
# If not a valid GNU date string, it could be in our timestamp format already.
72-
# aggregate.py will ensure the timestamp is in the proper format, so we can pass the
73-
# time forward regardless:
74-
echo 'CUTOFF_TIMESTAMP=${{ inputs.cutoff_timestamp }}' >> $GITHUB_ENV
75-
fi
76-
fi
77-
- name: Checkout historical performance results repository
78-
run: |
79-
git clone -b $PERF_RES_BRANCH https://github.com/$PERF_RES_GIT_REPO $PERF_RES_PATH
80-
- name: Run aggregator on historical results
81-
run: |
82-
# The current format of the historical results respository is:
83-
#
84-
# /<ONEAPI_DEVICE_SELECTOR>/<runner>/<test name>
85-
#
86-
# Thus, a min/max depth of 3 is used to enumerate all test cases in the
87-
# repository. Test name is also derived from here.
88-
for dir in $(find "$PERF_RES_PATH" -mindepth 3 -maxdepth 3 -type d ! -path '*.git*'); do
89-
test_name="$(basename $dir)"
90-
python llvm/devops/scripts/benchmarking/aggregate.py "$test_name" "$dir" "$CUTOFF_TIMESTAMP"
91-
done
92-
- name: Upload average to the repo
93-
env:
94-
GITHUB_TOKEN: ${{ secrets.LLVM_SYCL_BENCHMARK_TOKEN }}
95-
run: |
96-
# TODO -- waiting on security clearance
97-
cd "$PERF_RES_PATH"
98-
git config user.name "SYCL Benchmarking Bot"
99-
git config user.email "[email protected]"
100-
git add .
101-
git commit -m "[GHA] Aggregate median data from $CUTOFF_TIMESTAMP to $(date +"$TIMESTAMP_FORMAT")"
102-
git push "https://[email protected]/$PERF_RES_GIT_REPO.git" "$PERF_RES_BRANCH"
103-
- name: Archive new medians
104-
if: always()
105-
uses: actions/upload-artifact@v4
38+
- name: Aggregate benchmark results and produce historical average
39+
uses: ./devops/actions/benchmarking/aggregate
10640
with:
107-
name: llvm-ci-perf-results new medians
108-
path: ${{ env.PERF_RES_PATH }}/**/*-median.csv
41+
cutoff_timestamp: ${{ inputs.cutoff_timestamp }}
42+
env:
43+
GITHUB_TOKEN: ${{ secrets.LLVM_SYCL_BENCHMARK_TOKEN }}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
name: 'Aggregate compute-benchmark results and produce historical averages'
2+
3+
# The benchmarking workflow in sycl-linux-run-tests.yml passes or fails based on
4+
# how the benchmark results compare to a historical average: This historical
5+
# average is calculated in this workflow, which aggregates historical data and
6+
# produces measures of central tendency (median in this case) used for this
7+
# purpose.
8+
#
9+
# This action assumes that /devops has been checked out in ./devops. This action
10+
# also assumes that GITHUB_TOKEN was properly set in env, because according to
11+
# Github, that's apparently the recommended way to pass a secret into a github
12+
# action:
13+
#
14+
# https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions#accessing-your-secrets
15+
#
16+
17+
inputs:
18+
cutoff_timestamp:
19+
type: string
20+
required: true
21+
22+
runs:
23+
using: "composite"
24+
steps:
25+
- name: Sanitize provided timestamp
26+
run: |
27+
# Sanitize the cutoff timestamp provided
28+
#
29+
# This timestamp controls which historical results are used to compute
30+
# measures of central tendency: Any files timestamped *before* this time
31+
# will be *excluded* from the central tendency calculation.
32+
33+
# Regex greps YYYYMMDD_HHMMSS
34+
TIMESTAMP_RE='^[0-9]{4}(0[1-9]|1[0-2])([0-2][0-9]|3[01])_([01][0-9]|2[0-3])([0-5][0-9])([0-5][0-9])$'
35+
36+
# Note:
37+
# - variables from input context should be surrounded with '' to prevent
38+
# remote code execution
39+
# - `-o` needs to be kept in the grep command; `-o` is exact match only,
40+
# incase user somehow manages to inject extra text, `-o` should take
41+
# care of it.
42+
# - DO NOT use input.cutoff_timestamp directly, only use SANITIZED_TIMESTAMP
43+
SANITIZED_TIMESTAMP="$(echo '${{ input.cutoff_timestamp }}' | grep -oE "$TIMESTAM_RE")"
44+
if [ -z "$SANITIZED_TIMESTAMP" ]; then
45+
echo "Please ensure input in input.cutoff_timestamp is exactly YYYYMMDD_HHMMSS."
46+
exit 1 # Terminate workflow
47+
fi
48+
echo "SANITIZED_TIMESTAMP=$SANITIZED_TIMESTAMP" >> $GITHUB_ENV
49+
- name: Load benchmarking configuration
50+
run: |
51+
$(python ./devops/scripts/benchmarking/load_config.py ./devops constants)
52+
echo "SANITIZED_PERF_RES_GIT_REPO=$SANITIZED_PERF_RES_GIT_REPO" >> $GITHUB_ENV
53+
echo "SANITIZED_PERF_RES_GIT_BRANCH=$SANITIZED_PERF_RES_GIT_BRANCH" >> $GITHUB_ENV
54+
echo "SANITIZED_PERF_RES_PATH=$SANITIZED_PERF_RES_PATH" >> $GITHUB_ENV
55+
- name: Checkout historical performance results repository
56+
run: |
57+
git clone -b "$SANITIZED_PERF_RES_GIT_BRANCH" "https://github.com/$SANITIZED_PERF_RES_GIT_REPO" "$SANITIZED_PERF_RES_PATH"
58+
- name: Run aggregator on historical results
59+
run: |
60+
# The current format of the historical results respository is:
61+
#
62+
# /<ONEAPI_DEVICE_SELECTOR>/<runner>/<test name>
63+
#
64+
# Thus, a min/max depth of 3 is used to enumerate all test cases in the
65+
# repository. Test name is also derived from here.
66+
for dir in "$(find "$SANITIZED_PERF_RES_PATH" -mindepth 3 -maxdepth 3 -type d ! -path '*.git*')"; do
67+
test_name="$(basename "$dir")"
68+
python ./devops/scripts/benchmarking/aggregate.py "$test_name" "$dir" "$SANITIZED_TIMESTAMP"
69+
done
70+
- name: Upload average to the repo
71+
run: |
72+
# TODO -- waiting on security clearance
73+
cd "$SANITIZED_PERF_RES_PATH"
74+
git config user.name "SYCL Benchmarking Bot"
75+
git config user.email "[email protected]"
76+
git add .
77+
git commit -m "[GHA] Aggregate median data from $SANITIZED_TIMESTAMP to $(date +%Y%m%d_%H%M%S)"
78+
git push "https://[email protected]/$SANITIZED_PERF_RES_GIT_REPO.git" "$SANITIZED_PERF_RES_GIT_BRANCH"
79+
- name: Archive new medians
80+
if: always()
81+
uses: actions/upload-artifact@v4
82+
with:
83+
name: llvm-ci-perf-results new medians
84+
path: ${{ env.SANITIZED_PERF_RES_PATH }}/**/*-median.csv

devops/actions/run-tests/benchmark/action.yml

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ name: 'Run compute-benchmarks'
22

33
# Run compute-benchmarks on SYCL
44
#
5-
# This action assumes SYCL is in $PWD/toolchain, and that /devops has been
6-
# checked out in $PWD/devops. This action also assumes that GITHUB_TOKEN
5+
# This action assumes SYCL is in ./toolchain, and that /devops has been
6+
# checked out in ./devops. This action also assumes that GITHUB_TOKEN
77
# was properly set in env, because according to Github, that's apparently the
88
# recommended way to pass a secret into a github action:
99
#
@@ -17,6 +17,12 @@ inputs:
1717
runs:
1818
using: "composite"
1919
steps:
20+
- name: (Test) aggregate benchmark results and produce historical average
21+
uses: ./devops/actions/benchmarking/aggregate
22+
with:
23+
cutoff_timestamp: 20240101_000000
24+
env:
25+
GITHUB_TOKEN: ${{ env.GITHUB_TOKEN }}
2026
- name: Run compute-benchmarks
2127
shell: bash
2228
run: |
@@ -36,7 +42,8 @@ runs:
3642
3743
EOF
3844
export ONEAPI_DEVICE_SELECTOR="${{ inputs.target_devices }}"
39-
export CMPLR_ROOT=$PWD/toolchain
45+
export CMPLR_ROOT=./toolchain
46+
echo "-----"
4047
sycl-ls
4148
echo "-----"
4249
./devops/scripts/benchmarking/benchmark.sh -n '${{ runner.name }}' -s
@@ -45,19 +52,17 @@ runs:
4552
run: |
4653
# TODO -- waiting on security clearance
4754
# Load configuration values
48-
. "$PWD/devops/scripts/benchmarking/utils.sh"
49-
CONFIG_FILE="$PWD/devops/benchmarking/benchmark-ci.conf"
50-
load_config_constants "$CONFIG_FILE"
55+
$(python ./devops/scripts/benchmarking/load_config.py ./devops constants)
5156
52-
cd "$PERF_RES_PATH"
57+
cd "$SANITIZED_PERF_RES_PATH"
5358
git config user.name "SYCL Benchmarking Bot"
5459
git config user.email "[email protected]"
5560
git add .
5661
git commit -m "[GHA] Upload compute-benchmarks results from https://github.com/intel/llvm/actions/runs/${{ github.run_id }}"
57-
git push "https://[email protected]/$PERF_RES_GIT_REPO.git" "$PERF_RES_BRANCH"
62+
git push "https://[email protected]/$SANITIZED_PERF_RES_GIT_REPO.git" "$SANITIZED_PERF_RES_GIT_BRANCH"
5863
- name: Archive compute-benchmark results
5964
if: always()
6065
uses: actions/upload-artifact@v4
6166
with:
62-
name: Compute-benchmark results (${{ runner.name }})
67+
name: Compute-benchmark run ${{ github.run_id }} (${{ runner.name }})
6368
path: ./artifact

devops/scripts/benchmarking/benchmark.sh

Lines changed: 19 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,22 @@ This script builds and runs benchmarks from compute-benchmarks."
2323
clone_perf_res() {
2424
echo "### Cloning llvm-ci-perf-res ($SANITIZED_PERF_RES_GIT_REPO:$SANITIZED_PERF_RES_GIT_BRANCH) ###"
2525
mkdir -p "$(dirname "$SANITIZED_PERF_RES_PATH")"
26-
git clone -b $SANITIZED_PERF_RES_GIT_BRANCH https://github.com/$SANITIZED_PERF_RES_GIT_REPO $SANITIZED_PERF_RES_PATH
26+
git clone -b "$SANITIZED_PERF_RES_GIT_BRANCH" "https://github.com/$SANITIZED_PERF_RES_GIT_REPO" "$SANITIZED_PERF_RES_PATH"
2727
[ "$?" -ne 0 ] && exit $?
2828
}
2929

3030
clone_compute_bench() {
3131
echo "### Cloning compute-benchmarks ($SANITIZED_COMPUTE_BENCH_GIT_REPO:$SANITIZED_COMPUTE_BENCH_GIT_BRANCH) ###"
3232
mkdir -p "$(dirname "$SANITIZED_COMPUTE_BENCH_PATH")"
33-
git clone -b $SANITIZED_COMPUTE_BENCH_GIT_BRANCH \
34-
--recurse-submodules https://github.com/$SANITIZED_COMPUTE_BENCH_GIT_REPO \
35-
$SANITIZED_COMPUTE_BENCH_PATH
36-
[ "$?" -ne 0 ] && exit $?
33+
git clone -b "$SANITIZED_COMPUTE_BENCH_GIT_BRANCH" \
34+
--recurse-submodules "https://github.com/$SANITIZED_COMPUTE_BENCH_GIT_REPO" \
35+
"$SANITIZED_COMPUTE_BENCH_PATH"
36+
[ "$?" -ne 0 ] && exit "$?"
3737
}
3838

3939
build_compute_bench() {
4040
echo "### Building compute-benchmarks ($SANITIZED_COMPUTE_BENCH_GIT_REPO:$SANITIZED_COMPUTE_BENCH_GIT_BRANCH) ###"
41-
mkdir $SANITIZED_COMPUTE_BENCH_PATH/build && cd $SANITIZED_COMPUTE_BENCH_PATH/build &&
41+
mkdir "$SANITIZED_COMPUTE_BENCH_PATH/build" && cd "$SANITIZED_COMPUTE_BENCH_PATH/build" &&
4242
# No reason to turn on ccache, if this docker image will be disassembled later on
4343
cmake .. -DBUILD_SYCL=ON -DBUILD_L0=OFF -DBUILD=OCL=OFF -DCCACHE_ALLOWED=FALSE
4444
# TODO enable mechanism for opting into L0 and OCL -- the concept is to
@@ -58,38 +58,9 @@ build_compute_bench() {
5858
make "-j$SANITIZED_COMPUTE_BENCH_COMPILE_JOBS" "$case"
5959
done < "$TESTS_CONFIG"
6060
fi
61-
#compute_bench_build_stat=$?
6261
cd -
63-
#[ "$compute_bench_build_stat" -ne 0 ] && exit $compute_bench_build_stat
6462
}
6563

66-
# print_bench_res() {
67-
# # Usage: print_bench_res <benchmark output .csv file> <benchmark status code> <summary file>
68-
# if [ ! -s $1 ]; then
69-
# printf "NO OUTPUT! (Status $2)\n" | tee -a $3
70-
# return # Do not proceed if file is empty
71-
# fi
72-
#
73-
# get_csv_col_index $1 run-time-mean
74-
# tmp_run_time_mean_i=$tmp_csv_col_i
75-
# get_csv_col_index $1 run-time-median
76-
# tmp_run_time_median_i=$tmp_csv_col_i
77-
# get_csv_col_index $1 run-time-throughput
78-
# tmp_run_time_throughput_i=$tmp_csv_col_i
79-
#
80-
# # `sycl-bench` output seems to like inserting the header multiple times.
81-
# # Here we cache the header to make sure it prints only once:
82-
# tmp_header_title="$(cat $1 | head -n 1 | sed 's/^\# Benchmark name/benchmark/')"
83-
# tmp_result="$(cat $1 | grep '^[^\#]')"
84-
#
85-
# printf "%s\n%s" "$tmp_header_title" "$tmp_result" \
86-
# | awk -F',' -v me="$tmp_run_time_mean_i" \
87-
# -v md="$tmp_run_time_median_i" \
88-
# -v th="$tmp_run_time_throughput_i" \
89-
# '{printf "%-57s %-13s %-15s %-20s\n", $1, $me, $md, $th }' \
90-
# | tee -a $3 # Print to summary file
91-
# }
92-
9364
# Check if the number of samples for a given test case is less than a threshold
9465
# set in benchmark-ci.conf
9566
#
@@ -155,6 +126,7 @@ process_benchmarks() {
155126
# Loop through each line of enabled_tests.conf, but ignore lines in the
156127
# test config starting with #'s:
157128
grep "^[^#]" "$TESTS_CONFIG" | while read -r testcase; do
129+
# Make sure testcase is clean:
158130
if [ -n "$(printf "%s" "$testcase" | sed "s/[a-zA-Z_]*//g")" ]; then
159131
echo "Illegal characters in $TESTS_CONFIG."
160132
exit 1
@@ -214,8 +186,8 @@ process_results() {
214186

215187
cleanup() {
216188
echo "### Cleaning up compute-benchmark builds from prior runs ###"
217-
rm -rf $SANITIZED_COMPUTE_BENCH_PATH
218-
rm -rf $SANITIZED_PERF_RES_PATH
189+
rm -rf "$SANITIZED_COMPUTE_BENCH_PATH"
190+
rm -rf "$SANITIZED_PERF_RES_PATH"
219191
[ ! -z "$_exit_after_cleanup" ] && exit
220192
}
221193

@@ -234,9 +206,9 @@ load_configs() {
234206
# Derive /devops based on location of this script:
235207
[ -z "$DEVOPS_PATH" ] && DEVOPS_PATH="$(dirname "$0")/../.."
236208

237-
TESTS_CONFIG="$(realpath $DEVOPS_PATH/benchmarking/enabled_tests.conf)"
238-
COMPARE_PATH="$(realpath $DEVOPS_PATH/scripts/benchmarking/compare.py)"
239-
LOAD_CONFIG_PY="$(realpath $DEVOPS_PATH/scripts/benchmarking/load_config.py)"
209+
TESTS_CONFIG="$(realpath "$DEVOPS_PATH/benchmarking/enabled_tests.conf")"
210+
COMPARE_PATH="$(realpath "$DEVOPS_PATH/scripts/benchmarking/compare.py")"
211+
LOAD_CONFIG_PY="$(realpath "$DEVOPS_PATH/scripts/benchmarking/load_config.py")"
240212

241213
for file in \
242214
"$TESTS_CONFIG" "$COMPARE_PATH" "$LOAD_CONFIG_PY"
@@ -261,17 +233,17 @@ TIMESTAMP="$(date +"$SANITIZED_TIMESTAMP_FORMAT")"
261233

262234
# CLI flags + overrides to configuration options:
263235
while getopts "p:b:r:f:n:cCs" opt; do
264-
case $opt in
265-
p) COMPUTE_BENCH_PATH=$OPTARG ;;
266-
r) COMPUTE_BENCH_GIT_REPO=$OPTARG ;;
267-
b) COMPUTE_BENCH_BRANCH=$OPTARG ;;
268-
f) COMPUTE_BENCH_COMPILE_FLAGS=$OPTARG ;;
269-
n) RUNNER=$OPTARG ;;
236+
case "$opt" in
237+
p) COMPUTE_BENCH_PATH="$OPTARG" ;;
238+
r) COMPUTE_BENCH_GIT_REPO="$OPTARG" ;;
239+
b) COMPUTE_BENCH_BRANCH="$OPTARG" ;;
240+
f) COMPUTE_BENCH_COMPILE_FLAGS="$OPTARG" ;;
241+
n) RUNNER="$OPTARG" ;;
270242
# Cleanup status is saved in a var to ensure all arguments are processed before
271243
# performing cleanup
272244
c) _cleanup=1 ;;
273245
C) _cleanup=1 && _exit_after_cleanup=1 ;;
274-
s) CACHE_RESULTS="1";;
246+
s) CACHE_RESULTS=1;;
275247
\?) usage ;;
276248
esac
277249
done

0 commit comments

Comments
 (0)