Skip to content

Commit

Permalink
Deprecate fake backends based on BackendV1 (backport #12660) (#12837)
Browse files Browse the repository at this point in the history
* Deprecate fake backends based on BackendV1 (#12660)

* deprecate qobj and assemble

* reno

* first attempt on Fake1QV2

* deprecate Fake1Q

* Fake1QV2 should not have two-qubit gates

Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>

* test.python.circuit.test_parameters.TestParameters

* test.python.providers.fake_provider.test_fake_backends.FakeBackendsTest

* test.python.providers.test_fake_backends.TestFakeBackends

* test.python.result.test_mitigators

* test.python.transpiler.test_preset_passmanagers

* test.python.transpiler.test_target

* test.python.transpiler.test_unitary_synthesis

* test.python.transpiler.test_vf2_layout

* test.python.transpiler.test_vf2_post_layout

* test/python/visualization/test_circuit_latex

* test.python.transpiler.test_sabre_layout

* test.python.transpiler.test_sabre_layout

* test.python.transpiler.test_pulse_gate_pass

* test.python.scheduler.test_basic_scheduler.TestBasicSchedule

* test.python.pulse.test_transforms

* test.python.pulse.test_schedule

* test.python.pulse.test_macros

* test.python.pulse.test_instruction_schedule_map

* test.python.pulse.test_block

* test.python.circuit.test_scheduled_circuit

* test.python.transpiler.test_calibrationbuilder

* test.python.providers.test_backendconfiguration

* test.python.compiler.test_transpiler

* test.python.transpiler.test_passmanager_run

* test.python.transpiler.test_passmanager_config.TestPassManagerConfig.test_from_backend_and_user

* test.python.transpiler.test_passmanager_config

* test.python.primitives.test_backend_estimator.TestBackendEstimator

* test.python.circuit.test_scheduled_circuit.TestScheduledCircuit.test_schedule_circuit_when_backend_tells_dt

* test.python.circuit.test_scheduled_circuit

* test.python.transpiler.test_vf2_layout

* shallow deprecation of assemble

* test.python.compiler.test_disassembler

* fakebackend pulse

* test.python.circuit.test_parameters

* PulseQobjInstruction  is used by GenericBackendV2

* test.python.scheduler.test_basic_scheduler

* test.python.result.test_result

* test.python.pulse.test_calibration_entries

* test.python.compiler.test_assembler

* test.python.transpiler.test_star_prerouting

* test.python.pulse.test_instruction_schedule_map

* test.python.providers.basic_provider.test_basic_simulator

* test.python.primitives.test_backend_sampler_v2

* test.python.compiler.test_disassembler

* test.python.compiler.test_compiler

* test.python.circuit.test_scheduled_circuit

* test.python.providers.test_fake_backends

* test.python.circuit.test_unitary

* test.python.transpiler.test_sabre_swap

* test.python.providers.fake_provider.test_fake_backends

* Aer using Provider ABC

* aer warnings

* reno

* another pass on reno

* test.python.pulse

* test.python.compiler.test_compiler

* add module to fiterwarning

* test.python.compiler.test_transpiler

* fixing obscure expcetion handleing for comparison

* test.python.transpiler.test_stochastic_swap test.python.transpiler.test_sabre_swap

* test.python.transpiler.test_echo_rzx_weyl_decomposition

* test.python.transpiler.test_instruction_durations

* test.python.providers.test_backendproperties

* test.python.qpy.test_circuit_load_from_qpy

* test.python.providers.test_pulse_defaults

* test.python.primitives.test_backend_sampler_v2

* test.python.primitives.test_backend_sampler

* test.python.compiler.test_scheduler

* test/python/compiler/test_scheduler.py

* test.python.compiler.test_disassembler

* test.python.compiler.test_assembler

* test.python.compiler.test_sequencer

* test.python.compiler.test_transpiler

* test.python.primitives.test_primitive

* better depreaction handleling from Aer

* test.python.primitives.test_backend_estimator_v2

* test.python.compiler.test_compiler

* ignore warnings, because the output is otherwise very verbose

* ignore to avoid fludding the CI log

* seeding all GenericBackendV2

* test.python.visualization.test_gate_map

* deprecation warnings: once

* default

* default

* Apply suggestions from code review

Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>

* remove catch

* new deprecate warning message

* lint qiskit/assembler/assemble_circuits.py

* concurrency warnings

* ignore aer warnings

* Update test/python/providers/fake_provider/test_fake_backends.py

Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>

* Update test/python/circuit/test_parameters.py

Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>

* Update qiskit/providers/models/pulsedefaults.py

Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>

* Update test/python/providers/fake_provider/test_fake_backends.py

Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>

* Update test/python/providers/fake_provider/test_generic_backend_v2.py

Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>

* lint

* #12649 (comment)

* #12649 (comment)

* Update test/python/transpiler/test_sabre_swap.py

Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>

* Update qiskit/providers/models/pulsedefaults.py

Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>

* ignore Treating CircuitInstruction...

* another unnecessary catch from aer

* another unnecessary catch from aer, again

* removing more unnecesary catches

* less lines

* seeding

* remove those comments

* test.python.compiler.test_transpiler.TestTranspile.test_scheduling_timing_constraints

* tokyo cmap

* test.python.circuit.test_scheduled_circuit.TestScheduledCircuit.test_schedule_circuit_when_backend_tells_dt

* comment in test_sequencer.py

* test.python.compiler.test_transpiler.TestPostTranspileIntegration.test_qasm3_output

* Update test/python/primitives/test_primitive.py

Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>

* test/python/providers/test_backendconfiguration.py:30

* test.python.primitives.test_backend_sampler

* restore the assertWarns, waiting for #12818

* use legacy_cmaps instead of explict coupling maps

* use more legacy_map

* KYOTO_CMAP

* more legacy_cmap

* #12832

---------

Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>
(cherry picked from commit 7cd2c41)

# Conflicts:
#	test/python/primitives/test_primitive.py
#	test/python/transpiler/test_sabre_layout.py

* Fix merge conflict

* Fix merge conflict

---------

Co-authored-by: Luciano Bello <bel@zurich.ibm.com>
Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>
  • Loading branch information
3 people authored Jul 29, 2024
1 parent bc45606 commit 04b4d20
Show file tree
Hide file tree
Showing 54 changed files with 1,212 additions and 313 deletions.
9 changes: 8 additions & 1 deletion qiskit/providers/fake_provider/fake_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from qiskit.providers import BackendV1
from qiskit import pulse
from qiskit.exceptions import QiskitError
from qiskit.utils import optionals as _optionals
from qiskit.utils import optionals as _optionals, deprecate_func
from qiskit.providers import basic_provider


Expand All @@ -39,6 +39,13 @@ def __init__(self, token="123456", url="https://"):
class FakeBackend(BackendV1):
"""This is a dummy backend just for testing purposes."""

@deprecate_func(
since="1.2",
removal_timeline="in the 2.0 release",
additional_msg="Fake backends using BackendV1 are deprecated in favor of "
":class:`.GenericBackendV2`. You can convert BackendV1 to "
":class:`.BackendV2` with :class:`.BackendV2Converter`.",
)
def __init__(self, configuration, time_alive=10):
"""FakeBackend initializer.
Expand Down
16 changes: 5 additions & 11 deletions qiskit/providers/fake_provider/generic_backend_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -567,18 +567,12 @@ def _setup_sim(self) -> None:

@classmethod
def _default_options(cls) -> Options:
with warnings.catch_warnings(): # TODO remove catch once aer release without Provider ABC
warnings.filterwarnings(
"ignore",
category=DeprecationWarning,
message=".+abstract Provider and ProviderV1.+",
)
if _optionals.HAS_AER:
from qiskit_aer import AerSimulator
if _optionals.HAS_AER:
from qiskit_aer import AerSimulator

return AerSimulator._default_options()
else:
return BasicSimulator._default_options()
return AerSimulator._default_options()
else:
return BasicSimulator._default_options()

def drive_channel(self, qubit: int):
drive_channels_map = getattr(self, "channels_map", {}).get("drive", {})
Expand Down
2 changes: 1 addition & 1 deletion qiskit/visualization/circuit/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ def _get_valid_justify_arg(justify):
warn(
f"Setting QuantumCircuit.draw()’s or circuit_drawer()'s justify argument: {justify}, to a "
"value other than 'left', 'right', 'none' or None (='left'). Default 'left' will be used. "
"Support for invalid justify arguments is deprecated as of qiskit 1.2.0. Starting no "
"Support for invalid justify arguments is deprecated as of Qiskit 1.2.0. Starting no "
"earlier than 3 months after the release date, invalid arguments will error.",
DeprecationWarning,
2,
Expand Down
33 changes: 31 additions & 2 deletions test/python/circuit/test_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@
from qiskit.compiler import assemble, transpile
from qiskit import pulse
from qiskit.quantum_info import Operator
from qiskit.providers.fake_provider import Fake5QV1
from qiskit.providers.fake_provider import Fake5QV1, GenericBackendV2
from qiskit.providers.basic_provider import BasicSimulator
from qiskit.utils import parallel_map
from test import QiskitTestCase, combine # pylint: disable=wrong-import-order
from ..legacy_cmaps import BOGOTA_CMAP


def raise_if_parameter_table_invalid(circuit):
Expand Down Expand Up @@ -1074,6 +1075,26 @@ def test_transpiling_multiple_parameterized_circuits(self):

self.assertTrue(len(job.result().results), 2)

@data(0, 1, 2, 3)
def test_transpile_across_optimization_levelsV1(self, opt_level):
"""Verify parameterized circuits can be transpiled with all default pass managers.
To remove once Fake5QV1 gets removed"""

qc = QuantumCircuit(5, 5)

theta = Parameter("theta")
phi = Parameter("phi")

qc.rx(theta, 0)
qc.x(0)
for i in range(5 - 1):
qc.rxx(phi, i, i + 1)

qc.measure(range(5 - 1), range(5 - 1))
with self.assertWarns(DeprecationWarning):
backend = Fake5QV1()
transpile(qc, backend, optimization_level=opt_level)

@data(0, 1, 2, 3)
def test_transpile_across_optimization_levels(self, opt_level):
"""Verify parameterized circuits can be transpiled with all default pass managers."""
Expand All @@ -1090,7 +1111,15 @@ def test_transpile_across_optimization_levels(self, opt_level):

qc.measure(range(5 - 1), range(5 - 1))

transpile(qc, Fake5QV1(), optimization_level=opt_level)
transpile(
qc,
GenericBackendV2(
num_qubits=5,
coupling_map=BOGOTA_CMAP,
seed=42,
),
optimization_level=opt_level,
)

def test_repeated_gates_to_dag_and_back(self):
"""Verify circuits with repeated parameterized gates can be converted
Expand Down
24 changes: 14 additions & 10 deletions test/python/circuit/test_scheduled_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ class TestScheduledCircuit(QiskitTestCase):

def setUp(self):
super().setUp()
self.backend_with_dt = Fake27QPulseV1()
self.backend_without_dt = Fake27QPulseV1()
with self.assertWarns(DeprecationWarning):
self.backend_with_dt = Fake27QPulseV1()
self.backend_without_dt = Fake27QPulseV1()
delattr(self.backend_without_dt.configuration(), "dt")
# Remove timing constraints from the backends (alignment values,
# granularity and min_length), so that these values will default
Expand All @@ -50,21 +51,24 @@ def setUp(self):
def test_schedule_circuit_when_backend_tells_dt(self):
"""dt is known to transpiler by backend"""
qc = QuantumCircuit(2)
qc.delay(0.1, 0, unit="ms") # 450000[dt]
qc.delay(0.1, 0, unit="ms") # 450450[dt]
qc.delay(100, 0, unit="ns") # 450[dt]
qc.h(0) # 160[dt]
qc.h(1) # 160[dt]
sc = transpile(qc, self.backend_with_dt, scheduling_method="alap", layout_method="trivial")
self.assertEqual(sc.duration, 450546)
qc.h(0) # 195[dt]
qc.h(1) # 210[dt]

backend = GenericBackendV2(2, calibrate_instructions=True, seed=42)

sc = transpile(qc, backend, scheduling_method="alap", layout_method="trivial")
self.assertEqual(sc.duration, 451095)
self.assertEqual(sc.unit, "dt")
self.assertEqual(sc.data[0].operation.name, "delay")
self.assertEqual(sc.data[0].operation.duration, 450450)
self.assertEqual(sc.data[0].operation.duration, 450900)
self.assertEqual(sc.data[0].operation.unit, "dt")
self.assertEqual(sc.data[1].operation.name, "rz")
self.assertEqual(sc.data[1].operation.duration, 0)
self.assertEqual(sc.data[1].operation.unit, "dt")
self.assertEqual(sc.data[4].operation.name, "delay")
self.assertEqual(sc.data[4].operation.duration, 450450)
self.assertEqual(sc.data[4].operation.duration, 450885)
self.assertEqual(sc.data[4].operation.unit, "dt")

def test_schedule_circuit_when_transpile_option_tells_dt(self):
Expand Down Expand Up @@ -301,7 +305,7 @@ def test_convert_duration_to_dt(self):
"""Test that circuit duration unit conversion is applied only when necessary.
Tests fix for bug reported in PR #11782."""

backend = GenericBackendV2(num_qubits=3, calibrate_instructions=True, seed=10)
backend = GenericBackendV2(num_qubits=3, calibrate_instructions=True, seed=42)
schedule_config = ScheduleConfig(
inst_map=backend.target.instruction_schedule_map(),
meas_map=backend.meas_map,
Expand Down
33 changes: 22 additions & 11 deletions test/python/compiler/test_assembler.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ def setUp(self):
self.circ.cx(qr[0], qr[1])
self.circ.measure(qr, cr)

self.backend = Fake5QV1()
with self.assertWarns(DeprecationWarning):
self.backend = Fake5QV1()
self.backend_config = self.backend.configuration()
self.num_qubits = self.backend_config.n_qubits

Expand Down Expand Up @@ -591,7 +592,8 @@ def test_pulse_gates_with_parameteric_pulses(self):
circ.h(0)
circ.add_calibration("h", [0], custom_h_schedule)

backend = FakeOpenPulse2Q()
with self.assertWarns(DeprecationWarning):
backend = FakeOpenPulse2Q()
backend.configuration().parametric_pulses = ["drag"]
with self.assertWarns(DeprecationWarning):
qobj = assemble(circ, backend)
Expand Down Expand Up @@ -974,7 +976,8 @@ class TestPulseAssembler(QiskitTestCase):

def setUp(self):
super().setUp()
self.backend = FakeOpenPulse2Q()
with self.assertWarns(DeprecationWarning):
self.backend = FakeOpenPulse2Q()
self.backend_config = self.backend.configuration()

test_pulse = pulse.Waveform(
Expand Down Expand Up @@ -1282,7 +1285,8 @@ def test_pulse_name_conflicts(self):

def test_pulse_name_conflicts_in_other_schedule(self):
"""Test two pulses with the same name in different schedule can be resolved."""
backend = Fake27QPulseV1()
with self.assertWarns(DeprecationWarning):
backend = Fake27QPulseV1()
defaults = backend.defaults()

schedules = []
Expand Down Expand Up @@ -1390,7 +1394,8 @@ def test_assemble_parametric(self):
)
<< sched.duration
)
backend = FakeOpenPulse3Q()
with self.assertWarns(DeprecationWarning):
backend = FakeOpenPulse3Q()
backend.configuration().parametric_pulses = [
"gaussian",
"drag",
Expand Down Expand Up @@ -1437,7 +1442,8 @@ def test_assemble_parametric_unsupported(self):
)
sched += Play(pulse.Constant(duration=25, amp=1), DriveChannel(2))

backend = FakeOpenPulse3Q()
with self.assertWarns(DeprecationWarning):
backend = FakeOpenPulse3Q()
backend.configuration().parametric_pulses = ["something_extra"]

with self.assertWarns(DeprecationWarning):
Expand All @@ -1449,7 +1455,8 @@ def test_assemble_parametric_unsupported(self):

def test_assemble_parametric_pulse_kwarg_with_backend_setting(self):
"""Test that parametric pulses respect the kwarg over backend"""
backend = Fake27QPulseV1()
with self.assertWarns(DeprecationWarning):
backend = Fake27QPulseV1()

qc = QuantumCircuit(1, 1)
qc.x(0)
Expand All @@ -1465,7 +1472,8 @@ def test_assemble_parametric_pulse_kwarg_with_backend_setting(self):

def test_assemble_parametric_pulse_kwarg_empty_list_with_backend_setting(self):
"""Test that parametric pulses respect the kwarg as empty list over backend"""
backend = Fake27QPulseV1()
with self.assertWarns(DeprecationWarning):
backend = Fake27QPulseV1()

qc = QuantumCircuit(1, 1)
qc.x(0)
Expand Down Expand Up @@ -1822,7 +1830,8 @@ def setUp(self):
super().setUp()
self.schedule = pulse.Schedule(name="fake_experiment")

self.backend = FakeOpenPulse2Q()
with self.assertWarns(DeprecationWarning):
self.backend = FakeOpenPulse2Q()
self.config = self.backend.configuration()
self.defaults = self.backend.defaults()
self.qubit_lo_freq = list(self.defaults.qubit_freq_est)
Expand Down Expand Up @@ -1963,7 +1972,8 @@ def test_missing_lo_ranges(self):

def test_unsupported_meas_level(self):
"""Test that assembly raises an error if meas_level is not supported"""
backend = FakeOpenPulse2Q()
with self.assertWarns(DeprecationWarning):
backend = FakeOpenPulse2Q()
backend.configuration().meas_levels = [1, 2]
with self.assertRaises(QiskitError), self.assertWarns(DeprecationWarning):
assemble(
Expand All @@ -1983,7 +1993,8 @@ def test_unsupported_meas_level(self):

def test_single_and_deprecated_acquire_styles(self):
"""Test that acquires are identically combined with Acquires that take a single channel."""
backend = FakeOpenPulse2Q()
with self.assertWarns(DeprecationWarning):
backend = FakeOpenPulse2Q()
new_style_schedule = Schedule()
acq_dur = 1200
for i in range(2):
Expand Down
5 changes: 3 additions & 2 deletions test/python/compiler/test_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ def test_example_swap_bits(self):

def test_parallel_compile(self):
"""Trigger parallel routines in compile."""
backend = Fake20QV1()
qr = QuantumRegister(16)
cr = ClassicalRegister(2)
qc = QuantumCircuit(qr, cr)
Expand All @@ -198,6 +197,7 @@ def test_parallel_compile(self):
qc.measure(qr[5], cr[0])
qlist = [qc for k in range(10)]
with self.assertWarns(DeprecationWarning):
backend = Fake20QV1()
qobj = assemble(transpile(qlist, backend=backend))
self.assertEqual(len(qobj.experiments), 10)

Expand Down Expand Up @@ -500,7 +500,8 @@ def test_yzy_zyz_cases(self):
See: https://github.com/Qiskit/qiskit-terra/issues/607
"""
backend = Fake5QV1()
with self.assertWarns(DeprecationWarning):
backend = Fake5QV1()
qr = QuantumRegister(2)
circ1 = QuantumCircuit(qr)
circ1.cx(qr[0], qr[1])
Expand Down
3 changes: 2 additions & 1 deletion test/python/compiler/test_disassembler.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,8 @@ class TestPulseScheduleDisassembler(QiskitTestCase):

def setUp(self):
super().setUp()
self.backend = FakeOpenPulse2Q()
with self.assertWarns(DeprecationWarning):
self.backend = FakeOpenPulse2Q()
self.backend_config = self.backend.configuration()
self.backend_config.parametric_pulses = ["constant", "gaussian", "gaussian_square", "drag"]

Expand Down
10 changes: 6 additions & 4 deletions test/python/compiler/test_scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from qiskit.circuit import QuantumRegister, ClassicalRegister, QuantumCircuit
from qiskit.exceptions import QiskitError
from qiskit.pulse import InstructionScheduleMap, Schedule
from qiskit.providers.fake_provider import FakeOpenPulse3Q
from qiskit.providers.fake_provider import FakeOpenPulse3Q, GenericBackendV2
from qiskit.compiler.scheduler import schedule
from test import QiskitTestCase # pylint: disable=wrong-import-order

Expand All @@ -37,9 +37,9 @@ def setUp(self):
self.circ2.cx(qr2[0], qr2[1])
self.circ2.measure(qr2, cr2)

self.backend = FakeOpenPulse3Q()
self.backend_config = self.backend.configuration()
self.num_qubits = self.backend_config.n_qubits
self.backend = GenericBackendV2(
3, calibrate_instructions=True, basis_gates=["cx", "u1", "u2", "u3"], seed=42
)

def test_instruction_map_and_backend_not_supplied(self):
"""Test instruction map and backend not supplied."""
Expand All @@ -51,6 +51,8 @@ def test_instruction_map_and_backend_not_supplied(self):

def test_instruction_map_and_backend_defaults_unavailable(self):
"""Test backend defaults unavailable when backend is provided, but instruction map is not."""
with self.assertWarns(DeprecationWarning):
self.backend = FakeOpenPulse3Q()
self.backend._defaults = None
with self.assertRaisesRegex(
QiskitError, r"The backend defaults are unavailable. The backend may not support pulse."
Expand Down
5 changes: 4 additions & 1 deletion test/python/compiler/test_sequencer.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
# pylint: disable=missing-function-docstring

"""Tests basic functionality of the sequence function"""
# TODO with the removal of pulses, this file can be removed too.

import unittest

from qiskit import QuantumCircuit, pulse
Expand All @@ -27,7 +29,8 @@ class TestSequence(QiskitTestCase):

def setUp(self):
super().setUp()
self.backend = Fake127QPulseV1()
with self.assertWarns(DeprecationWarning):
self.backend = Fake127QPulseV1()
self.backend.configuration().timing_constraints = {}

def test_sequence_empty(self):
Expand Down
Loading

0 comments on commit 04b4d20

Please sign in to comment.