From 9807e3f16d38af109ac4fd0173fd25b320578bf7 Mon Sep 17 00:00:00 2001 From: Melf Date: Tue, 26 Mar 2024 11:01:54 +0000 Subject: [PATCH 01/12] remove IBMQEmulatorbackend, replace with local --- docs/api.rst | 5 - docs/intro.txt | 5 +- pytket/extensions/qiskit/__init__.py | 1 - pytket/extensions/qiskit/backends/__init__.py | 1 - pytket/extensions/qiskit/backends/ibm.py | 3 +- .../qiskit/backends/ibmq_emulator.py | 251 ------------------ tests/backend_test.py | 23 +- tests/conftest.py | 28 -- tests/qiskit_backend_test.py | 6 +- 9 files changed, 15 insertions(+), 308 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 033acfb9..f3cc63d5 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -6,11 +6,6 @@ API documentation :show-inheritance: :members: -.. autoclass:: pytket.extensions.qiskit.IBMQEmulatorBackend - :special-members: __init__ - :show-inheritance: - :members: - .. autoclass:: pytket.extensions.qiskit.IBMQLocalEmulatorBackend :special-members: __init__ :show-inheritance: diff --git a/docs/intro.txt b/docs/intro.txt index b2c3a4f6..500d11dc 100644 --- a/docs/intro.txt +++ b/docs/intro.txt @@ -28,7 +28,6 @@ Available IBM Backends :nosignatures: IBMQBackend - IBMQEmulatorBackend IBMQLocalEmulatorBackend AerBackend AerStateBackend @@ -95,7 +94,7 @@ to disk: IBMProvider.save_account(token=ibm_token) QiskitRuntimeService.save_account(channel="ibm_quantum", token=ibm_token) -To see which devices you can access you can use the ``available_devices`` method on the :py:class:`IBMQBackend` or :py:class:`IBMQEmulatorBackend`. Note that it is possible to pass optional ``instance`` and ``provider`` arguments to this method. This allows you to see which devices are accessible through your IBM hub. +To see which devices you can access you can use the ``available_devices`` method on the :py:class:`IBMQBackend`. Note that it is possible to pass optional ``instance`` and ``provider`` arguments to this method. This allows you to see which devices are accessible through your IBM hub. :: @@ -160,7 +159,7 @@ Default Compilation Every :py:class:`Backend` in pytket has its own ``default_compilation_pass`` method. This method applies a sequence of optimisations to a circuit depending on the value of an ``optimisation_level`` parameter. This default compilation will ensure that the circuit meets all the constraints required to run on the :py:class:`Backend`. The passes applied by different levels of optimisation are specified in the table below. -.. list-table:: **Default compilation pass for the IBMQBackend, IBMQEmulatorBackend and IBMQLocalEmulatorBackend** +.. list-table:: **Default compilation pass for the IBMQBackend and IBMQLocalEmulatorBackend** :widths: 25 25 25 :header-rows: 1 diff --git a/pytket/extensions/qiskit/__init__.py b/pytket/extensions/qiskit/__init__.py index 98aba5f4..36e0ab37 100644 --- a/pytket/extensions/qiskit/__init__.py +++ b/pytket/extensions/qiskit/__init__.py @@ -21,7 +21,6 @@ AerBackend, AerStateBackend, AerUnitaryBackend, - IBMQEmulatorBackend, IBMQLocalEmulatorBackend, ) from .backends.config import set_ibmq_config diff --git a/pytket/extensions/qiskit/backends/__init__.py b/pytket/extensions/qiskit/backends/__init__.py index 0b6b8f88..8260b23e 100644 --- a/pytket/extensions/qiskit/backends/__init__.py +++ b/pytket/extensions/qiskit/backends/__init__.py @@ -15,5 +15,4 @@ from .ibm import IBMQBackend, NoIBMQCredentialsError from .aer import AerBackend, AerStateBackend, AerUnitaryBackend -from .ibmq_emulator import IBMQEmulatorBackend from .ibmq_local_emulator import IBMQLocalEmulatorBackend diff --git a/pytket/extensions/qiskit/backends/ibm.py b/pytket/extensions/qiskit/backends/ibm.py index 6a4523a0..1970559f 100644 --- a/pytket/extensions/qiskit/backends/ibm.py +++ b/pytket/extensions/qiskit/backends/ibm.py @@ -355,8 +355,7 @@ def default_compilation_pass( This is a an abstract method which is implemented in the backend itself, and so is tailored to the backend's requirements. - The default compilation passes for the :py:class:`IBMQBackend`, - :py:class:`IBMQEmulatorBackend` and the + The default compilation passes for the :py:class:`IBMQBackend` and the Aer simulators support an optional ``placement_options`` dictionary containing arguments to override the default settings in :py:class:`NoiseAwarePlacement`. diff --git a/pytket/extensions/qiskit/backends/ibmq_emulator.py b/pytket/extensions/qiskit/backends/ibmq_emulator.py index e97b264c..e69de29b 100644 --- a/pytket/extensions/qiskit/backends/ibmq_emulator.py +++ b/pytket/extensions/qiskit/backends/ibmq_emulator.py @@ -1,251 +0,0 @@ -# Copyright 2019-2024 Cambridge Quantum Computing -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ast import literal_eval -from collections import Counter -import itertools -import json -from typing import ( - cast, - Dict, - Optional, - List, - Sequence, - Tuple, - Union, -) -from warnings import warn - -from qiskit_aer.noise.noise_model import NoiseModel # type: ignore -from qiskit_ibm_runtime import ( # type: ignore - QiskitRuntimeService, - Session, - Options, - Sampler, - RuntimeJob, -) -from qiskit_ibm_provider import IBMProvider # type: ignore - -from pytket.backends import Backend, CircuitNotRunError, ResultHandle, CircuitStatus -from pytket.backends.backendinfo import BackendInfo -from pytket.backends.backendresult import BackendResult -from pytket.backends.resulthandle import _ResultIdTuple -from pytket.circuit import Bit, Circuit, OpType -from pytket.extensions.qiskit.qiskit_convert import tk_to_qiskit -from pytket.passes import BasePass -from pytket.predicates import Predicate -from pytket.utils import prepare_circuit -from pytket.utils.outcomearray import OutcomeArray -from pytket.utils.results import KwargTypes - -from .ibm import IBMQBackend -from .ibm_utils import _STATUS_MAP, _batch_circuits - - -class IBMQEmulatorBackend(Backend): - """A Backend which uses the ibmq_qasm_simulator to emulate the behaviour of - IBMQBackend. Identical to :py:class:`IBMQBackend` except there is no `monitor` - parameter. Performs the same compilation and predicate checks as IBMQBackend. - Requires a valid IBMQ account. - """ - - _supports_shots = False - _supports_counts = True - _supports_contextual_optimisation = True - _persistent_handles = False - _supports_expectation = False - - def __init__( - self, - backend_name: str, - instance: Optional[str] = None, - provider: Optional["IBMProvider"] = None, - token: Optional[str] = None, - ): - super().__init__() - self._ibmq = IBMQBackend( - backend_name=backend_name, - instance=instance, - provider=provider, - token=token, - ) - - self._service = QiskitRuntimeService( - channel="ibm_quantum", instance=instance, token=token - ) - self._session = Session(service=self._service, backend="ibmq_qasm_simulator") - - # Get noise model: - self._noise_model = NoiseModel.from_backend(self._ibmq._backend) - - # cache of results keyed by job id and circuit index - self._ibm_res_cache: Dict[Tuple[str, int], Counter] = dict() - - @property - def backend_info(self) -> BackendInfo: - return self._ibmq._backend_info - - @property - def required_predicates(self) -> List[Predicate]: - return self._ibmq.required_predicates - - def default_compilation_pass( - self, optimisation_level: int = 2, placement_options: Optional[Dict] = None - ) -> BasePass: - """ - See documentation for :py:meth:`IBMQBackend.default_compilation_pass`. - """ - return self._ibmq.default_compilation_pass( - optimisation_level=optimisation_level, placement_options=placement_options - ) - - @property - def _result_id_type(self) -> _ResultIdTuple: - # job ID, index, stringified sequence of measured bits, post-processing circuit - return (str, int, str, str) - - def rebase_pass(self) -> BasePass: - return self._ibmq.rebase_pass() - - def process_circuits( - self, - circuits: Sequence[Circuit], - n_shots: Union[None, int, Sequence[Optional[int]]] = None, - valid_check: bool = True, - **kwargs: KwargTypes, - ) -> List[ResultHandle]: - """ - See :py:meth:`pytket.backends.Backend.process_circuits`. - Supported kwargs: `seed`, `postprocess`. - """ - circuits = list(circuits) - n_shots_list = Backend._get_n_shots_as_list( - n_shots, - len(circuits), - optional=False, - ) - - handle_list: List[Optional[ResultHandle]] = [None] * len(circuits) - seed = kwargs.get("seed") - circuit_batches, batch_order = _batch_circuits(circuits, n_shots_list) - - batch_id = 0 # identify batches for debug purposes only - for (n_shots, batch), indices in zip(circuit_batches, batch_order): - for chunk in itertools.zip_longest( - *([iter(zip(batch, indices))] * self._ibmq._max_per_job) - ): - filtchunk = list(filter(lambda x: x is not None, chunk)) - batch_chunk, indices_chunk = zip(*filtchunk) - - if valid_check: - self._check_all_circuits(batch_chunk) - - postprocess = kwargs.get("postprocess", False) - - qcs, c_bit_strs, ppcirc_strs = [], [], [] - for tkc in batch_chunk: - if postprocess: - c0, ppcirc = prepare_circuit(tkc, allow_classical=False) - ppcirc_rep = ppcirc.to_dict() - else: - c0, ppcirc_rep = tkc, None - qcs.append(tk_to_qiskit(c0)) - measured_bits = sorted( - [cmd.args[1] for cmd in tkc if cmd.op.type == OpType.Measure] - ) - c_bit_strs.append( - repr([(b.reg_name, b.index) for b in measured_bits]) - ) - ppcirc_strs.append(json.dumps(ppcirc_rep)) - options = Options() - options.resilience_level = 0 - options.execution.shots = n_shots - options.simulator.noise_model = self._noise_model - options.seed_simulator = seed - if type(seed) is int: - seed += 1 - sampler = Sampler(session=self._session, options=options) - job = sampler.run(circuits=qcs) - job_id = job.job_id() - for i, ind in enumerate(indices_chunk): - handle_list[ind] = ResultHandle( - job_id, i, c_bit_strs[i], ppcirc_strs[i] - ) - batch_id += 1 - for handle in handle_list: - assert handle is not None - self._cache[handle] = dict() - return cast(List[ResultHandle], handle_list) - - def _retrieve_job(self, jobid: str) -> RuntimeJob: - return self._service.job(jobid) - - def cancel(self, handle: ResultHandle) -> None: - jobid = cast(str, handle[0]) - job = self._retrieve_job(jobid) - try: - job.cancel() - except Exception as e: - warn(f"Unable to cancel job {jobid}: {e}") - - def circuit_status(self, handle: ResultHandle) -> CircuitStatus: - self._check_handle_type(handle) - jobid = cast(str, handle[0]) - job = self._service.job(jobid) - ibmstatus = job.status() - return CircuitStatus(_STATUS_MAP[ibmstatus], ibmstatus.value) - - def get_result(self, handle: ResultHandle, **kwargs: KwargTypes) -> BackendResult: - """ - See :py:meth:`pytket.backends.Backend.get_result`. - Supported kwargs: `timeout`, `wait`. - """ - self._check_handle_type(handle) - if handle in self._cache: - cached_result = self._cache[handle] - if "result" in cached_result: - return cast(BackendResult, cached_result["result"]) - jobid, index, c_bit_str, ppcirc_str = handle - c_bits = [Bit(reg_name, index) for reg_name, index in literal_eval(c_bit_str)] - ppcirc_rep = json.loads(ppcirc_str) - ppcirc = Circuit.from_dict(ppcirc_rep) if ppcirc_rep is not None else None - cache_key = (jobid, index) - if cache_key not in self._ibm_res_cache: - try: - job = self._retrieve_job(jobid) - except Exception as e: - warn(f"Unable to retrieve job {jobid}: {e}") - raise CircuitNotRunError(handle) - - res = job.result(timeout=kwargs.get("timeout", None)) - for circ_index, (r, d) in enumerate(zip(res.quasi_dists, res.metadata)): - self._ibm_res_cache[(jobid, circ_index)] = Counter( - {n: int(0.5 + d["shots"] * p) for n, p in r.items()} - ) - - counts = self._ibm_res_cache[cache_key] # Counter[int] - # Convert to `OutcomeArray`: - tket_counts: Counter = Counter() - for outcome_key, sample_count in counts.items(): - array = OutcomeArray.from_ints( - ints=[outcome_key], - width=len(c_bits), - big_endian=False, - ) - tket_counts[array] = sample_count - # Convert to `BackendResult`: - result = BackendResult(c_bits=c_bits, counts=tket_counts, ppcirc=ppcirc) - - self._cache[handle] = {"result": result} - return result diff --git a/tests/backend_test.py b/tests/backend_test.py index 55db9584..8da07f92 100644 --- a/tests/backend_test.py +++ b/tests/backend_test.py @@ -63,7 +63,6 @@ AerBackend, AerStateBackend, AerUnitaryBackend, - IBMQEmulatorBackend, IBMQLocalEmulatorBackend, ) from pytket.extensions.qiskit import ( @@ -471,10 +470,9 @@ def test_nshots_batching(brisbane_backend: IBMQBackend) -> None: @pytest.mark.flaky(reruns=3, reruns_delay=10) @pytest.mark.skipif(skip_remote_tests, reason=REASON) def test_nshots( - brisbane_emulator_backend: IBMQEmulatorBackend, brisbane_local_emulator_backend: IBMQLocalEmulatorBackend, ) -> None: - for b in [AerBackend(), brisbane_emulator_backend, brisbane_local_emulator_backend]: + for b in [AerBackend(), brisbane_local_emulator_backend]: circuit = Circuit(1).X(0) circuit.measure_all() n_shots = [1, 2, 3] @@ -836,10 +834,9 @@ def test_operator_expectation_value() -> None: @pytest.mark.flaky(reruns=3, reruns_delay=10) @pytest.mark.skipif(skip_remote_tests, reason=REASON) def test_ibmq_emulator( - brisbane_emulator_backend: IBMQEmulatorBackend, brisbane_local_emulator_backend: IBMQLocalEmulatorBackend, ) -> None: - for b in [brisbane_emulator_backend, brisbane_local_emulator_backend]: + for b in [brisbane_local_emulator_backend]: assert b._noise_model is not None # type: ignore b_ibm = b._ibmq # type: ignore b_aer = AerBackend() @@ -1115,17 +1112,17 @@ def test_postprocess() -> None: @pytest.mark.flaky(reruns=3, reruns_delay=10) @pytest.mark.skipif(skip_remote_tests, reason=REASON) -def test_postprocess_emu(ibmq_qasm_emulator_backend: IBMQEmulatorBackend) -> None: - assert ibmq_qasm_emulator_backend.supports_contextual_optimisation +def test_postprocess_emu(brisbane_local_emulator_backend: IBMQLocalEmulatorBackend) -> None: + assert brisbane_local_emulator_backend.supports_contextual_optimisation c = Circuit(2, 2) c.X(0).X(1).measure_all() - c = ibmq_qasm_emulator_backend.get_compiled_circuit(c) - h = ibmq_qasm_emulator_backend.process_circuit(c, n_shots=10, postprocess=True) + c = brisbane_local_emulator_backend.get_compiled_circuit(c) + h = brisbane_local_emulator_backend.process_circuit(c, n_shots=10, postprocess=True) ppcirc = Circuit.from_dict(json.loads(cast(str, h[3]))) ppcmds = ppcirc.get_commands() assert len(ppcmds) > 0 assert all(ppcmd.op.type == OpType.ClassicalTransform for ppcmd in ppcmds) - r = ibmq_qasm_emulator_backend.get_result(h) + r = brisbane_local_emulator_backend.get_result(h) counts = r.get_counts() assert sum(counts.values()) == 10 @@ -1193,11 +1190,10 @@ def test_available_devices(ibm_provider: IBMProvider) -> None: @pytest.mark.flaky(reruns=3, reruns_delay=10) @pytest.mark.skipif(skip_remote_tests, reason=REASON) def test_backendinfo_serialization1( - brisbane_emulator_backend: IBMQEmulatorBackend, brisbane_local_emulator_backend: IBMQLocalEmulatorBackend, ) -> None: # https://github.com/CQCL/tket/issues/192 - for b in [brisbane_emulator_backend, brisbane_local_emulator_backend]: + for b in [brisbane_local_emulator_backend]: backend_info_json = b.backend_info.to_dict() # type: ignore s = json.dumps(backend_info_json) backend_info_json1 = json.loads(s) @@ -1250,11 +1246,10 @@ def test_sim_qubit_order() -> None: @pytest.mark.flaky(reruns=3, reruns_delay=10) @pytest.mark.skipif(skip_remote_tests, reason=REASON) def test_required_predicates( - brisbane_emulator_backend: IBMQEmulatorBackend, brisbane_local_emulator_backend: IBMQLocalEmulatorBackend, ) -> None: # https://github.com/CQCL/pytket-qiskit/issues/93 - for b in [brisbane_emulator_backend, brisbane_local_emulator_backend]: + for b in [brisbane_local_emulator_backend]: circ = Circuit(8) # 8 qubit circuit in IBMQ gateset circ.X(0).CX(0, 1).CX(0, 2).CX(0, 3).CX(0, 4).CX(0, 5).CX(0, 6).CX( 0, 7 diff --git a/tests/conftest.py b/tests/conftest.py index 25255efe..9f8ba833 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -18,7 +18,6 @@ from qiskit_ibm_provider import IBMProvider # type: ignore from pytket.extensions.qiskit import ( IBMQBackend, - IBMQEmulatorBackend, IBMQLocalEmulatorBackend, ) @@ -68,33 +67,6 @@ def simulator_stabilizer_backend() -> IBMQBackend: ) -@pytest.fixture(scope="module") -def brisbane_emulator_backend() -> IBMQEmulatorBackend: - return IBMQEmulatorBackend( - "ibm_brisbane", - instance="ibm-q/open/main", - token=os.getenv("PYTKET_REMOTE_QISKIT_TOKEN"), - ) - - -@pytest.fixture(scope="module") -def ibmq_qasm_emulator_backend() -> IBMQEmulatorBackend: - return IBMQEmulatorBackend( - "ibmq_qasm_simulator", - instance="ibm-q/open/main", - token=os.getenv("PYTKET_REMOTE_QISKIT_TOKEN"), - ) - - -@pytest.fixture(scope="module") -def nairobi_emulator_backend() -> IBMQEmulatorBackend: - return IBMQEmulatorBackend( - "ibm_brisbane", - instance="ibm-q/open/main", - token=os.getenv("PYTKET_REMOTE_QISKIT_TOKEN"), - ) - - @pytest.fixture(scope="module") def brisbane_local_emulator_backend() -> IBMQLocalEmulatorBackend: return IBMQLocalEmulatorBackend( diff --git a/tests/qiskit_backend_test.py b/tests/qiskit_backend_test.py index 31b51b34..dbb6cff8 100644 --- a/tests/qiskit_backend_test.py +++ b/tests/qiskit_backend_test.py @@ -30,7 +30,7 @@ AerBackend, AerStateBackend, AerUnitaryBackend, - IBMQEmulatorBackend, + IBMQLocalEmulatorBackend, ) from pytket.extensions.qiskit.tket_backend import TketBackend from pytket.circuit import OpType @@ -115,14 +115,14 @@ def test_cancel() -> None: # https://github.com/CQCL/pytket-qiskit/issues/272 @pytest.mark.xfail(reason="Qiskit sampler not working") @pytest.mark.skipif(skip_remote_tests, reason=REASON) -def test_qiskit_counts(ibmq_qasm_emulator_backend: IBMQEmulatorBackend) -> None: +def test_qiskit_counts(brisbane_local_emulator_backend: IBMQLocalEmulatorBackend) -> None: num_qubits = 2 qc = QuantumCircuit(num_qubits) qc.h(0) qc.cx(0, 1) qc.measure_all() - s = BackendSampler(TketBackend(ibmq_qasm_emulator_backend)) + s = BackendSampler(TketBackend(brisbane_local_emulator_backend)) job = s.run([qc], shots=10) res = job.result() From 6b7aa636068fae3a372a90ab54eca5650e4ef6dc Mon Sep 17 00:00:00 2001 From: Melf Date: Tue, 26 Mar 2024 11:03:05 +0000 Subject: [PATCH 02/12] remove testcase, local fails supports_contextual_optimisation --- tests/backend_test.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/tests/backend_test.py b/tests/backend_test.py index 8da07f92..2d194477 100644 --- a/tests/backend_test.py +++ b/tests/backend_test.py @@ -1110,23 +1110,6 @@ def test_postprocess() -> None: b.cancel(h) -@pytest.mark.flaky(reruns=3, reruns_delay=10) -@pytest.mark.skipif(skip_remote_tests, reason=REASON) -def test_postprocess_emu(brisbane_local_emulator_backend: IBMQLocalEmulatorBackend) -> None: - assert brisbane_local_emulator_backend.supports_contextual_optimisation - c = Circuit(2, 2) - c.X(0).X(1).measure_all() - c = brisbane_local_emulator_backend.get_compiled_circuit(c) - h = brisbane_local_emulator_backend.process_circuit(c, n_shots=10, postprocess=True) - ppcirc = Circuit.from_dict(json.loads(cast(str, h[3]))) - ppcmds = ppcirc.get_commands() - assert len(ppcmds) > 0 - assert all(ppcmd.op.type == OpType.ClassicalTransform for ppcmd in ppcmds) - r = brisbane_local_emulator_backend.get_result(h) - counts = r.get_counts() - assert sum(counts.values()) == 10 - - # https://github.com/CQCL/pytket-qiskit/issues/278 # @pytest.mark.flaky(reruns=3, reruns_delay=10) @pytest.mark.xfail(reason="Qiskit rejecting cx") From 3d10ed3f2886c2da19c4f299857331331425ce77 Mon Sep 17 00:00:00 2001 From: Melf Date: Tue, 26 Mar 2024 11:23:48 +0000 Subject: [PATCH 03/12] remove not working simulator_stabilizer --- tests/backend_test.py | 39 --------------------------------------- tests/conftest.py | 10 ---------- 2 files changed, 49 deletions(-) diff --git a/tests/backend_test.py b/tests/backend_test.py index 2d194477..6e2f7410 100644 --- a/tests/backend_test.py +++ b/tests/backend_test.py @@ -1110,45 +1110,6 @@ def test_postprocess() -> None: b.cancel(h) -# https://github.com/CQCL/pytket-qiskit/issues/278 -# @pytest.mark.flaky(reruns=3, reruns_delay=10) -@pytest.mark.xfail(reason="Qiskit rejecting cx") -@pytest.mark.skipif(skip_remote_tests, reason=REASON) -def test_cloud_stabiliser(simulator_stabilizer_backend: IBMQBackend) -> None: - c = Circuit(2, 2) - c.H(0).SX(1).CX(0, 1).measure_all() - c = simulator_stabilizer_backend.get_compiled_circuit(c, 0) - h = simulator_stabilizer_backend.process_circuit(c, n_shots=10) - assert sum(simulator_stabilizer_backend.get_result(h).get_counts().values()) == 10 - - c = Circuit(2, 2) - c.H(0).SX(1).Rz(0.1, 0).CX(0, 1).measure_all() - assert not simulator_stabilizer_backend.valid_circuit(c) - - -# https://github.com/CQCL/pytket-qiskit/issues/278 -@pytest.mark.xfail(reason="Qiskit rejecting cx") -@pytest.mark.skipif(skip_remote_tests, reason=REASON) -def test_cloud_stabiliser_0() -> None: - num_qubits = 2 - qc = QuantumCircuit(num_qubits) - qc.h(0) - qc.sx(1) - qc.cx(0, 1) - qc.measure_all() - - _service = QiskitRuntimeService( - channel="ibm_quantum", - instance="ibm-q/open/main", - token=os.getenv("PYTKET_REMOTE_QISKIT_TOKEN"), - ) - _session = Session(service=_service, backend="simulator_stabilizer") - - sampler = Sampler(session=_session) - job = sampler.run(circuits=qc) - job.result() - - @pytest.mark.skipif(skip_remote_tests, reason=REASON) def test_available_devices(ibm_provider: IBMProvider) -> None: backend_info_list = IBMQBackend.available_devices(instance="ibm-q/open/main") diff --git a/tests/conftest.py b/tests/conftest.py index 9f8ba833..c2adde6f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -57,16 +57,6 @@ def qasm_simulator_backend() -> IBMQBackend: ) -@pytest.fixture(scope="module") -def simulator_stabilizer_backend() -> IBMQBackend: - return IBMQBackend( - "simulator_stabilizer", - instance="ibm-q/open/main", - monitor=False, - token=os.getenv("PYTKET_REMOTE_QISKIT_TOKEN"), - ) - - @pytest.fixture(scope="module") def brisbane_local_emulator_backend() -> IBMQLocalEmulatorBackend: return IBMQLocalEmulatorBackend( From 195c8e7b6180c825e78d0908f42972fa8a994974 Mon Sep 17 00:00:00 2001 From: Melf Date: Tue, 26 Mar 2024 11:25:50 +0000 Subject: [PATCH 04/12] rename IBMQLocalEmulatorBackend to IBMQEmulatorBackend --- docs/api.rst | 2 +- docs/intro.txt | 4 ++-- pytket/extensions/qiskit/__init__.py | 2 +- pytket/extensions/qiskit/backends/__init__.py | 2 +- .../qiskit/backends/ibmq_local_emulator.py | 2 +- tests/backend_test.py | 12 ++++++------ tests/conftest.py | 6 +++--- tests/qiskit_backend_test.py | 4 ++-- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index f3cc63d5..191152d5 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -6,7 +6,7 @@ API documentation :show-inheritance: :members: -.. autoclass:: pytket.extensions.qiskit.IBMQLocalEmulatorBackend +.. autoclass:: pytket.extensions.qiskit.IBMQEmulatorBackend :special-members: __init__ :show-inheritance: :members: diff --git a/docs/intro.txt b/docs/intro.txt index 500d11dc..8fbe5f0f 100644 --- a/docs/intro.txt +++ b/docs/intro.txt @@ -28,7 +28,7 @@ Available IBM Backends :nosignatures: IBMQBackend - IBMQLocalEmulatorBackend + IBMQEmulatorBackend AerBackend AerStateBackend AerUnitaryBackend @@ -159,7 +159,7 @@ Default Compilation Every :py:class:`Backend` in pytket has its own ``default_compilation_pass`` method. This method applies a sequence of optimisations to a circuit depending on the value of an ``optimisation_level`` parameter. This default compilation will ensure that the circuit meets all the constraints required to run on the :py:class:`Backend`. The passes applied by different levels of optimisation are specified in the table below. -.. list-table:: **Default compilation pass for the IBMQBackend and IBMQLocalEmulatorBackend** +.. list-table:: **Default compilation pass for the IBMQBackend and IBMQEmulatorBackend** :widths: 25 25 25 :header-rows: 1 diff --git a/pytket/extensions/qiskit/__init__.py b/pytket/extensions/qiskit/__init__.py index 36e0ab37..0887ac7f 100644 --- a/pytket/extensions/qiskit/__init__.py +++ b/pytket/extensions/qiskit/__init__.py @@ -21,7 +21,7 @@ AerBackend, AerStateBackend, AerUnitaryBackend, - IBMQLocalEmulatorBackend, + IBMQEmulatorBackend, ) from .backends.config import set_ibmq_config from .qiskit_convert import qiskit_to_tk, tk_to_qiskit, process_characterisation diff --git a/pytket/extensions/qiskit/backends/__init__.py b/pytket/extensions/qiskit/backends/__init__.py index 8260b23e..deb2ecdf 100644 --- a/pytket/extensions/qiskit/backends/__init__.py +++ b/pytket/extensions/qiskit/backends/__init__.py @@ -15,4 +15,4 @@ from .ibm import IBMQBackend, NoIBMQCredentialsError from .aer import AerBackend, AerStateBackend, AerUnitaryBackend -from .ibmq_local_emulator import IBMQLocalEmulatorBackend +from .ibmq_local_emulator import IBMQEmulatorBackend diff --git a/pytket/extensions/qiskit/backends/ibmq_local_emulator.py b/pytket/extensions/qiskit/backends/ibmq_local_emulator.py index ff326374..c0560fe5 100644 --- a/pytket/extensions/qiskit/backends/ibmq_local_emulator.py +++ b/pytket/extensions/qiskit/backends/ibmq_local_emulator.py @@ -43,7 +43,7 @@ from .ibm import IBMQBackend -class IBMQLocalEmulatorBackend(Backend): +class IBMQEmulatorBackend(Backend): """A backend which uses the AerBackend to loaclly emulate the behaviour of IBMQBackend. Identical to :py:class:`IBMQBackend` except there is no `monitor` parameter. Performs the same compilation and predicate checks as IBMQBackend. diff --git a/tests/backend_test.py b/tests/backend_test.py index 6e2f7410..57ede023 100644 --- a/tests/backend_test.py +++ b/tests/backend_test.py @@ -63,7 +63,7 @@ AerBackend, AerStateBackend, AerUnitaryBackend, - IBMQLocalEmulatorBackend, + IBMQEmulatorBackend, ) from pytket.extensions.qiskit import ( qiskit_to_tk, @@ -470,7 +470,7 @@ def test_nshots_batching(brisbane_backend: IBMQBackend) -> None: @pytest.mark.flaky(reruns=3, reruns_delay=10) @pytest.mark.skipif(skip_remote_tests, reason=REASON) def test_nshots( - brisbane_local_emulator_backend: IBMQLocalEmulatorBackend, + brisbane_local_emulator_backend: IBMQEmulatorBackend, ) -> None: for b in [AerBackend(), brisbane_local_emulator_backend]: circuit = Circuit(1).X(0) @@ -834,7 +834,7 @@ def test_operator_expectation_value() -> None: @pytest.mark.flaky(reruns=3, reruns_delay=10) @pytest.mark.skipif(skip_remote_tests, reason=REASON) def test_ibmq_emulator( - brisbane_local_emulator_backend: IBMQLocalEmulatorBackend, + brisbane_local_emulator_backend: IBMQEmulatorBackend, ) -> None: for b in [brisbane_local_emulator_backend]: assert b._noise_model is not None # type: ignore @@ -1134,7 +1134,7 @@ def test_available_devices(ibm_provider: IBMProvider) -> None: @pytest.mark.flaky(reruns=3, reruns_delay=10) @pytest.mark.skipif(skip_remote_tests, reason=REASON) def test_backendinfo_serialization1( - brisbane_local_emulator_backend: IBMQLocalEmulatorBackend, + brisbane_local_emulator_backend: IBMQEmulatorBackend, ) -> None: # https://github.com/CQCL/tket/issues/192 for b in [brisbane_local_emulator_backend]: @@ -1190,7 +1190,7 @@ def test_sim_qubit_order() -> None: @pytest.mark.flaky(reruns=3, reruns_delay=10) @pytest.mark.skipif(skip_remote_tests, reason=REASON) def test_required_predicates( - brisbane_local_emulator_backend: IBMQLocalEmulatorBackend, + brisbane_local_emulator_backend: IBMQEmulatorBackend, ) -> None: # https://github.com/CQCL/pytket-qiskit/issues/93 for b in [brisbane_local_emulator_backend]: @@ -1411,7 +1411,7 @@ def test_barriers_in_aer_simulators() -> None: @pytest.mark.skipif(skip_remote_tests, reason=REASON) def test_ibmq_local_emulator( - brisbane_local_emulator_backend: IBMQLocalEmulatorBackend, + brisbane_local_emulator_backend: IBMQEmulatorBackend, ) -> None: b = brisbane_local_emulator_backend assert not b.supports_contextual_optimisation diff --git a/tests/conftest.py b/tests/conftest.py index c2adde6f..113e85e6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -18,7 +18,7 @@ from qiskit_ibm_provider import IBMProvider # type: ignore from pytket.extensions.qiskit import ( IBMQBackend, - IBMQLocalEmulatorBackend, + IBMQEmulatorBackend, ) @@ -58,8 +58,8 @@ def qasm_simulator_backend() -> IBMQBackend: @pytest.fixture(scope="module") -def brisbane_local_emulator_backend() -> IBMQLocalEmulatorBackend: - return IBMQLocalEmulatorBackend( +def brisbane_local_emulator_backend() -> IBMQEmulatorBackend: + return IBMQEmulatorBackend( "ibm_brisbane", instance="ibm-q/open/main", token=os.getenv("PYTKET_REMOTE_QISKIT_TOKEN"), diff --git a/tests/qiskit_backend_test.py b/tests/qiskit_backend_test.py index dbb6cff8..dad40fc6 100644 --- a/tests/qiskit_backend_test.py +++ b/tests/qiskit_backend_test.py @@ -30,7 +30,7 @@ AerBackend, AerStateBackend, AerUnitaryBackend, - IBMQLocalEmulatorBackend, + IBMQEmulatorBackend, ) from pytket.extensions.qiskit.tket_backend import TketBackend from pytket.circuit import OpType @@ -115,7 +115,7 @@ def test_cancel() -> None: # https://github.com/CQCL/pytket-qiskit/issues/272 @pytest.mark.xfail(reason="Qiskit sampler not working") @pytest.mark.skipif(skip_remote_tests, reason=REASON) -def test_qiskit_counts(brisbane_local_emulator_backend: IBMQLocalEmulatorBackend) -> None: +def test_qiskit_counts(brisbane_local_emulator_backend: IBMQEmulatorBackend) -> None: num_qubits = 2 qc = QuantumCircuit(num_qubits) qc.h(0) From 7c6d0b30a7083724822d5ab0aa6e32907d000e80 Mon Sep 17 00:00:00 2001 From: Melf Date: Tue, 26 Mar 2024 11:26:53 +0000 Subject: [PATCH 05/12] clean up --- pytket/extensions/qiskit/backends/ibmq_emulator.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 pytket/extensions/qiskit/backends/ibmq_emulator.py diff --git a/pytket/extensions/qiskit/backends/ibmq_emulator.py b/pytket/extensions/qiskit/backends/ibmq_emulator.py deleted file mode 100644 index e69de29b..00000000 From b1c8ba996a02aac6af59756abc92b8cf18bda8be Mon Sep 17 00:00:00 2001 From: Melf Date: Tue, 26 Mar 2024 11:27:52 +0000 Subject: [PATCH 06/12] update changelog --- docs/changelog.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 8809ea44..365013ab 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -5,6 +5,8 @@ Unreleased ---------- * Update qiskit-ibm-runtime version requirement to 0.22. +* remove all remote simulators +* rename ``IBMQLocalEmulatorBackend`` to ``IBMQEmulatorBackend`` 0.50.0 (March 2024) ------------------- From b3598ac8f0ce8ea47efa25ad6c5341611da338df Mon Sep 17 00:00:00 2001 From: Melf Date: Tue, 26 Mar 2024 11:36:19 +0000 Subject: [PATCH 07/12] fix mypy --- tests/backend_test.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/backend_test.py b/tests/backend_test.py index 57ede023..fc5d12fc 100644 --- a/tests/backend_test.py +++ b/tests/backend_test.py @@ -837,8 +837,8 @@ def test_ibmq_emulator( brisbane_local_emulator_backend: IBMQEmulatorBackend, ) -> None: for b in [brisbane_local_emulator_backend]: - assert b._noise_model is not None # type: ignore - b_ibm = b._ibmq # type: ignore + assert b._noise_model is not None + b_ibm = b._ibmq b_aer = AerBackend() for ol in range(3): comp_pass = b.default_compilation_pass(ol) @@ -863,7 +863,7 @@ def test_ibmq_emulator( b.rebase_pass().apply(copy_circ) assert b.required_predicates[1].verify(copy_circ) circ = b.get_compiled_circuit(circ) - b_noi = AerBackend(noise_model=b._noise_model) # type: ignore + b_noi = AerBackend(noise_model=b._noise_model) emu_counts = b.run_circuit(circ, n_shots=10, seed=10).get_counts() aer_counts = b_noi.run_circuit(circ, n_shots=10, seed=10).get_counts() # Even with the same seed, the results may differ. @@ -1138,7 +1138,7 @@ def test_backendinfo_serialization1( ) -> None: # https://github.com/CQCL/tket/issues/192 for b in [brisbane_local_emulator_backend]: - backend_info_json = b.backend_info.to_dict() # type: ignore + backend_info_json = b.backend_info.to_dict() s = json.dumps(backend_info_json) backend_info_json1 = json.loads(s) assert backend_info_json == backend_info_json1 From bff3e001904cfcc03a338df13b1863b599b47d8a Mon Sep 17 00:00:00 2001 From: Melf Date: Thu, 28 Mar 2024 10:02:13 +0000 Subject: [PATCH 08/12] remove for loops --- tests/backend_test.py | 97 +++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 50 deletions(-) diff --git a/tests/backend_test.py b/tests/backend_test.py index fc5d12fc..91d42806 100644 --- a/tests/backend_test.py +++ b/tests/backend_test.py @@ -836,38 +836,37 @@ def test_operator_expectation_value() -> None: def test_ibmq_emulator( brisbane_local_emulator_backend: IBMQEmulatorBackend, ) -> None: - for b in [brisbane_local_emulator_backend]: - assert b._noise_model is not None - b_ibm = b._ibmq - b_aer = AerBackend() - for ol in range(3): - comp_pass = b.default_compilation_pass(ol) - c = Circuit(3, 3) - c.H(0) - c.CX(0, 1) - c.CSWAP(1, 0, 2) - c.ZZPhase(0.84, 2, 0) - c_cop = c.copy() - comp_pass.apply(c_cop) - c.measure_all() - for bac in (b, b_ibm): - assert all(pred.verify(c_cop) for pred in bac.required_predicates) - - c_cop_2 = c.copy() - c_cop_2 = b_aer.get_compiled_circuit(c_cop_2, ol) - if ol == 0: - assert not all(pred.verify(c_cop_2) for pred in b.required_predicates) - - circ = Circuit(2, 2).H(0).CX(0, 1).measure_all() - copy_circ = circ.copy() - b.rebase_pass().apply(copy_circ) - assert b.required_predicates[1].verify(copy_circ) - circ = b.get_compiled_circuit(circ) - b_noi = AerBackend(noise_model=b._noise_model) - emu_counts = b.run_circuit(circ, n_shots=10, seed=10).get_counts() - aer_counts = b_noi.run_circuit(circ, n_shots=10, seed=10).get_counts() - # Even with the same seed, the results may differ. - assert sum(emu_counts.values()) == sum(aer_counts.values()) + assert brisbane_local_emulator_backend._noise_model is not None + b_ibm = brisbane_local_emulator_backend._ibmq + b_aer = AerBackend() + for ol in range(3): + comp_pass = brisbane_local_emulator_backend.default_compilation_pass(ol) + c = Circuit(3, 3) + c.H(0) + c.CX(0, 1) + c.CSWAP(1, 0, 2) + c.ZZPhase(0.84, 2, 0) + c_cop = c.copy() + comp_pass.apply(c_cop) + c.measure_all() + for bac in (brisbane_local_emulator_backend, b_ibm): + assert all(pred.verify(c_cop) for pred in bac.required_predicates) + + c_cop_2 = c.copy() + c_cop_2 = b_aer.get_compiled_circuit(c_cop_2, ol) + if ol == 0: + assert not all(pred.verify(c_cop_2) for pred in brisbane_local_emulator_backend.required_predicates) + + circ = Circuit(2, 2).H(0).CX(0, 1).measure_all() + copy_circ = circ.copy() + brisbane_local_emulator_backend.rebase_pass().apply(copy_circ) + assert brisbane_local_emulator_backend.required_predicates[1].verify(copy_circ) + circ = brisbane_local_emulator_backend.get_compiled_circuit(circ) + b_noi = AerBackend(noise_model=brisbane_local_emulator_backend._noise_model) + emu_counts = brisbane_local_emulator_backend.run_circuit(circ, n_shots=10, seed=10).get_counts() + aer_counts = b_noi.run_circuit(circ, n_shots=10, seed=10).get_counts() + # Even with the same seed, the results may differ. + assert sum(emu_counts.values()) == sum(aer_counts.values()) @given( @@ -1137,11 +1136,10 @@ def test_backendinfo_serialization1( brisbane_local_emulator_backend: IBMQEmulatorBackend, ) -> None: # https://github.com/CQCL/tket/issues/192 - for b in [brisbane_local_emulator_backend]: - backend_info_json = b.backend_info.to_dict() - s = json.dumps(backend_info_json) - backend_info_json1 = json.loads(s) - assert backend_info_json == backend_info_json1 + backend_info_json = brisbane_local_emulator_backend.backend_info.to_dict() + s = json.dumps(backend_info_json) + backend_info_json1 = json.loads(s) + assert backend_info_json == backend_info_json1 def test_backendinfo_serialization2() -> None: @@ -1193,19 +1191,18 @@ def test_required_predicates( brisbane_local_emulator_backend: IBMQEmulatorBackend, ) -> None: # https://github.com/CQCL/pytket-qiskit/issues/93 - for b in [brisbane_local_emulator_backend]: - circ = Circuit(8) # 8 qubit circuit in IBMQ gateset - circ.X(0).CX(0, 1).CX(0, 2).CX(0, 3).CX(0, 4).CX(0, 5).CX(0, 6).CX( - 0, 7 - ).measure_all() - with pytest.raises(CircuitNotValidError) as errorinfo: - b.run_circuit(circ, n_shots=100) - assert ( - "pytket.backends.backend_exceptions.CircuitNotValidError:" - + "Circuit with index 0 in submitted does" - + "not satisfy MaxNQubitsPredicate(5)" - in str(errorinfo) - ) + circ = Circuit(8) # 8 qubit circuit in IBMQ gateset + circ.X(0).CX(0, 1).CX(0, 2).CX(0, 3).CX(0, 4).CX(0, 5).CX(0, 6).CX( + 0, 7 + ).measure_all() + with pytest.raises(CircuitNotValidError) as errorinfo: + brisbane_local_emulator_backend.run_circuit(circ, n_shots=100) + assert ( + "pytket.backends.backend_exceptions.CircuitNotValidError:" + + "Circuit with index 0 in submitted does" + + "not satisfy MaxNQubitsPredicate(5)" + in str(errorinfo) + ) @pytest.mark.flaky(reruns=3, reruns_delay=10) From b17a67e5b4e0ddb0835a92748f24e19c9f114887 Mon Sep 17 00:00:00 2001 From: Melf Date: Thu, 28 Mar 2024 10:07:14 +0000 Subject: [PATCH 09/12] rename brisbane_local_emulator_backend to brisbane_emulator_backend --- tests/backend_test.py | 38 ++++++++++++++++++------------------ tests/conftest.py | 2 +- tests/qiskit_backend_test.py | 4 ++-- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/tests/backend_test.py b/tests/backend_test.py index 91d42806..9252e23c 100644 --- a/tests/backend_test.py +++ b/tests/backend_test.py @@ -470,9 +470,9 @@ def test_nshots_batching(brisbane_backend: IBMQBackend) -> None: @pytest.mark.flaky(reruns=3, reruns_delay=10) @pytest.mark.skipif(skip_remote_tests, reason=REASON) def test_nshots( - brisbane_local_emulator_backend: IBMQEmulatorBackend, + brisbane_emulator_backend: IBMQEmulatorBackend, ) -> None: - for b in [AerBackend(), brisbane_local_emulator_backend]: + for b in [AerBackend(), brisbane_emulator_backend]: circuit = Circuit(1).X(0) circuit.measure_all() n_shots = [1, 2, 3] @@ -834,13 +834,13 @@ def test_operator_expectation_value() -> None: @pytest.mark.flaky(reruns=3, reruns_delay=10) @pytest.mark.skipif(skip_remote_tests, reason=REASON) def test_ibmq_emulator( - brisbane_local_emulator_backend: IBMQEmulatorBackend, + brisbane_emulator_backend: IBMQEmulatorBackend, ) -> None: - assert brisbane_local_emulator_backend._noise_model is not None - b_ibm = brisbane_local_emulator_backend._ibmq + assert brisbane_emulator_backend._noise_model is not None + b_ibm = brisbane_emulator_backend._ibmq b_aer = AerBackend() for ol in range(3): - comp_pass = brisbane_local_emulator_backend.default_compilation_pass(ol) + comp_pass = brisbane_emulator_backend.default_compilation_pass(ol) c = Circuit(3, 3) c.H(0) c.CX(0, 1) @@ -849,21 +849,21 @@ def test_ibmq_emulator( c_cop = c.copy() comp_pass.apply(c_cop) c.measure_all() - for bac in (brisbane_local_emulator_backend, b_ibm): + for bac in (brisbane_emulator_backend, b_ibm): assert all(pred.verify(c_cop) for pred in bac.required_predicates) c_cop_2 = c.copy() c_cop_2 = b_aer.get_compiled_circuit(c_cop_2, ol) if ol == 0: - assert not all(pred.verify(c_cop_2) for pred in brisbane_local_emulator_backend.required_predicates) + assert not all(pred.verify(c_cop_2) for pred in brisbane_emulator_backend.required_predicates) circ = Circuit(2, 2).H(0).CX(0, 1).measure_all() copy_circ = circ.copy() - brisbane_local_emulator_backend.rebase_pass().apply(copy_circ) - assert brisbane_local_emulator_backend.required_predicates[1].verify(copy_circ) - circ = brisbane_local_emulator_backend.get_compiled_circuit(circ) - b_noi = AerBackend(noise_model=brisbane_local_emulator_backend._noise_model) - emu_counts = brisbane_local_emulator_backend.run_circuit(circ, n_shots=10, seed=10).get_counts() + brisbane_emulator_backend.rebase_pass().apply(copy_circ) + assert brisbane_emulator_backend.required_predicates[1].verify(copy_circ) + circ = brisbane_emulator_backend.get_compiled_circuit(circ) + b_noi = AerBackend(noise_model=brisbane_emulator_backend._noise_model) + emu_counts = brisbane_emulator_backend.run_circuit(circ, n_shots=10, seed=10).get_counts() aer_counts = b_noi.run_circuit(circ, n_shots=10, seed=10).get_counts() # Even with the same seed, the results may differ. assert sum(emu_counts.values()) == sum(aer_counts.values()) @@ -1133,10 +1133,10 @@ def test_available_devices(ibm_provider: IBMProvider) -> None: @pytest.mark.flaky(reruns=3, reruns_delay=10) @pytest.mark.skipif(skip_remote_tests, reason=REASON) def test_backendinfo_serialization1( - brisbane_local_emulator_backend: IBMQEmulatorBackend, + brisbane_emulator_backend: IBMQEmulatorBackend, ) -> None: # https://github.com/CQCL/tket/issues/192 - backend_info_json = brisbane_local_emulator_backend.backend_info.to_dict() + backend_info_json = brisbane_emulator_backend.backend_info.to_dict() s = json.dumps(backend_info_json) backend_info_json1 = json.loads(s) assert backend_info_json == backend_info_json1 @@ -1188,7 +1188,7 @@ def test_sim_qubit_order() -> None: @pytest.mark.flaky(reruns=3, reruns_delay=10) @pytest.mark.skipif(skip_remote_tests, reason=REASON) def test_required_predicates( - brisbane_local_emulator_backend: IBMQEmulatorBackend, + brisbane_emulator_backend: IBMQEmulatorBackend, ) -> None: # https://github.com/CQCL/pytket-qiskit/issues/93 circ = Circuit(8) # 8 qubit circuit in IBMQ gateset @@ -1196,7 +1196,7 @@ def test_required_predicates( 0, 7 ).measure_all() with pytest.raises(CircuitNotValidError) as errorinfo: - brisbane_local_emulator_backend.run_circuit(circ, n_shots=100) + brisbane_emulator_backend.run_circuit(circ, n_shots=100) assert ( "pytket.backends.backend_exceptions.CircuitNotValidError:" + "Circuit with index 0 in submitted does" @@ -1408,9 +1408,9 @@ def test_barriers_in_aer_simulators() -> None: @pytest.mark.skipif(skip_remote_tests, reason=REASON) def test_ibmq_local_emulator( - brisbane_local_emulator_backend: IBMQEmulatorBackend, + brisbane_emulator_backend: IBMQEmulatorBackend, ) -> None: - b = brisbane_local_emulator_backend + b = brisbane_emulator_backend assert not b.supports_contextual_optimisation circ = Circuit(2).H(0).CX(0, 1).measure_all() circ1 = b.get_compiled_circuit(circ) diff --git a/tests/conftest.py b/tests/conftest.py index 113e85e6..ffa18aa5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -58,7 +58,7 @@ def qasm_simulator_backend() -> IBMQBackend: @pytest.fixture(scope="module") -def brisbane_local_emulator_backend() -> IBMQEmulatorBackend: +def brisbane_emulator_backend() -> IBMQEmulatorBackend: return IBMQEmulatorBackend( "ibm_brisbane", instance="ibm-q/open/main", diff --git a/tests/qiskit_backend_test.py b/tests/qiskit_backend_test.py index dad40fc6..7c5e64f4 100644 --- a/tests/qiskit_backend_test.py +++ b/tests/qiskit_backend_test.py @@ -115,14 +115,14 @@ def test_cancel() -> None: # https://github.com/CQCL/pytket-qiskit/issues/272 @pytest.mark.xfail(reason="Qiskit sampler not working") @pytest.mark.skipif(skip_remote_tests, reason=REASON) -def test_qiskit_counts(brisbane_local_emulator_backend: IBMQEmulatorBackend) -> None: +def test_qiskit_counts(brisbane_emulator_backend: IBMQEmulatorBackend) -> None: num_qubits = 2 qc = QuantumCircuit(num_qubits) qc.h(0) qc.cx(0, 1) qc.measure_all() - s = BackendSampler(TketBackend(brisbane_local_emulator_backend)) + s = BackendSampler(TketBackend(brisbane_emulator_backend)) job = s.run([qc], shots=10) res = job.result() From a7a247060088f8eb09a6785f2af3659df9f73f1c Mon Sep 17 00:00:00 2001 From: Melf Date: Thu, 28 Mar 2024 10:08:43 +0000 Subject: [PATCH 10/12] update changelog --- docs/changelog.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 365013ab..594addd6 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -7,6 +7,7 @@ Unreleased * Update qiskit-ibm-runtime version requirement to 0.22. * remove all remote simulators * rename ``IBMQLocalEmulatorBackend`` to ``IBMQEmulatorBackend`` +* ``IBMQEmulatorBackend`` will now run locally 0.50.0 (March 2024) ------------------- From 6a3f76d0aba68b391f593f26420f1c277d5a8f0b Mon Sep 17 00:00:00 2001 From: Melf Date: Thu, 28 Mar 2024 10:13:33 +0000 Subject: [PATCH 11/12] clean up format --- tests/backend_test.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/backend_test.py b/tests/backend_test.py index 9252e23c..fe600697 100644 --- a/tests/backend_test.py +++ b/tests/backend_test.py @@ -855,7 +855,10 @@ def test_ibmq_emulator( c_cop_2 = c.copy() c_cop_2 = b_aer.get_compiled_circuit(c_cop_2, ol) if ol == 0: - assert not all(pred.verify(c_cop_2) for pred in brisbane_emulator_backend.required_predicates) + assert not all( + pred.verify(c_cop_2) + for pred in brisbane_emulator_backend.required_predicates + ) circ = Circuit(2, 2).H(0).CX(0, 1).measure_all() copy_circ = circ.copy() @@ -863,7 +866,9 @@ def test_ibmq_emulator( assert brisbane_emulator_backend.required_predicates[1].verify(copy_circ) circ = brisbane_emulator_backend.get_compiled_circuit(circ) b_noi = AerBackend(noise_model=brisbane_emulator_backend._noise_model) - emu_counts = brisbane_emulator_backend.run_circuit(circ, n_shots=10, seed=10).get_counts() + emu_counts = brisbane_emulator_backend.run_circuit( + circ, n_shots=10, seed=10 + ).get_counts() aer_counts = b_noi.run_circuit(circ, n_shots=10, seed=10).get_counts() # Even with the same seed, the results may differ. assert sum(emu_counts.values()) == sum(aer_counts.values()) From 12eb951d3682b668dac86a3b44f5cfd6a13126e2 Mon Sep 17 00:00:00 2001 From: Melf Date: Thu, 28 Mar 2024 10:15:56 +0000 Subject: [PATCH 12/12] rename ibmq_(local_)emulator file --- pytket/extensions/qiskit/backends/__init__.py | 2 +- .../backends/{ibmq_local_emulator.py => ibmq_emulator.py} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename pytket/extensions/qiskit/backends/{ibmq_local_emulator.py => ibmq_emulator.py} (100%) diff --git a/pytket/extensions/qiskit/backends/__init__.py b/pytket/extensions/qiskit/backends/__init__.py index deb2ecdf..a7a0c547 100644 --- a/pytket/extensions/qiskit/backends/__init__.py +++ b/pytket/extensions/qiskit/backends/__init__.py @@ -15,4 +15,4 @@ from .ibm import IBMQBackend, NoIBMQCredentialsError from .aer import AerBackend, AerStateBackend, AerUnitaryBackend -from .ibmq_local_emulator import IBMQEmulatorBackend +from .ibmq_emulator import IBMQEmulatorBackend diff --git a/pytket/extensions/qiskit/backends/ibmq_local_emulator.py b/pytket/extensions/qiskit/backends/ibmq_emulator.py similarity index 100% rename from pytket/extensions/qiskit/backends/ibmq_local_emulator.py rename to pytket/extensions/qiskit/backends/ibmq_emulator.py