ctrl(fn, control, control_values=None)[source]

Create a method that applies a controlled version of the provided method.

  • fn (function) – Any python function that applies pennylane operations.

  • control (Wires) – The control wire(s).

  • control_values (int or list[int]) – The value(s) the control wire(s) should take. Integers other than 0 or 1 will be treated as int(bool(x)).


A new function that applies the controlled equivalent of fn. The returned function takes the same input arguments as fn.

Return type



dev = qml.device('default.qubit', wires=4)

def ops(params):
    qml.RX(params[0], wires=0)
    qml.RZ(params[1], wires=3)

ops1 = qml.ctrl(ops, control=1)
ops2 = qml.ctrl(ops, control=2)

def my_circuit():
    ops1(params=[0.123, 0.456])
    ops1(params=[0.789, 1.234])
    ops2(params=[2.987, 3.654])
    ops2(params=[2.321, 1.111])
    return qml.state()

The above code would be equivalent to

def my_circuit2():
    # ops1(params=[0.123, 0.456])
    qml.CRX(0.123, wires=[1, 0])
    qml.CRZ(0.456, wires=[1, 3])

    # ops1(params=[0.789, 1.234])
    qml.CRX(0.789, wires=[1, 0])
    qml.CRZ(1.234, wires=[1, 3])

    # ops2(params=[2.987, 3.654])
    qml.CRX(2.987, wires=[2, 0])
    qml.CRZ(3.654, wires=[2, 3])

    # ops2(params=[2.321, 1.111])
    qml.CRX(2.321, wires=[2, 0])
    qml.CRZ(1.111, wires=[2, 3])
    return qml.state()


Some devices are able to take advantage of the inherent sparsity of a controlled operation. In those cases, it may be more efficient to use this transform rather than adding controls by hand. For devices that don’t have special control support, the operation is expanded to add control wires to each underlying op individually.

Nesting Controls

The ctrl transform can be nested with itself arbitrarily.

# These two ops are equivalent.
op1 = qml.ctrl(qml.ctrl(ops, 1), 2)
op2 = qml.ctrl(ops, [2, 1])

Control Value Assignment

Control values can be assigned as follows.

op = qml.ctrl(ops, 2, control_values=0)
op(params=[0.1, 0.2])

This is equivalent to the following.

op = qml.ctrl(ops, 2)
op(params=[0.1, 0.2])