Continuous benchmarking of PyLops operators with airspeed velocity (asv).
For every operator, the suite in benchmarks/ measures the wall time and the peak memory
of the forward (matvec) and adjoint (rmatvec) passes. The results are published at
https://pylops.github.io/pylops-asv/
benchmarks/holds onebench_*.pymodule per family of operators. Every benchmark subclassesbenchmarks.common.OperatorBenchmarkand only implementsmake_operator;time_forward,time_adjoint,peakmem_forwardandpeakmem_adjointare inherited.asv.conf.jsonpoints asv at the PyLops GitHub repository: for each benchmarked commit asv clones it, builds a wheel and installs it in a freshuvenvironment with the latest release of every dependency in the matrix (numpy, scipy, numba, pyfftw, PyWavelets, scikit-fmm).- The
PyLops-benchmarksGitHub Action runs every night on the heads of themasteranddevbranches of PyLops and on the latest release tag (commits that already have results are skipped). Results are committed toresults/onmainand the website is rebuilt withasv publishand deployed to GitHub Pages. - Older releases or arbitrary revision ranges can be benchmarked retroactively by triggering
the same workflow manually (Actions → PyLops-benchmarks → Run workflow) with either the
number of most recent release tags (
last_tags) or a git revision range (revisions, e.g.v2.7.0..master). Tickquickfor a smoke test that runs every benchmark once.
Benchmarks run on GitHub-hosted runners (ubuntu-latest), so timings are noisy across
runs: look at trends and at the peak-memory numbers rather than at single points.
When a new operator is added to PyLops, open a companion pull request here:
-
Add a class to the relevant
benchmarks/bench_*.pymodule (or a new module) that subclassesOperatorBenchmarkand implementsmake_operator, which returns the operator to benchmark. Choose the size of the operator such that a single forward pass takes between 1 and 100 milliseconds. -
Resolve the operator with
getop("FFT")(orgetop("signalprocessing.FFT")) rather than importing it: operators that do not exist in an older PyLops release are then skipped instead of failing. Likewise usebuild(cls, ...)for keyword arguments introduced after a release andrequire("numba")for optional dependencies. -
Use
params/param_namesto benchmark several engines or sizes, andsetup_cachefor expensive inputs shared by all parameters. -
Validate the suite (nothing is executed) and lint it:
make install make benchcheck make lint
Local runs benchmark a local checkout of PyLops (PYLOPS_REPO, default ../pylops),
installed in editable mode in this project's environment. Results are written to the
git-ignored .asv/results-local directory and never uploaded: they are useful to develop
benchmarks or to compare two versions of an operator, but the numbers published by the
GitHub Action are the reference.
make bench BENCH_ARGS="--quick -b bench_ffts" # only the FFT module, one iteration
make bench PYLOPS_REPO=~/src/pylops # another checkout
make benchpreview # browse http://127.0.0.1:8765/ (ASV_PORT=<port>)BENCH_ARGS is passed verbatim to asv run; see asv run --help for the options
(-b REGEX to select benchmarks, --quick, --profile, ...).
asv.conf.json asv configuration (project repo, environment matrix, build commands)
benchmarks/ benchmark suite (bench_*.py) and shared base class (common.py)
ci/ helpers used by the workflow and by `make bench`
results/ results committed by the PyLops-benchmarks workflow
.github/workflows/ benchmarks.yaml (nightly/manual runs + deploy), check.yaml (PRs)