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: set up a CI job for automated benchmarking (Linux, Python 3.9) #129

Open
wants to merge 1 commit into
base: meson
Choose a base branch
from
Open
Changes from all commits
Commits
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
121 changes: 121 additions & 0 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
name: Benchmark CI

on:
pull_request:
Copy link
Owner

Choose a reason for hiding this comment

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

I don't think we want to run this job on PRs - it takes too long.

Copy link
Owner

Choose a reason for hiding this comment

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

Same for branches. I think the best would be a scheduled job, say once every 3 days.

Copy link
Author

@HarshCasper HarshCasper Feb 2, 2022

Choose a reason for hiding this comment

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

My idea here was to run this on specific PRs with a specific label, like run-benchmarks. It would be quite useful for significant PRs, especially around releases. Please let me know your thoughts, otherwise, I would just remove this.

Copy link
Owner

Choose a reason for hiding this comment

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

I like that idea. That's even better than regularly scheduled runs, very user-friendly.

Can you make the label ci/run-benchmarks? Then we can later extend the pattern with ci/other-job-to-run. PyTorch has this too, and it's quite nice.

Copy link
Author

Choose a reason for hiding this comment

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

Sure, I will make this change.

branches:
- meson
- master
# types: [labeled]

# workflow_dispatch:
Copy link
Owner

Choose a reason for hiding this comment

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

can be uncommented?


env:
CCACHE_DIR: "${{ github.workspace }}/.ccache"
INSTALLDIR: "installdir"

jobs:
benchmark:
name: Benchmark
# if: ${{ github.event.label.name == 'run_benchmark' && github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' }}
Copy link
Owner

Choose a reason for hiding this comment

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

Uncomment, and add the protections for not running on a fork (see the linux_meson job)?

runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.9]

steps:
- uses: actions/checkout@v2
with:
submodules: recursive

- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}

- name: Install Ubuntu dependencies
run: |
# NOTE: not the same OpenBLAS version as in upstream CI (I'm being lazy here)
sudo apt-get update
sudo apt-get install -y libopenblas-dev libatlas-base-dev liblapack-dev gfortran libgmp-dev libmpfr-dev libsuitesparse-dev ccache libmpc-dev
- name: Caching Python dependencies
uses: actions/cache@v2
id: cache
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip

- name: Install Python packages
run: |
python -m pip install numpy setuptools wheel cython asv pytest pytest-xdist pybind11 pytest-xdist mpmath gmpy2 pythran ninja
python -m pip install git+https://github.com/mesonbuild/meson.git@master
Copy link
Owner

Choose a reason for hiding this comment

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

This can now be replaced by python -m pip install meson==0.61.1


- name: Prepare compiler cache
id: prep-ccache
shell: bash
run: |
mkdir -p "${CCACHE_DIR}"
echo "::set-output name=dir::$CCACHE_DIR"
NOW=$(date -u +"%F-%T")
echo "::set-output name=timestamp::${NOW}"

- name: Setup compiler cache
uses: actions/cache@v2
id: cache-ccache
# Reference: https://docs.github.com/en/actions/guides/caching-dependencies-to-speed-up-workflows#matching-a-cache-key
# NOTE: The caching strategy is modeled in a way that it will always have a unique cache key for each workflow run
# (even if the same workflow is run multiple times). The restore keys are not unique and for a partial match, they will
# return the most recently created cache entry, according to the GitHub Action Docs.
with:
path: ${{ steps.prep-ccache.outputs.dir }}
# Restores ccache from either a previous build on this branch or on master
key: ${{ github.workflow }}-${{ matrix.python-version }}-ccache-linux-${{ steps.prep-ccache.outputs.timestamp }}
# This evaluates to `Benchmark CI-3.9-ccache-linux-` which is not unique. As the CI matrix is expanded, this will
# need to be updated to be unique so that the cache is not restored from a different job altogether.
restore-keys: |
${{ github.workflow }}-${{ matrix.python-version }}-ccache-linux-

- name: Setup build and install scipy
run: |
python dev.py -j 2 --build-only --werror
Copy link
Owner

Choose a reason for hiding this comment

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

Let's remove --werror here; it is best-practice to have that only in a single CI job (at least on the same platform).


- name: Ccache performance
shell: bash -l {0}
run: ccache -s

- name: Run Benchmarks
id: benchmark
shell: bash -l {0}
env:
ASV_FACTOR: 1.5
run: |
export PYTHONPATH="$PWD/installdir/lib/python3.9/site-packages/"
pushd benchmarks

set -x
asv machine --yes
Copy link
Owner

Choose a reason for hiding this comment

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

This block could use a few comments on what the goal is; does it run a comparison, use baseline data, or ... ?

echo "Baseline: ${{ github.event.pull_request.base.sha }} (${{ github.event.pull_request.base.label }})"
echo "Contender: ${GITHUB_SHA} (${{ github.event.pull_request.head.label }})"

ASV_OPTIONS="--split --show-stderr --factor $ASV_FACTOR"
git fetch origin meson
Copy link
Owner

Choose a reason for hiding this comment

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

ah, this is the branch to compare against

Copy link
Author

Choose a reason for hiding this comment

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

Should this be changed?

Copy link
Owner

Choose a reason for hiding this comment

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

No, you can leave it like this, I am keeping meson up to date and am trying out various Meson-specific build changes there. Just adding comments so this whole asv block becomes easier to understand would be great.


asv continuous $ASV_OPTIONS ${{ github.event.pull_request.base.sha }} ${GITHUB_SHA} \
| sed "/Traceback \|failed$\|PERFORMANCE DECREASED/ s/^/::error::/" \
| tee benchmarks.log

asv publish

if grep "Traceback \|failed\|PERFORMANCE DECREASED" benchmarks.log > /dev/null ; then
exit 1
fi

- uses: actions/upload-artifact@v2
if: always()
with:
name: asv-benchmark-logs-${{ runner.os }}
# Uploads the asv benchmark logs, results and generated HTML files to the GitHub Actions artifacts
path: |
benchmarks/benchmarks.log
benchmarks/results
benchmarks/html
benchmarks/asv.conf.json