Skip to content

Commit

Permalink
✨ Support for Qiskit 1.0 (#349)
Browse files Browse the repository at this point in the history
  • Loading branch information
burgholzer authored Feb 16, 2024
1 parent a50b525 commit 37d0485
Show file tree
Hide file tree
Showing 13 changed files with 25 additions and 308 deletions.
13 changes: 1 addition & 12 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ classifiers = [
]
requires-python = ">=3.8"
dependencies = [
"qiskit[qasm3-import]>=0.45.0"
"qiskit[qasm3-import]>=1.0.0"
]
dynamic = ["version"]

Expand Down Expand Up @@ -143,14 +143,7 @@ log_cli_level = "INFO"
xfail_strict = true
filterwarnings = [
"error",
"ignore:.*qiskit.__qiskit_version__.*:DeprecationWarning:qiskit:",
"ignore:.*qiskit.utils.algorithm_globals.QiskitAlgorithmGlobals*:DeprecationWarning:qiskit",
"ignore:.*Building a flow controller with keyword arguments is going to be deprecated*:PendingDeprecationWarning:qiskit",
"ignore:.*qiskit.extensions module is pending deprecation*:PendingDeprecationWarning:qiskit",
'ignore:.*datetime\.datetime\.utcfromtimestamp.*:DeprecationWarning:',
"ignore:.*qiskit.utils.parallel*:DeprecationWarning:qiskit",
"ignore:.*qiskit.tools.events*:DeprecationWarning:qiskit",
"ignore:.*qiskit.qasm*:DeprecationWarning:qiskit",
]

[tool.coverage]
Expand All @@ -172,10 +165,6 @@ warn_unreachable = true
explicit_package_bases = true
pretty = true

[[tool.mypy.overrides]]
module = ["qiskit.*"]
ignore_missing_imports = true

[tool.ruff]
line-length = 120
extend-include = ["*.ipynb"]
Expand Down
2 changes: 1 addition & 1 deletion src/mqt/ddsim/hybridqasmsimulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def _run_experiment(self, qc: QuantumCircuit, **options: Any) -> ExperimentResul
nthreads = int(options.get("nthreads", local_hardware_info()["cpus"]))
if mode == "amplitude":
hybrid_mode = HybridMode.amplitude
max_qubits = self.max_qubits()
max_qubits = 30 # hard-coded 16GiB memory limit
algorithm_qubits = qc.num_qubits
if algorithm_qubits > max_qubits:
msg = "Not enough memory available to simulate the circuit even on a single thread"
Expand Down
2 changes: 1 addition & 1 deletion src/mqt/ddsim/hybridstatevectorsimulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class HybridStatevectorSimulatorBackend(HybridQasmSimulatorBackend):
_SHOW_STATE_VECTOR = True
_HSF_SV_TARGET = Target(
description="MQT DDSIM HSF Statevector Simulator Target",
num_qubits=HybridQasmSimulatorBackend.max_qubits(),
num_qubits=30, # corresponds to 16GiB memory for storing the full statevector
)

def __init__(self) -> None:
Expand Down
2 changes: 1 addition & 1 deletion src/mqt/ddsim/pathstatevectorsimulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class PathStatevectorSimulatorBackend(PathQasmSimulatorBackend):
_SHOW_STATE_VECTOR = True
_Path_SV_TARGET = Target(
description="MQT DDSIM Simulation Path Framework Statevector Target",
num_qubits=PathQasmSimulatorBackend.max_qubits(),
num_qubits=30, # corresponds to 16GiB memory for storing the full statevector
)

def __init__(self) -> None:
Expand Down
55 changes: 4 additions & 51 deletions src/mqt/ddsim/primitives/estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,21 @@

import numpy as np
from qiskit.circuit import QuantumCircuit
from qiskit.primitives.base import BaseEstimator, EstimatorResult
from qiskit.primitives.primitive_job import PrimitiveJob
from qiskit.primitives.utils import (
_circuit_key, # noqa: PLC2701
_observable_key, # noqa: PLC2701
init_observable,
)
from qiskit.quantum_info import Pauli, PauliList, SparsePauliOp
from qiskit.primitives import Estimator as QiskitEstimator
from qiskit.primitives import EstimatorResult
from qiskit.quantum_info import Pauli, PauliList

from mqt.ddsim.pyddsim import CircuitSimulator
from mqt.ddsim.qasmsimulator import QasmSimulatorBackend

if TYPE_CHECKING:
from qiskit.circuit import Parameter
from qiskit.circuit.parameterexpression import ParameterValueType
from qiskit.quantum_info.operators.base_operator import BaseOperator

Parameters = Union[Mapping[Parameter, ParameterValueType], Sequence[ParameterValueType]]


class Estimator(BaseEstimator):
class Estimator(QiskitEstimator):
"""DDSIM implementation of qiskit's sampler.
Code adapted from Qiskit's BackendEstimator class.
"""
Expand Down Expand Up @@ -152,47 +146,6 @@ def _observable_circuit(num_qubits: int, pauli: Pauli) -> tuple[QuantumCircuit,

return obs_circuit, qubit_indices

def _run(
self,
circuits: Sequence[QuantumCircuit],
observables: Sequence[BaseOperator | SparsePauliOp],
parameter_values: Sequence[Parameters],
**run_options: dict[str, Any],
) -> PrimitiveJob:
circuit_indices = []
for circuit in circuits:
key_circ = _circuit_key(circuit)
index = self._circuit_ids.get(key_circ)
if index is not None:
circuit_indices.append(index)
else:
num_circuits = len(self._circuits)
circuit_indices.append(num_circuits)
self._circuit_ids[key_circ] = num_circuits
self._circuits.append(circuit)
self._parameters.append(circuit.parameters)
observable_indices = []
for observable in observables:
observable_copy = init_observable(observable)
key_obs = _observable_key(observable_copy)
index = self._observable_ids.get(key_obs)
if index is not None:
observable_indices.append(index)
else:
num_observables = len(self._observables)
observable_indices.append(num_observables)
self._observable_ids[key_obs] = num_observables
self._observables.append(observable_copy)
job = PrimitiveJob(
self._call,
circuit_indices,
observable_indices,
parameter_values,
**run_options,
)
job.submit()
return job

def _call(
self,
circuits: Sequence[int],
Expand Down
45 changes: 7 additions & 38 deletions src/mqt/ddsim/primitives/sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,20 @@
import math
from typing import TYPE_CHECKING, Any, Mapping, Sequence, Union

from qiskit.primitives.base import BaseSampler, SamplerResult
from qiskit.primitives.primitive_job import PrimitiveJob
from qiskit.primitives.utils import _circuit_key # noqa: PLC2701
from qiskit.primitives import SamplerResult
from qiskit.primitives.sampler import Sampler as QiskitSampler
from qiskit.result import QuasiDistribution, Result

from mqt.ddsim.qasmsimulator import QasmSimulatorBackend

if TYPE_CHECKING:
from qiskit.circuit import Parameter
from qiskit.circuit.parameterexpression import ParameterValueType
from qiskit.circuit.quantumcircuit import QuantumCircuit

Parameters = Union[Mapping[Parameter, ParameterValueType], Sequence[ParameterValueType]]


class Sampler(BaseSampler):
class Sampler(QiskitSampler):
_BACKEND = QasmSimulatorBackend()

def __init__(
Expand All @@ -41,39 +39,10 @@ def __init__(
def backend(self) -> QasmSimulatorBackend:
return self._BACKEND

def _run(
self,
circuits: Sequence[QuantumCircuit],
parameter_values: Sequence[Parameters],
**run_options: Any,
) -> PrimitiveJob:
"""Stores circuits and parameters within the instance.
Executes _call function.
Args:
circuits: List of quantum circuits to simulate
parameter_values: List of parameters associated with those circuits
run_options: Additional run options.
Returns:
PrimitiveJob.
"""
circuit_indices = []
for circuit in circuits:
key = _circuit_key(circuit)
index = self._circuit_ids.get(key)
if index is not None:
circuit_indices.append(index)
else:
num_circuits = len(self._circuits)
circuit_indices.append(num_circuits)
self._circuit_ids[key] = num_circuits
self._circuits.append(circuit)
self._parameters.append(circuit.parameters)

job = PrimitiveJob(self._call, circuit_indices, parameter_values, **run_options)
job.submit()
return job
@property
def num_circuits(self) -> int:
"""The number of circuits stored in the sampler."""
return len(self._circuits)

def _call(
self,
Expand Down
10 changes: 0 additions & 10 deletions src/mqt/ddsim/qasmsimulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import time
import uuid
from math import log2
from typing import TYPE_CHECKING, Any, Mapping, Sequence, Union

from qiskit import QuantumCircuit
Expand All @@ -13,7 +12,6 @@
from qiskit.result import Result
from qiskit.result.models import ExperimentResult, ExperimentResultData
from qiskit.transpiler import Target
from qiskit.utils.multiprocessing import local_hardware_info

from . import __version__
from .header import DDSIMHeader
Expand All @@ -34,14 +32,6 @@ class QasmSimulatorBackend(BackendV2):
_SHOW_STATE_VECTOR = False
_TARGET = Target(description="MQT DDSIM Simulator Target", num_qubits=128)

@staticmethod
def max_qubits(for_matrix: bool = False) -> int:
max_complex = local_hardware_info()["memory"] * (1024**3) / 16
max_qubits = int(log2(max_complex))
if for_matrix:
max_qubits = max_qubits // 2
return max_qubits

@staticmethod
def _add_operations_to_target(target: Target) -> None:
DDSIMTargetBuilder.add_0q_gates(target)
Expand Down
2 changes: 1 addition & 1 deletion src/mqt/ddsim/statevectorsimulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class StatevectorSimulatorBackend(QasmSimulatorBackend):
_SHOW_STATE_VECTOR = True
_SV_TARGET = Target(
description="MQT DDSIM Statevector Simulator Target",
num_qubits=QasmSimulatorBackend.max_qubits(),
num_qubits=30, # corresponds to 16GiB memory for storing the full statevector
)

def __init__(self) -> None:
Expand Down
2 changes: 1 addition & 1 deletion src/mqt/ddsim/unitarysimulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class UnitarySimulatorBackend(QasmSimulatorBackend):

_US_TARGET = Target(
description="MQT DDSIM Unitary Simulator Target",
num_qubits=QasmSimulatorBackend.max_qubits(for_matrix=True),
num_qubits=15, # corresponds to 16GiB memory for storing the full matrix
)

@staticmethod
Expand Down
1 change: 0 additions & 1 deletion test/__init__.py

This file was deleted.

2 changes: 1 addition & 1 deletion test/python/constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ scikit-build-core==0.6.1
setuptools-scm==7.0.0
pybind11==2.11.0
pytest==7.0.0
qiskit==0.45.0
qiskit==1.0.0
Loading

0 comments on commit 37d0485

Please sign in to comment.