qml.for_loop¶
- for_loop([start, ]stop[, step])[source]¶
A
qjit()
compatible for-loop for PennyLane programs. When used withoutqjit()
, this function will fall back to a standard Python for loop.This decorator provides a functional version of the traditional for-loop, similar to jax.cond.fori_loop. That is, any variables that are modified across iterations need to be provided as inputs/outputs to the loop body function:
Input arguments contain the value of a variable at the start of an iteration.
output arguments contain the value at the end of the iteration. The outputs are then fed back as inputs to the next iteration.
The final iteration values are also returned from the transformed function.
The semantics of
for_loop
are given by the following Python pseudo-code:def for_loop(start, stop, step, loop_fn, *args): for i in range(start, stop, step): args = loop_fn(i, *args) return args
Unlike
jax.cond.fori_loop
, the step can be negative if it is known at tracing time (i.e., constant). If a non-constant negative step is used, the loop will produce no iterations.Note
This function can be used in the following different ways:
for_loop(stop)
: Values are generated within the interval[0, stop)
for_loop(start, stop)
: Values are generated within the interval[start, stop)
for_loop(start, stop, step)
: Values are generated within the interval[start, stop)
, with spacing between the values given bystep
- Parameters
start (int, optional) – starting value of the iteration index. The default start value is
0
stop (int) – upper bound of the iteration index
step (int, optional) – increment applied to the iteration index at the end of each iteration. The default step size is
1
- Returns
A wrapper around the loop body function. Note that the loop body function must always have the iteration index as its first argument, which can be used arbitrarily inside the loop body. As the value of the index across iterations is handled automatically by the provided loop bounds, it must not be returned from the function.
- Return type
Callable[[int, …], …]
See also
Example
dev = qml.device("lightning.qubit", wires=1) @qml.qnode(dev) def circuit(n: int, x: float): @qml.for_loop(0, n, 1) def loop_rx(i, x): # perform some work and update (some of) the arguments qml.RX(x, wires=0) # update the value of x for the next iteration return jnp.sin(x) # apply the for loop final_x = loop_rx(x) return qml.expval(qml.Z(0))
>>> circuit(7, 1.6) array(0.97926626)
for_loop
is alsoqjit()
compatible; when used with theqjit()
decorator, the for loop will not be unrolled, and instead will be captured as-is during compilation and executed during runtime:>>> qml.qjit(circuit)(7, 1.6) Array(0.97926626, dtype=float64)
Note
Please see the Catalyst quickstart guide, as well as the sharp bits and debugging tips page for an overview of using quantum just-in-time compilation.