Skip to content

Latest commit

 

History

History
323 lines (226 loc) · 18.1 KB

File metadata and controls

323 lines (226 loc) · 18.1 KB

Quantum Metal — Developer Guide

Companion to README.md (user-facing) and docs/contributor-guide.rst (rendered into the docs site). This file collects the practical recipes — env setup, tests, docs build, tutorials sync, common gotchas — for working on Quantum Metal itself.

Development Setup

Quantum Metal uses uv for project/dependency management. Install uv first, following the official instructions.

Development (virtual) environments

The next few paragraphs describe the setup. We recommend reading through it at least once before you start making contributions. Skip to the next section for instructions on how to activate venvs, run tasks, etc.

All development activities should be carried out inside Python virtual environments (venvs). Thankfully, uv can manage all our venvs for us. In addition to this, we can use tox to orchestrate venvs to fit the needs of different development tasks: testing, linting, building docs, etc.

All information about project dependencies can be found in the pyproject.toml file located in the root directory of this repository. The direct project dependencies are listed in the requirements section of the [project] table. These are required to run user code.

Development dependencies are specified in the [dependency-groups] table.There are four groups available: test, lint, docs, and jupyter. These are used by tox to create a virtual environment with the required dependencies for each task. At the time of writing, the jupyter group is available for convenience, but unused in tasks. See PEP 735-Dependency Groups in pyproject.toml and the PyPA specification page for dependency groups for more information.

The file uv.lock lists "locked" versions for all dependencies listed in pyproject.toml across different platforms. This allows uv to create reproducible environments. At present, tox does not create virtual environments using the lockfile, but the tox-uv plugin allows for this functionality to be enabled by setting the runner configuration variable in each tox task as described here.

Running tests

Tox is configured to run tests (using pytest) for Python 3.10-3.12. Use the following command to run tests for all three versions:

tox -m test

We use the pytest-rich(https://github.com/nicoddemus/pytest-rich) to provide rich output of testing progress. Tests can be run for specific versions using the following command

tox -e py3.12 # replace 3.12 with the version you want to run

Linting and Formatting

We use ruff for linting and formatting. Our linting configuration is described in pyproject.toml under the [tool.ruff.lint] table. Note that this configuration is a work in progress and likely to change until further notice. The linter can be run using the following command:

tox -e lint

This will show all the linting errors and the location for each. For a summary showing the number of violations of each linting rule, use the following command:

tox -e lint -- --statistics

Formatting for the whole repository can be performed using the following command:

tox -e format

Note that we have not yet settled on a formatting configuration other than default options provided by ruff, but this may change.

Building docs

Documentation is built using Sphinx + nbsphinx. The detailed guide lives in the contributor guide. Quick recipes:

# Full build (fast — ~1–2 min; skips notebook re-execution by default)
uvx --with tox-uv tox -e docs

# Full build, re-execute every tutorial notebook (slow; needs all extras
# installed, e.g. [full] — used for releases / docs deploys)
QISKIT_DOCS_BUILD_TUTORIALS=always uvx --with tox-uv tox -e docs

# Open the result
open docs/_build/html/index.html

For iterative .rst editing — live reload at http://localhost:8000:

uv sync --group docs          # one-time
uv run sphinx-autobuild docs docs/_build/html

If autodoc emits stale or duplicated stubs, blow them away and rebuild clean:

rm -rf docs/_build docs/stubs && uvx --with tox-uv tox -e docs

Tutorials sync — dual-folder workflow

Every numbered tutorial notebook lives in two places that must stay content-identical:

Path Why
tutorials/ User-facing — spaces in filenames, browsable on GitHub
docs/tut/ Sphinx + nbsphinx source — hyphenated filenames for clean URLs

CI fails any PR where the two folders drift (scripts/check_tutorials_sync.py runs on every push). The check compares cell source content only, so metadata churn (kernel ids, execution counts) doesn't cause false drift.

Recipes:

# 1. Authoritative drift check — use this as the source of truth
uv run scripts/check_tutorials_sync.py
#    → "✓ All 54 notebook pairs in sync."  = you're done.

# 2. If drift IS detected: dry-run the sync to see what will change
python3 _dev/sync_two_folders.py
#    Reports per-pair: in-sync vs. would-copy, with the chosen direction.

# 3. Apply the sync (overwrites the non-canonical side)
python3 _dev/sync_two_folders.py --write

# 4. Re-run the check to confirm
uv run scripts/check_tutorials_sync.py

Per-notebook canonical choices ("which folder wins on conflict") live in the CANONICAL dict in _dev/sync_two_folders.py. Update it there if you intentionally want the other folder to be authoritative for a specific notebook, then re-sync.

Gotcha: _dev/sync_two_folders.py's "src→dst" column shows the direction it would copy if there's drift. The actual decision of whether to copy is in the status column (in-sync vs. would copy). Don't be alarmed if every row prints — what matters is the summary line at the bottom and the status column per row.

Old Instructions

NOTE: The following instructions are from 2020 and might be used for the qiskit-metal<0.5.

Quick install tutorial

Retrieve the code from GitHub

You could download the code as a zip file at the top of this page. However we recommend investing time into setting up a proper git linkage, which will simplify the retrieval of code updates and your possible contributions back to the source code.

To do that, you will need to git clone this repository's main branch following one of two ways.

  1. Open any command line shell that has been configured with git and execute the following command:
git clone https://github.com/qiskit-community/qiskit-metal.git
  1. Alternatively, you can download and use the user interface GitHub Desktop GUI and refer to these notes.

Now that you have a local copy of the code, you can install Qiskit Metal either in a virtual conda environment or in a virtual Python environment, as described below. We recommend conda.

Notes:

  • For your own sanity, it is recommended to read this document in its entirety before proceeding.
  • On Windows, the conda environment is strongly recommended because Shapely is difficult to install directly via pip.

Setup in a conda environment (preferred setup)

If you did not yet install conda, please follow these instructions. We will setup a conda environment to use the local copy of Qiskit Metal you obtained in the previous section. This approach enables you to immediately observe the effect of your code modifications.

For this section you will need to use the command line. If you use github desktop, you can open one from the menu Repository -> Open In....

Option 1: A new environment

The most reliable way to set up a qiskit_metal environment is to build one from scratch using the provided conda environment specification file environment.yml. To do so, first navigate to the folder created by the clone. For example:

cd qiskit-metal

Once you are in the folder that contains the environemnt.yml file, execute the following installation commands:

conda env create -n <env_name> environment.yml
conda activate <env_name>
python -m pip install --no-deps -e .

Note the use of --no-deps. Indeed the environment.yml already instructs conda to install all the necessary package dependencies. We therefore prevent setup.py from overwriting them with the pip-equivalent packages, which might not be compatible with conda.

This creates a new environment with name <env_name> with all the necessary library dependencies. Then it activates the new environment. Finally installs the local Qiskit Metal code inside that environment.

The -e flag install qiskit_metal in editable mode. You can add the -v flag if you would like to observe the verbose output during the installation.

Option 2: A pre-existing environment

If convenient, you can instead try to install directly in an existing conda environment <env_name_exist>. To do so, just replace the word create with update in the commands in the previous section. Find the resulting commands updated below for simplicity:

conda env update -n <env_name_exist> environment.yml
conda activate <env_name_exist>
python -m pip install --no-deps -e .

Notes:

  • It is possible that you may run into version conflicts during the above installation, as qiskit-metal requires specific library versions to work correctly on every OS. In this case, please revert to using a separate conda environment.
  • Important: Remember to conda activate <env_name> if you intend to use qiskit-metal. See what a conda environment is

Jupyter notebook and Jupyter lab hints

The file environment.yml contains jupyter. Therefore, launching jupyter notebook from your activated new environment <env_name>, will make jupyter notebook python execution default to the <env_name> python installation.

However, if you did not install jupyter in your <env_name> (to save disk space, or to use an existing favorite install), jupyter notebook will execute the python code in the <other_env> (typically base) where it was installed.

Similarly, jupyter lab will in general execute python code from the base environment.

In the two above cases, you will need to setup a jupyter kernel that points to your <env_name> environment, to be able to find and execute successfully the qiskit-metal package.

Check for the instructions to install a new kernel in the FAQ.

Subsequent updates of the conda environment

Package dependencies will evolve over time and could at some point require a new version of a library. For example, we can anticipate updating pyEPR-quantum to enable Ansys interactions previously unsupported. To update your local install, simply execute the metal package install command

conda env update -n <env_name_exist> environment.yml

Alternatively, you can remove your conda environment by executing the commands below and later re-create a new environment following the original install instructions in section 1.

conda env list
conda env remove -n <env_name_exist>

Notice that using the conda env update command might introduce inconsistencies in your virtual environment, and render it unusable. This occurs in general when using conda install commands after any number of pip install commands.

Setup without conda: in a virtual environment (alternative setup)

Prerequisites

The package dependency gdstk, needs C++ compilation to successfully install in a base or virtualenv. Make sure the right compiler is installed on your machine if you encounter errors during the installation process described above. Windows you can install the Visual C++ x.0 using the C++ Build Tools. Be sure to select the most current versions of MSVC and Windows SDK, as suggested in this wiki. Linux on Ubuntu or other Debian based systems, execute the following command sudo apt-get install gcc g++. Linux users might encounter other python-related errors during creation of the virtualenv or during qiskit-metal installation. You might be able to deal with those by executing sudo apt-get install python3-dev python3-venv. Be sure to customize the python3 string if you are trying to use a custom installation of python.

Install

To create and populate the Python virtual environment, execute these commands in the top-level of the repository:

python -m venv <virtual_env_path/name>
source <virtual_env_path/name>/bin/activate
python -m pip install -U pip
python -m pip install -e .

add -r requirements-dev.txt to the last line if you intend to install also the packages required for development. where <virtual_env_path/name> is the name of your new Python virtual environment. You can also specify its path. On Windows, replace the activate command line above with this one: .\<virtual_env_path/name>\Scripts\activate.

Installation hints

Here are some things to consider when setting up a development environment:

  • Remember to type the period (".") at the end of the pip install command.
  • If using a virtual environment, make sure pip is up to date. PySide6 (used by the optional [gui] extra) requires a recent pip.
  • In some setups, you might need to add the qiskit-metal folder path to your PATH variable
  • Library errors when activating conda environments, or initializing jupyter notebook/lab, might indicate a conflict between python libraries in the base and sub environments. Go ahead and manually delete the library from the base environment site-packages folder, shown in the error message. You might need to reinstall them in the sub environment, or create a new one.
  • If Jupyter notebook has trouble finding a dll for a package that works in the new environment outside of Jupyter, then try opening Jupyter notebook from the new environment instead of from base

Installing other dependencies for Open-source Renderers (Gmsh and ElmerFEM)

If you want to use the open-source renderers for Gmsh and ElmerFEM for simulation of your design, install the [mesh] extra (pip install "quantum-metal[mesh]" — or its alias [fem]) to get the gmsh Python binding, and install ElmerFEM separately (it's an external CLI binary, not a Python package). For the full open FEM toolchain setup — gmsh, Elmer, and the planned Palace path — see README_Open_FEM_Stack.md.

NOTE on Apple Silicon (M1/M2/M3/M4): As of v0.5+, Quantum Metal uses PySide6 (Qt 6), which is native on Apple Silicon — MetalGUI works out of the box with pip install "quantum-metal[gui]". For the headless lite install (default in v0.7.0+) you don't need PySide6 at all; use qm.view(design) instead. See docs/headless-usage.rst. Gmsh on Apple Silicon may still need extra setup — see README_Open_FEM_Stack.md.

Other Common Issues

For other common installation issues, please refer to the FAQ

Additional steps for developers

If you are planning to develop the qiskit metal codebase, you need extra packages, which you can install by running the following command instead of (or after) the previous one:

python -m pip install -r requirements-dev.txt

You may also want to also use these instructions to setup user environment

Setting up git hooks (recommended)

./hook_setup.sh installs two hooks that mirror the cheapest CI gates locally — so most "passed locally, fails in CI" surprises get caught at commit/push time instead of after a cloud round-trip:

Hook Runs When
pre-commit ruff check + ruff format --check on staged Python files every git commit (fast — ~2s)
pre-push full-repo ruff check + ruff format --check + check_env_consistency.py + check_tutorials_sync.py (notebook touches only) every git push (~15s)

Install once:

./hook_setup.sh

This symlinks .git/hooks/{pre-commit,pre-push}hooks/{pre-commit,pre-push}. On Windows, run from Git Bash or another POSIX-compatible shell. Both hooks invoke ruff via uvx ruff@<pinned-version> (matching CI), so no global ruff install needed.

Example output on commit:

Pre-commit: checking 3 staged Python file(s) with ruff 0.15.14
  → ruff check
  → ruff format --check
  ✓ ruff checks pass

If something needs reformatting, the hook prints the exact command. Emergency bypass (e.g. WIP push of a draft branch): git commit --no-verify / git push --no-verify.

Reproducing CI's lint/format locally without the hooks

uvx ruff@0.15.14 check .              # lint
uvx ruff@0.15.14 format --check .     # format check
uvx ruff@0.15.14 format .             # auto-fix formatting
uv run scripts/check_env_consistency.py
uv run scripts/check_tutorials_sync.py

Uninstall git hooks

rm .git/hooks/pre-commit .git/hooks/pre-push

If you need to uninstall the precommit hook, go to the root of the project and run the above command.