qml.capture.make_plxpr

make_plxpr(func, static_argnums=(), autograph=True, **kwargs)[source]

Takes a function and returns a Callable that, when called, produces a PLxPR representing the function with the given args.

This function relies on jax.make_jaxpr as part of creating the representation. Any keyword arguments passed to make_plxpr that are not directly used in the function will be passed to make_jaxpr.

Parameters

func (Callable) – the Callable to be captured

Keyword Arguments
  • static_argnums (Union(int, Sequence[int])) – optional, an int or collection of ints that specify which positional arguments to treat as static (trace- and compile-time constant).

  • autograph (bool) – whether to use AutoGraph to convert Python control flow to native PennyLane control flow. Defaults to True.

Returns

function that, when called, returns the PLxPR representation of func for the specified inputs.

Return type

Callable

Note

More details on using AutoGraph are provided under Usage Details.

There are some limitations and sharp bits regarding AutoGraph; to better understand supported behaviour and limitations, see https://docs.pennylane.ai/en/stable/development/autograph.html

Example

qml.capture.enable()

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

@qml.qnode(dev)
def circ(x):
    qml.RX(x, 0)
    qml.Hadamard(0)
    return qml.expval(qml.X(0))

plxpr = qml.capture.make_plxpr(circ)(1.2)
>>> print(plxpr)
{ lambda ; a:f32[]. let
    b:f32[] = qnode[
        device=<default.qubit device (wires=1) at 0x152a6f010>
        n_consts=0
        qfunc_jaxpr={ lambda ; c:f32[]. let
            _:AbstractOperator() = RX[n_wires=1] c 0
            _:AbstractOperator() = Hadamard[n_wires=1] 0
            d:AbstractOperator() = PauliX[n_wires=1] 0
            e:AbstractMeasurement(n_wires=None) = expval_obs d
          in (e,) }
        qnode=<QNode: device='<default.qubit device (wires=1) at 0x152a6f010>', interface='auto', diff_method='best'>
        qnode_kwargs={'diff_method': 'best', 'grad_on_execution': 'best', 'cache': False, 'cachesize': 10000, 'max_diff': 1, 'device_vjp': False, 'mcm_method': None, 'postselect_mode': None}
        shots=Shots(total=None)
    ] a
  in (b,) }

The autograph argument is True by default, converting Pythonic control flow to PennyLane supported control flow. This requires the diastatic-malt package, a standalone fork of the AutoGraph module in TensorFlow (official documentation ).

Note

There are some limitations and sharp bits regarding AutoGraph; to better understand supported behaviour and limitations, see https://docs.pennylane.ai/en/stable/development/autograph.html

On its own, capture of standard Python control flow is not supported:

def fn(x):
    if x > 5:
        return x+1
    return x+2

For this function, capture doesn’t work without autograph:

>>> plxpr_fn = qml.capture.make_plxpr(fn, autograph=False)
>>> plxpr = plxpr_fn(3)
TracerBoolConversionError: Attempted boolean conversion of traced array with shape bool[].

With AutoGraph, the control flow is automatically converted to the native PennyLane control flow implementation, and succeeds:

>>> plxpr_fn = qml.capture.make_plxpr(fn)
>>> plxpr = plxpr_fn(3)
>>> plxpr
{ lambda ; a:i64[]. let
    b:bool[] = gt a 5
    _:bool[] c:i64[] = cond[
      args_slice=slice(4, None, None)
      consts_slices=[slice(2, 3, None), slice(3, 4, None)]
      jaxpr_branches=[{ lambda a:i64[]; . let  in (True, a) }, { lambda a:i64[]; . let b:i64[] = add a 2 in (True, b) }]
    ] b True a a
  in (c,) }

We can evaulate this to get the results:

>>> jax.core.eval_jaxpr(plxpr.jaxpr, plxpr.consts, 2)
[Array(4, dtype=int64, weak_type=True)]
>>> jax.core.eval_jaxpr(plxpr.jaxpr, plxpr.consts, 7)
[Array(8, dtype=int64, weak_type=True)]

Contents

Using PennyLane

Release news

Development

API

Internals