diff --git a/docs/changelog.rst b/docs/changelog.rst index 1dd4c385..48a2f816 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -5,6 +5,8 @@ Unreleased ---------- * Add `IBMQBackend.default_compilation_pass_static` for offline compilation given config and props objects. +* Add `DirectednessPredicate` to IBMQBackend +* Default compilation pass of IBMQBackend will keep ECR gates in the direction required by the backend. 0.51.1rc0 (April 2024) ---------------------- diff --git a/pytket/extensions/qiskit/backends/ibm.py b/pytket/extensions/qiskit/backends/ibm.py index 96dd44ac..1f3b948d 100644 --- a/pytket/extensions/qiskit/backends/ibm.py +++ b/pytket/extensions/qiskit/backends/ibm.py @@ -82,11 +82,12 @@ NoFastFeedforwardPredicate, MaxNQubitsPredicate, Predicate, + DirectednessPredicate, ) from qiskit.providers.models import BackendProperties, QasmBackendConfiguration # type: ignore from ..qiskit_convert import tk_to_qiskit, _tk_gate_set -from pytket.architecture import FullyConnected +from pytket.architecture import FullyConnected, Architecture from pytket.placement import NoiseAwarePlacement from pytket.utils import prepare_circuit from pytket.utils.outcomearray import OutcomeArray @@ -346,17 +347,16 @@ def required_predicates(self) -> List[Predicate]: ) ), ] + if isinstance(self.backend_info.architecture, Architecture): + predicates.append(DirectednessPredicate(self.backend_info.architecture)) + mid_measure = self._backend_info.supports_midcircuit_measurement fast_feedforward = self._backend_info.supports_fast_feedforward if not mid_measure: - predicates = [ - NoClassicalControlPredicate(), - NoMidMeasurePredicate(), - ] + predicates + predicates.append(NoClassicalControlPredicate()) + predicates.append(NoMidMeasurePredicate()) if not fast_feedforward: - predicates = [ - NoFastFeedforwardPredicate(), - ] + predicates + predicates.append(NoFastFeedforwardPredicate()) return predicates def default_compilation_pass( @@ -451,7 +451,7 @@ def default_compilation_pass_offline( CXMappingPass( arch, noise_aware_placement, - directed_cx=False, + directed_cx=True, delay_measures=(not mid_measure), ) ) diff --git a/tests/backend_test.py b/tests/backend_test.py index 88514d5f..e82de3c1 100644 --- a/tests/backend_test.py +++ b/tests/backend_test.py @@ -476,7 +476,8 @@ def test_nshots( circuit = Circuit(1).X(0) circuit.measure_all() n_shots = [1, 2, 3] - results = b.get_results(b.process_circuits([circuit] * 3, n_shots=n_shots)) + circ_comp = b.get_compiled_circuit(circuit) + results = b.get_results(b.process_circuits([circ_comp] * 3, n_shots=n_shots)) assert [sum(r.get_counts().values()) for r in results] == n_shots @@ -1330,6 +1331,21 @@ def test_crosstalk_noise_model() -> None: res.get_counts() +@pytest.mark.skipif(skip_remote_tests, reason=REASON) +def test_ecr(ibm_brisbane_backend: IBMQBackend) -> None: + ghz5 = Circuit(5) + ghz5.H(0).CX(0, 1).CX(0, 2).CX(0, 3).CX(0, 4) + ghz5.measure_all() + ibm_ghz5 = ibm_brisbane_backend.get_compiled_circuit(ghz5) + + compiled_ghz5 = ibm_brisbane_backend.get_compiled_circuit(ibm_ghz5) + + ibm_brisbane_backend.valid_circuit(compiled_ghz5) + + handle = ibm_brisbane_backend.process_circuit(compiled_ghz5, n_shots=1000) + ibm_brisbane_backend.cancel(handle) + + # helper function for testing def _get_qiskit_statevector(qc: QuantumCircuit) -> np.ndarray: """Given a QuantumCircuit, use aer_simulator_statevector to compute its