mirror of https://github.com/Qiskit/qiskit.git
Update `transpile()` to convert `BackendV1` inputs to `BackendV2` with `BackendV2Converter` (#11996)
* Convert to V2 inside transpile, deal with small changes in tests. * Fix lint * Add reno and apply comment from Ray's review
This commit is contained in:
parent
f15d758838
commit
f04eaab9c7
|
@ -24,6 +24,7 @@ from qiskit.circuit.quantumcircuit import QuantumCircuit
|
|||
from qiskit.circuit.quantumregister import Qubit
|
||||
from qiskit.dagcircuit import DAGCircuit
|
||||
from qiskit.providers.backend import Backend
|
||||
from qiskit.providers.backend_compat import BackendV2Converter
|
||||
from qiskit.providers.models import BackendProperties
|
||||
from qiskit.pulse import Schedule, InstructionScheduleMap
|
||||
from qiskit.transpiler import Layout, CouplingMap, PropertySet
|
||||
|
@ -316,6 +317,12 @@ def transpile( # pylint: disable=too-many-return-statements
|
|||
config = user_config.get_config()
|
||||
optimization_level = config.get("transpile_optimization_level", 1)
|
||||
|
||||
if backend is not None and getattr(backend, "version", 0) <= 1:
|
||||
# This is a temporary conversion step to allow for a smoother transition
|
||||
# to a fully target-based transpiler pipeline while maintaining the behavior
|
||||
# of `transpile` with BackendV1 inputs.
|
||||
backend = BackendV2Converter(backend)
|
||||
|
||||
if (
|
||||
scheduling_method is not None
|
||||
and backend is None
|
||||
|
@ -471,14 +478,8 @@ def _check_circuits_coupling_map(circuits, cmap, backend):
|
|||
if cmap is not None:
|
||||
max_qubits = cmap.size()
|
||||
elif backend is not None:
|
||||
backend_version = getattr(backend, "version", 0)
|
||||
if backend_version <= 1:
|
||||
if not backend.configuration().simulator:
|
||||
max_qubits = backend.configuration().n_qubits
|
||||
else:
|
||||
max_qubits = None
|
||||
else:
|
||||
max_qubits = backend.num_qubits
|
||||
max_qubits = backend.num_qubits
|
||||
|
||||
for circuit in circuits:
|
||||
# If coupling_map is not None or num_qubits == 1
|
||||
num_qubits = len(circuit.qubits)
|
||||
|
@ -496,27 +497,15 @@ def _log_transpile_time(start_time, end_time):
|
|||
|
||||
def _parse_inst_map(inst_map, backend):
|
||||
# try getting inst_map from user, else backend
|
||||
if inst_map is None:
|
||||
backend_version = getattr(backend, "version", 0)
|
||||
if backend_version <= 1:
|
||||
if hasattr(backend, "defaults"):
|
||||
inst_map = getattr(backend.defaults(), "instruction_schedule_map", None)
|
||||
else:
|
||||
inst_map = backend.target.instruction_schedule_map()
|
||||
if inst_map is None and backend is not None:
|
||||
inst_map = backend.target.instruction_schedule_map()
|
||||
return inst_map
|
||||
|
||||
|
||||
def _parse_coupling_map(coupling_map, backend):
|
||||
# try getting coupling_map from user, else backend
|
||||
if coupling_map is None:
|
||||
backend_version = getattr(backend, "version", 0)
|
||||
if backend_version <= 1:
|
||||
if getattr(backend, "configuration", None):
|
||||
configuration = backend.configuration()
|
||||
if hasattr(configuration, "coupling_map") and configuration.coupling_map:
|
||||
coupling_map = CouplingMap(configuration.coupling_map)
|
||||
else:
|
||||
coupling_map = backend.coupling_map
|
||||
if coupling_map is None and backend is not None:
|
||||
coupling_map = backend.coupling_map
|
||||
|
||||
# coupling_map could be None, or a list of lists, e.g. [[0, 1], [2, 1]]
|
||||
if coupling_map is None or isinstance(coupling_map, CouplingMap):
|
||||
|
@ -553,14 +542,8 @@ def _parse_instruction_durations(backend, inst_durations, dt, circuit):
|
|||
take precedence over backend durations, but be superceded by ``inst_duration``s.
|
||||
"""
|
||||
if not inst_durations:
|
||||
backend_version = getattr(backend, "version", 0)
|
||||
if backend_version <= 1:
|
||||
backend_durations = InstructionDurations()
|
||||
try:
|
||||
backend_durations = InstructionDurations.from_backend(backend)
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
backend_durations = InstructionDurations()
|
||||
if backend is not None:
|
||||
backend_durations = backend.instruction_durations
|
||||
|
||||
circ_durations = InstructionDurations()
|
||||
|
@ -629,13 +612,6 @@ def _parse_timing_constraints(backend, timing_constraints):
|
|||
return timing_constraints
|
||||
if backend is None and timing_constraints is None:
|
||||
timing_constraints = TimingConstraints()
|
||||
else:
|
||||
backend_version = getattr(backend, "version", 0)
|
||||
if backend_version <= 1:
|
||||
if timing_constraints is None:
|
||||
# get constraints from backend
|
||||
timing_constraints = getattr(backend.configuration(), "timing_constraints", {})
|
||||
timing_constraints = TimingConstraints(**timing_constraints)
|
||||
else:
|
||||
timing_constraints = backend.target.timing_constraints()
|
||||
elif backend is not None:
|
||||
timing_constraints = backend.target.timing_constraints()
|
||||
return timing_constraints
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# This code is part of Qiskit.
|
||||
#
|
||||
# (C) Copyright IBM 2020.
|
||||
# (C) Copyright IBM 2020, 2024.
|
||||
#
|
||||
# This code is licensed under the Apache License, Version 2.0. You may
|
||||
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
||||
|
@ -57,7 +57,7 @@ def convert_to_target(
|
|||
A ``Target`` instance.
|
||||
"""
|
||||
|
||||
# importing pacakges where they are needed, to avoid cyclic-import.
|
||||
# importing packages where they are needed, to avoid cyclic-import.
|
||||
# pylint: disable=cyclic-import
|
||||
from qiskit.transpiler.target import (
|
||||
Target,
|
||||
|
@ -82,7 +82,7 @@ def convert_to_target(
|
|||
"switch_case": SwitchCaseOp,
|
||||
}
|
||||
|
||||
in_data = {"num_qubits": configuration.n_qubits}
|
||||
in_data = {"num_qubits": configuration.num_qubits}
|
||||
|
||||
# Parse global configuration properties
|
||||
if hasattr(configuration, "dt"):
|
||||
|
@ -97,7 +97,6 @@ def convert_to_target(
|
|||
all_instructions = set.union(
|
||||
basis_gates, set(required), supported_instructions.intersection(CONTROL_FLOW_OP_NAMES)
|
||||
)
|
||||
|
||||
inst_name_map = {} # type: Dict[str, Instruction]
|
||||
|
||||
faulty_ops = set()
|
||||
|
@ -244,10 +243,8 @@ def convert_to_target(
|
|||
|
||||
for name in inst_sched_map.instructions:
|
||||
for qubits in inst_sched_map.qubits_with_instruction(name):
|
||||
|
||||
if not isinstance(qubits, tuple):
|
||||
qubits = (qubits,)
|
||||
|
||||
if (
|
||||
name not in all_instructions
|
||||
or name not in prop_name_map
|
||||
|
@ -267,17 +264,18 @@ def convert_to_target(
|
|||
continue
|
||||
|
||||
entry = inst_sched_map._get_calibration_entry(name, qubits)
|
||||
|
||||
try:
|
||||
prop_name_map[name][qubits].calibration = entry
|
||||
except AttributeError:
|
||||
# if instruction properties are "None", add entry
|
||||
prop_name_map[name].update({qubits: InstructionProperties(None, None, entry)})
|
||||
logger.info(
|
||||
"The PulseDefaults payload received contains an instruction %s on "
|
||||
"qubits %s which is not present in the configuration or properties payload.",
|
||||
"qubits %s which is not present in the configuration or properties payload."
|
||||
"A new properties entry will be added to include the new calibration data.",
|
||||
name,
|
||||
qubits,
|
||||
)
|
||||
|
||||
# Add parsed properties to target
|
||||
target = Target(**in_data)
|
||||
for inst_name in all_instructions:
|
||||
|
@ -384,7 +382,7 @@ class BackendV2Converter(BackendV2):
|
|||
super().__init__(
|
||||
provider=backend.provider,
|
||||
name=backend.name(),
|
||||
description=self._config.description,
|
||||
description=getattr(self._config, "description", None),
|
||||
online_date=getattr(self._config, "online_date", None),
|
||||
backend_version=self._config.backend_version,
|
||||
)
|
||||
|
|
|
@ -32,7 +32,7 @@ class Fake1Q(FakeBackend):
|
|||
configuration = BackendProperties(
|
||||
backend_name="fake_1q",
|
||||
backend_version="0.0.0",
|
||||
n_qubits=1,
|
||||
num_qubits=1,
|
||||
basis_gates=["u1", "u2", "u3", "cx"],
|
||||
simulator=False,
|
||||
local=True,
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
upgrade:
|
||||
- |
|
||||
The :func:`.transpile` function has been upgraded to internally convert
|
||||
`backend` inputs of type :class:`.BackendV1` to :class:`.BackendV2`,
|
||||
which allows the transpilation pipeline to now access the backend
|
||||
constraints through a :class:`.Target`. This change does not require any
|
||||
user action.
|
|
@ -1,6 +1,6 @@
|
|||
# This code is part of Qiskit.
|
||||
#
|
||||
# (C) Copyright IBM 2019.
|
||||
# (C) Copyright IBM 2019, 2024.
|
||||
#
|
||||
# This code is licensed under the Apache License, Version 2.0. You may
|
||||
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
||||
|
@ -17,6 +17,7 @@ from ddt import ddt
|
|||
from qiskit import QuantumCircuit
|
||||
from qiskit.compiler import transpile
|
||||
from qiskit.providers.fake_provider import Fake1Q
|
||||
from qiskit.providers.basic_provider import BasicSimulator
|
||||
from qiskit.transpiler import TranspilerError
|
||||
from test import combine # pylint: disable=wrong-import-order
|
||||
from test import QiskitTestCase # pylint: disable=wrong-import-order
|
||||
|
@ -76,9 +77,7 @@ class Test1QWorking(QiskitTestCase):
|
|||
name="{circuit.__name__}_level{level}_valid",
|
||||
)
|
||||
def test_simulator(self, circuit, level):
|
||||
"""All the levels with all the 1Q simulator backend"""
|
||||
# Set fake backend config to simulator
|
||||
backend = Fake1Q()
|
||||
backend._configuration.simulator = True
|
||||
"""All the levels with a simulator backend"""
|
||||
backend = BasicSimulator()
|
||||
result = transpile(circuit(), backend=backend, optimization_level=level, seed_transpiler=42)
|
||||
self.assertIsInstance(result, QuantumCircuit)
|
||||
|
|
|
@ -324,7 +324,7 @@ class TestPassesInspection(QiskitTestCase):
|
|||
qc = QuantumCircuit(qr)
|
||||
qc.cx(qr[2], qr[4])
|
||||
|
||||
backend = GenericBackendV2(num_qubits=14, coupling_map=MELBOURNE_CMAP)
|
||||
backend = GenericBackendV2(num_qubits=14, coupling_map=MELBOURNE_CMAP, seed=42)
|
||||
|
||||
_ = transpile(qc, backend, optimization_level=level, callback=self.callback)
|
||||
|
||||
|
@ -413,7 +413,7 @@ class TestPassesInspection(QiskitTestCase):
|
|||
"""Custom post translation stage."""
|
||||
return "custom_stage_for_test"
|
||||
|
||||
target = TargetBackend(num_qubits=7)
|
||||
target = TargetBackend(num_qubits=7, seed=42)
|
||||
qr = QuantumRegister(2, "q")
|
||||
qc = QuantumCircuit(qr)
|
||||
qc.h(qr[0])
|
||||
|
@ -425,7 +425,7 @@ class TestPassesInspection(QiskitTestCase):
|
|||
|
||||
def test_level1_runs_vf2post_layout_when_routing_required(self):
|
||||
"""Test that if we run routing as part of sabre layout VF2PostLayout runs."""
|
||||
target = GenericBackendV2(num_qubits=7, coupling_map=LAGOS_CMAP)
|
||||
target = GenericBackendV2(num_qubits=7, coupling_map=LAGOS_CMAP, seed=42)
|
||||
qc = QuantumCircuit(5)
|
||||
qc.h(0)
|
||||
qc.cy(0, 1)
|
||||
|
@ -448,7 +448,7 @@ class TestPassesInspection(QiskitTestCase):
|
|||
|
||||
def test_level1_runs_vf2post_layout_when_routing_method_set_and_required(self):
|
||||
"""Test that if we run routing as part of sabre layout VF2PostLayout runs."""
|
||||
target = GenericBackendV2(num_qubits=7, coupling_map=LAGOS_CMAP)
|
||||
target = GenericBackendV2(num_qubits=7, coupling_map=LAGOS_CMAP, seed=42)
|
||||
qc = QuantumCircuit(5)
|
||||
qc.h(0)
|
||||
qc.cy(0, 1)
|
||||
|
@ -473,7 +473,10 @@ class TestPassesInspection(QiskitTestCase):
|
|||
def test_level1_not_runs_vf2post_layout_when_layout_method_set(self):
|
||||
"""Test that if we don't run VF2PostLayout with custom layout_method."""
|
||||
target = GenericBackendV2(
|
||||
num_qubits=7, basis_gates=["cx", "id", "rz", "sx", "x"], coupling_map=LAGOS_CMAP
|
||||
num_qubits=7,
|
||||
basis_gates=["cx", "id", "rz", "sx", "x"],
|
||||
coupling_map=LAGOS_CMAP,
|
||||
seed=42,
|
||||
)
|
||||
qc = QuantumCircuit(5)
|
||||
qc.h(0)
|
||||
|
@ -495,7 +498,10 @@ class TestPassesInspection(QiskitTestCase):
|
|||
def test_level1_not_run_vf2post_layout_when_trivial_is_perfect(self):
|
||||
"""Test that if we find a trivial perfect layout we don't run vf2post."""
|
||||
target = GenericBackendV2(
|
||||
num_qubits=7, basis_gates=["cx", "id", "rz", "sx", "x"], coupling_map=LAGOS_CMAP
|
||||
num_qubits=7,
|
||||
basis_gates=["cx", "id", "rz", "sx", "x"],
|
||||
coupling_map=LAGOS_CMAP,
|
||||
seed=42,
|
||||
)
|
||||
qc = QuantumCircuit(2)
|
||||
qc.h(0)
|
||||
|
@ -512,7 +518,10 @@ class TestPassesInspection(QiskitTestCase):
|
|||
def test_level1_not_run_vf2post_layout_when_vf2layout_is_perfect(self):
|
||||
"""Test that if we find a vf2 perfect layout we don't run vf2post."""
|
||||
target = GenericBackendV2(
|
||||
num_qubits=7, basis_gates=["cx", "id", "rz", "sx", "x"], coupling_map=LAGOS_CMAP
|
||||
num_qubits=7,
|
||||
basis_gates=["cx", "id", "rz", "sx", "x"],
|
||||
coupling_map=LAGOS_CMAP,
|
||||
seed=42,
|
||||
)
|
||||
qc = QuantumCircuit(4)
|
||||
qc.h(0)
|
||||
|
@ -531,7 +540,10 @@ class TestPassesInspection(QiskitTestCase):
|
|||
def test_level1_runs_vf2post_layout_when_routing_required_control_flow(self):
|
||||
"""Test that if we run routing as part of sabre layout VF2PostLayout runs."""
|
||||
target = GenericBackendV2(
|
||||
num_qubits=7, basis_gates=["cx", "id", "rz", "sx", "x"], coupling_map=LAGOS_CMAP
|
||||
num_qubits=7,
|
||||
basis_gates=["cx", "id", "rz", "sx", "x"],
|
||||
coupling_map=LAGOS_CMAP,
|
||||
seed=42,
|
||||
)
|
||||
_target = target.target
|
||||
target._target.add_instruction(ForLoopOp, name="for_loop")
|
||||
|
@ -558,7 +570,10 @@ class TestPassesInspection(QiskitTestCase):
|
|||
def test_level1_not_runs_vf2post_layout_when_layout_method_set_control_flow(self):
|
||||
"""Test that if we don't run VF2PostLayout with custom layout_method."""
|
||||
target = GenericBackendV2(
|
||||
num_qubits=7, basis_gates=["cx", "id", "rz", "sx", "x"], coupling_map=LAGOS_CMAP
|
||||
num_qubits=7,
|
||||
basis_gates=["cx", "id", "rz", "sx", "x"],
|
||||
coupling_map=LAGOS_CMAP,
|
||||
seed=42,
|
||||
)
|
||||
_target = target.target
|
||||
target._target.add_instruction(ForLoopOp, name="for_loop")
|
||||
|
@ -584,7 +599,10 @@ class TestPassesInspection(QiskitTestCase):
|
|||
def test_level1_not_run_vf2post_layout_when_trivial_is_perfect_control_flow(self):
|
||||
"""Test that if we find a trivial perfect layout we don't run vf2post."""
|
||||
target = GenericBackendV2(
|
||||
num_qubits=7, basis_gates=["cx", "id", "rz", "sx", "x"], coupling_map=LAGOS_CMAP
|
||||
num_qubits=7,
|
||||
basis_gates=["cx", "id", "rz", "sx", "x"],
|
||||
coupling_map=LAGOS_CMAP,
|
||||
seed=42,
|
||||
)
|
||||
_target = target.target
|
||||
target._target.add_instruction(ForLoopOp, name="for_loop")
|
||||
|
@ -604,7 +622,10 @@ class TestPassesInspection(QiskitTestCase):
|
|||
def test_level1_not_run_vf2post_layout_when_vf2layout_is_perfect_control_flow(self):
|
||||
"""Test that if we find a vf2 perfect layout we don't run vf2post."""
|
||||
target = GenericBackendV2(
|
||||
num_qubits=7, basis_gates=["cx", "id", "rz", "sx", "x"], coupling_map=LAGOS_CMAP
|
||||
num_qubits=7,
|
||||
basis_gates=["cx", "id", "rz", "sx", "x"],
|
||||
coupling_map=LAGOS_CMAP,
|
||||
seed=42,
|
||||
)
|
||||
_target = target.target
|
||||
target._target.add_instruction(ForLoopOp, name="for_loop")
|
||||
|
@ -630,7 +651,7 @@ class TestInitialLayouts(QiskitTestCase):
|
|||
|
||||
@data(0, 1, 2, 3)
|
||||
def test_layout_1711(self, level):
|
||||
"""Test that a user-given initial layout is respected,
|
||||
"""Test that a user-given initial layout is respected
|
||||
in the qobj.
|
||||
|
||||
See: https://github.com/Qiskit/qiskit-terra/issues/1711
|
||||
|
@ -661,9 +682,7 @@ class TestInitialLayouts(QiskitTestCase):
|
|||
14: ancilla[12],
|
||||
15: qr[2],
|
||||
}
|
||||
|
||||
backend = Fake20QV1()
|
||||
backend.configuration().coupling_map = RUESCHLIKON_CMAP
|
||||
backend = GenericBackendV2(num_qubits=16, coupling_map=RUESCHLIKON_CMAP, seed=42)
|
||||
qc_b = transpile(qc, backend, initial_layout=initial_layout, optimization_level=level)
|
||||
qobj = assemble(qc_b)
|
||||
|
||||
|
@ -672,7 +691,7 @@ class TestInitialLayouts(QiskitTestCase):
|
|||
compiled_ops = qobj.experiments[0].instructions
|
||||
for operation in compiled_ops:
|
||||
if operation.name == "cx":
|
||||
self.assertIn(operation.qubits, backend.configuration().coupling_map)
|
||||
self.assertIn(tuple(operation.qubits), backend.coupling_map)
|
||||
self.assertIn(operation.qubits, [[15, 0], [15, 2]])
|
||||
|
||||
@data(0, 1, 2, 3)
|
||||
|
@ -711,10 +730,8 @@ class TestInitialLayouts(QiskitTestCase):
|
|||
12: ancilla[7],
|
||||
13: ancilla[8],
|
||||
}
|
||||
backend = Fake20QV1()
|
||||
backend.configuration().coupling_map = MELBOURNE_CMAP
|
||||
backend = GenericBackendV2(num_qubits=14, coupling_map=MELBOURNE_CMAP, seed=42)
|
||||
qc_b = transpile(qc, backend, initial_layout=initial_layout, optimization_level=level)
|
||||
|
||||
self.assertEqual(qc_b._layout.initial_layout._p2v, final_layout)
|
||||
|
||||
output_qr = qc_b.qregs[0]
|
||||
|
@ -766,7 +783,6 @@ class TestInitialLayouts(QiskitTestCase):
|
|||
}
|
||||
|
||||
backend = Fake20QV1()
|
||||
|
||||
qc_b = transpile(qc, backend, initial_layout=initial_layout, optimization_level=level)
|
||||
|
||||
self.assertEqual(qc_b._layout.initial_layout._p2v, final_layout)
|
||||
|
@ -796,50 +812,51 @@ class TestFinalLayouts(QiskitTestCase):
|
|||
qc.cx(qr1[2], qr2[0])
|
||||
qc.cx(qr2[0], qr2[1])
|
||||
|
||||
ancilla = QuantumRegister(15, "ancilla")
|
||||
trivial_layout = {
|
||||
0: Qubit(QuantumRegister(3, "qr1"), 0),
|
||||
1: Qubit(QuantumRegister(3, "qr1"), 1),
|
||||
2: Qubit(QuantumRegister(3, "qr1"), 2),
|
||||
3: Qubit(QuantumRegister(2, "qr2"), 0),
|
||||
4: Qubit(QuantumRegister(2, "qr2"), 1),
|
||||
5: Qubit(QuantumRegister(15, "ancilla"), 0),
|
||||
6: Qubit(QuantumRegister(15, "ancilla"), 1),
|
||||
7: Qubit(QuantumRegister(15, "ancilla"), 2),
|
||||
8: Qubit(QuantumRegister(15, "ancilla"), 3),
|
||||
9: Qubit(QuantumRegister(15, "ancilla"), 4),
|
||||
10: Qubit(QuantumRegister(15, "ancilla"), 5),
|
||||
11: Qubit(QuantumRegister(15, "ancilla"), 6),
|
||||
12: Qubit(QuantumRegister(15, "ancilla"), 7),
|
||||
13: Qubit(QuantumRegister(15, "ancilla"), 8),
|
||||
14: Qubit(QuantumRegister(15, "ancilla"), 9),
|
||||
15: Qubit(QuantumRegister(15, "ancilla"), 10),
|
||||
16: Qubit(QuantumRegister(15, "ancilla"), 11),
|
||||
17: Qubit(QuantumRegister(15, "ancilla"), 12),
|
||||
18: Qubit(QuantumRegister(15, "ancilla"), 13),
|
||||
19: Qubit(QuantumRegister(15, "ancilla"), 14),
|
||||
0: qr1[0],
|
||||
1: qr1[1],
|
||||
2: qr1[2],
|
||||
3: qr2[0],
|
||||
4: qr2[1],
|
||||
5: ancilla[0],
|
||||
6: ancilla[1],
|
||||
7: ancilla[2],
|
||||
8: ancilla[3],
|
||||
9: ancilla[4],
|
||||
10: ancilla[5],
|
||||
11: ancilla[6],
|
||||
12: ancilla[7],
|
||||
13: ancilla[8],
|
||||
14: ancilla[9],
|
||||
15: ancilla[10],
|
||||
16: ancilla[11],
|
||||
17: ancilla[12],
|
||||
18: ancilla[13],
|
||||
19: ancilla[14],
|
||||
}
|
||||
|
||||
vf2_layout = {
|
||||
0: Qubit(QuantumRegister(15, "ancilla"), 0),
|
||||
1: Qubit(QuantumRegister(15, "ancilla"), 1),
|
||||
2: Qubit(QuantumRegister(15, "ancilla"), 2),
|
||||
3: Qubit(QuantumRegister(15, "ancilla"), 3),
|
||||
4: Qubit(QuantumRegister(15, "ancilla"), 4),
|
||||
5: Qubit(QuantumRegister(15, "ancilla"), 5),
|
||||
6: Qubit(QuantumRegister(15, "ancilla"), 6),
|
||||
7: Qubit(QuantumRegister(15, "ancilla"), 7),
|
||||
8: Qubit(QuantumRegister(3, "qr1"), 1),
|
||||
9: Qubit(QuantumRegister(15, "ancilla"), 8),
|
||||
10: Qubit(QuantumRegister(15, "ancilla"), 9),
|
||||
11: Qubit(QuantumRegister(15, "ancilla"), 10),
|
||||
12: Qubit(QuantumRegister(3, "qr1"), 0),
|
||||
13: Qubit(QuantumRegister(3, "qr1"), 2),
|
||||
14: Qubit(QuantumRegister(2, "qr2"), 1),
|
||||
15: Qubit(QuantumRegister(15, "ancilla"), 11),
|
||||
16: Qubit(QuantumRegister(15, "ancilla"), 12),
|
||||
17: Qubit(QuantumRegister(15, "ancilla"), 13),
|
||||
18: Qubit(QuantumRegister(15, "ancilla"), 14),
|
||||
19: Qubit(QuantumRegister(2, "qr2"), 0),
|
||||
0: ancilla[0],
|
||||
1: ancilla[1],
|
||||
2: ancilla[2],
|
||||
3: ancilla[3],
|
||||
4: ancilla[4],
|
||||
5: qr1[2],
|
||||
6: qr2[0],
|
||||
7: qr2[1],
|
||||
8: ancilla[5],
|
||||
9: ancilla[6],
|
||||
10: qr1[1],
|
||||
11: qr1[0],
|
||||
12: ancilla[7],
|
||||
13: ancilla[8],
|
||||
14: ancilla[9],
|
||||
15: ancilla[10],
|
||||
16: ancilla[11],
|
||||
17: ancilla[12],
|
||||
18: ancilla[13],
|
||||
19: ancilla[14],
|
||||
}
|
||||
|
||||
# Trivial layout
|
||||
|
@ -856,8 +873,8 @@ class TestFinalLayouts(QiskitTestCase):
|
|||
expected_layout_level2,
|
||||
expected_layout_level3,
|
||||
]
|
||||
backend = Fake20QV1()
|
||||
backend.configuration().coupling_map = TOKYO_CMAP
|
||||
|
||||
backend = GenericBackendV2(num_qubits=20, coupling_map=TOKYO_CMAP, seed=42)
|
||||
result = transpile(qc, backend, optimization_level=level, seed_transpiler=42)
|
||||
self.assertEqual(result._layout.initial_layout._p2v, expected_layouts[level])
|
||||
|
||||
|
@ -904,64 +921,18 @@ class TestFinalLayouts(QiskitTestCase):
|
|||
2: ancilla[2],
|
||||
3: ancilla[3],
|
||||
4: ancilla[4],
|
||||
5: qr[2],
|
||||
6: qr[1],
|
||||
7: ancilla[6],
|
||||
8: ancilla[7],
|
||||
9: ancilla[8],
|
||||
10: qr[3],
|
||||
11: qr[0],
|
||||
12: ancilla[9],
|
||||
13: ancilla[10],
|
||||
14: ancilla[11],
|
||||
15: ancilla[5],
|
||||
16: qr[4],
|
||||
17: ancilla[12],
|
||||
18: ancilla[13],
|
||||
19: ancilla[14],
|
||||
}
|
||||
|
||||
sabre_layout_lvl_2 = {
|
||||
0: ancilla[0],
|
||||
1: ancilla[1],
|
||||
2: ancilla[2],
|
||||
3: ancilla[3],
|
||||
4: ancilla[4],
|
||||
5: qr[2],
|
||||
6: qr[1],
|
||||
7: ancilla[6],
|
||||
8: ancilla[7],
|
||||
9: ancilla[8],
|
||||
10: qr[3],
|
||||
11: qr[0],
|
||||
12: ancilla[9],
|
||||
13: ancilla[10],
|
||||
14: ancilla[11],
|
||||
15: ancilla[5],
|
||||
16: qr[4],
|
||||
17: ancilla[12],
|
||||
18: ancilla[13],
|
||||
19: ancilla[14],
|
||||
}
|
||||
|
||||
sabre_layout_lvl_3 = {
|
||||
0: ancilla[0],
|
||||
1: ancilla[1],
|
||||
2: ancilla[2],
|
||||
3: ancilla[3],
|
||||
4: ancilla[4],
|
||||
5: qr[2],
|
||||
6: qr[1],
|
||||
7: ancilla[6],
|
||||
8: ancilla[7],
|
||||
9: ancilla[8],
|
||||
10: qr[3],
|
||||
11: qr[0],
|
||||
12: ancilla[9],
|
||||
13: ancilla[10],
|
||||
14: ancilla[11],
|
||||
15: ancilla[5],
|
||||
16: qr[4],
|
||||
5: qr[1],
|
||||
6: qr[0],
|
||||
7: qr[4],
|
||||
8: ancilla[6],
|
||||
9: ancilla[7],
|
||||
10: qr[2],
|
||||
11: qr[3],
|
||||
12: ancilla[5],
|
||||
13: ancilla[8],
|
||||
14: ancilla[9],
|
||||
15: ancilla[10],
|
||||
16: ancilla[11],
|
||||
17: ancilla[12],
|
||||
18: ancilla[13],
|
||||
19: ancilla[14],
|
||||
|
@ -969,8 +940,8 @@ class TestFinalLayouts(QiskitTestCase):
|
|||
|
||||
expected_layout_level0 = trivial_layout
|
||||
expected_layout_level1 = sabre_layout
|
||||
expected_layout_level2 = sabre_layout_lvl_2
|
||||
expected_layout_level3 = sabre_layout_lvl_3
|
||||
expected_layout_level2 = sabre_layout
|
||||
expected_layout_level3 = sabre_layout
|
||||
|
||||
expected_layouts = [
|
||||
expected_layout_level0,
|
||||
|
@ -978,9 +949,7 @@ class TestFinalLayouts(QiskitTestCase):
|
|||
expected_layout_level2,
|
||||
expected_layout_level3,
|
||||
]
|
||||
backend = Fake20QV1()
|
||||
backend.configuration().coupling_map = TOKYO_CMAP
|
||||
|
||||
backend = GenericBackendV2(num_qubits=20, coupling_map=TOKYO_CMAP, seed=42)
|
||||
result = transpile(qc, backend, optimization_level=level, seed_transpiler=42)
|
||||
self.assertEqual(result._layout.initial_layout._p2v, expected_layouts[level])
|
||||
|
||||
|
@ -991,12 +960,10 @@ class TestFinalLayouts(QiskitTestCase):
|
|||
See: https://github.com/Qiskit/qiskit-terra/issues/5694 for more
|
||||
details
|
||||
"""
|
||||
backend = Fake20QV1()
|
||||
backend.configuration().coupling_map = TOKYO_CMAP
|
||||
config = backend.configuration()
|
||||
backend = GenericBackendV2(num_qubits=20, coupling_map=TOKYO_CMAP, seed=42)
|
||||
|
||||
rows = [x[0] for x in config.coupling_map]
|
||||
cols = [x[1] for x in config.coupling_map]
|
||||
rows = [x[0] for x in backend.coupling_map]
|
||||
cols = [x[1] for x in backend.coupling_map]
|
||||
|
||||
adjacency_matrix = np.zeros((20, 20))
|
||||
adjacency_matrix[rows, cols] = 1
|
||||
|
@ -1255,7 +1222,7 @@ class TestGeneratePresetPassManagers(QiskitTestCase):
|
|||
@data(0, 1, 2, 3)
|
||||
def test_with_no_backend(self, optimization_level):
|
||||
"""Test a passmanager is constructed with no backend and optimization level."""
|
||||
target = GenericBackendV2(num_qubits=7, coupling_map=LAGOS_CMAP)
|
||||
target = GenericBackendV2(num_qubits=7, coupling_map=LAGOS_CMAP, seed=42)
|
||||
pm = generate_preset_pass_manager(
|
||||
optimization_level,
|
||||
coupling_map=target.coupling_map,
|
||||
|
@ -1270,7 +1237,7 @@ class TestGeneratePresetPassManagers(QiskitTestCase):
|
|||
@data(0, 1, 2, 3)
|
||||
def test_with_no_backend_only_target(self, optimization_level):
|
||||
"""Test a passmanager is constructed with a manual target and optimization level."""
|
||||
target = GenericBackendV2(num_qubits=7, coupling_map=LAGOS_CMAP)
|
||||
target = GenericBackendV2(num_qubits=7, coupling_map=LAGOS_CMAP, seed=42)
|
||||
pm = generate_preset_pass_manager(optimization_level, target=target.target)
|
||||
self.assertIsInstance(pm, PassManager)
|
||||
|
||||
|
@ -1299,7 +1266,7 @@ class TestGeneratePresetPassManagers(QiskitTestCase):
|
|||
"""Custom post translation stage."""
|
||||
return "custom_stage_for_test"
|
||||
|
||||
target = TargetBackend(num_qubits=7, coupling_map=LAGOS_CMAP)
|
||||
target = TargetBackend(num_qubits=7, coupling_map=LAGOS_CMAP, seed=42)
|
||||
pm = generate_preset_pass_manager(optimization_level, backend=target)
|
||||
self.assertIsInstance(pm, PassManager)
|
||||
|
||||
|
@ -1331,7 +1298,7 @@ class TestGeneratePresetPassManagers(QiskitTestCase):
|
|||
"""Custom post translation stage."""
|
||||
return "custom_stage_for_test"
|
||||
|
||||
target = TargetBackend(num_qubits=7, coupling_map=LAGOS_CMAP)
|
||||
target = TargetBackend(num_qubits=7, coupling_map=LAGOS_CMAP, seed=42)
|
||||
pm = generate_preset_pass_manager(optimization_level, backend=target)
|
||||
self.assertIsInstance(pm, PassManager)
|
||||
|
||||
|
@ -1363,7 +1330,7 @@ class TestGeneratePresetPassManagers(QiskitTestCase):
|
|||
"""Custom post translation stage."""
|
||||
return "custom_stage_for_test"
|
||||
|
||||
target = TargetBackend(num_qubits=7, coupling_map=LAGOS_CMAP)
|
||||
target = TargetBackend(num_qubits=7, coupling_map=LAGOS_CMAP, seed=42)
|
||||
pm = generate_preset_pass_manager(optimization_level, backend=target)
|
||||
self.assertIsInstance(pm, PassManager)
|
||||
|
||||
|
@ -1395,7 +1362,7 @@ class TestGeneratePresetPassManagers(QiskitTestCase):
|
|||
"""Custom post translation stage."""
|
||||
return "custom_stage_for_test"
|
||||
|
||||
target = TargetBackend(num_qubits=7, coupling_map=LAGOS_CMAP)
|
||||
target = TargetBackend(num_qubits=7, coupling_map=LAGOS_CMAP, seed=42)
|
||||
pm = generate_preset_pass_manager(optimization_level, backend=target)
|
||||
self.assertIsInstance(pm, PassManager)
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import ddt
|
|||
|
||||
from qiskit import pulse, circuit, transpile
|
||||
from qiskit.providers.fake_provider import Fake27QPulseV1, GenericBackendV2
|
||||
from qiskit.providers.models import GateConfig
|
||||
from qiskit.quantum_info.random import random_unitary
|
||||
from test import QiskitTestCase # pylint: disable=wrong-import-order
|
||||
|
||||
|
@ -185,6 +186,12 @@ class TestPulseGate(QiskitTestCase):
|
|||
backend.defaults().instruction_schedule_map.add(
|
||||
"my_gate", (1,), self.my_gate_q1, arguments=["P0"]
|
||||
)
|
||||
# Add gate to backend configuration
|
||||
backend.configuration().basis_gates.append("my_gate")
|
||||
dummy_config = GateConfig(
|
||||
name="my_gate", parameters=[], qasm_def="", coupling_map=[(0,), (1,)]
|
||||
)
|
||||
backend.configuration().gates.append(dummy_config)
|
||||
# Remove timing constraints to avoid triggering
|
||||
# scheduling passes.
|
||||
backend.configuration().timing_constraints = {}
|
||||
|
@ -212,6 +219,10 @@ class TestPulseGate(QiskitTestCase):
|
|||
backend.defaults().instruction_schedule_map.add(
|
||||
"my_gate", (0,), self.my_gate_q0, arguments=["P0"]
|
||||
)
|
||||
# Add gate to backend configuration
|
||||
backend.configuration().basis_gates.append("my_gate")
|
||||
dummy_config = GateConfig(name="my_gate", parameters=[], qasm_def="", coupling_map=[(0,)])
|
||||
backend.configuration().gates.append(dummy_config)
|
||||
# Remove timing constraints to avoid triggering
|
||||
# scheduling passes.
|
||||
backend.configuration().timing_constraints = {}
|
||||
|
@ -237,6 +248,10 @@ class TestPulseGate(QiskitTestCase):
|
|||
backend.defaults().instruction_schedule_map.add(
|
||||
"my_gate", (0,), self.my_gate_q0, arguments=["P0"]
|
||||
)
|
||||
# Add gate to backend configuration
|
||||
backend.configuration().basis_gates.append("my_gate")
|
||||
dummy_config = GateConfig(name="my_gate", parameters=[], qasm_def="", coupling_map=[(0,)])
|
||||
backend.configuration().gates.append(dummy_config)
|
||||
# Remove timing constraints to avoid triggering
|
||||
# scheduling passes.
|
||||
backend.configuration().timing_constraints = {}
|
||||
|
@ -263,6 +278,10 @@ class TestPulseGate(QiskitTestCase):
|
|||
backend.defaults().instruction_schedule_map.add(
|
||||
"my_gate", (0,), self.my_gate_q0, arguments=["P0"]
|
||||
)
|
||||
# Add gate to backend configuration
|
||||
backend.configuration().basis_gates.append("my_gate")
|
||||
dummy_config = GateConfig(name="my_gate", parameters=[], qasm_def="", coupling_map=[(0,)])
|
||||
backend.configuration().gates.append(dummy_config)
|
||||
# Remove timing constraints to avoid triggering
|
||||
# scheduling passes.
|
||||
backend.configuration().timing_constraints = {}
|
||||
|
|
Loading…
Reference in New Issue