Contributing to BQSKit
The Berkeley Quantum Synthesis Toolkit is an open-source superoptimizing compiler committed to making synthesis easy to use and quick to extend. As such, one of our primary goals is to allow everyone to join our community and contribute to the BQSKit project. This page describes how to do just that.
[!TIP] If you encounter any issues or need help, please don’t hesitate to reach out through a GitHub Issue.
Getting Started
We welcome all contributions, but we envision two common contributions to BQSKit: extending the IR with new gates and implementing or altering algorithms in a compiler pass. If you plan to make a similar contribution, you can find documentation for the IR and supported algorithms under the API Reference section.
Before contributing, you will probably want to familiarize yourself with the codebase and documentation and set up a development environment.
Development Environment
BQSKit primarily uses uv to manage its development environment. You can set up the development environment as follows:
git clone https://github.com/BQSKit/bqskit.git
cd bqskit
uv sync
uv sync creates a virtual environment in ./.venv with BQSKit installed in editable mode, plus everything needed for development (pytest, ruff, pre-commit, etc.). You can then run anything inside that environment with uv run <command> (e.g. uv run pytest). If you’re working on or testing documentation, uv sync --group docs will additionally install the Sphinx toolchain.
Without uv
If you’d rather not use uv, you can alternatively use a standard python virtual environment workflow, using pip’s native support for PEP 735 dependency groups (requires pip >= 25.1):
git clone https://github.com/BQSKit/BQSKit.git
cd bqskit
python -m venv .venv
source .venv/bin/activate # .venv\Scripts\activate on Windows
pip install -e . --group dev
This installs BQSKit in editable mode, as well as the same development dependencies as uv sync. For the documentation toolchain, use the docs group instead: pip install -e . --group docs.
[!NOTE] This environment may differ than the one installed via
uv syncas pip resolves--group devfresh each time, rather than readinguv.lock. This means that it is not guaranteed to produce the same exact dependency versions CI uses. If you hit a test failure that only happens in a pip-managed environment, try reproducing it withuv sync.
Guidelines
Please follow the below short list of guidelines when contributing.
Pull Request Checklist
Please ensure the pre-commit checks pass on your branch. Run
uv run pre-commit installonce per clone to have ruff (lint + format) and mypy run automatically on everygit commit. Before pushing, it’s worth runninguv run pre-commit run --all-filesto check the whole repository at once, since the per-commit hooks only see the files in that commit.Please ensure all tests are still passing, which can be checked with
uv run pytest. If your change might behave differently across Python versions, you can additionally run the full suite against every supported interpreter withuvx --with tox-uv tox. If appropriate, please add tests to ensure your change behaves correctly. See the testing section below for more information.Please ensure that any added package, module, class, attribute, function, or method has an appropriate Google-style docstring. The documentation engine uses these to produce API references. If you have created a user-facing class, please add those to the autosummary list in the top-level package’s
__init__.py(e.g.bqskit.ir.__init__).BQSKit is a type-annotated Python package, which helps catch some bugs early with static code analysis tools like Mypy. You can see PEP 484: Type Annotations for more information. Please annotate your contribution with types. Sometimes, this can be tricky. If you need help, please don’t hesitate to ask.
If you have added a new algorithm and/or compiler pass that references one or more publications, please use the
@citedecorator, which cites by DOI. For example, from bqskit/passes/mapping/sabre.py:
@cite(doi='10.1145/3297858.3304023')
@cite(doi='10.1145/3445814.3446718')
class GeneralizedSabreAlgorithm:
Testing
Testing Frameworks
Our test suite resides in the tests folder and uses a combination of pytest and hypothesis.
tox can also optionally be used to run the test suite against every supported Python version at once, similar to the version matrix in CI: uvx --with tox-uv tox.
pytest
After making any changes, it is essential to ensure that all the previous tests still pass. Run uv run pytest to execute the test suite. If your change touches version-sensitive code, you can also run the full suite against every supported Python version with uvx --with tox-uv tox (this requires uv to be installed; alternatively you can install tox with pip or your preferred package manager).
Some tests are marked slow (long-running synthesis, many randomized circuits, etc.) and are excluded by default; uv run pytest with no path or -m argument skips them and prints a note saying how many were excluded. If you instead point pytest at a specific path (e.g. uv run pytest tests/compiler/compile) OR pass an explicit marker expression (e.g. -m "slow or not slow"), everything in scope will run, slow included.
Adding New Tests
You may want to write tests for any appropriate changes that you have introduced. Any Python method or function that starts with test_ in the tests folder will be collected and run as part of the test suite. You can write normal Python code and use assert statements in your tests. Although you can place your test anywhere in the tests folder, please follow the same structure there already. The tests directory structure closely follows the bqskit package structure, which makes it easy to find tests. If you are not familiar with pytest, we recommend you read a few of the tests included already and ask any questions you may have.
Hypothesis is a powerful library that will intelligently generate inputs to tests. Any test that starts with the @given decorator uses Hypothesis to generate inputs according to some strategy. BQSKit has several custom strategies that can be found in bqskit.utils.test module. We recommend using hypothesis to test complex functionality that may have corner cases.
BQSKit also uses nbval to check that the tutorial notebooks under examples/tutorials/ still execute correctly. This isn’t part of the default uv run pytest (only tests/ is collected by default). If you change a public API or edit a tutorial notebook, please run it explicitly before pushing with uv run pytest --nbval-lax examples/tutorials/.
Testing Documentation
BQSKit’s documentation is built with the Sphinx toolchain automatically. This is run in CI, but if it fails you may want to test it locally. To build and preview the docs:
cd docs
uv run make html
The rendered site is written to docs/_build/html/; open index.html there in a browser. Run uv run make clean first if you want a full rebuild (useful if you’ve renamed or removed pages, since Sphinx’s incremental build can leave stale output otherwise).