defer_measurements(tape, **kwargs)[source]

Quantum function transform that substitutes operations conditioned on measurement outcomes to controlled operations.

This transform uses the deferred measurement principle and applies to qubit-based quantum functions.

Support for mid-circuit measurements is device-dependent. If a device doesn’t support mid-circuit measurements natively, then the QNode will apply this transform.


The transform uses the ctrl() transform to implement operations controlled on mid-circuit measurement outcomes. The set of operations that can be controlled as such depends on the set of operations supported by the chosen device.


Devices that inherit from QubitDevice must be initialized with an additional wire for each mid-circuit measurement after which the measured wire is reused or reset for defer_measurements to transform the quantum tape correctly.


This transform does not change the list of terminal measurements returned by the quantum function.


When applying the transform on a quantum function that contains the Snapshot instruction, state information corresponding to simulating the transformed circuit will be obtained. No post-measurement states are considered.


state() is not supported with the defer_measurements transform. Additionally, probs(), sample() and counts() can only be used with defer_measurements if wires or an observable are explicitly specified.


defer_measurements does not support using custom wire labels if any measured wires are reused or reset.


tape (QNode or QuantumTape or Callable) – a quantum circuit.


The transformed circuit as described in qml.transform.

Return type

qnode (QNode) or quantum function (Callable) or tuple[List[QuantumTape], function]

  • ValueError – If custom wire labels are used with qubit reuse or reset

  • ValueError – If any measurements with no wires or observable are present

  • ValueError – If continuous variable operations or measurements are present

  • ValueError – If using the transform with any device other than default.qubit and postselection is used


Suppose we have a quantum function with mid-circuit measurements and conditional operations:

def qfunc(par):
    qml.RY(0.123, wires=0)
    m_0 = qml.measure(1)
    qml.cond(m_0, qml.RY)(par, wires=0)
    return qml.expval(qml.Z(0))

The defer_measurements transform allows executing such quantum functions without having to perform mid-circuit measurements:

>>> dev = qml.device('default.qubit', wires=2)
>>> transformed_qfunc = qml.defer_measurements(qfunc)
>>> qnode = qml.QNode(transformed_qfunc, dev)
>>> par = np.array(np.pi/2, requires_grad=True)
>>> qnode(par)
tensor(0.43487747, requires_grad=True)

We can also differentiate parameters passed to conditional operations:

>>> qml.grad(qnode)(par)
tensor(-0.49622252, requires_grad=True)

Reusing and reseting measured wires will work as expected with the defer_measurements transform:

dev = qml.device("default.qubit", wires=3)

def func(x, y):
    qml.RY(x, wires=0)
    qml.CNOT(wires=[0, 1])
    m_0 = qml.measure(1, reset=True)

    qml.cond(m_0, qml.RY)(y, wires=0)
    qml.RX(np.pi/4, wires=1)
    return qml.probs(wires=[0, 1])

Executing this QNode:

>>> pars = np.array([0.643, 0.246], requires_grad=True)
>>> func(*pars)
tensor([0.76960924, 0.13204407, 0.08394415, 0.01440254], requires_grad=True)