Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 6efbb42

Browse files
authoredAug 29, 2024··
Add benchmarking CI that generates graphs on updates to master (#544)
This PR adds a CI workflow that generates performance graphs on every update to master. It stores the data as json in the `gh-pages` branch and renders the graphs on a Github Page. Here's [an example](https://galoisinc.github.io/cerberus/dev/bench/) of what this looks like with [dummy data](https://github.com/GaloisInc/cerberus/blob/gh-pages/dev/bench/data.js). This currently runs `cn` on all the .c files in the test suite. Eventually, we probably want to make a proper benchmark suite using something like [Core_bench](https://blog.janestreet.com/core_bench-micro-benchmarking-for-ocaml/). It relies upon the existence of the (currently empty) `gh-pages` branch. Implements part of rems-project/cn-tutorial/issues/54.
1 parent 9dcd80b commit 6efbb42

File tree

2 files changed

+163
-0
lines changed

2 files changed

+163
-0
lines changed
 

‎.github/workflows/ci-bench.yml

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
name: CI Benchmarks
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
8+
env:
9+
CERBERUS_IMAGE_ID: ghcr.io/rems-project/cerberus/cn:release
10+
11+
permissions:
12+
# deployments permission to deploy GitHub pages website
13+
deployments: write
14+
# contents permission to update benchmark contents in gh-pages branch
15+
contents: write
16+
17+
# cancel in-progress job when a new push is performed
18+
concurrency:
19+
group: ci-bench-${{ github.workflow }}-${{ github.ref }}
20+
cancel-in-progress: true
21+
22+
jobs:
23+
benchmark:
24+
name: Performance benchmarks
25+
strategy:
26+
matrix:
27+
# version: [4.12.0, 4.14.1]
28+
version: [4.14.1]
29+
30+
31+
runs-on: ubuntu-22.04
32+
33+
steps:
34+
- uses: actions/checkout@v3
35+
36+
- name: System dependencies (ubuntu)
37+
run: |
38+
sudo apt install build-essential libgmp-dev z3 opam cmake jq
39+
40+
- name: Restore cached opam
41+
id: cache-opam-restore
42+
uses: actions/cache/restore@v4
43+
with:
44+
path: ~/.opam
45+
key: ${{ matrix.version }}
46+
47+
- name: Setup opam
48+
if: steps.cache-opam-restore.outputs.cache-hit != 'true'
49+
run: |
50+
opam init --yes --no-setup --shell=sh --compiler=${{ matrix.version }}
51+
opam install --deps-only --yes ./cerberus-lib.opam
52+
opam switch create with_coq ${{ matrix.version }}
53+
eval $(opam env --switch=with_coq)
54+
opam repo add --yes --this-switch coq-released https://coq.inria.fr/opam/released
55+
opam pin --yes -n coq-struct-tact https://github.com/uwplse/StructTact.git
56+
opam repo add --yes --this-switch iris-dev https://gitlab.mpi-sws.org/iris/opam.git
57+
opam pin --yes -n coq-sail-stdpp https://github.com/rems-project/coq-sail.git#f319aad
58+
opam pin --yes -n coq-cheri-capabilities https://github.com/rems-project/coq-cheri-capabilities.git
59+
opam install --deps-only --yes ./cerberus-lib.opam ./cerberus-cheri.opam
60+
61+
- name: Save cached opam
62+
if: steps.cache-opam-restore.outputs.cache-hit != 'true'
63+
id: cache-opam-save
64+
uses: actions/cache/save@v4
65+
with:
66+
path: ~/.opam
67+
key: ${{ steps.cache-opam-restore.outputs.cache-primary-key }}
68+
69+
- name: Install Cerberus
70+
run: |
71+
opam switch ${{ matrix.version }}
72+
eval $(opam env --switch=${{ matrix.version }})
73+
opam pin --yes --no-action add cerberus-lib .
74+
opam pin --yes --no-action add cerberus .
75+
opam install --yes cerberus
76+
77+
- name: Download cvc5 release
78+
uses: robinraju/release-downloader@v1
79+
with:
80+
repository: cvc5/cvc5
81+
tag: cvc5-1.1.2
82+
fileName: cvc5-Linux-static.zip
83+
84+
- name: Unzip and install cvc5
85+
run: |
86+
unzip cvc5-Linux-static.zip
87+
chmod +x cvc5-Linux-static/bin/cvc5
88+
sudo cp cvc5-Linux-static/bin/cvc5 /usr/local/bin/
89+
90+
- name: Install CN
91+
run: |
92+
opam switch ${{ matrix.version }}
93+
eval $(opam env --switch=${{ matrix.version }})
94+
opam pin --yes --no-action add cn .
95+
opam install --yes cn ocamlformat.0.26.2
96+
97+
- name: Run benchmark
98+
run: |
99+
opam switch ${{ matrix.version }}
100+
eval $(opam env --switch=${{ matrix.version }})
101+
cd tests; USE_OPAM='' ./run-ci-benchmarks.sh
102+
cd ..
103+
104+
- name: Store benchmark result
105+
uses: benchmark-action/github-action-benchmark@v1
106+
with:
107+
name: CN Benchmarks
108+
tool: 'customSmallerIsBetter'
109+
output-file-path: tests/benchmark-data.json
110+
# Access token to deploy GitHub Pages branch
111+
github-token: ${{ secrets.GITHUB_TOKEN }}
112+
# Push and deploy GitHub pages branch automatically
113+
auto-push: true

‎tests/run-ci-benchmarks.sh

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail -o noclobber
3+
# set -xv # uncomment to debug variables
4+
5+
JSON_FILE="benchmark-data.json"
6+
7+
echo "[" >> "${JSON_FILE}"
8+
9+
DIRNAME=$(dirname "$0")
10+
11+
TESTS=$(find "${DIRNAME}"/cn -name '*.c')
12+
13+
COUNT=0
14+
for TEST in ${TESTS}; do
15+
let COUNT=${COUNT}+1
16+
done
17+
18+
INDEX=0
19+
for TEST in ${TESTS}; do
20+
21+
# Record wall clock time in seconds
22+
/usr/bin/time --quiet -f "%e" -o /tmp/time cn verify "${TEST}" || true
23+
TIME=$(cat /tmp/time)
24+
25+
# If we're last, don't print a trailing comma.
26+
if [[ ${INDEX} -eq ${COUNT}-1 ]]; then
27+
# Hack to output JSON.
28+
cat << EOF >> ${JSON_FILE}
29+
{
30+
"name": "${TEST}",
31+
"unit": "Seconds",
32+
"value": ${TIME}
33+
}
34+
EOF
35+
else
36+
cat << EOF >> ${JSON_FILE}
37+
{
38+
"name": "${TEST}",
39+
"unit": "Seconds",
40+
"value": ${TIME}
41+
},
42+
EOF
43+
fi
44+
45+
let INDEX=${INDEX}+1
46+
done
47+
48+
echo "]" >> "${JSON_FILE}"
49+
50+
jq . "${JSON_FILE}"

0 commit comments

Comments
 (0)
Please sign in to comment.