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

Pauli.evolve() should recognize ECR gates as Clifford gates #12086

Closed
aeddins-ibm opened this issue Mar 26, 2024 · 6 comments · Fixed by #12095
Closed

Pauli.evolve() should recognize ECR gates as Clifford gates #12086

aeddins-ibm opened this issue Mar 26, 2024 · 6 comments · Fixed by #12095
Labels
bug Something isn't working mod: quantum info Related to the Quantum Info module (States & Operators)

Comments

@aeddins-ibm
Copy link
Contributor

Environment

  • Qiskit version: 1.0.2
  • Python version: 3.11
  • Operating system: macos

What is happening?

qc = QuantumCircuit(2)
qc.ecr(0,1)
qi.Pauli('XX').evolve(qc)

The above call to evolve() raises an error even though qc contains only Clifford gates:

QiskitError: 'Cannot apply Instruction: u'

How can we reproduce the issue?

qc = QuantumCircuit(2)
qc.ecr(0,1)
qi.Pauli('XX').evolve(qc)

What should happen?

ECR gates should be recognized as Clifford gates, and the Pauli should evolve successfully.

Related: #12085

Any suggestions?

No response

@aeddins-ibm aeddins-ibm added the bug Something isn't working label Mar 26, 2024
@aeddins-ibm aeddins-ibm changed the title Pauli.evolve() should recognize ECR gates as Clifford gates Pauli.evolve() should recognize ECR gates as Clifford gates Mar 26, 2024
@ShellyGarion ShellyGarion added the mod: quantum info Related to the Quantum Info module (States & Operators) label Mar 27, 2024
@ShellyGarion
Copy link
Member

Currently, the ECRGate is a Clifford gate, and can be transformed into a Clifford operator, so this code should work:

from qiskit.quantum_info import *
qc = QuantumCircuit(2)
qc.ecr(0,1)
cliff = Clifford(qc)
Pauli('XX').evolve(cliff)

but since the ECRGate definition contains non-Clifford gates, when appending it to a QuantumCircuit, it's being decomposed into non-Clifford gates, and that's why your code doesn't work.

@aeddins-ibm
Copy link
Contributor Author

aeddins-ibm commented Mar 27, 2024

Thank you for the info about the bug. This workaround is helpful, but if I understand correctly converting to a Clifford and then evolving is slower than evolving by a circuit, and in general it seems important for Pauli.evolve() to recognize ECR since it's a standard basis gate for backends.

Currently there is a dictionary of recognized Clifford gates in _append_circuit, the subroutine inside of Pauli.evolve:

basis_2q = {"cx": _evolve_cx, "cz": _evolve_cz, "cy": _evolve_cy, "swap": _evolve_swap}

So one solution could be to add 'ecr' to this dictionary, along with a specialized _evolve_ecr() method.

One straightforward implementation is:

def _evolve_ecr(base_pauli, q0, q1):
    base_pauli = _evolve_s(base_pauli, q0)
    base_pauli = _evolve_h(base_pauli, q1)
    base_pauli = _evolve_s(base_pauli, q1)
    base_pauli = _evolve_h(base_pauli, q1)
    base_pauli = _evolve_cx(base_pauli, q0, q1)
    base_pauli = _evolve_x(base_pauli, q0)
    return base_pauli

following the Clifford decomposition of the ECRGate:
image

There's presumably a way to simplify those steps, but already a significant speedup is available. Here is a setup for a quick timing test,

qc = QuantumCircuit(2)
qc.ecr(0,1)
cliff= qi.Clifford(qc)
random_paulis = qi.random.random_pauli_list(100,10000)
random_pauli_lists = [qi.random.random_pauli_list(100, 10000) for _ in range(2000)]

and results (approximate times in lower left corner of each cell):
image

These are crude timing tests but suggest a large speedup vs the workaround. Maybe more importantly the change would remove the burden on the user of having to explicitly handle the special case of an ECR gate.

Does this seem like a reasonable way to add support for the ECRGate? If so I can put together a PR.

@aeddins-ibm
Copy link
Contributor Author

I went ahead and made a draft PR here: #12095 .

The call to the new Pauli.evolve(qc) is not as fast as calling _evolve_ecr directly, but still almost ~2x faster for this single-gate circuit than evolving by the Clifford (tried a few sizes of Paulis).

The PauliList.evolve() tests ran in the same approximate time as calling _evolve_ecr directly in the above test.

@ShellyGarion
Copy link
Member

I went ahead and made a draft PR here: #12095 .

The call to the new Pauli.evolve(qc) is not as fast as calling _evolve_ecr directly, but still almost ~2x faster for this single-gate circuit than evolving by the Clifford (tried a few sizes of Paulis).

The PauliList.evolve() tests ran in the same approximate time as calling _evolve_ecr directly in the above test.

I think that this would be the best approach. This is similar to the way that I added the ECRGate and other gates to the Clifford class in #9623. Do you think that you need other gates as well?

@aeddins-ibm
Copy link
Contributor Author

Thanks for the feedback!

Do you think that you need other gates as well?

I think supporting ECRGate is important since it seems to be a standard basis-gate for real backends nowadays (at least for IBM backends), and given that ECRGate is a standard gate included in Qiskit.

The single-qubit rotations by pi/2 angles as in the other issue would also be good I think, but would need to be handled a little differently so maybe it's better not to further complicate this PR... And maybe it's a little less surprising from a user perspective that Rz might not be detected as a Clifford gate since it depends on the parameter, whereas ECR is always Clifford.

@aeddins-ibm
Copy link
Contributor Author

I marked the PR as "ready for review," but if I should change it back for some reason (like if you were planning to make changes first or anything) just let me know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working mod: quantum info Related to the Quantum Info module (States & Operators)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants