Barebone generic backend options (#12747)

* Update generic_backend_v2.py

* reno

* Update barebone-backend-option-675c86df4382a443.yaml

* ...

* suggestions from code review

* Update barebone-backend-option-675c86df4382a443.yaml

* tests, typo
This commit is contained in:
Sebastian Brandhofer 2024-07-11 15:40:01 +02:00 committed by GitHub
parent 99ae318d89
commit a306cb67c8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 72 additions and 19 deletions

View File

@ -112,6 +112,8 @@ class GenericBackendV2(BackendV2):
calibrate_instructions: bool | InstructionScheduleMap | None = None,
dtm: float | None = None,
seed: int | None = None,
pulse_channels: bool = True,
noise_info: bool = True,
):
"""
Args:
@ -159,6 +161,10 @@ class GenericBackendV2(BackendV2):
None by default.
seed: Optional seed for generation of default values.
pulse_channels: If true, sets default pulse channel information on the backend.
noise_info: If true, associates gates and qubits with default noise information.
"""
super().__init__(
@ -175,6 +181,10 @@ class GenericBackendV2(BackendV2):
self._control_flow = control_flow
self._calibrate_instructions = calibrate_instructions
self._supported_gates = get_standard_gate_name_mapping()
self._noise_info = noise_info
if calibrate_instructions and not noise_info:
raise QiskitError("Must set parameter noise_info when calibrating instructions.")
if coupling_map is None:
self._coupling_map = CouplingMap().from_full(num_qubits)
@ -198,7 +208,10 @@ class GenericBackendV2(BackendV2):
self._basis_gates.append(name)
self._build_generic_target()
self._build_default_channels()
if pulse_channels:
self._build_default_channels()
else:
self.channels_map = {}
@property
def target(self):
@ -340,22 +353,31 @@ class GenericBackendV2(BackendV2):
"""
# the qubit properties are sampled from default ranges
properties = _QUBIT_PROPERTIES
self._target = Target(
description=f"Generic Target with {self._num_qubits} qubits",
num_qubits=self._num_qubits,
dt=properties["dt"],
qubit_properties=[
QubitProperties(
t1=self._rng.uniform(properties["t1"][0], properties["t1"][1]),
t2=self._rng.uniform(properties["t2"][0], properties["t2"][1]),
frequency=self._rng.uniform(
properties["frequency"][0], properties["frequency"][1]
),
)
for _ in range(self._num_qubits)
],
concurrent_measurements=[list(range(self._num_qubits))],
)
if not self._noise_info:
self._target = Target(
description=f"Generic Target with {self._num_qubits} qubits",
num_qubits=self._num_qubits,
dt=properties["dt"],
qubit_properties=None,
concurrent_measurements=[list(range(self._num_qubits))],
)
else:
self._target = Target(
description=f"Generic Target with {self._num_qubits} qubits",
num_qubits=self._num_qubits,
dt=properties["dt"],
qubit_properties=[
QubitProperties(
t1=self._rng.uniform(properties["t1"][0], properties["t1"][1]),
t2=self._rng.uniform(properties["t2"][0], properties["t2"][1]),
frequency=self._rng.uniform(
properties["frequency"][0], properties["frequency"][1]
),
)
for _ in range(self._num_qubits)
],
concurrent_measurements=[list(range(self._num_qubits))],
)
# Generate instruction schedule map with calibrations to add to target.
calibration_inst_map = None
@ -380,8 +402,11 @@ class GenericBackendV2(BackendV2):
f"Provided basis gate {name} needs more qubits than {self.num_qubits}, "
f"which is the size of the backend."
)
noise_params = self._get_noise_defaults(name, gate.num_qubits)
self._add_noisy_instruction_to_target(gate, noise_params, calibration_inst_map)
if self._noise_info:
noise_params = self._get_noise_defaults(name, gate.num_qubits)
self._add_noisy_instruction_to_target(gate, noise_params, calibration_inst_map)
else:
self._target.add_instruction(gate, properties=None, name=name)
if self._control_flow:
self._target.add_instruction(IfElseOp, name="if_else")

View File

@ -0,0 +1,8 @@
---
features:
- |
Added two parameters to :class:`.GenericBackendV2` to exclude error (`noise_info`) and
pulse channel information (`pulse_channels`) from the construction of the backend. These parameters
are true by default, replicating the initial default behavior of the constructor. A memory-sensitive
user may set these options to `False` to reduce the memory overhead by 40x when transpiling on large-
scale :class:`.GenericBackendV2`.

View File

@ -45,6 +45,26 @@ class TestGenericBackendV2(QiskitTestCase):
with self.assertRaises(QiskitError):
GenericBackendV2(num_qubits=2, basis_gates=["ccx", "id"])
def test_calibration_no_noise_info(self):
"""Test failing with a backend with calibration and no noise info"""
with self.assertRaises(QiskitError):
GenericBackendV2(
num_qubits=2,
basis_gates=["ccx", "id"],
calibrate_instructions=True,
noise_info=False,
)
def test_no_noise(self):
"""Test no noise info when parameter is false"""
backend = GenericBackendV2(num_qubits=2, noise_info=False)
self.assertEqual(backend.target.qubit_properties, None)
def test_no_pulse_channels(self):
"""Test no/empty pulse channels when parameter is false"""
backend = GenericBackendV2(num_qubits=2, pulse_channels=False)
self.assertTrue(len(backend.channels_map) == 0)
def test_operation_names(self):
"""Test that target basis gates include "delay", "measure" and "reset" even
if not provided by user."""