Skip to content

Commit fcbbe52

Browse files
committed
Change folder structure
1 parent 6193059 commit fcbbe52

File tree

7 files changed

+190
-140
lines changed

7 files changed

+190
-140
lines changed

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,14 @@ jobs:
8383
- name: Run aggregator on historical results
8484
run: |
8585
# The current format of the historical results respository is:
86-
# /<runner type>/<test case name>
87-
# Thus, a min/max depth of 2 is used to enumerate all test cases in the
88-
# repository. Runner type and testcase name is also extracted from this
89-
# path.
90-
for dir in $(find "$PERF_RES_PATH" -mindepth 2 -maxdepth 2 -type d ! -path '*.git*'); do
91-
_runner="$(basename $(dirname $dir))"
92-
_testcase="$(basename $dir)"
93-
python llvm/devops/scripts/benchmarking/aggregate.py "$_runner" "$_testcase" "$CUTOFF_TIMESTAMP"
86+
#
87+
# /<ONEAPI_DEVICE_SELECTOR>/<runner>/<test name>
88+
#
89+
# Thus, a min/max depth of 3 is used to enumerate all test cases in the
90+
# repository. Test name is also derived from here.
91+
for dir in $(find "$PERF_RES_PATH" -mindepth 3 -maxdepth 3 -type d ! -path '*.git*'); do
92+
test_name="$(basename $dir)"
93+
python llvm/devops/scripts/benchmarking/aggregate.py "$test_name" "$dir" "$CUTOFF_TIMESTAMP"
9494
done
9595
- name: Upload average to the repo
9696
env:

devops/scripts/benchmarking/aggregate.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,18 +63,18 @@ def get_median(self) -> float:
6363
return -self.maxheap_smaller[0]
6464

6565

66-
def aggregate_median(runner: str, benchmark: str, cutoff: str):
66+
def aggregate_median(test_name: str, test_dir: str, cutoff: str):
6767

68-
# Get all .csv benchmark samples for the requested runner + benchmark
68+
# Get all .csv samples for the requested test folder
6969
def csv_samples() -> list[str]:
7070
# TODO check that the path below is valid directory
71-
cache_dir = Path(f"{common.PERF_RES_PATH}/{runner}/{benchmark}")
71+
cache_dir = Path(f"{test_dir}")
7272
# TODO check for time range; What time range do I want?
7373
return filter(
7474
lambda f: f.is_file()
7575
and common.valid_timestamp(str(f)[-19:-4])
7676
and str(f)[-19:-4] > cutoff,
77-
cache_dir.glob(f"{benchmark}-*_*.csv"),
77+
cache_dir.glob(f"{test_name}-*_*.csv"),
7878
)
7979

8080
# Calculate median of every desired metric:
@@ -95,7 +95,7 @@ def csv_samples() -> list[str]:
9595

9696
# Write calculated median (aggregate_s) as a new .csv file:
9797
with open(
98-
f"{common.PERF_RES_PATH}/{runner}/{benchmark}/{benchmark}-median.csv", "w"
98+
f"{test_dir}/{test_name}-median.csv", "w"
9999
) as output_csv:
100100
writer = csv.DictWriter(
101101
output_csv, fieldnames=["TestCase", *common.metrics_variance.keys()]
@@ -114,13 +114,13 @@ def csv_samples() -> list[str]:
114114
if __name__ == "__main__":
115115
if len(sys.argv) < 4:
116116
print(
117-
f"Usage: {sys.argv[0]} <runner name> <test case name> <cutoff date YYYYMMDD_HHMMSS>"
117+
f"Usage: {sys.argv[0]} <test name> <absolute path to test directory> <cutoff timestamp YYYYMMDD_HHMMSS>"
118118
)
119119
exit(1)
120120
if not common.valid_timestamp(sys.argv[3]):
121121
print(sys.argv)
122122
print(f"Bad cutoff timestamp, please use YYYYMMDD_HHMMSS.")
123123
exit(1)
124124
common.load_configs()
125-
# <runner>, <test case>, <cutoff>
125+
126126
aggregate_median(sys.argv[1], sys.argv[2], sys.argv[3])

devops/scripts/benchmarking/benchmark-ci.conf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,6 @@ BENCHMARK_SLOW_LOG="./benchmarks-over_tolerance.log"
4545
# Log file for test cases that errored / failed to build
4646
BENCHMARK_ERROR_LOG="./benchmarks-errored.log"
4747

48-
# Runner types to parse from runner tag
49-
RUNNER_TYPES="arc,pvc,amdgpu,cuda,gen12"
50-
# These type names will be used to separate benchmark results based on hardware
48+
# Enabled ONEAPI_DEVICE_SELECTOR backends
49+
DEVICE_SELECTOR_ENABLED_BACKENDS="level_zero,opencl,cuda,hip" # Disabled: native_cpu
50+
DEVICE_SELECTOR_ENABLED_DEVICES="cpu,gpu" # Disabled: fpga

devops/scripts/benchmarking/benchmark.sh

Lines changed: 85 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
usage () {
88
>&2 echo "Usage: $0 <compute-benchmarks git repo> -t <runner type> [-B <compute-benchmarks build path>]
9-
-t Specify runner type -- Required
9+
-n Github runner name -- Required
1010
-B Path to clone and build compute-benchmarks on
1111
-p Path to compute-benchmarks (or directory to build compute-benchmarks in)
1212
-r Github repo to use for compute-benchmarks origin, in format <org>/<name>
@@ -84,45 +84,51 @@ build_compute_bench() {
8484
# | tee -a $3 # Print to summary file
8585
# }
8686

87-
###
88-
STATUS_SUCCESS=0
89-
STATUS_ERROR=1
90-
###
91-
9287
# Check if the number of samples for a given test case is less than a threshold
9388
# set in benchmark-ci.conf
89+
#
90+
# Usage: <relative path of directory containing test case results>
9491
samples_under_threshold () {
95-
mkdir -p $1
96-
file_count="$(find $1 -maxdepth 1 -type f | wc -l )"
92+
[ ! -d "$PERF_RES_PATH/$1" ] && return 1 # Directory doesn't exist
93+
file_count="$(find "$PERF_RES_PATH/$1" -maxdepth 1 -type f | wc -l )"
9794
[ "$file_count" -lt "$AVERAGE_THRESHOLD" ]
9895
}
9996

97+
# Check for a regression via compare.py
98+
#
99+
# Usage: check_regression <relative path of output csv>
100100
check_regression() {
101-
if samples_under_threshold "$PERF_RES_PATH/$RUNNER/$1"; then
102-
echo "Not enough samples to construct an average, performance check skipped!"
103-
return $STATUS_SUCCESS
101+
csv_relpath="$(dirname $1)"
102+
csv_name="$(basename $1)"
103+
if samples_under_threshold "$csv_relpath"; then
104+
echo "Not enough samples to construct a good average, performance\
105+
check skipped!"
106+
return 0 # Success status
104107
fi
105-
BENCHMARKING_ROOT="$BENCHMARKING_ROOT" python "$BENCHMARKING_ROOT/compare.py" "$RUNNER" "$1" "$2"
108+
BENCHMARKING_ROOT="$BENCHMARKING_ROOT" \
109+
python "$BENCHMARKING_ROOT/compare.py" "$csv_relpath" "$csv_name"
106110
return $?
107111
}
108112

109113
# Move the results of our benchmark into the git repo
114+
#
115+
# Usage: cache <relative path of output csv>
110116
cache() {
111-
mv "$2" "$PERF_RES_PATH/$RUNNER/$1/"
117+
mv "$OUTPUT_PATH/$1" "$PERF_RES_PATH/$1"
112118
}
113119

114-
# Check for a regression, and cache if no regression found
120+
# Check for a regression + cache if no regression found
121+
#
122+
# Usage: check_and_cache <relative path of output csv>
115123
check_and_cache() {
116-
echo "Checking $testcase..."
117-
if check_regression $1 $2; then
124+
echo "Checking $1..."
125+
if check_regression $1; then
118126
if [ "$CACHE_RESULTS" -eq "1" ]; then
119-
echo "Caching $testcase..."
120-
cache $1 $2
127+
echo "Caching $1..."
128+
cache $1
121129
fi
122130
else
123-
if [ "$CACHE_RESULTS" -eq "1" ]; then
124-
echo "Not caching!"
125-
fi
131+
[ "$CACHE_RESULTS" -eq "1" ] && echo "Regression found -- Not caching!"
126132
fi
127133
}
128134

@@ -133,24 +139,39 @@ process_benchmarks() {
133139
echo "### Running and processing selected benchmarks ###"
134140
if [ -z "$TESTS_CONFIG" ]; then
135141
echo "Setting tests to run via cli is not currently supported."
136-
exit $STATUS_ERROR
142+
exit 1
137143
else
138144
rm "$BENCHMARK_ERROR_LOG" "$BENCHMARK_SLOW_LOG" 2> /dev/null
139-
# Ignore lines in the test config starting with #'s
145+
# Loop through each line of enabled_tests.conf, but ignore lines in the
146+
# test config starting with #'s:
140147
grep "^[^#]" "$TESTS_CONFIG" | while read -r testcase; do
141148
echo "# Running $testcase..."
142149

143-
test_csv_output="$OUTPUT_PATH/$RUNNER/$testcase-$TIMESTAMP.csv"
144-
mkdir -p "$OUTPUT_PATH/$RUNNER/"
145-
$COMPUTE_BENCH_PATH/build/bin/$testcase --csv --iterations="$COMPUTE_BENCH_ITERATIONS" | tail +8 > "$test_csv_output"
146-
# The tail +8 filters out initial debug prints not in csv format
150+
# The benchmark results git repo and this script's output both share
151+
# the following directory structure:
152+
#
153+
# /<device selector>/<runner>/<test name>
154+
#
155+
# Figure out the relative path of our testcase result in both
156+
# directories:
157+
test_dir_relpath="$DEVICE_SELECTOR_DIRNAME/$RUNNER/$testcase"
158+
mkdir -p "$OUTPUT_PATH/$test_dir_relpath" # Ensure directory exists
159+
# TODO generate runner config txt if not exist
160+
output_csv_relpath="$test_dir_relpath/$testcase-$TIMESTAMP.csv"
161+
162+
output_csv="$OUTPUT_PATH/$output_csv_relpath" # Real output path
163+
$COMPUTE_BENCH_PATH/build/bin/$testcase --csv \
164+
--iterations="$COMPUTE_BENCH_ITERATIONS" \
165+
| tail +8 > "$output_csv"
166+
# The tail +8 filters out header lines not in csv format
147167

148-
if [ "$?" -eq 0 ] && [ -s "$test_csv_output" ]; then
149-
check_and_cache $testcase $test_csv_output
168+
exit_status="$?"
169+
if [ "$exit_status" -eq 0 ] && [ -s "$output_csv" ]; then
170+
check_and_cache $output_csv_relpath
150171
else
151-
# TODO consider capturing error for logging
152-
echo "ERROR @ $test_case"
153-
echo "-- $testcase: error $?" >> "$BENCHMARK_ERROR_LOG"
172+
# TODO consider capturing stderr for logging
173+
echo "[ERROR] $testcase returned exit status $exit_status"
174+
echo "-- $testcase: error $exit_status" >> "$BENCHMARK_ERROR_LOG"
154175
fi
155176
done
156177
fi
@@ -163,13 +184,13 @@ process_results() {
163184
printf "\n### Tests performing over acceptable range of average: ###\n"
164185
cat "$BENCHMARK_SLOW_LOG"
165186
echo ""
166-
fail=1
187+
fail=2
167188
fi
168189
if [ -s "$BENCHMARK_ERROR_LOG" ]; then
169190
printf "\n### Tests that failed to run: ###\n"
170191
cat "$BENCHMARK_ERROR_LOG"
171192
echo ""
172-
fail=2
193+
fail=1
173194
fi
174195
exit $fail
175196
}
@@ -203,40 +224,24 @@ load_configs() {
203224

204225
. $BENCHMARKING_ROOT/utils.sh
205226
load_all_configs "$BENCHMARK_CI_CONFIG"
206-
207-
# Debug
208-
# echo "PERF_RES_GIT_REPO: $PERF_RES_GIT_REPO"
209-
# echo "PERF_RES_BRANCH: $PERF_RES_BRANCH"
210-
# echo "PERF_RES_PATH: $PERF_RES_PATH"
211-
# echo "COMPUTE_BENCH_GIT_REPO: $COMPUTE_BENCH_GIT_REPO"
212-
# echo "COMPUTE_BENCH_BRANCH: $COMPUTE_BENCH_BRANCH"
213-
# echo "COMPUTE_BENCH_PATH: $COMPUTE_BENCH_PATH"
214-
# echo "COMPUTE_BENCH_COMPILE_FLAGS: $COMPUTE_BENCH_COMPILE_FLAGS"
215-
# echo "OUTPUT_PATH: $OUTPUT_PATH"
216-
# echo "METRICS_VARIANCE: $METRICS_VARIANCE"
217-
# echo "METRICS_RECORDED: $METRICS_RECORDED"
218-
# echo "AVERAGE_THRESHOLD: $AVERAGE_THRESHOLD"
219-
# echo "AVERAGE_CUTOFF_RANGE: $AVERAGE_CUTOFF_RANGE"
220-
# echo "TIMESTAMP_FORMAT: $TIMESTAMP_FORMAT"
221-
# echo "BENCHMARK_SLOW_LOG: $BENCHMARK_SLOW_LOG"
222-
# echo "BENCHMARK_ERROR_LOG: $BENCHMARK_ERROR_LOG"
223-
echo "Configured runner types: $RUNNER_TYPES"
224227
}
225228

226-
load_configs
229+
#####
227230

228231
COMPUTE_BENCH_COMPILE_FLAGS=""
229232
CACHE_RESULTS="0"
230233
TIMESTAMP="$(date +"$TIMESTAMP_FORMAT")"
231234

232-
# CLI overrides to configuration options
233-
while getopts "p:b:r:f:t:cCs" opt; do
235+
load_configs
236+
237+
# CLI flags + overrides to configuration options:
238+
while getopts "p:b:r:f:n:cCs" opt; do
234239
case $opt in
235240
p) COMPUTE_BENCH_PATH=$OPTARG ;;
236241
r) COMPUTE_BENCH_GIT_REPO=$OPTARG ;;
237242
b) COMPUTE_BENCH_BRANCH=$OPTARG ;;
238243
f) COMPUTE_BENCH_COMPILE_FLAGS=$OPTARG ;;
239-
t) RUNNER_TYPE=$OPTARG ;;
244+
n) RUNNER=$OPTARG ;;
240245
# Cleanup status is saved in a var to ensure all arguments are processed before
241246
# performing cleanup
242247
c) _cleanup=1 ;;
@@ -246,28 +251,40 @@ while getopts "p:b:r:f:t:cCs" opt; do
246251
esac
247252
done
248253

254+
# Check all necessary variables exist:
249255
if [ -z "$CMPLR_ROOT" ]; then
250256
echo "Please set \$CMPLR_ROOT first; it is needed by compute-benchmarks to build."
251257
exit 1
258+
elif [ -z "$ONEAPI_DEVICE_SELECTOR" ]; then
259+
echo "Please set \$ONEAPI_DEVICE_SELECTOR first to specify which device to use."
260+
exit 1
261+
elif [ -z "$RUNNER" ]; then
262+
echo "Please specify runner name using -n first; it is needed for storing/comparing benchmark results."
263+
exit 1
252264
fi
253-
if [ -z "$RUNNER_TYPE" ]; then
254-
echo "Please specify runner type using -t first; it is needed for comparing benchmark results"
265+
266+
# Make sure ONEAPI_DEVICE_SELECTOR doesn't try to enable multiple devices at the
267+
# same time, or use specific device id's
268+
_dev_sel_backend_re="$(sed 's/,/|/g' <<< "$DEVICE_SELECTOR_ENABLED_BACKENDS")"
269+
_dev_sel_device_re="$(sed 's/,/|/g' <<< "$DEVICE_SELECTOR_ENABLED_DEVICES")"
270+
_dev_sel_re="s/($_dev_sel_backend_re):($_dev_sel_device_re)//"
271+
if [ -n "$(sed -E "$_dev_sel_re" <<< "$ONEAPI_DEVICE_SELECTOR" )" ]; then
272+
echo "Unsupported \$ONEAPI_DEVICE_SELECTOR value: please ensure only one \
273+
device is selected, and devices are not selected by indices."
274+
echo "Enabled backends: $DEVICE_SELECTOR_ENABLED_BACKENDS"
275+
echo "Enabled device types: $DEVICE_SELECTOR_ENABLED_DEVICES"
255276
exit 1
256-
else
257-
# Identify runner being used
258-
runner_regex="$(printf "$RUNNER_TYPES" | sed 's/,/|/g')"
259-
RUNNER="$(printf "$RUNNER_TYPE" | grep -o -E "\b($runner_regex)\b")"
260-
if [ -z "$RUNNER" ]; then
261-
echo "Unknown runner type! Configured runners: $RUNNER_TYPES"
262-
exit 1
263-
fi
264-
echo "Chosen runner: $RUNNER"
265277
fi
278+
# ONEAPI_DEVICE_SELECTOR values are not valid directory names in unix: this
279+
# value lets us use ONEAPI_DEVICE_SELECTOR as actual directory names
280+
DEVICE_SELECTOR_DIRNAME="$(sed 's/:/-/' <<< "$ONEAPI_DEVICE_SELECTOR")"
266281

282+
# Clean up and delete all cached files if specified:
267283
[ ! -z "$_cleanup" ] && cleanup
268-
284+
# Clone and build only if they aren't already cached/deleted:
269285
[ ! -d "$PERF_RES_PATH" ] && clone_perf_res
270286
[ ! -d "$COMPUTE_BENCH_PATH" ] && clone_compute_bench
271287
[ ! -d "$COMPUTE_BENCH_PATH/build" ] && build_compute_bench
288+
# Process benchmarks:
272289
process_benchmarks
273290
process_results

devops/scripts/benchmarking/common.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
def sanitize(stat: str) -> float:
1111
# Get rid of %
12-
if stat[-1] == '%':
12+
if stat[-1] == "%":
1313
stat = stat[:-1]
1414
return float(stat)
1515

@@ -24,15 +24,16 @@ def load_configs():
2424
if not os.path.isfile(benchmarking_ci_conf_path):
2525
raise Exception(f"Please provide path to a valid BENCHMARKING_ROOT.")
2626

27-
global PERF_RES_PATH, metrics_variance, metrics_recorded
27+
global PERF_RES_PATH, OUTPUT_PATH, metrics_variance, metrics_recorded
2828
global BENCHMARK_ERROR_LOG, BENCHMARK_SLOW_LOG
29-
perf_res_re = re.compile(r'^PERF_RES_PATH=(.*)$', re.M)
30-
m_variance_re = re.compile(r'^METRICS_VARIANCE=(.*)$', re.M)
31-
m_recorded_re = re.compile(r'^METRICS_RECORDED=(.*)$', re.M)
32-
b_slow_re = re.compile(r'^BENCHMARK_SLOW_LOG=(.*)$', re.M)
33-
b_error_re = re.compile(r'^BENCHMARK_ERROR_LOG=(.*)$', re.M)
29+
perf_res_re = re.compile(r"^PERF_RES_PATH=(.*)$", re.M)
30+
output_path_re = re.compile(r"^OUTPUT_PATH=(.*)$", re.M)
31+
m_variance_re = re.compile(r"^METRICS_VARIANCE=(.*)$", re.M)
32+
m_recorded_re = re.compile(r"^METRICS_RECORDED=(.*)$", re.M)
33+
b_slow_re = re.compile(r"^BENCHMARK_SLOW_LOG=(.*)$", re.M)
34+
b_error_re = re.compile(r"^BENCHMARK_ERROR_LOG=(.*)$", re.M)
3435

35-
with open(benchmarking_ci_conf_path, 'r') as configs_file:
36+
with open(benchmarking_ci_conf_path, "r") as configs_file:
3637
configs_str = configs_file.read()
3738

3839
for m_variance in m_variance_re.findall(configs_str):
@@ -48,6 +49,9 @@ def load_configs():
4849
for perf_res in perf_res_re.findall(configs_str):
4950
PERF_RES_PATH = str(perf_res[1:-1])
5051

52+
for output_path in output_path_re.findall(configs_str):
53+
OUTPUT_PATH = str(output_path[1:-1])
54+
5155
for b_slow_log in b_slow_re.findall(configs_str):
5256
BENCHMARK_SLOW_LOG = str(b_slow_log[1:-1])
5357

@@ -58,6 +62,6 @@ def load_configs():
5862
def valid_timestamp(timestamp: str) -> bool:
5963
timestamp_re = re.compile(
6064
# YYYYMMDD_HHMMSS
61-
r'^\d{4}(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])_(0[0-9]|1[0-9]|2[0-3])[0-5][0-9][0-5][0-9]$'
65+
r"^\d{4}(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])_(0[0-9]|1[0-9]|2[0-3])[0-5][0-9][0-5][0-9]$"
6266
)
6367
return timestamp_re.match(timestamp) is not None

0 commit comments

Comments
 (0)