Skip to content

Commit

Permalink
Add ESP readout support to Qiskit (#6543)
Browse files Browse the repository at this point in the history
* Add tests for esp support

* Add reno note

* Fix comments and run black

* Update docs

* Remove explicit use_measure_esp from execute
  • Loading branch information
zachschoenfeld33 authored Jun 14, 2021
1 parent 5ec4278 commit 6d605a0
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 4 deletions.
21 changes: 20 additions & 1 deletion qiskit/compiler/assembler.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ def assemble(
parameter_binds: Optional[List[Dict[Parameter, float]]] = None,
parametric_pulses: Optional[List[str]] = None,
init_qubits: bool = True,
use_measure_esp: Optional[bool] = None,
**run_config: Dict,
) -> Qobj:
"""Assemble a list of circuits or pulse schedules into a ``Qobj``.
Expand Down Expand Up @@ -140,7 +141,12 @@ def assemble(
['gaussian', 'constant']
init_qubits: Whether to reset the qubits to the ground state for each shot.
Default: ``True``.
Default: ``True``.
use_measure_esp: Whether to use excited state promoted (ESP) readout for the final
measurement in each circuit. ESP readout discriminates between the ``|0>`` and higher
transmon states to improve readout fidelity. See
`here <https://arxiv.org/pdf/2008.08571.pdf>`_.
Default: ``True`` if the backend supports ESP readout, else ``False``.
**run_config: Extra arguments used to configure the run (e.g., for Aer configurable
backends). Refer to the backend documentation for details on these
arguments.
Expand All @@ -163,6 +169,7 @@ def assemble(
max_credits,
seed_simulator,
init_qubits,
use_measure_esp,
rep_delay,
qubit_lo_freq,
meas_lo_freq,
Expand Down Expand Up @@ -230,6 +237,7 @@ def _parse_common_args(
max_credits,
seed_simulator,
init_qubits,
use_measure_esp,
rep_delay,
qubit_lo_freq,
meas_lo_freq,
Expand Down Expand Up @@ -258,6 +266,8 @@ def _parse_common_args(
- If any of qubit or meas lo's, or associated ranges do not have length equal to
``n_qubits``.
- If qubit or meas lo's do not fit into perscribed ranges.
- If ``use_measure_esp`` is set to ``True`` on a device which does not support ESP
readout.
"""
# grab relevant info from backend if it exists
backend_config = None
Expand Down Expand Up @@ -343,13 +353,22 @@ def _parse_common_args(
for lo_config in schedule_los
]

measure_esp_enabled = getattr(backend_config, "measure_esp_enabled", False)
use_measure_esp = use_measure_esp or measure_esp_enabled # default to backend support value
if use_measure_esp and not measure_esp_enabled:
raise QiskitError(
"ESP readout not supported on this device. Please make sure the flag "
"'use_measure_esp' is unset or set to 'False'."
)

# create run configuration and populate
run_config_dict = dict(
shots=shots,
memory=memory,
max_credits=max_credits,
seed_simulator=seed_simulator,
init_qubits=init_qubits,
use_measure_esp=use_measure_esp,
rep_delay=rep_delay,
qubit_lo_freq=qubit_lo_freq,
meas_lo_freq=meas_lo_freq,
Expand Down
2 changes: 1 addition & 1 deletion qiskit/execute_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ def execute(
Optionally specify a particular scheduling method.
init_qubits (bool): Whether to reset the qubits to the ground state for each shot.
Default: ``True``.
Default: ``True``.
run_config (dict):
Extra arguments used to configure the run (e.g. for Aer configurable backends).
Expand Down
9 changes: 8 additions & 1 deletion qiskit/providers/models/backendconfiguration.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ def __init__(
dtm=None,
processor_type=None,
parametric_pulses=None,
measure_esp_enabled=False,
**kwargs,
):
"""Initialize a QasmBackendConfiguration Object
Expand Down Expand Up @@ -300,7 +301,10 @@ def __init__(
- segment: Segment this processor belongs to within a larger chip.
parametric_pulses (list): A list of pulse shapes which are supported on the backend.
For example: ``['gaussian', 'constant']``
measure_esp_enabled (bool): Whether excited state promoted (ESP) readout is enabled on
this device. ESP readout discriminates between the ``|0>`` and higher transmon
states to improve readout fidelity. See
`here <https://arxiv.org/pdf/2008.08571.pdf>`_. Defaults to ``False``.
**kwargs: optional fields
"""
self._data = {}
Expand Down Expand Up @@ -360,6 +364,8 @@ def __init__(
if parametric_pulses is not None:
self.parametric_pulses = parametric_pulses

self.measure_esp_enabled = measure_esp_enabled

# convert lo range from GHz to Hz
if "qubit_lo_range" in kwargs.keys():
kwargs["qubit_lo_range"] = [
Expand Down Expand Up @@ -421,6 +427,7 @@ def to_dict(self):
"max_shots": self.max_shots,
"coupling_map": self.coupling_map,
"dynamic_reprate_enabled": self.dynamic_reprate_enabled,
"measure_esp_enabled": self.measure_esp_enabled,
}

if hasattr(self, "supported_instructions"):
Expand Down
7 changes: 6 additions & 1 deletion qiskit/schemas/backend_configuration_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "http://www.qiskit.org/schemas/backend_config_schema.json",
"description": "Qiskit device backend configuration",
"version": "1.4.3",
"version": "1.4.4",
"definitions": {
"hamiltonian": {
"type": "object",
Expand Down Expand Up @@ -157,6 +157,11 @@
"description": "Whether delay between programs can be set dynamically using 'rep_delay').",
"default": false
},
"measure_esp_enabled": {
"type": "boolean",
"description": "Whether ESP readout is supported by the backend.",
"default": false
},
"supported_instructions": {
"type": "array",
"minItems": 0,
Expand Down
23 changes: 23 additions & 0 deletions releasenotes/notes/esp-readout-3aa5fff772ddbab1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
features:
- |
Support for Excited State Promoted (ESP) readout from Qiskit has been added. ESP readout
discriminates between ``|0>`` and higher order energy states of transmon qubits in order to
improve readout fidelity. Further details may be found
`here <https://arxiv.org/pdf/2008.08571.pdf>`_.
To check whether the backend supports ESP readout, one can query::
measure_esp_enabled = getattr(backend.configuration(), "measure_esp_enabled", False)
If the flag ``measure_esp_enabled`` is not in the backend configuration, we return ``False``
by default.
A user can request usage of ESP readout via the ``use_measure_esp`` flag in
:meth:`~qiskit.compiler.assemble`. This tells the backend to use ESP readout on the final
measurement of each circuit. This is done via::
qobj = assemble(circ, backend, use_measure_esp=True)
If ``measure_esp_enabled=False`` and ``use_measure_esp=True``, a ``QiskitError`` is raised. If
``use_measure_esp`` is not set, it will default to the value of ``measure_esp_enabled``.
27 changes: 27 additions & 0 deletions test/python/compiler/test_assembler.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,33 @@ def test_init_qubits_false(self):
qobj = assemble(self.circ, init_qubits=False)
self.assertEqual(qobj.config.init_qubits, False)

def test_measure_esp_not_enabled(self):
"""Check that an error is raised if ``use_measure_esp=True`` on a device which does not
support ESP readout."""
setattr(self.backend_config, "measure_esp_enabled", False)
with self.assertRaises(QiskitError):
assemble(self.circ, self.backend, use_measure_esp=True)

def test_measure_esp_defaults(self):
"""Check that ``use_measure_esp`` defaults to True if ESP readout is enabled on the device
and false otherwise."""
# esp readout enabled
setattr(self.backend_config, "measure_esp_enabled", True)
qobj = assemble(self.circ, self.backend)
self.assertEqual(qobj.config.use_measure_esp, True)

# esp readout not enabled
setattr(self.backend_config, "measure_esp_enabled", False)
qobj = assemble(self.circ, self.backend)
self.assertEqual(qobj.config.use_measure_esp, False)

def test_measure_esp(self):
"""Test that ``use_measure_esp=True`` works on a device that supports ESP readout."""
# esp readout enabled
setattr(self.backend_config, "measure_esp_enabled", True)
qobj = assemble(self.circ, self.backend, use_measure_esp=True)
self.assertEqual(qobj.config.use_measure_esp, True)

def test_circuit_with_global_phase(self):
"""Test that global phase for a circuit is handled correctly."""
circ = QuantumCircuit(2)
Expand Down

0 comments on commit 6d605a0

Please sign in to comment.