Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transpilation routing causes StandardRB to cheat #1279

Closed
fvoichick opened this issue Sep 30, 2023 · 2 comments · Fixed by #1288
Closed

Transpilation routing causes StandardRB to cheat #1279

fvoichick opened this issue Sep 30, 2023 · 2 comments · Fixed by #1288
Labels
bug Something isn't working

Comments

@fvoichick
Copy link

fvoichick commented Sep 30, 2023

Informations

  • Qiskit Experiments version: 0.5.3
  • Python version: 3.8.10
  • Operating system: Ubuntu
  • I first mentioned this issue in the #experiments channel, where @wshanks suggested opening an issue.

What is the current behavior?

StandardRB gives inaccurate benchmarking results for greater than two qubits. The Qiskit transpiler routing stage does not respect the barrier instructions between the Clifford gates, and so SWAP gates are optimized away using TranspileLayout relabeling. This makes it impossible to accurately benchmark three-qubit gates using StandardRB, because the randomly-sampled Clifford gates are skewed toward those that involve fewer SWAP gates. (Two-qubit RB has a custom transpilation that seems to avoid this problem.)

Steps to reproduce the problem

Run this script:

from itertools import takewhile

from qiskit import QuantumCircuit
from qiskit.quantum_info import Clifford
from qiskit_experiments.library import StandardRB


def circuit_until_barrier(circuit: QuantumCircuit) -> QuantumCircuit:
    result = QuantumCircuit(3)
    for instruction in takewhile(lambda i: i.operation.name != "barrier", circuit.data):
        result.append(instruction)
    return result


experiment = StandardRB(
    physical_qubits=(0, 1, 2),
    lengths=(1,),
    num_samples=1,
    seed=2023,
)
experiment.transpile_options["coupling_map"] = [[0, 1], [1, 0], [1, 2], [2, 1]]
experiment.transpile_options["basis_gates"] = ["rz", "sx", "x", "cx"]
before: QuantumCircuit = experiment.circuits()[0]
after: QuantumCircuit = experiment._transpiled_circuits()[0]
print(Clifford.from_circuit(circuit_until_barrier(before)))
print(Clifford.from_circuit(circuit_until_barrier(after)))
print(after.layout)

It produces the following output:

Clifford: Stabilizer = ['-XIZ', '+ZZY', '+YYY'], Destabilizer = ['+XIX', '-XZI', '+IZI']
Clifford: Stabilizer = ['-IXZ', '+ZZY', '+YYY'], Destabilizer = ['+IXX', '-ZXI', '+ZII']
TranspileLayout(initial_layout=Layout({
0: Qubit(QuantumRegister(3, 'q'), 0),
1: Qubit(QuantumRegister(3, 'q'), 1),
2: Qubit(QuantumRegister(3, 'q'), 2)
}), input_qubit_mapping={Qubit(QuantumRegister(3, 'q'), 0): 0, Qubit(QuantumRegister(3, 'q'), 1): 1, Qubit(QuantumRegister(3, 'q'), 2): 2}, final_layout=Layout({
0: Qubit(QuantumRegister(3, 'q'), 0),
2: Qubit(QuantumRegister(3, 'q'), 1),
1: Qubit(QuantumRegister(3, 'q'), 2)
}))

What is the expected behavior?

The Clifford gates before and after transpilation should be the same. (I would also expect final_layout to match initial_layout).

Suggested solutions

Edit the _transpiled_circuits method so that it decomposes each Clifford gate in a way that preserves the qubit layout.

(edited for clarity)

@fvoichick fvoichick added the bug Something isn't working label Sep 30, 2023
@wshanks
Copy link
Collaborator

wshanks commented Oct 1, 2023

One note -- relabeling does not occur for the case where there is all-to-all coupling. This is always the case for two qubit RB, so the special handling there does not matter. The smallest case where this effect occurs is three qubit RB with linearly coupled qubits (for three qubits all coupled to each other it also should not occur).

@coruscating
Copy link
Collaborator

Thanks for reporting this. The root of this issue is that the Qiskit transpiler tries to optimize the layout whenever possible by relabeling qubits regardless of the presence of barriers, so we need to add an option to force the final layout to stay the same as the initial. This work is already being tracked in Qiskit/qiskit#8185. In the meantime, we'll add a note to the documentation that 3Q+ experiments cannot be guaranteed to run on the exact physical qubits specified by the user when coupling is limited.

github-merge-queue bot pushed a commit that referenced this issue Jan 18, 2024
### Summary
Make the Clifford synthesis algorithm for RB circuits pluggable
(implementing it as a `HighLevelSynthesisPlugin`).
Fixes #1279 and #1023.
Change to accept Clifford elements consisting only of instructions
supported by the backend for `interleaved_element` option in
`InterleavedRB`.
Speed up 2Q RB/IRB for backends with unidirectional 2q gates, e.g. IBM's
127Q Eagle processors.

### Details and comments
Previously, for 3Q+ RB circuits, entire circuit is transpiled at once
and hence for each of the resulting Cliffords, the initial and the final
layout may differ, that means sampled Cliffords are changed during the
transpilation. Also in the worst case, the resulting circuit may use
physical qubits not in the supplied `physical_qubits`. To avoid that,
this commit changes to transpile an RB sequence Clifford by Clifford.
The Clifford synthesis algorithm (`rb_default`) is implemented as a
`HighLevelSynthesisPlugin` (see `RBDefaultCliffordSynthesis` in
`clifford_synthesis.py`), which forces the initial layout (i.e.
guarantees the initial layout = the final layout) and physical qubits to
use. As a byproduct, the performance of 2Q RB/IRB for backends with
directed 2q gates (e.g. IBM's 127Q Eagle processors) is drastically
improved. For those cases, previously we had to rely on `transpile`
function to make generated circuits comply with the coupling map,
however, after this commit, we can synthesize Cliffords with considering
the 2q-gate direction and go through the fast path introduced in #982.

Depends on Qiskit/qiskit#10477 (qiskit 0.45)

---------

Co-authored-by: Helena Zhang <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants