Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CI] Add CI workflow to run compute-benchmarks on incoming syclos PRs #14454

Open
wants to merge 159 commits into
base: sycl
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 115 commits
Commits
Show all changes
159 commits
Select commit Hold shift + click to select a range
1276f39
[SYCL] Introduce PoC benchmarking option into sycl-linux-run-tests
ianayl Jul 3, 2024
754c33a
[SYCL] Fix EOF character for sycl-linux-run-tests
ianayl Jul 3, 2024
9981c3a
[SYCL] Fix: Make benchmarking script executable
ianayl Jul 3, 2024
3ed35ca
[SYCL] Bug fix on sycl-bench.sh
ianayl Jul 3, 2024
6ea0110
[SYCL] Amend workflow as per review in #14351
ianayl Jul 4, 2024
6d14a32
Merge branch 'sycl' of https://github.com/intel/llvm into benchmarkin…
ianayl Jul 4, 2024
940e3be
Complete redo of workflow, switch to compute-benchmarks
ianayl Sep 6, 2024
7aafdf5
Add safeguards and update usage(), names
ianayl Sep 12, 2024
24b5169
Change SYCL_PI_TRACE to SYCL_UR_TRACE
ianayl Sep 12, 2024
b2d4463
Test commit to learn more about the workflow
ianayl Sep 12, 2024
5f1cd57
Test commit to integrate building into the workflow
ianayl Sep 12, 2024
7a889f8
Refactor benchmarks out of sycl e2e
ianayl Sep 12, 2024
6e1b3bb
Re-enable benchmarks for testing purposes
ianayl Sep 12, 2024
5d1dea4
temporarily hijack precommit for testing
ianayl Sep 12, 2024
991cd55
temporarily enable benchmark
ianayl Sep 12, 2024
6e141e8
Merge branch 'sycl' of https://github.com/intel/llvm into benchmarkin…
ianayl Sep 12, 2024
8a5ecb6
Set CMPLR_ROOT for run
ianayl Sep 12, 2024
606c02a
Test pushing
ianayl Sep 12, 2024
5dd976e
Enable more debugging
ianayl Sep 12, 2024
6c83d2b
disable post commit temporarily for testing purposes, turn down paral…
ianayl Sep 12, 2024
5266cac
disable ccache
ianayl Sep 12, 2024
ab17254
Take benchmarking out of sycl-linux-run-tests
ianayl Sep 13, 2024
45a93ba
Fix leftover chars
ianayl Sep 13, 2024
a4a1c03
Add missing fields
ianayl Sep 13, 2024
52f5dc3
Disable windows, fix missing fields
ianayl Sep 13, 2024
90575fe
ammend permissions
ianayl Sep 13, 2024
8dfeff6
ammend boolean matching
ianayl Sep 13, 2024
3346a09
change ssh key directory
ianayl Sep 13, 2024
3a28ded
Added options to disable caching
ianayl Sep 16, 2024
e67c29f
attempt to introduce aggregate
ianayl Sep 17, 2024
88f8b3b
Merge branch 'sycl' of https://github.com/intel/llvm into benchmarkin…
ianayl Sep 17, 2024
e6cbc2e
changed permissions to allow aggregate
ianayl Sep 17, 2024
c6645aa
further write permission correction
ianayl Sep 17, 2024
867e6e6
further read permission correction
ianayl Sep 17, 2024
18ff8b1
test amendmnet of build permissions
ianayl Sep 17, 2024
cc29c23
Initial support for time ranges
ianayl Sep 17, 2024
3b5454f
Fixed aggregate, improved logging
ianayl Sep 18, 2024
6ed0361
Change repo used
ianayl Sep 18, 2024
f54e1d2
Resolve issue with using two action/checkout's
ianayl Sep 18, 2024
47693f9
amend location of aggregate
ianayl Sep 18, 2024
f1d3a7f
amend location of aggregate
ianayl Sep 18, 2024
652667f
fix timestamp format in common
ianayl Sep 18, 2024
be75574
fix missing $
ianayl Sep 18, 2024
1200217
fix missing $
ianayl Sep 18, 2024
97b2d4f
exit on error
ianayl Sep 19, 2024
08da292
exit on error
ianayl Sep 19, 2024
441bc10
update config to trigger new run
ianayl Sep 20, 2024
8979115
update config to trigger new run
ianayl Sep 20, 2024
7fa6a2e
Fix up typo
ianayl Sep 20, 2024
1074e42
Merge branch 'sycl' of https://github.com/intel/llvm into benchmarkin…
ianayl Oct 15, 2024
21498b4
Revert permissions on previous files
ianayl Oct 16, 2024
8506c20
Amend permissions to be more strict
ianayl Oct 16, 2024
c2835cd
Amend permissions on aggregate
ianayl Oct 16, 2024
51cdaee
Fix bug with permissions
ianayl Oct 16, 2024
ef6a085
Revert amend
ianayl Oct 16, 2024
2fd6b7b
Amend benchmarks permissions
ianayl Oct 16, 2024
1d5c676
Make build permissions more restrictive
ianayl Oct 16, 2024
c20d75e
Amend benchmark permissions
ianayl Oct 16, 2024
a9dad80
Try new config file loading
ianayl Oct 22, 2024
0c3e901
Fixed sed expression
ianayl Oct 22, 2024
12326ce
trigger workflow
ianayl Oct 22, 2024
4335bf9
Merge branch 'sycl' of https://github.com/intel/llvm into benchmarkin…
ianayl Oct 28, 2024
ba29015
Added iteration options, changed build to each case
ianayl Oct 30, 2024
90fe17f
Add debug prints
ianayl Oct 30, 2024
59e38fe
Make changes to the debug prints
ianayl Oct 30, 2024
d212adc
Upped number of iterations
ianayl Oct 30, 2024
321d83a
increase iterations
ianayl Nov 11, 2024
ba3c45c
Test PVC
ianayl Nov 26, 2024
81fb277
Merge branch 'sycl' into benchmarking-workflow
ianayl Nov 26, 2024
e8178c5
Merge branch 'sycl' of https://github.com/intel/llvm into benchmarkin…
ianayl Jan 2, 2025
410666e
disable igc dev for now
ianayl Jan 2, 2025
c32ad36
fix benchmarking
ianayl Jan 2, 2025
b5fa113
fix benchmarking
ianayl Jan 2, 2025
0ae396d
Introduce separating of results based on runners
ianayl Jan 10, 2025
5d8f864
Merge branch 'sycl' of https://github.com/intel/llvm into benchmarkin…
ianayl Jan 15, 2025
fda62fc
Fix merge fault
ianayl Jan 15, 2025
0a083b8
undo change to build
ianayl Jan 16, 2025
e58248d
Redo changes to build
ianayl Jan 16, 2025
8091ed0
expand build perms
ianayl Jan 16, 2025
d142575
propagate expanded permissions
ianayl Jan 16, 2025
c77f967
Give more perms to benchmark
ianayl Jan 16, 2025
c04ccaa
Remove write perms
ianayl Jan 16, 2025
e4897d5
remove unnecessary permission grant
ianayl Jan 16, 2025
a5b7e23
Remove further write perms
ianayl Jan 16, 2025
6a12cf4
expand benchmark perms
ianayl Jan 16, 2025
f027f8e
Clean up some files before review
ianayl Jan 16, 2025
08388fa
Enable more tests
ianayl Jan 17, 2025
9f7b0ff
Remove non-sycl tests, clean up code
ianayl Jan 17, 2025
30bd28c
Amend bad test case names
ianayl Jan 17, 2025
a3b0487
Merge branch 'sycl' of https://github.com/intel/llvm into benchmarkin…
ianayl Jan 17, 2025
0e4bb7f
Put benchmarking back into sycl-linux-run-tests
ianayl Jan 18, 2025
74bd73c
add benchmark option to sycl-linux-run-tests
ianayl Jan 18, 2025
0282c0a
parallelize aggregate again:
ianayl Jan 18, 2025
66a51f3
Restore CI testing
ianayl Jan 20, 2025
5173a0d
Conditional dependency on aggregate if benchmarking
ianayl Jan 20, 2025
d5a9468
Merge branch 'sycl' of https://github.com/intel/llvm into benchmarkin…
ianayl Jan 20, 2025
867fc5a
Attempt to correct syntax
ianayl Jan 20, 2025
168325f
Add dependency on benchmark_aggregate
ianayl Jan 20, 2025
cf599c0
fix conditional for aggregate
ianayl Jan 20, 2025
96ad8dd
try to trigger aggregate
ianayl Jan 21, 2025
a4f1d5e
try to trigger aggregate
ianayl Jan 21, 2025
7bf79fd
try to trigger aggregate
ianayl Jan 21, 2025
23a21e9
try to trigger aggregate
ianayl Jan 21, 2025
c1c7313
Enable nightly
ianayl Jan 21, 2025
3bdf383
added extra debugging to sus out where the working directories are
ianayl Jan 21, 2025
e9425f5
Prepare workflows for git tokens, add comments
ianayl Jan 21, 2025
6e889d4
Sanitize workflow config variables
ianayl Jan 22, 2025
e158a70
Figure out where aggregate runner paths are
ianayl Jan 22, 2025
bfedd09
Fix paths, update load_single_config
ianayl Jan 22, 2025
d5bfa08
Fix missing apostrophe
ianayl Jan 22, 2025
02428d6
Fix cutoff format
ianayl Jan 22, 2025
54b8fd4
fixed glaring python issues
ianayl Jan 22, 2025
acd1931
Add more documentation
ianayl Jan 22, 2025
38c9bed
Fix bad merges from before
ianayl Jan 22, 2025
6193059
Appease check formatting
ianayl Jan 22, 2025
fcbbe52
Change folder structure
ianayl Jan 23, 2025
e5a12b8
fix bad options in benchmark.sh
ianayl Jan 23, 2025
cf886e9
Apparently posix shell doesn't have herestrings
ianayl Jan 23, 2025
e434d74
Fix config
ianayl Jan 23, 2025
ec8b2f0
add extra debug prints
ianayl Jan 23, 2025
3936328
fix bug
ianayl Jan 23, 2025
dff86d2
add debug for timestamp
ianayl Jan 23, 2025
371097d
oops
ianayl Jan 23, 2025
619c86b
Upload uncached results to artifactory
ianayl Jan 23, 2025
792769e
Update artifacts
ianayl Jan 23, 2025
ec369cd
Fix bug
ianayl Jan 23, 2025
3f1666f
Merge branch 'sycl' of https://github.com/intel/llvm into benchmarkin…
ianayl Jan 23, 2025
07bca84
Fix repository secrets not propagating
ianayl Jan 24, 2025
5d5c755
Improve artifacts
ianayl Jan 24, 2025
40e8b9b
bug fixes
ianayl Jan 24, 2025
7bf8043
needs newline
ianayl Jan 24, 2025
3d366ae
forgot to load artifact path
ianayl Jan 24, 2025
98b1acf
fix artifact path
ianayl Jan 24, 2025
4c13ae7
Move configs out of scripts directory
ianayl Jan 24, 2025
ba9da64
Split config loading into constants and options
ianayl Jan 25, 2025
798e16b
Remove old lines
ianayl Jan 25, 2025
0dea393
Preliminary impl of python config loading, new configs, and changes r…
ianayl Jan 31, 2025
3252b59
Fix typo
ianayl Jan 31, 2025
37612f5
Fix bug
ianayl Jan 31, 2025
6f5074f
Fix bug with timestamp
ianayl Jan 31, 2025
efef394
Sanitize tests conf
ianayl Jan 31, 2025
93456e0
Amend config loading to python, split aggregate workflow
ianayl Feb 3, 2025
625c72f
Fix bug
ianayl Feb 3, 2025
0faada5
fix bug
ianayl Feb 3, 2025
c256b5c
Fix issue with double cloning
ianayl Feb 3, 2025
ab29ffc
Add missing arugment
ianayl Feb 3, 2025
337c51e
fix bugs
ianayl Feb 3, 2025
cdea68d
fix bug
ianayl Feb 3, 2025
beb2942
fix bug
ianayl Feb 3, 2025
f4d8a3f
fix bug
ianayl Feb 3, 2025
572ff7e
Shuffle testing to the end
ianayl Feb 3, 2025
412449e
Hardcode all paths
ianayl Feb 3, 2025
2951b37
apply clang-format
ianayl Feb 3, 2025
bce5229
Remove cutoff timestamp behavior for aggregate
ianayl Feb 3, 2025
5c25a95
Fix typo
ianayl Feb 3, 2025
3e01431
Fix small formatting issues and add comments here and there
ianayl Feb 4, 2025
82c1248
Merge branch 'sycl' of https://github.com/intel/llvm into benchmarkin…
ianayl Feb 4, 2025
ff8675a
fix bug
ianayl Feb 4, 2025
6751d2b
fix bug
ianayl Feb 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions .github/workflows/sycl-benchmark-aggregate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: Aggregate compute-benchmark averages from historical data

# The benchmarking workflow in sycl-linux-run-tests.yml passes or fails based on
# how the benchmark results compare to a historical average: This historical
# average is calculated in this workflow, which aggregates historical data and
# produces measures of central tendency (median in this case) used for this
# purpose.

on:
workflow_dispatch:
inputs:
cutoff_timestamp:
description: |
Timestamp indicating the age limit of data used in average calculation:
Any benchmark results created before this timestamp is excluded from
being aggregated.

Any valid date string supported by GNU coreutils is valid here:
https://www.gnu.org/software/coreutils/manual/html_node/Date-input-formats.html
type: string
required: false
workflow_call:
inputs:
cutoff_timestamp:
type: string
required: false

permissions:
contents: read

jobs:
aggregate:
name: Aggregate average (median) value for all metrics
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
path: llvm
sparse-checkout: |
devops/scripts/benchmarking
- name: Load benchmarking configuration
run: |
CONFIG_FILE="$GITHUB_WORKSPACE/llvm/devops/scripts/benchmarking/benchmark-ci.conf"

# Load default values from configuration file
. "$GITHUB_WORKSPACE/llvm/devops/scripts/benchmarking/utils.sh"
# utils.sh contains functions to sanitize config file settings
load_single_config $CONFIG_FILE PERF_RES_GIT_REPO
load_single_config $CONFIG_FILE PERF_RES_BRANCH
load_single_config $CONFIG_FILE PERF_RES_PATH
echo "PERF_RES_GIT_REPO=$PERF_RES_GIT_REPO" >> $GITHUB_ENV
echo "PERF_RES_BRANCH=$PERF_RES_BRANCH" >> $GITHUB_ENV
echo "PERF_RES_PATH=$PERF_RES_PATH" >> $GITHUB_ENV
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I correct to assume that all these lines do is to read variables from .conf file and add to GITHUB_ENV? If so, can we have a function in utils.sh (say, read_conf_and_populate_github_env) to encapsulate all this? Same with TIMESTAMP_FORMAT, AVERAGE_CUTOFF_RANGE env vars too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds like it'd make life easier, I can add a smaller one next to load_all_configs for GITHUB_ENV only


# Determine a "cutoff timestamp" used by the aggregator script
#
# This timestamp controls which historical results are used to compute
# measures of central tendency: Any files timestamped *before* this time
# will be *excluded* from the central tendency calculation.

load_single_config $CONFIG_FILE TIMESTAMP_FORMAT
echo "TIMESTAMP_FORMAT=$TIMESTAMP_FORMAT" >> $GITHUB_ENV
if [ -z '${{ inputs.cutoff_timestamp }}' ]; then
uditagarwal97 marked this conversation as resolved.
Show resolved Hide resolved
# No time given, use default time period from config file:
load_single_config $CONFIG_FILE AVERAGE_CUTOFF_RANGE
echo "CUTOFF_TIMESTAMP=$(date --date="$AVERAGE_CUTOFF_RANGE" +"$TIMESTAMP_FORMAT")" >> $GITHUB_ENV
else
# If the provided time is a valid GNU coreutils date string, convert
# the time to our format:
_converted_timestamp="$(date --date '${{ inputs.cutoff_timestamp }}' +"$TIMESTAMP_FORMAT" 2> /dev/null)"
if [ -n "$_converted_timestamp" ]; then
echo "CUTOFF_TIMESTAMP=$_converted_timestamp" >> $GITHUB_ENV
else
# If not a valid GNU date string, it could be in our timestamp format already.
# aggregate.py will ensure the timestamp is in the proper format, so we can pass the
# time forward regardless:
echo 'CUTOFF_TIMESTAMP=${{ inputs.cutoff_timestamp }}' >> $GITHUB_ENV
fi
fi
- name: Checkout historical performance results repository
run: |
git clone -b $PERF_RES_BRANCH https://github.com/$PERF_RES_GIT_REPO $PERF_RES_PATH
- name: Run aggregator on historical results
run: |
# The current format of the historical results respository is:
# /<runner type>/<test case name>
# Thus, a min/max depth of 2 is used to enumerate all test cases in the
# repository. Runner type and testcase name is also extracted from this
# path.
for dir in $(find "$PERF_RES_PATH" -mindepth 2 -maxdepth 2 -type d ! -path '*.git*'); do
uditagarwal97 marked this conversation as resolved.
Show resolved Hide resolved
_runner="$(basename $(dirname $dir))"
_testcase="$(basename $dir)"
python llvm/devops/scripts/benchmarking/aggregate.py "$_runner" "$_testcase" "$CUTOFF_TIMESTAMP"
done
- name: Upload average to the repo
env:
GITHUB_TOKEN: ${{ secrets.LLVM_SYCL_BENCHMARK_TOKEN }}
run: |
# TODO -- waiting on security clearance
cd "$PERF_RES_PATH"
git config user.name "SYCL Benchmarking Bot"
git config user.email "[email protected]"
git add .
git commit -m "[GHA] Aggregate median data from $CUTOFF_TIMESTAMP to $(date +"$TIMESTAMP_FORMAT")"
git push "https://[email protected]/$PERF_RES_GIT_REPO.git" "$PERF_RES_BRANCH"
57 changes: 46 additions & 11 deletions .github/workflows/sycl-linux-run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ on:
required: False
tests_selector:
description: |
Two possible options: "e2e" and "cts".
Three possible options: "e2e", "cts", and "benchmark".
type: string
default: "e2e"

Expand Down Expand Up @@ -153,6 +153,7 @@ on:
options:
- e2e
- cts
- benchmark

env:
description: |
Expand Down Expand Up @@ -192,8 +193,14 @@ permissions:
packages: read

jobs:
benchmark_aggregate:
if: ${{ inputs.tests_selector == 'benchmark' }}
name: (Benchmark only) Aggregate benchmark data
uses: ./.github/workflows/sycl-benchmark-aggregate.yml

run:
if: github.event_name == 'workflow_dispatch' || inputs.skip_run == 'false'
if: ${{ always() && ( github.event_name == 'workflow_dispatch' || inputs.skip_run == 'false' ) }}
needs: benchmark_aggregate
name: ${{ inputs.name }}
runs-on: ${{ fromJSON(inputs.runner) }}
container:
Expand Down Expand Up @@ -316,12 +323,12 @@ jobs:
fi

- name: Download E2E Binaries
if: inputs.e2e_binaries_artifact != ''
if: inputs.tests_selector == 'e2e' && inputs.e2e_binaries_artifact != ''
uses: actions/download-artifact@v4
with:
name: ${{ inputs.e2e_binaries_artifact }}
- name: Extract E2E Binaries
if: inputs.e2e_binaries_artifact != ''
if: inputs.tests_selector == 'e2e' && inputs.e2e_binaries_artifact != ''
run: |
mkdir build-e2e
tar -I 'zstd' -xf e2e_binaries.tar.zst -C build-e2e
Expand Down Expand Up @@ -389,25 +396,25 @@ jobs:
ninja -C build-cts -k0 $( [ -n "$CTS_TESTS_TO_BUILD" ] && echo "$CTS_TESTS_TO_BUILD" || echo "test_conformance")

- name: Pack SYCL-CTS binaries
if: always() && !cancelled() && inputs.cts_testing_mode == 'build-only'
if: inputs.tests_selector == 'cts' && always() && !cancelled() && inputs.cts_testing_mode == 'build-only'
run: tar -I 'zstd -9' -cf sycl_cts_bin.tar.zst -C ./build-cts/bin .

- name: Upload SYCL-CTS binaries
if: always() && !cancelled() && inputs.cts_testing_mode == 'build-only'
if: inputs.tests_selector == 'cts' && always() && !cancelled() && inputs.cts_testing_mode == 'build-only'
uses: actions/upload-artifact@v4
with:
name: sycl_cts_bin
path: sycl_cts_bin.tar.zst
retention-days: ${{ inputs.retention-days }}

- name: Download SYCL-CTS binaries
if: inputs.sycl_cts_artifact != ''
if: inputs.tests_selector == 'cts' && inputs.sycl_cts_artifact != ''
uses: actions/download-artifact@v4
with:
name: ${{ inputs.sycl_cts_artifact }}

- name: Extract SYCL-CTS binaries
if: inputs.sycl_cts_artifact != ''
if: inputs.tests_selector == 'cts' && inputs.sycl_cts_artifact != ''
run: |
mkdir -p build-cts/bin
tar -I 'zstd' -xf sycl_cts_bin.tar.zst -C build-cts/bin
Expand All @@ -427,7 +434,7 @@ jobs:
# these files may differ from each other, so when there is a pre-built set of
# tests, we need to filter it according to the filter-file.
- name: Filter SYCL CTS test categories
if: inputs.sycl_cts_artifact != ''
if: inputs.tests_selector == 'cts' && inputs.sycl_cts_artifact != ''
shell: bash
run: |
cts_exclude_filter=""
Expand Down Expand Up @@ -481,12 +488,40 @@ jobs:

exit $ret
- name: Pack E2E binaries
if: ${{ always() && !cancelled() && inputs.e2e_testing_mode == 'build-only'}}
if: inputs.tests_selector == 'e2e' && always() && !cancelled() && inputs.e2e_testing_mode == 'build-only'
run: tar -I 'zstd -9' -cf e2e_binaries.tar.zst -C ./build-e2e .
- name: Upload E2E binaries
if: ${{ always() && !cancelled() && inputs.e2e_testing_mode == 'build-only'}}
if: inputs.tests_selector == 'e2e' && always() && !cancelled() && inputs.e2e_testing_mode == 'build-only'
uses: actions/upload-artifact@v4
with:
name: sycl_e2e_bin_${{ inputs.artifact_suffix }}
path: e2e_binaries.tar.zst
retention-days: ${{ inputs.retention-days }}

- name: Run compute-benchmarks
if: inputs.tests_selector == 'benchmark'
run: |
export ONEAPI_DEVICE_SELECTOR="${{ inputs.target_devices }}"
export CMPLR_ROOT=$PWD/toolchain
sycl-ls
./devops/scripts/benchmarking/benchmark.sh -t '${{ inputs.runner }}' -s
- name: Push compute-benchmarks results
if: inputs.tests_selector == 'benchmark'
env:
GITHUB_TOKEN: ${{ secrets.LLVM_SYCL_BENCHMARK_TOKEN }}
run: |
# TODO -- waiting on security clearance

# Load configuration values
. "./devops/scripts/benchmarking/utils.sh"
CONFIG_FILE="./devops/scripts/benchmarking/benchmark-ci.conf"
load_single_config "$CONFIG_FILE" PERF_RES_PATH
load_single_config "$CONFIG_FILE" PERF_RES_GIT_REPO
load_single_config "$CONFIG_FILE" PERF_RES_BRANCH

cd "$PERF_RES_PATH"
git config user.name "SYCL Benchmarking Bot"
git config user.email "[email protected]"
git add .
git commit -m "[GHA] Upload compute-benchmarks results from ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
git push "https://[email protected]/$PERF_RES_GIT_REPO.git" "$PERF_RES_BRANCH"
27 changes: 27 additions & 0 deletions .github/workflows/sycl-nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,33 @@ jobs:
sycl_toolchain_archive: ${{ needs.ubuntu2204_build.outputs.artifact_archive_name }}
sycl_toolchain_decompress_command: ${{ needs.ubuntu2204_build.outputs.artifact_decompress_command }}
sycl_cts_artifact: sycl_cts_bin

run-sycl-benchmarks:
needs: ubuntu2204_build
if: ${{ always() && !cancelled() && needs.ubuntu2204_build.outputs.build_conclusion == 'success' }}
strategy:
fail-fast: false
matrix:
include:
- name: Compute-benchmarks on L0 Gen12
runner: '["Linux", "gen12"]'
image: ghcr.io/intel/llvm/ubuntu2404_intel_drivers:latest
image_options: -u 1001 --device=/dev/dri -v /dev/dri/by-path:/dev/dri/by-path --privileged --cap-add SYS_ADMIN
target_devices: level_zero:gpu
reset_intel_gpu: true
uses: ./.github/workflows/sycl-linux-run-tests.yml
with:
name: ${{ matrix.name }}
runner: ${{ matrix.runner }}
image: ${{ matrix.image }}
image_options: ${{ matrix.image_options }}
target_devices: ${{ matrix.target_devices }}
tests_selector: benchmark
reset_intel_gpu: ${{ matrix.reset_intel_gpu }}
ref: ${{ github.sha }}
sycl_toolchain_artifact: sycl_linux_default
sycl_toolchain_archive: ${{ needs.ubuntu2204_build.outputs.artifact_archive_name }}
sycl_toolchain_decompress_command: ${{ needs.ubuntu2204_build.outputs.artifact_decompress_command }}

nightly_build_upload:
name: Nightly Build Upload
Expand Down
126 changes: 126 additions & 0 deletions devops/scripts/benchmarking/aggregate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import csv
import sys
from pathlib import Path
import heapq
import statistics

import common


# Simple median calculation
class SimpleMedian:

def __init__(self):
self.elements = []

def add(self, n: float):
self.elements.append(n)

def get_median(self) -> float:
return statistics.median(elements)


# Calculate medians incrementally using a heap: Useful for when dealing with
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i didnt look at these scripts in depth but my initial reaction is they seem really complicated and it seems like it would be really difficult for anyone else to debug them or extend them. is there no prebuild tool, either a linux program or a github action that we can rely on?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would more documentation help? I think a lot of complexity, specifically in aggregate.py, can be removed by simply removing StreamingMedian. However, median would then have to be calculated in a less efficient manner: I'm not sure how this scales with a ton of historical data. Although my short-term goal is for this to run nightly, a less efficient algorithm might not be feasible if e.g. this is to be put into precommit eventually.

As for the complexity of the general project, I'm actually not sure if this is too simple -- The unified runtime team has a whole proper python program written for this here: https://github.com/oneapi-src/unified-runtime/tree/main/scripts/benchmarks. There is plans for me to integrate my solution into theirs when the UR pulldown happens, but the deadline for this workflow was unexpectedly changed to have a hard deadline for next week: I simply cannot wait any longer.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the deadline for this workflow was unexpectedly changed to have a hard deadline for next week:

If it would help, one option may be to use UR scripts in an intel/llvm workflow like this:
https://github.com/EuphoricThinking/unified-memory-framework/blob/benchmark_python9_11_fulljob/.github/workflows/reusable_benchmarks.yml#L144

Reach out to me if you want help.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, if there's any urgent need to run those benchmarks, you can rely on the already set-up unified-runtime infrastructure. It's already possible to run the benchmark workflow with a specific intel/llvm commit and fork. We will just need to grant anyone who needs access to run those workflows (described here: https://github.com/oneapi-src/unified-runtime/tree/main/scripts/benchmarks#running-in-ci).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey thanks for reaching out @pbalcer! Currently it is possible to run this workflow manually to gather the data required, and that's what I've been relying on.

With regards to merging this with the benchmarking infrastructure in the UR, the scope of this workflow has changed: Above running the benchmarks, we are also looking to instrument the benchmarks with a tracing system. This would add extra complexity to just simply running the benchmarks, and I haven't really mulled over how a merge with the UR infrastructure just yet, nevermind if you guys are open to having this in your infrastructure in the first place. I'll reach out to you in private once I have a better picture of how we are going to proceed with this.

# large number of samples.
#
# TODO how many samples are we going to realistically get? I had written this
# with precommit in mind, but if this only runs nightly, it would actually be
# faster to do a normal median calculation.
class StreamingMedian:

def __init__(self):
# Gist: we keep a minheap and a maxheap, and store the median as the top
# of the minheap. When a new element comes it gets put into the heap
# based on if the element is bigger than the current median. Then, the
# heaps are heapified and the median is repopulated by heapify.
self.minheap_larger = []
self.maxheap_smaller = []

# Note: numbers on maxheap should be negative, as heapq
# is minheap by default

def add(self, n: float):
if len(self.maxheap_smaller) == 0 or -self.maxheap_smaller[0] >= n:
heapq.heappush(self.maxheap_smaller, -n)
else:
heapq.heappush(self.minheap_larger, n)

# Ensure minheap has more elements than maxheap
if len(self.maxheap_smaller) > len(self.minheap_larger) + 1:
heapq.heappush(self.minheap_larger, -heapq.heappop(self.maxheap_smaller))
elif len(self.maxheap_smaller) < len(self.minheap_larger):
heapq.heappush(self.maxheap_smaller, -heapq.heappop(self.minheap_larger))

def get_median(self) -> float:
if len(self.maxheap_smaller) == len(self.minheap_larger):
# Equal number of elements smaller and larger than "median":
# thus, there are two median values. The median would then become
# the average of both median values.
return (-self.maxheap_smaller[0] + self.minheap_larger[0]) / 2.0
else:
# Otherwise, median is always in minheap, as minheap is always
# bigger
return -self.maxheap_smaller[0]


def aggregate_median(runner: str, benchmark: str, cutoff: str):

# Get all .csv benchmark samples for the requested runner + benchmark
def csv_samples() -> list[str]:
# TODO check that the path below is valid directory
cache_dir = Path(f"{common.PERF_RES_PATH}/{runner}/{benchmark}")
# TODO check for time range; What time range do I want?
return filter(
lambda f: f.is_file()
and common.valid_timestamp(str(f)[-19:-4])
and str(f)[-19:-4] > cutoff,
cache_dir.glob(f"{benchmark}-*_*.csv"),
)

# Calculate median of every desired metric:
aggregate_s = dict()
for sample_path in csv_samples():
with open(sample_path, "r") as sample_file:
for s in csv.DictReader(sample_file):
test_case = s["TestCase"]
# Construct entry in aggregate_s for test case if it does not
# exist already:
if test_case not in aggregate_s:
aggregate_s[test_case] = {
metric: SimpleMedian() for metric in common.metrics_variance
}

for metric in common.metrics_variance:
aggregate_s[test_case][metric].add(common.sanitize(s[metric]))

# Write calculated median (aggregate_s) as a new .csv file:
with open(
f"{common.PERF_RES_PATH}/{runner}/{benchmark}/{benchmark}-median.csv", "w"
) as output_csv:
writer = csv.DictWriter(
output_csv, fieldnames=["TestCase", *common.metrics_variance.keys()]
)
writer.writeheader()
for test_case in aggregate_s:
writer.writerow(
{"TestCase": test_case}
| {
metric: aggregate_s[test_case][metric].get_median()
for metric in common.metrics_variance
}
)


if __name__ == "__main__":
if len(sys.argv) < 4:
print(
f"Usage: {sys.argv[0]} <runner name> <test case name> <cutoff date YYYYMMDD_HHMMSS>"
)
exit(1)
if not common.valid_timestamp(sys.argv[3]):
print(sys.argv)
print(f"Bad cutoff timestamp, please use YYYYMMDD_HHMMSS.")
exit(1)
common.load_configs()
# <runner>, <test case>, <cutoff>
aggregate_median(sys.argv[1], sys.argv[2], sys.argv[3])
Loading
Loading