Skip to content

Commit

Permalink
Barebone generic backend options (Qiskit#12747)
Browse files Browse the repository at this point in the history
* Update generic_backend_v2.py

* reno

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

* ...

* suggestions from code review

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

* tests, typo
  • Loading branch information
sbrandhsn authored and Procatv committed Aug 1, 2024
1 parent c6f720c commit c0d34a9
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 19 deletions.
63 changes: 44 additions & 19 deletions qiskit/providers/fake_provider/generic_backend_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ def __init__(
calibrate_instructions: bool | InstructionScheduleMap | None = None,
dtm: float | None = None,
seed: int | None = None,
pulse_channels: bool = True,
noise_info: bool = True,
):
"""
Args:
Expand Down Expand Up @@ -159,6 +161,10 @@ def __init__(
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__(
Expand All @@ -175,6 +181,10 @@ def __init__(
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)
Expand All @@ -198,7 +208,10 @@ def __init__(
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):
Expand Down Expand Up @@ -340,22 +353,31 @@ def _build_generic_target(self):
"""
# 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
Expand All @@ -380,8 +402,11 @@ def _build_generic_target(self):
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")
Expand Down
Original file line number Diff line number Diff line change
@@ -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`.
20 changes: 20 additions & 0 deletions test/python/providers/fake_provider/test_generic_backend_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,26 @@ def test_ccx_2Q(self):
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."""
Expand Down

0 comments on commit c0d34a9

Please sign in to comment.