# Rotations with angle 0 after transpiling with qiskit

When using qiskit to transpile a circuit sometimes there is a gate Rz(0.0)in the result. I wonder 1) why this happens and 2) what does it mean for the executed circuit (is it just a waiting time with length gate-length)?

In more detail: I transpile the following circuit with optimization_level=3 for ibm_oslo (here shown without the measurements on all qubits) :

        ┌───┐    ┌──────────┐┌───┐
q_0: ───┤ X ├────┤ Ry(p[0]) ├┤ X ├─────
├───┤    ├──────────┤└─┬─┘┌───┐
q_1: ───┤ X ├────┤ Ry(p[1]) ├──┼──┤ X ├
┌──┴───┴───┐└──────────┘  │  └─┬─┘
q_2: ┤ Ry(p[2]) ├─────■────────■────┼──
├──────────┤   ┌─┴─┐           │
q_3: ┤ Ry(p[3]) ├───┤ X ├───────────■──
└──────────┘   └───┘


It sometimes gives the mentioned RZ(0.0) in the 1st and 5th logical qubit :

               ┌───┐   ┌─────────┐   ┌────┐┌──────────────┐┌────┐┌────────┐┌───┐ ░    ┌─┐
q_1 -> 0 ┤ X ├───┤ Rz(0.0) ├───┤ √X ├┤ Rz(p[1] + π) ├┤ √X ├┤ Rz(3π) ├┤ X ├─░────┤M├──────
├───┴┐┌─┴─────────┴──┐├────┤└──┬────────┬──┘├───┬┘└────────┘└─┬─┘ ░    └╥┘   ┌─┐
q_3 -> 1 ┤ √X ├┤ Rz(p[3] + π) ├┤ √X ├───┤ Rz(3π) ├───┤ X ├─────────────■───░─────╫────┤M├
└────┘└──────────────┘└────┘   └────────┘   └─┬─┘                 ░     ║    └╥┘
ancilla_0 -> 2 ──────────────────────────────────────────────┼─────────────────────────╫─────╫─
┌────┐┌──────────────┐┌────┐   ┌────────┐     │                   ░     ║ ┌─┐ ║
q_2 -> 3 ┤ √X ├┤ Rz(p[2] + π) ├┤ √X ├───┤ Rz(3π) ├─────■───────────────■───░─────╫─┤M├─╫─
└────┘└──────────────┘└────┘   └────────┘                     │   ░     ║ └╥┘ ║
ancilla_1 -> 4 ──────────────────────────────────────────────────────────────┼─────────╫──╫──╫─
┌───┐   ┌─────────┐   ┌────┐┌──────────────┐┌────┐┌────────┐┌─┴─┐ ░ ┌─┐ ║  ║  ║
q_0 -> 5 ┤ X ├───┤ Rz(0.0) ├───┤ √X ├┤ Rz(p[0] + π) ├┤ √X ├┤ Rz(3π) ├┤ X ├─░─┤M├─╫──╫──╫─
└───┘   └─────────┘   └────┘└──────────────┘└────┘└────────┘└───┘ ░ └╥┘ ║  ║  ║
ancilla_2 -> 6 ─────────────────────────────────────────────────────────────────────╫──╫──╫──╫─
║  ║  ║  ║
meas: 4/═════════════════════════════════════════════════════════════════════╩══╩══╩══╩═
0  1  2  3

• My guess is that there may be some noise evaluation where the delays there lead to better performance. Jun 9 at 11:14
• Could you elaborate on this a little bit? I would expect a shorter circuit to always perform better, because less noise has happened Jun 9 at 11:57
• I don't know how the qiskit optimiser (lvl 3) works, nor how noise affects computation in case this is optimised differently. Mine is only a guess, otherwise I would write an answer. This is an interesting question. Have you found the same result with lower optimisation levels (1,2)? Jun 9 at 12:00
• From qiskit doc: "Level 3 pass manager: heavy optimization by noise adaptive qubit mapping and gate cancellation using commutativity rules and unitary synthesis." Jun 9 at 12:03

1. why this happens

This happens because of the way BasisTranslator transpiler pass works. BasisTranslator translates gates to a target basis by searching for a set of translations from a given EquivalenceLibrary. According to the translations in the standard equivalence library:

• Ry(theta) gate will be translated into R(theta, pi/2) gate.
• R(theta, phi) will be translated into U3(theta, phi - pi/2, pi/2 - phi)
• U3(theta, phi, lam) will be translated into the sequence Rz(lam), SX, Rz(theta + pi), SX, Rz(phi + 3pi)

So, Ry(theta) becomes R(theta, pi/2) which in turn translated to U3(theta, 0, 0) and finally we get the sequence Rz(0), SX, Rz(theta + pi), SX, Rz(3pi)

Note 1: see this answer for more details about how to get the standard equivalence library content.

Note 2: transpile method accepts a callback function which can be used to dig deep into the transpilation process. For example, the following code snippet will display the transpiler pass name and the circuit after executing it:

from qiskit.converters import dag_to_circuit

def transpiler_callback(**kwargs):
pass_ = kwargs['pass_']
dag = kwargs['dag']
qc = dag_to_circuit(dag)
print(pass_.name())
display(qc.draw('mpl'))

tr_circ = transpile(circ, backend=backend, optimization_level=3, callback=transpiler_callback)


Note 3: If you transpile your circuit using the latest version of Qiskit, Optimize1qGatesDecomposition transpiler pass will remove the gates with zero rotation.

1. what does it mean for the executed circuit (is it just a waiting time with length gate-length)?

Because of how Rz gate is implemented in IBM quantum hardware, it doesn't mean anything (see this answer for the details).