Skip to content
This repository was archived by the owner on Jul 28, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 92 additions & 1 deletion qiskit/providers/ibmq/ibmqbackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
from datetime import datetime as python_datetime

from qiskit.compiler import assemble
from qiskit.circuit import QuantumCircuit, Parameter
from qiskit.circuit import QuantumCircuit, Parameter, Delay
from qiskit.circuit.duration import duration_in_dt
from qiskit.pulse import Schedule, LoConfig
from qiskit.pulse.channels import PulseChannel
from qiskit.qobj import QasmQobj, PulseQobj, validate_qobj_against_schema
Expand Down Expand Up @@ -102,6 +103,7 @@ class IBMQBackend(Backend):
"""

qobj_warning_issued = False
id_warning_issued = False

def __init__(
self,
Expand Down Expand Up @@ -286,6 +288,9 @@ def run(
"'use_measure_esp' is unset or set to 'False'."
)

if not self.configuration().simulator:
self._deprecate_id_instruction(circuits)

if isinstance(circuits, (QasmQobj, PulseQobj)):
if not self.qobj_warning_issued:
warnings.warn("Passing a Qobj to Backend.run is deprecated and will "
Expand Down Expand Up @@ -746,6 +751,92 @@ def __repr__(self) -> str:
return "<{}('{}') from IBMQ({})>".format(
self.__class__.__name__, self.name(), credentials_info)

def _deprecate_id_instruction(
self,
circuits: Union[QasmQobj, PulseQobj, QuantumCircuit, Schedule,
List[Union[QuantumCircuit, Schedule]]]
) -> None:
"""Raise a DeprecationWarning if any circuit contains an 'id' instruction.

Additionally, if 'delay' is a 'supported_instruction', replace each 'id'
instruction (in-place) with the equivalent ('sx'-length) 'delay' instruction.

Args:
circuits: The individual or list of :class:`~qiskit.circuits.QuantumCircuit` or
:class:`~qiskit.pulse.Schedule` objects passed to
:meth:`IBMQBackend.run()<IBMQBackend.run>`. Modified in-place.

Returns:
None
"""

if isinstance(circuits, PulseQobj):
return

id_support = 'id' in getattr(self.configuration(), 'basis_gates', [])
delay_support = 'delay' in getattr(self.configuration(), 'supported_instructions', [])

if not delay_support:
return

if isinstance(circuits, QasmQobj):
circuit_has_id = any(instr.name == 'id'
for experiment in circuits.experiments
for instr in experiment.instructions)
else:
if not isinstance(circuits, List):
circuits = [circuits]

circuit_has_id = any(instr.name == 'id'
for circuit in circuits
if isinstance(circuit, QuantumCircuit)
for instr, qargs, cargs in circuit.data)

if not circuit_has_id:
return

if not self.id_warning_issued:
if id_support and delay_support:
warnings.warn("Support for the 'id' instruction has been deprecated "
"from IBM hardware backends. Any 'id' instructions "
"will be replaced with their equivalent 'delay' instruction. "
"Please use the 'delay' instruction instead.", DeprecationWarning,
stacklevel=4)
else:
warnings.warn("Support for the 'id' instruction has been removed "
"from IBM hardware backends. Any 'id' instructions "
"will be replaced with their equivalent 'delay' instruction. "
"Please use the 'delay' instruction instead.", DeprecationWarning,
stacklevel=4)

self.id_warning_issued = True

dt_in_s = self.configuration().dt

if isinstance(circuits, QasmQobj):
for experiment in circuits.experiments:
for instr in experiment.instructions:
if instr.name == 'id':
sx_duration = self.properties().gate_length('sx', instr.qubits[0])
sx_duration_in_dt = duration_in_dt(sx_duration, dt_in_s)

instr.name = 'delay'
instr.params = [sx_duration_in_dt]
else:
for circuit in circuits:
if isinstance(circuit, Schedule):
continue

for idx, (instr, qargs, cargs) in enumerate(circuit.data):
if instr.name == 'id':

sx_duration = self.properties().gate_length('sx', qargs[0].index)
sx_duration_in_dt = duration_in_dt(sx_duration, dt_in_s)

delay_instr = Delay(sx_duration_in_dt)

circuit.data[idx] = (delay_instr, qargs, cargs)


class IBMQSimulator(IBMQBackend):
"""Backend class interfacing with an IBM Quantum Experience simulator."""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
deprecations:
- |
The `id` instruction has been deprecated on IBM hardware
backends. Instead, please use the `delay` instruction which
implements variable-length delays, specified in units of
`dt`. When running a circuit containing an `id` instruction,
a warning will be raised on job submission and any `id`
instructions in the job will be automatically replaced with their
equivalent `delay` instruction.

35 changes: 34 additions & 1 deletion test/ibmq/test_ibmq_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
from datetime import timedelta, datetime
import warnings
from unittest import SkipTest
from unittest.mock import patch

from qiskit import transpile, assemble
from qiskit import QuantumCircuit, transpile, assemble
from qiskit.providers.models import QasmBackendConfiguration
from qiskit.test.reference_circuits import ReferenceCircuits
from qiskit.providers.ibmq.ibmqbackend import IBMQBackend
from qiskit.providers.ibmq.ibmqbackendservice import IBMQBackendService
Expand Down Expand Up @@ -176,6 +178,37 @@ def test_sim_backend_options(self):
self.assertTrue(qobj.config.memory)
self.assertEqual(qobj.config.foo, 'foo')

def test_deprecate_id_instruction(self):
"""Test replacement of 'id' Instructions with 'Delay' instructions."""

circuit_with_id = QuantumCircuit(2)
circuit_with_id.id(0)
circuit_with_id.id(0)
circuit_with_id.id(1)

config = QasmBackendConfiguration(
basis_gates=['id'],
supported_instructions=['delay'],
dt=0.25,
backend_name='test',
backend_version=0.0,
n_qubits=1,
gates=[],
local=False,
simulator=False,
conditional=False,
open_pulse=False,
memory=False,
max_shots=1,
coupling_map=None,
)

with patch.object(self.backend, 'configuration', return_value=config):
with self.assertWarnsRegex(DeprecationWarning, r"'id' instruction"):
self.backend._deprecate_id_instruction(circuit_with_id)

self.assertEqual(circuit_with_id.count_ops(), {'delay': 3})


class TestIBMQBackendService(IBMQTestCase):
"""Test ibmqbackendservice module."""
Expand Down