Skip to content

Commit

Permalink
🚨 update pre-commit, lockfile, and adjust to Qiskit 1.3 (#483)
Browse files Browse the repository at this point in the history
## Description

This PR updates combines a couple of updates for the project
configuration that are long overdue.

## Checklist:

<!---
This checklist serves as a reminder of a couple of things that ensure
your pull request will be merged swiftly.
-->

- [x] The pull request only contains commits that are related to it.
- [x] I have added appropriate tests and documentation.
- [x] I have made sure that all CI jobs on GitHub pass.
- [x] The pull request introduces no new warnings and follows the
project's style guidelines.

---------

Signed-off-by: burgholzer <[email protected]>
  • Loading branch information
burgholzer authored Dec 11, 2024
1 parent 86b7a00 commit f8e26e5
Show file tree
Hide file tree
Showing 14 changed files with 427 additions and 381 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
# whether the workflow is triggered from a PR, a push to main, or a release, respectively.
python-packaging:
name: 🐍 Packaging
uses: cda-tum/mqt-workflows/.github/workflows/reusable-python-packaging.yml@v1.4
uses: cda-tum/mqt-workflows/.github/workflows/reusable-python-packaging.yml@v1.5
with:
# Do not include local version information on pushes to main to facilitate TestPyPI uploads.
no-local-version: ${{ github.ref == 'refs/heads/main' && github.event_name == 'push' }}
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ concurrency:
jobs:
change-detection:
name: 🔍 Change
uses: cda-tum/mqt-workflows/.github/workflows/reusable-change-detection.yml@v1.4
uses: cda-tum/mqt-workflows/.github/workflows/reusable-change-detection.yml@v1.5

cpp-tests:
name: 🇨‌ Test
needs: change-detection
if: fromJSON(needs.change-detection.outputs.run-cpp-tests)
uses: cda-tum/mqt-workflows/.github/workflows/reusable-cpp-ci.yml@v1.4
uses: cda-tum/mqt-workflows/.github/workflows/reusable-cpp-ci.yml@v1.5
# Explicitly set permissions so that the workflows also work from forks.
permissions:
contents: read # Required for the `actions/checkout` action
Expand All @@ -35,13 +35,13 @@ jobs:
name: 🇨‌ Lint
needs: change-detection
if: fromJSON(needs.change-detection.outputs.run-cpp-linter)
uses: cda-tum/mqt-workflows/.github/workflows/reusable-cpp-linter.yml@v1.4
uses: cda-tum/mqt-workflows/.github/workflows/reusable-cpp-linter.yml@v1.5

python-tests:
name: 🐍 Test
needs: change-detection
if: fromJSON(needs.change-detection.outputs.run-python-tests)
uses: cda-tum/mqt-workflows/.github/workflows/reusable-python-ci.yml@v1.4
uses: cda-tum/mqt-workflows/.github/workflows/reusable-python-ci.yml@v1.5
# Explicitly set permissions so that the workflows also work from forks.
permissions:
contents: read # Required for the `actions/checkout` action
Expand All @@ -51,13 +51,13 @@ jobs:
name: 📝 CodeQL
needs: change-detection
if: fromJSON(needs.change-detection.outputs.run-code-ql)
uses: cda-tum/mqt-workflows/.github/workflows/reusable-code-ql.yml@v1.4
uses: cda-tum/mqt-workflows/.github/workflows/reusable-code-ql.yml@v1.5

cd:
name: 🚀 CD
needs: change-detection
if: fromJSON(needs.change-detection.outputs.run-cd)
uses: cda-tum/mqt-workflows/.github/workflows/reusable-python-packaging.yml@v1.4
uses: cda-tum/mqt-workflows/.github/workflows/reusable-python-packaging.yml@v1.5

required-checks-pass: # This job does nothing and is only used for branch protection
name: 🚦 Check
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/update-mqt-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ concurrency:
jobs:
update-mqt-core:
name: ⬆️ Update MQT Core
uses: cda-tum/mqt-workflows/.github/workflows/reusable-mqt-core-update.yml@v1.4
uses: cda-tum/mqt-workflows/.github/workflows/reusable-mqt-core-update.yml@v1.5
with:
update-to-head: ${{ github.event.inputs.update-to-head == 'true' }}
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ repos:

# Python linting using ruff
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.7.4
rev: v0.8.2
hooks:
- id: ruff
args: ["--fix", "--show-fixes"]
Expand All @@ -81,7 +81,7 @@ repos:

# Clang-format the C++ part of the code base automatically
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v19.1.4
rev: v19.1.5
hooks:
- id: clang-format
types_or: [c++, c, cuda]
Expand All @@ -106,7 +106,7 @@ repos:

# Check for spelling
- repo: https://github.com/crate-ci/typos
rev: v1.27.3
rev: typos-dict-v0.11.37
hooks:
- id: typos

Expand Down Expand Up @@ -136,6 +136,6 @@ repos:

# Check the pyproject.toml file
- repo: https://github.com/henryiii/validate-pyproject-schema-store
rev: 2024.11.11
rev: 2024.11.25
hooks:
- id: validate-pyproject
6 changes: 3 additions & 3 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,13 @@ def _run_tests(
if shutil.which("ninja") is None:
session.install("ninja")

_extras = ["test", *extras]
extras_ = ["test", *extras]
if "--cov" in posargs:
_extras.append("coverage")
extras_.append("coverage")
posargs.append("--cov-config=pyproject.toml")

session.install(*BUILD_REQUIREMENTS, *install_args, env=env)
install_arg = f"-ve.[{','.join(_extras)}]"
install_arg = f"-ve.[{','.join(extras_)}]"
session.install("--no-build-isolation", install_arg, *install_args, env=env)
session.run("pytest", *run_args, *posargs, env=env)

Expand Down
12 changes: 7 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ xfail_strict = true
filterwarnings = [
"error",
'ignore:.*datetime\.datetime\.utcfromtimestamp.*:DeprecationWarning:',
# Qiskit 1.3 deprecations
'ignore:.*``qiskit.dagcircuit.dagcircuit.DAGCircuit.*`` is deprecated as of qiskit 1.3.0.*:DeprecationWarning:',
'ignore:.*``qiskit.circuit.instruction.Instruction.condition`` is deprecated as of qiskit 1.3.0.*:DeprecationWarning:',
'ignore:.*``qiskit.circuit.library.standard_gates.x.*`` is pending deprecation as of qiskit 1.3.*:PendingDeprecationWarning:',
'ignore:.*``qiskit.circuit.library.n_local.*`` is pending deprecation as of qiskit 1.3.*:PendingDeprecationWarning:',
# The warning filters below are only temporary and should be removed once the Sampler and the Estimator are updated
'ignore:.*BaseSamplerV1.*:DeprecationWarning:',
'ignore:.*BaseEstimatorV1.*:DeprecationWarning:',
Expand Down Expand Up @@ -213,20 +218,17 @@ extend-select = [
"SLOT", # flake8-slots
"SIM", # flake8-simplify
"T20", # flake8-print
"TCH", # flake8-type-checking
"TC", # flake8-type-checking
"TID", # flake8-tidy-imports
"TRY", # tryceratops
"UP", # pyupgrade
"YTT", # flake8-2020
]
ignore = [
"ANN101", # Missing type annotation for `self` in method
"ANN102", # Missing type annotation for `cls` in classmethod
"ISC001", # Conflicts with formatter
"PLR09", # Too many <...>
"PLR2004", # Magic value used in comparison
"PLC0415", # Import should be at top of file
"PT004", # Incorrect, just usefixtures instead.
"S101", # Use of assert detected
"S404", # `subprocess` module is possibly insecure
]
Expand Down Expand Up @@ -286,7 +288,7 @@ archs = "auto64"
test-command = "python -c \"from mqt import ddsim\""
test-skip = ["cp313*"] # skip testing on Python 3.13 until our dependencies are ready
build-frontend = "build[uv]"
free-threaded-support = true
enable = ["cpython-freethreading"]
manylinux-x86_64-image = "manylinux_2_28"
manylinux-aarch64-image = "manylinux_2_28"
manylinux-ppc64le-image = "manylinux_2_28"
Expand Down
12 changes: 6 additions & 6 deletions src/mqt/ddsim/deterministicnoisesimulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ def _default_options(cls) -> Options:
@staticmethod
def _run_experiment(qc: QuantumCircuit, **options: dict[str, Any]) -> ExperimentResult:
start_time = time.time()
noise_effects = cast(str, options.get("noise_effects", "APD"))
noise_probability = cast(float, options.get("noise_probability", 0.01))
amp_damping_probability = cast(float, options.get("amp_damping_probability", 0.02))
multi_qubit_gate_factor = cast(float, options.get("multi_qubit_gate_factor", 2))
seed = cast(int, options.get("simulator_seed", -1))
shots = cast(int, options.get("shots", 1024))
noise_effects = cast("str", options.get("noise_effects", "APD"))
noise_probability = cast("float", options.get("noise_probability", 0.01))
amp_damping_probability = cast("float", options.get("amp_damping_probability", 0.02))
multi_qubit_gate_factor = cast("float", options.get("multi_qubit_gate_factor", 2))
seed = cast("int", options.get("simulator_seed", -1))
shots = cast("int", options.get("shots", 1024))

sim = ddsim.DeterministicNoiseSimulator(
circ=qc,
Expand Down
2 changes: 1 addition & 1 deletion src/mqt/ddsim/pathqasmsimulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def get_simulation_path(
minimize="flops",
)
info = tn.contract(all, get="path-info", optimize=opt)
path = cast(list[tuple[int, int]], linear_to_ssa(info.path))
path = cast("list[tuple[int, int]]", linear_to_ssa(info.path))

if dump_path:
filename = qc.name + "_" + str(qc.num_qubits) + ".path" if isinstance(qc, QuantumCircuit) else "simulation.path"
Expand Down
6 changes: 3 additions & 3 deletions src/mqt/ddsim/primitives/estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,10 +180,10 @@ def _run_experiment(
obs_circ_list: list[QuantumCircuit],
**options: dict[str, Any],
) -> list[float]:
approximation_step_fidelity = cast(float, options.get("approximation_step_fidelity", 1.0))
approximation_steps = cast(int, options.get("approximation_steps", 1))
approximation_step_fidelity = cast("float", options.get("approximation_step_fidelity", 1.0))
approximation_steps = cast("int", options.get("approximation_steps", 1))
approximation_strategy = str(options.get("approximation_strategy", "fidelity"))
seed = cast(int, options.get("seed_simulator", -1))
seed = cast("int", options.get("seed_simulator", -1))

sim = CircuitSimulator(
circ,
Expand Down
5 changes: 3 additions & 2 deletions src/mqt/ddsim/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

from typing import TYPE_CHECKING, Any, cast

from qiskit.providers import BackendV2
from qiskit.providers.exceptions import QiskitBackendNotFoundError
from qiskit.providers.providerutils import filter_backends

Expand All @@ -21,6 +20,8 @@
if TYPE_CHECKING:
from collections.abc import Callable

from qiskit.providers import BackendV2


class DDSIMProvider:
"""Provider for DDSIM backends."""
Expand Down Expand Up @@ -70,7 +71,7 @@ def backends(
backends = [
backend_cls() for backend_name, backend_cls in self._BACKENDS if name is None or backend_name == name
]
return cast(list[BackendV2], filter_backends(backends, filters=filters, **kwargs))
return cast("list[BackendV2]", filter_backends(backends, filters=filters, **kwargs))

def __str__(self) -> str:
"""Return the provider name."""
Expand Down
8 changes: 4 additions & 4 deletions src/mqt/ddsim/qasmsimulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,11 @@ def _run_job(

def _run_experiment(self, qc: QuantumCircuit, **options: dict[str, Any]) -> ExperimentResult:
start_time = time.time()
approximation_step_fidelity = cast(float, options.get("approximation_step_fidelity", 1.0))
approximation_steps = cast(int, options.get("approximation_steps", 1))
approximation_step_fidelity = cast("float", options.get("approximation_step_fidelity", 1.0))
approximation_steps = cast("int", options.get("approximation_steps", 1))
approximation_strategy = str(options.get("approximation_strategy", "fidelity"))
seed = cast(int, options.get("seed_simulator", -1))
shots = cast(int, options.get("shots", 1024))
seed = cast("int", options.get("seed_simulator", -1))
shots = cast("int", options.get("shots", 1024))

sim = CircuitSimulator(
qc,
Expand Down
18 changes: 9 additions & 9 deletions src/mqt/ddsim/stochasticnoisesimulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ def _default_options(cls) -> Options:
@staticmethod
def _run_experiment(qc: QuantumCircuit, **options: dict[str, Any]) -> ExperimentResult:
start_time = time.time()
approximation_step_fidelity = cast(float, options.get("approximation_step_fidelity", 1.0))
approximation_steps = cast(int, options.get("approximation_steps", 1))
approximation_strategy = cast(str, options.get("approximation_strategy", "fidelity"))
noise_effects = cast(str, options.get("noise_effects", "APD"))
noise_probability = cast(float, options.get("noise_probability", 0.01))
amp_damping_probability = cast(float, options.get("amp_damping_probability", 0.02))
multi_qubit_gate_factor = cast(float, options.get("multi_qubit_gate_factor", 2))
seed = cast(int, options.get("seed_simulator", -1))
shots = cast(int, options.get("shots", 1024))
approximation_step_fidelity = cast("float", options.get("approximation_step_fidelity", 1.0))
approximation_steps = cast("int", options.get("approximation_steps", 1))
approximation_strategy = cast("str", options.get("approximation_strategy", "fidelity"))
noise_effects = cast("str", options.get("noise_effects", "APD"))
noise_probability = cast("float", options.get("noise_probability", 0.01))
amp_damping_probability = cast("float", options.get("amp_damping_probability", 0.02))
multi_qubit_gate_factor = cast("float", options.get("multi_qubit_gate_factor", 2))
seed = cast("int", options.get("seed_simulator", -1))
shots = cast("int", options.get("shots", 1024))

sim = ddsim.StochasticNoiseSimulator(
circ=qc,
Expand Down
7 changes: 4 additions & 3 deletions test/python/test_target.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,16 @@ def test_transpilation_preserves_2q_0p_target_gates(target: Target, gate: str) -
getattr(qc, gate)(0, 1)
qc_transpiled = transpile(qc, target=target)
print(qc_transpiled)
assert len(qc_transpiled.data) == 1
assert qc_transpiled.data[0].operation.name == gate
num_gates = len(qc_transpiled.data)
assert num_gates <= 1
assert num_gates == 0 or qc_transpiled.data[0].operation.name == gate


@pytest.mark.parametrize("gate", ["rxx", "ryy", "rzz", "rzx", "cp", "crx", "cry", "crz"])
def test_transpilation_preserves_2q_1p_target_gates(target: Target, gate: str) -> None:
"""Test that transpilation does not change two-qubit gates with one parameter that are already in the target."""
qc = QuantumCircuit(2)
getattr(qc, gate)(np.pi, 0, 1)
getattr(qc, gate)(np.pi / 2, 0, 1)
qc_transpiled = transpile(qc, target=target)
assert len(qc_transpiled.data) == 1
assert qc_transpiled.data[0].operation.name == gate
Expand Down
Loading

0 comments on commit f8e26e5

Please sign in to comment.