Open Sola85 opened 1 year ago
This is a pretty weird one, thanks. For others, this is a more minimal reproducer:
from qiskit import QuantumCircuit
from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary
from qiskit.circuit.library import XXPlusYYGate
from qiskit.transpiler.passes import BasisTranslator
qc = QuantumCircuit(2)
qc.append(XXPlusYYGate(0.5, 0.5), [0, 1])
pass_ = BasisTranslator(SessionEquivalenceLibrary, ["rx", "ry", "cx"])
pass_(qc)
I suspect that the root cause for us is an issue in symengine
that can introduce spurious imaginary components when it encounters powers of numbers in a context that it cannot prove is fully real, in which case it's going to be tricky for us to fix in the near term, because we have very little control over how symengine
decides to represent its expressions.
The issue is showing itself when using XXPlusYYGate
, but it's not really the culprit itself. It's just that the particular basis translation path from that gate to the ["rx", "ry", "cx"]
basis happens to give symengine
problems. If you're able to use a basis that includes rz
, that should step around the bug. Alternatively, and a bit more arcanely, if you run this at the start of your Python session, it'll also work around the bug:
from math import pi
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary
from qiskit.circuit.library import XXPlusYYGate
a, b = Parameter("a"), Parameter("b")
qc = QuantumCircuit(2)
qc.rx(pi / 2, 0)
qc.ry(-b - pi / 2, 0)
qc.rx(-pi / 2, 0)
qc.ry(pi/2, 1)
qc.cx(1, 0)
qc.ry(-a/2, 0)
qc.ry(-a/2, 1)
qc.cx(1, 0)
qc.rx(pi/2, 0)
qc.ry(b + pi/2, 0)
qc.rx(-pi/2, 0)
qc.ry(-pi/2, 1)
SessionEquivalenceLibrary.add_equivalence(XXPlusYYGate(a, b), qc)
@jakelishman I would like to work on this issue. Please assign this to me. Thank you!
Thanks @galeinston: I can assign you. There's really not a clear general-solution path forwards with regards to how symengine
can sometimes spurious imaginary components to enter when evaluating complex powers.
For the immediate problem at hand, it might be sufficient to add the equivalence rule I wrote out above to the StandardEquivalenceLibrary
that Qiskit maintains, and probably a similar one for XXMinusYYGate
.
@jakelishman thanks for the pointer. I'll start with your suggestion and see if there's anything else to improve
Environment
What is happening?
Transpilation fails with a
CircuitError: "Invalid param type <class 'complex'> for gate ry."
How can we reproduce the issue?
What should happen?
Transpilations succeeds
Any suggestions?
No response