Skip to content
This repository was archived by the owner on Jul 28, 2023. It is now read-only.

Deprecate 'id' instructions on IBM Quantum hardware backends.#976

Merged
jyu00 merged 5 commits into
Qiskit:masterfrom
kdk:deprecate-hardware-id-instructions
Jul 7, 2021
Merged

Deprecate 'id' instructions on IBM Quantum hardware backends.#976
jyu00 merged 5 commits into
Qiskit:masterfrom
kdk:deprecate-hardware-id-instructions

Conversation

@kdk
Copy link
Copy Markdown
Member

@kdk kdk commented Jun 22, 2021

Summary

Updates IBMBackend.run to inspect submitted circuits for instructions containing 'id'.

  • If 'id' is still reported in the device's basis_gates, only a DeprecationWarning is raised.
  • If neither 'id' nor 'delay' are reported as supported by the device, a DeprecationWarning is raised.
  • If 'id' is no longer reported in the device's basis_gates and 'delay' is reported in the device's supported_instruction, a DeprecationWarning is raised and any 'id' instructions are replaced with their equivalent ('sx'-length) 'delay' instructions.

Details and comments

As an example, run a 'id'-based T1 experiment on ibmq_16_melbourne (the only device active device different length 'sx' gates on different qubits) from main and PR branch (forcing 'id'->'delay' conversion):

>>> id_qcs = []
>>> for n in range(200):
...    qc = qk.QuantumCircuit(7,4)
...    qc.x([0,1,5,6])
...    for _ in range(n):
...        for __ in range(20):
...            qc.id([0,1,5,6])
...    qc.measure([0,1,5,6],[0,1,2,3])
...    id_qcs.append(qc)
...
>>> melbourne = provider.get_backend('ibmq_16_melbourne')
>>> id_tqcs = qk.transpile(id_qcs, melbourne, optimization_level=0)
>>> id_qobj = qk.assemble(id_tqcs)
>>>
>>>job_qobj = melbourne.run(id_qobj)
>>>job_circ = melbourne.run(id_tqcs)

image

For reference, compare PR and main branch performance of backend.run(...) for id_qobj, id_tqcs (up to 15,920 'id' gates) and x_qobj, x_tqcs (as above, but replace all 'id' gates with 'x' gates to isolate worst-case performance of 'scan-for-'id'). N.B. These are single-shot runtime readings.

Runtime comparison of backend.run(...):

Main backend.run(qc) PR Branch backend.run(qc) Main backend.run(Qobj) PR backend.run(Qobj)
'id' 3m55s 3m57s 2m23s 2m33s
'x' 4m15s 3m59s 2m16 2m45s

Isolate overhead of backend._deprecate_id_instructions(...):

Function call Runtime
backend._deprecate_id_instructions(id_tqcs) 2.09s
backend._deprecate_id_instructions(x_tqcs) 1.64s
backend._deprecate_id_instructions(id_qobj) 812ms
backend._deprecate_id_instructions(x_qobj) 440ms

@nonhermitian
Copy link
Copy Markdown
Contributor

I am curious as to why we need this here? Shouldn't the transpiler know to convert an id into a delay? I see that it currently does not, e.g.

qc = QuantumCircuit(1)
qc.id(0)
transpile(qc, basis_gates=['reset'])

fails

QiskitError: "Cannot unroll the circuit to the given basis, ['reset']. Instruction id not found in equivalence library and no rule found to expand."

If it did then there probably wouldn't need to be these gymnastics right?

@kdk kdk linked an issue Jun 22, 2021 that may be closed by this pull request
@kdk
Copy link
Copy Markdown
Member Author

kdk commented Jun 22, 2021

Agree that the transpiler is a better place for these kinds of transformations in general. However, the behavior that's being deprecated here ('id' as an implicit 'delay') is specific to IBM Quantum hardware backends (there are providers with backends which implement 'id' as a no-op which we wouldn't want to affect).

We've floated the idea in the past of providers being able to supply transpiler passes to the transpiler to handle backend or provider specific transformations or optimizations. Having this done currently by the provider was chosen because it was more inline with the ownership of those designs than the alternative (a transpiler pass which gates on backend.name().startswith('ibmq')).

@nonhermitian
Copy link
Copy Markdown
Contributor

nonhermitian commented Jun 22, 2021

Yeah but isn't unrolling always a backend specific task? Here you just need a rule to map a id to a delay. There would just need to be a placeholder value that the backend can populate (nominally in the transpiler pass itself) based on what it says a default delay should equal. Since a delay gate is a QASM3 native gate I would assume the id to delay mapping would be needed across other system vendors at some point as well.

@kdk
Copy link
Copy Markdown
Member Author

kdk commented Jun 22, 2021

This case is slightly more complicated than unrolling because the IBM backends have a unique definition of 'id' (so I would expect we explicitly wouldn't need a pass like this across other system vendors).

While we do have a standardized interface across providers to report which instructions the device natively supports, we don't have a standardized interface to describe deprecation, removal or change of behavior for instructions, so this is for now handled by the provider.

@ajavadia
Copy link
Copy Markdown
Member

ajavadia commented Jun 24, 2021

While backend.run() is equipped to handle the different combinations of id/delay being present/absent, wouldn't we hit a transpiler error before we even get to backend.run()?
i.e. this line in your code:
qk.transpile(id_qcs, melbourne, optimization_level=0)
will raise if melbourne stops reporting id in basis gates.

@kdk
Copy link
Copy Markdown
Member Author

kdk commented Jun 24, 2021

While backend.run() is equipped to handle the different combinations of id/delay being present/absent, wouldn't we hit a transpiler error before we even get to backend.run()?
i.e. this line in your code:
qk.transpile(id_qcs, melbourne, optimization_level=0)
will raise if melbourne stops reporting id in basis gates.

You're right, I had mistakenly thought 'id' was a basis_instr (but it isn't). A few possible workarounds:

  1. Begin warning and replacing 'id' instructions immediately (instead of waiting until 'id' is removed from basis_gates) until device support is removed, at which point jobs will fail at transpile.
  2. Have the provider artificially add 'id' back into basis_gates once removed from the backend, for as long as this conversion needs to be supported.
  3. Allow the provider to supply this as a pass to the transpiler, to be run before translation (maybe as part of Implement next version of the provider interface qiskit#5894 ).

@ajavadia
Copy link
Copy Markdown
Member

I vote for 1.

@kdk kdk force-pushed the deprecate-hardware-id-instructions branch from 5c40a18 to 0e2c588 Compare July 2, 2021 21:09
@kdk
Copy link
Copy Markdown
Member Author

kdk commented Jul 2, 2021

I vote for 1.

Updated to 1 in 0e2c588.

@kdk kdk marked this pull request as ready for review July 2, 2021 21:19
Comment thread qiskit/providers/ibmq/ibmqbackend.py Outdated
Comment thread qiskit/providers/ibmq/ibmqbackend.py Outdated
Comment on lines +816 to +817
if not delay_support:
return
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The warnings on line 797 and 803 say id is being replaced by delay, but that's not true if delay is not reported as supported by the backend? And can people use delay if it's not reported?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I moved the if not delay_support: early exit earlier in the function, so the warning and 'id' search aren't performed if the device doesn't support 'delay'.

Co-authored-by: Jessie Yu <jessieyu@us.ibm.com>
Comment thread qiskit/providers/ibmq/ibmqbackend.py Outdated
Copy link
Copy Markdown
Collaborator

@jyu00 jyu00 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! @ajavadia I'm going to merge this if you're good with it too.

Copy link
Copy Markdown
Member

@ajavadia ajavadia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Changelog: Deprecation Include in Deprecated section of changelog

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ID gates should be replaced by delay instructions

4 participants